private bool P_Step() { bool r = P_Position < _input.Length; if (r) { char c = _input[P_Position]; int TableStackUBound = P_TableStack.Count - 1; P_TableLevel CurrentTable = null; bool EndingBlock = false; if (P_TableStack.Count > 0) { CurrentTable = P_TableStack[TableStackUBound]; } // To know when to end a stream block #region BlockEnder if (c == '|') { P_FailSafeEndCharCount++; if (!P_CharEscapedInString) { P_EndCharCount++; } if (P_EndCharCount == 2 | P_FailSafeEndCharCount == 2) { EndingBlock = true; } } else { if (P_EndCharCount == 1) { P_ThrowError(1); } P_FailSafeEndCharCount = 0; P_EndCharCount = 0; } #endregion if (P_ErrorCode == 0) // If no error then... { bool CharIsHandled = false; bool String_IsFirstBracket = false; #region Value Type Determiner if (P_ValueParser_ValueType == -1) { switch (c) { case 'T': case 'F': P_ValueParser_ValueType = 1; // Boolean CharIsHandled = true; break; case 'N': P_ValueParser_ValueType = 0; // null CharIsHandled = true; break; case '\"': P_ValueParser_ValueType = 4; // String String_IsFirstBracket = true; P_ValueParser_StringMode = true; CharIsHandled = true; break; case '[': P_TableLevel NewTableLevel = new P_TableLevel(); NewTableLevel.Table = new TableValue(); P_TableStack.Add(NewTableLevel); CharIsHandled = true; break; default: if (P_IsCharNumber(c)) { P_ValueParser_ValueType = 2; // Int CharIsHandled = true; } break; } } #endregion #region Value Extractor // Parse the value. if (P_ValueParser_ValueType >= 0) { switch (P_ValueParser_ValueType) { case 0: // null case 1: // Boolean if (P_ValueParser_ValueRaw.Length == 0) { P_ValueParser_ValueRaw.Append(c); } else { IAbstractValue o = null; switch (P_ValueParser_ValueRaw[0]) { case 'N': o = null; break; default: o = new BooleanValue(P_ValueParser_ValueRaw[0] == 'T'); break; } P_ValueParser_OutputValue(o); } CharIsHandled = true; break; case 2: // Int case 3: // Float if (P_IsCharNumber(c)) { P_ValueParser_ValueRaw.Append(c); } else if (c == '.') { if (P_ValueParser_ValueType == 2) { P_ValueParser_ValueType = 3; P_ValueParser_ValueRaw.Append(c); } else { P_ThrowError(1); // There should not be two decimals in the same number. } } else if (P_ValueParser_ValueType == 2) { P_ValueParser_OutputValue(new IntValue(int.Parse(P_ValueParser_ValueRaw.ToString()))); } else if (P_ValueParser_ValueType == 3) { P_ValueParser_OutputValue(new FloatValue(JsEncoder_Type_Float.Parse(P_ValueParser_ValueRaw.ToString()))); } CharIsHandled = true; break; case 4: // String if (P_ValueParser_StringMode) { bool String_RecordChar = true; // False to avoid recording current character into a string. if (!P_CharEscapedInString) { if (c == '\\') { String_RecordChar = false; P_CharEscapedInString = true; } else if (c == '\"') { String_RecordChar = false; if (!String_IsFirstBracket) { P_ValueParser_StringMode = false; P_ValueParser_OutputValue(new StringValue(P_ValueParser_ValueRaw.ToString())); } } } else { P_CharEscapedInString = false; } if (String_RecordChar) { P_ValueParser_ValueRaw.Append(c); } } CharIsHandled = true; break; } } #endregion #region Table Parser if (!P_ValueParser_StringMode && CurrentTable != null) // Only process these when not in a string. { int EndType = 0; switch (c) { case ':': if (!CurrentTable.PairHasCustomKey) { CurrentTable.PairHasCustomKey = true; CurrentTable.V1 = P_ValueParser_TakeValue(); P_ValueParser_ValueType = -1; } else { P_ThrowError(1); } CharIsHandled = true; break; case ']': EndType = 2; CharIsHandled = true; break; case ';': EndType = 1; CharIsHandled = true; break; } if (EndType > 0) { if (P_ValueParser_ValueType != -1) { CurrentTable.V2 = P_ValueParser_TakeValue(); if (CurrentTable.V2 != null) { if (CurrentTable.V1 != null) { CurrentTable.Table[CurrentTable.V1] = CurrentTable.V2; } else { CurrentTable.IndexingUBound++; CurrentTable.Table[CurrentTable.IndexingUBound] = CurrentTable.V2; } } } // Clear these so we can use them later. CurrentTable.V1 = null; CurrentTable.V2 = null; CurrentTable.PairHasCustomKey = false; if (EndType == 2) { // Close table and go back up. P_TableStack.RemoveAt(TableStackUBound); P_ValueParser_OutputValue(CurrentTable.Table); P_ValueParser_ValueType = -2; } else //if (EndType == 1) { P_ValueParser_ValueType = -1; } } } #endregion #region Character Ignore Handler if (!CharIsHandled && (c == ' ' | c == '|' | c == '\n')) { CharIsHandled = true; } #endregion // If nothing handled this character, it must be an error. if (!CharIsHandled) { P_ThrowError(1); } } P_Position++; if (EndingBlock) { P_EndBlock(); } } return(r); }
private bool P_Step() { bool result = (P_Position < _input.Length); if (result) { char c = _input[P_Position]; int TableStackUBound = P_TableStack.Count - 1; P_TableLevel CurrentTable = null; bool EndingBlock = false; if (P_TableStack.Count > 0) { CurrentTable = P_TableStack[TableStackUBound]; } // To know when to end a stream block #region BlockEnder if (c == '|' && !P_EscapedInString) { P_FailSafeEndCharCount++; if (!P_EscapedInString) { P_EndCharCount++; } if (P_EndCharCount == 2 | P_FailSafeEndCharCount == 2) { EndingBlock = true; } } else { if (P_EndCharCount == 1) { P_ThrowError(1); } P_FailSafeEndCharCount = 0; P_EndCharCount = 0; } #endregion if (P_ErrorCode == 0) // Don't permit other processes if there is an error. { bool CIsUnhandled = true; bool String_IsFirstBracket = false; #region ValueTypeDeterminer if (!P_ValueParser_StringMode) { bool handled2 = true; if (P_ValueParser_ValueType == -1) { // What type is this value? switch (c) { case 'T': case 'F': P_ValueParser_ValueType = 1; // Boolean break; case 'N': P_ValueParser_ValueType = 0; // nullptr break; case '\"': P_ValueParser_ValueType = 4; // String String_IsFirstBracket = true; P_ValueParser_StringMode = true; break; case '[': P_TableStack.Add(new P_TableLevel() { Table = new TableDigested() }); break; default: if (P_IsCharNumber(c)) { P_ValueParser_ValueType = 2; // Int } else { handled2 = false; } break; } } if (handled2) { CIsUnhandled = false; } } #endregion // Parse the value. #region ValueExtractor if (P_ValueParser_ValueType >= 0) { bool handled = true; switch (P_ValueParser_ValueType) { case 0: // nullptr or case 1: // Boolean if (P_ValueParser_ValueRaw.Length == 0) { P_ValueParser_ValueRaw.Append(c); } else { ValueBase o = null; switch (P_ValueParser_ValueRaw[0]) { case 'N': o = null; break; default: o = new BooleanValue(P_ValueParser_ValueRaw[0] == 'T'); break; } P_ValueParser_OutputValue(o); } break; case 2: // Int case 3: // Float if (P_IsCharNumber(c)) { P_ValueParser_ValueRaw.Append(c); } else if (c == '.') { if (P_ValueParser_ValueType == 2) { P_ValueParser_ValueType = 3; P_ValueParser_ValueRaw.Append(c); } else { P_ThrowError(1); } } else { switch (P_ValueParser_ValueType) { case 2: P_ValueParser_OutputValue(new IntValue(int.Parse(P_ValueParser_ValueRaw.ToString()))); break; case 3: P_ValueParser_OutputValue(new FloatValue(double.Parse(P_ValueParser_ValueRaw.ToString()))); break; } } break; case 4: // String if (P_ValueParser_StringMode) { bool String_RecordChar = true; // False to avoid recording current character into a string. if (!P_EscapedInString) { if (c == '\\') { P_EscapedInString = true; String_RecordChar = false; } if (c == '\"') { if (!String_IsFirstBracket) { P_ValueParser_StringMode = false; String_RecordChar = false; P_ValueParser_OutputValue(new StringValue(P_ValueParser_ValueRaw.ToString())); } else { String_RecordChar = false; } } } else { P_EscapedInString = false; } if (String_RecordChar) { P_ValueParser_ValueRaw.Append(c); } } break; default: handled = false; break; } if (handled) { CIsUnhandled = false; } } #endregion #region TableChars // Table-Specific if (!P_ValueParser_StringMode) // Only process these when not in a string. { if (CurrentTable != null) { bool handled1 = true; int EndType = 0; // 1 = Finish value and ready for next. 2 = Finish value and table. switch (c) { case ':': if (!CurrentTable.PairHasCustomKey) { CurrentTable.PairHasCustomKey = true; CurrentTable.V1 = P_ValueParser_TakeValue(); P_ValueParser_ValueType = -1; } else { P_ThrowError(1); } break; case ']': EndType = 2; break; case ';': EndType = 1; break; default: handled1 = false; break; } if (EndType > 0) { if (P_ValueParser_ValueType != -1) { CurrentTable.V2 = P_ValueParser_TakeValue(); ValueBase V1 = CurrentTable.V1; ValueBase V2 = CurrentTable.V2; if (V2 != null) { if (V1 != null) { if (CurrentTable.V1.GetValueType() == ValueType.Int) { CurrentTable.Table.ManualIntDictionary.Add(((IntValue)V1).Value, V2); } else { CurrentTable.Table.MiscKeyDictionary.Add(V1, V2); } } else { CurrentTable.Table.AutoIntArray.Add(V2); } } } // Clear these so we can use them later. CurrentTable.V1 = null; CurrentTable.V2 = null; CurrentTable.PairHasCustomKey = false; if (EndType == 2) { // Close table and go back up. P_TableStack.RemoveAt(TableStackUBound); P_ValueParser_OutputValue(CurrentTable.Table.ToTable()); P_ValueParser_ValueType = -2; } else //if (EndType == 1) { P_ValueParser_ValueType = -1; } } if (handled1) { CIsUnhandled = false; } } } #endregion // If nothing handled this character, it must be invalid. if (CIsUnhandled) { if (c == ' ' | c == '|') // Ignore spaces in this case. { CIsUnhandled = false; } else { P_ThrowError(1); } } } P_Position++; if (EndingBlock) { P_EndBlock(); } } return(result); }