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)); } }
static JsonValue Parse(Utf8String segment, List <JsonValue> values, int parentIndex) { // 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: { var value = ParsePrimitive(segment, valueType, parentIndex); values.Add(value); return(value); } case ValueNodeType.String: { var value = ParseString(segment, parentIndex); values.Add(value); return(value); } case ValueNodeType.Array: // fall through { var index = values.Count; values.Add(new JsonValue()); // placeholder var current = ParseArray(segment, values, index); values[index] = new JsonValue(segment.Subbytes(0, current.Bytes.Offset + 1 - segment.Bytes.Offset), ValueNodeType.Array, parentIndex); return(values[index]); } case ValueNodeType.Object: // fall through { var index = values.Count; values.Add(new JsonValue()); // placeholder var current = ParseObject(segment, values, index); values[index] = new JsonValue(segment.Subbytes(0, current.Bytes.Offset + 1 - segment.Bytes.Offset), ValueNodeType.Object, parentIndex); return(values[index]); } default: throw new NotImplementedException(); } }
/// <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)); }
static Utf8String ParseArray(Utf8String segment, List <JsonValue> values, int parentIndex) { 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 value = Parse(current, values, parentIndex); current = current.Subbytes(value.Segment.ByteLength); } return(current); }
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)); }
static JsonValue ParseString(Utf8String segment, int parentIndex) { int pos; if (segment.TrySearchAscii((Byte)'"', 1, out pos)) { return new JsonValue(segment.Subbytes(0, pos + 1), ValueNodeType.String, parentIndex); } else { throw new ParserException("no close string: " + segment); } }
static JsonNode ParseString(JsonNode 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); } }
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)); } }
static TomlValue ParseRHS(Utf8String segment, int parentIndex) { switch ((char)segment[0]) { case '+': case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (segment.IsInt) { return(new TomlValue(segment.SplitInteger(), TomlValueType.Integer, parentIndex)); } else { return(new TomlValue(segment, TomlValueType.Float, parentIndex)); } case '"': { int pos; if (segment.TrySearchAscii((Byte)'"', 1, out pos)) { return(new TomlValue(segment.Subbytes(0, pos + 1), TomlValueType.BasicString, parentIndex)); } else { throw new ParserException("no close string: " + segment); } } case '[': { throw new NotImplementedException(); } } throw new NotImplementedException(); }
/// <summary> /// Expected null, boolean, integer, number /// </summary> /// <param name="segment"></param> /// <param name="valueType"></param> /// <param name="parentIndex"></param> /// <returns></returns> static JsonValue ParsePrimitive(Utf8String segment, ValueNodeType valueType, int parentIndex) { int i = 1; for (; i < segment.ByteLength; ++i) { if (Char.IsWhiteSpace((char)segment[i]) || segment[i] == '}' || segment[i] == ']' || segment[i] == ',' || segment[i] == ':' ) { break; } } return new JsonValue(segment.Subbytes(0, i), valueType, parentIndex); }
/// <summary> /// Expected null, boolean, integer, number /// </summary> /// <param name="segment"></param> /// <param name="valueType"></param> /// <param name="parentIndex"></param> /// <returns></returns> static JsonNode ParsePrimitive(JsonNode 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)); }
static TomlValue ParseLHS(Utf8String segment, int parentIndex) { var it = segment.GetIterator(); while (it.MoveNext()) { if (it.Current == '"') { throw new NotImplementedException(); } else if (it.Current == '.') { throw new NotImplementedException(); } else if (it.Current == ' ' || it.Current == '\t' || it.Current == '=') { return(new TomlValue(segment.Subbytes(0, it.BytePosition), TomlValueType.BareKey, parentIndex)); } } throw new NotImplementedException(); }
public static JsonNode Parse(JsonNode 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(); } }
public static int Unquote(Utf8String src, IStore w) { return(Unescape(src.Subbytes(1, src.ByteLength - 2), w)); }
static Utf8String ParseObject(Utf8String segment, List <JsonValue> values, int parentIndex) { 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(current, values, parentIndex); if (key.ValueType != ValueNodeType.String) { throw new ParserException("object key must string: " + key.Segment); } current = current.Subbytes(key.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(current, values, parentIndex); current = current.Subbytes(value.Segment.ByteLength); } return(current); }
static JsonNode ParseObject(JsonNode 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); }
public static ListTreeNode <TomlValue> Parse(Utf8String segment) { var values = new List <TomlValue>() { new TomlValue(segment, TomlValueType.Table, -1), }; var current = 0; while (!segment.IsEmpty) { segment = segment.TrimStart(); if (segment.IsEmpty) { break; } if (segment[0] == '#') { // comment line // skip to line end segment = segment.Subbytes(segment.GetLine().ByteLength); continue; } if (segment.ByteLength >= 4 && segment[0] == '[' && segment[1] == '[') { // [[array_name]] throw new NotImplementedException(); } else if (segment.ByteLength >= 2 && segment[0] == '[') { // [table_name] int table_end; if (!segment.TrySearchByte(x => x == ']', out table_end)) { throw new ParserException("] not found"); } var table_name = segment.Subbytes(1, table_end - 1).Trim(); if (table_name.IsEmpty) { throw new ParserException("empty table name"); } // top level key values.Add(new TomlValue(table_name, TomlValueType.Table, 0)); current = values.Count - 1; // skip to line end segment = segment.Subbytes(segment.GetLine().ByteLength); } else { // key = value { var key = ParseLHS(segment, current); switch (key.TomlValueType) { case TomlValueType.BareKey: case TomlValueType.QuotedKey: { values.Add(key); // skip key segment = segment.Subbytes(key.Bytes.Count); } break; case TomlValueType.DottedKey: throw new NotImplementedException(); } } { // search and skip = int eq; if (!segment.TrySearchByte(x => x == '=', out eq)) { throw new ParserException("= not found"); } segment = segment.Subbytes(eq + 1); // skip white space segment = segment.TrimStart(); } { var value = ParseRHS(segment, current); values.Add(value); // skip value segment = segment.Subbytes(value.Bytes.Count); // skip to line end segment = segment.Subbytes(segment.GetLine().ByteLength); } } } return(new ListTreeNode <TomlValue>(values)); }
static JsonNode ParseArray(JsonNode 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); }