##// END OF EJS Templates
Reimplemented JsonXmlReader, added support for null values: JSON null values are...
cin -
r227:8d5de4eb9c2c v2
parent child
Show More
This diff has been collapsed as it changes many lines, (629 lines changed) Show them Hide them
@@ -0,0 +1,629
1 using Implab.Formats.JSON;
2 using System;
3 using System.Collections.Generic;
4 using System.Globalization;
5 using System.Linq;
6 using System.Text;
7 using System.Threading.Tasks;
8 using System.Xml;
9
10 namespace Implab.Xml {
11 public class JsonXmlReader : XmlReader {
12 struct JsonContext {
13 public string localName;
14 public bool skip;
15 }
16
17 JSONParser m_parser;
18 JsonXmlReaderOptions m_options;
19 JsonXmlReaderPosition m_position = JsonXmlReaderPosition.Initial;
20 XmlNameTable m_nameTable;
21
22 readonly string m_jsonRootName;
23 readonly string m_jsonNamespace;
24 readonly string m_jsonPrefix;
25 readonly bool m_jsonFlattenArrays;
26 readonly string m_jsonArrayItemName;
27
28 string m_jsonLocalName;
29 string m_jsonValueName;
30 bool m_jsonSkip; // indicates wheather to generate closing tag for objects or arrays
31
32 readonly Stack<JsonContext> m_jsonNameStack = new Stack<JsonContext>();
33
34 XmlQualifiedName m_elementQName;
35 string m_elementPrefix;
36 int m_elementDepth;
37 bool m_elementIsEmpty;
38
39 XmlQualifiedName m_qName;
40 string m_prefix;
41 int m_xmlDepth;
42
43 XmlSimpleAttribute[] m_attributes;
44 object m_value;
45 bool m_isEmpty;
46
47 XmlNodeType m_nodeType = XmlNodeType.None;
48
49 bool m_isAttribute; // indicates that we are reading attribute nodes
50 int m_currentAttribute;
51 bool m_currentAttributeRead;
52
53
54 XmlNameContext m_context;
55 int m_nextPrefix = 1;
56
57 readonly string m_xmlnsPrefix;
58 readonly string m_xmlnsNamespace;
59 readonly string m_xsiPrefix;
60 readonly string m_xsiNamespace;
61
62
63 public JsonXmlReader(JSONParser parser, JsonXmlReaderOptions options) {
64 Safe.ArgumentNotNull(parser, nameof(parser));
65 m_parser = parser;
66
67 m_options = options ?? new JsonXmlReaderOptions();
68
69 m_jsonFlattenArrays = m_options.FlattenArrays;
70 m_nameTable = m_options.NameTable ?? new NameTable();
71
72 m_jsonRootName = m_nameTable.Add(string.IsNullOrEmpty(m_options.RootName) ? "data" : m_options.RootName);
73 m_jsonArrayItemName = m_nameTable.Add(string.IsNullOrEmpty(m_options.ArrayItemName) ? "item" : m_options.ArrayItemName);
74 m_jsonNamespace = m_nameTable.Add(m_options.NamespaceUri ?? string.Empty);
75 m_jsonPrefix = m_nameTable.Add(m_options.NodesPrefix ?? string.Empty);
76 m_xmlnsPrefix = m_nameTable.Add(XmlNameContext.XmlnsPrefix);
77 m_xmlnsNamespace = m_nameTable.Add(XmlNameContext.XmlnsNamespace);
78 m_xsiPrefix = m_nameTable.Add(XmlNameContext.XsiPrefix);
79 m_xsiNamespace = m_nameTable.Add(XmlNameContext.XsiNamespace);
80
81 // TODO validate m_jsonRootName, m_jsonArrayItemName
82
83 m_context = new XmlNameContext(null);
84 }
85
86 public override int AttributeCount {
87 get {
88 return m_attributes == null ? 0 : m_attributes.Length;
89 }
90 }
91
92 public override string BaseURI {
93 get {
94 return string.Empty;
95 }
96 }
97
98 public override int Depth {
99 get {
100 return m_xmlDepth;
101 }
102 }
103
104 public override bool EOF {
105 get {
106 return m_position == JsonXmlReaderPosition.Eof;
107 }
108 }
109
110 public override bool IsEmptyElement {
111 get { return m_isEmpty; }
112 }
113
114
115 public override string LocalName {
116 get {
117 return m_qName.Name;
118 }
119 }
120
121 public override string NamespaceURI {
122 get {
123 return m_qName.Namespace;
124 }
125 }
126
127 public override XmlNameTable NameTable {
128 get {
129 return m_nameTable;
130 }
131 }
132
133 public override XmlNodeType NodeType {
134 get {
135 return m_nodeType;
136 }
137 }
138
139 public override string Prefix {
140 get {
141 return m_prefix;
142 }
143 }
144
145 public override ReadState ReadState {
146 get {
147 switch (m_position) {
148 case JsonXmlReaderPosition.Initial:
149 return ReadState.Initial;
150 case JsonXmlReaderPosition.Eof:
151 return ReadState.EndOfFile;
152 case JsonXmlReaderPosition.Closed:
153 return ReadState.Closed;
154 case JsonXmlReaderPosition.Error:
155 return ReadState.Error;
156 default:
157 return ReadState.Interactive;
158 };
159 }
160 }
161
162 public override string Value {
163 get {
164 return ConvertValueToString(m_value);
165 }
166 }
167
168 static string ConvertValueToString(object value) {
169 if (value == null)
170 return string.Empty;
171
172 switch (Convert.GetTypeCode(value)) {
173 case TypeCode.Double:
174 return ((double)value).ToString(CultureInfo.InvariantCulture);
175 case TypeCode.String:
176 return (string)value;
177 case TypeCode.Boolean:
178 return (bool)value ? "true" : "false";
179 default:
180 return value.ToString();
181 }
182 }
183
184 public override string GetAttribute(int i) {
185 Safe.ArgumentInRange(i, 0, AttributeCount - 1, nameof(i));
186 return ConvertValueToString(m_attributes[i].Value);
187 }
188
189 public override string GetAttribute(string name) {
190 if (m_attributes == null)
191 return null;
192 var qName = m_context.Resolve(name);
193 var attr = Array.Find(m_attributes, x => x.QName == qName);
194 var value = ConvertValueToString(attr?.Value);
195 return value == string.Empty ? null : value;
196 }
197
198 public override string GetAttribute(string name, string namespaceURI) {
199 if (m_attributes == null)
200 return null;
201 var qName = new XmlQualifiedName(name, namespaceURI);
202 var attr = Array.Find(m_attributes, x => x.QName == qName);
203 var value = ConvertValueToString(attr?.Value);
204 return value == string.Empty ? null : value;
205 }
206
207 public override string LookupNamespace(string prefix) {
208 return m_context.ResolvePrefix(prefix);
209 }
210
211 public override bool MoveToAttribute(string name) {
212 if (m_attributes == null || m_attributes.Length == 0)
213 return false;
214
215 var qName = m_context.Resolve(name);
216 var index = Array.FindIndex(m_attributes, x => x.QName == qName);
217 if (index >= 0) {
218 MoveToAttributeImpl(index);
219 return true;
220 }
221 return false;
222 }
223
224 public override bool MoveToAttribute(string name, string ns) {
225 if (m_attributes == null || m_attributes.Length == 0)
226 return false;
227
228 var qName = m_context.Resolve(name);
229 var index = Array.FindIndex(m_attributes, x => x.QName == qName);
230 if (index >= 0) {
231 MoveToAttributeImpl(index);
232 return true;
233 }
234 return false;
235 }
236
237 void MoveToAttributeImpl(int i) {
238 if (!m_isAttribute) {
239 m_elementQName = m_qName;
240 m_elementDepth = m_xmlDepth;
241 m_elementPrefix = m_prefix;
242 m_elementIsEmpty = m_isEmpty;
243 m_isAttribute = true;
244 }
245
246 var attr = m_attributes[i];
247
248
249 m_currentAttribute = i;
250 m_currentAttributeRead = false;
251 m_nodeType = XmlNodeType.Attribute;
252
253 m_xmlDepth = m_elementDepth + 1;
254 m_qName = attr.QName;
255 m_value = attr.Value;
256 m_prefix = attr.Prefix;
257 }
258
259 public override bool MoveToElement() {
260 if (m_isAttribute) {
261 m_value = null;
262 m_nodeType = XmlNodeType.Element;
263 m_xmlDepth = m_elementDepth;
264 m_prefix = m_elementPrefix;
265 m_qName = m_elementQName;
266 m_isEmpty = m_elementIsEmpty;
267 m_isAttribute = false;
268 return true;
269 }
270 return false;
271 }
272
273 public override bool MoveToFirstAttribute() {
274 if (m_attributes != null && m_attributes.Length > 0) {
275 MoveToAttributeImpl(0);
276 return true;
277 }
278 return false;
279 }
280
281 public override bool MoveToNextAttribute() {
282 if (m_isAttribute) {
283 var next = m_currentAttribute + 1;
284 if (next < AttributeCount) {
285 MoveToAttributeImpl(next);
286 return true;
287 }
288 return false;
289 } else {
290 return MoveToFirstAttribute();
291 }
292
293 }
294
295 public override bool ReadAttributeValue() {
296 if (!m_isAttribute || m_currentAttributeRead)
297 return false;
298
299 ValueNode(m_attributes[m_currentAttribute].Value);
300 m_currentAttributeRead = true;
301 return true;
302 }
303
304 public override void ResolveEntity() {
305 /* do nothing */
306 }
307
308 /// <summary>
309 /// Determines do we need to increase depth after the current node
310 /// </summary>
311 /// <returns></returns>
312 public bool IsSibling() {
313 switch (m_nodeType) {
314 case XmlNodeType.None: // start document
315 case XmlNodeType.Attribute: // after attribute only it's content can be iterated with ReadAttributeValue method
316 return false;
317 case XmlNodeType.Element:
318 // if the elemnt is empty the next element will be it's sibling
319 return m_isEmpty;
320
321 case XmlNodeType.Document:
322 case XmlNodeType.DocumentFragment:
323 case XmlNodeType.Entity:
324 case XmlNodeType.Text:
325 case XmlNodeType.CDATA:
326 case XmlNodeType.EntityReference:
327 case XmlNodeType.ProcessingInstruction:
328 case XmlNodeType.Comment:
329 case XmlNodeType.DocumentType:
330 case XmlNodeType.Notation:
331 case XmlNodeType.Whitespace:
332 case XmlNodeType.SignificantWhitespace:
333 case XmlNodeType.EndElement:
334 case XmlNodeType.EndEntity:
335 case XmlNodeType.XmlDeclaration:
336 default:
337 return true;
338 }
339 }
340
341 void ValueNode(object value) {
342 if (!IsSibling()) // the node is nested
343 m_xmlDepth++;
344
345 m_qName = XmlQualifiedName.Empty;
346 m_nodeType = XmlNodeType.Text;
347 m_prefix = string.Empty;
348 m_value = value;
349 m_isEmpty = false;
350 m_attributes = null;
351 }
352
353 void ElementNode(string name, string ns, XmlSimpleAttribute[] attrs, bool empty) {
354 if (!IsSibling()) // the node is nested
355 m_xmlDepth++;
356
357 m_context = new XmlNameContext(m_context);
358 List<XmlSimpleAttribute> definedAttrs = null;
359
360 // define new namespaces
361 if (attrs != null) {
362 foreach (var attr in attrs) {
363 if (attr.QName.Name == "xmlns") {
364 m_context.DefinePrefix(ConvertValueToString(attr.Value), string.Empty);
365 } else if (attr.Prefix == m_xmlnsPrefix) {
366 m_context.DefinePrefix(ConvertValueToString(attr.Value), attr.QName.Name);
367 } else {
368 string attrPrefix;
369 if (string.IsNullOrEmpty(attr.QName.Namespace))
370 continue;
371
372 // auto-define prefixes
373 if (!m_context.LookupNamespacePrefix(attr.QName.Namespace, out attrPrefix) || string.IsNullOrEmpty(attrPrefix)) {
374 // new namespace prefix added
375 attrPrefix = m_context.CreateNamespacePrefix(attr.QName.Namespace);
376 attr.Prefix = attrPrefix;
377
378 if (definedAttrs == null)
379 definedAttrs = new List<XmlSimpleAttribute>();
380
381 definedAttrs.Add(new XmlSimpleAttribute(attrPrefix, m_xmlnsNamespace, m_xmlnsPrefix, attr.QName.Namespace));
382 }
383 }
384 }
385 }
386
387 string p;
388 // auto-define prefixes
389 if (!m_context.LookupNamespacePrefix(ns, out p)) {
390 p = m_context.CreateNamespacePrefix(ns);
391 if (definedAttrs == null)
392 definedAttrs = new List<XmlSimpleAttribute>();
393
394 definedAttrs.Add(new XmlSimpleAttribute(p, m_xmlnsNamespace, m_xmlnsPrefix, ns));
395 }
396
397 if (definedAttrs != null) {
398 if (attrs != null)
399 definedAttrs.AddRange(attrs);
400 attrs = definedAttrs.ToArray();
401 }
402
403 m_nodeType = XmlNodeType.Element;
404 m_qName = new XmlQualifiedName(name, ns);
405 m_prefix = p;
406 m_value = null;
407 m_isEmpty = empty;
408 m_attributes = attrs;
409 }
410
411 void EndElementNode(string name, string ns) {
412 if (IsSibling()) // closing the element which has children
413 m_xmlDepth--;
414
415 string p;
416 if (!m_context.LookupNamespacePrefix(ns, out p))
417 throw new Exception($"Failed to lookup namespace '{ns}'");
418
419 m_context = m_context.ParentContext;
420 m_nodeType = XmlNodeType.EndElement;
421 m_prefix = p;
422 m_qName = new XmlQualifiedName(name, ns);
423 m_value = null;
424 m_attributes = null;
425 m_isEmpty = false;
426 }
427
428 void XmlDeclaration() {
429 if (!IsSibling()) // the node is nested
430 m_xmlDepth++;
431 m_nodeType = XmlNodeType.XmlDeclaration;
432 m_qName = new XmlQualifiedName("xml");
433 m_value = "version='1.0'";
434 m_prefix = string.Empty;
435 m_attributes = null;
436 m_isEmpty = false;
437 }
438
439 public override bool Read() {
440 try {
441 string elementName;
442 XmlSimpleAttribute[] elementAttrs = null;
443 MoveToElement();
444
445 switch (m_position) {
446 case JsonXmlReaderPosition.Initial:
447 m_jsonLocalName = m_jsonRootName;
448 m_jsonSkip = false;
449 XmlDeclaration();
450 m_position = JsonXmlReaderPosition.Declaration;
451 return true;
452 case JsonXmlReaderPosition.Declaration:
453 elementAttrs = new[] {
454 new XmlSimpleAttribute(m_xsiPrefix, m_xmlnsNamespace, m_xmlnsPrefix, m_xsiNamespace),
455 string.IsNullOrEmpty(m_jsonPrefix) ?
456 new XmlSimpleAttribute(m_xmlnsPrefix, string.Empty, string.Empty, m_jsonNamespace) :
457 new XmlSimpleAttribute(m_jsonPrefix, m_xmlnsNamespace, m_xmlnsPrefix, m_jsonNamespace)
458 };
459 break;
460 case JsonXmlReaderPosition.ValueElement:
461 if (!m_isEmpty) {
462 ValueNode(m_parser.ElementValue);
463 m_position = JsonXmlReaderPosition.ValueContent;
464 return true;
465 } else {
466 m_position = JsonXmlReaderPosition.ValueEndElement;
467 break;
468 }
469 case JsonXmlReaderPosition.ValueContent:
470 EndElementNode(m_jsonValueName, m_jsonNamespace);
471 m_position = JsonXmlReaderPosition.ValueEndElement;
472 return true;
473 case JsonXmlReaderPosition.Eof:
474 case JsonXmlReaderPosition.Closed:
475 case JsonXmlReaderPosition.Error:
476 return false;
477 }
478
479 while (m_parser.Read()) {
480 var jsonName = m_nameTable.Add(m_parser.ElementName);
481
482 switch (m_parser.ElementType) {
483 case JSONElementType.BeginObject:
484 if (!EnterJsonObject(jsonName, out elementName))
485 continue;
486
487 m_position = JsonXmlReaderPosition.BeginObject;
488 ElementNode(elementName, m_jsonNamespace, elementAttrs, false);
489 break;
490 case JSONElementType.EndObject:
491 if (!LeaveJsonScope(out elementName))
492 continue;
493
494 m_position = JsonXmlReaderPosition.EndObject;
495 EndElementNode(elementName, m_jsonNamespace);
496 break;
497 case JSONElementType.BeginArray:
498 if (!EnterJsonArray(jsonName, out elementName))
499 continue;
500
501 m_position = JsonXmlReaderPosition.BeginArray;
502 ElementNode(elementName, m_jsonNamespace, elementAttrs, false);
503 break;
504 case JSONElementType.EndArray:
505 if (!LeaveJsonScope(out elementName))
506 continue;
507
508 m_position = JsonXmlReaderPosition.EndArray;
509 EndElementNode(elementName, m_jsonNamespace);
510 break;
511 case JSONElementType.Value:
512 if (!VisitJsonValue(jsonName, out m_jsonValueName))
513 continue;
514
515 m_position = JsonXmlReaderPosition.ValueElement;
516 if (m_parser.ElementValue == null)
517 // generate empty element with xsi:nil="true" attribute
518 ElementNode(
519 m_jsonValueName,
520 m_jsonNamespace,
521 new[] {
522 new XmlSimpleAttribute("nil", m_xsiNamespace, m_xsiPrefix, true)
523 },
524 true
525 );
526 else
527 ElementNode(m_jsonValueName, m_jsonNamespace, elementAttrs, m_parser.ElementValue as string == string.Empty);
528 break;
529 default:
530 throw new Exception($"Unexpected JSON element {m_parser.ElementType}: {m_parser.ElementName}");
531 }
532 return true;
533 }
534
535 m_position = JsonXmlReaderPosition.Eof;
536 return false;
537 } catch {
538 m_position = JsonXmlReaderPosition.Error;
539 throw;
540 }
541 }
542
543 void SaveJsonName() {
544 m_jsonNameStack.Push(new JsonContext {
545 skip = m_jsonSkip,
546 localName = m_jsonLocalName
547 });
548
549 }
550
551 bool EnterJsonObject(string name, out string elementName) {
552 SaveJsonName();
553 m_jsonSkip = false;
554
555 if (string.IsNullOrEmpty(name)) {
556 if (m_jsonNameStack.Count != 1 && !m_jsonFlattenArrays)
557 m_jsonLocalName = m_jsonArrayItemName;
558 } else {
559 m_jsonLocalName = name;
560 }
561
562 elementName = m_jsonLocalName;
563 return true;
564 }
565
566 /// <summary>
567 /// Called when JSON parser visits BeginArray ('[') element.
568 /// </summary>
569 /// <param name="name">Optional property name if the array is the member of an object</param>
570 /// <returns>true if element should be emited, false otherwise</returns>
571 bool EnterJsonArray(string name, out string elementName) {
572 SaveJsonName();
573
574 if (string.IsNullOrEmpty(name)) {
575 // m_jsonNameStack.Count == 1 means the root node
576 if (m_jsonNameStack.Count != 1 && !m_jsonFlattenArrays)
577 m_jsonLocalName = m_jsonArrayItemName;
578
579 m_jsonSkip = false; // we should not flatten arrays inside arrays or in the document root
580 } else {
581 m_jsonLocalName = name;
582 m_jsonSkip = m_jsonFlattenArrays;
583 }
584 elementName = m_jsonLocalName;
585
586 return !m_jsonSkip;
587 }
588
589 bool VisitJsonValue(string name, out string elementName) {
590 if (string.IsNullOrEmpty(name)) {
591 // m_jsonNameStack.Count == 0 means that JSON document consists from simple value
592 elementName = (m_jsonNameStack.Count == 0 || m_jsonFlattenArrays) ? m_jsonLocalName : m_jsonArrayItemName;
593 } else {
594 elementName = name;
595 }
596 return true;
597 }
598
599 bool LeaveJsonScope(out string elementName) {
600 elementName = m_jsonLocalName;
601 var skip = m_jsonSkip;
602
603 var prev = m_jsonNameStack.Pop();
604 m_jsonLocalName = prev.localName;
605 m_jsonSkip = prev.skip;
606
607 return !skip;
608 }
609
610 public override string ToString() {
611 switch (NodeType) {
612 case XmlNodeType.Element:
613 return $"<{Name} {string.Join(" ", (m_attributes ?? new XmlSimpleAttribute[0]).Select(x => $"{x.Prefix}{(string.IsNullOrEmpty(x.Prefix) ? "" : ":")}{x.QName.Name}='{ConvertValueToString(x.Value)}'"))} {(IsEmptyElement ? "/" : "")}>";
614 case XmlNodeType.Attribute:
615 return $"@{Name}";
616 case XmlNodeType.Text:
617 return $"{Value}";
618 case XmlNodeType.CDATA:
619 return $"<![CDATA[{Value}]]>";
620 case XmlNodeType.EntityReference:
621 return $"&{Name};";
622 case XmlNodeType.EndElement:
623 return $"</{Name}>";
624 default:
625 return $".{NodeType} {Name} {Value}";
626 }
627 }
628 }
629 }
@@ -0,0 +1,66
1
2 using System;
3 using System.Xml;
4
5 namespace Implab.Formats.JSON {
6 /// <summary>
7 /// Набор необязательных параметров для <see cref="JSONXmlReader"/>, позволяющий управлять процессом
8 /// интерпретации <c>JSON</c> документа.
9 /// </summary>
10 public class JSONXmlReaderOptions : ICloneable {
11 /// <summary>
12 /// Пространство имен в котором будут располагаться читаемые элементы документа
13 /// </summary>
14 public string NamespaceURI {
15 get;
16 set;
17 }
18
19 /// <summary>
20 /// Интерпретировать массивы как множественные элементы (убирает один уровень вложенности), иначе массив
21 /// представляется в виде узла, дочерними элементами которого являются элементы массива, имена дочерних элементов
22 /// определяются свойством <see cref="ArrayItemName"/>. По умолчанию <c>false</c>.
23 /// </summary>
24 public bool FlattenArrays {
25 get;
26 set;
27 }
28
29 /// <summary>
30 /// Префикс, для узлов документа
31 /// </summary>
32 public string NodesPrefix {
33 get;
34 set;
35 }
36
37 /// <summary>
38 /// Имя корневого элемента в xml документе
39 /// </summary>
40 public string RootName {
41 get;
42 set;
43 }
44
45 /// <summary>
46 /// Имя элемента для массивов, если не включена опция <see cref="FlattenArrays"/>.
47 /// По умолчанию <c>item</c>.
48 /// </summary>
49 public string ArrayItemName {
50 get;
51 set;
52 }
53
54 /// <summary>
55 /// Таблица атомизированных строк для построения документа.
56 /// </summary>
57 public XmlNameTable NameTable {
58 get;
59 set;
60 }
61
62 public object Clone() {
63 return MemberwiseClone();
64 }
65 }
66 }
@@ -0,0 +1,22
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6
7 namespace Implab.Xml {
8 public enum JsonXmlReaderPosition {
9 Initial,
10 Declaration,
11 BeginArray,
12 BeginObject,
13 EndArray,
14 EndObject,
15 ValueElement,
16 ValueContent,
17 ValueEndElement,
18 Eof,
19 Closed,
20 Error
21 }
22 }
@@ -0,0 +1,111
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6 using System.Xml;
7
8 namespace Implab.Xml {
9 public class XmlNameContext {
10 public const string XmlnsNamespace = "http://www.w3.org/2000/xmlns/";
11 public const string XmlnsPrefix = "xmlns";
12 public const string XmlNamespace = "http://www.w3.org/XML/1998/namespace";
13 public const string XmlPrefix = "xml";
14 public const string XsiNamespace = "http://www.w3.org/2001/XMLSchema-instance";
15 public const string XsiPrefix = "xsi";
16
17 readonly static char[] _qNameDelim = new[] { ':' };
18
19 Dictionary<string, string> m_ns2prefix;
20 Dictionary<string, string> m_prefix2ns;
21 int m_nextPrefix = 1;
22
23 public XmlNameContext ParentContext { get; private set; }
24
25 public XmlNameContext(XmlNameContext parent) {
26 ParentContext = parent;
27 if (parent == null) {
28 DefinePrefixNoCheck(XmlnsNamespace, XmlnsPrefix);
29 DefinePrefixNoCheck(XmlNamespace, XmlPrefix);
30 } else {
31 m_nextPrefix = parent.m_nextPrefix;
32 }
33 }
34
35 public bool LookupNamespacePrefix(string ns, out string prefix) {
36 if (ns == null)
37 ns = string.Empty;
38
39 prefix = null;
40 for (var ctx = this; ctx != null; ctx = ctx.ParentContext) {
41 if (ctx.m_ns2prefix?.TryGetValue(ns, out prefix) == true) {
42 if (ctx != this) // cache for the future use
43 DefinePrefixNoCheck(ns, prefix);
44 return true;
45 }
46 }
47 return false;
48 }
49
50 public string CreateNamespacePrefix(string ns) {
51 var prefix = $"p{m_nextPrefix++}";
52 DefinePrefixNoCheck(ns, prefix);
53 return prefix;
54 }
55
56 void DefinePrefixNoCheck(string ns, string prefix) {
57 if (ns == null)
58 ns = string.Empty;
59 if (prefix == null)
60 prefix = string.Empty;
61
62 if (m_ns2prefix == null)
63 m_ns2prefix = new Dictionary<string, string>();
64 m_ns2prefix[ns] = prefix;
65
66 if (m_prefix2ns == null)
67 m_prefix2ns = new Dictionary<string, string>();
68 m_prefix2ns[prefix] = ns;
69 }
70
71 public void DefinePrefix(string ns, string prefix) {
72 // according to https://www.w3.org/TR/xml-names/#ns-decl
73
74 // It MUST NOT be declared . Other prefixes MUST NOT be bound to this namespace name, and it MUST NOT be declared as the default namespace
75 if (ns == XmlnsNamespace)
76 throw new Exception($"Attempt to define xmlns:{prefix}='{ns}'");
77
78 // It MAY, but need not, be declared, and MUST NOT be bound to any other namespace name
79 if (ns == XmlNamespace && prefix != XmlPrefix)
80 throw new Exception($"Attempt to define xmlns:{prefix}='{ns}'");
81
82 // add mapping
83 DefinePrefixNoCheck(ns, prefix);
84 }
85
86 public string ResolvePrefix(string prefix) {
87 if (prefix == null)
88 prefix = string.Empty;
89 string ns = null;
90 for(var ctx = this; ctx != null; ctx = ctx.ParentContext) {
91 if (ctx.m_prefix2ns?.TryGetValue(prefix, out ns) == true) {
92 if (ctx != this) // cache for the future use
93 DefinePrefixNoCheck(ns, prefix);
94 return ns;
95 }
96 }
97 return null;
98 }
99
100 public XmlQualifiedName Resolve(string name) {
101 Safe.ArgumentNotEmpty(name, nameof(name));
102 var parts = name.Split(_qNameDelim, 2, StringSplitOptions.RemoveEmptyEntries);
103
104 if (parts.Length == 2) {
105 return new XmlQualifiedName(parts[1], ResolvePrefix(parts[0]));
106 } else {
107 return new XmlQualifiedName(parts[0], ResolvePrefix(string.Empty));
108 }
109 }
110 }
111 }
@@ -0,0 +1,22
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6 using System.Xml;
7
8 namespace Implab.Xml {
9 public class XmlSimpleAttribute {
10 public XmlSimpleAttribute(string name, string ns, string prefix, object value) {
11 QName = new XmlQualifiedName(name, ns);
12 Prefix = prefix;
13 Value = value;
14 }
15
16 public XmlQualifiedName QName { get; set; }
17
18 public string Prefix { get; set; }
19
20 public object Value { get; set; }
21 }
22 }
@@ -18,3 +18,6 MonoPlay/obj/
18 Implab.Test/Implab.Format.Test/bin/
18 Implab.Test/Implab.Format.Test/bin/
19 Implab.Test/Implab.Format.Test/obj/
19 Implab.Test/Implab.Format.Test/obj/
20 *.suo
20 *.suo
21 Implab.Format.Test/bin/
22 Implab.Format.Test/obj/
23 packages/
@@ -31,25 +31,27
31 <ConsolePause>false</ConsolePause>
31 <ConsolePause>false</ConsolePause>
32 </PropertyGroup>
32 </PropertyGroup>
33 <ItemGroup>
33 <ItemGroup>
34 <Reference Include="nunit.framework, Version=3.8.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
35 <HintPath>..\packages\NUnit.3.8.1\lib\net45\nunit.framework.dll</HintPath>
36 <Private>True</Private>
37 </Reference>
34 <Reference Include="System" />
38 <Reference Include="System" />
35 <Reference Include="nunit.framework">
39 <Reference Include="System.Xml" />
36 <HintPath>..\..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
37 </Reference>
38 </ItemGroup>
40 </ItemGroup>
39 <ItemGroup>
41 <ItemGroup>
40 <Compile Include="JsonTests.cs" />
42 <Compile Include="JsonTests.cs" />
41 </ItemGroup>
43 </ItemGroup>
42 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
44 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
43 <ItemGroup>
45 <ItemGroup>
44 <ProjectReference Include="..\..\Implab\Implab.csproj">
46 <ProjectReference Include="..\Implab\Implab.csproj">
45 <Project>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</Project>
47 <Project>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</Project>
46 <Name>Implab</Name>
48 <Name>Implab</Name>
47 </ProjectReference>
49 </ProjectReference>
48 </ItemGroup>
50 </ItemGroup>
49 <ItemGroup>
51 <ItemGroup>
50 <None Include="packages.config" />
52 <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
51 </ItemGroup>
53 </ItemGroup>
52 <ItemGroup>
54 <ItemGroup>
53 <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
55 <None Include="packages.config" />
54 </ItemGroup>
56 </ItemGroup>
55 </Project> No newline at end of file
57 </Project>
@@ -2,7 +2,10
2 using System;
2 using System;
3 using Implab.Formats.JSON;
3 using Implab.Formats.JSON;
4 using Implab.Automaton;
4 using Implab.Automaton;
5
5 using Implab.Xml;
6 using System.Xml;
7 using System.Text;
8
6 namespace Implab.Format.Test {
9 namespace Implab.Format.Test {
7 [TestFixture]
10 [TestFixture]
8 public class JsonTests {
11 public class JsonTests {
@@ -10,7 +13,7 namespace Implab.Format.Test {
10 public void TestScannerValidTokens() {
13 public void TestScannerValidTokens() {
11 using (var scanner = new JSONScanner(@"9123, -123, 0, 0.1, -0.2, -0.1e3, 1.3E-3, ""some \t\n\u0020 text"", literal []{}:")) {
14 using (var scanner = new JSONScanner(@"9123, -123, 0, 0.1, -0.2, -0.1e3, 1.3E-3, ""some \t\n\u0020 text"", literal []{}:")) {
12
15
13 Tuple<JsonTokenType,object>[] expexted = {
16 Tuple<JsonTokenType, object>[] expexted = {
14 new Tuple<JsonTokenType,object>(JsonTokenType.Number, 9123d),
17 new Tuple<JsonTokenType,object>(JsonTokenType.Number, 9123d),
15 new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, ", "),
18 new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, ", "),
16 new Tuple<JsonTokenType,object>(JsonTokenType.Number, -123d),
19 new Tuple<JsonTokenType,object>(JsonTokenType.Number, -123d),
@@ -37,8 +40,8 namespace Implab.Format.Test {
37
40
38 object value;
41 object value;
39 JsonTokenType tokenType;
42 JsonTokenType tokenType;
40 for (var i = 0; i < expexted.Length; i++) {
43 for (var i = 0; i < expexted.Length; i++) {
41
44
42 Assert.IsTrue(scanner.ReadToken(out value, out tokenType));
45 Assert.IsTrue(scanner.ReadToken(out value, out tokenType));
43 Assert.AreEqual(expexted[i].Item1, tokenType);
46 Assert.AreEqual(expexted[i].Item1, tokenType);
44 Assert.AreEqual(expexted[i].Item2, value);
47 Assert.AreEqual(expexted[i].Item2, value);
@@ -50,7 +53,7 namespace Implab.Format.Test {
50
53
51 [Test]
54 [Test]
52 public void TestScannerBadTokens() {
55 public void TestScannerBadTokens() {
53 var bad = new [] {
56 var bad = new[] {
54 " 1",
57 " 1",
55 " literal",
58 " literal",
56 " \"",
59 " \"",
@@ -66,22 +69,76 namespace Implab.Format.Test {
66 "-.123"
69 "-.123"
67 };
70 };
68
71
69 foreach (var json in bad)
72 foreach (var json in bad) {
70 using (var scanner = new JSONScanner(json)) {
73 using (var scanner = new JSONScanner(json)) {
71 try {
74 try {
72 object value;
75 object value;
73 JsonTokenType token;
76 JsonTokenType token;
74 scanner.ReadToken(out value, out token);
77 scanner.ReadToken(out value, out token);
75 if (!Object.Equals(value,json)) {
78 if (!Object.Equals(value, json)) {
76 Console.WriteLine("'{0}' is read as {1}", json, value is String ? String.Format("'{0}'", value) : value );
79 Console.WriteLine("'{0}' is read as {1}", json, value is String ? String.Format("'{0}'", value) : value);
77 continue;
80 continue;
78 }
81 }
79 Assert.Fail("Token '{0}' shouldn't pass", json);
82 Assert.Fail("Token '{0}' shouldn't pass", json);
80 } catch (ParserException e) {
83 } catch (ParserException e) {
81 Console.WriteLine(e.Message);
84 Console.WriteLine(e.Message);
82 }
85 }
83 }
86 }
84
87 }
88 }
89
90 [Test]
91 public void JsonXmlReaderSimpleTest() {
92 var json = "\"some text\"";
93 //Console.WriteLine($"JSON: {json}");
94 //Console.WriteLine("XML");
95 /*using (var xmlReader = new JsonXmlReader(new JSONParser(json), new JsonXmlReaderOptions { NamespaceUri = "JsonXmlReaderSimpleTest", RootName = "string", NodesPrefix = "json" })) {
96 Assert.AreEqual(xmlReader.ReadState, System.Xml.ReadState.Initial);
97
98 AssertRead(xmlReader, XmlNodeType.XmlDeclaration);
99 AssertRead(xmlReader, XmlNodeType.Element);
100 AssertRead(xmlReader, XmlNodeType.Text);
101 AssertRead(xmlReader, XmlNodeType.EndElement);
102 Assert.IsFalse(xmlReader.Read());
103 }*/
104
105 //DumpJsonParse("\"text value\"");
106 //DumpJsonParse("null");
107 //DumpJsonParse("true");
108 //DumpJsonParse("{}");
109 //DumpJsonParse("[]");
110 DumpJsonParse("{\"one\":1, \"two\":2}");
111 DumpJsonParse("[1,2,3]");
112 DumpJsonParse("[{\"info\": [7,8,9]}]");
113 DumpJsonFlatParse("[1,2,[3,4],{\"info\": [5,6]},{\"num\": [7,8,null]}, null,[null]]");
114 }
115
116 void AssertRead(XmlReader reader, XmlNodeType expected) {
117 Assert.IsTrue(reader.Read());
118 Console.WriteLine($"{new string(' ', reader.Depth*2)}{reader}");
119 Assert.AreEqual(expected, reader.NodeType);
120 }
121
122 void DumpJsonParse(string json) {
123 Console.WriteLine($"JSON: {json}");
124 Console.WriteLine("XML");
125 using (var xmlReader = new JsonXmlReader(new JSONParser(json), new JsonXmlReaderOptions { NamespaceUri = "JsonXmlReaderSimpleTest", NodesPrefix = "json" })) {
126 while (xmlReader.Read())
127 Console.WriteLine($"{new string(' ', xmlReader.Depth * 2)}{xmlReader}");
128 }
129 }
130
131 void DumpJsonFlatParse(string json) {
132 Console.WriteLine($"JSON: {json}");
133 Console.WriteLine("XML");
134 using (var xmlWriter = XmlWriter.Create(Console.Out, new XmlWriterSettings {
135 Indent = true,
136 CloseOutput = false,
137 ConformanceLevel = ConformanceLevel.Document
138 }))
139 using (var xmlReader = new JsonXmlReader(new JSONParser(json), new JsonXmlReaderOptions { NamespaceUri = "JsonXmlReaderSimpleTest", NodesPrefix = "", FlattenArrays = true })) {
140 xmlWriter.WriteNode(xmlReader, false);
141 }
85 }
142 }
86 }
143 }
87 }
144 }
@@ -1,4 +1,4
1 <?xml version="1.0" encoding="utf-8"?>
1 <?xml version="1.0" encoding="utf-8"?>
2 <packages>
2 <packages>
3 <package id="NUnit" version="2.6.4" targetFramework="net45" />
3 <package id="NUnit" version="3.8.1" targetFramework="net45" />
4 </packages> No newline at end of file
4 </packages>
@@ -76,9 +76,7
76 <Name>Implab</Name>
76 <Name>Implab</Name>
77 </ProjectReference>
77 </ProjectReference>
78 </ItemGroup>
78 </ItemGroup>
79 <ItemGroup>
79 <ItemGroup />
80 <Folder Include="Implab.Format.Test\" />
81 </ItemGroup>
82 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
80 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
83 <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
81 <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
84 Other similar extension points exist, see Microsoft.Common.targets.
82 Other similar extension points exist, see Microsoft.Common.targets.
@@ -1,6 +1,8
1 
1 
2 Microsoft Visual Studio Solution File, Format Version 11.00
2 Microsoft Visual Studio Solution File, Format Version 12.00
3 # Visual Studio 2010
3 # Visual Studio 14
4 VisualStudioVersion = 14.0.25420.1
5 MinimumVisualStudioVersion = 10.0.40219.1
4 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab", "Implab\Implab.csproj", "{F550F1F8-8746-4AD0-9614-855F4C4B7F05}"
6 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab", "Implab\Implab.csproj", "{F550F1F8-8746-4AD0-9614-855F4C4B7F05}"
5 EndProject
7 EndProject
6 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CE8D8D18-437A-445C-B662-4C2CE79A76F6}"
8 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CE8D8D18-437A-445C-B662-4C2CE79A76F6}"
@@ -16,14 +18,32 Project("{FAE04EC0-301F-11D3-BF4B-00C04F
16 EndProject
18 EndProject
17 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Fx.Test", "Implab.Fx.Test\Implab.Fx.Test.csproj", "{2F31E405-E267-4195-A05D-574093C21209}"
19 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Fx.Test", "Implab.Fx.Test\Implab.Fx.Test.csproj", "{2F31E405-E267-4195-A05D-574093C21209}"
18 EndProject
20 EndProject
21 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Format.Test", "Implab.Format.Test\Implab.Format.Test.csproj", "{4D364996-7ECD-4193-8F90-F223FFEA49DA}"
22 EndProject
19 Global
23 Global
20 GlobalSection(SolutionConfigurationPlatforms) = preSolution
24 GlobalSection(SolutionConfigurationPlatforms) = preSolution
25 Debug 4.5|Any CPU = Debug 4.5|Any CPU
21 Debug|Any CPU = Debug|Any CPU
26 Debug|Any CPU = Debug|Any CPU
27 Release 4.5|Any CPU = Release 4.5|Any CPU
22 Release|Any CPU = Release|Any CPU
28 Release|Any CPU = Release|Any CPU
23 Debug 4.5|Any CPU = Debug 4.5|Any CPU
24 Release 4.5|Any CPU = Release 4.5|Any CPU
25 EndGlobalSection
29 EndGlobalSection
26 GlobalSection(ProjectConfigurationPlatforms) = postSolution
30 GlobalSection(ProjectConfigurationPlatforms) = postSolution
31 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
32 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
33 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
34 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.Build.0 = Debug|Any CPU
35 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU
36 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
37 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.ActiveCfg = Release|Any CPU
38 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.Build.0 = Release|Any CPU
39 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
40 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
41 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
42 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
43 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU
44 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
45 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
46 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release|Any CPU.Build.0 = Release|Any CPU
27 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
47 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
28 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
48 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
29 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
49 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
@@ -40,24 +60,17 Global
40 {2F31E405-E267-4195-A05D-574093C21209}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
60 {2F31E405-E267-4195-A05D-574093C21209}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
41 {2F31E405-E267-4195-A05D-574093C21209}.Release|Any CPU.ActiveCfg = Release|Any CPU
61 {2F31E405-E267-4195-A05D-574093C21209}.Release|Any CPU.ActiveCfg = Release|Any CPU
42 {2F31E405-E267-4195-A05D-574093C21209}.Release|Any CPU.Build.0 = Release|Any CPU
62 {2F31E405-E267-4195-A05D-574093C21209}.Release|Any CPU.Build.0 = Release|Any CPU
43 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
63 {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Debug 4.5|Any CPU.ActiveCfg = Debug|Any CPU
44 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
64 {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Debug 4.5|Any CPU.Build.0 = Debug|Any CPU
45 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
65 {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
46 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
66 {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
47 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU
67 {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Release 4.5|Any CPU.ActiveCfg = Release|Any CPU
48 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
68 {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Release 4.5|Any CPU.Build.0 = Release|Any CPU
49 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
69 {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
50 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release|Any CPU.Build.0 = Release|Any CPU
70 {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Release|Any CPU.Build.0 = Release|Any CPU
51 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
52 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
53 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
54 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.Build.0 = Debug|Any CPU
55 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU
56 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
57 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.ActiveCfg = Release|Any CPU
58 {F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.Build.0 = Release|Any CPU
59 EndGlobalSection
71 EndGlobalSection
60 GlobalSection(NestedProjects) = preSolution
72 GlobalSection(SolutionProperties) = preSolution
73 HideSolutionNode = FALSE
61 EndGlobalSection
74 EndGlobalSection
62 GlobalSection(MonoDevelopProperties) = preSolution
75 GlobalSection(MonoDevelopProperties) = preSolution
63 StartupItem = Implab\Implab.csproj
76 StartupItem = Implab\Implab.csproj
@@ -84,7 +97,7 Global
84 $1.inheritsSet = Mono
97 $1.inheritsSet = Mono
85 $1.inheritsScope = text/x-csharp
98 $1.inheritsScope = text/x-csharp
86 $1.scope = text/x-csharp
99 $1.scope = text/x-csharp
87 $0.TextStylePolicy = $2
100 $0.TextStylePolicy = $6
88 $2.FileWidth = 120
101 $2.FileWidth = 120
89 $2.EolMarker = Unix
102 $2.EolMarker = Unix
90 $2.inheritsSet = VisualStudio
103 $2.inheritsSet = VisualStudio
@@ -93,7 +106,6 Global
93 $0.DotNetNamingPolicy = $3
106 $0.DotNetNamingPolicy = $3
94 $3.DirectoryNamespaceAssociation = PrefixedHierarchical
107 $3.DirectoryNamespaceAssociation = PrefixedHierarchical
95 $3.ResourceNamePolicy = MSBuild
108 $3.ResourceNamePolicy = MSBuild
96 $0.TextStylePolicy = $4
97 $4.FileWidth = 120
109 $4.FileWidth = 120
98 $4.TabsToSpaces = False
110 $4.TabsToSpaces = False
99 $4.inheritsSet = VisualStudio
111 $4.inheritsSet = VisualStudio
@@ -103,7 +115,6 Global
103 $5.inheritsSet = Mono
115 $5.inheritsSet = Mono
104 $5.inheritsScope = application/xml
116 $5.inheritsScope = application/xml
105 $5.scope = application/xml
117 $5.scope = application/xml
106 $0.TextStylePolicy = $6
107 $6.FileWidth = 120
118 $6.FileWidth = 120
108 $6.TabsToSpaces = False
119 $6.TabsToSpaces = False
109 $6.inheritsSet = VisualStudio
120 $6.inheritsSet = VisualStudio
@@ -111,21 +122,19 Global
111 $6.scope = text/plain
122 $6.scope = text/plain
112 $0.NameConventionPolicy = $7
123 $0.NameConventionPolicy = $7
113 $7.Rules = $8
124 $7.Rules = $8
114 $8.NamingRule = $9
125 $8.NamingRule = $34
115 $9.Name = Namespaces
126 $9.Name = Namespaces
116 $9.AffectedEntity = Namespace
127 $9.AffectedEntity = Namespace
117 $9.VisibilityMask = VisibilityMask
128 $9.VisibilityMask = VisibilityMask
118 $9.NamingStyle = PascalCase
129 $9.NamingStyle = PascalCase
119 $9.IncludeInstanceMembers = True
130 $9.IncludeInstanceMembers = True
120 $9.IncludeStaticEntities = True
131 $9.IncludeStaticEntities = True
121 $8.NamingRule = $10
122 $10.Name = Types
132 $10.Name = Types
123 $10.AffectedEntity = Class, Struct, Enum, Delegate
133 $10.AffectedEntity = Class, Struct, Enum, Delegate
124 $10.VisibilityMask = VisibilityMask
134 $10.VisibilityMask = VisibilityMask
125 $10.NamingStyle = PascalCase
135 $10.NamingStyle = PascalCase
126 $10.IncludeInstanceMembers = True
136 $10.IncludeInstanceMembers = True
127 $10.IncludeStaticEntities = True
137 $10.IncludeStaticEntities = True
128 $8.NamingRule = $11
129 $11.Name = Interfaces
138 $11.Name = Interfaces
130 $11.RequiredPrefixes = $12
139 $11.RequiredPrefixes = $12
131 $12.String = I
140 $12.String = I
@@ -134,7 +143,6 Global
134 $11.NamingStyle = PascalCase
143 $11.NamingStyle = PascalCase
135 $11.IncludeInstanceMembers = True
144 $11.IncludeInstanceMembers = True
136 $11.IncludeStaticEntities = True
145 $11.IncludeStaticEntities = True
137 $8.NamingRule = $13
138 $13.Name = Attributes
146 $13.Name = Attributes
139 $13.RequiredSuffixes = $14
147 $13.RequiredSuffixes = $14
140 $14.String = Attribute
148 $14.String = Attribute
@@ -143,7 +151,6 Global
143 $13.NamingStyle = PascalCase
151 $13.NamingStyle = PascalCase
144 $13.IncludeInstanceMembers = True
152 $13.IncludeInstanceMembers = True
145 $13.IncludeStaticEntities = True
153 $13.IncludeStaticEntities = True
146 $8.NamingRule = $15
147 $15.Name = Event Arguments
154 $15.Name = Event Arguments
148 $15.RequiredSuffixes = $16
155 $15.RequiredSuffixes = $16
149 $16.String = EventArgs
156 $16.String = EventArgs
@@ -152,7 +159,6 Global
152 $15.NamingStyle = PascalCase
159 $15.NamingStyle = PascalCase
153 $15.IncludeInstanceMembers = True
160 $15.IncludeInstanceMembers = True
154 $15.IncludeStaticEntities = True
161 $15.IncludeStaticEntities = True
155 $8.NamingRule = $17
156 $17.Name = Exceptions
162 $17.Name = Exceptions
157 $17.RequiredSuffixes = $18
163 $17.RequiredSuffixes = $18
158 $18.String = Exception
164 $18.String = Exception
@@ -161,35 +167,30 Global
161 $17.NamingStyle = PascalCase
167 $17.NamingStyle = PascalCase
162 $17.IncludeInstanceMembers = True
168 $17.IncludeInstanceMembers = True
163 $17.IncludeStaticEntities = True
169 $17.IncludeStaticEntities = True
164 $8.NamingRule = $19
165 $19.Name = Methods
170 $19.Name = Methods
166 $19.AffectedEntity = Methods
171 $19.AffectedEntity = Methods
167 $19.VisibilityMask = VisibilityMask
172 $19.VisibilityMask = VisibilityMask
168 $19.NamingStyle = PascalCase
173 $19.NamingStyle = PascalCase
169 $19.IncludeInstanceMembers = True
174 $19.IncludeInstanceMembers = True
170 $19.IncludeStaticEntities = True
175 $19.IncludeStaticEntities = True
171 $8.NamingRule = $20
172 $20.Name = Static Readonly Fields
176 $20.Name = Static Readonly Fields
173 $20.AffectedEntity = ReadonlyField
177 $20.AffectedEntity = ReadonlyField
174 $20.VisibilityMask = Internal, Protected, Public
178 $20.VisibilityMask = Internal, Protected, Public
175 $20.NamingStyle = CamelCase
179 $20.NamingStyle = CamelCase
176 $20.IncludeInstanceMembers = False
180 $20.IncludeInstanceMembers = False
177 $20.IncludeStaticEntities = True
181 $20.IncludeStaticEntities = True
178 $8.NamingRule = $21
179 $21.Name = Fields (Non Private)
182 $21.Name = Fields (Non Private)
180 $21.AffectedEntity = Field
183 $21.AffectedEntity = Field
181 $21.VisibilityMask = Internal, Public
184 $21.VisibilityMask = Internal, Public
182 $21.NamingStyle = CamelCase
185 $21.NamingStyle = CamelCase
183 $21.IncludeInstanceMembers = True
186 $21.IncludeInstanceMembers = True
184 $21.IncludeStaticEntities = True
187 $21.IncludeStaticEntities = True
185 $8.NamingRule = $22
186 $22.Name = ReadOnly Fields (Non Private)
188 $22.Name = ReadOnly Fields (Non Private)
187 $22.AffectedEntity = ReadonlyField
189 $22.AffectedEntity = ReadonlyField
188 $22.VisibilityMask = Internal, Public
190 $22.VisibilityMask = Internal, Public
189 $22.NamingStyle = CamelCase
191 $22.NamingStyle = CamelCase
190 $22.IncludeInstanceMembers = True
192 $22.IncludeInstanceMembers = True
191 $22.IncludeStaticEntities = False
193 $22.IncludeStaticEntities = False
192 $8.NamingRule = $23
193 $23.Name = Fields (Private)
194 $23.Name = Fields (Private)
194 $23.RequiredPrefixes = $24
195 $23.RequiredPrefixes = $24
195 $24.String = m_
196 $24.String = m_
@@ -198,7 +199,6 Global
198 $23.NamingStyle = CamelCase
199 $23.NamingStyle = CamelCase
199 $23.IncludeInstanceMembers = True
200 $23.IncludeInstanceMembers = True
200 $23.IncludeStaticEntities = False
201 $23.IncludeStaticEntities = False
201 $8.NamingRule = $25
202 $25.Name = Static Fields (Private)
202 $25.Name = Static Fields (Private)
203 $25.RequiredPrefixes = $26
203 $25.RequiredPrefixes = $26
204 $26.String = _
204 $26.String = _
@@ -207,7 +207,6 Global
207 $25.NamingStyle = CamelCase
207 $25.NamingStyle = CamelCase
208 $25.IncludeInstanceMembers = False
208 $25.IncludeInstanceMembers = False
209 $25.IncludeStaticEntities = True
209 $25.IncludeStaticEntities = True
210 $8.NamingRule = $27
211 $27.Name = ReadOnly Fields (Private)
210 $27.Name = ReadOnly Fields (Private)
212 $27.RequiredPrefixes = $28
211 $27.RequiredPrefixes = $28
213 $28.String = m_
212 $28.String = m_
@@ -216,42 +215,36 Global
216 $27.NamingStyle = CamelCase
215 $27.NamingStyle = CamelCase
217 $27.IncludeInstanceMembers = True
216 $27.IncludeInstanceMembers = True
218 $27.IncludeStaticEntities = False
217 $27.IncludeStaticEntities = False
219 $8.NamingRule = $29
220 $29.Name = Constant Fields
218 $29.Name = Constant Fields
221 $29.AffectedEntity = ConstantField
219 $29.AffectedEntity = ConstantField
222 $29.VisibilityMask = VisibilityMask
220 $29.VisibilityMask = VisibilityMask
223 $29.NamingStyle = AllUpper
221 $29.NamingStyle = AllUpper
224 $29.IncludeInstanceMembers = True
222 $29.IncludeInstanceMembers = True
225 $29.IncludeStaticEntities = True
223 $29.IncludeStaticEntities = True
226 $8.NamingRule = $30
227 $30.Name = Properties
224 $30.Name = Properties
228 $30.AffectedEntity = Property
225 $30.AffectedEntity = Property
229 $30.VisibilityMask = VisibilityMask
226 $30.VisibilityMask = VisibilityMask
230 $30.NamingStyle = PascalCase
227 $30.NamingStyle = PascalCase
231 $30.IncludeInstanceMembers = True
228 $30.IncludeInstanceMembers = True
232 $30.IncludeStaticEntities = True
229 $30.IncludeStaticEntities = True
233 $8.NamingRule = $31
234 $31.Name = Events
230 $31.Name = Events
235 $31.AffectedEntity = Event
231 $31.AffectedEntity = Event
236 $31.VisibilityMask = VisibilityMask
232 $31.VisibilityMask = VisibilityMask
237 $31.NamingStyle = PascalCase
233 $31.NamingStyle = PascalCase
238 $31.IncludeInstanceMembers = True
234 $31.IncludeInstanceMembers = True
239 $31.IncludeStaticEntities = True
235 $31.IncludeStaticEntities = True
240 $8.NamingRule = $32
241 $32.Name = Enum Members
236 $32.Name = Enum Members
242 $32.AffectedEntity = EnumMember
237 $32.AffectedEntity = EnumMember
243 $32.VisibilityMask = VisibilityMask
238 $32.VisibilityMask = VisibilityMask
244 $32.NamingStyle = PascalCase
239 $32.NamingStyle = PascalCase
245 $32.IncludeInstanceMembers = True
240 $32.IncludeInstanceMembers = True
246 $32.IncludeStaticEntities = True
241 $32.IncludeStaticEntities = True
247 $8.NamingRule = $33
248 $33.Name = Parameters
242 $33.Name = Parameters
249 $33.AffectedEntity = Parameter, LocalVariable
243 $33.AffectedEntity = Parameter, LocalVariable
250 $33.VisibilityMask = VisibilityMask
244 $33.VisibilityMask = VisibilityMask
251 $33.NamingStyle = CamelCase
245 $33.NamingStyle = CamelCase
252 $33.IncludeInstanceMembers = True
246 $33.IncludeInstanceMembers = True
253 $33.IncludeStaticEntities = True
247 $33.IncludeStaticEntities = True
254 $8.NamingRule = $34
255 $34.Name = Type Parameters
248 $34.Name = Type Parameters
256 $34.RequiredPrefixes = $35
249 $34.RequiredPrefixes = $35
257 $35.String = T
250 $35.String = T
@@ -264,7 +257,4 Global
264 GlobalSection(TestCaseManagementSettings) = postSolution
257 GlobalSection(TestCaseManagementSettings) = postSolution
265 CategoryFile = Implab.vsmdi
258 CategoryFile = Implab.vsmdi
266 EndGlobalSection
259 EndGlobalSection
267 GlobalSection(SolutionProperties) = preSolution
268 HideSolutionNode = FALSE
269 EndGlobalSection
270 EndGlobal
260 EndGlobal
@@ -110,7 +110,8 namespace Implab.Formats.JSON {
110 #endregion
110 #endregion
111
111
112 readonly JSONScanner m_scanner;
112 readonly JSONScanner m_scanner;
113 MemberContext m_memberContext;
113 // json starts from the value context and may content even a single literal
114 MemberContext m_memberContext = MemberContext.MemberValue;
114
115
115 JSONElementType m_elementType;
116 JSONElementType m_elementType;
116 object m_elementValue;
117 object m_elementValue;
@@ -1,16 +1,16
1
1
2 using System.Xml;
2 using System.Xml;
3
3
4 namespace Implab.Formats.JSON {
4 namespace Implab.Xml {
5 /// <summary>
5 /// <summary>
6 /// Набор необязательных параметров для <see cref="JSONXmlReader"/>, позволяющий управлять процессом
6 /// Набор необязательных параметров для <see cref="JSONXmlReader"/>, позволяющий управлять процессом
7 /// интерпретации <c>JSON</c> документа.
7 /// интерпретации <c>JSON</c> документа.
8 /// </summary>
8 /// </summary>
9 public class JSONXmlReaderOptions {
9 public class JsonXmlReaderOptions {
10 /// <summary>
10 /// <summary>
11 /// Пространство имен в котором будут располагаться читаемые элементы документа
11 /// Пространство имен в котором будут располагаться читаемые элементы документа
12 /// </summary>
12 /// </summary>
13 public string NamespaceURI {
13 public string NamespaceUri {
14 get;
14 get;
15 set;
15 set;
16 }
16 }
@@ -198,6 +198,11
198 <Compile Include="FailedPromise.cs" />
198 <Compile Include="FailedPromise.cs" />
199 <Compile Include="FailedPromiseT.cs" />
199 <Compile Include="FailedPromiseT.cs" />
200 <Compile Include="Components\PollingComponent.cs" />
200 <Compile Include="Components\PollingComponent.cs" />
201 <Compile Include="Xml\JsonXmlReader.cs" />
202 <Compile Include="Xml\JsonXmlReaderOptions.cs" />
203 <Compile Include="Xml\JsonXmlReaderPosition.cs" />
204 <Compile Include="Xml\XmlSimpleAttribute.cs" />
205 <Compile Include="Xml\XmlNameContext.cs" />
201 </ItemGroup>
206 </ItemGroup>
202 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
207 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
203 <ItemGroup />
208 <ItemGroup />
@@ -210,7 +215,7
210 <DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="MSBuild" />
215 <DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="MSBuild" />
211 <TextStylePolicy FileWidth="120" TabWidth="4" TabsToSpaces="False" IndentWidth="4" RemoveTrailingWhitespace="True" NoTabsAfterNonTabs="False" EolMarker="Native" scope="application/xml" />
216 <TextStylePolicy FileWidth="120" TabWidth="4" TabsToSpaces="False" IndentWidth="4" RemoveTrailingWhitespace="True" NoTabsAfterNonTabs="False" EolMarker="Native" scope="application/xml" />
212 <XmlFormattingPolicy scope="application/xml">
217 <XmlFormattingPolicy scope="application/xml">
213 <DefaultFormat OmitXmlDeclaration="False" NewLineChars="&#xA;" IndentContent="True" ContentIndentString="&#x9;" AttributesInNewLine="False" MaxAttributesPerLine="10" AttributesIndentString="&#x9;" WrapAttributes="False" AlignAttributes="False" AlignAttributeValues="False" QuoteChar="&quot;" SpacesBeforeAssignment="0" SpacesAfterAssignment="0" EmptyLinesBeforeStart="0" EmptyLinesAfterStart="0" EmptyLinesBeforeEnd="0" EmptyLinesAfterEnd="0" />
218 <DefaultFormat OmitXmlDeclaration="False" NewLineChars="&#xA;" IndentContent="True" ContentIndentString=" " AttributesInNewLine="False" MaxAttributesPerLine="10" AttributesIndentString=" " WrapAttributes="False" AlignAttributes="False" AlignAttributeValues="False" QuoteChar="&quot;" SpacesBeforeAssignment="0" SpacesAfterAssignment="0" EmptyLinesBeforeStart="0" EmptyLinesAfterStart="0" EmptyLinesBeforeEnd="0" EmptyLinesAfterEnd="0" />
214 </XmlFormattingPolicy>
219 </XmlFormattingPolicy>
215 <TextStylePolicy FileWidth="120" TabWidth="4" TabsToSpaces="False" IndentWidth="4" RemoveTrailingWhitespace="True" NoTabsAfterNonTabs="False" EolMarker="Native" scope="text/plain" />
220 <TextStylePolicy FileWidth="120" TabWidth="4" TabsToSpaces="False" IndentWidth="4" RemoveTrailingWhitespace="True" NoTabsAfterNonTabs="False" EolMarker="Native" scope="text/plain" />
216 <NameConventionPolicy>
221 <NameConventionPolicy>
@@ -385,8 +385,6 namespace Implab.Parallels {
385 if (next == null) {
385 if (next == null) {
386
386
387 if (first != Interlocked.CompareExchange(ref m_last, null, first)) {
387 if (first != Interlocked.CompareExchange(ref m_last, null, first)) {
388 /*while (first.next == null)
389 Thread.MemoryBarrier();*/
390
388
391 // race
389 // race
392 // someone already updated the tail, restore the pointer to the queue head
390 // someone already updated the tail, restore the pointer to the queue head
@@ -394,12 +392,6 namespace Implab.Parallels {
394 }
392 }
395 // the tail is updated
393 // the tail is updated
396 }
394 }
397
398 // we need to update the head
399 //Interlocked.CompareExchange(ref m_first, next, first);
400 // if the head is already updated then give up
401 //return;
402
403 }
395 }
404
396
405 public void Clear() {
397 public void Clear() {
General Comments 3
Under Review
author

Auto status change to "Under Review"

Approved
author

ok, latest stable version should be in default

You need to be logged in to leave comments. Login now