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);
        }
Exemple #2
0
        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);
        }