#region License // Copyright (c) 2007 James Newton-King // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, // copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. #endregion using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Xml; using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json { /// /// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data. /// public class JsonTextWriter : JsonWriter { private readonly TextWriter _writer; private Base64Encoder _base64Encoder; private char _indentChar; private int _indentation; private char _quoteChar; private bool _quoteName; private Base64Encoder Base64Encoder { get { if (_base64Encoder == null) _base64Encoder = new Base64Encoder(_writer); return _base64Encoder; } } /// /// Gets or sets how many IndentChars to write for each level in the hierarchy when is set to Formatting.Indented. /// public int Indentation { get { return _indentation; } set { if (value < 0) throw new ArgumentException("Indentation value must be greater than 0."); _indentation = value; } } /// /// Gets or sets which character to use to quote attribute values. /// public char QuoteChar { get { return _quoteChar; } set { if (value != '"' && value != '\'') throw new ArgumentException(@"Invalid JavaScript string quote character. Valid quote characters are ' and ""."); _quoteChar = value; } } /// /// Gets or sets which character to use for indenting when is set to Formatting.Indented. /// public char IndentChar { get { return _indentChar; } set { _indentChar = value; } } /// /// Gets or sets a value indicating whether object names will be surrounded with quotes. /// public bool QuoteName { get { return _quoteName; } set { _quoteName = value; } } /// /// Creates an instance of the JsonWriter class using the specified . /// /// The TextWriter to write to. public JsonTextWriter(TextWriter textWriter) { if (textWriter == null) throw new ArgumentNullException("textWriter"); _writer = textWriter; _quoteChar = '"'; _quoteName = true; _indentChar = ' '; _indentation = 2; } /// /// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. /// public override void Flush() { _writer.Flush(); } /// /// Closes this stream and the underlying stream. /// public override void Close() { base.Close(); _writer.Close(); } /// /// Writes the beginning of a Json object. /// public override void WriteStartObject() { base.WriteStartObject(); _writer.Write("{"); } /// /// Writes the beginning of a Json array. /// public override void WriteStartArray() { base.WriteStartArray(); _writer.Write("["); } /// /// Writes the start of a constructor with the given name. /// /// The name of the constructor. public override void WriteStartConstructor(string name) { base.WriteStartConstructor(name); _writer.Write("new "); _writer.Write(name); _writer.Write("("); } /// /// Writes the specified end token. /// /// The end token to write. protected override void WriteEnd(JsonToken token) { switch (token) { case JsonToken.EndObject: _writer.Write("}"); break; case JsonToken.EndArray: _writer.Write("]"); break; case JsonToken.EndConstructor: _writer.Write(")"); break; default: throw new JsonWriterException("Invalid JsonToken: " + token); } } /// /// Writes the property name of a name/value pair on a Json object. /// /// The name of the property. public override void WritePropertyName(string name) { base.WritePropertyName(name); JavaScriptUtils.WriteEscapedJavaScriptString(_writer, name, _quoteChar, _quoteName); _writer.Write(':'); } /// /// Writes indent characters. /// protected override void WriteIndent() { if (Formatting == Formatting.Indented) { _writer.Write(Environment.NewLine); // levels of indentation multiplied by the indent count int currentIndentCount = Top * _indentation; for (int i = 0; i < currentIndentCount; i++) { _writer.Write(_indentChar); } } } /// /// Writes the JSON value delimiter. /// protected override void WriteValueDelimiter() { _writer.Write(','); } /// /// Writes an indent space. /// protected override void WriteIndentSpace() { _writer.Write(' '); } private void WriteValueInternal(string value, JsonToken token) { _writer.Write(value); } #region WriteValue methods /// /// Writes a null value. /// public override void WriteNull() { base.WriteNull(); WriteValueInternal(JsonConvert.Null, JsonToken.Null); } /// /// Writes an undefined value. /// public override void WriteUndefined() { base.WriteUndefined(); WriteValueInternal(JsonConvert.Undefined, JsonToken.Undefined); } /// /// Writes raw JSON. /// /// The raw JSON to write. public override void WriteRaw(string json) { base.WriteRaw(json); _writer.Write(json); } /// /// Writes a value. /// /// The value to write. public override void WriteValue(string value) { base.WriteValue(value); if (value == null) WriteValueInternal(JsonConvert.Null, JsonToken.Null); else JavaScriptUtils.WriteEscapedJavaScriptString(_writer, value, _quoteChar, true); } /// /// Writes a value. /// /// The value to write. public override void WriteValue(int value) { base.WriteValue(value); WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer); } /// /// Writes a value. /// /// The value to write. public override void WriteValue(uint value) { base.WriteValue(value); WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer); } /// /// Writes a value. /// /// The value to write. public override void WriteValue(long value) { base.WriteValue(value); WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer); } /// /// Writes a value. /// /// The value to write. public override void WriteValue(ulong value) { base.WriteValue(value); WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer); } /// /// Writes a value. /// /// The value to write. public override void WriteValue(float value) { base.WriteValue(value); WriteValueInternal(JsonConvert.ToString(value), JsonToken.Float); } /// /// Writes a value. /// /// The value to write. public override void WriteValue(double value) { base.WriteValue(value); WriteValueInternal(JsonConvert.ToString(value), JsonToken.Float); } /// /// Writes a value. /// /// The value to write. public override void WriteValue(bool value) { base.WriteValue(value); WriteValueInternal(JsonConvert.ToString(value), JsonToken.Boolean); } /// /// Writes a value. /// /// The value to write. public override void WriteValue(short value) { base.WriteValue(value); WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer); } /// /// Writes a value. /// /// The value to write. public override void WriteValue(ushort value) { base.WriteValue(value); WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer); } /// /// Writes a value. /// /// The value to write. public override void WriteValue(char value) { base.WriteValue(value); WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer); } /// /// Writes a value. /// /// The value to write. public override void WriteValue(byte value) { base.WriteValue(value); WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer); } /// /// Writes a value. /// /// The value to write. public override void WriteValue(sbyte value) { base.WriteValue(value); WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer); } /// /// Writes a value. /// /// The value to write. public override void WriteValue(decimal value) { base.WriteValue(value); WriteValueInternal(JsonConvert.ToString(value), JsonToken.Float); } /// /// Writes a value. /// /// The value to write. public override void WriteValue(DateTime value) { base.WriteValue(value); JsonConvert.WriteDateTimeString(_writer, value); } /// /// Writes a value. /// /// The value to write. public override void WriteValue(byte[] value) { base.WriteValue(value); if (value != null) { _writer.Write(_quoteChar); Base64Encoder.Encode(value, 0, value.Length); Base64Encoder.Flush(); _writer.Write(_quoteChar); } } #if !PocketPC && !NET20 /// /// Writes a value. /// /// The value to write. public override void WriteValue(DateTimeOffset value) { base.WriteValue(value); WriteValueInternal(JsonConvert.ToString(value), JsonToken.Date); } #endif #endregion /// /// Writes out a comment /*...*/ containing the specified text. /// /// Text to place inside the comment. public override void WriteComment(string text) { base.WriteComment(text); _writer.Write("/*"); _writer.Write(text); _writer.Write("*/"); } /// /// Writes out the given white space. /// /// The string of white space characters. public override void WriteWhitespace(string ws) { base.WriteWhitespace(ws); _writer.Write(ws); } } }