bugfixes and optimization of dtsod

This commit is contained in:
Timerix22 2022-01-14 00:02:40 +03:00
parent be5dbfc938
commit 54d9a43e75
3 changed files with 76 additions and 151 deletions

View File

@ -81,9 +81,6 @@ public class DtsodV21 : Dictionary<string, dynamic>, IDtsod
int i = 0; int i = 0;
for (; i < text.Length; i++) for (; i < text.Length; i++)
ReadName(); ReadName();
#if DEBUG
DebugNoTime("g", $"Parse returns {parsed.Keys.Count} keys\n");
#endif
return parsed; return parsed;
// СЛОМАНО // СЛОМАНО
@ -99,9 +96,6 @@ public class DtsodV21 : Dictionary<string, dynamic>, IDtsod
dynamic value; dynamic value;
StringBuilder defaultNameBuilder = new(); StringBuilder defaultNameBuilder = new();
#if DEBUG
DebugNoTime("m", "ReadName\n");
#endif
for (; i < text.Length; i++) for (; i < text.Length; i++)
{ {
switch (text[i]) switch (text[i])
@ -116,7 +110,7 @@ public class DtsodV21 : Dictionary<string, dynamic>, IDtsod
string name = defaultNameBuilder.ToString(); string name = defaultNameBuilder.ToString();
value = ReadValue(); value = ReadValue();
// если value это null, эта строка выдавала ошибку // если value это null, эта строка выдавала ошибку
//DebugNoTime("c", $"parsed.Add({name}, {value} { value.GetType() })\n"); //DebugNoTime("c", $"parsed.Add({name}, {value} { value.GetType() })");
if (isListElem) if (isListElem)
{ {
if (!parsed.ContainsKey(name)) if (!parsed.ContainsKey(name))
@ -134,9 +128,6 @@ public class DtsodV21 : Dictionary<string, dynamic>, IDtsod
throw new Exception("Parse.ReadName() error: unexpected '}' at " + i + " char"); throw new Exception("Parse.ReadName() error: unexpected '}' at " + i + " char");
// если $ перед названием параметра поставить, значение value добавится в лист с названием name // если $ перед названием параметра поставить, значение value добавится в лист с названием name
case '$': case '$':
#if DEBUG
DebugNoTime("w", text[i].ToString());
#endif
if (defaultNameBuilder.ToString().Length != 0) if (defaultNameBuilder.ToString().Length != 0)
throw new Exception("Parse.ReadName() error: unexpected '$' at " + i + " char"); throw new Exception("Parse.ReadName() error: unexpected '$' at " + i + " char");
isListElem = true; isListElem = true;
@ -144,9 +135,6 @@ public class DtsodV21 : Dictionary<string, dynamic>, IDtsod
case ';': case ';':
throw new Exception("Parse.ReadName() error: unexpected ';' at " + i + " char"); throw new Exception("Parse.ReadName() error: unexpected ';' at " + i + " char");
default: default:
#if DEBUG
DebugNoTime("w", text[i].ToString());
#endif
defaultNameBuilder.Append(text[i]); defaultNameBuilder.Append(text[i]);
break; break;
} }
@ -165,15 +153,9 @@ public class DtsodV21 : Dictionary<string, dynamic>, IDtsod
valueBuilder.Append('"'); valueBuilder.Append('"');
for (; text[i] != '"' || text[i - 1] == '\\'; i++) for (; text[i] != '"' || text[i - 1] == '\\'; i++)
{ {
#if DEBUG
DebugNoTime("h", text[i].ToString());
#endif
valueBuilder.Append(text[i]); valueBuilder.Append(text[i]);
} }
valueBuilder.Append('"'); valueBuilder.Append('"');
#if DEBUG
DebugNoTime("h", text[i].ToString());
#endif
type = ValueType.String; type = ValueType.String;
return valueBuilder.ToString(); return valueBuilder.ToString();
} }
@ -185,9 +167,6 @@ public class DtsodV21 : Dictionary<string, dynamic>, IDtsod
StringBuilder valueBuilder = new(); StringBuilder valueBuilder = new();
for (; text[i] != ']'; i++) for (; text[i] != ']'; i++)
{ {
#if DEBUG
DebugNoTime("c", text[i].ToString());
#endif
switch (text[i]) switch (text[i])
{ {
case ' ': case ' ':
@ -210,9 +189,6 @@ public class DtsodV21 : Dictionary<string, dynamic>, IDtsod
ParseValueToRightType(valueBuilder.ToString()); ParseValueToRightType(valueBuilder.ToString());
output.Add(value); output.Add(value);
} }
#if DEBUG
DebugNoTime("c", text[i].ToString());
#endif
type = ValueType.List; type = ValueType.List;
return output; return output;
} }
@ -224,9 +200,6 @@ public class DtsodV21 : Dictionary<string, dynamic>, IDtsod
i++; i++;
for (; balance != 0; i++) for (; balance != 0; i++)
{ {
#if DEBUG
DebugNoTime("y", text[i].ToString());
#endif
switch (text[i]) switch (text[i])
{ {
case '"': case '"':
@ -234,17 +207,11 @@ public class DtsodV21 : Dictionary<string, dynamic>, IDtsod
break; break;
case '}': case '}':
balance--; balance--;
#if DEBUG
DebugNoTime("b", $"\nbalance -- = {balance}\n");
#endif
if (balance != 0) if (balance != 0)
valueBuilder.Append(text[i]); valueBuilder.Append(text[i]);
break; break;
case '{': case '{':
balance++; balance++;
#if DEBUG
DebugNoTime("b", $"\nbalance ++ = {balance}\n");
#endif
valueBuilder.Append(text[i]); valueBuilder.Append(text[i]);
break; break;
default: default:
@ -260,9 +227,6 @@ public class DtsodV21 : Dictionary<string, dynamic>, IDtsod
void ParseValueToRightType(string stringValue) void ParseValueToRightType(string stringValue)
{ {
#if DEBUG
DebugNoTime("b", $"\nParseValueToRightType({stringValue})\n");
#endif
switch (stringValue) switch (stringValue)
{ {
@ -318,14 +282,8 @@ public class DtsodV21 : Dictionary<string, dynamic>, IDtsod
} }
StringBuilder defaultValueBuilder = new(); StringBuilder defaultValueBuilder = new();
#if DEBUG
DebugNoTime("m", "\nReadValue\n");
#endif
for (; i < text.Length; i++) for (; i < text.Length; i++)
{ {
#if DEBUG
DebugNoTime("b", text[i].ToString());
#endif
switch (text[i]) switch (text[i])
{ {
case ' ': case ' ':
@ -365,10 +323,5 @@ public class DtsodV21 : Dictionary<string, dynamic>, IDtsod
throw new Exception("Dtsod.Parse.ReadValue error: wtf it's the end of function"); 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
} }

View File

@ -102,9 +102,6 @@ public class DtsodV22 : Dictionary<string, DtsodV22.ValueStruct>, IDtsod
int i = 0; int i = 0;
for (; i < text.Length; i++) for (; i < text.Length; i++)
ReadName(); ReadName();
#if DEBUG
DebugNoTime("g", $"Parse returns {parsed.Keys.Count} keys\n");
#endif
return new DtsodV22(parsed); return new DtsodV22(parsed);
// СЛОМАНО // СЛОМАНО
@ -120,9 +117,6 @@ public class DtsodV22 : Dictionary<string, DtsodV22.ValueStruct>, IDtsod
dynamic value; dynamic value;
StringBuilder defaultNameBuilder = new(); StringBuilder defaultNameBuilder = new();
#if DEBUG
DebugNoTime("m", "ReadName\n");
#endif
for (; i < text.Length; i++) for (; i < text.Length; i++)
{ {
switch (text[i]) switch (text[i])
@ -136,9 +130,6 @@ public class DtsodV22 : Dictionary<string, DtsodV22.ValueStruct>, IDtsod
i++; i++;
string name = defaultNameBuilder.ToString(); string name = defaultNameBuilder.ToString();
value = ReadValue(out ValueTypes type, out bool isList); value = ReadValue(out ValueTypes type, out bool isList);
#if DEBUG
DebugNoTime("c", $"parsed.Add({name},{type} {value} )\n");
#endif
if (isListElem) if (isListElem)
{ {
if (!parsed.ContainsKey(name)) if (!parsed.ContainsKey(name))
@ -155,9 +146,6 @@ public class DtsodV22 : Dictionary<string, DtsodV22.ValueStruct>, IDtsod
throw new Exception("Parse.ReadName() error: unexpected '}' at " + i + " char"); throw new Exception("Parse.ReadName() error: unexpected '}' at " + i + " char");
// если $ перед названием параметра поставить, значение value добавится в лист с названием name // если $ перед названием параметра поставить, значение value добавится в лист с названием name
case '$': case '$':
#if DEBUG
DebugNoTime("w", text[i].ToString());
#endif
if (defaultNameBuilder.ToString().Length != 0) if (defaultNameBuilder.ToString().Length != 0)
throw new Exception("Parse.ReadName() error: unexpected '$' at " + i + " char"); throw new Exception("Parse.ReadName() error: unexpected '$' at " + i + " char");
isListElem = true; isListElem = true;
@ -165,9 +153,6 @@ public class DtsodV22 : Dictionary<string, DtsodV22.ValueStruct>, IDtsod
case ';': case ';':
throw new Exception("Parse.ReadName() error: unexpected ';' at " + i + " char"); throw new Exception("Parse.ReadName() error: unexpected ';' at " + i + " char");
default: default:
#if DEBUG
DebugNoTime("w", text[i].ToString());
#endif
defaultNameBuilder.Append(text[i]); defaultNameBuilder.Append(text[i]);
break; break;
} }
@ -187,15 +172,9 @@ public class DtsodV22 : Dictionary<string, DtsodV22.ValueStruct>, IDtsod
valueBuilder.Append('"'); valueBuilder.Append('"');
for (; text[i] != '"' || text[i - 1] == '\\'; i++) for (; text[i] != '"' || text[i - 1] == '\\'; i++)
{ {
#if DEBUG
DebugNoTime("h", text[i].ToString());
#endif
valueBuilder.Append(text[i]); valueBuilder.Append(text[i]);
} }
valueBuilder.Append('"'); valueBuilder.Append('"');
#if DEBUG
DebugNoTime("h", text[i].ToString());
#endif
type = ValueTypes.String; type = ValueTypes.String;
return valueBuilder.ToString(); return valueBuilder.ToString();
} }
@ -207,9 +186,6 @@ public class DtsodV22 : Dictionary<string, DtsodV22.ValueStruct>, IDtsod
StringBuilder valueBuilder = new(); StringBuilder valueBuilder = new();
for (; text[i] != ']'; i++) for (; text[i] != ']'; i++)
{ {
#if DEBUG
DebugNoTime("c", text[i].ToString());
#endif
switch (text[i]) switch (text[i])
{ {
case ' ': case ' ':
@ -232,9 +208,6 @@ public class DtsodV22 : Dictionary<string, DtsodV22.ValueStruct>, IDtsod
ParseValueToRightType(valueBuilder.ToString()); ParseValueToRightType(valueBuilder.ToString());
output.Add(value); output.Add(value);
} }
#if DEBUG
DebugNoTime("c", text[i].ToString());
#endif
type = ValueTypes.List; type = ValueTypes.List;
return output; return output;
} }
@ -246,9 +219,6 @@ public class DtsodV22 : Dictionary<string, DtsodV22.ValueStruct>, IDtsod
i++; i++;
for (; balance != 0; i++) for (; balance != 0; i++)
{ {
#if DEBUG
DebugNoTime("y", text[i].ToString());
#endif
switch (text[i]) switch (text[i])
{ {
case '"': case '"':
@ -256,17 +226,11 @@ public class DtsodV22 : Dictionary<string, DtsodV22.ValueStruct>, IDtsod
break; break;
case '}': case '}':
balance--; balance--;
#if DEBUG
DebugNoTime("b", $"\nbalance -- = {balance}\n");
#endif
if (balance != 0) if (balance != 0)
valueBuilder.Append(text[i]); valueBuilder.Append(text[i]);
break; break;
case '{': case '{':
balance++; balance++;
#if DEBUG
DebugNoTime("b", $"\nbalance ++ = {balance}\n");
#endif
valueBuilder.Append(text[i]); valueBuilder.Append(text[i]);
break; break;
default: default:
@ -281,9 +245,6 @@ public class DtsodV22 : Dictionary<string, DtsodV22.ValueStruct>, IDtsod
void ParseValueToRightType(string stringValue) void ParseValueToRightType(string stringValue)
{ {
#if DEBUG
DebugNoTime("b", $"\nParseValueToRightType({stringValue})\n");
#endif
switch (stringValue) switch (stringValue)
{ {
@ -353,14 +314,8 @@ public class DtsodV22 : Dictionary<string, DtsodV22.ValueStruct>, IDtsod
} }
StringBuilder defaultValueBuilder = new(); StringBuilder defaultValueBuilder = new();
#if DEBUG
DebugNoTime("m", "\nReadValue\n");
#endif
for (; i < text.Length; i++) for (; i < text.Length; i++)
{ {
#if DEBUG
DebugNoTime("b", text[i].ToString());
#endif
switch (text[i]) switch (text[i])
{ {
case ' ': case ' ':
@ -487,9 +442,4 @@ public class DtsodV22 : Dictionary<string, DtsodV22.ValueStruct>, IDtsod
Add(pair.Key, pair.Value); Add(pair.Key, pair.Value);
return this; return this;
} }
#if DEBUG
static void Debug(params string[] msg) => PublicLog.Log(msg);
static void DebugNoTime(params string[] msg) => PublicLog.LogNoTime(msg);
#endif
} }

View File

@ -1,4 +1,6 @@
using System.Globalization; using System.Globalization;
using System.IO;
using System.Linq.Expressions;
namespace DTLib.Dtsod; namespace DTLib.Dtsod;
@ -13,20 +15,22 @@ public class DtsodV23 : DtsodDict<string, dynamic>, IDtsod
public DtsodVersion Version { get; } = DtsodVersion.V30; public DtsodVersion Version { get; } = DtsodVersion.V30;
public IDictionary<string, dynamic> ToDictionary() => this; public IDictionary<string, dynamic> ToDictionary() => this;
public DtsodV23() : base() => UpdateLazy(); public DtsodV23() : base() {}
public DtsodV23(IDictionary<string, dynamic> dict) : base(dict) => UpdateLazy(); public DtsodV23(IDictionary<string, dynamic> dict) : base(dict) {}
public DtsodV23(string serialized) : this() => Append(Deserialize(serialized)); public DtsodV23(string serialized) => Append(Deserialize(serialized));
static DtsodV23 Deserialize(string text) static DtsodV23 Deserialize(string _text)
{ {
char[] text = _text.ToArray();
char c; char c;
int i = -1; // ++i в ReadName int i = -1; // ++i в ReadName
StringBuilder b = new(); StringBuilder b = new();
Dictionary<string, dynamic> output = new(); Dictionary<string, dynamic> output = new();
bool partOfDollarList = false; bool partOfDollarList = false;
for (; i < text.Length; i++) while (i < text.Length)
{ {
string name = ReadName(); string name = ReadName();
if (name == "") goto end;
dynamic value = ReadValue(out bool _); dynamic value = ReadValue(out bool _);
if (partOfDollarList) if (partOfDollarList)
{ {
@ -39,7 +43,7 @@ public class DtsodV23 : DtsodDict<string, dynamic>, IDtsod
} }
else output.Add(name, value); else output.Add(name, value);
} }
return new DtsodV23(output); end:return new DtsodV23(output);
string ReadName() string ReadName()
{ {
@ -78,7 +82,9 @@ public class DtsodV23 : DtsodDict<string, dynamic>, 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) dynamic ReadValue(out bool endOfList)
@ -87,8 +93,12 @@ public class DtsodV23 : DtsodDict<string, dynamic>, IDtsod
void ReadString() 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); b.Append(c);
if (++i >= text.Length) throw new Exception("DtsodV23.Deserialize() error: end of text\ntext:\n" + text); if (++i >= text.Length) throw new Exception("DtsodV23.Deserialize() error: end of text\ntext:\n" + text);
c = text[i]; c = text[i];
@ -122,7 +132,6 @@ public class DtsodV23 : DtsodDict<string, dynamic>, IDtsod
b.Append(c); b.Append(c);
break; break;
case '"': case '"':
case '\'':
ReadString(); ReadString();
break; break;
default: default:
@ -134,8 +143,9 @@ public class DtsodV23 : DtsodDict<string, dynamic>, IDtsod
c = text[i]; c = text[i];
} }
var __text = b.ToString();
b.Clear(); b.Clear();
return Deserialize(b.ToString()); return Deserialize(__text);
} }
List<dynamic> ReadList() List<dynamic> ReadList()
@ -162,7 +172,7 @@ public class DtsodV23 : DtsodDict<string, dynamic>, IDtsod
return null; return null;
default: default:
if (value_str.Contains('"')) 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('\'')) else if (value_str.Contains('\''))
return value_str[1]; return value_str[1];
else switch (value_str[value_str.Length - 1]) else switch (value_str[value_str.Length - 1])
@ -192,9 +202,17 @@ public class DtsodV23 : DtsodDict<string, dynamic>, IDtsod
? value_str.Remove(value_str.Length - 2).ToDecimal() ? value_str.Remove(value_str.Length - 2).ToDecimal()
: throw new Exception("can't parse value:" + value_str); : throw new Exception("can't parse value:" + value_str);
default: default:
return value_str.Contains('.') if (value_str.Contains('.'))
? value_str.ToDouble() return (object)(value_str.ToDouble());
: value_str.ToInt(); 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<string, dynamic>, IDtsod
SkipComment(); SkipComment();
break; break;
case '"': case '"':
case '\'':
ReadString(); ReadString();
break; 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 ';':
case ',': case ',':
string str = b.ToString(); string str = b.ToString();
@ -253,7 +276,7 @@ public class DtsodV23 : DtsodDict<string, dynamic>, IDtsod
{ {
{ typeof(bool), (val, b) => b.Append(val.ToString()) }, { typeof(bool), (val, b) => b.Append(val.ToString()) },
{ typeof(char), (val, b) => b.Append('\'').Append(val).Append('\'') }, { 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(byte), (val, b) => b.Append(val.ToString()).Append('b') },
{ typeof(sbyte), (val, b) => b.Append(val.ToString()).Append("sb") }, { typeof(sbyte), (val, b) => b.Append(val.ToString()).Append("sb") },
{ typeof(short), (val, b) => b.Append(val.ToString()).Append('s') }, { typeof(short), (val, b) => b.Append(val.ToString()).Append('s') },
@ -267,7 +290,7 @@ public class DtsodV23 : DtsodDict<string, dynamic>, IDtsod
{ typeof(decimal), (val, b) => b.Append(val.ToString(CultureInfo.InvariantCulture)).Append("de") } { typeof(decimal), (val, b) => b.Append(val.ToString(CultureInfo.InvariantCulture)).Append("de") }
}; };
short tabscount = -1; short tabscount = -1;
protected StringBuilder Serialize(IDictionary<string, dynamic> dtsod, StringBuilder b = null) protected StringBuilder Serialize(DtsodV23 dtsod, StringBuilder b = null)
{ {
tabscount++; tabscount++;
if (b is null) b = new StringBuilder(); if (b is null) b = new StringBuilder();
@ -279,7 +302,8 @@ public class DtsodV23 : DtsodDict<string, dynamic>, IDtsod
void SerializeType(dynamic value) void SerializeType(dynamic value)
{ {
if (value is IList _list) if (value is null) b.Append("null");
else if (value is IList _list)
{ {
b.Append('['); b.Append('[');
foreach (object el in _list) foreach (object el in _list)
@ -289,20 +313,18 @@ public class DtsodV23 : DtsodDict<string, dynamic>, IDtsod
} }
b.Remove(b.Length - 1, 1).Append(']'); b.Remove(b.Length - 1, 1).Append(']');
} }
else if (value is IDictionary _dict) else if (value is DtsodV23 _dtsod)
{ {
b.Append('{'); b.Append("{\n");
Serialize(value, b); Serialize(_dtsod, b);
b.Append('}'); b.Append('}');
} }
else b.Append(TypeSerializeFuncs[value.GetType()].Invoke(value, b)); else TypeSerializeFuncs[value.GetType()].Invoke(value, b);
} }
} }
tabscount--; tabscount--;
return b; return b;
} }
protected Lazy<string> serialized; public override string ToString() => Serialize(this).ToString();
protected void UpdateLazy() => serialized = new(() => Serialize(this).ToString());
public override string ToString() => serialized.Value;
} }