예제 #1
0
        public NullToken(Tokeniser tokeniser, ObjectId?objectId, bool isErrorNull = false) : base(tokeniser, objectId)
        {
            //null
            if (!isErrorNull)
            {
                var b = tokeniser.SkipWhiteSpace();
                if (b == 'n')
                {
                    b = tokeniser.GetNextByte();
                    if (b == 'u')
                    {
                        b = tokeniser.GetNextByte();
                        if (b == 'l')
                        {
                            b = tokeniser.GetNextByte();
                            if (b == 'l')
                            {
                                tokeniser.GetNextByte();
                                tokeniser.ValidateDelimiter(Tokeniser.ErrorEnum.Bool);
                                return;
                            }
                        }
                    }
                }

                throw tokeniser.Exception($"Null token not valid, should be 'null'. Invalid character: {(char)b}");
            }
        }
예제 #2
0
        public DictionaryToken(Tokeniser tokeniser, ObjectId?objectId) : base(tokeniser, objectId)
        {
            // <<
            //   /Name1 123
            //   /Name2 [(string) (array) 123]
            //   /Name3 <</subDictionaryName1 123 /subDictionaryName2 true>>
            //   /Name4 (another string)
            //   /Name5 <112233EE>
            // >>
            this.tokeniser = tokeniser;
            var b = tokeniser.SkipWhiteSpace();

            if (b != '<' || tokeniser.GetNextByte() != '<')
            {
                throw tokeniser.Exception($"illegal dictionary format, leading characters '<<' expected, but was'{(char)b}{(char)tokeniser.LookaheadByte()}'.");
            }

            //parse key
            tokens = new Dictionary <string, Token>();
            tokeniser.GetNextByte();
            b = tokeniser.SkipWhiteSpace();
            while (b != '>' && tokeniser.LookaheadByte() != '>')
            {
                if (b != '/')
                {
                    throw tokeniser.Exception($"Invalid dictionary format, '/' expected as leading character for dictionary key name, but was {(char)b}.");
                }
                var key   = new NameToken(tokeniser, null);
                var value = tokeniser.GetNextToken();
                if (key.Value == "Type" && value is NameToken typeNameToken)
                {
                    Type = typeNameToken.Value;
                }
                if (tokens.TryGetValue(key.Value, out var existingToken))
                {
                    if (existingToken is ArrayToken existingArrayToken)
                    {
                        existingArrayToken.Add(value);
                    }
                    else
                    {
                        tokens[key.Value] = new ArrayToken(tokeniser, existingToken)
                        {
                            value
                        };
                    }
                }
                else
                {
                    tokens.Add(key.Value, value);
                }
                b = tokeniser.SkipWhiteSpace();
            }
            tokeniser.GetNextByte();
            tokeniser.GetNextByte();

            StreamStartIndex = tokeniser.GetStreamStartIndex(this, out var length);
            Length           = length;
            keys             = tokens.Keys.ToArray();
        }
예제 #3
0
        public ArrayToken(Tokeniser tokeniser, ObjectId?objectId) : base(tokeniser, objectId)
        {
            //[/someName false -0 (string)]
            this.tokeniser = tokeniser;
            tokens         = new List <Token>();
            var b = tokeniser.SkipWhiteSpace();

            if (b != '[')
            {
                throw tokeniser.Exception($"illegal array format, leading character '[' expected but was {(char)b}.");
            }

            b = tokeniser.GetNextByte();
            while (b != ']')
            {
                var token = tokeniser.GetNextToken(isThrowExceptionWhenError: false);
                if (token != null)
                {
                    tokens.Add(token);
                    b = tokeniser.SkipWhiteSpace();
                }
                else
                {
                    b = tokeniser.GetByte();
                    if (b != ']')
                    {
                        throw tokeniser.Exception($"NextToken(): unexpected character '{(char)b}'.");
                    }
                    //we come here when array is empty but has some whitespace
                }
            }
            tokeniser.GetNextByte();
        }
예제 #4
0
        public BoolToken(Tokeniser tokeniser, ObjectId?objectId) : base(tokeniser, objectId)
        {
            //true
            //false
            var b = tokeniser.SkipWhiteSpace();

            if (b == 't')
            {
                b = tokeniser.GetNextByte();
                if (b == 'r')
                {
                    b = tokeniser.GetNextByte();
                    if (b == 'u')
                    {
                        b = tokeniser.GetNextByte();
                        if (b == 'e')
                        {
                            Value = true;
                            tokeniser.GetNextByte();
                            tokeniser.ValidateDelimiter(Tokeniser.ErrorEnum.Bool);
                            return;
                        }
                    }
                }
            }
            else if (b == 'f')
            {
                b = tokeniser.GetNextByte();
                if (b == 'a')
                {
                    b = tokeniser.GetNextByte();
                    if (b == 'l')
                    {
                        b = tokeniser.GetNextByte();
                        if (b == 's')
                        {
                            b = tokeniser.GetNextByte();
                            if (b == 'e')
                            {
                                Value = false;
                                tokeniser.GetNextByte();
                                tokeniser.ValidateDelimiter(Tokeniser.ErrorEnum.Bool);
                                return;
                            }
                        }
                    }
                }
            }
            throw tokeniser.Exception($"Bool not valid, should be 'true' or 'false'. Invalid character: {(char)b}");
        }
예제 #5
0
        public NameToken(Tokeniser tokeniser, ObjectId?objectId) : base(tokeniser, objectId)
        {
            // /Name
            tokeniser.StringBuilder.Clear();
            var b = tokeniser.SkipWhiteSpace();

            if (b != '/')
            {
                throw tokeniser.Exception($"Name format error: First character should be '/' but was '{(char)b}'");
            }

            b = tokeniser.GetNextByte();
            while (!tokeniser.IsDelimiterByte())
            {
                tokeniser.StringBuilder.Append((char)b);
                b = tokeniser.GetNextByte();
            }
            Value = tokeniser.StringBuilder.ToString();
        }
예제 #6
0
        public StringToken(Tokeniser tokeniser, ObjectId?objectId) : base(tokeniser, objectId)
        {
            //(this is a string)
            //(a string can be\r\n on 2 lines or more)
            //(a string can contain ()matched brackets)
            //(a string with an unpaired \( bracket needs a slash before the bracket)
            //<E0F0>
            tokeniser.StringBuilder.Clear();
            var b = tokeniser.SkipWhiteSpace();

            if (b == '(')
            {
                //literal string
                var bracketsCount = 1;
                b = tokeniser.GetNextByte();
                while (true)
                {
                    if (b == '\\')
                    {
                        tokeniser.StringBuilder.Append((char)b);
                        b = tokeniser.GetNextByte();
                    }
                    else
                    {
                        if (b == '(')
                        {
                            bracketsCount++;
                        }
                        else if (b == ')')
                        {
                            bracketsCount--;
                            if (bracketsCount == 0)
                            {
                                break;
                            }
                        }
                    }
                    tokeniser.StringBuilder.Append((char)b);
                    b = tokeniser.GetNextByte();
                }
            }
            else if (b == '<')
            {
                //hexadecimal string
                tokeniser.StringBuilder.Append('<');
                b = tokeniser.GetNextByte();
                while (b != '>')
                {
                    tokeniser.StringBuilder.Append((char)b);
                    b = tokeniser.GetNextByte();
                }
                tokeniser.StringBuilder.Append('>');
            }
            else
            {
                throw tokeniser.Exception($"String format error, '(' or '<' expected as leading character, but was '{(char)b}'.");
            }
            Value = tokeniser.StringBuilder.ToString();
            tokeniser.GetNextByte();
            //tokeniser.ValidateDelimiter(Tokeniser.ErrorEnum.String);
        }
예제 #7
0
        public NumberToken(Tokeniser tokeniser, ObjectId?objectId) : base(tokeniser, objectId)
        {
            //+999999
            //32
            //+0
            //0
            //-0
            //-123
            //+123.4
            //34.5
            //34.
            //+.2
            //.1
            //0.0
            //-.002
            //-3.62
            var     sign    = 1;
            decimal value   = 0;
            var     divider = 0m;
            var     b       = tokeniser.SkipWhiteSpace();

            if (b == '+')
            {
                b = tokeniser.GetNextByte();
            }
            else if (b == '-')
            {
                sign = -1;
                b    = tokeniser.GetNextByte();
            }
            while (true)
            {
                if (b >= '0' && b <= '9')
                {
                    if (divider == 0m)
                    {
                        //so far integer
                        value = 10 * value + b - '0';
                    }
                    else
                    {
                        //decimal point was found
                        value   += (b - '0') / divider;
                        divider *= 10;
                    }
                }
                else if (b == '.')
                {
                    if (divider != 0)
                    {
                        throw tokeniser.Exception($"Reading number error: Second decimal point found.");
                    }
                    divider = 10;
                }
                else
                {
                    break;
                }
                b = tokeniser.GetNextByte();
            }
            Decimal = sign * value;
            if (divider <= 10)
            {
                Integer = (int)Decimal;
            }
            tokeniser.ValidateDelimiter(Tokeniser.ErrorEnum.Number);
        }