##// 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 18 Implab.Test/Implab.Format.Test/bin/
19 19 Implab.Test/Implab.Format.Test/obj/
20 20 *.suo
21 Implab.Format.Test/bin/
22 Implab.Format.Test/obj/
23 packages/
@@ -31,25 +31,27
31 31 <ConsolePause>false</ConsolePause>
32 32 </PropertyGroup>
33 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 38 <Reference Include="System" />
35 <Reference Include="nunit.framework">
36 <HintPath>..\..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
37 </Reference>
39 <Reference Include="System.Xml" />
38 40 </ItemGroup>
39 41 <ItemGroup>
40 42 <Compile Include="JsonTests.cs" />
41 43 </ItemGroup>
42 44 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
43 45 <ItemGroup>
44 <ProjectReference Include="..\..\Implab\Implab.csproj">
46 <ProjectReference Include="..\Implab\Implab.csproj">
45 47 <Project>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</Project>
46 48 <Name>Implab</Name>
47 49 </ProjectReference>
48 50 </ItemGroup>
49 51 <ItemGroup>
50 <None Include="packages.config" />
52 <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
51 53 </ItemGroup>
52 54 <ItemGroup>
53 <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
55 <None Include="packages.config" />
54 56 </ItemGroup>
55 57 </Project> No newline at end of file
@@ -2,7 +2,10
2 2 using System;
3 3 using Implab.Formats.JSON;
4 4 using Implab.Automaton;
5
5 using Implab.Xml;
6 using System.Xml;
7 using System.Text;
8
6 9 namespace Implab.Format.Test {
7 10 [TestFixture]
8 11 public class JsonTests {
@@ -10,7 +13,7 namespace Implab.Format.Test {
10 13 public void TestScannerValidTokens() {
11 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 17 new Tuple<JsonTokenType,object>(JsonTokenType.Number, 9123d),
15 18 new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, ", "),
16 19 new Tuple<JsonTokenType,object>(JsonTokenType.Number, -123d),
@@ -37,8 +40,8 namespace Implab.Format.Test {
37 40
38 41 object value;
39 42 JsonTokenType tokenType;
40 for (var i = 0; i < expexted.Length; i++) {
41
43 for (var i = 0; i < expexted.Length; i++) {
44
42 45 Assert.IsTrue(scanner.ReadToken(out value, out tokenType));
43 46 Assert.AreEqual(expexted[i].Item1, tokenType);
44 47 Assert.AreEqual(expexted[i].Item2, value);
@@ -50,7 +53,7 namespace Implab.Format.Test {
50 53
51 54 [Test]
52 55 public void TestScannerBadTokens() {
53 var bad = new [] {
56 var bad = new[] {
54 57 " 1",
55 58 " literal",
56 59 " \"",
@@ -66,22 +69,76 namespace Implab.Format.Test {
66 69 "-.123"
67 70 };
68 71
69 foreach (var json in bad)
72 foreach (var json in bad) {
70 73 using (var scanner = new JSONScanner(json)) {
71 74 try {
72 75 object value;
73 76 JsonTokenType token;
74 77 scanner.ReadToken(out value, out token);
75 if (!Object.Equals(value,json)) {
76 Console.WriteLine("'{0}' is read as {1}", json, value is String ? String.Format("'{0}'", value) : value );
78 if (!Object.Equals(value, json)) {
79 Console.WriteLine("'{0}' is read as {1}", json, value is String ? String.Format("'{0}'", value) : value);
77 80 continue;
78 81 }
79 82 Assert.Fail("Token '{0}' shouldn't pass", json);
80 83 } catch (ParserException e) {
81 84 Console.WriteLine(e.Message);
82 85 }
83 }
84
86 }
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"?>
2 <packages>
3 <package id="NUnit" version="2.6.4" targetFramework="net45" />
1 <?xml version="1.0" encoding="utf-8"?>
2 <packages>
3 <package id="NUnit" version="3.8.1" targetFramework="net45" />
4 4 </packages> No newline at end of file
@@ -76,9 +76,7
76 76 <Name>Implab</Name>
77 77 </ProjectReference>
78 78 </ItemGroup>
79 <ItemGroup>
80 <Folder Include="Implab.Format.Test\" />
81 </ItemGroup>
79 <ItemGroup />
82 80 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
83 81 <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
84 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
3 # Visual Studio 2010
2 Microsoft Visual Studio Solution File, Format Version 12.00
3 # Visual Studio 14
4 VisualStudioVersion = 14.0.25420.1
5 MinimumVisualStudioVersion = 10.0.40219.1
4 6 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab", "Implab\Implab.csproj", "{F550F1F8-8746-4AD0-9614-855F4C4B7F05}"
5 7 EndProject
6 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 18 EndProject
17 19 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Fx.Test", "Implab.Fx.Test\Implab.Fx.Test.csproj", "{2F31E405-E267-4195-A05D-574093C21209}"
18 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 23 Global
20 24 GlobalSection(SolutionConfigurationPlatforms) = preSolution
25 Debug 4.5|Any CPU = Debug 4.5|Any CPU
21 26 Debug|Any CPU = Debug|Any CPU
27 Release 4.5|Any CPU = Release 4.5|Any CPU
22 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 29 EndGlobalSection
26 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 47 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
28 48 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
29 49 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
@@ -40,24 +60,17 Global
40 60 {2F31E405-E267-4195-A05D-574093C21209}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
41 61 {2F31E405-E267-4195-A05D-574093C21209}.Release|Any CPU.ActiveCfg = Release|Any CPU
42 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
44 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
45 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
46 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.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
48 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
49 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
50 {63F92C0C-61BF-48C0-A377-8D67C3C661D0}.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
63 {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Debug 4.5|Any CPU.ActiveCfg = Debug|Any CPU
64 {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Debug 4.5|Any CPU.Build.0 = Debug|Any CPU
65 {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
66 {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
67 {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Release 4.5|Any CPU.ActiveCfg = Release|Any CPU
68 {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Release 4.5|Any CPU.Build.0 = Release|Any CPU
69 {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
70 {4D364996-7ECD-4193-8F90-F223FFEA49DA}.Release|Any CPU.Build.0 = Release|Any CPU
59 71 EndGlobalSection
60 GlobalSection(NestedProjects) = preSolution
72 GlobalSection(SolutionProperties) = preSolution
73 HideSolutionNode = FALSE
61 74 EndGlobalSection
62 75 GlobalSection(MonoDevelopProperties) = preSolution
63 76 StartupItem = Implab\Implab.csproj
@@ -84,7 +97,7 Global
84 97 $1.inheritsSet = Mono
85 98 $1.inheritsScope = text/x-csharp
86 99 $1.scope = text/x-csharp
87 $0.TextStylePolicy = $2
100 $0.TextStylePolicy = $6
88 101 $2.FileWidth = 120
89 102 $2.EolMarker = Unix
90 103 $2.inheritsSet = VisualStudio
@@ -93,7 +106,6 Global
93 106 $0.DotNetNamingPolicy = $3
94 107 $3.DirectoryNamespaceAssociation = PrefixedHierarchical
95 108 $3.ResourceNamePolicy = MSBuild
96 $0.TextStylePolicy = $4
97 109 $4.FileWidth = 120
98 110 $4.TabsToSpaces = False
99 111 $4.inheritsSet = VisualStudio
@@ -103,7 +115,6 Global
103 115 $5.inheritsSet = Mono
104 116 $5.inheritsScope = application/xml
105 117 $5.scope = application/xml
106 $0.TextStylePolicy = $6
107 118 $6.FileWidth = 120
108 119 $6.TabsToSpaces = False
109 120 $6.inheritsSet = VisualStudio
@@ -111,21 +122,19 Global
111 122 $6.scope = text/plain
112 123 $0.NameConventionPolicy = $7
113 124 $7.Rules = $8
114 $8.NamingRule = $9
125 $8.NamingRule = $34
115 126 $9.Name = Namespaces
116 127 $9.AffectedEntity = Namespace
117 128 $9.VisibilityMask = VisibilityMask
118 129 $9.NamingStyle = PascalCase
119 130 $9.IncludeInstanceMembers = True
120 131 $9.IncludeStaticEntities = True
121 $8.NamingRule = $10
122 132 $10.Name = Types
123 133 $10.AffectedEntity = Class, Struct, Enum, Delegate
124 134 $10.VisibilityMask = VisibilityMask
125 135 $10.NamingStyle = PascalCase
126 136 $10.IncludeInstanceMembers = True
127 137 $10.IncludeStaticEntities = True
128 $8.NamingRule = $11
129 138 $11.Name = Interfaces
130 139 $11.RequiredPrefixes = $12
131 140 $12.String = I
@@ -134,7 +143,6 Global
134 143 $11.NamingStyle = PascalCase
135 144 $11.IncludeInstanceMembers = True
136 145 $11.IncludeStaticEntities = True
137 $8.NamingRule = $13
138 146 $13.Name = Attributes
139 147 $13.RequiredSuffixes = $14
140 148 $14.String = Attribute
@@ -143,7 +151,6 Global
143 151 $13.NamingStyle = PascalCase
144 152 $13.IncludeInstanceMembers = True
145 153 $13.IncludeStaticEntities = True
146 $8.NamingRule = $15
147 154 $15.Name = Event Arguments
148 155 $15.RequiredSuffixes = $16
149 156 $16.String = EventArgs
@@ -152,7 +159,6 Global
152 159 $15.NamingStyle = PascalCase
153 160 $15.IncludeInstanceMembers = True
154 161 $15.IncludeStaticEntities = True
155 $8.NamingRule = $17
156 162 $17.Name = Exceptions
157 163 $17.RequiredSuffixes = $18
158 164 $18.String = Exception
@@ -161,35 +167,30 Global
161 167 $17.NamingStyle = PascalCase
162 168 $17.IncludeInstanceMembers = True
163 169 $17.IncludeStaticEntities = True
164 $8.NamingRule = $19
165 170 $19.Name = Methods
166 171 $19.AffectedEntity = Methods
167 172 $19.VisibilityMask = VisibilityMask
168 173 $19.NamingStyle = PascalCase
169 174 $19.IncludeInstanceMembers = True
170 175 $19.IncludeStaticEntities = True
171 $8.NamingRule = $20
172 176 $20.Name = Static Readonly Fields
173 177 $20.AffectedEntity = ReadonlyField
174 178 $20.VisibilityMask = Internal, Protected, Public
175 179 $20.NamingStyle = CamelCase
176 180 $20.IncludeInstanceMembers = False
177 181 $20.IncludeStaticEntities = True
178 $8.NamingRule = $21
179 182 $21.Name = Fields (Non Private)
180 183 $21.AffectedEntity = Field
181 184 $21.VisibilityMask = Internal, Public
182 185 $21.NamingStyle = CamelCase
183 186 $21.IncludeInstanceMembers = True
184 187 $21.IncludeStaticEntities = True
185 $8.NamingRule = $22
186 188 $22.Name = ReadOnly Fields (Non Private)
187 189 $22.AffectedEntity = ReadonlyField
188 190 $22.VisibilityMask = Internal, Public
189 191 $22.NamingStyle = CamelCase
190 192 $22.IncludeInstanceMembers = True
191 193 $22.IncludeStaticEntities = False
192 $8.NamingRule = $23
193 194 $23.Name = Fields (Private)
194 195 $23.RequiredPrefixes = $24
195 196 $24.String = m_
@@ -198,7 +199,6 Global
198 199 $23.NamingStyle = CamelCase
199 200 $23.IncludeInstanceMembers = True
200 201 $23.IncludeStaticEntities = False
201 $8.NamingRule = $25
202 202 $25.Name = Static Fields (Private)
203 203 $25.RequiredPrefixes = $26
204 204 $26.String = _
@@ -207,7 +207,6 Global
207 207 $25.NamingStyle = CamelCase
208 208 $25.IncludeInstanceMembers = False
209 209 $25.IncludeStaticEntities = True
210 $8.NamingRule = $27
211 210 $27.Name = ReadOnly Fields (Private)
212 211 $27.RequiredPrefixes = $28
213 212 $28.String = m_
@@ -216,42 +215,36 Global
216 215 $27.NamingStyle = CamelCase
217 216 $27.IncludeInstanceMembers = True
218 217 $27.IncludeStaticEntities = False
219 $8.NamingRule = $29
220 218 $29.Name = Constant Fields
221 219 $29.AffectedEntity = ConstantField
222 220 $29.VisibilityMask = VisibilityMask
223 221 $29.NamingStyle = AllUpper
224 222 $29.IncludeInstanceMembers = True
225 223 $29.IncludeStaticEntities = True
226 $8.NamingRule = $30
227 224 $30.Name = Properties
228 225 $30.AffectedEntity = Property
229 226 $30.VisibilityMask = VisibilityMask
230 227 $30.NamingStyle = PascalCase
231 228 $30.IncludeInstanceMembers = True
232 229 $30.IncludeStaticEntities = True
233 $8.NamingRule = $31
234 230 $31.Name = Events
235 231 $31.AffectedEntity = Event
236 232 $31.VisibilityMask = VisibilityMask
237 233 $31.NamingStyle = PascalCase
238 234 $31.IncludeInstanceMembers = True
239 235 $31.IncludeStaticEntities = True
240 $8.NamingRule = $32
241 236 $32.Name = Enum Members
242 237 $32.AffectedEntity = EnumMember
243 238 $32.VisibilityMask = VisibilityMask
244 239 $32.NamingStyle = PascalCase
245 240 $32.IncludeInstanceMembers = True
246 241 $32.IncludeStaticEntities = True
247 $8.NamingRule = $33
248 242 $33.Name = Parameters
249 243 $33.AffectedEntity = Parameter, LocalVariable
250 244 $33.VisibilityMask = VisibilityMask
251 245 $33.NamingStyle = CamelCase
252 246 $33.IncludeInstanceMembers = True
253 247 $33.IncludeStaticEntities = True
254 $8.NamingRule = $34
255 248 $34.Name = Type Parameters
256 249 $34.RequiredPrefixes = $35
257 250 $35.String = T
@@ -264,7 +257,4 Global
264 257 GlobalSection(TestCaseManagementSettings) = postSolution
265 258 CategoryFile = Implab.vsmdi
266 259 EndGlobalSection
267 GlobalSection(SolutionProperties) = preSolution
268 HideSolutionNode = FALSE
269 EndGlobalSection
270 260 EndGlobal
@@ -110,7 +110,8 namespace Implab.Formats.JSON {
110 110 #endregion
111 111
112 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 116 JSONElementType m_elementType;
116 117 object m_elementValue;
@@ -1,16 +1,16
1 1
2 2 using System.Xml;
3 3
4 namespace Implab.Formats.JSON {
4 namespace Implab.Xml {
5 5 /// <summary>
6 6 /// Набор необязательных параметров для <see cref="JSONXmlReader"/>, позволяющий управлять процессом
7 7 /// интерпретации <c>JSON</c> документа.
8 8 /// </summary>
9 public class JSONXmlReaderOptions {
9 public class JsonXmlReaderOptions {
10 10 /// <summary>
11 11 /// Пространство имен в котором будут располагаться читаемые элементы документа
12 12 /// </summary>
13 public string NamespaceURI {
13 public string NamespaceUri {
14 14 get;
15 15 set;
16 16 }
@@ -198,6 +198,11
198 198 <Compile Include="FailedPromise.cs" />
199 199 <Compile Include="FailedPromiseT.cs" />
200 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 206 </ItemGroup>
202 207 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
203 208 <ItemGroup />
@@ -210,7 +215,7
210 215 <DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="MSBuild" />
211 216 <TextStylePolicy FileWidth="120" TabWidth="4" TabsToSpaces="False" IndentWidth="4" RemoveTrailingWhitespace="True" NoTabsAfterNonTabs="False" EolMarker="Native" scope="application/xml" />
212 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 219 </XmlFormattingPolicy>
215 220 <TextStylePolicy FileWidth="120" TabWidth="4" TabsToSpaces="False" IndentWidth="4" RemoveTrailingWhitespace="True" NoTabsAfterNonTabs="False" EolMarker="Native" scope="text/plain" />
216 221 <NameConventionPolicy>
@@ -385,8 +385,6 namespace Implab.Parallels {
385 385 if (next == null) {
386 386
387 387 if (first != Interlocked.CompareExchange(ref m_last, null, first)) {
388 /*while (first.next == null)
389 Thread.MemoryBarrier();*/
390 388
391 389 // race
392 390 // someone already updated the tail, restore the pointer to the queue head
@@ -394,12 +392,6 namespace Implab.Parallels {
394 392 }
395 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 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