annotate Implab/JSON/JSONWriter.cs @ 55:c0bf853aa04f

Added initial JSON support +JSONParser +JSONWriter
author cin
date Sun, 15 Jun 2014 19:39:11 +0400
parents
children d67b95eddaf4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
55
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
1 using System;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
2 using System.Collections.Generic;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
3 using System.IO;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
4 using System.Linq;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
5 using System.Text;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
6 using System.Threading.Tasks;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
7
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
8 namespace Implab.JSON {
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
9 public class JSONWriter {
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
10 struct Context {
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
11 public bool needComma;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
12 public JSONElementContext element;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
13 }
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
14 Stack<Context> m_contextStack = new Stack<Context>();
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
15 Context m_context;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
16
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
17 TextWriter m_writer;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
18 bool m_indent;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
19
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
20 static readonly char [] _escapeBKS,
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
21 _escapeFWD,
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
22 _escapeCR,
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
23 _escapeNL,
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
24 _escapeTAB,
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
25 _escapeSLASH,
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
26 _escapeBSLASH,
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
27 _escapeQ;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
28
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
29 static JSONWriter() {
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
30 _escapeBKS = "\\b".ToCharArray();
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
31 _escapeFWD = "\\f".ToCharArray();
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
32 _escapeCR = "\\r".ToCharArray();
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
33 _escapeNL = "\\n".ToCharArray();
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
34 _escapeTAB = "\\t".ToCharArray();
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
35 _escapeBSLASH = "\\\\".ToCharArray();
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
36 _escapeSLASH = "\\/".ToCharArray();
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
37 _escapeQ = "\\\"".ToCharArray();
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
38 }
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
39
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
40 public JSONWriter(TextWriter writer) {
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
41 Safe.ArgumentNotNull(writer, "writer");
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
42
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
43 m_writer = writer;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
44 }
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
45
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
46 void WriteMemberName(string name) {
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
47 Safe.ArgumentNotEmpty(name, "name");
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
48 if (m_context.element != JSONElementContext.Object)
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
49 OperationNotApplicable("WriteMember");
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
50 if (m_context.needComma)
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
51 m_writer.Write(", ");
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
52 // TODO indent
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
53 m_context.needComma = true;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
54 Write(name);
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
55 m_writer.Write(" : ");
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
56 }
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
57
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
58 public void WriteValue(string name, string value) {
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
59 WriteMemberName(name);
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
60 Write(value);
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
61 }
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
62
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
63 public void WriteValue(string name, bool value) {
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
64 WriteMemberName(name);
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
65 Write(value);
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
66 }
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
67
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
68 public void WriteValue(string name, double value) {
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
69 WriteMemberName(name);
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
70 Write(value);
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
71 }
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
72
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
73
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
74
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
75 public void WriteValue(string value) {
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
76 if (m_context.element != JSONElementContext.Array)
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
77 OperationNotApplicable("WriteValue");
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
78 if (m_context.needComma)
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
79 m_writer.Write(", ");
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
80 m_context.needComma = true;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
81
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
82 Write(value);
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
83 }
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
84
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
85 public void WriteValue(bool value) {
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
86 if (m_context.element != JSONElementContext.Array)
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
87 OperationNotApplicable("WriteValue");
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
88 if (m_context.needComma)
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
89 m_writer.Write(", ");
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
90 m_context.needComma = true;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
91
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
92 Write(value);
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
93 }
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
94
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
95 public void WriteValue(double value) {
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
96 if (m_context.element != JSONElementContext.Array)
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
97 OperationNotApplicable("WriteValue");
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
98 if (m_context.needComma)
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
99 m_writer.Write(", ");
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
100 m_context.needComma = true;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
101
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
102 Write(value);
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
103 }
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
104
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
105 public void BeginObject() {
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
106 if (m_context.element != JSONElementContext.None && m_context.element != JSONElementContext.Array)
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
107 OperationNotApplicable("BeginObject");
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
108 if (m_context.needComma)
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
109 m_writer.Write(", ");
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
110 m_context.needComma = true;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
111
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
112 m_contextStack.Push(m_context);
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
113
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
114 m_context = new Context { element = JSONElementContext.Object, needComma = false };
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
115 m_writer.Write("{ ");
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
116 }
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
117
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
118 public void BeginObject(string name) {
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
119 WriteMemberName(name);
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
120
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
121 m_contextStack.Push(m_context);
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
122
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
123 m_context = new Context { element = JSONElementContext.Object, needComma = false };
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
124 m_writer.Write("{ ");
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
125 }
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
126
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
127 public void EndObject() {
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
128 if (m_context.element != JSONElementContext.Object)
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
129 OperationNotApplicable("EndArray");
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
130
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
131 m_writer.Write(" }");
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
132 m_context = m_contextStack.Pop();
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
133 }
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
134
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
135 public void BeginArray() {
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
136 if (m_context.element != JSONElementContext.None && m_context.element != JSONElementContext.Array)
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
137 throw new InvalidOperationException();
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
138 if (m_context.needComma)
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
139 m_writer.Write(", ");
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
140 m_context.needComma = true;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
141
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
142 m_contextStack.Push(m_context);
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
143
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
144 m_context = new Context { element = JSONElementContext.Array, needComma = false };
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
145 m_writer.Write("[ ");
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
146 }
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
147
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
148 public void BeginArray(string name) {
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
149 WriteMemberName(name);
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
150
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
151 m_contextStack.Push(m_context);
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
152
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
153 m_context = new Context { element = JSONElementContext.Array, needComma = false };
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
154 m_writer.Write("[ ");
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
155 }
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
156
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
157 public void EndArray() {
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
158 if (m_context.element != JSONElementContext.Array)
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
159 OperationNotApplicable("EndArray");
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
160
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
161 m_writer.Write(" ]");
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
162 m_context = m_contextStack.Pop();
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
163 }
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
164
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
165 void Write(bool value) {
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
166 m_writer.Write(value ? "true" : "false");
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
167 }
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
168
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
169
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
170 void Write(string value) {
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
171 if (value == null)
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
172 m_writer.Write("null");
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
173
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
174 var chars = value.ToCharArray();
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
175 m_writer.Write('"');
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
176
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
177 for (int i = 0; i < chars.Length; i++) {
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
178 var ch = chars[i];
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
179
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
180 switch (ch) {
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
181 case '\b':
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
182 m_writer.Write(_escapeBKS);
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
183 break;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
184 case '\f':
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
185 m_writer.Write(_escapeFWD);
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
186 break;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
187 case '\r':
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
188 m_writer.Write(_escapeCR);
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
189 break;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
190 case '\n':
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
191 m_writer.Write(_escapeNL);
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
192 break;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
193 case '\t':
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
194 m_writer.Write(_escapeTAB);
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
195 break;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
196 case '\\':
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
197 m_writer.Write(_escapeBSLASH);
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
198 break;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
199 case '/':
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
200 m_writer.Write(_escapeSLASH);
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
201 break;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
202 case '"':
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
203 m_writer.Write(_escapeQ);
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
204 break;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
205 default:
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
206 if (ch < 0x20) {
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
207 m_writer.Write("\\u00{0:x2}",(int)ch);
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
208 } else {
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
209 m_writer.Write(ch);
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
210 }
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
211 break;
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
212 }
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
213 }
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
214
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
215 m_writer.Write('"');
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
216 }
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
217
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
218 void Write(double value) {
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
219 m_writer.Write(value);
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
220 }
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
221
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
222 void OperationNotApplicable(string opName) {
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
223 throw new InvalidOperationException(String.Format("The operation '{0}' isn't applicable in the context of '{1}'", opName, m_context.element ));
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
224 }
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
225
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
226 }
c0bf853aa04f Added initial JSON support
cin
parents:
diff changeset
227 }