private static void ThrowException(this IMyMemory byteArray, int position) { var i = position - 10; if (i < 0) { i = 0; } var str = Encoding.UTF8.GetString(byteArray.Slice(i, position - i).Span); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(str); Console.ResetColor(); throw new Exception("Invalid Json at position: " + str); }
public static DynamicEntity ParseDynamicEntity( this IMyMemory inData) { var result = new Dictionary <string, IJsonFirstLine>(); var expectedToken = ExpectedToken.OpenBracket; var subObjectLevel = 0; var subObjectString = false; var keyStartIndex = 0; var keyEndIndex = 0; var valueStartIndex = 0; var skipItems = 0; foreach (var(b, index) in inData.Enumerate()) { if (skipItems > 0) { skipItems--; continue; } if (expectedToken == ExpectedToken.EndOfFile) { break; } switch (expectedToken) { case ExpectedToken.OpenBracket: if (b.IsSpace()) { continue; } if (b != OpenBracket) { inData.ThrowException(index); } expectedToken = ExpectedToken.OpenKey; break; case ExpectedToken.OpenKey: if (b == CloseBracket) { expectedToken = ExpectedToken.EndOfFile; break; } if (b.IsSpace()) { continue; } if (b != DoubleQuote) { inData.ThrowException(index); } keyStartIndex = index; expectedToken = ExpectedToken.CloseKey; break; case ExpectedToken.CloseKey: switch (b) { case EscSymbol: skipItems++; break; case DoubleQuote: keyEndIndex = index + 1; expectedToken = ExpectedToken.DoubleColumn; break; } break; case ExpectedToken.DoubleColumn: if (b.IsSpace()) { continue; } if (b != DoubleColumn) { inData.ThrowException(index); } expectedToken = ExpectedToken.OpenValue; break; case ExpectedToken.OpenValue: if (b.IsSpace()) { continue; } valueStartIndex = index; switch (b) { case OpenArray: expectedToken = ExpectedToken.CloseArray; break; case DoubleQuote: expectedToken = ExpectedToken.CloseStringValue; break; case OpenBracket: subObjectLevel = 0; subObjectString = false; expectedToken = ExpectedToken.CloseObject; break; default: { if (StartOfDigit.ContainsKey((char)b) || b.IsStartOfBool()) { expectedToken = ExpectedToken.CloseNumberOrBoolValue; } else { inData.ThrowException(index); } break; } } break; case ExpectedToken.CloseStringValue: switch (b) { case EscSymbol: skipItems++; break; case DoubleQuote: var item = new MyJsonFirstLevelFieldData( inData.Slice(keyStartIndex, keyEndIndex - keyStartIndex), inData.Slice(valueStartIndex, index + 1 - valueStartIndex)); result.Add(item.Name, item); expectedToken = ExpectedToken.Comma; break; } break; case ExpectedToken.CloseNumberOrBoolValue: if (b == Comma || b == CloseBracket || b.IsSpace()) { var item = new MyJsonFirstLevelFieldData( inData.Slice(keyStartIndex, keyEndIndex - keyStartIndex), inData.Slice(valueStartIndex, index - valueStartIndex)); result.Add(item.Name, item); if (b == CloseBracket) { expectedToken = ExpectedToken.EndOfFile; } else { expectedToken = b == Comma ? ExpectedToken.OpenKey : ExpectedToken.Comma; } } break; case ExpectedToken.Comma: if (b.IsSpace()) { continue; } if (b == CloseBracket) { expectedToken = ExpectedToken.EndOfFile; continue; } if (b != Comma) { inData.ThrowException(index); } expectedToken = ExpectedToken.OpenKey; continue; case ExpectedToken.CloseObject: if (subObjectString) { switch (b) { case EscSymbol: skipItems++; continue; case DoubleQuote: subObjectString = false; break; } } else { switch (b) { case DoubleQuote: subObjectString = true; continue; case OpenBracket: subObjectLevel++; continue; case CloseBracket when subObjectLevel == 0: var item = new MyJsonFirstLevelFieldData( inData.Slice(keyStartIndex, keyEndIndex - keyStartIndex), inData.Slice(valueStartIndex, index + 1 - valueStartIndex)); result.Add(item.Name, item); expectedToken = ExpectedToken.Comma; break; case CloseBracket: subObjectLevel--; break; } } break; case ExpectedToken.CloseArray: if (subObjectString) { switch (b) { case EscSymbol: skipItems++; continue; case DoubleQuote: subObjectString = false; break; } } else { switch (b) { case DoubleQuote: subObjectString = true; continue; case OpenArray: subObjectLevel++; continue; case CloseArray when subObjectLevel == 0: var item = new MyJsonFirstLevelFieldData( inData.Slice(keyStartIndex, keyEndIndex - keyStartIndex), inData.Slice(valueStartIndex, index + 1 - valueStartIndex)); result.Add(item.Name, item); expectedToken = ExpectedToken.Comma; break; case CloseArray: subObjectLevel--; break; } } break; } } if (expectedToken != ExpectedToken.EndOfFile) { throw new Exception("Invalid Json"); } return(new DynamicEntity(result)); }