##// END OF EJS Templates
sync
sync

File last commit:

r72:d67b95eddaf4 v2
r108:f3bdb7ba59b9 v2
Show More
JSONWriter.cs
256 lines | 7.9 KiB | text/x-csharp | CSharpLexer
cin
Added initial JSON support...
r55 using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Implab.JSON {
public class JSONWriter {
struct Context {
public bool needComma;
public JSONElementContext element;
}
Stack<Context> m_contextStack = new Stack<Context>();
Context m_context;
TextWriter m_writer;
cin
promises refactoring
r72 readonly bool m_indent = true;
readonly int m_indentSize = 4;
cin
Added initial JSON support...
r55
static readonly char [] _escapeBKS,
_escapeFWD,
_escapeCR,
_escapeNL,
_escapeTAB,
_escapeSLASH,
_escapeBSLASH,
_escapeQ;
static JSONWriter() {
_escapeBKS = "\\b".ToCharArray();
_escapeFWD = "\\f".ToCharArray();
_escapeCR = "\\r".ToCharArray();
_escapeNL = "\\n".ToCharArray();
_escapeTAB = "\\t".ToCharArray();
_escapeBSLASH = "\\\\".ToCharArray();
_escapeSLASH = "\\/".ToCharArray();
_escapeQ = "\\\"".ToCharArray();
}
public JSONWriter(TextWriter writer) {
Safe.ArgumentNotNull(writer, "writer");
m_writer = writer;
}
cin
promises refactoring
r72 public JSONWriter(TextWriter writer, bool indent) {
Safe.ArgumentNotNull(writer, "writer");
m_writer = writer;
m_indent = indent;
}
void WriteIndent() {
if (m_indent) {
var indent = new char[m_contextStack.Count * m_indentSize + 1];
indent[0] = '\n';
for (int i = 1; i < indent.Length; i++)
indent[i] = ' ';
m_writer.Write(new String(indent));
} else {
m_writer.Write(' ');
}
}
cin
Added initial JSON support...
r55 void WriteMemberName(string name) {
Safe.ArgumentNotEmpty(name, "name");
if (m_context.element != JSONElementContext.Object)
OperationNotApplicable("WriteMember");
if (m_context.needComma)
cin
promises refactoring
r72 m_writer.Write(",");
WriteIndent();
cin
Added initial JSON support...
r55 m_context.needComma = true;
Write(name);
m_writer.Write(" : ");
}
public void WriteValue(string name, string value) {
WriteMemberName(name);
Write(value);
}
public void WriteValue(string name, bool value) {
WriteMemberName(name);
Write(value);
}
public void WriteValue(string name, double value) {
WriteMemberName(name);
Write(value);
}
public void WriteValue(string value) {
if (m_context.element != JSONElementContext.Array)
OperationNotApplicable("WriteValue");
if (m_context.needComma)
cin
promises refactoring
r72 m_writer.Write(",");
WriteIndent();
cin
Added initial JSON support...
r55 m_context.needComma = true;
Write(value);
}
public void WriteValue(bool value) {
if (m_context.element != JSONElementContext.Array)
OperationNotApplicable("WriteValue");
if (m_context.needComma)
cin
promises refactoring
r72 m_writer.Write(",");
cin
Added initial JSON support...
r55 m_context.needComma = true;
cin
promises refactoring
r72 WriteIndent();
cin
Added initial JSON support...
r55 Write(value);
}
public void WriteValue(double value) {
if (m_context.element != JSONElementContext.Array)
OperationNotApplicable("WriteValue");
if (m_context.needComma)
cin
promises refactoring
r72 m_writer.Write(",");
cin
Added initial JSON support...
r55 m_context.needComma = true;
cin
promises refactoring
r72 WriteIndent();
cin
Added initial JSON support...
r55 Write(value);
}
public void BeginObject() {
if (m_context.element != JSONElementContext.None && m_context.element != JSONElementContext.Array)
OperationNotApplicable("BeginObject");
if (m_context.needComma)
cin
promises refactoring
r72 m_writer.Write(",");
WriteIndent();
cin
Added initial JSON support...
r55 m_context.needComma = true;
m_contextStack.Push(m_context);
m_context = new Context { element = JSONElementContext.Object, needComma = false };
cin
promises refactoring
r72 m_writer.Write("{");
cin
Added initial JSON support...
r55 }
public void BeginObject(string name) {
WriteMemberName(name);
m_contextStack.Push(m_context);
m_context = new Context { element = JSONElementContext.Object, needComma = false };
cin
promises refactoring
r72 m_writer.Write("{");
cin
Added initial JSON support...
r55 }
public void EndObject() {
if (m_context.element != JSONElementContext.Object)
OperationNotApplicable("EndArray");
cin
promises refactoring
r72
cin
Added initial JSON support...
r55 m_context = m_contextStack.Pop();
cin
promises refactoring
r72 WriteIndent();
m_writer.Write("}");
cin
Added initial JSON support...
r55 }
public void BeginArray() {
if (m_context.element != JSONElementContext.None && m_context.element != JSONElementContext.Array)
throw new InvalidOperationException();
cin
promises refactoring
r72 if (m_context.needComma) {
m_writer.Write(",");
}
cin
Added initial JSON support...
r55 m_context.needComma = true;
cin
promises refactoring
r72 WriteIndent();
cin
Added initial JSON support...
r55 m_contextStack.Push(m_context);
m_context = new Context { element = JSONElementContext.Array, needComma = false };
cin
promises refactoring
r72 m_writer.Write("[");
cin
Added initial JSON support...
r55 }
public void BeginArray(string name) {
WriteMemberName(name);
m_contextStack.Push(m_context);
m_context = new Context { element = JSONElementContext.Array, needComma = false };
cin
promises refactoring
r72 m_writer.Write("[");
cin
Added initial JSON support...
r55 }
public void EndArray() {
if (m_context.element != JSONElementContext.Array)
OperationNotApplicable("EndArray");
m_context = m_contextStack.Pop();
cin
promises refactoring
r72 WriteIndent();
m_writer.Write("]");
cin
Added initial JSON support...
r55 }
void Write(bool value) {
m_writer.Write(value ? "true" : "false");
}
void Write(string value) {
if (value == null)
m_writer.Write("null");
var chars = value.ToCharArray();
m_writer.Write('"');
for (int i = 0; i < chars.Length; i++) {
var ch = chars[i];
switch (ch) {
case '\b':
m_writer.Write(_escapeBKS);
break;
case '\f':
m_writer.Write(_escapeFWD);
break;
case '\r':
m_writer.Write(_escapeCR);
break;
case '\n':
m_writer.Write(_escapeNL);
break;
case '\t':
m_writer.Write(_escapeTAB);
break;
case '\\':
m_writer.Write(_escapeBSLASH);
break;
case '/':
m_writer.Write(_escapeSLASH);
break;
case '"':
m_writer.Write(_escapeQ);
break;
default:
if (ch < 0x20) {
m_writer.Write("\\u00{0:x2}",(int)ch);
} else {
m_writer.Write(ch);
}
break;
}
}
m_writer.Write('"');
}
void Write(double value) {
m_writer.Write(value);
}
void OperationNotApplicable(string opName) {
throw new InvalidOperationException(String.Format("The operation '{0}' isn't applicable in the context of '{1}'", opName, m_context.element ));
}
}
}