From 54d9a43e7593547548e0ae32527bd7981222430a Mon Sep 17 00:00:00 2001 From: Timerix22 Date: Fri, 14 Jan 2022 00:02:40 +0300 Subject: [PATCH] bugfixes and optimization of dtsod --- Dtsod/DtsodV21.cs | 49 +----------------- Dtsod/DtsodV22.cs | 50 ------------------ Dtsod/DtsodV23.cs | 128 +++++++++++++++++++++++++++------------------- 3 files changed, 76 insertions(+), 151 deletions(-) diff --git a/Dtsod/DtsodV21.cs b/Dtsod/DtsodV21.cs index 5201e19..d502f69 100644 --- a/Dtsod/DtsodV21.cs +++ b/Dtsod/DtsodV21.cs @@ -81,9 +81,6 @@ public class DtsodV21 : Dictionary, IDtsod int i = 0; for (; i < text.Length; i++) ReadName(); -#if DEBUG - DebugNoTime("g", $"Parse returns {parsed.Keys.Count} keys\n"); -#endif return parsed; // СЛОМАНО @@ -99,9 +96,6 @@ public class DtsodV21 : Dictionary, IDtsod dynamic value; StringBuilder defaultNameBuilder = new(); -#if DEBUG - DebugNoTime("m", "ReadName\n"); -#endif for (; i < text.Length; i++) { switch (text[i]) @@ -116,7 +110,7 @@ public class DtsodV21 : Dictionary, IDtsod string name = defaultNameBuilder.ToString(); value = ReadValue(); // если value это null, эта строка выдавала ошибку - //DebugNoTime("c", $"parsed.Add({name}, {value} { value.GetType() })\n"); + //DebugNoTime("c", $"parsed.Add({name}, {value} { value.GetType() })"); if (isListElem) { if (!parsed.ContainsKey(name)) @@ -134,9 +128,6 @@ public class DtsodV21 : Dictionary, IDtsod throw new Exception("Parse.ReadName() error: unexpected '}' at " + i + " char"); // если $ перед названием параметра поставить, значение value добавится в лист с названием name case '$': -#if DEBUG - DebugNoTime("w", text[i].ToString()); -#endif if (defaultNameBuilder.ToString().Length != 0) throw new Exception("Parse.ReadName() error: unexpected '$' at " + i + " char"); isListElem = true; @@ -144,9 +135,6 @@ public class DtsodV21 : Dictionary, IDtsod case ';': throw new Exception("Parse.ReadName() error: unexpected ';' at " + i + " char"); default: -#if DEBUG - DebugNoTime("w", text[i].ToString()); -#endif defaultNameBuilder.Append(text[i]); break; } @@ -165,15 +153,9 @@ public class DtsodV21 : Dictionary, IDtsod valueBuilder.Append('"'); for (; text[i] != '"' || text[i - 1] == '\\'; i++) { -#if DEBUG - DebugNoTime("h", text[i].ToString()); -#endif valueBuilder.Append(text[i]); } valueBuilder.Append('"'); -#if DEBUG - DebugNoTime("h", text[i].ToString()); -#endif type = ValueType.String; return valueBuilder.ToString(); } @@ -185,9 +167,6 @@ public class DtsodV21 : Dictionary, IDtsod StringBuilder valueBuilder = new(); for (; text[i] != ']'; i++) { -#if DEBUG - DebugNoTime("c", text[i].ToString()); -#endif switch (text[i]) { case ' ': @@ -210,9 +189,6 @@ public class DtsodV21 : Dictionary, IDtsod ParseValueToRightType(valueBuilder.ToString()); output.Add(value); } -#if DEBUG - DebugNoTime("c", text[i].ToString()); -#endif type = ValueType.List; return output; } @@ -224,9 +200,6 @@ public class DtsodV21 : Dictionary, IDtsod i++; for (; balance != 0; i++) { -#if DEBUG - DebugNoTime("y", text[i].ToString()); -#endif switch (text[i]) { case '"': @@ -234,17 +207,11 @@ public class DtsodV21 : Dictionary, IDtsod break; case '}': balance--; -#if DEBUG - DebugNoTime("b", $"\nbalance -- = {balance}\n"); -#endif if (balance != 0) valueBuilder.Append(text[i]); break; case '{': balance++; -#if DEBUG - DebugNoTime("b", $"\nbalance ++ = {balance}\n"); -#endif valueBuilder.Append(text[i]); break; default: @@ -260,9 +227,6 @@ public class DtsodV21 : Dictionary, IDtsod void ParseValueToRightType(string stringValue) { -#if DEBUG - DebugNoTime("b", $"\nParseValueToRightType({stringValue})\n"); -#endif switch (stringValue) { @@ -318,14 +282,8 @@ public class DtsodV21 : Dictionary, IDtsod } StringBuilder defaultValueBuilder = new(); -#if DEBUG - DebugNoTime("m", "\nReadValue\n"); -#endif for (; i < text.Length; i++) { -#if DEBUG - DebugNoTime("b", text[i].ToString()); -#endif switch (text[i]) { case ' ': @@ -365,10 +323,5 @@ public class DtsodV21 : Dictionary, IDtsod throw new Exception("Dtsod.Parse.ReadValue error: wtf it's the end of function"); } } - -#if DEBUG - static void Debug(params string[] msg) => PublicLog.Log(msg); - static void DebugNoTime(params string[] msg) => PublicLog.LogNoTime(msg); -#endif } diff --git a/Dtsod/DtsodV22.cs b/Dtsod/DtsodV22.cs index 5aa112b..64edd22 100644 --- a/Dtsod/DtsodV22.cs +++ b/Dtsod/DtsodV22.cs @@ -102,9 +102,6 @@ public class DtsodV22 : Dictionary, IDtsod int i = 0; for (; i < text.Length; i++) ReadName(); -#if DEBUG - DebugNoTime("g", $"Parse returns {parsed.Keys.Count} keys\n"); -#endif return new DtsodV22(parsed); // СЛОМАНО @@ -120,9 +117,6 @@ public class DtsodV22 : Dictionary, IDtsod dynamic value; StringBuilder defaultNameBuilder = new(); -#if DEBUG - DebugNoTime("m", "ReadName\n"); -#endif for (; i < text.Length; i++) { switch (text[i]) @@ -136,9 +130,6 @@ public class DtsodV22 : Dictionary, IDtsod i++; string name = defaultNameBuilder.ToString(); value = ReadValue(out ValueTypes type, out bool isList); -#if DEBUG - DebugNoTime("c", $"parsed.Add({name},{type} {value} )\n"); -#endif if (isListElem) { if (!parsed.ContainsKey(name)) @@ -155,9 +146,6 @@ public class DtsodV22 : Dictionary, IDtsod throw new Exception("Parse.ReadName() error: unexpected '}' at " + i + " char"); // если $ перед названием параметра поставить, значение value добавится в лист с названием name case '$': -#if DEBUG - DebugNoTime("w", text[i].ToString()); -#endif if (defaultNameBuilder.ToString().Length != 0) throw new Exception("Parse.ReadName() error: unexpected '$' at " + i + " char"); isListElem = true; @@ -165,9 +153,6 @@ public class DtsodV22 : Dictionary, IDtsod case ';': throw new Exception("Parse.ReadName() error: unexpected ';' at " + i + " char"); default: -#if DEBUG - DebugNoTime("w", text[i].ToString()); -#endif defaultNameBuilder.Append(text[i]); break; } @@ -187,15 +172,9 @@ public class DtsodV22 : Dictionary, IDtsod valueBuilder.Append('"'); for (; text[i] != '"' || text[i - 1] == '\\'; i++) { -#if DEBUG - DebugNoTime("h", text[i].ToString()); -#endif valueBuilder.Append(text[i]); } valueBuilder.Append('"'); -#if DEBUG - DebugNoTime("h", text[i].ToString()); -#endif type = ValueTypes.String; return valueBuilder.ToString(); } @@ -207,9 +186,6 @@ public class DtsodV22 : Dictionary, IDtsod StringBuilder valueBuilder = new(); for (; text[i] != ']'; i++) { -#if DEBUG - DebugNoTime("c", text[i].ToString()); -#endif switch (text[i]) { case ' ': @@ -232,9 +208,6 @@ public class DtsodV22 : Dictionary, IDtsod ParseValueToRightType(valueBuilder.ToString()); output.Add(value); } -#if DEBUG - DebugNoTime("c", text[i].ToString()); -#endif type = ValueTypes.List; return output; } @@ -246,9 +219,6 @@ public class DtsodV22 : Dictionary, IDtsod i++; for (; balance != 0; i++) { -#if DEBUG - DebugNoTime("y", text[i].ToString()); -#endif switch (text[i]) { case '"': @@ -256,17 +226,11 @@ public class DtsodV22 : Dictionary, IDtsod break; case '}': balance--; -#if DEBUG - DebugNoTime("b", $"\nbalance -- = {balance}\n"); -#endif if (balance != 0) valueBuilder.Append(text[i]); break; case '{': balance++; -#if DEBUG - DebugNoTime("b", $"\nbalance ++ = {balance}\n"); -#endif valueBuilder.Append(text[i]); break; default: @@ -281,9 +245,6 @@ public class DtsodV22 : Dictionary, IDtsod void ParseValueToRightType(string stringValue) { -#if DEBUG - DebugNoTime("b", $"\nParseValueToRightType({stringValue})\n"); -#endif switch (stringValue) { @@ -353,14 +314,8 @@ public class DtsodV22 : Dictionary, IDtsod } StringBuilder defaultValueBuilder = new(); -#if DEBUG - DebugNoTime("m", "\nReadValue\n"); -#endif for (; i < text.Length; i++) { -#if DEBUG - DebugNoTime("b", text[i].ToString()); -#endif switch (text[i]) { case ' ': @@ -487,9 +442,4 @@ public class DtsodV22 : Dictionary, IDtsod Add(pair.Key, pair.Value); return this; } - -#if DEBUG - static void Debug(params string[] msg) => PublicLog.Log(msg); - static void DebugNoTime(params string[] msg) => PublicLog.LogNoTime(msg); -#endif } diff --git a/Dtsod/DtsodV23.cs b/Dtsod/DtsodV23.cs index dddab05..d2f27af 100644 --- a/Dtsod/DtsodV23.cs +++ b/Dtsod/DtsodV23.cs @@ -1,4 +1,6 @@ using System.Globalization; +using System.IO; +using System.Linq.Expressions; namespace DTLib.Dtsod; @@ -13,20 +15,22 @@ public class DtsodV23 : DtsodDict, IDtsod public DtsodVersion Version { get; } = DtsodVersion.V30; public IDictionary ToDictionary() => this; - public DtsodV23() : base() => UpdateLazy(); - public DtsodV23(IDictionary dict) : base(dict) => UpdateLazy(); - public DtsodV23(string serialized) : this() => Append(Deserialize(serialized)); + public DtsodV23() : base() {} + public DtsodV23(IDictionary dict) : base(dict) {} + public DtsodV23(string serialized) => Append(Deserialize(serialized)); - static DtsodV23 Deserialize(string text) + static DtsodV23 Deserialize(string _text) { + char[] text = _text.ToArray(); char c; int i = -1; // ++i в ReadName StringBuilder b = new(); Dictionary output = new(); bool partOfDollarList = false; - for (; i < text.Length; i++) + while (i < text.Length) { string name = ReadName(); + if (name == "") goto end; dynamic value = ReadValue(out bool _); if (partOfDollarList) { @@ -39,7 +43,7 @@ public class DtsodV23 : DtsodDict, IDtsod } else output.Add(name, value); } - return new DtsodV23(output); + end:return new DtsodV23(output); string ReadName() { @@ -78,7 +82,9 @@ public class DtsodV23 : DtsodDict, IDtsod } } - throw new Exception("DtsodV23.Deserialize.ReadName() error: end of text\ntext:\n" + text); + return b.Length == 0 + ? "" + : throw new Exception("DtsodV23.Deserialize.ReadName() error: end of text\ntext:\n" + text); } dynamic ReadValue(out bool endOfList) @@ -87,8 +93,12 @@ public class DtsodV23 : DtsodDict, IDtsod void ReadString() { - while ((c != '"' && c != '\'') || (text[i - 1] == '\\' && text[i - 2] != '\\')) + bool prevIsBackslash = false; + b.Append('"'); + c = text[++i]; + while (c != '"' || prevIsBackslash) { + prevIsBackslash = c == '\\' && !prevIsBackslash; b.Append(c); if (++i >= text.Length) throw new Exception("DtsodV23.Deserialize() error: end of text\ntext:\n" + text); c = text[i]; @@ -122,7 +132,6 @@ public class DtsodV23 : DtsodDict, IDtsod b.Append(c); break; case '"': - case '\'': ReadString(); break; default: @@ -134,8 +143,9 @@ public class DtsodV23 : DtsodDict, IDtsod c = text[i]; } + var __text = b.ToString(); b.Clear(); - return Deserialize(b.ToString()); + return Deserialize(__text); } List ReadList() @@ -162,40 +172,48 @@ public class DtsodV23 : DtsodDict, IDtsod return null; default: if (value_str.Contains('"')) - return value_str.Substring(1, value_str.Length - 2); + return value_str.Substring(1, value_str.Length - 2).Replace("\\\\","\\").Replace("\\\"","\""); else if (value_str.Contains('\'')) return value_str[1]; else switch (value_str[value_str.Length - 1]) - { - case 's': - return value_str[value_str.Length - 2] == 'u' - ? value_str.Remove(value_str.Length - 2).ToUShort() - : value_str.Remove(value_str.Length - 1).ToShort(); - case 'u': - return value_str.Remove(value_str.Length - 1).ToUInt(); - case 'i': - return value_str[value_str.Length - 2] == 'u' - ? value_str.Remove(value_str.Length - 2).ToUInt() - : value_str.Remove(value_str.Length - 1).ToInt(); - case 'l': - return value_str[value_str.Length - 2] == 'u' - ? value_str.Remove(value_str.Length - 2).ToULong() - : value_str.Remove(value_str.Length - 1).ToLong(); - case 'b': - return value_str[value_str.Length - 2] == 's' - ? value_str.Remove(value_str.Length - 2).ToSByte() - : value_str.Remove(value_str.Length - 1).ToByte(); - case 'f': - return value_str.Remove(value_str.Length - 1).ToFloat(); - case 'e': - return value_str[value_str.Length - 2] == 'd' - ? value_str.Remove(value_str.Length - 2).ToDecimal() - : throw new Exception("can't parse value:" + value_str); - default: - return value_str.Contains('.') - ? value_str.ToDouble() - : value_str.ToInt(); - } + { + case 's': + return value_str[value_str.Length - 2] == 'u' + ? value_str.Remove(value_str.Length - 2).ToUShort() + : value_str.Remove(value_str.Length - 1).ToShort(); + case 'u': + return value_str.Remove(value_str.Length - 1).ToUInt(); + case 'i': + return value_str[value_str.Length - 2] == 'u' + ? value_str.Remove(value_str.Length - 2).ToUInt() + : value_str.Remove(value_str.Length - 1).ToInt(); + case 'l': + return value_str[value_str.Length - 2] == 'u' + ? value_str.Remove(value_str.Length - 2).ToULong() + : value_str.Remove(value_str.Length - 1).ToLong(); + case 'b': + return value_str[value_str.Length - 2] == 's' + ? value_str.Remove(value_str.Length - 2).ToSByte() + : value_str.Remove(value_str.Length - 1).ToByte(); + case 'f': + return value_str.Remove(value_str.Length - 1).ToFloat(); + case 'e': + return value_str[value_str.Length - 2] == 'd' + ? value_str.Remove(value_str.Length - 2).ToDecimal() + : throw new Exception("can't parse value:" + value_str); + default: + if (value_str.Contains('.')) + return (object)(value_str.ToDouble()); + else + { + try { return (object)(value_str.ToInt()); } + catch (FormatException) + { + Log("r", $"can't parse value: {value_str}"); + return null; + } + } + } }; } @@ -213,9 +231,14 @@ public class DtsodV23 : DtsodDict, IDtsod SkipComment(); break; case '"': - case '\'': ReadString(); break; + case '\'': + b.Append(c).Append(text[++i]); + c = text[++i]; + if (c != '\'') throw new Exception("after <\'> should be char"); + else b.Append(c); + break; case ';': case ',': string str = b.ToString(); @@ -253,7 +276,7 @@ public class DtsodV23 : DtsodDict, IDtsod { { typeof(bool), (val, b) => b.Append(val.ToString()) }, { typeof(char), (val, b) => b.Append('\'').Append(val).Append('\'') }, - { typeof(string), (val, b) => b.Append('"').Append(val).Append('"') }, + { typeof(string), (val, b) => b.Append('"').Append(val.Replace("\\","\\\\").Replace("\"", "\\\"")).Append('"') }, { typeof(byte), (val, b) => b.Append(val.ToString()).Append('b') }, { typeof(sbyte), (val, b) => b.Append(val.ToString()).Append("sb") }, { typeof(short), (val, b) => b.Append(val.ToString()).Append('s') }, @@ -267,7 +290,7 @@ public class DtsodV23 : DtsodDict, IDtsod { typeof(decimal), (val, b) => b.Append(val.ToString(CultureInfo.InvariantCulture)).Append("de") } }; short tabscount = -1; - protected StringBuilder Serialize(IDictionary dtsod, StringBuilder b = null) + protected StringBuilder Serialize(DtsodV23 dtsod, StringBuilder b = null) { tabscount++; if (b is null) b = new StringBuilder(); @@ -279,7 +302,8 @@ public class DtsodV23 : DtsodDict, IDtsod void SerializeType(dynamic value) { - if (value is IList _list) + if (value is null) b.Append("null"); + else if (value is IList _list) { b.Append('['); foreach (object el in _list) @@ -289,20 +313,18 @@ public class DtsodV23 : DtsodDict, IDtsod } b.Remove(b.Length - 1, 1).Append(']'); } - else if (value is IDictionary _dict) + else if (value is DtsodV23 _dtsod) { - b.Append('{'); - Serialize(value, b); + b.Append("{\n"); + Serialize(_dtsod, b); b.Append('}'); } - else b.Append(TypeSerializeFuncs[value.GetType()].Invoke(value, b)); + else TypeSerializeFuncs[value.GetType()].Invoke(value, b); } } tabscount--; return b; } - - protected Lazy serialized; - protected void UpdateLazy() => serialized = new(() => Serialize(this).ToString()); - public override string ToString() => serialized.Value; + + public override string ToString() => Serialize(this).ToString(); }