Mercurial > pub > ImplabNet
comparison Implab/JSON/JSONXmlReader.cs @ 58:1710dcda34bb
Added JSONXmlReader
author | cin |
---|---|
date | Tue, 17 Jun 2014 19:40:43 +0400 |
parents | |
children | 21611344d366 |
comparison
equal
deleted
inserted
replaced
57:7759c80cad95 | 58:1710dcda34bb |
---|---|
1 using Implab; | |
2 using Implab.JSON; | |
3 using Implab.Parsing; | |
4 using System; | |
5 using System.Collections.Generic; | |
6 using System.Linq; | |
7 using System.Text; | |
8 using System.Threading.Tasks; | |
9 using System.Xml; | |
10 | |
11 namespace ConsPlay { | |
12 public class JSONXmlReader : XmlReader { | |
13 | |
14 enum ValueContext { | |
15 Undefined, | |
16 ElementStart, | |
17 ElementValue, | |
18 ElementEnd, | |
19 ElementEmpty | |
20 } | |
21 | |
22 struct LocalNameContext { | |
23 public string localName; | |
24 public bool isArray; | |
25 } | |
26 | |
27 JSONParser m_parser; | |
28 ValueContext m_valueContext; | |
29 ReadState m_state = ReadState.Initial; | |
30 Stack<LocalNameContext> m_localNameStack = new Stack<LocalNameContext>(); | |
31 LocalNameContext m_localName; | |
32 string m_rootName = "json"; | |
33 string m_prefix = String.Empty; | |
34 string m_namespaceUri = String.Empty; | |
35 bool m_flattenArrays = false; | |
36 NameTable m_nameTable = new NameTable(); | |
37 int m_depthCorrection = 0; | |
38 | |
39 public JSONXmlReader(JSONParser parser) { | |
40 Safe.ArgumentNotNull(parser, "parser"); | |
41 m_parser = parser; | |
42 } | |
43 | |
44 /// <summary> | |
45 /// Always 0, JSON doesn't support attributes | |
46 /// </summary> | |
47 public override int AttributeCount { | |
48 get { return 0; } | |
49 } | |
50 | |
51 public override string BaseURI { | |
52 get { return String.Empty; } | |
53 } | |
54 | |
55 public override int Depth { | |
56 get { | |
57 return m_localNameStack.Count+m_depthCorrection; | |
58 } | |
59 } | |
60 | |
61 public override bool EOF { | |
62 get { return m_parser.EOF; } | |
63 } | |
64 | |
65 /// <summary> | |
66 /// Always throws an exception | |
67 /// </summary> | |
68 /// <param name="i"></param> | |
69 /// <returns></returns> | |
70 public override string GetAttribute(int i) { | |
71 throw new ArgumentOutOfRangeException(); | |
72 } | |
73 | |
74 /// <summary> | |
75 /// Always returns empty string | |
76 /// </summary> | |
77 /// <param name="name"></param> | |
78 /// <param name="namespaceURI"></param> | |
79 /// <returns></returns> | |
80 public override string GetAttribute(string name, string namespaceURI) { | |
81 return String.Empty; | |
82 } | |
83 | |
84 /// <summary> | |
85 /// Always returns empty string | |
86 /// </summary> | |
87 /// <param name="name"></param> | |
88 /// <returns></returns> | |
89 public override string GetAttribute(string name) { | |
90 return String.Empty; | |
91 } | |
92 | |
93 public override bool IsEmptyElement { | |
94 get { return m_parser.ElementType == JSONElementType.Value && m_valueContext == ValueContext.ElementEmpty; } | |
95 } | |
96 | |
97 public override string LocalName { | |
98 get { return m_localName.localName; } | |
99 } | |
100 | |
101 public override string LookupNamespace(string prefix) { | |
102 if (String.IsNullOrEmpty(prefix) || prefix == m_prefix) | |
103 return m_namespaceUri; | |
104 else | |
105 return String.Empty; | |
106 } | |
107 | |
108 public override bool MoveToAttribute(string name, string ns) { | |
109 return false; | |
110 } | |
111 | |
112 public override bool MoveToAttribute(string name) { | |
113 return false; | |
114 } | |
115 | |
116 public override bool MoveToElement() { | |
117 return false; | |
118 } | |
119 | |
120 public override bool MoveToFirstAttribute() { | |
121 return false; | |
122 } | |
123 | |
124 public override bool MoveToNextAttribute() { | |
125 return false; | |
126 } | |
127 | |
128 public override XmlNameTable NameTable { | |
129 get { return m_nameTable; } | |
130 } | |
131 | |
132 public override string NamespaceURI { | |
133 get { return m_namespaceUri; } | |
134 } | |
135 | |
136 public override XmlNodeType NodeType { | |
137 get { | |
138 switch (m_parser.ElementType) { | |
139 case JSONElementType.BeginObject: | |
140 case JSONElementType.BeginArray: | |
141 return XmlNodeType.Element; | |
142 case JSONElementType.EndObject: | |
143 case JSONElementType.EndArray: | |
144 return XmlNodeType.EndElement; | |
145 case JSONElementType.Value: | |
146 switch (m_valueContext) { | |
147 case ValueContext.ElementStart: | |
148 case ValueContext.ElementEmpty: | |
149 return XmlNodeType.Element; | |
150 case ValueContext.ElementValue: | |
151 return XmlNodeType.Text; | |
152 case ValueContext.ElementEnd: | |
153 return XmlNodeType.EndElement; | |
154 default: | |
155 throw new InvalidOperationException(); | |
156 } | |
157 default: | |
158 throw new InvalidOperationException(); | |
159 } | |
160 } | |
161 } | |
162 | |
163 public override string Prefix { | |
164 get { return m_prefix; } | |
165 } | |
166 | |
167 public override bool Read() { | |
168 if (m_state != System.Xml.ReadState.Interactive && m_state != System.Xml.ReadState.Initial) | |
169 return false; | |
170 | |
171 if (m_state == ReadState.Initial) | |
172 m_state = System.Xml.ReadState.Interactive; | |
173 | |
174 try { | |
175 switch (m_parser.ElementType) { | |
176 case JSONElementType.Value: | |
177 switch (m_valueContext) { | |
178 case ValueContext.ElementStart: | |
179 SetLocalName(String.Empty); | |
180 m_valueContext = ValueContext.ElementValue; | |
181 return true; | |
182 case ValueContext.ElementValue: | |
183 RestoreLocalName(); | |
184 m_valueContext = ValueContext.ElementEnd; | |
185 return true; | |
186 case ValueContext.ElementEmpty: | |
187 case ValueContext.ElementEnd: | |
188 RestoreLocalName(); | |
189 break; | |
190 } | |
191 break; | |
192 case JSONElementType.EndArray: | |
193 case JSONElementType.EndObject: | |
194 RestoreLocalName(); | |
195 break; | |
196 } | |
197 string itemName = m_parser.ElementType == JSONElementType.None ? m_rootName : m_flattenArrays ? m_localName.localName : "item"; | |
198 while (m_parser.Read()) { | |
199 if (!String.IsNullOrEmpty(m_parser.ElementName)) | |
200 itemName = m_parser.ElementName; | |
201 | |
202 switch (m_parser.ElementType) { | |
203 case JSONElementType.BeginArray: | |
204 if (m_flattenArrays && !m_localName.isArray) { | |
205 m_depthCorrection--; | |
206 SetLocalName(itemName, true); | |
207 continue; | |
208 } else { | |
209 SetLocalName(itemName, true); | |
210 } | |
211 break; | |
212 case JSONElementType.BeginObject: | |
213 SetLocalName(itemName); | |
214 break; | |
215 case JSONElementType.EndArray: | |
216 if (m_flattenArrays && !m_localNameStack.Peek().isArray) { | |
217 RestoreLocalName(); | |
218 m_depthCorrection++; | |
219 continue; | |
220 } | |
221 break; | |
222 case JSONElementType.EndObject: | |
223 break; | |
224 case JSONElementType.Value: | |
225 SetLocalName(itemName); | |
226 m_valueContext = m_parser.ElementValue == null ? ValueContext.ElementEmpty : ValueContext.ElementStart; | |
227 break; | |
228 default: | |
229 break; | |
230 } | |
231 return true; | |
232 } | |
233 | |
234 m_state = System.Xml.ReadState.EndOfFile; | |
235 return false; | |
236 } catch { | |
237 m_state = System.Xml.ReadState.Error; | |
238 throw; | |
239 } | |
240 } | |
241 | |
242 public override bool ReadAttributeValue() { | |
243 return false; | |
244 } | |
245 | |
246 public override ReadState ReadState { | |
247 get { return m_state; } | |
248 } | |
249 | |
250 public override void ResolveEntity() { | |
251 // do nothing | |
252 } | |
253 | |
254 public override string Value { | |
255 get { return m_parser.ElementValue == null ? String.Empty : m_parser.ElementValue.ToString(); } | |
256 } | |
257 | |
258 void SetLocalName(string name) { | |
259 m_localNameStack.Push(m_localName); | |
260 m_localName.localName = name; | |
261 m_localName.isArray = false; | |
262 } | |
263 | |
264 void SetLocalName(string name, bool isArray) { | |
265 m_localNameStack.Push(m_localName); | |
266 m_localName.localName = name; | |
267 m_localName.isArray = isArray; | |
268 } | |
269 | |
270 void RestoreLocalName() { | |
271 m_localName = m_localNameStack.Pop(); | |
272 } | |
273 | |
274 public override void Close() { | |
275 m_state = System.Xml.ReadState.EndOfFile ; | |
276 } | |
277 } | |
278 } |