Пример #1
0
        public static IEnumerable <Utf8String> Split(this Utf8String src, byte delemeter)
        {
            var start = 0;
            var p     = new Utf8Iterator(src.Bytes);

            while (p.MoveNext())
            {
                if (p.Current == delemeter)
                {
                    if (p.BytePosition - start == 0)
                    {
                        yield return(default(Utf8String));
                    }
                    else
                    {
                        yield return(src.Subbytes(start, p.BytePosition - start));
                    }
                    start = p.BytePosition + 1;
                }
            }

            if (start < p.BytePosition)
            {
                yield return(src.Subbytes(start, p.BytePosition - start));
            }
        }
Пример #2
0
        /// <summary>
        /// Split integer from start
        ///
        /// "123 " => "123"
        /// " 123" => FormatException
        ///
        /// must start +-0123456789
        ///
        /// </summary>
        /// <param name="src"></param>
        /// <returns></returns>
        public static Utf8String SplitInteger(this Utf8String src)
        {
            var i = 0;

            if (src[0] == '+' || src[0] == '-')
            {
                ++i;
            }

            var j = i;

            for (; j < src.ByteLength; ++j)
            {
                if (src[j] < '0' || src[j] > '9')
                {
                    break;
                }
            }

            if (i == j)
            {
                throw new FormatException();
            }

            return(src.Subbytes(0, j));
        }
Пример #3
0
        public static Utf8String GetLine(this Utf8String src)
        {
            int pos;

            if (!src.TrySearchAscii((byte)'\n', 0, out pos))
            {
                return(src);
            }

            return(src.Subbytes(0, pos + 1));
        }
Пример #4
0
        static JsonTreeNode ParseString(JsonTreeNode tree, Utf8String segment)
        {
            int pos;

            if (segment.TrySearchAscii((Byte)'"', 1, out pos))
            {
                return(tree.AddValue(segment.Subbytes(0, pos + 1).Bytes, ValueNodeType.String));
            }
            else
            {
                throw new ParserException("no close string: " + segment);
            }
        }
Пример #5
0
        public static Utf8String Unquote(Utf8String src)
        {
            var count = Unquote(src, null);

            if (count == src.ByteLength - 2)
            {
                return(src.Subbytes(1, src.ByteLength - 2));
            }
            else
            {
                var sb = new BytesStore(count);
                Unquote(src, sb);
                return(new Utf8String(sb.Bytes));
            }
        }
Пример #6
0
        /// <summary>
        /// Expected null, boolean, integer, number
        /// </summary>
        /// <param name="segment"></param>
        /// <param name="valueType"></param>
        /// <param name="parentIndex"></param>
        /// <returns></returns>
        static JsonTreeNode ParsePrimitive(JsonTreeNode tree, Utf8String segment, ValueNodeType valueType)
        {
            int i = 1;

            for (; i < segment.ByteLength; ++i)
            {
                if (Char.IsWhiteSpace((char)segment[i]) ||
                    segment[i] == '}' ||
                    segment[i] == ']' ||
                    segment[i] == ',' ||
                    segment[i] == ':'
                    )
                {
                    break;
                }
            }
            return(tree.AddValue(segment.Subbytes(0, i).Bytes, valueType));
        }
Пример #7
0
        public static JsonTreeNode Parse(JsonTreeNode tree, Utf8String segment)
        {
            // skip white space
            int pos;

            if (!segment.TrySearchByte(x => !char.IsWhiteSpace((char)x), out pos))
            {
                throw new ParserException("only whitespace");
            }
            segment = segment.Subbytes(pos);

            var valueType = GetValueType(segment);

            switch (valueType)
            {
            case ValueNodeType.Boolean:
            case ValueNodeType.Integer:
            case ValueNodeType.Number:
            case ValueNodeType.Null:
            case ValueNodeType.NaN:
            case ValueNodeType.Infinity:
            case ValueNodeType.MinusInfinity:
                return(ParsePrimitive(tree, segment, valueType));

            case ValueNodeType.String:
                return(ParseString(tree, segment));

            case ValueNodeType.Array:     // fall through
                return(ParseArray(tree, segment));

            case ValueNodeType.Object:     // fall through
                return(ParseObject(tree, segment));

            default:
                throw new NotImplementedException();
            }
        }
Пример #8
0
 public static int Unquote(Utf8String src, IStore w)
 {
     return(Unescape(src.Subbytes(1, src.ByteLength - 2), w));
 }
Пример #9
0
        static JsonTreeNode ParseObject(JsonTreeNode tree, Utf8String segment)
        {
            var obj = tree.AddValue(segment.Bytes, ValueNodeType.Object);

            var  closeChar = '}';
            bool isFirst   = true;
            var  current   = segment.Subbytes(1);

            while (true)
            {
                {
                    // skip white space
                    int nextToken;
                    if (!current.TrySearchByte(x => !Char.IsWhiteSpace((char)x), out nextToken))
                    {
                        throw new ParserException("no white space expected");
                    }
                    current = current.Subbytes(nextToken);
                }

                {
                    if (current[0] == closeChar)
                    {
                        break;
                    }
                }

                if (isFirst)
                {
                    isFirst = false;
                }
                else
                {
                    // search ',' or closeChar
                    int keyPos;
                    if (!current.TrySearchByte(x => x == ',', out keyPos))
                    {
                        throw new ParserException("',' expected");
                    }
                    current = current.Subbytes(keyPos + 1);
                }

                {
                    // skip white space
                    int nextToken;
                    if (!current.TrySearchByte(x => !Char.IsWhiteSpace((char)x), out nextToken))
                    {
                        throw new ParserException("not whitespace expected");
                    }
                    current = current.Subbytes(nextToken);
                }

                // key
                var key = Parse(obj, current);
                if (!key.IsString())
                {
                    throw new ParserException("object key must string: " + key.Value.Segment);
                }
                current = current.Subbytes(key.Value.Segment.ByteLength);

                // search ':'
                int valuePos;
                if (!current.TrySearchByte(x => x == ':', out valuePos))
                {
                    throw new ParserException(": is not found");
                }
                current = current.Subbytes(valuePos + 1);

                {
                    // skip white space
                    int nextToken;
                    if (!current.TrySearchByte(x => !Char.IsWhiteSpace((char)x), out nextToken))
                    {
                        throw new ParserException("not whitespace expected");
                    }
                    current = current.Subbytes(nextToken);
                }

                // value
                var value = Parse(obj, current);
                current = current.Subbytes(value.Value.Segment.ByteLength);
            }

            // fix obj range
            var count = current.Bytes.Offset + 1 - segment.Bytes.Offset;

            obj.SetValueBytesCount(count);

            return(obj);
        }
Пример #10
0
        static JsonTreeNode ParseArray(JsonTreeNode tree, Utf8String segment)
        {
            var array = tree.AddValue(segment.Bytes, ValueNodeType.Array);

            var  closeChar = ']';
            bool isFirst   = true;
            var  current   = segment.Subbytes(1);

            while (true)
            {
                {
                    // skip white space
                    int nextToken;
                    if (!current.TrySearchByte(x => !Char.IsWhiteSpace((char)x), out nextToken))
                    {
                        throw new ParserException("no white space expected");
                    }
                    current = current.Subbytes(nextToken);
                }

                {
                    if (current[0] == closeChar)
                    {
                        // end
                        break;
                    }
                }

                if (isFirst)
                {
                    isFirst = false;
                }
                else
                {
                    // search ',' or closeChar
                    int keyPos;
                    if (!current.TrySearchByte(x => x == ',', out keyPos))
                    {
                        throw new ParserException("',' expected");
                    }
                    current = current.Subbytes(keyPos + 1);
                }

                {
                    // skip white space
                    int nextToken;
                    if (!current.TrySearchByte(x => !Char.IsWhiteSpace((char)x), out nextToken))
                    {
                        throw new ParserException("not whitespace expected");
                    }
                    current = current.Subbytes(nextToken);
                }

                // value
                var child = Parse(array, current);
                current = current.Subbytes(child.Value.Segment.ByteLength);
            }

            // fix array range
            var count = current.Bytes.Offset + 1 - segment.Bytes.Offset;

            array.SetValueBytesCount(count);

            return(array);
        }