<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ArrayDepthTooLarge" xml:space="preserve">
- <value>CurrentDepth ({0}) is larger than the maximum configured depth of {1}. Cannot read next JSON array.</value>
+ <value>The maximum configured depth of {0} has been exceeded. Cannot read next JSON array.</value>
</data>
<data name="CallFlushToAvoidDataLoss" xml:space="preserve">
<value>The JSON writer needs to be flushed before getting the current state. There are {0} bytes that have not been committed to the output.</value>
<value>'{0}' is invalid without a matching open.</value>
</data>
<data name="ObjectDepthTooLarge" xml:space="preserve">
- <value>CurrentDepth ({0}) is larger than the maximum configured depth of {1}. Cannot read next JSON object.</value>
+ <value>The maximum configured depth of {0} has been exceeded. Cannot read next JSON object.</value>
</data>
<data name="PropertyNameTooLarge" xml:space="preserve">
<value>The JSON property name of length {0} is too large and not supported by the JSON writer.</value>
<value>The JSON value of length {0} is too large and not supported by the JSON writer.</value>
</data>
<data name="ZeroDepthAtEnd" xml:space="preserve">
- <value>Expected CurrentDepth ({0}) to be zero at the end of the JSON payload. There is an open JSON object or array that should be closed.</value>
+ <value>Expected depth to be zero at the end of the JSON payload. There is an open JSON object or array that should be closed.</value>
</data>
<data name="DeserializeCannotBeNull" xml:space="preserve">
<value>The JSON value from {0} cannot be null.</value>
}
}
- if (CurrentDepth == 0)
+ if (_bitStack.CurrentDepth == 0)
{
ThrowHelper.ThrowJsonReaderException(ref this, ExceptionResource.ExpectedEndAfterSingleJson, marker);
}
first = _buffer[_consumed];
}
- if (CurrentDepth == 0 && _tokenType != JsonTokenType.None)
+ if (_bitStack.CurrentDepth == 0 && _tokenType != JsonTokenType.None)
{
ThrowHelper.ThrowJsonReaderException(ref this, ExceptionResource.ExpectedEndAfterSingleJson, first);
}
}
goto Done;
}
- else if (CurrentDepth == 0)
+ else if (_bitStack.CurrentDepth == 0)
{
ThrowHelper.ThrowJsonReaderException(ref this, ExceptionResource.ExpectedEndAfterSingleJson, marker);
}
/// Tracks the recursive depth of the nested objects / arrays within the JSON text
/// processed so far. This provides the depth of the current token.
/// </summary>
- public int CurrentDepth => _bitStack.CurrentDepth;
+ public int CurrentDepth
+ {
+ get
+ {
+ int readerDepth = _bitStack.CurrentDepth;
+ if (TokenType == JsonTokenType.StartArray || TokenType == JsonTokenType.StartObject)
+ {
+ Debug.Assert(readerDepth >= 1);
+ readerDepth--;
+ }
+ return readerDepth;
+ }
+ }
internal bool IsInArray => !_inObject;
private void StartObject()
{
- if (CurrentDepth >= _readerOptions.MaxDepth)
+ if (_bitStack.CurrentDepth >= _readerOptions.MaxDepth)
ThrowHelper.ThrowJsonReaderException(ref this, ExceptionResource.ObjectDepthTooLarge);
_bitStack.PushTrue();
private void EndObject()
{
- if (!_inObject || CurrentDepth <= 0)
+ if (!_inObject || _bitStack.CurrentDepth <= 0)
ThrowHelper.ThrowJsonReaderException(ref this, ExceptionResource.MismatchedObjectArray, JsonConstants.CloseBrace);
_tokenType = JsonTokenType.EndObject;
private void StartArray()
{
- if (CurrentDepth >= _readerOptions.MaxDepth)
+ if (_bitStack.CurrentDepth >= _readerOptions.MaxDepth)
ThrowHelper.ThrowJsonReaderException(ref this, ExceptionResource.ArrayDepthTooLarge);
_bitStack.PushFalse();
private void EndArray()
{
- if (_inObject || CurrentDepth <= 0)
+ if (_inObject || _bitStack.CurrentDepth <= 0)
ThrowHelper.ThrowJsonReaderException(ref this, ExceptionResource.MismatchedObjectArray, JsonConstants.CloseBracket);
_tokenType = JsonTokenType.EndArray;
{
if (_isNotPrimitive && IsLastSpan)
{
- if (CurrentDepth != 0)
+ if (_bitStack.CurrentDepth != 0)
{
ThrowHelper.ThrowJsonReaderException(ref this, ExceptionResource.ZeroDepthAtEnd);
}
}
}
- if (CurrentDepth == 0)
+ if (_bitStack.CurrentDepth == 0)
{
ThrowHelper.ThrowJsonReaderException(ref this, ExceptionResource.ExpectedEndAfterSingleJson, marker);
}
first = _buffer[_consumed];
}
- if (CurrentDepth == 0 && _tokenType != JsonTokenType.None)
+ if (_bitStack.CurrentDepth == 0 && _tokenType != JsonTokenType.None)
{
ThrowHelper.ThrowJsonReaderException(ref this, ExceptionResource.ExpectedEndAfterSingleJson, first);
}
}
goto Done;
}
- else if (CurrentDepth == 0)
+ else if (_bitStack.CurrentDepth == 0)
{
ThrowHelper.ThrowJsonReaderException(ref this, ExceptionResource.ExpectedEndAfterSingleJson, marker);
}
switch (resource)
{
case ExceptionResource.ArrayDepthTooLarge:
- message = SR.Format(SR.ArrayDepthTooLarge, json.CurrentDepth + 1, json.CurrentState.Options.MaxDepth);
+ message = SR.Format(SR.ArrayDepthTooLarge, json.CurrentState.Options.MaxDepth);
break;
case ExceptionResource.MismatchedObjectArray:
message = SR.Format(SR.MismatchedObjectArray, character);
message = SR.Format(SR.InvalidEndOfJsonNonPrimitive, json.TokenType);
break;
case ExceptionResource.ObjectDepthTooLarge:
- message = SR.Format(SR.ObjectDepthTooLarge, json.CurrentDepth + 1, json.CurrentState.Options.MaxDepth);
+ message = SR.Format(SR.ObjectDepthTooLarge, json.CurrentState.Options.MaxDepth);
break;
case ExceptionResource.ExpectedFalse:
message = SR.Format(SR.ExpectedFalse, characters);
message = SR.EndOfCommentNotFound;
break;
case ExceptionResource.ZeroDepthAtEnd:
- message = SR.Format(SR.ZeroDepthAtEnd, json.CurrentDepth);
+ message = SR.Format(SR.ZeroDepthAtEnd);
break;
case ExceptionResource.ExpectedJsonTokens:
message = SR.ExpectedJsonTokens;
}
}
+ [Fact]
+ public static void CurrentDepthArrayTest()
+ {
+ string jsonString =
+@"[
+ [
+ 1,
+ 2,
+ 3
+ ]
+]";
+
+ byte[] dataUtf8 = Encoding.UTF8.GetBytes(jsonString);
+ var json = new Utf8JsonReader(dataUtf8, isFinalBlock: true, state: default);
+
+ Assert.Equal(0, json.CurrentDepth);
+ Assert.True(json.Read());
+ Assert.Equal(0, json.CurrentDepth);
+ Assert.True(json.Read());
+ Assert.Equal(1, json.CurrentDepth);
+ Assert.True(json.Read());
+ Assert.Equal(2, json.CurrentDepth);
+ Assert.True(json.Read());
+ Assert.Equal(2, json.CurrentDepth);
+ Assert.True(json.Read());
+ Assert.Equal(2, json.CurrentDepth);
+ Assert.True(json.Read());
+ Assert.Equal(1, json.CurrentDepth);
+ Assert.True(json.Read());
+ Assert.Equal(0, json.CurrentDepth);
+ Assert.False(json.Read());
+ Assert.Equal(0, json.CurrentDepth);
+ }
+
+ [Fact]
+ public static void CurrentDepthObjectTest()
+ {
+ string jsonString =
+@"{
+ ""array"": [
+ 1,
+ 2,
+ 3,
+ {}
+ ]
+}";
+
+ byte[] dataUtf8 = Encoding.UTF8.GetBytes(jsonString);
+ var json = new Utf8JsonReader(dataUtf8, isFinalBlock: true, state: default);
+
+ Assert.Equal(0, json.CurrentDepth);
+ Assert.True(json.Read());
+ Assert.Equal(0, json.CurrentDepth);
+ Assert.True(json.Read());
+ Assert.Equal(1, json.CurrentDepth);
+ Assert.True(json.Read());
+ Assert.Equal(1, json.CurrentDepth);
+ Assert.True(json.Read());
+ Assert.Equal(2, json.CurrentDepth);
+ Assert.True(json.Read());
+ Assert.Equal(2, json.CurrentDepth);
+ Assert.True(json.Read());
+ Assert.Equal(2, json.CurrentDepth);
+ Assert.True(json.Read());
+ Assert.Equal(2, json.CurrentDepth);
+ Assert.True(json.Read());
+ Assert.Equal(2, json.CurrentDepth);
+ Assert.True(json.Read());
+ Assert.Equal(1, json.CurrentDepth);
+ Assert.True(json.Read());
+ Assert.Equal(0, json.CurrentDepth);
+ Assert.False(json.Read());
+ Assert.Equal(0, json.CurrentDepth);
+ }
+
[Theory]
// Pad depth by nested objects, but minimize the text
[InlineData(1, true, true)]