diff --git a/DTLib.Dtsod/ClassSerializer/DtsodAttributes.cs b/DTLib.Dtsod/ClassSerializer/DtsodAttributes.cs new file mode 100644 index 0000000..e870b1c --- /dev/null +++ b/DTLib.Dtsod/ClassSerializer/DtsodAttributes.cs @@ -0,0 +1,41 @@ +using System.Xml.Serialization; + +namespace DTLib.Dtsod; + +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface)] +public class DtsodSerializableAttribute : Attribute +{ + public DtsodVersion Version; + public DtsodSerializableAttribute(DtsodVersion ver) => Version = ver; +} + + +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] +public class SerializeAsAttribute: Attribute +{ + public string Key; + /// + /// use it only for base types + /// + /// name the field will be serialized as + public SerializeAsAttribute(string key) => Key = key; +} + +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] +public class SerializationMethodAttribute : Attribute +{ + public Func Method; + /// + /// + /// how to serialize field + public SerializationMethodAttribute(Func method) => Method = method; +} +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] +public class DeserializationMethodAttribute : Attribute +{ + public Func Method; + /// + /// + /// how to deserialize field + public DeserializationMethodAttribute( Func method) => Method = method; +} \ No newline at end of file diff --git a/DTLib.Dtsod/Dependencies/windows/x64/kerep.dll b/DTLib.Dtsod/Dependencies/windows/x64/kerep.dll index 0aff218..2286c23 100644 Binary files a/DTLib.Dtsod/Dependencies/windows/x64/kerep.dll and b/DTLib.Dtsod/Dependencies/windows/x64/kerep.dll differ diff --git a/DTLib.Dtsod/Dependencies/windows/x86/kerep.dll b/DTLib.Dtsod/Dependencies/windows/x86/kerep.dll index b5a30f8..109371d 100644 Binary files a/DTLib.Dtsod/Dependencies/windows/x86/kerep.dll and b/DTLib.Dtsod/Dependencies/windows/x86/kerep.dll differ diff --git a/DTLib.Dtsod/DtsodV23.cs b/DTLib.Dtsod/DtsodV23.cs index e9e32fd..29cacda 100644 --- a/DTLib.Dtsod/DtsodV23.cs +++ b/DTLib.Dtsod/DtsodV23.cs @@ -151,7 +151,9 @@ public class DtsodV23 : DtsodDict, IDtsod List list = new(); while (true) { - list.Add(ReadValue(out bool _eol)); + var item = ReadValue(out bool _eol); + if(item!=null) + list.Add(item); if (_eol) break; } @@ -239,6 +241,12 @@ public class DtsodV23 : DtsodDict, IDtsod break; case ';': case ',': + if(b.Length == 0) + { + if(endOfList) + return null; + throw new Exception("zero length value"); + } string str = b.ToString(); b.Clear(); return ParseValue(str); @@ -287,42 +295,54 @@ public class DtsodV23 : DtsodDict, IDtsod { typeof(double), (val, b) => b.Append(val.ToString(CultureInfo.InvariantCulture)) }, { typeof(decimal), (val, b) => b.Append(val.ToString(CultureInfo.InvariantCulture)).Append("de") } }; - short tabscount = -1; - protected StringBuilder Serialize(DtsodV23 dtsod, StringBuilder b = null) - { + + protected StringBuilder Serialize(DtsodV23 dtsod, ref int tabscount, StringBuilder b = null) + {; tabscount++; if (b is null) b = new StringBuilder(); foreach (var pair in dtsod) { b.Append('\t', tabscount).Append(pair.Key).Append(": "); - SerializeType(pair.Value); + SerializeType(pair.Value, ref tabscount); b.Append(";\n"); - void SerializeType(dynamic value) + void SerializeType(dynamic value, ref int tabscount) { if (value is null) b.Append("null"); + else if (value is DtsodV23 _dtsod) + { + b.Append("{\n"); + Serialize(_dtsod, ref tabscount, b); + b.Append('}'); + } else if (value is IList _list) { b.Append('['); foreach (object el in _list) { - SerializeType(el); + SerializeType(el, ref tabscount); b.Append(','); } b.Remove(b.Length - 1, 1).Append(']'); } - else if (value is DtsodV23 _dtsod) - { - b.Append("{\n"); - Serialize(_dtsod, b); - b.Append('}'); - } else TypeSerializeFuncs[value.GetType()].Invoke(value, b); } } tabscount--; return b; } - - public override string ToString() => Serialize(this).ToString(); + + public override string ToString() + { + int tabscount = -1; + return Serialize(this, ref tabscount).ToString(); + } + + ///serializes dtsod as part of list + public string ToString(string partialListName) + { + int tabscount = 0; + var builder = new StringBuilder().Append('$').Append(partialListName).Append(":\n{\n"); + return Serialize(this, ref tabscount, builder).Append("};\n").ToString(); + } } diff --git a/DTLib.Dtsod/V30/DtsodSerializableAttribute.cs b/DTLib.Dtsod/V30/DtsodSerializableAttribute.cs deleted file mode 100644 index 9d3fe10..0000000 --- a/DTLib.Dtsod/V30/DtsodSerializableAttribute.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace DTLib.Dtsod; - -public class DtsodSerializableAttribute : Attribute -{ - public DtsodVersion Version; - public DtsodSerializableAttribute(DtsodVersion ver) => Version = ver; -} diff --git a/DTLib/Extensions/Collections.cs b/DTLib/Extensions/Collections.cs index f189203..ec7f5cc 100644 --- a/DTLib/Extensions/Collections.cs +++ b/DTLib/Extensions/Collections.cs @@ -2,37 +2,9 @@ public static class Collections { - public static void ForEach(this IEnumerable en, Action act) { foreach (T elem in en) act(elem); } - - // массив в лист - public static List ToList(this T[] input) - { - var list = new List(); - list.AddRange(input); - return list; - } - - // удаление нескольких элементов массива - public static T[] RemoveRange(this T[] input, int startIndex, int count) - { - var list = input.ToList(); - list.RemoveRange(startIndex, count); - return list.ToArray(); - } - public static T[] RemoveRange(this T[] input, int startIndex) => input.RemoveRange(startIndex, input.Length - startIndex); - - - // метод как у листов - public static bool Contains(this T[] array, T value) - { - for (int i = 0; i < array.Length; i++) - if (array[i].Equals(value)) - return true; - return false; - } } diff --git a/DTLib/Extensions/StringConverter.cs b/DTLib/Extensions/StringConverter.cs index b849962..70ed1c1 100644 --- a/DTLib/Extensions/StringConverter.cs +++ b/DTLib/Extensions/StringConverter.cs @@ -144,4 +144,6 @@ public static class StringConverter if (max * length != s.Length) parts.Add(s.Substring(max * length, s.Length - max * length)); return parts; } + + public static bool IsNullOrEmpty(this string s) => String.IsNullOrEmpty(s); }