-Added JsonWriter.SetWriteState to support inheriting and override JsonWriters

This commit is contained in:
James Newton-King
2013-04-21 21:41:04 +12:00
parent b6d3168ed8
commit c70eaaa004
3 changed files with 182 additions and 58 deletions
@@ -26,6 +26,11 @@
using System;
using System.Collections.Generic;
using System.Globalization;
#if NET20
using Newtonsoft.Json.Utilities.LinqBridge;
#else
using System.Linq;
#endif
using System.Runtime.Serialization;
using System.Text;
using System.Xml;
@@ -1312,6 +1317,83 @@ _____'propertyName': NaN
if (appendDelimiters)
writer.Write(delimiter);
}
[Test]
public void CustomJsonTextWriterTests()
{
StringWriter sw = new StringWriter();
CustomJsonTextWriter writer = new CustomJsonTextWriter(sw) { Formatting = Formatting.Indented };
writer.WriteStartObject();
Assert.AreEqual(WriteState.Object, writer.WriteState);
writer.WritePropertyName("Property1");
Assert.AreEqual(WriteState.Property, writer.WriteState);
Assert.AreEqual("Property1", writer.Path);
writer.WriteNull();
Assert.AreEqual(WriteState.Object, writer.WriteState);
writer.WriteEndObject();
Assert.AreEqual(WriteState.Start, writer.WriteState);
Assert.AreEqual(@"{{{
""1ytreporP"": NULL!!!
}}}", sw.ToString());
}
}
public class CustomJsonTextWriter : JsonTextWriter
{
private readonly TextWriter _writer;
public CustomJsonTextWriter(TextWriter textWriter) : base(textWriter)
{
_writer = textWriter;
}
public override void WritePropertyName(string name)
{
WritePropertyName(name, true);
}
public override void WritePropertyName(string name, bool escape)
{
SetWriteState(JsonToken.PropertyName, name);
if (QuoteName)
_writer.Write(QuoteChar);
_writer.Write(new string(name.Reverse().ToArray()));
if (QuoteName)
_writer.Write(QuoteChar);
_writer.Write(':');
}
public override void WriteNull()
{
SetWriteState(JsonToken.Null, null);
_writer.Write("NULL!!!");
}
public override void WriteStartObject()
{
SetWriteState(JsonToken.StartObject, null);
_writer.Write("{{{");
}
public override void WriteEndObject()
{
SetWriteState(JsonToken.EndObject, null);
}
protected override void WriteEnd(JsonToken token)
{
if (token == JsonToken.EndObject)
_writer.Write("}}}");
else
base.WriteEnd(token);
}
}
#if !(PORTABLE || NETFX_CORE)
+2 -2
View File
@@ -329,7 +329,7 @@ namespace Newtonsoft.Json
/// </summary>
public override void WriteNull()
{
InternalWriteNull();
InternalWriteValue(JsonToken.Null);
WriteValueInternal(JsonConvert.Null, JsonToken.Null);
}
@@ -338,7 +338,7 @@ namespace Newtonsoft.Json
/// </summary>
public override void WriteUndefined()
{
InternalWriteUndefined();
InternalWriteValue(JsonToken.Undefined);
WriteValueInternal(JsonConvert.Undefined, JsonToken.Undefined);
}
+98 -56
View File
@@ -358,13 +358,6 @@ namespace Newtonsoft.Json
InternalWriteStart(JsonToken.StartObject, JsonContainerType.Object);
}
internal void InternalWriteStart(JsonToken token, JsonContainerType container)
{
UpdateScopeWithFinishedValue();
AutoComplete(token);
Push(container);
}
/// <summary>
/// Writes the end of a Json object.
/// </summary>
@@ -406,11 +399,6 @@ namespace Newtonsoft.Json
InternalWriteEnd(JsonContainerType.Constructor);
}
internal void InternalWriteEnd(JsonContainerType container)
{
AutoCompleteClose(container);
}
/// <summary>
/// Writes the property name of a name/value pair on a JSON object.
/// </summary>
@@ -430,12 +418,6 @@ namespace Newtonsoft.Json
WritePropertyName(name);
}
internal void InternalWritePropertyName(string name)
{
_currentPosition.PropertyName = name;
AutoComplete(JsonToken.PropertyName);
}
/// <summary>
/// Writes the end of the current Json object or array.
/// </summary>
@@ -775,13 +757,7 @@ namespace Newtonsoft.Json
/// </summary>
public virtual void WriteNull()
{
InternalWriteNull();
}
internal void InternalWriteNull()
{
UpdateScopeWithFinishedValue();
AutoComplete(JsonToken.Null);
InternalWriteValue(JsonToken.Null);
}
/// <summary>
@@ -789,13 +765,7 @@ namespace Newtonsoft.Json
/// </summary>
public virtual void WriteUndefined()
{
InternalWriteUndefined();
}
internal void InternalWriteUndefined()
{
UpdateScopeWithFinishedValue();
AutoComplete(JsonToken.Undefined);
InternalWriteValue(JsonToken.Undefined);
}
/// <summary>
@@ -807,10 +777,6 @@ namespace Newtonsoft.Json
InternalWriteRaw();
}
internal void InternalWriteRaw()
{
}
/// <summary>
/// Writes raw JSON where a value is expected and updates the writer's state.
/// </summary>
@@ -832,12 +798,6 @@ namespace Newtonsoft.Json
InternalWriteValue(JsonToken.String);
}
internal void InternalWriteValue(JsonToken token)
{
UpdateScopeWithFinishedValue();
AutoComplete(token);
}
/// <summary>
/// Writes a <see cref="Int32"/> value.
/// </summary>
@@ -1265,11 +1225,6 @@ namespace Newtonsoft.Json
InternalWriteComment();
}
internal void InternalWriteComment()
{
AutoComplete(JsonToken.Comment);
}
/// <summary>
/// Writes out the given white space.
/// </summary>
@@ -1279,15 +1234,6 @@ namespace Newtonsoft.Json
InternalWriteWhitespace(ws);
}
internal void InternalWriteWhitespace(string ws)
{
if (ws != null)
{
if (!StringUtils.IsWhiteSpace(ws))
throw JsonWriterException.Create(this, "Only white space characters should be used.", null);
}
}
void IDisposable.Dispose()
{
Dispose(true);
@@ -1456,5 +1402,101 @@ namespace Newtonsoft.Json
{
return JsonWriterException.Create(writer, "Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType()), null);
}
/// <summary>
/// Sets the state of the JsonWriter,
/// </summary>
/// <param name="token">The JsonToken being written.</param>
/// <param name="value">The value being written.</param>
protected void SetWriteState(JsonToken token, object value)
{
switch (token)
{
case JsonToken.StartObject:
InternalWriteStart(token, JsonContainerType.Object);
break;
case JsonToken.StartArray:
InternalWriteStart(token, JsonContainerType.Array);
break;
case JsonToken.StartConstructor:
InternalWriteStart(token, JsonContainerType.Constructor);
break;
case JsonToken.PropertyName:
if (!(value is string))
throw new ArgumentException("A name is required when setting property name state.", "value");
InternalWritePropertyName((string)value);
break;
case JsonToken.Comment:
InternalWriteComment();
break;
case JsonToken.Raw:
InternalWriteRaw();
break;
case JsonToken.Integer:
case JsonToken.Float:
case JsonToken.String:
case JsonToken.Boolean:
case JsonToken.Date:
case JsonToken.Bytes:
case JsonToken.Null:
case JsonToken.Undefined:
InternalWriteValue(token);
break;
case JsonToken.EndObject:
InternalWriteEnd(JsonContainerType.Object);
break;
case JsonToken.EndArray:
InternalWriteEnd(JsonContainerType.Array);
break;
case JsonToken.EndConstructor:
InternalWriteEnd(JsonContainerType.Constructor);
break;
default:
throw new ArgumentOutOfRangeException("token");
}
}
internal void InternalWriteEnd(JsonContainerType container)
{
AutoCompleteClose(container);
}
internal void InternalWritePropertyName(string name)
{
_currentPosition.PropertyName = name;
AutoComplete(JsonToken.PropertyName);
}
internal void InternalWriteRaw()
{
}
internal void InternalWriteStart(JsonToken token, JsonContainerType container)
{
UpdateScopeWithFinishedValue();
AutoComplete(token);
Push(container);
}
internal void InternalWriteValue(JsonToken token)
{
UpdateScopeWithFinishedValue();
AutoComplete(token);
}
internal void InternalWriteWhitespace(string ws)
{
if (ws != null)
{
if (!StringUtils.IsWhiteSpace(ws))
throw JsonWriterException.Create(this, "Only white space characters should be used.", null);
}
}
internal void InternalWriteComment()
{
AutoComplete(JsonToken.Comment);
}
}
}