public void ObjectDepth() { string json = "{ \"foo\": { \"x\": 1, \"y\": [ 0 ] } }"; var tokenizer = JsonTokenizer.FromTextReader(new StringReader(json)); // If we had more tests like this, I'd introduce a helper method... but for one test, it's not worth it. Assert.AreEqual(0, tokenizer.ObjectDepth); Assert.AreEqual(JsonToken.StartObject, tokenizer.Next()); Assert.AreEqual(1, tokenizer.ObjectDepth); Assert.AreEqual(JsonToken.Name("foo"), tokenizer.Next()); Assert.AreEqual(1, tokenizer.ObjectDepth); Assert.AreEqual(JsonToken.StartObject, tokenizer.Next()); Assert.AreEqual(2, tokenizer.ObjectDepth); Assert.AreEqual(JsonToken.Name("x"), tokenizer.Next()); Assert.AreEqual(2, tokenizer.ObjectDepth); Assert.AreEqual(JsonToken.Value(1), tokenizer.Next()); Assert.AreEqual(2, tokenizer.ObjectDepth); Assert.AreEqual(JsonToken.Name("y"), tokenizer.Next()); Assert.AreEqual(2, tokenizer.ObjectDepth); Assert.AreEqual(JsonToken.StartArray, tokenizer.Next()); Assert.AreEqual(2, tokenizer.ObjectDepth); // Depth hasn't changed in array Assert.AreEqual(JsonToken.Value(0), tokenizer.Next()); Assert.AreEqual(2, tokenizer.ObjectDepth); Assert.AreEqual(JsonToken.EndArray, tokenizer.Next()); Assert.AreEqual(2, tokenizer.ObjectDepth); Assert.AreEqual(JsonToken.EndObject, tokenizer.Next()); Assert.AreEqual(1, tokenizer.ObjectDepth); Assert.AreEqual(JsonToken.EndObject, tokenizer.Next()); Assert.AreEqual(0, tokenizer.ObjectDepth); Assert.AreEqual(JsonToken.EndDocument, tokenizer.Next()); Assert.AreEqual(0, tokenizer.ObjectDepth); }
public void ObjectMixedType() { AssertTokens(@"{'a': 1, 'b': 'bar', 'c': null, 'd': false, 'e': true, 'f': [2], 'g': {'x':'y' }}", JsonToken.StartObject, JsonToken.Name("a"), JsonToken.Value(1), JsonToken.Name("b"), JsonToken.Value("bar"), JsonToken.Name("c"), JsonToken.Null, JsonToken.Name("d"), JsonToken.False, JsonToken.Name("e"), JsonToken.True, JsonToken.Name("f"), JsonToken.StartArray, JsonToken.Value(2), JsonToken.EndArray, JsonToken.Name("g"), JsonToken.StartObject, JsonToken.Name("x"), JsonToken.Value("y"), JsonToken.EndObject, JsonToken.EndObject); }
public void ArrayMixedType() { AssertTokens("[1, 'foo', null, false, true, [2], {'x':'y' }]", JsonToken.StartArray, JsonToken.Value(1), JsonToken.Value("foo"), JsonToken.Null, JsonToken.False, JsonToken.True, JsonToken.StartArray, JsonToken.Value(2), JsonToken.EndArray, JsonToken.StartObject, JsonToken.Name("x"), JsonToken.Value("y"), JsonToken.EndObject, JsonToken.EndArray); }
/// <summary> /// Returns the next JSON token in the stream. An EndDocument token is returned to indicate the end of the stream, /// after which point <c>Next()</c> should not be called again. /// </summary> /// <remarks> /// This method essentially just loops through characters skipping whitespace, validating and /// changing state (e.g. from ObjectBeforeColon to ObjectAfterColon) /// until it reaches something which will be a genuine token (e.g. a start object, or a value) at which point /// it returns the token. Although the method is large, it would be relatively hard to break down further... most /// of it is the large switch statement, which sometimes returns and sometimes doesn't. /// </remarks> /// <returns>The next token in the stream. This is never null.</returns> /// <exception cref="InvalidOperationException">This method is called after an EndDocument token has been returned</exception> internal JsonToken Next() { if (bufferedToken != null) { var ret = bufferedToken; bufferedToken = null; return(ret); } if (state == State.ReaderExhausted) { throw new InvalidOperationException("Next() called after end of document"); } while (true) { var next = reader.Read(); if (next == null) { ValidateState(State.ExpectedEndOfDocument, "Unexpected end of document in state: "); state = State.ReaderExhausted; return(JsonToken.EndDocument); } switch (next.Value) { // Skip whitespace between tokens case ' ': case '\t': case '\r': case '\n': break; case ':': ValidateState(State.ObjectBeforeColon, "Invalid state to read a colon: "); state = State.ObjectAfterColon; break; case ',': ValidateState(State.ObjectAfterProperty | State.ArrayAfterValue, "Invalid state to read a colon: "); state = state == State.ObjectAfterProperty ? State.ObjectAfterComma : State.ArrayAfterComma; break; case '"': string stringValue = ReadString(); if ((state & (State.ObjectStart | State.ObjectAfterComma)) != 0) { state = State.ObjectBeforeColon; return(JsonToken.Name(stringValue)); } else { ValidateAndModifyStateForValue("Invalid state to read a double quote: "); return(JsonToken.Value(stringValue)); } case '{': ValidateState(ValueStates, "Invalid state to read an open brace: "); state = State.ObjectStart; containerStack.Push(ContainerType.Object); return(JsonToken.StartObject); case '}': ValidateState(State.ObjectAfterProperty | State.ObjectStart, "Invalid state to read a close brace: "); PopContainer(); return(JsonToken.EndObject); case '[': ValidateState(ValueStates, "Invalid state to read an open square bracket: "); state = State.ArrayStart; containerStack.Push(ContainerType.Array); return(JsonToken.StartArray); case ']': ValidateState(State.ArrayAfterValue | State.ArrayStart, "Invalid state to read a close square bracket: "); PopContainer(); return(JsonToken.EndArray); case 'n': // Start of null ConsumeLiteral("null"); ValidateAndModifyStateForValue("Invalid state to read a null literal: "); return(JsonToken.Null); case 't': // Start of true ConsumeLiteral("true"); ValidateAndModifyStateForValue("Invalid state to read a true literal: "); return(JsonToken.True); case 'f': // Start of false ConsumeLiteral("false"); ValidateAndModifyStateForValue("Invalid state to read a false literal: "); return(JsonToken.False); case '-': // Start of a number case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': double number = ReadNumber(next.Value); ValidateAndModifyStateForValue("Invalid state to read a number token: "); return(JsonToken.Value(number)); default: throw new InvalidProtocolBufferException("Invalid first character of token: " + next.Value); } } }
public void SimpleObject() { AssertTokens("{'x': 'y'}", JsonToken.StartObject, JsonToken.Name("x"), JsonToken.Value("y"), JsonToken.EndObject); }