-Improved memory usage

This commit is contained in:
James Newton-King
2013-04-20 15:45:34 +12:00
parent d53fe4ec59
commit c032b292bb
7 changed files with 219 additions and 70 deletions
+48 -1
View File
@@ -217,7 +217,7 @@ namespace Newtonsoft.Json
} }
else else
{ {
writer.Write(value.ToString(@"yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFF", CultureInfo.InvariantCulture)); WriteIsoDate(writer, value);
switch (kind) switch (kind)
{ {
@@ -232,6 +232,53 @@ namespace Newtonsoft.Json
} }
} }
internal static void WriteIsoDate(TextWriter writer, DateTime dt)
{
char[] chars = new char[27];
int length = 19;
IntToCharArray(chars, 0, dt.Year, 4);
chars[4] = '-';
IntToCharArray(chars, 5, dt.Month, 2);
chars[7] = '-';
IntToCharArray(chars, 8, dt.Day, 2);
chars[10] = 'T';
IntToCharArray(chars, 11, dt.Hour, 2);
chars[13] = ':';
IntToCharArray(chars, 14, dt.Minute, 2);
chars[16] = ':';
IntToCharArray(chars, 17, dt.Second, 2);
DateTime time = new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second);
int fraction = (int)(dt.Ticks - time.Ticks);
if (fraction != 0)
{
int digits = 7;
while ((fraction % 10) == 0)
{
digits--;
fraction /= 10;
}
chars[19] = '.';
IntToCharArray(chars, 20, fraction, digits);
length += digits + 1;
}
writer.Write(chars, 0, length);
}
private static void IntToCharArray(char[] text, int start, int value, int digits)
{
while (digits-- != 0)
{
text[start + digits] = (char)((value % 10) + 48);
value /= 10;
}
}
internal static void WriteDateTimeOffset(TextWriter writer, TimeSpan offset, DateFormatHandling format) internal static void WriteDateTimeOffset(TextWriter writer, TimeSpan offset, DateFormatHandling format)
{ {
writer.Write((offset.Ticks >= 0L) ? "+" : "-"); writer.Write((offset.Ticks >= 0L) ? "+" : "-");
+65 -33
View File
@@ -103,7 +103,7 @@ namespace Newtonsoft.Json
// current Token data // current Token data
private JsonToken _tokenType; private JsonToken _tokenType;
private object _value; private object _value;
private char _quoteChar; internal char _quoteChar;
internal State _currentState; internal State _currentState;
internal ReadType _readType; internal ReadType _readType;
private JsonPosition _currentPosition; private JsonPosition _currentPosition;
@@ -380,6 +380,8 @@ namespace Newtonsoft.Json
{ {
_readType = ReadType.ReadAsDateTimeOffset; _readType = ReadType.ReadAsDateTimeOffset;
JsonToken t;
do do
{ {
if (!ReadInternal()) if (!ReadInternal())
@@ -387,9 +389,13 @@ namespace Newtonsoft.Json
SetToken(JsonToken.None); SetToken(JsonToken.None);
return null; return null;
} }
} while (TokenType == JsonToken.Comment); else
{
t = TokenType;
}
} while (t == JsonToken.Comment);
if (TokenType == JsonToken.Date) if (t == JsonToken.Date)
{ {
if (Value is DateTime) if (Value is DateTime)
SetToken(JsonToken.Date, new DateTimeOffset((DateTime)Value)); SetToken(JsonToken.Date, new DateTimeOffset((DateTime)Value));
@@ -397,11 +403,11 @@ namespace Newtonsoft.Json
return (DateTimeOffset)Value; return (DateTimeOffset)Value;
} }
if (TokenType == JsonToken.Null) if (t == JsonToken.Null)
return null; return null;
DateTimeOffset dt; DateTimeOffset dt;
if (TokenType == JsonToken.String) if (t == JsonToken.String)
{ {
string s = (string)Value; string s = (string)Value;
if (string.IsNullOrEmpty(s)) if (string.IsNullOrEmpty(s))
@@ -421,10 +427,10 @@ namespace Newtonsoft.Json
} }
} }
if (TokenType == JsonToken.EndArray) if (t == JsonToken.EndArray)
return null; return null;
throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, t));
} }
#endif #endif
@@ -432,6 +438,8 @@ namespace Newtonsoft.Json
{ {
_readType = ReadType.ReadAsBytes; _readType = ReadType.ReadAsBytes;
JsonToken t;
do do
{ {
if (!ReadInternal()) if (!ReadInternal())
@@ -439,7 +447,11 @@ namespace Newtonsoft.Json
SetToken(JsonToken.None); SetToken(JsonToken.None);
return null; return null;
} }
} while (TokenType == JsonToken.Comment); else
{
t = TokenType;
}
} while (t == JsonToken.Comment);
if (IsWrappedInTypeObject()) if (IsWrappedInTypeObject())
{ {
@@ -450,26 +462,28 @@ namespace Newtonsoft.Json
} }
// attempt to convert possible base 64 string to bytes // attempt to convert possible base 64 string to bytes
if (TokenType == JsonToken.String) if (t == JsonToken.String)
{ {
string s = (string)Value; string s = (string)Value;
byte[] data = (s.Length == 0) ? new byte[0] : Convert.FromBase64String(s); byte[] data = (s.Length == 0) ? new byte[0] : Convert.FromBase64String(s);
SetToken(JsonToken.Bytes, data); SetToken(JsonToken.Bytes, data);
return data;
} }
if (TokenType == JsonToken.Null) if (t == JsonToken.Null)
return null; return null;
if (TokenType == JsonToken.Bytes) if (t == JsonToken.Bytes)
return (byte[])Value; return (byte[])Value;
if (TokenType == JsonToken.StartArray) if (t == JsonToken.StartArray)
{ {
List<byte> data = new List<byte>(); List<byte> data = new List<byte>();
while (ReadInternal()) while (ReadInternal())
{ {
switch (TokenType) t = TokenType;
switch (t)
{ {
case JsonToken.Integer: case JsonToken.Integer:
data.Add(Convert.ToByte(Value, CultureInfo.InvariantCulture)); data.Add(Convert.ToByte(Value, CultureInfo.InvariantCulture));
@@ -482,23 +496,25 @@ namespace Newtonsoft.Json
// skip // skip
break; break;
default: default:
throw JsonReaderException.Create(this, "Unexpected token when reading bytes: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); throw JsonReaderException.Create(this, "Unexpected token when reading bytes: {0}.".FormatWith(CultureInfo.InvariantCulture, t));
} }
} }
throw JsonReaderException.Create(this, "Unexpected end when reading bytes."); throw JsonReaderException.Create(this, "Unexpected end when reading bytes.");
} }
if (TokenType == JsonToken.EndArray) if (t == JsonToken.EndArray)
return null; return null;
throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, t));
} }
internal decimal? ReadAsDecimalInternal() internal decimal? ReadAsDecimalInternal()
{ {
_readType = ReadType.ReadAsDecimal; _readType = ReadType.ReadAsDecimal;
JsonToken t;
do do
{ {
if (!ReadInternal()) if (!ReadInternal())
@@ -506,9 +522,13 @@ namespace Newtonsoft.Json
SetToken(JsonToken.None); SetToken(JsonToken.None);
return null; return null;
} }
} while (TokenType == JsonToken.Comment); else
{
t = TokenType;
}
} while (t == JsonToken.Comment);
if (TokenType == JsonToken.Integer || TokenType == JsonToken.Float) if (t == JsonToken.Integer || t == JsonToken.Float)
{ {
if (!(Value is decimal)) if (!(Value is decimal))
SetToken(JsonToken.Float, Convert.ToDecimal(Value, CultureInfo.InvariantCulture)); SetToken(JsonToken.Float, Convert.ToDecimal(Value, CultureInfo.InvariantCulture));
@@ -516,11 +536,11 @@ namespace Newtonsoft.Json
return (decimal)Value; return (decimal)Value;
} }
if (TokenType == JsonToken.Null) if (t == JsonToken.Null)
return null; return null;
decimal d; decimal d;
if (TokenType == JsonToken.String) if (t == JsonToken.String)
{ {
string s = (string)Value; string s = (string)Value;
if (string.IsNullOrEmpty(s)) if (string.IsNullOrEmpty(s))
@@ -540,16 +560,18 @@ namespace Newtonsoft.Json
} }
} }
if (TokenType == JsonToken.EndArray) if (t == JsonToken.EndArray)
return null; return null;
throw JsonReaderException.Create(this, "Error reading decimal. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); throw JsonReaderException.Create(this, "Error reading decimal. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, t));
} }
internal int? ReadAsInt32Internal() internal int? ReadAsInt32Internal()
{ {
_readType = ReadType.ReadAsInt32; _readType = ReadType.ReadAsInt32;
JsonToken t;
do do
{ {
if (!ReadInternal()) if (!ReadInternal())
@@ -557,9 +579,13 @@ namespace Newtonsoft.Json
SetToken(JsonToken.None); SetToken(JsonToken.None);
return null; return null;
} }
} while (TokenType == JsonToken.Comment); else
{
t = TokenType;
}
} while (t == JsonToken.Comment);
if (TokenType == JsonToken.Integer || TokenType == JsonToken.Float) if (t == JsonToken.Integer || t == JsonToken.Float)
{ {
if (!(Value is int)) if (!(Value is int))
SetToken(JsonToken.Integer, Convert.ToInt32(Value, CultureInfo.InvariantCulture)); SetToken(JsonToken.Integer, Convert.ToInt32(Value, CultureInfo.InvariantCulture));
@@ -567,11 +593,11 @@ namespace Newtonsoft.Json
return (int)Value; return (int)Value;
} }
if (TokenType == JsonToken.Null) if (t == JsonToken.Null)
return null; return null;
int i; int i;
if (TokenType == JsonToken.String) if (t == JsonToken.String)
{ {
string s = (string)Value; string s = (string)Value;
if (string.IsNullOrEmpty(s)) if (string.IsNullOrEmpty(s))
@@ -591,7 +617,7 @@ namespace Newtonsoft.Json
} }
} }
if (TokenType == JsonToken.EndArray) if (t == JsonToken.EndArray)
return null; return null;
throw JsonReaderException.Create(this, "Error reading integer. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); throw JsonReaderException.Create(this, "Error reading integer. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
@@ -601,6 +627,8 @@ namespace Newtonsoft.Json
{ {
_readType = ReadType.ReadAsString; _readType = ReadType.ReadAsString;
JsonToken t;
do do
{ {
if (!ReadInternal()) if (!ReadInternal())
@@ -608,15 +636,19 @@ namespace Newtonsoft.Json
SetToken(JsonToken.None); SetToken(JsonToken.None);
return null; return null;
} }
} while (TokenType == JsonToken.Comment); else
{
t = TokenType;
}
} while (t == JsonToken.Comment);
if (TokenType == JsonToken.String) if (t == JsonToken.String)
return (string)Value; return (string)Value;
if (TokenType == JsonToken.Null) if (t == JsonToken.Null)
return null; return null;
if (IsPrimitiveToken(TokenType)) if (IsPrimitiveToken(t))
{ {
if (Value != null) if (Value != null)
{ {
@@ -631,10 +663,10 @@ namespace Newtonsoft.Json
} }
} }
if (TokenType == JsonToken.EndArray) if (t == JsonToken.EndArray)
return null; return null;
throw JsonReaderException.Create(this, "Error reading string. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); throw JsonReaderException.Create(this, "Error reading string. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, t));
} }
internal DateTime? ReadAsDateTimeInternal() internal DateTime? ReadAsDateTimeInternal()
+5 -5
View File
@@ -78,7 +78,7 @@ namespace Newtonsoft.Json
_reader = reader; _reader = reader;
_lineNumber = 1; _lineNumber = 1;
_chars = new char[4097]; _chars = new char[2049];
} }
#if DEBUG #if DEBUG
@@ -92,7 +92,7 @@ namespace Newtonsoft.Json
{ {
if (_buffer == null) if (_buffer == null)
{ {
_buffer = new StringBuffer(4096); _buffer = new StringBuffer(2048);
} }
else else
{ {
@@ -134,7 +134,7 @@ namespace Newtonsoft.Json
string text = _stringReference.ToString(); string text = _stringReference.ToString();
SetToken(JsonToken.String, text); SetToken(JsonToken.String, text);
QuoteChar = quote; _quoteChar = quote;
} }
else else
{ {
@@ -161,7 +161,7 @@ namespace Newtonsoft.Json
} }
SetToken(JsonToken.String, text); SetToken(JsonToken.String, text);
QuoteChar = quote; _quoteChar = quote;
} }
} }
@@ -846,7 +846,7 @@ namespace Newtonsoft.Json
_charPos++; _charPos++;
SetToken(JsonToken.PropertyName, propertyName); SetToken(JsonToken.PropertyName, propertyName);
QuoteChar = quoteChar; _quoteChar = quoteChar;
ClearRecentString(); ClearRecentString();
return true; return true;
@@ -70,11 +70,18 @@ namespace Newtonsoft.Json.Serialization
{ {
internal bool IsNullable; internal bool IsNullable;
internal bool IsConvertable; internal bool IsConvertable;
internal bool IsSealed;
internal Type NonNullableUnderlyingType; internal Type NonNullableUnderlyingType;
internal ReadType InternalReadType; internal ReadType InternalReadType;
internal JsonContractType ContractType; internal JsonContractType ContractType;
internal bool IsReadOnlyOrFixedSize; internal bool IsReadOnlyOrFixedSize;
private List<SerializationCallback> _onDeserializedCallbacks;
private IList<SerializationCallback> _onDeserializingCallbacks;
private IList<SerializationCallback> _onSerializedCallbacks;
private IList<SerializationCallback> _onSerializingCallbacks;
private IList<SerializationErrorCallback> _onErrorCallbacks;
/// <summary> /// <summary>
/// Gets the underlying type for the contract. /// Gets the underlying type for the contract.
/// </summary> /// </summary>
@@ -107,31 +114,76 @@ namespace Newtonsoft.Json.Serialization
/// Gets or sets all methods called immediately after deserialization of the object. /// Gets or sets all methods called immediately after deserialization of the object.
/// </summary> /// </summary>
/// <value>The methods called immediately after deserialization of the object.</value> /// <value>The methods called immediately after deserialization of the object.</value>
public IList<SerializationCallback> OnDeserializedCallbacks { get; private set; } public IList<SerializationCallback> OnDeserializedCallbacks
{
get
{
if (_onDeserializedCallbacks == null)
_onDeserializedCallbacks = new List<SerializationCallback>();
return _onDeserializedCallbacks;
}
}
/// <summary> /// <summary>
/// Gets or sets all methods called during deserialization of the object. /// Gets or sets all methods called during deserialization of the object.
/// </summary> /// </summary>
/// <value>The methods called during deserialization of the object.</value> /// <value>The methods called during deserialization of the object.</value>
public IList<SerializationCallback> OnDeserializingCallbacks { get; private set; } public IList<SerializationCallback> OnDeserializingCallbacks
{
get
{
if (_onDeserializingCallbacks == null)
_onDeserializingCallbacks = new List<SerializationCallback>();
return _onDeserializingCallbacks;
}
}
/// <summary> /// <summary>
/// Gets or sets all methods called after serialization of the object graph. /// Gets or sets all methods called after serialization of the object graph.
/// </summary> /// </summary>
/// <value>The methods called after serialization of the object graph.</value> /// <value>The methods called after serialization of the object graph.</value>
public IList<SerializationCallback> OnSerializedCallbacks { get; private set; } public IList<SerializationCallback> OnSerializedCallbacks
{
get
{
if (_onSerializedCallbacks == null)
_onSerializedCallbacks = new List<SerializationCallback>();
return _onSerializedCallbacks;
}
}
/// <summary> /// <summary>
/// Gets or sets all methods called before serialization of the object. /// Gets or sets all methods called before serialization of the object.
/// </summary> /// </summary>
/// <value>The methods called before serialization of the object.</value> /// <value>The methods called before serialization of the object.</value>
public IList<SerializationCallback> OnSerializingCallbacks { get; private set; } public IList<SerializationCallback> OnSerializingCallbacks
{
get
{
if (_onSerializingCallbacks == null)
_onSerializingCallbacks = new List<SerializationCallback>();
return _onSerializingCallbacks;
}
}
/// <summary> /// <summary>
/// Gets or sets all method called when an error is thrown during the serialization of the object. /// Gets or sets all method called when an error is thrown during the serialization of the object.
/// </summary> /// </summary>
/// <value>The methods called when an error is thrown during the serialization of the object.</value> /// <value>The methods called when an error is thrown during the serialization of the object.</value>
public IList<SerializationErrorCallback> OnErrorCallbacks { get; private set; } public IList<SerializationErrorCallback> OnErrorCallbacks
{
get
{
if (_onErrorCallbacks == null)
_onErrorCallbacks = new List<SerializationErrorCallback>();
return _onErrorCallbacks;
}
}
/// <summary> /// <summary>
/// Gets or sets the method called immediately after deserialization of the object. /// Gets or sets the method called immediately after deserialization of the object.
@@ -226,6 +278,8 @@ namespace Newtonsoft.Json.Serialization
UnderlyingType = underlyingType; UnderlyingType = underlyingType;
IsSealed = underlyingType.IsSealed();
IsNullable = ReflectionUtils.IsNullable(underlyingType); IsNullable = ReflectionUtils.IsNullable(underlyingType);
NonNullableUnderlyingType = (IsNullable && ReflectionUtils.IsNullableType(underlyingType)) ? Nullable.GetUnderlyingType(underlyingType) : underlyingType; NonNullableUnderlyingType = (IsNullable && ReflectionUtils.IsNullableType(underlyingType)) ? Nullable.GetUnderlyingType(underlyingType) : underlyingType;
@@ -233,6 +287,7 @@ namespace Newtonsoft.Json.Serialization
IsConvertable = ConvertUtils.IsConvertible(NonNullableUnderlyingType); IsConvertable = ConvertUtils.IsConvertible(NonNullableUnderlyingType);
if (NonNullableUnderlyingType == typeof(byte[])) if (NonNullableUnderlyingType == typeof(byte[]))
{ {
InternalReadType = ReadType.ReadAsBytes; InternalReadType = ReadType.ReadAsBytes;
@@ -263,51 +318,60 @@ namespace Newtonsoft.Json.Serialization
{ {
InternalReadType = ReadType.Read; InternalReadType = ReadType.Read;
} }
OnErrorCallbacks = new List<SerializationErrorCallback>();
OnSerializedCallbacks = new List<SerializationCallback>();
OnSerializingCallbacks = new List<SerializationCallback>();
OnDeserializedCallbacks = new List<SerializationCallback>();
OnDeserializingCallbacks = new List<SerializationCallback>();
} }
internal void InvokeOnSerializing(object o, StreamingContext context) internal void InvokeOnSerializing(object o, StreamingContext context)
{ {
foreach (SerializationCallback callback in OnSerializingCallbacks) if (_onSerializingCallbacks != null)
{ {
callback(o, context); foreach (SerializationCallback callback in _onSerializingCallbacks)
{
callback(o, context);
}
} }
} }
internal void InvokeOnSerialized(object o, StreamingContext context) internal void InvokeOnSerialized(object o, StreamingContext context)
{ {
foreach (SerializationCallback callback in OnSerializedCallbacks) if (_onSerializedCallbacks != null)
{ {
callback(o, context); foreach (SerializationCallback callback in _onSerializedCallbacks)
{
callback(o, context);
}
} }
} }
internal void InvokeOnDeserializing(object o, StreamingContext context) internal void InvokeOnDeserializing(object o, StreamingContext context)
{ {
foreach (SerializationCallback callback in OnDeserializingCallbacks) if (_onDeserializingCallbacks != null)
{ {
callback(o, context); foreach (SerializationCallback callback in _onDeserializingCallbacks)
{
callback(o, context);
}
} }
} }
internal void InvokeOnDeserialized(object o, StreamingContext context) internal void InvokeOnDeserialized(object o, StreamingContext context)
{ {
foreach (SerializationCallback callback in OnDeserializedCallbacks) if (_onDeserializedCallbacks != null)
{ {
callback(o, context); foreach (SerializationCallback callback in _onDeserializedCallbacks)
{
callback(o, context);
}
} }
} }
internal void InvokeOnError(object o, StreamingContext context, ErrorContext errorContext) internal void InvokeOnError(object o, StreamingContext context, ErrorContext errorContext)
{ {
foreach (SerializationErrorCallback callback in OnErrorCallbacks) if (_onErrorCallbacks != null)
{ {
callback(o, context, errorContext); foreach (SerializationErrorCallback callback in _onErrorCallbacks)
{
callback(o, context, errorContext);
}
} }
} }
@@ -133,7 +133,6 @@ namespace Newtonsoft.Json.Serialization
return Dictionary.TryGetValue(key, out item); return Dictionary.TryGetValue(key, out item);
} }
/// <summary> /// <summary>
/// Gets a property by property name. /// Gets a property by property name.
/// </summary> /// </summary>
@@ -261,15 +261,17 @@ namespace Newtonsoft.Json.Serialization
case JsonToken.Bytes: case JsonToken.Bytes:
return EnsureType(reader, reader.Value, CultureInfo.InvariantCulture, contract, objectType); return EnsureType(reader, reader.Value, CultureInfo.InvariantCulture, contract, objectType);
case JsonToken.String: case JsonToken.String:
string s = (string)reader.Value;
// convert empty string to null automatically for nullable types // convert empty string to null automatically for nullable types
if (string.IsNullOrEmpty((string)reader.Value) && objectType != typeof(string) && objectType != typeof(object) && contract != null && contract.IsNullable) if (string.IsNullOrEmpty(s) && objectType != typeof(string) && objectType != typeof(object) && contract != null && contract.IsNullable)
return null; return null;
// string that needs to be returned as a byte array should be base 64 decoded // string that needs to be returned as a byte array should be base 64 decoded
if (objectType == typeof (byte[])) if (objectType == typeof (byte[]))
return Convert.FromBase64String((string) reader.Value); return Convert.FromBase64String(s);
return EnsureType(reader, reader.Value, CultureInfo.InvariantCulture, contract, objectType); return EnsureType(reader, s, CultureInfo.InvariantCulture, contract, objectType);
case JsonToken.StartConstructor: case JsonToken.StartConstructor:
string constructorName = reader.Value.ToString(); string constructorName = reader.Value.ToString();
@@ -778,6 +780,8 @@ To fix this error either change the JSON to a {1} or change the deserialized typ
return true; return true;
} }
JsonToken tokenType = reader.TokenType;
if (property.PropertyContract == null) if (property.PropertyContract == null)
property.PropertyContract = GetContractSafe(property.PropertyType); property.PropertyContract = GetContractSafe(property.PropertyType);
@@ -785,7 +789,7 @@ To fix this error either change the JSON to a {1} or change the deserialized typ
property.ObjectCreationHandling.GetValueOrDefault(Serializer.ObjectCreationHandling); property.ObjectCreationHandling.GetValueOrDefault(Serializer.ObjectCreationHandling);
if ((objectCreationHandling != ObjectCreationHandling.Replace) if ((objectCreationHandling != ObjectCreationHandling.Replace)
&& (reader.TokenType == JsonToken.StartArray || reader.TokenType == JsonToken.StartObject) && (tokenType == JsonToken.StartArray || tokenType == JsonToken.StartObject)
&& property.Readable) && property.Readable)
{ {
currentValue = property.ValueProvider.GetValue(target); currentValue = property.ValueProvider.GetValue(target);
@@ -806,7 +810,7 @@ To fix this error either change the JSON to a {1} or change the deserialized typ
} }
// test tokentype here because null might not be convertable to some types, e.g. ignoring null when applied to DateTime // test tokentype here because null might not be convertable to some types, e.g. ignoring null when applied to DateTime
if (property.NullValueHandling.GetValueOrDefault(Serializer.NullValueHandling) == NullValueHandling.Ignore && reader.TokenType == JsonToken.Null) if (property.NullValueHandling.GetValueOrDefault(Serializer.NullValueHandling) == NullValueHandling.Ignore && tokenType == JsonToken.Null)
{ {
reader.Skip(); reader.Skip();
return true; return true;
@@ -814,7 +818,7 @@ To fix this error either change the JSON to a {1} or change the deserialized typ
// test tokentype here because default value might not be convertable to actual type, e.g. default of "" for DateTime // test tokentype here because default value might not be convertable to actual type, e.g. default of "" for DateTime
if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer.DefaultValueHandling), DefaultValueHandling.Ignore) if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer.DefaultValueHandling), DefaultValueHandling.Ignore)
&& JsonReader.IsPrimitiveToken(reader.TokenType) && JsonReader.IsPrimitiveToken(tokenType)
&& MiscellaneousUtils.ValueEquals(reader.Value, property.GetResolvedDefaultValue())) && MiscellaneousUtils.ValueEquals(reader.Value, property.GetResolvedDefaultValue()))
{ {
reader.Skip(); reader.Skip();
@@ -370,8 +370,9 @@ namespace Newtonsoft.Json.Serialization
int initialDepth = writer.Top; int initialDepth = writer.Top;
foreach (JsonProperty property in contract.Properties) for (int index = 0; index < contract.Properties.Count; index++)
{ {
JsonProperty property = contract.Properties[index];
try try
{ {
object memberValue; object memberValue;
@@ -407,7 +408,7 @@ namespace Newtonsoft.Json.Serialization
property.PropertyContract = Serializer.ContractResolver.ResolveContract(property.PropertyType); property.PropertyContract = Serializer.ContractResolver.ResolveContract(property.PropertyType);
memberValue = property.ValueProvider.GetValue(value); memberValue = property.ValueProvider.GetValue(value);
memberContract = (property.PropertyContract.UnderlyingType.IsSealed()) ? property.PropertyContract : GetContractSafe(memberValue); memberContract = (property.PropertyContract.IsSealed) ? property.PropertyContract : GetContractSafe(memberValue);
if (ShouldWriteProperty(memberValue, property)) if (ShouldWriteProperty(memberValue, property))
{ {
@@ -719,8 +720,10 @@ To fix this error either change the environment to be fully trusted, change the
int initialDepth = writer.Top; int initialDepth = writer.Top;
foreach (JsonProperty property in contract.Properties) for (int index = 0; index < contract.Properties.Count; index++)
{ {
JsonProperty property = contract.Properties[index];
// only write non-dynamic properties that have an explicit attribute // only write non-dynamic properties that have an explicit attribute
if (property.HasMemberAttribute) if (property.HasMemberAttribute)
{ {