diff --git a/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs b/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs
index 85be33ef..b0e3c52d 100644
--- a/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs
+++ b/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs
@@ -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)
diff --git a/Src/Newtonsoft.Json/JsonTextWriter.cs b/Src/Newtonsoft.Json/JsonTextWriter.cs
index a14e0960..53287afd 100644
--- a/Src/Newtonsoft.Json/JsonTextWriter.cs
+++ b/Src/Newtonsoft.Json/JsonTextWriter.cs
@@ -329,7 +329,7 @@ namespace Newtonsoft.Json
///
public override void WriteNull()
{
- InternalWriteNull();
+ InternalWriteValue(JsonToken.Null);
WriteValueInternal(JsonConvert.Null, JsonToken.Null);
}
@@ -338,7 +338,7 @@ namespace Newtonsoft.Json
///
public override void WriteUndefined()
{
- InternalWriteUndefined();
+ InternalWriteValue(JsonToken.Undefined);
WriteValueInternal(JsonConvert.Undefined, JsonToken.Undefined);
}
diff --git a/Src/Newtonsoft.Json/JsonWriter.cs b/Src/Newtonsoft.Json/JsonWriter.cs
index 49296137..465f9705 100644
--- a/Src/Newtonsoft.Json/JsonWriter.cs
+++ b/Src/Newtonsoft.Json/JsonWriter.cs
@@ -358,13 +358,6 @@ namespace Newtonsoft.Json
InternalWriteStart(JsonToken.StartObject, JsonContainerType.Object);
}
- internal void InternalWriteStart(JsonToken token, JsonContainerType container)
- {
- UpdateScopeWithFinishedValue();
- AutoComplete(token);
- Push(container);
- }
-
///
/// Writes the end of a Json object.
///
@@ -406,11 +399,6 @@ namespace Newtonsoft.Json
InternalWriteEnd(JsonContainerType.Constructor);
}
- internal void InternalWriteEnd(JsonContainerType container)
- {
- AutoCompleteClose(container);
- }
-
///
/// Writes the property name of a name/value pair on a JSON object.
///
@@ -430,12 +418,6 @@ namespace Newtonsoft.Json
WritePropertyName(name);
}
- internal void InternalWritePropertyName(string name)
- {
- _currentPosition.PropertyName = name;
- AutoComplete(JsonToken.PropertyName);
- }
-
///
/// Writes the end of the current Json object or array.
///
@@ -775,13 +757,7 @@ namespace Newtonsoft.Json
///
public virtual void WriteNull()
{
- InternalWriteNull();
- }
-
- internal void InternalWriteNull()
- {
- UpdateScopeWithFinishedValue();
- AutoComplete(JsonToken.Null);
+ InternalWriteValue(JsonToken.Null);
}
///
@@ -789,13 +765,7 @@ namespace Newtonsoft.Json
///
public virtual void WriteUndefined()
{
- InternalWriteUndefined();
- }
-
- internal void InternalWriteUndefined()
- {
- UpdateScopeWithFinishedValue();
- AutoComplete(JsonToken.Undefined);
+ InternalWriteValue(JsonToken.Undefined);
}
///
@@ -807,10 +777,6 @@ namespace Newtonsoft.Json
InternalWriteRaw();
}
- internal void InternalWriteRaw()
- {
- }
-
///
/// Writes raw JSON where a value is expected and updates the writer's state.
///
@@ -832,12 +798,6 @@ namespace Newtonsoft.Json
InternalWriteValue(JsonToken.String);
}
- internal void InternalWriteValue(JsonToken token)
- {
- UpdateScopeWithFinishedValue();
- AutoComplete(token);
- }
-
///
/// Writes a value.
///
@@ -1265,11 +1225,6 @@ namespace Newtonsoft.Json
InternalWriteComment();
}
- internal void InternalWriteComment()
- {
- AutoComplete(JsonToken.Comment);
- }
-
///
/// Writes out the given white space.
///
@@ -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);
}
+
+ ///
+ /// Sets the state of the JsonWriter,
+ ///
+ /// The JsonToken being written.
+ /// The value being written.
+ 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);
+ }
}
}
\ No newline at end of file