-Added CurrentToken to JTokenWriter
-Added WriteToken(JsonToken, object) to JsonWriter
This commit is contained in:
@@ -825,6 +825,49 @@ namespace Newtonsoft.Json.Tests
|
||||
]", sb.ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WriteTokenDirect()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
StringWriter sw = new StringWriter(sb);
|
||||
|
||||
using (JsonWriter jsonWriter = new JsonTextWriter(sw))
|
||||
{
|
||||
jsonWriter.WriteToken(JsonToken.StartArray);
|
||||
jsonWriter.WriteToken(JsonToken.Integer, 1);
|
||||
jsonWriter.WriteToken(JsonToken.StartObject);
|
||||
jsonWriter.WriteToken(JsonToken.PropertyName, "string");
|
||||
jsonWriter.WriteToken(JsonToken.Integer, int.MaxValue);
|
||||
jsonWriter.WriteToken(JsonToken.EndObject);
|
||||
jsonWriter.WriteToken(JsonToken.EndArray);
|
||||
}
|
||||
|
||||
Assert.AreEqual(@"[1,{""string"":2147483647}]", sb.ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WriteTokenDirect_BadValue()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
StringWriter sw = new StringWriter(sb);
|
||||
|
||||
using (JsonWriter jsonWriter = new JsonTextWriter(sw))
|
||||
{
|
||||
jsonWriter.WriteToken(JsonToken.StartArray);
|
||||
|
||||
ExceptionAssert.Throws<FormatException>(() =>
|
||||
{
|
||||
jsonWriter.WriteToken(JsonToken.Integer, "three");
|
||||
}, "Input string was not in a correct format.");
|
||||
|
||||
ExceptionAssert.Throws<ArgumentNullException>(() =>
|
||||
{
|
||||
jsonWriter.WriteToken(JsonToken.Integer);
|
||||
}, @"Value cannot be null.
|
||||
Parameter name: value");
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BadWriteEndArray()
|
||||
{
|
||||
|
||||
@@ -140,6 +140,62 @@ namespace Newtonsoft.Json.Tests.Linq
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CurrentToken()
|
||||
{
|
||||
using (JTokenWriter jsonWriter = new JTokenWriter())
|
||||
{
|
||||
Assert.AreEqual(WriteState.Start, jsonWriter.WriteState);
|
||||
Assert.AreEqual(null, jsonWriter.CurrentToken);
|
||||
|
||||
jsonWriter.WriteStartObject();
|
||||
Assert.AreEqual(WriteState.Object, jsonWriter.WriteState);
|
||||
Assert.AreEqual(jsonWriter.Token, jsonWriter.CurrentToken);
|
||||
|
||||
JObject o = (JObject)jsonWriter.Token;
|
||||
|
||||
jsonWriter.WritePropertyName("CPU");
|
||||
Assert.AreEqual(WriteState.Property, jsonWriter.WriteState);
|
||||
Assert.AreEqual(o.Property("CPU"), jsonWriter.CurrentToken);
|
||||
|
||||
jsonWriter.WriteValue("Intel");
|
||||
Assert.AreEqual(WriteState.Object, jsonWriter.WriteState);
|
||||
Assert.AreEqual(o["CPU"], jsonWriter.CurrentToken);
|
||||
|
||||
jsonWriter.WritePropertyName("Drives");
|
||||
Assert.AreEqual(WriteState.Property, jsonWriter.WriteState);
|
||||
Assert.AreEqual(o.Property("Drives"), jsonWriter.CurrentToken);
|
||||
|
||||
jsonWriter.WriteStartArray();
|
||||
Assert.AreEqual(WriteState.Array, jsonWriter.WriteState);
|
||||
Assert.AreEqual(o["Drives"], jsonWriter.CurrentToken);
|
||||
|
||||
JArray a = (JArray)jsonWriter.CurrentToken;
|
||||
|
||||
jsonWriter.WriteValue("DVD read/writer");
|
||||
Assert.AreEqual(WriteState.Array, jsonWriter.WriteState);
|
||||
Assert.AreEqual(a[a.Count - 1], jsonWriter.CurrentToken);
|
||||
|
||||
#if !(NET20 || NET35 || PORTABLE || ASPNETCORE50 || PORTABLE40)
|
||||
jsonWriter.WriteValue(new BigInteger(123));
|
||||
Assert.AreEqual(WriteState.Array, jsonWriter.WriteState);
|
||||
Assert.AreEqual(a[a.Count - 1], jsonWriter.CurrentToken);
|
||||
#endif
|
||||
|
||||
jsonWriter.WriteValue(new byte[0]);
|
||||
Assert.AreEqual(WriteState.Array, jsonWriter.WriteState);
|
||||
Assert.AreEqual(a[a.Count - 1], jsonWriter.CurrentToken);
|
||||
|
||||
jsonWriter.WriteEnd();
|
||||
Assert.AreEqual(WriteState.Object, jsonWriter.WriteState);
|
||||
Assert.AreEqual(a, jsonWriter.CurrentToken);
|
||||
|
||||
jsonWriter.WriteEndObject();
|
||||
Assert.AreEqual(WriteState.Start, jsonWriter.WriteState);
|
||||
Assert.AreEqual(o, jsonWriter.CurrentToken);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WriteComment()
|
||||
{
|
||||
|
||||
@@ -449,6 +449,28 @@ namespace Newtonsoft.Json
|
||||
WriteToken(reader, writeChildren, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the <see cref="JsonToken"/> token and its value.
|
||||
/// </summary>
|
||||
/// <param name="token">The <see cref="JsonToken"/> to write.</param>
|
||||
/// <param name="value">
|
||||
/// The value to write.
|
||||
/// A value is only required for tokens that have an associated value, e.g. the <see cref="String"/> property name for <see cref="JsonToken.PropertyName"/>.
|
||||
/// A null value can be passed to the method for token's that don't have a value, e.g. <see cref="JsonToken.StartObject"/>.</param>
|
||||
public void WriteToken(JsonToken token, object value)
|
||||
{
|
||||
WriteTokenInternal(token, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the <see cref="JsonToken"/> token.
|
||||
/// </summary>
|
||||
/// <param name="token">The <see cref="JsonToken"/> to write.</param>
|
||||
public void WriteToken(JsonToken token)
|
||||
{
|
||||
WriteTokenInternal(token, null);
|
||||
}
|
||||
|
||||
internal void WriteToken(JsonReader reader, bool writeChildren, bool writeDateConstructorAsDate)
|
||||
{
|
||||
int initialDepth;
|
||||
@@ -467,96 +489,11 @@ namespace Newtonsoft.Json
|
||||
{
|
||||
do
|
||||
{
|
||||
switch (reader.TokenType)
|
||||
{
|
||||
case JsonToken.None:
|
||||
// read to next
|
||||
break;
|
||||
case JsonToken.StartObject:
|
||||
WriteStartObject();
|
||||
break;
|
||||
case JsonToken.StartArray:
|
||||
WriteStartArray();
|
||||
break;
|
||||
case JsonToken.StartConstructor:
|
||||
string constructorName = reader.Value.ToString();
|
||||
// write a JValue date when the constructor is for a date
|
||||
if (writeDateConstructorAsDate && string.Equals(constructorName, "Date", StringComparison.Ordinal))
|
||||
WriteConstructorDate(reader);
|
||||
else
|
||||
WriteStartConstructor(reader.Value.ToString());
|
||||
break;
|
||||
case JsonToken.PropertyName:
|
||||
WritePropertyName(reader.Value.ToString());
|
||||
break;
|
||||
case JsonToken.Comment:
|
||||
WriteComment((reader.Value != null) ? reader.Value.ToString() : null);
|
||||
break;
|
||||
case JsonToken.Integer:
|
||||
#if !(NET20 || NET35 || PORTABLE || PORTABLE40)
|
||||
if (reader.Value is BigInteger)
|
||||
{
|
||||
WriteValue((BigInteger)reader.Value);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
WriteValue(Convert.ToInt64(reader.Value, CultureInfo.InvariantCulture));
|
||||
}
|
||||
break;
|
||||
case JsonToken.Float:
|
||||
object value = reader.Value;
|
||||
|
||||
if (value is decimal)
|
||||
WriteValue((decimal)value);
|
||||
else if (value is double)
|
||||
WriteValue((double)value);
|
||||
else if (value is float)
|
||||
WriteValue((float)value);
|
||||
else
|
||||
WriteValue(Convert.ToDouble(value, CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case JsonToken.String:
|
||||
WriteValue(reader.Value.ToString());
|
||||
break;
|
||||
case JsonToken.Boolean:
|
||||
WriteValue(Convert.ToBoolean(reader.Value, CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case JsonToken.Null:
|
||||
WriteNull();
|
||||
break;
|
||||
case JsonToken.Undefined:
|
||||
WriteUndefined();
|
||||
break;
|
||||
case JsonToken.EndObject:
|
||||
WriteEndObject();
|
||||
break;
|
||||
case JsonToken.EndArray:
|
||||
WriteEndArray();
|
||||
break;
|
||||
case JsonToken.EndConstructor:
|
||||
WriteEndConstructor();
|
||||
break;
|
||||
case JsonToken.Date:
|
||||
#if !NET20
|
||||
if (reader.Value is DateTimeOffset)
|
||||
WriteValue((DateTimeOffset)reader.Value);
|
||||
else
|
||||
#endif
|
||||
WriteValue(Convert.ToDateTime(reader.Value, CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case JsonToken.Raw:
|
||||
WriteRawValue((reader.Value != null) ? reader.Value.ToString() : null);
|
||||
break;
|
||||
case JsonToken.Bytes:
|
||||
if (reader.Value is Guid)
|
||||
WriteValue((Guid)reader.Value);
|
||||
else
|
||||
WriteValue((byte[])reader.Value);
|
||||
break;
|
||||
default:
|
||||
throw MiscellaneousUtils.CreateArgumentOutOfRangeException("TokenType", reader.TokenType, "Unexpected token type.");
|
||||
}
|
||||
// write a JValue date when the constructor is for a date
|
||||
if (writeDateConstructorAsDate && reader.TokenType == JsonToken.StartConstructor && string.Equals(reader.Value.ToString(), "Date", StringComparison.Ordinal))
|
||||
WriteConstructorDate(reader);
|
||||
else
|
||||
WriteTokenInternal(reader.TokenType, reader.Value);
|
||||
} while (
|
||||
// stop if we have reached the end of the token being read
|
||||
initialDepth - 1 < reader.Depth - (IsEndToken(reader.TokenType) ? 1 : 0)
|
||||
@@ -564,6 +501,101 @@ namespace Newtonsoft.Json
|
||||
&& reader.Read());
|
||||
}
|
||||
|
||||
private void WriteTokenInternal(JsonToken tokenType, object value)
|
||||
{
|
||||
switch (tokenType)
|
||||
{
|
||||
case JsonToken.None:
|
||||
// read to next
|
||||
break;
|
||||
case JsonToken.StartObject:
|
||||
WriteStartObject();
|
||||
break;
|
||||
case JsonToken.StartArray:
|
||||
WriteStartArray();
|
||||
break;
|
||||
case JsonToken.StartConstructor:
|
||||
ValidationUtils.ArgumentNotNull(value, "value");
|
||||
WriteStartConstructor(value.ToString());
|
||||
break;
|
||||
case JsonToken.PropertyName:
|
||||
ValidationUtils.ArgumentNotNull(value, "value");
|
||||
WritePropertyName(value.ToString());
|
||||
break;
|
||||
case JsonToken.Comment:
|
||||
WriteComment((value != null) ? value.ToString() : null);
|
||||
break;
|
||||
case JsonToken.Integer:
|
||||
ValidationUtils.ArgumentNotNull(value, "value");
|
||||
#if !(NET20 || NET35 || PORTABLE || PORTABLE40)
|
||||
if (value is BigInteger)
|
||||
{
|
||||
WriteValue((BigInteger)value);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
WriteValue(Convert.ToInt64(value, CultureInfo.InvariantCulture));
|
||||
}
|
||||
break;
|
||||
case JsonToken.Float:
|
||||
ValidationUtils.ArgumentNotNull(value, "value");
|
||||
if (value is decimal)
|
||||
WriteValue((decimal)value);
|
||||
else if (value is double)
|
||||
WriteValue((double)value);
|
||||
else if (value is float)
|
||||
WriteValue((float)value);
|
||||
else
|
||||
WriteValue(Convert.ToDouble(value, CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case JsonToken.String:
|
||||
ValidationUtils.ArgumentNotNull(value, "value");
|
||||
WriteValue(value.ToString());
|
||||
break;
|
||||
case JsonToken.Boolean:
|
||||
ValidationUtils.ArgumentNotNull(value, "value");
|
||||
WriteValue(Convert.ToBoolean(value, CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case JsonToken.Null:
|
||||
WriteNull();
|
||||
break;
|
||||
case JsonToken.Undefined:
|
||||
WriteUndefined();
|
||||
break;
|
||||
case JsonToken.EndObject:
|
||||
WriteEndObject();
|
||||
break;
|
||||
case JsonToken.EndArray:
|
||||
WriteEndArray();
|
||||
break;
|
||||
case JsonToken.EndConstructor:
|
||||
WriteEndConstructor();
|
||||
break;
|
||||
case JsonToken.Date:
|
||||
ValidationUtils.ArgumentNotNull(value, "value");
|
||||
#if !NET20
|
||||
if (value is DateTimeOffset)
|
||||
WriteValue((DateTimeOffset)value);
|
||||
else
|
||||
#endif
|
||||
WriteValue(Convert.ToDateTime(value, CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case JsonToken.Raw:
|
||||
WriteRawValue((value != null) ? value.ToString() : null);
|
||||
break;
|
||||
case JsonToken.Bytes:
|
||||
ValidationUtils.ArgumentNotNull(value, "value");
|
||||
if (value is Guid)
|
||||
WriteValue((Guid)value);
|
||||
else
|
||||
WriteValue((byte[])value);
|
||||
break;
|
||||
default:
|
||||
throw MiscellaneousUtils.CreateArgumentOutOfRangeException("TokenType", tokenType, "Unexpected token type.");
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteConstructorDate(JsonReader reader)
|
||||
{
|
||||
if (!reader.Read())
|
||||
|
||||
@@ -33,7 +33,7 @@ using Newtonsoft.Json.Utilities;
|
||||
namespace Newtonsoft.Json.Linq
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data.
|
||||
/// Represents a writer that provides a fast, non-cached, forward-only way of generating JSON data.
|
||||
/// </summary>
|
||||
public class JTokenWriter : JsonWriter
|
||||
{
|
||||
@@ -41,6 +41,15 @@ namespace Newtonsoft.Json.Linq
|
||||
private JContainer _parent;
|
||||
// used when writer is writing single value and the value has no containing parent
|
||||
private JValue _value;
|
||||
private JToken _current;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="JToken"/> at the writer's current position.
|
||||
/// </summary>
|
||||
public JToken CurrentToken
|
||||
{
|
||||
get { return _current; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the token being writen.
|
||||
@@ -109,10 +118,12 @@ namespace Newtonsoft.Json.Linq
|
||||
_parent.AddAndSkipParentCheck(container);
|
||||
|
||||
_parent = container;
|
||||
_current = container;
|
||||
}
|
||||
|
||||
private void RemoveParent()
|
||||
{
|
||||
_current = _parent;
|
||||
_parent = _parent.Parent;
|
||||
|
||||
if (_parent != null && _parent.Type == JTokenType.Property)
|
||||
@@ -172,6 +183,7 @@ namespace Newtonsoft.Json.Linq
|
||||
if (_parent != null)
|
||||
{
|
||||
_parent.Add(value);
|
||||
_current = _parent.Last;
|
||||
|
||||
if (_parent.Type == JTokenType.Property)
|
||||
_parent = _parent.Parent;
|
||||
@@ -179,6 +191,7 @@ namespace Newtonsoft.Json.Linq
|
||||
else
|
||||
{
|
||||
_value = value ?? JValue.CreateNull();
|
||||
_current = _value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user