-Added ReadAsBoolean

-Fixed reading booleans as strings
-Fixed reading large integers as booleans
This commit is contained in:
James Newton-King
2016-01-05 22:12:01 +13:00
parent 1ada613903
commit 9021858293
11 changed files with 564 additions and 101 deletions
@@ -2807,6 +2807,55 @@ new Date()"));
Assert.IsTrue(reader.Read());
}
[Test]
public void ReadAsString_Boolean()
{
JsonTextReader reader = new JsonTextReader(new StringReader("{\"Test1\":false}"));
Assert.IsTrue(reader.Read());
Assert.IsTrue(reader.Read());
string s = reader.ReadAsString();
Assert.AreEqual("false", s);
Assert.IsTrue(reader.Read());
Assert.IsFalse(reader.Read());
}
[Test]
public void Read_Boolean_Failure()
{
JsonTextReader reader = new JsonTextReader(new StringReader("{\"Test1\":false1}"));
Assert.IsTrue(reader.Read());
Assert.IsTrue(reader.Read());
ExceptionAssert.Throws<JsonReaderException>(
() => { reader.Read(); },
"Error parsing boolean value. Path 'Test1', line 1, position 14.");
Assert.IsTrue(reader.Read());
Assert.IsTrue(reader.Read());
Assert.IsFalse(reader.Read());
}
[Test]
public void ReadAsString_Boolean_Failure()
{
JsonTextReader reader = new JsonTextReader(new StringReader("{\"Test1\":false1}"));
Assert.IsTrue(reader.Read());
Assert.IsTrue(reader.Read());
ExceptionAssert.Throws<JsonReaderException>(
() => { reader.ReadAsString(); },
"Unexpected character encountered while parsing value: 1. Path 'Test1', line 1, position 14.");
Assert.IsTrue(reader.Read());
Assert.IsTrue(reader.Read());
Assert.IsFalse(reader.Read());
}
[Test]
public void ParseConstructorWithBadCharacter()
{
@@ -3402,6 +3451,86 @@ null//comment
Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
}
#if !(PORTABLE || PORTABLE40 || NET35 || NET20)
[Test]
public void ReadAsBoolean()
{
string json = @"[
1,
0,
1.1,
0.0,
0.000000000001,
9999999999,
-9999999999,
9999999999999999999999999999999999999999999999999999999999999999999999,
-9999999999999999999999999999999999999999999999999999999999999999999999,
'true',
'TRUE',
'false',
'FALSE',
'',
null
]";
JsonTextReader reader = new JsonTextReader(new StringReader(json));
Assert.IsTrue(reader.Read());
Assert.AreEqual("", reader.Path);
Assert.AreEqual(true, reader.ReadAsBoolean());
Assert.AreEqual("[0]", reader.Path);
Assert.AreEqual(false, reader.ReadAsBoolean());
Assert.AreEqual("[1]", reader.Path);
Assert.AreEqual(true, reader.ReadAsBoolean());
Assert.AreEqual("[2]", reader.Path);
Assert.AreEqual(false, reader.ReadAsBoolean());
Assert.AreEqual("[3]", reader.Path);
Assert.AreEqual(true, reader.ReadAsBoolean());
Assert.AreEqual("[4]", reader.Path);
Assert.AreEqual(true, reader.ReadAsBoolean());
Assert.AreEqual("[5]", reader.Path);
Assert.AreEqual(true, reader.ReadAsBoolean());
Assert.AreEqual("[6]", reader.Path);
Assert.AreEqual(true, reader.ReadAsBoolean());
Assert.AreEqual("[7]", reader.Path);
Assert.AreEqual(true, reader.ReadAsBoolean());
Assert.AreEqual("[8]", reader.Path);
Assert.AreEqual(true, reader.ReadAsBoolean());
Assert.AreEqual("[9]", reader.Path);
Assert.AreEqual(true, reader.ReadAsBoolean());
Assert.AreEqual("[10]", reader.Path);
Assert.AreEqual(false, reader.ReadAsBoolean());
Assert.AreEqual("[11]", reader.Path);
Assert.AreEqual(false, reader.ReadAsBoolean());
Assert.AreEqual("[12]", reader.Path);
Assert.AreEqual(null, reader.ReadAsBoolean());
Assert.AreEqual("[13]", reader.Path);
Assert.AreEqual(null, reader.ReadAsBoolean());
Assert.AreEqual("[14]", reader.Path);
Assert.IsTrue(reader.Read());
Assert.AreEqual("", reader.Path);
Assert.IsFalse(reader.Read());
Assert.AreEqual("", reader.Path);
}
#endif
[Test]
public void ReadAsBytes()
{
@@ -67,8 +67,12 @@ namespace Newtonsoft.Json.Tests
[TestFixture]
public class PerformanceTests : TestFixtureBase
{
#if DEBUG
public int Iterations = 1;
#else
public int Iterations = 100;
//public int Iterations = 10000;
#endif
#region Data
private const string BsonHex =
@@ -215,6 +215,114 @@ namespace Newtonsoft.Json.Tests.Serialization
}
#endif
[Test]
public void DeserializeBoolean_Null()
{
ExceptionAssert.Throws<JsonSerializationException>(
() => JsonConvert.DeserializeObject<IList<bool>>(@"[null]"),
"Error converting value {null} to type 'System.Boolean'. Path '[0]', line 1, position 5.");
}
[Test]
public void DeserializeBoolean_DateTime()
{
ExceptionAssert.Throws<JsonReaderException>(
() => JsonConvert.DeserializeObject<IList<bool>>(@"['2000-12-20T10:55:55Z']"),
"Could not convert string to boolean: 2000-12-20T10:55:55Z. Path '[0]', line 1, position 23.");
}
[Test]
public void DeserializeBoolean_BadString()
{
ExceptionAssert.Throws<JsonReaderException>(
() => JsonConvert.DeserializeObject<IList<bool>>(@"['pie']"),
@"Could not convert string to boolean: pie. Path '[0]', line 1, position 6.");
}
[Test]
public void DeserializeBoolean_EmptyString()
{
ExceptionAssert.Throws<JsonSerializationException>(
() => JsonConvert.DeserializeObject<IList<bool>>(@"['']"),
@"Error converting value {null} to type 'System.Boolean'. Path '[0]', line 1, position 3.");
}
#if !(PORTABLE || PORTABLE40 || NET35 || NET20)
[Test]
public void DeserializeBooleans()
{
IList<bool> l = JsonConvert.DeserializeObject<IList<bool>>(@"[
1,
0,
1.1,
0.0,
0.000000000001,
9999999999,
-9999999999,
9999999999999999999999999999999999999999999999999999999999999999999999,
-9999999999999999999999999999999999999999999999999999999999999999999999,
'true',
'TRUE',
'false',
'FALSE'
]");
int i = 0;
Assert.AreEqual(true, l[i++]);
Assert.AreEqual(false, l[i++]);
Assert.AreEqual(true, l[i++]);
Assert.AreEqual(false, l[i++]);
Assert.AreEqual(true, l[i++]);
Assert.AreEqual(true, l[i++]);
Assert.AreEqual(true, l[i++]);
Assert.AreEqual(true, l[i++]);
Assert.AreEqual(true, l[i++]);
Assert.AreEqual(true, l[i++]);
Assert.AreEqual(true, l[i++]);
Assert.AreEqual(false, l[i++]);
Assert.AreEqual(false, l[i++]);
}
[Test]
public void DeserializeNullableBooleans()
{
IList<bool?> l = JsonConvert.DeserializeObject<IList<bool?>>(@"[
1,
0,
1.1,
0.0,
0.000000000001,
9999999999,
-9999999999,
9999999999999999999999999999999999999999999999999999999999999999999999,
-9999999999999999999999999999999999999999999999999999999999999999999999,
'true',
'TRUE',
'false',
'FALSE',
'',
null
]");
int i = 0;
Assert.AreEqual(true, l[i++]);
Assert.AreEqual(false, l[i++]);
Assert.AreEqual(true, l[i++]);
Assert.AreEqual(false, l[i++]);
Assert.AreEqual(true, l[i++]);
Assert.AreEqual(true, l[i++]);
Assert.AreEqual(true, l[i++]);
Assert.AreEqual(true, l[i++]);
Assert.AreEqual(true, l[i++]);
Assert.AreEqual(true, l[i++]);
Assert.AreEqual(true, l[i++]);
Assert.AreEqual(false, l[i++]);
Assert.AreEqual(false, l[i++]);
Assert.AreEqual(null, l[i++]);
Assert.AreEqual(null, l[i++]);
}
#endif
[Test]
public void CaseInsensitiveRequiredPropertyConstructorCreation()
{
@@ -196,7 +196,7 @@ namespace Newtonsoft.Json.Tests.Serialization
var reader = new JsonTextReader(new StringReader(sb.ToString()));
var ser = new JsonSerializer();
ser.MetadataPropertyHandling = MetadataPropertyHandling.Default;
ser.Deserialize<bool>(reader);
ser.Deserialize<float>(reader);
}, "Unexpected token when deserializing primitive value: StartObject. Path '$value', line 1, position 11.");
}
+64 -1
View File
@@ -27,13 +27,15 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Globalization;
#if !(NET20 || NET35 || PORTABLE40 || PORTABLE)
using System.Numerics;
#endif
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Utilities;
#if NET20
using Newtonsoft.Json.Utilities.LinqBridge;
#else
using System.Linq;
#endif
namespace Newtonsoft.Json
@@ -646,6 +648,67 @@ namespace Newtonsoft.Json
}
}
/// <summary>
/// Reads the next JSON token from the stream as a <see cref="Nullable{Boolean}"/>.
/// </summary>
/// <returns>A <see cref="Nullable{Boolean}"/>. This method will return <c>null</c> at the end of an array.</returns>
public virtual bool? ReadAsBoolean()
{
JsonToken t = GetContentToken();
switch (t)
{
case JsonToken.None:
case JsonToken.Null:
case JsonToken.EndArray:
return null;
case JsonToken.Integer:
case JsonToken.Float:
bool b;
#if !(NET20 || NET35 || PORTABLE40 || PORTABLE)
if (Value is BigInteger)
{
b = (BigInteger)Value != 0;
}
else
#endif
{
b = Convert.ToBoolean(Value, CultureInfo.InvariantCulture);
}
SetToken(JsonToken.Boolean, b, false);
return b;
case JsonToken.String:
return ReadBooleanString((string)Value);
case JsonToken.Boolean:
return (bool)Value;
}
throw JsonReaderException.Create(this, "Error reading boolean. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, t));
}
internal bool? ReadBooleanString(string s)
{
if (string.IsNullOrEmpty(s))
{
SetToken(JsonToken.Null, null, false);
return null;
}
bool b;
if (bool.TryParse(s, out b))
{
SetToken(JsonToken.Boolean, b, false);
return b;
}
else
{
SetToken(JsonToken.String, s, false);
throw JsonReaderException.Create(this, "Could not convert string to boolean: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
}
}
/// <summary>
/// Reads the next JSON token from the stream as a <see cref="Nullable{Decimal}"/>.
/// </summary>
+228 -99
View File
@@ -30,6 +30,9 @@ using System.Runtime.CompilerServices;
using System.Text;
using System.IO;
using System.Globalization;
#if !(PORTABLE || PORTABLE40 || NET35 || NET20)
using System.Numerics;
#endif
using Newtonsoft.Json.Utilities;
namespace Newtonsoft.Json
@@ -45,7 +48,8 @@ namespace Newtonsoft.Json
#if !NET20
ReadAsDateTimeOffset,
#endif
ReadAsDouble
ReadAsDouble,
ReadAsBoolean
}
/// <summary>
@@ -129,81 +133,81 @@ namespace Newtonsoft.Json
ReadStringIntoBuffer(quote);
SetPostValueState(true);
if (readType == ReadType.ReadAsBytes)
switch (readType)
{
Guid g;
byte[] data;
if (_stringReference.Length == 0)
{
data = new byte[0];
}
else if (_stringReference.Length == 36 && ConvertUtils.TryConvertGuid(_stringReference.ToString(), out g))
{
data = g.ToByteArray();
}
else
{
data = Convert.FromBase64CharArray(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length);
}
SetToken(JsonToken.Bytes, data, false);
}
else if (readType == ReadType.ReadAsString)
{
string text = _stringReference.ToString();
SetToken(JsonToken.String, text, false);
_quoteChar = quote;
}
else if (readType == ReadType.ReadAsInt32 ||
readType == ReadType.ReadAsDecimal)
{
// caller will convert result
}
else
{
if (_dateParseHandling != DateParseHandling.None)
{
DateParseHandling dateParseHandling;
if (readType == ReadType.ReadAsDateTime)
case ReadType.ReadAsBytes:
Guid g;
byte[] data;
if (_stringReference.Length == 0)
{
dateParseHandling = DateParseHandling.DateTime;
data = new byte[0];
}
#if !NET20
else if (readType == ReadType.ReadAsDateTimeOffset)
else if (_stringReference.Length == 36 && ConvertUtils.TryConvertGuid(_stringReference.ToString(), out g))
{
dateParseHandling = DateParseHandling.DateTimeOffset;
data = g.ToByteArray();
}
#endif
else
{
dateParseHandling = _dateParseHandling;
data = Convert.FromBase64CharArray(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length);
}
if (dateParseHandling == DateParseHandling.DateTime)
SetToken(JsonToken.Bytes, data, false);
break;
case ReadType.ReadAsString:
string text = _stringReference.ToString();
SetToken(JsonToken.String, text, false);
_quoteChar = quote;
break;
case ReadType.ReadAsInt32:
case ReadType.ReadAsDecimal:
case ReadType.ReadAsBoolean:
// caller will convert result
break;
default:
if (_dateParseHandling != DateParseHandling.None)
{
DateTime dt;
if (DateTimeUtils.TryParseDateTime(_stringReference, DateTimeZoneHandling, DateFormatString, Culture, out dt))
DateParseHandling dateParseHandling;
if (readType == ReadType.ReadAsDateTime)
{
SetToken(JsonToken.Date, dt, false);
return;
dateParseHandling = DateParseHandling.DateTime;
}
}
#if !NET20
else
{
DateTimeOffset dt;
if (DateTimeUtils.TryParseDateTimeOffset(_stringReference, DateFormatString, Culture, out dt))
else if (readType == ReadType.ReadAsDateTimeOffset)
{
SetToken(JsonToken.Date, dt, false);
return;
dateParseHandling = DateParseHandling.DateTimeOffset;
}
}
#endif
}
else
{
dateParseHandling = _dateParseHandling;
}
SetToken(JsonToken.String, _stringReference.ToString(), false);
_quoteChar = quote;
if (dateParseHandling == DateParseHandling.DateTime)
{
DateTime dt;
if (DateTimeUtils.TryParseDateTime(_stringReference, DateTimeZoneHandling, DateFormatString, Culture, out dt))
{
SetToken(JsonToken.Date, dt, false);
return;
}
}
#if !NET20
else
{
DateTimeOffset dt;
if (DateTimeUtils.TryParseDateTimeOffset(_stringReference, DateFormatString, Culture, out dt))
{
SetToken(JsonToken.Date, dt, false);
return;
}
}
#endif
}
SetToken(JsonToken.String, _stringReference.ToString(), false);
_quoteChar = quote;
break;
}
}
@@ -488,15 +492,7 @@ namespace Newtonsoft.Json
ParseComment(false);
break;
case ',':
_charPos++;
if (_currentState != State.PostValue)
{
SetToken(JsonToken.Undefined);
throw JsonReaderException.Create(this, "Unexpected character encountered while parsing value: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar));
}
SetStateBasedOnCurrent();
ProcessValueComma();
break;
case ']':
_charPos++;
@@ -505,7 +501,7 @@ namespace Newtonsoft.Json
SetToken(JsonToken.EndArray);
return null;
}
throw JsonReaderException.Create(this, "Unexpected character encountered while parsing value: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar));
throw CreateUnexpectedCharacterException(currentChar);
case StringUtils.CarriageReturn:
ProcessCarriageReturn(false);
break;
@@ -522,7 +518,7 @@ namespace Newtonsoft.Json
if (!char.IsWhiteSpace(currentChar))
{
throw JsonReaderException.Create(this, "Unexpected character encountered while parsing value: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar));
throw CreateUnexpectedCharacterException(currentChar);
}
// eat
@@ -531,7 +527,6 @@ namespace Newtonsoft.Json
}
case State.Finished:
ReadFinished();
SetToken(JsonToken.None);
return null;
default:
throw JsonReaderException.Create(this, "Unexpected state: {0}.".FormatWith(CultureInfo.InvariantCulture, CurrentState));
@@ -605,12 +600,26 @@ namespace Newtonsoft.Json
if (readType != ReadType.ReadAsString)
{
_charPos++;
throw JsonReaderException.Create(this, "Unexpected character encountered while parsing value: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar));
throw CreateUnexpectedCharacterException(currentChar);
}
ParseNumber(ReadType.Read);
string s = ((IFormattable)Value).ToString(null, CultureInfo.InvariantCulture);
SetToken(JsonToken.String, s);
return s;
case 't':
case 'f':
if (readType != ReadType.ReadAsString)
{
_charPos++;
throw CreateUnexpectedCharacterException(currentChar);
}
string expected = currentChar == 't' ? JsonConvert.True : JsonConvert.False;
if (!MatchValueWithTrailingSeparator(expected))
{
throw CreateUnexpectedCharacterException(_chars[_charPos]);
}
SetToken(JsonToken.String, expected);
return expected;
case 'n':
HandleNull();
return null;
@@ -618,15 +627,7 @@ namespace Newtonsoft.Json
ParseComment(false);
break;
case ',':
_charPos++;
if (_currentState != State.PostValue)
{
SetToken(JsonToken.Undefined);
throw JsonReaderException.Create(this, "Unexpected character encountered while parsing value: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar));
}
SetStateBasedOnCurrent();
ProcessValueComma();
break;
case ']':
_charPos++;
@@ -635,7 +636,7 @@ namespace Newtonsoft.Json
SetToken(JsonToken.EndArray);
return null;
}
throw JsonReaderException.Create(this, "Unexpected character encountered while parsing value: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar));
throw CreateUnexpectedCharacterException(currentChar);
case StringUtils.CarriageReturn:
ProcessCarriageReturn(false);
break;
@@ -652,7 +653,7 @@ namespace Newtonsoft.Json
if (!char.IsWhiteSpace(currentChar))
{
throw JsonReaderException.Create(this, "Unexpected character encountered while parsing value: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar));
throw CreateUnexpectedCharacterException(currentChar);
}
// eat
@@ -661,13 +662,148 @@ namespace Newtonsoft.Json
}
case State.Finished:
ReadFinished();
SetToken(JsonToken.None);
return null;
default:
throw JsonReaderException.Create(this, "Unexpected state: {0}.".FormatWith(CultureInfo.InvariantCulture, CurrentState));
}
}
private JsonReaderException CreateUnexpectedCharacterException(char c)
{
return JsonReaderException.Create(this, "Unexpected character encountered while parsing value: {0}.".FormatWith(CultureInfo.InvariantCulture, c));
}
/// <summary>
/// Reads the next JSON token from the stream as a <see cref="Nullable{Boolean}"/>.
/// </summary>
/// <returns>A <see cref="Nullable{Boolean}"/>. This method will return <c>null</c> at the end of an array.</returns>
public override bool? ReadAsBoolean()
{
EnsureBuffer();
switch (_currentState)
{
case State.Start:
case State.Property:
case State.Array:
case State.ArrayStart:
case State.Constructor:
case State.ConstructorStart:
case State.PostValue:
while (true)
{
char currentChar = _chars[_charPos];
switch (currentChar)
{
case '\0':
if (ReadNullChar())
{
SetToken(JsonToken.None, null, false);
return null;
}
break;
case '"':
case '\'':
ParseString(currentChar, ReadType.Read);
return ReadBooleanString(_stringReference.ToString());
case 'n':
HandleNull();
return null;
case '-':
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
ParseNumber(ReadType.Read);
bool b;
#if !(NET20 || NET35 || PORTABLE40 || PORTABLE)
if (Value is BigInteger)
{
b = (BigInteger)Value != 0;
}
else
#endif
{
b = Convert.ToBoolean(Value, CultureInfo.InvariantCulture);
}
SetToken(JsonToken.Boolean, b, false);
return b;
case 't':
case 'f':
bool isTrue = currentChar == 't';
string expected = isTrue ? JsonConvert.True : JsonConvert.False;
if (!MatchValueWithTrailingSeparator(expected))
{
throw CreateUnexpectedCharacterException(_chars[_charPos]);
}
SetToken(JsonToken.Boolean, isTrue);
return isTrue;
case '/':
ParseComment(false);
break;
case ',':
ProcessValueComma();
break;
case ']':
_charPos++;
if (_currentState == State.Array || _currentState == State.ArrayStart || _currentState == State.PostValue)
{
SetToken(JsonToken.EndArray);
return null;
}
throw CreateUnexpectedCharacterException(currentChar);
case StringUtils.CarriageReturn:
ProcessCarriageReturn(false);
break;
case StringUtils.LineFeed:
ProcessLineFeed();
break;
case ' ':
case StringUtils.Tab:
// eat
_charPos++;
break;
default:
_charPos++;
if (!char.IsWhiteSpace(currentChar))
{
throw CreateUnexpectedCharacterException(currentChar);
}
// eat
break;
}
}
case State.Finished:
ReadFinished();
return null;
default:
throw JsonReaderException.Create(this, "Unexpected state: {0}.".FormatWith(CultureInfo.InvariantCulture, CurrentState));
}
}
private void ProcessValueComma()
{
_charPos++;
if (_currentState != State.PostValue)
{
SetToken(JsonToken.Undefined);
throw CreateUnexpectedCharacterException(',');
}
SetStateBasedOnCurrent();
}
private object ReadNumberValue(ReadType readType)
{
EnsureBuffer();
@@ -729,15 +865,7 @@ namespace Newtonsoft.Json
ParseComment(false);
break;
case ',':
_charPos++;
if (_currentState != State.PostValue)
{
SetToken(JsonToken.Undefined);
throw JsonReaderException.Create(this, "Unexpected character encountered while parsing value: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar));
}
SetStateBasedOnCurrent();
ProcessValueComma();
break;
case ']':
_charPos++;
@@ -746,7 +874,7 @@ namespace Newtonsoft.Json
SetToken(JsonToken.EndArray);
return null;
}
throw JsonReaderException.Create(this, "Unexpected character encountered while parsing value: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar));
throw CreateUnexpectedCharacterException(currentChar);
case StringUtils.CarriageReturn:
ProcessCarriageReturn(false);
break;
@@ -763,7 +891,7 @@ namespace Newtonsoft.Json
if (!char.IsWhiteSpace(currentChar))
{
throw JsonReaderException.Create(this, "Unexpected character encountered while parsing value: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar));
throw CreateUnexpectedCharacterException(currentChar);
}
// eat
@@ -772,7 +900,6 @@ namespace Newtonsoft.Json
}
case State.Finished:
ReadFinished();
SetToken(JsonToken.None);
return null;
default:
throw JsonReaderException.Create(this, "Unexpected state: {0}.".FormatWith(CultureInfo.InvariantCulture, CurrentState));
@@ -821,7 +948,7 @@ namespace Newtonsoft.Json
}
_charPos += 2;
throw JsonReaderException.Create(this, "Unexpected character encountered while parsing value: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos - 1]));
throw CreateUnexpectedCharacterException(_chars[_charPos - 1]);
}
throw JsonReaderException.Create(this, "Unexpected end when reading JSON.");
@@ -845,6 +972,8 @@ namespace Newtonsoft.Json
throw JsonReaderException.Create(this, "Additional text encountered after finished reading JSON content: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos]));
}
}
SetToken(JsonToken.None);
}
private bool ReadNullChar()
@@ -1416,7 +1545,7 @@ namespace Newtonsoft.Json
}
else
{
throw JsonReaderException.Create(this, "Unexpected character encountered while parsing value: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos]));
throw CreateUnexpectedCharacterException(_chars[_charPos]);
}
}
else
@@ -1491,7 +1620,7 @@ namespace Newtonsoft.Json
return true;
}
throw JsonReaderException.Create(this, "Unexpected character encountered while parsing value: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar));
throw CreateUnexpectedCharacterException(currentChar);
}
}
}
@@ -441,6 +441,18 @@ namespace Newtonsoft.Json
return d;
}
/// <summary>
/// Reads the next JSON token from the stream as a <see cref="Nullable{Boolean}"/>.
/// </summary>
/// <returns>A <see cref="Nullable{Boolean}"/>.</returns>
public override bool? ReadAsBoolean()
{
bool? b = _reader.ReadAsBoolean();
ValidateCurrentToken();
return b;
}
/// <summary>
/// Reads the next JSON token from the stream as a <see cref="String"/>.
/// </summary>
@@ -333,6 +333,10 @@ namespace Newtonsoft.Json.Serialization
{
InternalReadType = ReadType.ReadAsDecimal;
}
else if (NonNullableUnderlyingType == typeof(bool))
{
InternalReadType = ReadType.ReadAsBoolean;
}
else if (NonNullableUnderlyingType == typeof(string))
{
InternalReadType = ReadType.ReadAsString;
@@ -2216,6 +2216,9 @@ namespace Newtonsoft.Json.Serialization
case ReadType.ReadAsBytes:
reader.ReadAsBytes();
break;
case ReadType.ReadAsBoolean:
reader.ReadAsBoolean();
break;
case ReadType.ReadAsString:
reader.ReadAsString();
break;
@@ -71,6 +71,13 @@ namespace Newtonsoft.Json.Serialization
return value;
}
public override bool? ReadAsBoolean()
{
var value = _innerReader.ReadAsBoolean();
_textWriter.WriteToken(_innerReader, false, false, true);
return value;
}
public override DateTime? ReadAsDateTime()
{
var value = _innerReader.ReadAsDateTime();
@@ -376,6 +376,10 @@ namespace Newtonsoft.Json.Utilities
{
return (ulong)i;
}
if (targetType == typeof(bool))
{
return i != 0;
}
try
{