##// 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 }
@@ -1,20 +1,23
1 syntax: glob
1 syntax: glob
2 Implab.Test/bin/
2 Implab.Test/bin/
3 *.user
3 *.user
4 Implab.Test/obj/
4 Implab.Test/obj/
5 *.userprefs
5 *.userprefs
6 Implab/bin/
6 Implab/bin/
7 Implab/obj/
7 Implab/obj/
8 TestResults/
8 TestResults/
9 Implab.Fx/obj/
9 Implab.Fx/obj/
10 Implab.Fx/bin/
10 Implab.Fx/bin/
11 Implab.Fx.Test/bin/
11 Implab.Fx.Test/bin/
12 Implab.Fx.Test/obj/
12 Implab.Fx.Test/obj/
13 _ReSharper.Implab/
13 _ReSharper.Implab/
14 Implab.Diagnostics.Interactive/bin/
14 Implab.Diagnostics.Interactive/bin/
15 Implab.Diagnostics.Interactive/obj/
15 Implab.Diagnostics.Interactive/obj/
16 MonoPlay/bin/
16 MonoPlay/bin/
17 MonoPlay/obj/
17 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/
@@ -1,55 +1,57
1 ο»Ώ<?xml version="1.0" encoding="utf-8"?>
1 ο»Ώ<?xml version="1.0" encoding="utf-8"?>
2 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 <PropertyGroup>
3 <PropertyGroup>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6 <ProductVersion>8.0.30703</ProductVersion>
6 <ProductVersion>8.0.30703</ProductVersion>
7 <SchemaVersion>2.0</SchemaVersion>
7 <SchemaVersion>2.0</SchemaVersion>
8 <ProjectGuid>{4D364996-7ECD-4193-8F90-F223FFEA49DA}</ProjectGuid>
8 <ProjectGuid>{4D364996-7ECD-4193-8F90-F223FFEA49DA}</ProjectGuid>
9 <OutputType>Library</OutputType>
9 <OutputType>Library</OutputType>
10 <RootNamespace>Implab.Format.Test</RootNamespace>
10 <RootNamespace>Implab.Format.Test</RootNamespace>
11 <AssemblyName>Implab.Format.Test</AssemblyName>
11 <AssemblyName>Implab.Format.Test</AssemblyName>
12 <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
12 <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
13 <ReleaseVersion>0.2</ReleaseVersion>
13 <ReleaseVersion>0.2</ReleaseVersion>
14 </PropertyGroup>
14 </PropertyGroup>
15 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
15 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
16 <DebugSymbols>true</DebugSymbols>
16 <DebugSymbols>true</DebugSymbols>
17 <DebugType>full</DebugType>
17 <DebugType>full</DebugType>
18 <Optimize>false</Optimize>
18 <Optimize>false</Optimize>
19 <OutputPath>bin\Debug</OutputPath>
19 <OutputPath>bin\Debug</OutputPath>
20 <DefineConstants>DEBUG;</DefineConstants>
20 <DefineConstants>DEBUG;</DefineConstants>
21 <ErrorReport>prompt</ErrorReport>
21 <ErrorReport>prompt</ErrorReport>
22 <WarningLevel>4</WarningLevel>
22 <WarningLevel>4</WarningLevel>
23 <ConsolePause>false</ConsolePause>
23 <ConsolePause>false</ConsolePause>
24 </PropertyGroup>
24 </PropertyGroup>
25 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
25 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
26 <DebugType>full</DebugType>
26 <DebugType>full</DebugType>
27 <Optimize>true</Optimize>
27 <Optimize>true</Optimize>
28 <OutputPath>bin\Release</OutputPath>
28 <OutputPath>bin\Release</OutputPath>
29 <ErrorReport>prompt</ErrorReport>
29 <ErrorReport>prompt</ErrorReport>
30 <WarningLevel>4</WarningLevel>
30 <WarningLevel>4</WarningLevel>
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>
@@ -1,88 +1,145
1 using NUnit.Framework;
1 using NUnit.Framework;
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 {
9 [Test]
12 [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),
17 new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, ", "),
20 new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, ", "),
18 new Tuple<JsonTokenType,object>(JsonTokenType.Number, 0d),
21 new Tuple<JsonTokenType,object>(JsonTokenType.Number, 0d),
19 new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, ", "),
22 new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, ", "),
20 new Tuple<JsonTokenType,object>(JsonTokenType.Number, 0.1d),
23 new Tuple<JsonTokenType,object>(JsonTokenType.Number, 0.1d),
21 new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, ", "),
24 new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, ", "),
22 new Tuple<JsonTokenType,object>(JsonTokenType.Number, -0.2d),
25 new Tuple<JsonTokenType,object>(JsonTokenType.Number, -0.2d),
23 new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, ", "),
26 new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, ", "),
24 new Tuple<JsonTokenType,object>(JsonTokenType.Number, -0.1e3d),
27 new Tuple<JsonTokenType,object>(JsonTokenType.Number, -0.1e3d),
25 new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, ", "),
28 new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, ", "),
26 new Tuple<JsonTokenType,object>(JsonTokenType.Number, 1.3E-3d),
29 new Tuple<JsonTokenType,object>(JsonTokenType.Number, 1.3E-3d),
27 new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, ", "),
30 new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, ", "),
28 new Tuple<JsonTokenType,object>(JsonTokenType.String, "some \t\n text"),
31 new Tuple<JsonTokenType,object>(JsonTokenType.String, "some \t\n text"),
29 new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, ", "),
32 new Tuple<JsonTokenType,object>(JsonTokenType.ValueSeparator, ", "),
30 new Tuple<JsonTokenType,object>(JsonTokenType.Literal, "literal"),
33 new Tuple<JsonTokenType,object>(JsonTokenType.Literal, "literal"),
31 new Tuple<JsonTokenType,object>(JsonTokenType.BeginArray, " ["),
34 new Tuple<JsonTokenType,object>(JsonTokenType.BeginArray, " ["),
32 new Tuple<JsonTokenType,object>(JsonTokenType.EndArray, "]"),
35 new Tuple<JsonTokenType,object>(JsonTokenType.EndArray, "]"),
33 new Tuple<JsonTokenType,object>(JsonTokenType.BeginObject, "{"),
36 new Tuple<JsonTokenType,object>(JsonTokenType.BeginObject, "{"),
34 new Tuple<JsonTokenType,object>(JsonTokenType.EndObject, "}"),
37 new Tuple<JsonTokenType,object>(JsonTokenType.EndObject, "}"),
35 new Tuple<JsonTokenType,object>(JsonTokenType.NameSeparator, ":")
38 new Tuple<JsonTokenType,object>(JsonTokenType.NameSeparator, ":")
36 };
39 };
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);
45 }
48 }
46
49
47 Assert.IsFalse(scanner.ReadToken(out value, out tokenType));
50 Assert.IsFalse(scanner.ReadToken(out value, out tokenType));
48 }
51 }
49 }
52 }
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 " \"",
57 "\"unclosed string",
60 "\"unclosed string",
58 "1.bad",
61 "1.bad",
59 "001", // should be read as three numbers
62 "001", // should be read as three numbers
60 "--10",
63 "--10",
61 "+10",
64 "+10",
62 "1.0.0",
65 "1.0.0",
63 "1e1.0",
66 "1e1.0",
64 "l1teral0",
67 "l1teral0",
65 ".123",
68 ".123",
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 }
88
145
@@ -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>
@@ -1,90 +1,88
1 ο»Ώ<?xml version="1.0" encoding="utf-8"?>
1 ο»Ώ<?xml version="1.0" encoding="utf-8"?>
2 <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2 <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 <PropertyGroup>
3 <PropertyGroup>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6 <ProductVersion>8.0.30703</ProductVersion>
6 <ProductVersion>8.0.30703</ProductVersion>
7 <SchemaVersion>2.0</SchemaVersion>
7 <SchemaVersion>2.0</SchemaVersion>
8 <ProjectGuid>{63F92C0C-61BF-48C0-A377-8D67C3C661D0}</ProjectGuid>
8 <ProjectGuid>{63F92C0C-61BF-48C0-A377-8D67C3C661D0}</ProjectGuid>
9 <OutputType>Library</OutputType>
9 <OutputType>Library</OutputType>
10 <AppDesignerFolder>Properties</AppDesignerFolder>
10 <AppDesignerFolder>Properties</AppDesignerFolder>
11 <RootNamespace>Implab.Test</RootNamespace>
11 <RootNamespace>Implab.Test</RootNamespace>
12 <AssemblyName>Implab.Test</AssemblyName>
12 <AssemblyName>Implab.Test</AssemblyName>
13 <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
13 <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
14 <FileAlignment>512</FileAlignment>
14 <FileAlignment>512</FileAlignment>
15 <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
15 <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
16 <TargetFrameworkProfile />
16 <TargetFrameworkProfile />
17 </PropertyGroup>
17 </PropertyGroup>
18 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
18 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
19 <DebugSymbols>true</DebugSymbols>
19 <DebugSymbols>true</DebugSymbols>
20 <DebugType>full</DebugType>
20 <DebugType>full</DebugType>
21 <Optimize>false</Optimize>
21 <Optimize>false</Optimize>
22 <OutputPath>bin\Debug\</OutputPath>
22 <OutputPath>bin\Debug\</OutputPath>
23 <DefineConstants>DEBUG;TRACE</DefineConstants>
23 <DefineConstants>DEBUG;TRACE</DefineConstants>
24 <ErrorReport>prompt</ErrorReport>
24 <ErrorReport>prompt</ErrorReport>
25 <WarningLevel>4</WarningLevel>
25 <WarningLevel>4</WarningLevel>
26 <Prefer32Bit>false</Prefer32Bit>
26 <Prefer32Bit>false</Prefer32Bit>
27 </PropertyGroup>
27 </PropertyGroup>
28 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
28 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
29 <DebugType>pdbonly</DebugType>
29 <DebugType>pdbonly</DebugType>
30 <Optimize>true</Optimize>
30 <Optimize>true</Optimize>
31 <OutputPath>bin\Release\</OutputPath>
31 <OutputPath>bin\Release\</OutputPath>
32 <DefineConstants>TRACE</DefineConstants>
32 <DefineConstants>TRACE</DefineConstants>
33 <ErrorReport>prompt</ErrorReport>
33 <ErrorReport>prompt</ErrorReport>
34 <WarningLevel>4</WarningLevel>
34 <WarningLevel>4</WarningLevel>
35 <Prefer32Bit>false</Prefer32Bit>
35 <Prefer32Bit>false</Prefer32Bit>
36 </PropertyGroup>
36 </PropertyGroup>
37 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug 4.5|AnyCPU' ">
37 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug 4.5|AnyCPU' ">
38 <DebugSymbols>true</DebugSymbols>
38 <DebugSymbols>true</DebugSymbols>
39 <DebugType>full</DebugType>
39 <DebugType>full</DebugType>
40 <Optimize>false</Optimize>
40 <Optimize>false</Optimize>
41 <OutputPath>bin\Debug\</OutputPath>
41 <OutputPath>bin\Debug\</OutputPath>
42 <DefineConstants>DEBUG;TRACE</DefineConstants>
42 <DefineConstants>DEBUG;TRACE</DefineConstants>
43 <ErrorReport>prompt</ErrorReport>
43 <ErrorReport>prompt</ErrorReport>
44 <WarningLevel>4</WarningLevel>
44 <WarningLevel>4</WarningLevel>
45 <Prefer32Bit>false</Prefer32Bit>
45 <Prefer32Bit>false</Prefer32Bit>
46 </PropertyGroup>
46 </PropertyGroup>
47 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release 4.5|AnyCPU' ">
47 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release 4.5|AnyCPU' ">
48 <DebugType>pdbonly</DebugType>
48 <DebugType>pdbonly</DebugType>
49 <Optimize>true</Optimize>
49 <Optimize>true</Optimize>
50 <OutputPath>bin\Release\</OutputPath>
50 <OutputPath>bin\Release\</OutputPath>
51 <DefineConstants>TRACE</DefineConstants>
51 <DefineConstants>TRACE</DefineConstants>
52 <ErrorReport>prompt</ErrorReport>
52 <ErrorReport>prompt</ErrorReport>
53 <WarningLevel>4</WarningLevel>
53 <WarningLevel>4</WarningLevel>
54 <Prefer32Bit>false</Prefer32Bit>
54 <Prefer32Bit>false</Prefer32Bit>
55 </PropertyGroup>
55 </PropertyGroup>
56 <ItemGroup>
56 <ItemGroup>
57 <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
57 <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
58 <Reference Include="System" />
58 <Reference Include="System" />
59 <Reference Include="System.Core">
59 <Reference Include="System.Core">
60 <RequiredTargetFramework>3.5</RequiredTargetFramework>
60 <RequiredTargetFramework>3.5</RequiredTargetFramework>
61 </Reference>
61 </Reference>
62 </ItemGroup>
62 </ItemGroup>
63 <ItemGroup>
63 <ItemGroup>
64 <Compile Include="AsyncTests.cs" />
64 <Compile Include="AsyncTests.cs" />
65 <Compile Include="CancelationTests.cs" />
65 <Compile Include="CancelationTests.cs" />
66 <Compile Include="Mock\MockPollingComponent.cs" />
66 <Compile Include="Mock\MockPollingComponent.cs" />
67 <Compile Include="Mock\MockRunnableComponent.cs" />
67 <Compile Include="Mock\MockRunnableComponent.cs" />
68 <Compile Include="PollingComponentTests.cs" />
68 <Compile Include="PollingComponentTests.cs" />
69 <Compile Include="PromiseHelper.cs" />
69 <Compile Include="PromiseHelper.cs" />
70 <Compile Include="Properties\AssemblyInfo.cs" />
70 <Compile Include="Properties\AssemblyInfo.cs" />
71 <Compile Include="RunnableComponentTests.cs" />
71 <Compile Include="RunnableComponentTests.cs" />
72 </ItemGroup>
72 </ItemGroup>
73 <ItemGroup>
73 <ItemGroup>
74 <ProjectReference Include="..\Implab\Implab.csproj">
74 <ProjectReference Include="..\Implab\Implab.csproj">
75 <Project>{99B95D0D-9CF9-4F70-8ADF-F4D0AA5CB0D9}</Project>
75 <Project>{99B95D0D-9CF9-4F70-8ADF-F4D0AA5CB0D9}</Project>
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.
85 <Target Name="BeforeBuild">
83 <Target Name="BeforeBuild">
86 </Target>
84 </Target>
87 <Target Name="AfterBuild">
85 <Target Name="AfterBuild">
88 </Target>
86 </Target>
89 -->
87 -->
90 </Project> No newline at end of file
88 </Project>
@@ -1,270 +1,260
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}"
7 ProjectSection(SolutionItems) = preProject
9 ProjectSection(SolutionItems) = preProject
8 Implab.vsmdi = Implab.vsmdi
10 Implab.vsmdi = Implab.vsmdi
9 Local.testsettings = Local.testsettings
11 Local.testsettings = Local.testsettings
10 TraceAndTestImpact.testsettings = TraceAndTestImpact.testsettings
12 TraceAndTestImpact.testsettings = TraceAndTestImpact.testsettings
11 EndProjectSection
13 EndProjectSection
12 EndProject
14 EndProject
13 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Test", "Implab.Test\Implab.Test.csproj", "{63F92C0C-61BF-48C0-A377-8D67C3C661D0}"
15 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Test", "Implab.Test\Implab.Test.csproj", "{63F92C0C-61BF-48C0-A377-8D67C3C661D0}"
14 EndProject
16 EndProject
15 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Fx", "Implab.Fx\Implab.Fx.csproj", "{06E706F8-6881-43EB-927E-FFC503AF6ABC}"
17 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Fx", "Implab.Fx\Implab.Fx.csproj", "{06E706F8-6881-43EB-927E-FFC503AF6ABC}"
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
30 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug|Any CPU.Build.0 = Debug|Any CPU
50 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug|Any CPU.Build.0 = Debug|Any CPU
31 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU
51 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU
32 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
52 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
33 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release|Any CPU.ActiveCfg = Release|Any CPU
53 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release|Any CPU.ActiveCfg = Release|Any CPU
34 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release|Any CPU.Build.0 = Release|Any CPU
54 {06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release|Any CPU.Build.0 = Release|Any CPU
35 {2F31E405-E267-4195-A05D-574093C21209}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
55 {2F31E405-E267-4195-A05D-574093C21209}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
36 {2F31E405-E267-4195-A05D-574093C21209}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
56 {2F31E405-E267-4195-A05D-574093C21209}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
37 {2F31E405-E267-4195-A05D-574093C21209}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
57 {2F31E405-E267-4195-A05D-574093C21209}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
38 {2F31E405-E267-4195-A05D-574093C21209}.Debug|Any CPU.Build.0 = Debug|Any CPU
58 {2F31E405-E267-4195-A05D-574093C21209}.Debug|Any CPU.Build.0 = Debug|Any CPU
39 {2F31E405-E267-4195-A05D-574093C21209}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU
59 {2F31E405-E267-4195-A05D-574093C21209}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU
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
64 Policies = $0
77 Policies = $0
65 $0.CSharpFormattingPolicy = $1
78 $0.CSharpFormattingPolicy = $1
66 $1.IndentSwitchBody = True
79 $1.IndentSwitchBody = True
67 $1.NamespaceBraceStyle = EndOfLine
80 $1.NamespaceBraceStyle = EndOfLine
68 $1.ClassBraceStyle = EndOfLine
81 $1.ClassBraceStyle = EndOfLine
69 $1.InterfaceBraceStyle = EndOfLine
82 $1.InterfaceBraceStyle = EndOfLine
70 $1.StructBraceStyle = EndOfLine
83 $1.StructBraceStyle = EndOfLine
71 $1.EnumBraceStyle = EndOfLine
84 $1.EnumBraceStyle = EndOfLine
72 $1.MethodBraceStyle = EndOfLine
85 $1.MethodBraceStyle = EndOfLine
73 $1.ConstructorBraceStyle = EndOfLine
86 $1.ConstructorBraceStyle = EndOfLine
74 $1.DestructorBraceStyle = EndOfLine
87 $1.DestructorBraceStyle = EndOfLine
75 $1.BeforeMethodDeclarationParentheses = False
88 $1.BeforeMethodDeclarationParentheses = False
76 $1.BeforeMethodCallParentheses = False
89 $1.BeforeMethodCallParentheses = False
77 $1.BeforeConstructorDeclarationParentheses = False
90 $1.BeforeConstructorDeclarationParentheses = False
78 $1.NewLineBeforeConstructorInitializerColon = NewLine
91 $1.NewLineBeforeConstructorInitializerColon = NewLine
79 $1.NewLineAfterConstructorInitializerColon = SameLine
92 $1.NewLineAfterConstructorInitializerColon = SameLine
80 $1.BeforeIndexerDeclarationBracket = False
93 $1.BeforeIndexerDeclarationBracket = False
81 $1.BeforeDelegateDeclarationParentheses = False
94 $1.BeforeDelegateDeclarationParentheses = False
82 $1.NewParentheses = False
95 $1.NewParentheses = False
83 $1.SpacesBeforeBrackets = False
96 $1.SpacesBeforeBrackets = False
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
91 $2.inheritsScope = text/plain
104 $2.inheritsScope = text/plain
92 $2.scope = text/x-csharp
105 $2.scope = text/x-csharp
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
100 $4.inheritsScope = text/plain
112 $4.inheritsScope = text/plain
101 $4.scope = application/xml
113 $4.scope = application/xml
102 $0.XmlFormattingPolicy = $5
114 $0.XmlFormattingPolicy = $5
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
110 $6.inheritsScope = text/plain
121 $6.inheritsScope = text/plain
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
132 $11.AffectedEntity = Interface
141 $11.AffectedEntity = Interface
133 $11.VisibilityMask = VisibilityMask
142 $11.VisibilityMask = VisibilityMask
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
141 $13.AffectedEntity = CustomAttributes
149 $13.AffectedEntity = CustomAttributes
142 $13.VisibilityMask = VisibilityMask
150 $13.VisibilityMask = VisibilityMask
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
150 $15.AffectedEntity = CustomEventArgs
157 $15.AffectedEntity = CustomEventArgs
151 $15.VisibilityMask = VisibilityMask
158 $15.VisibilityMask = VisibilityMask
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
159 $17.AffectedEntity = CustomExceptions
165 $17.AffectedEntity = CustomExceptions
160 $17.VisibilityMask = VisibilityMask
166 $17.VisibilityMask = VisibilityMask
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_
196 $23.AffectedEntity = Field, ReadonlyField
197 $23.AffectedEntity = Field, ReadonlyField
197 $23.VisibilityMask = Private, Protected
198 $23.VisibilityMask = Private, Protected
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 = _
205 $25.AffectedEntity = Field
205 $25.AffectedEntity = Field
206 $25.VisibilityMask = Private
206 $25.VisibilityMask = Private
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_
214 $27.AffectedEntity = ReadonlyField
213 $27.AffectedEntity = ReadonlyField
215 $27.VisibilityMask = Private, Protected
214 $27.VisibilityMask = Private, Protected
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
258 $34.AffectedEntity = TypeParameter
251 $34.AffectedEntity = TypeParameter
259 $34.VisibilityMask = VisibilityMask
252 $34.VisibilityMask = VisibilityMask
260 $34.NamingStyle = PascalCase
253 $34.NamingStyle = PascalCase
261 $34.IncludeInstanceMembers = True
254 $34.IncludeInstanceMembers = True
262 $34.IncludeStaticEntities = True
255 $34.IncludeStaticEntities = True
263 EndGlobalSection
256 EndGlobalSection
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
@@ -1,293 +1,294
1 using System;
1 using System;
2 using System.Diagnostics;
2 using System.Diagnostics;
3 using System.IO;
3 using System.IO;
4 using Implab.Automaton;
4 using Implab.Automaton;
5 using Implab.Automaton.RegularExpressions;
5 using Implab.Automaton.RegularExpressions;
6 using System.Linq;
6 using System.Linq;
7 using Implab.Components;
7 using Implab.Components;
8 using System.Collections.Generic;
8 using System.Collections.Generic;
9
9
10 namespace Implab.Formats.JSON {
10 namespace Implab.Formats.JSON {
11 /// <summary>
11 /// <summary>
12 /// Pull парсСр JSON Π΄Π°Π½Π½Ρ‹Ρ….
12 /// Pull парсСр JSON Π΄Π°Π½Π½Ρ‹Ρ….
13 /// </summary>
13 /// </summary>
14 /// <remarks>
14 /// <remarks>
15 /// Π‘Π»Π΅Π΄ΡƒΠ΅Ρ‚ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ†ΠΈΡŽ свойства <see cref="Level"/>,
15 /// Π‘Π»Π΅Π΄ΡƒΠ΅Ρ‚ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ†ΠΈΡŽ свойства <see cref="Level"/>,
16 /// ΠΎΠ½ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ влоТСнности ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², ΠΎΠ΄Π½Π°ΠΊΠΎ Π·Π°ΠΊΡ€Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ
16 /// ΠΎΠ½ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ влоТСнности ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², ΠΎΠ΄Π½Π°ΠΊΠΎ Π·Π°ΠΊΡ€Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ
17 /// элСмСнт ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΈ массива ΠΈΠΌΠ΅Π΅Ρ‚ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ мСньшС, Ρ‡Π΅ΠΌ сам ΠΎΠ±ΡŠΠ΅ΠΊΡ‚.
17 /// элСмСнт ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΈ массива ΠΈΠΌΠ΅Π΅Ρ‚ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ мСньшС, Ρ‡Π΅ΠΌ сам ΠΎΠ±ΡŠΠ΅ΠΊΡ‚.
18 /// <code>
18 /// <code>
19 /// { // Level = 1
19 /// { // Level = 1
20 /// "name" : "Peter", // Level = 1
20 /// "name" : "Peter", // Level = 1
21 /// "address" : { // Level = 2
21 /// "address" : { // Level = 2
22 /// city : "Stern" // Level = 2
22 /// city : "Stern" // Level = 2
23 /// } // Level = 1
23 /// } // Level = 1
24 /// } // Level = 0
24 /// } // Level = 0
25 /// </code>
25 /// </code>
26 /// </remarks>
26 /// </remarks>
27 public class JSONParser : Disposable {
27 public class JSONParser : Disposable {
28
28
29 enum MemberContext {
29 enum MemberContext {
30 MemberName,
30 MemberName,
31 MemberValue
31 MemberValue
32 }
32 }
33
33
34 #region Parser rules
34 #region Parser rules
35 struct ParserContext {
35 struct ParserContext {
36 readonly int[,] m_dfa;
36 readonly int[,] m_dfa;
37 int m_state;
37 int m_state;
38
38
39 readonly JSONElementContext m_elementContext;
39 readonly JSONElementContext m_elementContext;
40
40
41 public ParserContext(int[,] dfa, int state, JSONElementContext context) {
41 public ParserContext(int[,] dfa, int state, JSONElementContext context) {
42 m_dfa = dfa;
42 m_dfa = dfa;
43 m_state = state;
43 m_state = state;
44 m_elementContext = context;
44 m_elementContext = context;
45 }
45 }
46
46
47 public bool Move(JsonTokenType token) {
47 public bool Move(JsonTokenType token) {
48 var next = m_dfa[m_state, (int)token];
48 var next = m_dfa[m_state, (int)token];
49 if (next == AutomatonConst.UNREACHABLE_STATE)
49 if (next == AutomatonConst.UNREACHABLE_STATE)
50 return false;
50 return false;
51 m_state = next;
51 m_state = next;
52 return true;
52 return true;
53 }
53 }
54
54
55 public JSONElementContext ElementContext {
55 public JSONElementContext ElementContext {
56 get { return m_elementContext; }
56 get { return m_elementContext; }
57 }
57 }
58 }
58 }
59
59
60 static readonly ParserContext _jsonContext;
60 static readonly ParserContext _jsonContext;
61 static readonly ParserContext _objectContext;
61 static readonly ParserContext _objectContext;
62 static readonly ParserContext _arrayContext;
62 static readonly ParserContext _arrayContext;
63
63
64 static JSONParser() {
64 static JSONParser() {
65
65
66 var valueExpression = MakeToken(JsonTokenType.BeginArray, JsonTokenType.BeginObject, JsonTokenType.Literal, JsonTokenType.Number, JsonTokenType.String);
66 var valueExpression = MakeToken(JsonTokenType.BeginArray, JsonTokenType.BeginObject, JsonTokenType.Literal, JsonTokenType.Number, JsonTokenType.String);
67 var memberExpression = MakeToken(JsonTokenType.String).Cat(MakeToken(JsonTokenType.NameSeparator)).Cat(valueExpression);
67 var memberExpression = MakeToken(JsonTokenType.String).Cat(MakeToken(JsonTokenType.NameSeparator)).Cat(valueExpression);
68
68
69 var objectExpression = memberExpression
69 var objectExpression = memberExpression
70 .Cat(
70 .Cat(
71 MakeToken(JsonTokenType.ValueSeparator)
71 MakeToken(JsonTokenType.ValueSeparator)
72 .Cat(memberExpression)
72 .Cat(memberExpression)
73 .EClosure()
73 .EClosure()
74 )
74 )
75 .Optional()
75 .Optional()
76 .Cat(MakeToken(JsonTokenType.EndObject))
76 .Cat(MakeToken(JsonTokenType.EndObject))
77 .End();
77 .End();
78
78
79 var arrayExpression = valueExpression
79 var arrayExpression = valueExpression
80 .Cat(
80 .Cat(
81 MakeToken(JsonTokenType.ValueSeparator)
81 MakeToken(JsonTokenType.ValueSeparator)
82 .Cat(valueExpression)
82 .Cat(valueExpression)
83 .EClosure()
83 .EClosure()
84 )
84 )
85 .Optional()
85 .Optional()
86 .Cat(MakeToken(JsonTokenType.EndArray))
86 .Cat(MakeToken(JsonTokenType.EndArray))
87 .End();
87 .End();
88
88
89 var jsonExpression = valueExpression.End();
89 var jsonExpression = valueExpression.End();
90
90
91 _jsonContext = CreateParserContext(jsonExpression, JSONElementContext.None);
91 _jsonContext = CreateParserContext(jsonExpression, JSONElementContext.None);
92 _objectContext = CreateParserContext(objectExpression, JSONElementContext.Object);
92 _objectContext = CreateParserContext(objectExpression, JSONElementContext.Object);
93 _arrayContext = CreateParserContext(arrayExpression, JSONElementContext.Array);
93 _arrayContext = CreateParserContext(arrayExpression, JSONElementContext.Array);
94 }
94 }
95
95
96 static Token MakeToken(params JsonTokenType[] input) {
96 static Token MakeToken(params JsonTokenType[] input) {
97 return Token.New( input.Select(t => (int)t).ToArray() );
97 return Token.New( input.Select(t => (int)t).ToArray() );
98 }
98 }
99
99
100 static ParserContext CreateParserContext(Token expr, JSONElementContext context) {
100 static ParserContext CreateParserContext(Token expr, JSONElementContext context) {
101
101
102 var dfa = new DFATable();
102 var dfa = new DFATable();
103 var builder = new RegularExpressionVisitor(dfa);
103 var builder = new RegularExpressionVisitor(dfa);
104 expr.Accept(builder);
104 expr.Accept(builder);
105 builder.BuildDFA();
105 builder.BuildDFA();
106
106
107 return new ParserContext(dfa.CreateTransitionTable(), dfa.InitialState, context);
107 return new ParserContext(dfa.CreateTransitionTable(), dfa.InitialState, context);
108 }
108 }
109
109
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;
117 string m_memberName = String.Empty;
118 string m_memberName = String.Empty;
118
119
119 Stack<ParserContext> m_stack = new Stack<ParserContext>();
120 Stack<ParserContext> m_stack = new Stack<ParserContext>();
120 ParserContext m_context = _jsonContext;
121 ParserContext m_context = _jsonContext;
121
122
122 /// <summary>
123 /// <summary>
123 /// Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ Π½ΠΎΠ²Ρ‹ΠΉ парсСр Π½Π° основС строки, содСрТащСй JSON
124 /// Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ Π½ΠΎΠ²Ρ‹ΠΉ парсСр Π½Π° основС строки, содСрТащСй JSON
124 /// </summary>
125 /// </summary>
125 /// <param name="text"></param>
126 /// <param name="text"></param>
126 public JSONParser(string text) {
127 public JSONParser(string text) {
127 Safe.ArgumentNotEmpty(text, "text");
128 Safe.ArgumentNotEmpty(text, "text");
128 m_scanner = new JSONScanner(text);
129 m_scanner = new JSONScanner(text);
129 }
130 }
130
131
131 /// <summary>
132 /// <summary>
132 /// Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ Π½ΠΎΠ²Ρ‹ΠΉ экзСмпляр парсСра, Π½Π° основС тСкстового ΠΏΠΎΡ‚ΠΎΠΊΠ°.
133 /// Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ Π½ΠΎΠ²Ρ‹ΠΉ экзСмпляр парсСра, Π½Π° основС тСкстового ΠΏΠΎΡ‚ΠΎΠΊΠ°.
133 /// </summary>
134 /// </summary>
134 /// <param name="reader">ВСкстовый ΠΏΠΎΡ‚ΠΎΠΊ.</param>
135 /// <param name="reader">ВСкстовый ΠΏΠΎΡ‚ΠΎΠΊ.</param>
135 public JSONParser(TextReader reader) {
136 public JSONParser(TextReader reader) {
136 Safe.ArgumentNotNull(reader, "reader");
137 Safe.ArgumentNotNull(reader, "reader");
137 m_scanner = new JSONScanner(reader);
138 m_scanner = new JSONScanner(reader);
138 }
139 }
139
140
140 public int Level {
141 public int Level {
141 get { return m_stack.Count; }
142 get { return m_stack.Count; }
142 }
143 }
143
144
144 /// <summary>
145 /// <summary>
145 /// Π’ΠΈΠΏ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ элСмСнта Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ стоит парсСр.
146 /// Π’ΠΈΠΏ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ элСмСнта Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ стоит парсСр.
146 /// </summary>
147 /// </summary>
147 public JSONElementType ElementType {
148 public JSONElementType ElementType {
148 get { return m_elementType; }
149 get { return m_elementType; }
149 }
150 }
150
151
151 /// <summary>
152 /// <summary>
152 /// Имя элСмСнта - имя свойства Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π°. Для элСмСнтов массивов ΠΈ ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠ³ΠΎ всСгда
153 /// Имя элСмСнта - имя свойства Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π°. Для элСмСнтов массивов ΠΈ ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠ³ΠΎ всСгда
153 /// пустая строка.
154 /// пустая строка.
154 /// </summary>
155 /// </summary>
155 public string ElementName {
156 public string ElementName {
156 get { return m_memberName; }
157 get { return m_memberName; }
157 }
158 }
158
159
159 /// <summary>
160 /// <summary>
160 /// Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ элСмСнта. Волько для элСмСнтов Ρ‚ΠΈΠΏΠ° <see cref="JSONElementType.Value"/>, для ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ… <c>null</c>
161 /// Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ элСмСнта. Волько для элСмСнтов Ρ‚ΠΈΠΏΠ° <see cref="JSONElementType.Value"/>, для ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ… <c>null</c>
161 /// </summary>
162 /// </summary>
162 public object ElementValue {
163 public object ElementValue {
163 get { return m_elementValue; }
164 get { return m_elementValue; }
164 }
165 }
165
166
166 /// <summary>
167 /// <summary>
167 /// Π§ΠΈΡ‚Π°Π΅Ρ‚ ΡΠ»Π΅ΡŽΡƒΠ΄ΡƒΡ‰ΠΈΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΠ· ΠΏΠΎΡ‚ΠΎΠΊΠ°
168 /// Π§ΠΈΡ‚Π°Π΅Ρ‚ ΡΠ»Π΅ΡŽΡƒΠ΄ΡƒΡ‰ΠΈΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΠ· ΠΏΠΎΡ‚ΠΎΠΊΠ°
168 /// </summary>
169 /// </summary>
169 /// <returns><c>true</c> - опСрация чтСния ΠΏΡ€ΠΎΡˆΠ»Π° ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ, <c>false</c> - ΠΊΠΎΠ½Π΅Ρ† Π΄Π°Π½Π½Ρ‹Ρ…</returns>
170 /// <returns><c>true</c> - опСрация чтСния ΠΏΡ€ΠΎΡˆΠ»Π° ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ, <c>false</c> - ΠΊΠΎΠ½Π΅Ρ† Π΄Π°Π½Π½Ρ‹Ρ…</returns>
170 public bool Read() {
171 public bool Read() {
171 object tokenValue;
172 object tokenValue;
172 JsonTokenType tokenType;
173 JsonTokenType tokenType;
173
174
174 m_memberName = String.Empty;
175 m_memberName = String.Empty;
175
176
176 while (m_scanner.ReadToken(out tokenValue, out tokenType)) {
177 while (m_scanner.ReadToken(out tokenValue, out tokenType)) {
177 if(!m_context.Move(tokenType))
178 if(!m_context.Move(tokenType))
178 UnexpectedToken(tokenValue, tokenType);
179 UnexpectedToken(tokenValue, tokenType);
179
180
180 switch (tokenType) {
181 switch (tokenType) {
181 case JsonTokenType.BeginObject:
182 case JsonTokenType.BeginObject:
182 m_stack.Push(m_context);
183 m_stack.Push(m_context);
183 m_context = _objectContext;
184 m_context = _objectContext;
184
185
185 m_elementValue = null;
186 m_elementValue = null;
186 m_memberContext = MemberContext.MemberName;
187 m_memberContext = MemberContext.MemberName;
187 m_elementType = JSONElementType.BeginObject;
188 m_elementType = JSONElementType.BeginObject;
188 return true;
189 return true;
189 case JsonTokenType.EndObject:
190 case JsonTokenType.EndObject:
190 if (m_stack.Count == 0)
191 if (m_stack.Count == 0)
191 UnexpectedToken(tokenValue, tokenType);
192 UnexpectedToken(tokenValue, tokenType);
192 m_context = m_stack.Pop();
193 m_context = m_stack.Pop();
193
194
194 m_elementValue = null;
195 m_elementValue = null;
195 m_elementType = JSONElementType.EndObject;
196 m_elementType = JSONElementType.EndObject;
196 return true;
197 return true;
197 case JsonTokenType.BeginArray:
198 case JsonTokenType.BeginArray:
198 m_stack.Push(m_context);
199 m_stack.Push(m_context);
199 m_context = _arrayContext;
200 m_context = _arrayContext;
200
201
201 m_elementValue = null;
202 m_elementValue = null;
202 m_memberContext = MemberContext.MemberValue;
203 m_memberContext = MemberContext.MemberValue;
203 m_elementType = JSONElementType.BeginArray;
204 m_elementType = JSONElementType.BeginArray;
204 return true;
205 return true;
205 case JsonTokenType.EndArray:
206 case JsonTokenType.EndArray:
206 if (m_stack.Count == 0)
207 if (m_stack.Count == 0)
207 UnexpectedToken(tokenValue, tokenType);
208 UnexpectedToken(tokenValue, tokenType);
208 m_context = m_stack.Pop();
209 m_context = m_stack.Pop();
209
210
210 m_elementValue = null;
211 m_elementValue = null;
211 m_elementType = JSONElementType.EndArray;
212 m_elementType = JSONElementType.EndArray;
212 return true;
213 return true;
213 case JsonTokenType.String:
214 case JsonTokenType.String:
214 if (m_memberContext == MemberContext.MemberName) {
215 if (m_memberContext == MemberContext.MemberName) {
215 m_memberName = (string)tokenValue;
216 m_memberName = (string)tokenValue;
216 break;
217 break;
217 }
218 }
218 m_elementType = JSONElementType.Value;
219 m_elementType = JSONElementType.Value;
219 m_elementValue = tokenValue;
220 m_elementValue = tokenValue;
220 return true;
221 return true;
221 case JsonTokenType.Number:
222 case JsonTokenType.Number:
222 m_elementType = JSONElementType.Value;
223 m_elementType = JSONElementType.Value;
223 m_elementValue = tokenValue;
224 m_elementValue = tokenValue;
224 return true;
225 return true;
225 case JsonTokenType.Literal:
226 case JsonTokenType.Literal:
226 m_elementType = JSONElementType.Value;
227 m_elementType = JSONElementType.Value;
227 m_elementValue = ParseLiteral((string)tokenValue);
228 m_elementValue = ParseLiteral((string)tokenValue);
228 return true;
229 return true;
229 case JsonTokenType.NameSeparator:
230 case JsonTokenType.NameSeparator:
230 m_memberContext = MemberContext.MemberValue;
231 m_memberContext = MemberContext.MemberValue;
231 break;
232 break;
232 case JsonTokenType.ValueSeparator:
233 case JsonTokenType.ValueSeparator:
233 m_memberContext = m_context.ElementContext == JSONElementContext.Object ? MemberContext.MemberName : MemberContext.MemberValue;
234 m_memberContext = m_context.ElementContext == JSONElementContext.Object ? MemberContext.MemberName : MemberContext.MemberValue;
234 break;
235 break;
235 default:
236 default:
236 UnexpectedToken(tokenValue, tokenType);
237 UnexpectedToken(tokenValue, tokenType);
237 break;
238 break;
238 }
239 }
239 }
240 }
240 if (m_context.ElementContext != JSONElementContext.None)
241 if (m_context.ElementContext != JSONElementContext.None)
241 throw new ParserException("Unexpedted end of data");
242 throw new ParserException("Unexpedted end of data");
242
243
243 EOF = true;
244 EOF = true;
244
245
245 return false;
246 return false;
246 }
247 }
247
248
248 object ParseLiteral(string literal) {
249 object ParseLiteral(string literal) {
249 switch (literal) {
250 switch (literal) {
250 case "null":
251 case "null":
251 return null;
252 return null;
252 case "false":
253 case "false":
253 return false;
254 return false;
254 case "true":
255 case "true":
255 return true;
256 return true;
256 default:
257 default:
257 UnexpectedToken(literal, JsonTokenType.Literal);
258 UnexpectedToken(literal, JsonTokenType.Literal);
258 return null; // avoid compliler error
259 return null; // avoid compliler error
259 }
260 }
260 }
261 }
261
262
262 void UnexpectedToken(object value, JsonTokenType tokenType) {
263 void UnexpectedToken(object value, JsonTokenType tokenType) {
263 throw new ParserException(String.Format("Unexpected token {0}: '{1}'", tokenType, value));
264 throw new ParserException(String.Format("Unexpected token {0}: '{1}'", tokenType, value));
264 }
265 }
265
266
266
267
267 /// <summary>
268 /// <summary>
268 /// ΠŸΡ€ΠΈΠ·Π½Π°ΠΊ ΠΊΠΎΠ½Ρ†Π° ΠΏΠΎΡ‚ΠΎΠΊΠ°
269 /// ΠŸΡ€ΠΈΠ·Π½Π°ΠΊ ΠΊΠΎΠ½Ρ†Π° ΠΏΠΎΡ‚ΠΎΠΊΠ°
269 /// </summary>
270 /// </summary>
270 public bool EOF {
271 public bool EOF {
271 get;
272 get;
272 private set;
273 private set;
273 }
274 }
274
275
275 protected override void Dispose(bool disposing) {
276 protected override void Dispose(bool disposing) {
276 if (disposing)
277 if (disposing)
277 m_scanner.Dispose();
278 m_scanner.Dispose();
278 }
279 }
279
280
280 /// <summary>
281 /// <summary>
281 /// ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ Π² ΠΊΠΎΠ½Π΅Ρ† Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.
282 /// ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ Π² ΠΊΠΎΠ½Π΅Ρ† Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.
282 /// </summary>
283 /// </summary>
283 public void SeekElementEnd() {
284 public void SeekElementEnd() {
284 var level = Level - 1;
285 var level = Level - 1;
285
286
286 Debug.Assert(level >= 0);
287 Debug.Assert(level >= 0);
287
288
288 while (Level != level)
289 while (Level != level)
289 Read();
290 Read();
290 }
291 }
291 }
292 }
292
293
293 }
294 }
@@ -1,62 +1,62
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 }
17
17
18 /// <summary>
18 /// <summary>
19 /// Π˜Π½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ массивы ΠΊΠ°ΠΊ мноТСствСнныС элСмСнты (ΡƒΠ±ΠΈΡ€Π°Π΅Ρ‚ ΠΎΠ΄ΠΈΠ½ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ влоТСнности), ΠΈΠ½Π°Ρ‡Π΅ массив
19 /// Π˜Π½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ массивы ΠΊΠ°ΠΊ мноТСствСнныС элСмСнты (ΡƒΠ±ΠΈΡ€Π°Π΅Ρ‚ ΠΎΠ΄ΠΈΠ½ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ влоТСнности), ΠΈΠ½Π°Ρ‡Π΅ массив
20 /// прСдставляСтся Π² Π²ΠΈΠ΄Π΅ ΡƒΠ·Π»Π°, Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΌΠΈ элСмСнтами ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΡΠ²Π»ΡΡŽΡ‚ΡΡ элСмСнты массива, ΠΈΠΌΠ΅Π½Π° Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΡ… элСмСнтов
20 /// прСдставляСтся Π² Π²ΠΈΠ΄Π΅ ΡƒΠ·Π»Π°, Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΌΠΈ элСмСнтами ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΡΠ²Π»ΡΡŽΡ‚ΡΡ элСмСнты массива, ΠΈΠΌΠ΅Π½Π° Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΡ… элСмСнтов
21 /// ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚ΡΡ свойством <see cref="ArrayItemName"/>. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ <c>false</c>.
21 /// ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚ΡΡ свойством <see cref="ArrayItemName"/>. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ <c>false</c>.
22 /// </summary>
22 /// </summary>
23 public bool FlattenArrays {
23 public bool FlattenArrays {
24 get;
24 get;
25 set;
25 set;
26 }
26 }
27
27
28 /// <summary>
28 /// <summary>
29 /// ΠŸΡ€Π΅Ρ„ΠΈΠΊΡ, для ΡƒΠ·Π»ΠΎΠ² Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°
29 /// ΠŸΡ€Π΅Ρ„ΠΈΠΊΡ, для ΡƒΠ·Π»ΠΎΠ² Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°
30 /// </summary>
30 /// </summary>
31 public string NodesPrefix {
31 public string NodesPrefix {
32 get;
32 get;
33 set;
33 set;
34 }
34 }
35
35
36 /// <summary>
36 /// <summary>
37 /// Имя ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠ³ΠΎ элСмСнта Π² xml Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π΅
37 /// Имя ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠ³ΠΎ элСмСнта Π² xml Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π΅
38 /// </summary>
38 /// </summary>
39 public string RootName {
39 public string RootName {
40 get;
40 get;
41 set;
41 set;
42 }
42 }
43
43
44 /// <summary>
44 /// <summary>
45 /// Имя элСмСнта для массивов, Ссли Π½Π΅ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½Π° опция <see cref="FlattenArrays"/>.
45 /// Имя элСмСнта для массивов, Ссли Π½Π΅ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½Π° опция <see cref="FlattenArrays"/>.
46 /// По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ <c>item</c>.
46 /// По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ <c>item</c>.
47 /// </summary>
47 /// </summary>
48 public string ArrayItemName {
48 public string ArrayItemName {
49 get;
49 get;
50 set;
50 set;
51 }
51 }
52
52
53 /// <summary>
53 /// <summary>
54 /// Π’Π°Π±Π»ΠΈΡ†Π° Π°Ρ‚ΠΎΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… строк для построСния Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°.
54 /// Π’Π°Π±Π»ΠΈΡ†Π° Π°Ρ‚ΠΎΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… строк для построСния Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°.
55 /// </summary>
55 /// </summary>
56 public XmlNameTable NameTable {
56 public XmlNameTable NameTable {
57 get;
57 get;
58 set;
58 set;
59 }
59 }
60
60
61 }
61 }
62 }
62 }
@@ -1,276 +1,281
1 ο»Ώ<?xml version="1.0" encoding="utf-8"?>
1 ο»Ώ<?xml version="1.0" encoding="utf-8"?>
2 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 <PropertyGroup>
3 <PropertyGroup>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6 <ProjectGuid>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</ProjectGuid>
6 <ProjectGuid>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</ProjectGuid>
7 <OutputType>Library</OutputType>
7 <OutputType>Library</OutputType>
8 <RootNamespace>Implab</RootNamespace>
8 <RootNamespace>Implab</RootNamespace>
9 <AssemblyName>Implab</AssemblyName>
9 <AssemblyName>Implab</AssemblyName>
10 <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
10 <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
11 </PropertyGroup>
11 </PropertyGroup>
12 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
12 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
13 <DebugSymbols>true</DebugSymbols>
13 <DebugSymbols>true</DebugSymbols>
14 <DebugType>full</DebugType>
14 <DebugType>full</DebugType>
15 <Optimize>false</Optimize>
15 <Optimize>false</Optimize>
16 <OutputPath>bin\Debug</OutputPath>
16 <OutputPath>bin\Debug</OutputPath>
17 <DefineConstants>TRACE;DEBUG;</DefineConstants>
17 <DefineConstants>TRACE;DEBUG;</DefineConstants>
18 <ErrorReport>prompt</ErrorReport>
18 <ErrorReport>prompt</ErrorReport>
19 <WarningLevel>4</WarningLevel>
19 <WarningLevel>4</WarningLevel>
20 <ConsolePause>false</ConsolePause>
20 <ConsolePause>false</ConsolePause>
21 <RunCodeAnalysis>true</RunCodeAnalysis>
21 <RunCodeAnalysis>true</RunCodeAnalysis>
22 </PropertyGroup>
22 </PropertyGroup>
23 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
23 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
24 <DebugType>full</DebugType>
24 <DebugType>full</DebugType>
25 <Optimize>true</Optimize>
25 <Optimize>true</Optimize>
26 <OutputPath>bin\Release</OutputPath>
26 <OutputPath>bin\Release</OutputPath>
27 <ErrorReport>prompt</ErrorReport>
27 <ErrorReport>prompt</ErrorReport>
28 <WarningLevel>4</WarningLevel>
28 <WarningLevel>4</WarningLevel>
29 <ConsolePause>false</ConsolePause>
29 <ConsolePause>false</ConsolePause>
30 </PropertyGroup>
30 </PropertyGroup>
31 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug 4.5|AnyCPU' ">
31 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug 4.5|AnyCPU' ">
32 <DebugSymbols>true</DebugSymbols>
32 <DebugSymbols>true</DebugSymbols>
33 <DebugType>full</DebugType>
33 <DebugType>full</DebugType>
34 <Optimize>false</Optimize>
34 <Optimize>false</Optimize>
35 <OutputPath>bin\Debug</OutputPath>
35 <OutputPath>bin\Debug</OutputPath>
36 <DefineConstants>TRACE;DEBUG;NET_4_5</DefineConstants>
36 <DefineConstants>TRACE;DEBUG;NET_4_5</DefineConstants>
37 <ErrorReport>prompt</ErrorReport>
37 <ErrorReport>prompt</ErrorReport>
38 <WarningLevel>4</WarningLevel>
38 <WarningLevel>4</WarningLevel>
39 <RunCodeAnalysis>true</RunCodeAnalysis>
39 <RunCodeAnalysis>true</RunCodeAnalysis>
40 <ConsolePause>false</ConsolePause>
40 <ConsolePause>false</ConsolePause>
41 </PropertyGroup>
41 </PropertyGroup>
42 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release 4.5|AnyCPU' ">
42 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release 4.5|AnyCPU' ">
43 <Optimize>true</Optimize>
43 <Optimize>true</Optimize>
44 <OutputPath>bin\Release</OutputPath>
44 <OutputPath>bin\Release</OutputPath>
45 <ErrorReport>prompt</ErrorReport>
45 <ErrorReport>prompt</ErrorReport>
46 <WarningLevel>4</WarningLevel>
46 <WarningLevel>4</WarningLevel>
47 <ConsolePause>false</ConsolePause>
47 <ConsolePause>false</ConsolePause>
48 <DefineConstants>NET_4_5</DefineConstants>
48 <DefineConstants>NET_4_5</DefineConstants>
49 </PropertyGroup>
49 </PropertyGroup>
50 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugMono|AnyCPU' ">
50 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugMono|AnyCPU' ">
51 <DebugSymbols>true</DebugSymbols>
51 <DebugSymbols>true</DebugSymbols>
52 <DebugType>full</DebugType>
52 <DebugType>full</DebugType>
53 <Optimize>false</Optimize>
53 <Optimize>false</Optimize>
54 <OutputPath>bin\Debug</OutputPath>
54 <OutputPath>bin\Debug</OutputPath>
55 <DefineConstants>TRACE;DEBUG;NET_4_5;MONO</DefineConstants>
55 <DefineConstants>TRACE;DEBUG;NET_4_5;MONO</DefineConstants>
56 <ErrorReport>prompt</ErrorReport>
56 <ErrorReport>prompt</ErrorReport>
57 <WarningLevel>4</WarningLevel>
57 <WarningLevel>4</WarningLevel>
58 <RunCodeAnalysis>true</RunCodeAnalysis>
58 <RunCodeAnalysis>true</RunCodeAnalysis>
59 <ConsolePause>false</ConsolePause>
59 <ConsolePause>false</ConsolePause>
60 </PropertyGroup>
60 </PropertyGroup>
61 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseMono|AnyCPU' ">
61 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseMono|AnyCPU' ">
62 <Optimize>true</Optimize>
62 <Optimize>true</Optimize>
63 <OutputPath>bin\Release</OutputPath>
63 <OutputPath>bin\Release</OutputPath>
64 <DefineConstants>NET_4_5;MONO;</DefineConstants>
64 <DefineConstants>NET_4_5;MONO;</DefineConstants>
65 <ErrorReport>prompt</ErrorReport>
65 <ErrorReport>prompt</ErrorReport>
66 <WarningLevel>4</WarningLevel>
66 <WarningLevel>4</WarningLevel>
67 <ConsolePause>false</ConsolePause>
67 <ConsolePause>false</ConsolePause>
68 </PropertyGroup>
68 </PropertyGroup>
69 <ItemGroup>
69 <ItemGroup>
70 <Reference Include="System" />
70 <Reference Include="System" />
71 <Reference Include="System.Xml" />
71 <Reference Include="System.Xml" />
72 <Reference Include="mscorlib" />
72 <Reference Include="mscorlib" />
73 </ItemGroup>
73 </ItemGroup>
74 <ItemGroup>
74 <ItemGroup>
75 <Compile Include="Components\StateChangeEventArgs.cs" />
75 <Compile Include="Components\StateChangeEventArgs.cs" />
76 <Compile Include="CustomEqualityComparer.cs" />
76 <Compile Include="CustomEqualityComparer.cs" />
77 <Compile Include="Diagnostics\ConsoleTraceListener.cs" />
77 <Compile Include="Diagnostics\ConsoleTraceListener.cs" />
78 <Compile Include="Diagnostics\LogChannel.cs" />
78 <Compile Include="Diagnostics\LogChannel.cs" />
79 <Compile Include="Diagnostics\LogicalOperation.cs" />
79 <Compile Include="Diagnostics\LogicalOperation.cs" />
80 <Compile Include="Diagnostics\TextFileListener.cs" />
80 <Compile Include="Diagnostics\TextFileListener.cs" />
81 <Compile Include="Diagnostics\Trace.cs" />
81 <Compile Include="Diagnostics\Trace.cs" />
82 <Compile Include="Diagnostics\TraceLog.cs" />
82 <Compile Include="Diagnostics\TraceLog.cs" />
83 <Compile Include="Diagnostics\TraceEvent.cs" />
83 <Compile Include="Diagnostics\TraceEvent.cs" />
84 <Compile Include="Diagnostics\TraceEventType.cs" />
84 <Compile Include="Diagnostics\TraceEventType.cs" />
85 <Compile Include="Diagnostics\TraceSourceAttribute.cs" />
85 <Compile Include="Diagnostics\TraceSourceAttribute.cs" />
86 <Compile Include="ICancellable.cs" />
86 <Compile Include="ICancellable.cs" />
87 <Compile Include="IProgressHandler.cs" />
87 <Compile Include="IProgressHandler.cs" />
88 <Compile Include="IProgressNotifier.cs" />
88 <Compile Include="IProgressNotifier.cs" />
89 <Compile Include="IPromiseT.cs" />
89 <Compile Include="IPromiseT.cs" />
90 <Compile Include="IPromise.cs" />
90 <Compile Include="IPromise.cs" />
91 <Compile Include="IServiceLocator.cs" />
91 <Compile Include="IServiceLocator.cs" />
92 <Compile Include="ITaskController.cs" />
92 <Compile Include="ITaskController.cs" />
93 <Compile Include="Parallels\DispatchPool.cs" />
93 <Compile Include="Parallels\DispatchPool.cs" />
94 <Compile Include="Parallels\ArrayTraits.cs" />
94 <Compile Include="Parallels\ArrayTraits.cs" />
95 <Compile Include="Parallels\MTQueue.cs" />
95 <Compile Include="Parallels\MTQueue.cs" />
96 <Compile Include="Parallels\WorkerPool.cs" />
96 <Compile Include="Parallels\WorkerPool.cs" />
97 <Compile Include="ProgressInitEventArgs.cs" />
97 <Compile Include="ProgressInitEventArgs.cs" />
98 <Compile Include="Properties\AssemblyInfo.cs" />
98 <Compile Include="Properties\AssemblyInfo.cs" />
99 <Compile Include="Parallels\AsyncPool.cs" />
99 <Compile Include="Parallels\AsyncPool.cs" />
100 <Compile Include="Safe.cs" />
100 <Compile Include="Safe.cs" />
101 <Compile Include="SyncContextPromise.cs" />
101 <Compile Include="SyncContextPromise.cs" />
102 <Compile Include="ValueEventArgs.cs" />
102 <Compile Include="ValueEventArgs.cs" />
103 <Compile Include="PromiseExtensions.cs" />
103 <Compile Include="PromiseExtensions.cs" />
104 <Compile Include="SyncContextPromiseT.cs" />
104 <Compile Include="SyncContextPromiseT.cs" />
105 <Compile Include="Diagnostics\OperationContext.cs" />
105 <Compile Include="Diagnostics\OperationContext.cs" />
106 <Compile Include="Diagnostics\TraceContext.cs" />
106 <Compile Include="Diagnostics\TraceContext.cs" />
107 <Compile Include="Diagnostics\LogEventArgs.cs" />
107 <Compile Include="Diagnostics\LogEventArgs.cs" />
108 <Compile Include="Diagnostics\LogEventArgsT.cs" />
108 <Compile Include="Diagnostics\LogEventArgsT.cs" />
109 <Compile Include="Diagnostics\Extensions.cs" />
109 <Compile Include="Diagnostics\Extensions.cs" />
110 <Compile Include="PromiseEventType.cs" />
110 <Compile Include="PromiseEventType.cs" />
111 <Compile Include="Parallels\AsyncQueue.cs" />
111 <Compile Include="Parallels\AsyncQueue.cs" />
112 <Compile Include="PromiseT.cs" />
112 <Compile Include="PromiseT.cs" />
113 <Compile Include="IDeferred.cs" />
113 <Compile Include="IDeferred.cs" />
114 <Compile Include="IDeferredT.cs" />
114 <Compile Include="IDeferredT.cs" />
115 <Compile Include="Promise.cs" />
115 <Compile Include="Promise.cs" />
116 <Compile Include="PromiseTransientException.cs" />
116 <Compile Include="PromiseTransientException.cs" />
117 <Compile Include="Parallels\Signal.cs" />
117 <Compile Include="Parallels\Signal.cs" />
118 <Compile Include="Parallels\SharedLock.cs" />
118 <Compile Include="Parallels\SharedLock.cs" />
119 <Compile Include="Diagnostics\ILogWriter.cs" />
119 <Compile Include="Diagnostics\ILogWriter.cs" />
120 <Compile Include="Diagnostics\ListenerBase.cs" />
120 <Compile Include="Diagnostics\ListenerBase.cs" />
121 <Compile Include="Parallels\BlockingQueue.cs" />
121 <Compile Include="Parallels\BlockingQueue.cs" />
122 <Compile Include="AbstractEvent.cs" />
122 <Compile Include="AbstractEvent.cs" />
123 <Compile Include="AbstractPromise.cs" />
123 <Compile Include="AbstractPromise.cs" />
124 <Compile Include="AbstractPromiseT.cs" />
124 <Compile Include="AbstractPromiseT.cs" />
125 <Compile Include="FuncTask.cs" />
125 <Compile Include="FuncTask.cs" />
126 <Compile Include="FuncTaskBase.cs" />
126 <Compile Include="FuncTaskBase.cs" />
127 <Compile Include="FuncTaskT.cs" />
127 <Compile Include="FuncTaskT.cs" />
128 <Compile Include="ActionChainTaskBase.cs" />
128 <Compile Include="ActionChainTaskBase.cs" />
129 <Compile Include="ActionChainTask.cs" />
129 <Compile Include="ActionChainTask.cs" />
130 <Compile Include="ActionChainTaskT.cs" />
130 <Compile Include="ActionChainTaskT.cs" />
131 <Compile Include="FuncChainTaskBase.cs" />
131 <Compile Include="FuncChainTaskBase.cs" />
132 <Compile Include="FuncChainTask.cs" />
132 <Compile Include="FuncChainTask.cs" />
133 <Compile Include="FuncChainTaskT.cs" />
133 <Compile Include="FuncChainTaskT.cs" />
134 <Compile Include="ActionTaskBase.cs" />
134 <Compile Include="ActionTaskBase.cs" />
135 <Compile Include="ActionTask.cs" />
135 <Compile Include="ActionTask.cs" />
136 <Compile Include="ActionTaskT.cs" />
136 <Compile Include="ActionTaskT.cs" />
137 <Compile Include="ICancellationToken.cs" />
137 <Compile Include="ICancellationToken.cs" />
138 <Compile Include="SuccessPromise.cs" />
138 <Compile Include="SuccessPromise.cs" />
139 <Compile Include="SuccessPromiseT.cs" />
139 <Compile Include="SuccessPromiseT.cs" />
140 <Compile Include="PromiseAwaiterT.cs" />
140 <Compile Include="PromiseAwaiterT.cs" />
141 <Compile Include="PromiseAwaiter.cs" />
141 <Compile Include="PromiseAwaiter.cs" />
142 <Compile Include="Components\ComponentContainer.cs" />
142 <Compile Include="Components\ComponentContainer.cs" />
143 <Compile Include="Components\Disposable.cs" />
143 <Compile Include="Components\Disposable.cs" />
144 <Compile Include="Components\DisposablePool.cs" />
144 <Compile Include="Components\DisposablePool.cs" />
145 <Compile Include="Components\ObjectPool.cs" />
145 <Compile Include="Components\ObjectPool.cs" />
146 <Compile Include="Components\ServiceLocator.cs" />
146 <Compile Include="Components\ServiceLocator.cs" />
147 <Compile Include="Components\IInitializable.cs" />
147 <Compile Include="Components\IInitializable.cs" />
148 <Compile Include="TaskController.cs" />
148 <Compile Include="TaskController.cs" />
149 <Compile Include="Components\App.cs" />
149 <Compile Include="Components\App.cs" />
150 <Compile Include="Components\IRunnable.cs" />
150 <Compile Include="Components\IRunnable.cs" />
151 <Compile Include="Components\ExecutionState.cs" />
151 <Compile Include="Components\ExecutionState.cs" />
152 <Compile Include="Components\RunnableComponent.cs" />
152 <Compile Include="Components\RunnableComponent.cs" />
153 <Compile Include="Components\IFactory.cs" />
153 <Compile Include="Components\IFactory.cs" />
154 <Compile Include="Automaton\IAlphabet.cs" />
154 <Compile Include="Automaton\IAlphabet.cs" />
155 <Compile Include="Automaton\ParserException.cs" />
155 <Compile Include="Automaton\ParserException.cs" />
156 <Compile Include="Automaton\IndexedAlphabetBase.cs" />
156 <Compile Include="Automaton\IndexedAlphabetBase.cs" />
157 <Compile Include="Automaton\IAlphabetBuilder.cs" />
157 <Compile Include="Automaton\IAlphabetBuilder.cs" />
158 <Compile Include="Automaton\RegularExpressions\AltToken.cs" />
158 <Compile Include="Automaton\RegularExpressions\AltToken.cs" />
159 <Compile Include="Automaton\RegularExpressions\BinaryToken.cs" />
159 <Compile Include="Automaton\RegularExpressions\BinaryToken.cs" />
160 <Compile Include="Automaton\RegularExpressions\CatToken.cs" />
160 <Compile Include="Automaton\RegularExpressions\CatToken.cs" />
161 <Compile Include="Automaton\RegularExpressions\StarToken.cs" />
161 <Compile Include="Automaton\RegularExpressions\StarToken.cs" />
162 <Compile Include="Automaton\RegularExpressions\SymbolToken.cs" />
162 <Compile Include="Automaton\RegularExpressions\SymbolToken.cs" />
163 <Compile Include="Automaton\RegularExpressions\EmptyToken.cs" />
163 <Compile Include="Automaton\RegularExpressions\EmptyToken.cs" />
164 <Compile Include="Automaton\RegularExpressions\Token.cs" />
164 <Compile Include="Automaton\RegularExpressions\Token.cs" />
165 <Compile Include="Automaton\RegularExpressions\IVisitor.cs" />
165 <Compile Include="Automaton\RegularExpressions\IVisitor.cs" />
166 <Compile Include="Automaton\AutomatonTransition.cs" />
166 <Compile Include="Automaton\AutomatonTransition.cs" />
167 <Compile Include="Formats\JSON\JSONElementContext.cs" />
167 <Compile Include="Formats\JSON\JSONElementContext.cs" />
168 <Compile Include="Formats\JSON\JSONElementType.cs" />
168 <Compile Include="Formats\JSON\JSONElementType.cs" />
169 <Compile Include="Formats\JSON\JSONGrammar.cs" />
169 <Compile Include="Formats\JSON\JSONGrammar.cs" />
170 <Compile Include="Formats\JSON\JSONParser.cs" />
170 <Compile Include="Formats\JSON\JSONParser.cs" />
171 <Compile Include="Formats\JSON\JSONScanner.cs" />
171 <Compile Include="Formats\JSON\JSONScanner.cs" />
172 <Compile Include="Formats\JSON\JsonTokenType.cs" />
172 <Compile Include="Formats\JSON\JsonTokenType.cs" />
173 <Compile Include="Formats\JSON\JSONWriter.cs" />
173 <Compile Include="Formats\JSON\JSONWriter.cs" />
174 <Compile Include="Formats\JSON\JSONXmlReader.cs" />
174 <Compile Include="Formats\JSON\JSONXmlReader.cs" />
175 <Compile Include="Formats\JSON\JSONXmlReaderOptions.cs" />
175 <Compile Include="Formats\JSON\JSONXmlReaderOptions.cs" />
176 <Compile Include="Formats\JSON\StringTranslator.cs" />
176 <Compile Include="Formats\JSON\StringTranslator.cs" />
177 <Compile Include="Automaton\MapAlphabet.cs" />
177 <Compile Include="Automaton\MapAlphabet.cs" />
178 <Compile Include="Formats\CharAlphabet.cs" />
178 <Compile Include="Formats\CharAlphabet.cs" />
179 <Compile Include="Formats\ByteAlphabet.cs" />
179 <Compile Include="Formats\ByteAlphabet.cs" />
180 <Compile Include="Automaton\IDFATable.cs" />
180 <Compile Include="Automaton\IDFATable.cs" />
181 <Compile Include="Automaton\IDFATableBuilder.cs" />
181 <Compile Include="Automaton\IDFATableBuilder.cs" />
182 <Compile Include="Automaton\DFATable.cs" />
182 <Compile Include="Automaton\DFATable.cs" />
183 <Compile Include="Automaton\RegularExpressions\RegularExpressionVisitor.cs" />
183 <Compile Include="Automaton\RegularExpressions\RegularExpressionVisitor.cs" />
184 <Compile Include="Automaton\RegularExpressions\ITaggedDFABuilder.cs" />
184 <Compile Include="Automaton\RegularExpressions\ITaggedDFABuilder.cs" />
185 <Compile Include="Formats\TextScanner.cs" />
185 <Compile Include="Formats\TextScanner.cs" />
186 <Compile Include="Formats\StringScanner.cs" />
186 <Compile Include="Formats\StringScanner.cs" />
187 <Compile Include="Formats\ReaderScanner.cs" />
187 <Compile Include="Formats\ReaderScanner.cs" />
188 <Compile Include="Formats\ScannerContext.cs" />
188 <Compile Include="Formats\ScannerContext.cs" />
189 <Compile Include="Formats\Grammar.cs" />
189 <Compile Include="Formats\Grammar.cs" />
190 <Compile Include="Automaton\RegularExpressions\EndTokenT.cs" />
190 <Compile Include="Automaton\RegularExpressions\EndTokenT.cs" />
191 <Compile Include="Automaton\RegularExpressions\EndToken.cs" />
191 <Compile Include="Automaton\RegularExpressions\EndToken.cs" />
192 <Compile Include="Automaton\RegularExpressions\RegularExpressionVisitorT.cs" />
192 <Compile Include="Automaton\RegularExpressions\RegularExpressionVisitorT.cs" />
193 <Compile Include="Automaton\AutomatonConst.cs" />
193 <Compile Include="Automaton\AutomatonConst.cs" />
194 <Compile Include="Automaton\RegularExpressions\RegularDFA.cs" />
194 <Compile Include="Automaton\RegularExpressions\RegularDFA.cs" />
195 <Compile Include="Components\LazyAndWeak.cs" />
195 <Compile Include="Components\LazyAndWeak.cs" />
196 <Compile Include="AbstractTask.cs" />
196 <Compile Include="AbstractTask.cs" />
197 <Compile Include="AbstractTaskT.cs" />
197 <Compile Include="AbstractTaskT.cs" />
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 />
204 <ProjectExtensions>
209 <ProjectExtensions>
205 <MonoDevelop>
210 <MonoDevelop>
206 <Properties>
211 <Properties>
207 <Policies>
212 <Policies>
208 <CSharpFormattingPolicy IndentBlock="True" IndentBraces="False" IndentSwitchSection="False" IndentSwitchCaseSection="True" LabelPositioning="OneLess" NewLinesForBracesInProperties="False" NewLinesForBracesInAccessors="False" NewLinesForBracesInAnonymousMethods="False" NewLinesForBracesInControlBlocks="False" NewLinesForBracesInAnonymousTypes="False" NewLinesForBracesInObjectCollectionArrayInitializers="False" NewLinesForBracesInLambdaExpressionBody="False" NewLineForElse="False" NewLineForCatch="False" NewLineForFinally="False" NewLineForMembersInObjectInit="False" NewLineForMembersInAnonymousTypes="False" NewLineForClausesInQuery="False" SpaceWithinMethodDeclarationParenthesis="False" SpaceBetweenEmptyMethodDeclarationParentheses="False" SpaceWithinMethodCallParentheses="False" SpaceBetweenEmptyMethodCallParentheses="False" SpaceAfterControlFlowStatementKeyword="True" SpaceWithinExpressionParentheses="False" SpaceWithinCastParentheses="False" SpaceWithinOtherParentheses="False" SpaceAfterCast="False" SpacesIgnoreAroundVariableDeclaration="False" SpaceBetweenEmptySquareBrackets="False" SpaceWithinSquareBrackets="False" SpaceAfterColonInBaseTypeDeclaration="True" SpaceAfterComma="True" SpaceAfterDot="False" SpaceAfterSemicolonsInForStatement="True" SpaceBeforeComma="False" SpaceBeforeDot="False" SpaceBeforeSemicolonsInForStatement="False" SpacingAroundBinaryOperator="Single" WrappingPreserveSingleLine="True" WrappingKeepStatementsOnSingleLine="True" PlaceSystemDirectiveFirst="True" NewLinesForBracesInTypes="True" NewLinesForBracesInMethods="True" SpacingAfterMethodDeclarationName="True" SpaceAfterMethodCallName="True" SpaceBeforeOpenSquareBracket="True" SpaceBeforeColonInBaseTypeDeclaration="True" scope="text/x-csharp" />
213 <CSharpFormattingPolicy IndentBlock="True" IndentBraces="False" IndentSwitchSection="False" IndentSwitchCaseSection="True" LabelPositioning="OneLess" NewLinesForBracesInProperties="False" NewLinesForBracesInAccessors="False" NewLinesForBracesInAnonymousMethods="False" NewLinesForBracesInControlBlocks="False" NewLinesForBracesInAnonymousTypes="False" NewLinesForBracesInObjectCollectionArrayInitializers="False" NewLinesForBracesInLambdaExpressionBody="False" NewLineForElse="False" NewLineForCatch="False" NewLineForFinally="False" NewLineForMembersInObjectInit="False" NewLineForMembersInAnonymousTypes="False" NewLineForClausesInQuery="False" SpaceWithinMethodDeclarationParenthesis="False" SpaceBetweenEmptyMethodDeclarationParentheses="False" SpaceWithinMethodCallParentheses="False" SpaceBetweenEmptyMethodCallParentheses="False" SpaceAfterControlFlowStatementKeyword="True" SpaceWithinExpressionParentheses="False" SpaceWithinCastParentheses="False" SpaceWithinOtherParentheses="False" SpaceAfterCast="False" SpacesIgnoreAroundVariableDeclaration="False" SpaceBetweenEmptySquareBrackets="False" SpaceWithinSquareBrackets="False" SpaceAfterColonInBaseTypeDeclaration="True" SpaceAfterComma="True" SpaceAfterDot="False" SpaceAfterSemicolonsInForStatement="True" SpaceBeforeComma="False" SpaceBeforeDot="False" SpaceBeforeSemicolonsInForStatement="False" SpacingAroundBinaryOperator="Single" WrappingPreserveSingleLine="True" WrappingKeepStatementsOnSingleLine="True" PlaceSystemDirectiveFirst="True" NewLinesForBracesInTypes="True" NewLinesForBracesInMethods="True" SpacingAfterMethodDeclarationName="True" SpaceAfterMethodCallName="True" SpaceBeforeOpenSquareBracket="True" SpaceBeforeColonInBaseTypeDeclaration="True" scope="text/x-csharp" />
209 <TextStylePolicy FileWidth="120" TabWidth="4" IndentWidth="4" RemoveTrailingWhitespace="True" NoTabsAfterNonTabs="False" TabsToSpaces="True" EolMarker="Unix" scope="text/x-csharp" />
214 <TextStylePolicy FileWidth="120" TabWidth="4" IndentWidth="4" RemoveTrailingWhitespace="True" NoTabsAfterNonTabs="False" TabsToSpaces="True" EolMarker="Unix" scope="text/x-csharp" />
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>
217 <Rules>
222 <Rules>
218 <NamingRule Name="Namespaces" AffectedEntity="Namespace" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
223 <NamingRule Name="Namespaces" AffectedEntity="Namespace" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
219 <NamingRule Name="Types" AffectedEntity="Class, Struct, Enum, Delegate" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
224 <NamingRule Name="Types" AffectedEntity="Class, Struct, Enum, Delegate" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
220 <NamingRule Name="Interfaces" AffectedEntity="Interface" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
225 <NamingRule Name="Interfaces" AffectedEntity="Interface" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
221 <RequiredPrefixes>
226 <RequiredPrefixes>
222 <String>I</String>
227 <String>I</String>
223 </RequiredPrefixes>
228 </RequiredPrefixes>
224 </NamingRule>
229 </NamingRule>
225 <NamingRule Name="Attributes" AffectedEntity="CustomAttributes" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
230 <NamingRule Name="Attributes" AffectedEntity="CustomAttributes" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
226 <RequiredSuffixes>
231 <RequiredSuffixes>
227 <String>Attribute</String>
232 <String>Attribute</String>
228 </RequiredSuffixes>
233 </RequiredSuffixes>
229 </NamingRule>
234 </NamingRule>
230 <NamingRule Name="Event Arguments" AffectedEntity="CustomEventArgs" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
235 <NamingRule Name="Event Arguments" AffectedEntity="CustomEventArgs" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
231 <RequiredSuffixes>
236 <RequiredSuffixes>
232 <String>EventArgs</String>
237 <String>EventArgs</String>
233 </RequiredSuffixes>
238 </RequiredSuffixes>
234 </NamingRule>
239 </NamingRule>
235 <NamingRule Name="Exceptions" AffectedEntity="CustomExceptions" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
240 <NamingRule Name="Exceptions" AffectedEntity="CustomExceptions" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
236 <RequiredSuffixes>
241 <RequiredSuffixes>
237 <String>Exception</String>
242 <String>Exception</String>
238 </RequiredSuffixes>
243 </RequiredSuffixes>
239 </NamingRule>
244 </NamingRule>
240 <NamingRule Name="Methods" AffectedEntity="Methods" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
245 <NamingRule Name="Methods" AffectedEntity="Methods" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
241 <NamingRule Name="Static Readonly Fields" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Protected, Public" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True" />
246 <NamingRule Name="Static Readonly Fields" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Protected, Public" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True" />
242 <NamingRule Name="Fields (Non Private)" AffectedEntity="Field" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
247 <NamingRule Name="Fields (Non Private)" AffectedEntity="Field" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
243 <NamingRule Name="ReadOnly Fields (Non Private)" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False" />
248 <NamingRule Name="ReadOnly Fields (Non Private)" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False" />
244 <NamingRule Name="Fields (Private)" AffectedEntity="Field, ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
249 <NamingRule Name="Fields (Private)" AffectedEntity="Field, ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
245 <RequiredPrefixes>
250 <RequiredPrefixes>
246 <String>m_</String>
251 <String>m_</String>
247 </RequiredPrefixes>
252 </RequiredPrefixes>
248 </NamingRule>
253 </NamingRule>
249 <NamingRule Name="Static Fields (Private)" AffectedEntity="Field" VisibilityMask="Private" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True">
254 <NamingRule Name="Static Fields (Private)" AffectedEntity="Field" VisibilityMask="Private" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True">
250 <RequiredPrefixes>
255 <RequiredPrefixes>
251 <String>_</String>
256 <String>_</String>
252 </RequiredPrefixes>
257 </RequiredPrefixes>
253 </NamingRule>
258 </NamingRule>
254 <NamingRule Name="ReadOnly Fields (Private)" AffectedEntity="ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
259 <NamingRule Name="ReadOnly Fields (Private)" AffectedEntity="ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
255 <RequiredPrefixes>
260 <RequiredPrefixes>
256 <String>m_</String>
261 <String>m_</String>
257 </RequiredPrefixes>
262 </RequiredPrefixes>
258 </NamingRule>
263 </NamingRule>
259 <NamingRule Name="Constant Fields" AffectedEntity="ConstantField" VisibilityMask="VisibilityMask" NamingStyle="AllUpper" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
264 <NamingRule Name="Constant Fields" AffectedEntity="ConstantField" VisibilityMask="VisibilityMask" NamingStyle="AllUpper" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
260 <NamingRule Name="Properties" AffectedEntity="Property" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
265 <NamingRule Name="Properties" AffectedEntity="Property" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
261 <NamingRule Name="Events" AffectedEntity="Event" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
266 <NamingRule Name="Events" AffectedEntity="Event" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
262 <NamingRule Name="Enum Members" AffectedEntity="EnumMember" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
267 <NamingRule Name="Enum Members" AffectedEntity="EnumMember" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
263 <NamingRule Name="Parameters" AffectedEntity="Parameter, LocalVariable" VisibilityMask="VisibilityMask" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
268 <NamingRule Name="Parameters" AffectedEntity="Parameter, LocalVariable" VisibilityMask="VisibilityMask" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
264 <NamingRule Name="Type Parameters" AffectedEntity="TypeParameter" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
269 <NamingRule Name="Type Parameters" AffectedEntity="TypeParameter" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
265 <RequiredPrefixes>
270 <RequiredPrefixes>
266 <String>T</String>
271 <String>T</String>
267 </RequiredPrefixes>
272 </RequiredPrefixes>
268 </NamingRule>
273 </NamingRule>
269 </Rules>
274 </Rules>
270 </NameConventionPolicy>
275 </NameConventionPolicy>
271 </Policies>
276 </Policies>
272 </Properties>
277 </Properties>
273 </MonoDevelop>
278 </MonoDevelop>
274 </ProjectExtensions>
279 </ProjectExtensions>
275 <ItemGroup />
280 <ItemGroup />
276 </Project> No newline at end of file
281 </Project>
@@ -1,631 +1,623
1 using System.Threading;
1 using System.Threading;
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using System;
3 using System;
4 using System.Collections;
4 using System.Collections;
5 using System.Diagnostics;
5 using System.Diagnostics;
6
6
7 namespace Implab.Parallels {
7 namespace Implab.Parallels {
8 public class AsyncQueue<T> : IEnumerable<T> {
8 public class AsyncQueue<T> : IEnumerable<T> {
9 class Chunk {
9 class Chunk {
10 public Chunk next;
10 public Chunk next;
11
11
12 int m_low;
12 int m_low;
13 int m_hi;
13 int m_hi;
14 int m_alloc;
14 int m_alloc;
15 readonly int m_size;
15 readonly int m_size;
16 readonly T[] m_data;
16 readonly T[] m_data;
17
17
18 public Chunk(int size) {
18 public Chunk(int size) {
19 m_size = size;
19 m_size = size;
20 m_data = new T[size];
20 m_data = new T[size];
21 }
21 }
22
22
23 public Chunk(int size, T value) {
23 public Chunk(int size, T value) {
24 m_size = size;
24 m_size = size;
25 m_hi = 1;
25 m_hi = 1;
26 m_alloc = 1;
26 m_alloc = 1;
27 m_data = new T[size];
27 m_data = new T[size];
28 m_data[0] = value;
28 m_data[0] = value;
29 }
29 }
30
30
31 public Chunk(int size, T[] data, int offset, int length, int alloc) {
31 public Chunk(int size, T[] data, int offset, int length, int alloc) {
32 m_size = size;
32 m_size = size;
33 m_hi = length;
33 m_hi = length;
34 m_alloc = alloc;
34 m_alloc = alloc;
35 m_data = new T[size];
35 m_data = new T[size];
36 Array.Copy(data, offset, m_data, 0, length);
36 Array.Copy(data, offset, m_data, 0, length);
37 }
37 }
38
38
39 public int Low {
39 public int Low {
40 get { return m_low; }
40 get { return m_low; }
41 }
41 }
42
42
43 public int Hi {
43 public int Hi {
44 get { return m_hi; }
44 get { return m_hi; }
45 }
45 }
46
46
47 public int Size {
47 public int Size {
48 get { return m_size; }
48 get { return m_size; }
49 }
49 }
50
50
51 public bool TryEnqueue(T value, out bool extend) {
51 public bool TryEnqueue(T value, out bool extend) {
52 var alloc = Interlocked.Increment(ref m_alloc) - 1;
52 var alloc = Interlocked.Increment(ref m_alloc) - 1;
53
53
54 if (alloc >= m_size) {
54 if (alloc >= m_size) {
55 extend = alloc == m_size;
55 extend = alloc == m_size;
56 return false;
56 return false;
57 }
57 }
58
58
59 extend = false;
59 extend = false;
60 m_data[alloc] = value;
60 m_data[alloc] = value;
61
61
62 while (alloc != Interlocked.CompareExchange(ref m_hi, alloc + 1, alloc)) {
62 while (alloc != Interlocked.CompareExchange(ref m_hi, alloc + 1, alloc)) {
63 // spin wait for commit
63 // spin wait for commit
64 }
64 }
65 return true;
65 return true;
66 }
66 }
67
67
68 /// <summary>
68 /// <summary>
69 /// Prevents from allocating new space in the chunk and waits for all write operations to complete
69 /// Prevents from allocating new space in the chunk and waits for all write operations to complete
70 /// </summary>
70 /// </summary>
71 public void Commit() {
71 public void Commit() {
72 var actual = Math.Min(Interlocked.Exchange(ref m_alloc, m_size + 1), m_size);
72 var actual = Math.Min(Interlocked.Exchange(ref m_alloc, m_size + 1), m_size);
73
73
74 while (m_hi != actual)
74 while (m_hi != actual)
75 Thread.MemoryBarrier();
75 Thread.MemoryBarrier();
76 }
76 }
77
77
78 public bool TryDequeue(out T value, out bool recycle) {
78 public bool TryDequeue(out T value, out bool recycle) {
79 int low;
79 int low;
80 do {
80 do {
81 low = m_low;
81 low = m_low;
82 if (low >= m_hi) {
82 if (low >= m_hi) {
83 value = default(T);
83 value = default(T);
84 recycle = (low == m_size);
84 recycle = (low == m_size);
85 return false;
85 return false;
86 }
86 }
87 } while(low != Interlocked.CompareExchange(ref m_low, low + 1, low));
87 } while(low != Interlocked.CompareExchange(ref m_low, low + 1, low));
88
88
89 recycle = (low == m_size - 1);
89 recycle = (low == m_size - 1);
90 value = m_data[low];
90 value = m_data[low];
91
91
92 return true;
92 return true;
93 }
93 }
94
94
95 public bool TryEnqueueBatch(T[] batch, int offset, int length, out int enqueued, out bool extend) {
95 public bool TryEnqueueBatch(T[] batch, int offset, int length, out int enqueued, out bool extend) {
96 //int alloc;
96 //int alloc;
97 //int allocSize;
97 //int allocSize;
98
98
99 var alloc = Interlocked.Add(ref m_alloc, length) - length;
99 var alloc = Interlocked.Add(ref m_alloc, length) - length;
100 if (alloc > m_size) {
100 if (alloc > m_size) {
101 // the chunk is full and someone already
101 // the chunk is full and someone already
102 // creating the new one
102 // creating the new one
103 enqueued = 0; // nothing was added
103 enqueued = 0; // nothing was added
104 extend = false; // the caller shouldn't try to extend the queue
104 extend = false; // the caller shouldn't try to extend the queue
105 return false; // nothing was added
105 return false; // nothing was added
106 }
106 }
107
107
108 enqueued = Math.Min(m_size - alloc, length);
108 enqueued = Math.Min(m_size - alloc, length);
109 extend = length > enqueued;
109 extend = length > enqueued;
110
110
111 if (enqueued == 0)
111 if (enqueued == 0)
112 return false;
112 return false;
113
113
114
114
115 Array.Copy(batch, offset, m_data, alloc, enqueued);
115 Array.Copy(batch, offset, m_data, alloc, enqueued);
116
116
117 while (alloc != Interlocked.CompareExchange(ref m_hi, alloc + enqueued, alloc)) {
117 while (alloc != Interlocked.CompareExchange(ref m_hi, alloc + enqueued, alloc)) {
118 // spin wait for commit
118 // spin wait for commit
119 }
119 }
120
120
121 return true;
121 return true;
122 }
122 }
123
123
124 public bool TryDequeueBatch(T[] buffer, int offset, int length,out int dequeued, out bool recycle) {
124 public bool TryDequeueBatch(T[] buffer, int offset, int length,out int dequeued, out bool recycle) {
125 int low, hi, batchSize;
125 int low, hi, batchSize;
126
126
127 do {
127 do {
128 low = m_low;
128 low = m_low;
129 hi = m_hi;
129 hi = m_hi;
130 if (low >= hi) {
130 if (low >= hi) {
131 dequeued = 0;
131 dequeued = 0;
132 recycle = (low == m_size); // recycling could be restarted and we need to signal again
132 recycle = (low == m_size); // recycling could be restarted and we need to signal again
133 return false;
133 return false;
134 }
134 }
135 batchSize = Math.Min(hi - low, length);
135 batchSize = Math.Min(hi - low, length);
136 } while(low != Interlocked.CompareExchange(ref m_low, low + batchSize, low));
136 } while(low != Interlocked.CompareExchange(ref m_low, low + batchSize, low));
137
137
138 recycle = (low == m_size - batchSize);
138 recycle = (low == m_size - batchSize);
139 dequeued = batchSize;
139 dequeued = batchSize;
140
140
141 Array.Copy(m_data, low, buffer, offset, batchSize);
141 Array.Copy(m_data, low, buffer, offset, batchSize);
142
142
143 return true;
143 return true;
144 }
144 }
145
145
146 public T GetAt(int pos) {
146 public T GetAt(int pos) {
147 return m_data[pos];
147 return m_data[pos];
148 }
148 }
149 }
149 }
150
150
151 public const int DEFAULT_CHUNK_SIZE = 32;
151 public const int DEFAULT_CHUNK_SIZE = 32;
152 public const int MAX_CHUNK_SIZE = 262144;
152 public const int MAX_CHUNK_SIZE = 262144;
153
153
154 Chunk m_first;
154 Chunk m_first;
155 Chunk m_last;
155 Chunk m_last;
156
156
157 /// <summary>
157 /// <summary>
158 /// Adds the specified value to the queue.
158 /// Adds the specified value to the queue.
159 /// </summary>
159 /// </summary>
160 /// <param name="value">Tha value which will be added to the queue.</param>
160 /// <param name="value">Tha value which will be added to the queue.</param>
161 public virtual void Enqueue(T value) {
161 public virtual void Enqueue(T value) {
162 var last = m_last;
162 var last = m_last;
163 // spin wait to the new chunk
163 // spin wait to the new chunk
164 bool extend = true;
164 bool extend = true;
165 while (last == null || !last.TryEnqueue(value, out extend)) {
165 while (last == null || !last.TryEnqueue(value, out extend)) {
166 // try to extend queue
166 // try to extend queue
167 if (extend || last == null) {
167 if (extend || last == null) {
168 var chunk = new Chunk(DEFAULT_CHUNK_SIZE, value);
168 var chunk = new Chunk(DEFAULT_CHUNK_SIZE, value);
169 if (EnqueueChunk(last, chunk))
169 if (EnqueueChunk(last, chunk))
170 break; // success! exit!
170 break; // success! exit!
171 last = m_last;
171 last = m_last;
172 } else {
172 } else {
173 while (last == m_last) {
173 while (last == m_last) {
174 Thread.MemoryBarrier();
174 Thread.MemoryBarrier();
175 }
175 }
176 last = m_last;
176 last = m_last;
177 }
177 }
178 }
178 }
179 }
179 }
180
180
181 /// <summary>
181 /// <summary>
182 /// Adds the specified data to the queue.
182 /// Adds the specified data to the queue.
183 /// </summary>
183 /// </summary>
184 /// <param name="data">The buffer which contains the data to be enqueued.</param>
184 /// <param name="data">The buffer which contains the data to be enqueued.</param>
185 /// <param name="offset">The offset of the data in the buffer.</param>
185 /// <param name="offset">The offset of the data in the buffer.</param>
186 /// <param name="length">The size of the data to read from the buffer.</param>
186 /// <param name="length">The size of the data to read from the buffer.</param>
187 public virtual void EnqueueRange(T[] data, int offset, int length) {
187 public virtual void EnqueueRange(T[] data, int offset, int length) {
188 if (data == null)
188 if (data == null)
189 throw new ArgumentNullException("data");
189 throw new ArgumentNullException("data");
190 if (length == 0)
190 if (length == 0)
191 return;
191 return;
192 if (offset < 0)
192 if (offset < 0)
193 throw new ArgumentOutOfRangeException("offset");
193 throw new ArgumentOutOfRangeException("offset");
194 if (length < 1 || offset + length > data.Length)
194 if (length < 1 || offset + length > data.Length)
195 throw new ArgumentOutOfRangeException("length");
195 throw new ArgumentOutOfRangeException("length");
196
196
197 var last = m_last;
197 var last = m_last;
198
198
199 bool extend;
199 bool extend;
200 int enqueued;
200 int enqueued;
201
201
202 while (length > 0) {
202 while (length > 0) {
203 extend = true;
203 extend = true;
204 if (last != null && last.TryEnqueueBatch(data, offset, length, out enqueued, out extend)) {
204 if (last != null && last.TryEnqueueBatch(data, offset, length, out enqueued, out extend)) {
205 length -= enqueued;
205 length -= enqueued;
206 offset += enqueued;
206 offset += enqueued;
207 }
207 }
208
208
209 if (extend) {
209 if (extend) {
210 // there was no enough space in the chunk
210 // there was no enough space in the chunk
211 // or there was no chunks in the queue
211 // or there was no chunks in the queue
212
212
213 while (length > 0) {
213 while (length > 0) {
214
214
215 var size = Math.Min(length, MAX_CHUNK_SIZE);
215 var size = Math.Min(length, MAX_CHUNK_SIZE);
216
216
217 var chunk = new Chunk(
217 var chunk = new Chunk(
218 Math.Max(size, DEFAULT_CHUNK_SIZE),
218 Math.Max(size, DEFAULT_CHUNK_SIZE),
219 data,
219 data,
220 offset,
220 offset,
221 size,
221 size,
222 length // length >= size
222 length // length >= size
223 );
223 );
224
224
225 if (!EnqueueChunk(last, chunk)) {
225 if (!EnqueueChunk(last, chunk)) {
226 // looks like the queue has been updated then proceed from the beginning
226 // looks like the queue has been updated then proceed from the beginning
227 last = m_last;
227 last = m_last;
228 break;
228 break;
229 }
229 }
230
230
231 // we have successfully added the new chunk
231 // we have successfully added the new chunk
232 last = chunk;
232 last = chunk;
233 length -= size;
233 length -= size;
234 offset += size;
234 offset += size;
235 }
235 }
236 } else {
236 } else {
237 // we don't need to extend the queue, if we successfully enqueued data
237 // we don't need to extend the queue, if we successfully enqueued data
238 if (length == 0)
238 if (length == 0)
239 break;
239 break;
240
240
241 // if we need to wait while someone is extending the queue
241 // if we need to wait while someone is extending the queue
242 // spinwait
242 // spinwait
243 while (last == m_last) {
243 while (last == m_last) {
244 Thread.MemoryBarrier();
244 Thread.MemoryBarrier();
245 }
245 }
246
246
247 last = m_last;
247 last = m_last;
248 }
248 }
249 }
249 }
250 }
250 }
251
251
252 /// <summary>
252 /// <summary>
253 /// Tries to retrieve the first element from the queue.
253 /// Tries to retrieve the first element from the queue.
254 /// </summary>
254 /// </summary>
255 /// <returns><c>true</c>, if element is dequeued, <c>false</c> otherwise.</returns>
255 /// <returns><c>true</c>, if element is dequeued, <c>false</c> otherwise.</returns>
256 /// <param name="value">The value of the dequeued element.</param>
256 /// <param name="value">The value of the dequeued element.</param>
257 public bool TryDequeue(out T value) {
257 public bool TryDequeue(out T value) {
258 var chunk = m_first;
258 var chunk = m_first;
259 bool recycle;
259 bool recycle;
260 while (chunk != null) {
260 while (chunk != null) {
261
261
262 var result = chunk.TryDequeue(out value, out recycle);
262 var result = chunk.TryDequeue(out value, out recycle);
263
263
264 if (recycle) // this chunk is waste
264 if (recycle) // this chunk is waste
265 RecycleFirstChunk(chunk);
265 RecycleFirstChunk(chunk);
266 else
266 else
267 return result; // this chunk is usable and returned actual result
267 return result; // this chunk is usable and returned actual result
268
268
269 if (result) // this chunk is waste but the true result is always actual
269 if (result) // this chunk is waste but the true result is always actual
270 return true;
270 return true;
271
271
272 // try again
272 // try again
273 chunk = m_first;
273 chunk = m_first;
274 }
274 }
275
275
276 // the queue is empty
276 // the queue is empty
277 value = default(T);
277 value = default(T);
278 return false;
278 return false;
279 }
279 }
280
280
281 /// <summary>
281 /// <summary>
282 /// Tries to dequeue the specified amount of data from the queue.
282 /// Tries to dequeue the specified amount of data from the queue.
283 /// </summary>
283 /// </summary>
284 /// <returns><c>true</c>, if data was deuqueued, <c>false</c> otherwise.</returns>
284 /// <returns><c>true</c>, if data was deuqueued, <c>false</c> otherwise.</returns>
285 /// <param name="buffer">The buffer to which the data will be written.</param>
285 /// <param name="buffer">The buffer to which the data will be written.</param>
286 /// <param name="offset">The offset in the buffer at which the data will be written.</param>
286 /// <param name="offset">The offset in the buffer at which the data will be written.</param>
287 /// <param name="length">The maximum amount of data to be retrieved.</param>
287 /// <param name="length">The maximum amount of data to be retrieved.</param>
288 /// <param name="dequeued">The actual amout of the retrieved data.</param>
288 /// <param name="dequeued">The actual amout of the retrieved data.</param>
289 public bool TryDequeueRange(T[] buffer, int offset, int length, out int dequeued) {
289 public bool TryDequeueRange(T[] buffer, int offset, int length, out int dequeued) {
290 if (buffer == null)
290 if (buffer == null)
291 throw new ArgumentNullException("buffer");
291 throw new ArgumentNullException("buffer");
292 if (offset < 0)
292 if (offset < 0)
293 throw new ArgumentOutOfRangeException("offset");
293 throw new ArgumentOutOfRangeException("offset");
294 if (length < 1 || offset + length > buffer.Length)
294 if (length < 1 || offset + length > buffer.Length)
295 throw new ArgumentOutOfRangeException("length");
295 throw new ArgumentOutOfRangeException("length");
296
296
297 var chunk = m_first;
297 var chunk = m_first;
298 bool recycle;
298 bool recycle;
299 dequeued = 0;
299 dequeued = 0;
300 while (chunk != null) {
300 while (chunk != null) {
301
301
302 int actual;
302 int actual;
303 if (chunk.TryDequeueBatch(buffer, offset, length, out actual, out recycle)) {
303 if (chunk.TryDequeueBatch(buffer, offset, length, out actual, out recycle)) {
304 offset += actual;
304 offset += actual;
305 length -= actual;
305 length -= actual;
306 dequeued += actual;
306 dequeued += actual;
307 }
307 }
308
308
309 if (recycle) // this chunk is waste
309 if (recycle) // this chunk is waste
310 RecycleFirstChunk(chunk);
310 RecycleFirstChunk(chunk);
311 else if (actual == 0)
311 else if (actual == 0)
312 break; // the chunk is usable, but doesn't contain any data (it's the last chunk in the queue)
312 break; // the chunk is usable, but doesn't contain any data (it's the last chunk in the queue)
313
313
314 if (length == 0)
314 if (length == 0)
315 return true;
315 return true;
316
316
317 // we still may dequeue something
317 // we still may dequeue something
318 // try again
318 // try again
319 chunk = m_first;
319 chunk = m_first;
320 }
320 }
321
321
322 return dequeued != 0;
322 return dequeued != 0;
323 }
323 }
324
324
325 /// <summary>
325 /// <summary>
326 /// Tries to dequeue all remaining data in the first chunk.
326 /// Tries to dequeue all remaining data in the first chunk.
327 /// </summary>
327 /// </summary>
328 /// <returns><c>true</c>, if data was dequeued, <c>false</c> otherwise.</returns>
328 /// <returns><c>true</c>, if data was dequeued, <c>false</c> otherwise.</returns>
329 /// <param name="buffer">The buffer to which the data will be written.</param>
329 /// <param name="buffer">The buffer to which the data will be written.</param>
330 /// <param name="offset">The offset in the buffer at which the data will be written.</param>
330 /// <param name="offset">The offset in the buffer at which the data will be written.</param>
331 /// <param name="length">Tha maximum amount of the data to be dequeued.</param>
331 /// <param name="length">Tha maximum amount of the data to be dequeued.</param>
332 /// <param name="dequeued">The actual amount of the dequeued data.</param>
332 /// <param name="dequeued">The actual amount of the dequeued data.</param>
333 public bool TryDequeueChunk(T[] buffer, int offset, int length, out int dequeued) {
333 public bool TryDequeueChunk(T[] buffer, int offset, int length, out int dequeued) {
334 if (buffer == null)
334 if (buffer == null)
335 throw new ArgumentNullException("buffer");
335 throw new ArgumentNullException("buffer");
336 if (offset < 0)
336 if (offset < 0)
337 throw new ArgumentOutOfRangeException("offset");
337 throw new ArgumentOutOfRangeException("offset");
338 if (length < 1 || offset + length > buffer.Length)
338 if (length < 1 || offset + length > buffer.Length)
339 throw new ArgumentOutOfRangeException("length");
339 throw new ArgumentOutOfRangeException("length");
340
340
341 var chunk = m_first;
341 var chunk = m_first;
342 bool recycle;
342 bool recycle;
343 dequeued = 0;
343 dequeued = 0;
344
344
345 while (chunk != null) {
345 while (chunk != null) {
346
346
347 int actual;
347 int actual;
348 if (chunk.TryDequeueBatch(buffer, offset, length, out actual, out recycle)) {
348 if (chunk.TryDequeueBatch(buffer, offset, length, out actual, out recycle)) {
349 dequeued = actual;
349 dequeued = actual;
350 }
350 }
351
351
352 if (recycle) // this chunk is waste
352 if (recycle) // this chunk is waste
353 RecycleFirstChunk(chunk);
353 RecycleFirstChunk(chunk);
354
354
355 // if we have dequeued any data, then return
355 // if we have dequeued any data, then return
356 if (dequeued != 0)
356 if (dequeued != 0)
357 return true;
357 return true;
358
358
359 // we still may dequeue something
359 // we still may dequeue something
360 // try again
360 // try again
361 chunk = m_first;
361 chunk = m_first;
362 }
362 }
363
363
364 return false;
364 return false;
365 }
365 }
366
366
367 bool EnqueueChunk(Chunk last, Chunk chunk) {
367 bool EnqueueChunk(Chunk last, Chunk chunk) {
368 if (Interlocked.CompareExchange(ref m_last, chunk, last) != last)
368 if (Interlocked.CompareExchange(ref m_last, chunk, last) != last)
369 return false;
369 return false;
370
370
371 if (last != null)
371 if (last != null)
372 last.next = chunk;
372 last.next = chunk;
373 else {
373 else {
374 m_first = chunk;
374 m_first = chunk;
375 }
375 }
376 return true;
376 return true;
377 }
377 }
378
378
379 void RecycleFirstChunk(Chunk first) {
379 void RecycleFirstChunk(Chunk first) {
380 var next = first.next;
380 var next = first.next;
381
381
382 if (first != Interlocked.CompareExchange(ref m_first, next, first))
382 if (first != Interlocked.CompareExchange(ref m_first, next, first))
383 return;
383 return;
384
384
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
393 m_first = first;
391 m_first = first;
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() {
406 // start the new queue
398 // start the new queue
407 var chunk = new Chunk(DEFAULT_CHUNK_SIZE);
399 var chunk = new Chunk(DEFAULT_CHUNK_SIZE);
408
400
409 do {
401 do {
410 Thread.MemoryBarrier();
402 Thread.MemoryBarrier();
411 var first = m_first;
403 var first = m_first;
412 var last = m_last;
404 var last = m_last;
413
405
414 if (last == null) // nothing to clear
406 if (last == null) // nothing to clear
415 return;
407 return;
416
408
417 if (first == null || (first.next == null && first != last)) // inconcistency
409 if (first == null || (first.next == null && first != last)) // inconcistency
418 continue;
410 continue;
419
411
420 // here we will create inconsistency which will force others to spin
412 // here we will create inconsistency which will force others to spin
421 // and prevent from fetching. chunk.next = null
413 // and prevent from fetching. chunk.next = null
422 if (first != Interlocked.CompareExchange(ref m_first, chunk, first))
414 if (first != Interlocked.CompareExchange(ref m_first, chunk, first))
423 continue;// inconsistent
415 continue;// inconsistent
424
416
425 m_last = chunk;
417 m_last = chunk;
426
418
427 return;
419 return;
428
420
429 } while(true);
421 } while(true);
430 }
422 }
431
423
432 public T[] Drain() {
424 public T[] Drain() {
433 // start the new queue
425 // start the new queue
434 var chunk = new Chunk(DEFAULT_CHUNK_SIZE);
426 var chunk = new Chunk(DEFAULT_CHUNK_SIZE);
435
427
436 do {
428 do {
437 Thread.MemoryBarrier();
429 Thread.MemoryBarrier();
438 var first = m_first;
430 var first = m_first;
439 var last = m_last;
431 var last = m_last;
440
432
441 if (last == null)
433 if (last == null)
442 return new T[0];
434 return new T[0];
443
435
444 if (first == null || (first.next == null && first != last))
436 if (first == null || (first.next == null && first != last))
445 continue;
437 continue;
446
438
447 // here we will create inconsistency which will force others to spin
439 // here we will create inconsistency which will force others to spin
448 // and prevent from fetching. chunk.next = null
440 // and prevent from fetching. chunk.next = null
449 if (first != Interlocked.CompareExchange(ref m_first, chunk, first))
441 if (first != Interlocked.CompareExchange(ref m_first, chunk, first))
450 continue;// inconsistent
442 continue;// inconsistent
451
443
452 last = Interlocked.Exchange(ref m_last, chunk);
444 last = Interlocked.Exchange(ref m_last, chunk);
453
445
454 return ReadChunks(first, last);
446 return ReadChunks(first, last);
455
447
456 } while(true);
448 } while(true);
457 }
449 }
458
450
459 static T[] ReadChunks(Chunk chunk, object last) {
451 static T[] ReadChunks(Chunk chunk, object last) {
460 var result = new List<T>();
452 var result = new List<T>();
461 var buffer = new T[DEFAULT_CHUNK_SIZE];
453 var buffer = new T[DEFAULT_CHUNK_SIZE];
462 int actual;
454 int actual;
463 bool recycle;
455 bool recycle;
464 while (chunk != null) {
456 while (chunk != null) {
465 // ensure all write operations on the chunk are complete
457 // ensure all write operations on the chunk are complete
466 chunk.Commit();
458 chunk.Commit();
467
459
468 // we need to read the chunk using this way
460 // we need to read the chunk using this way
469 // since some client still may completing the dequeue
461 // since some client still may completing the dequeue
470 // operation, such clients most likely won't get results
462 // operation, such clients most likely won't get results
471 while (chunk.TryDequeueBatch(buffer, 0, buffer.Length, out actual, out recycle))
463 while (chunk.TryDequeueBatch(buffer, 0, buffer.Length, out actual, out recycle))
472 result.AddRange(new ArraySegmentCollection(buffer, 0, actual));
464 result.AddRange(new ArraySegmentCollection(buffer, 0, actual));
473
465
474 if (chunk == last) {
466 if (chunk == last) {
475 chunk = null;
467 chunk = null;
476 } else {
468 } else {
477 while (chunk.next == null)
469 while (chunk.next == null)
478 Thread.MemoryBarrier();
470 Thread.MemoryBarrier();
479 chunk = chunk.next;
471 chunk = chunk.next;
480 }
472 }
481 }
473 }
482
474
483 return result.ToArray();
475 return result.ToArray();
484 }
476 }
485
477
486 struct ArraySegmentCollection : ICollection<T> {
478 struct ArraySegmentCollection : ICollection<T> {
487 readonly T[] m_data;
479 readonly T[] m_data;
488 readonly int m_offset;
480 readonly int m_offset;
489 readonly int m_length;
481 readonly int m_length;
490
482
491 public ArraySegmentCollection(T[] data, int offset, int length) {
483 public ArraySegmentCollection(T[] data, int offset, int length) {
492 m_data = data;
484 m_data = data;
493 m_offset = offset;
485 m_offset = offset;
494 m_length = length;
486 m_length = length;
495 }
487 }
496
488
497 #region ICollection implementation
489 #region ICollection implementation
498
490
499 public void Add(T item) {
491 public void Add(T item) {
500 throw new NotSupportedException();
492 throw new NotSupportedException();
501 }
493 }
502
494
503 public void Clear() {
495 public void Clear() {
504 throw new NotSupportedException();
496 throw new NotSupportedException();
505 }
497 }
506
498
507 public bool Contains(T item) {
499 public bool Contains(T item) {
508 return false;
500 return false;
509 }
501 }
510
502
511 public void CopyTo(T[] array, int arrayIndex) {
503 public void CopyTo(T[] array, int arrayIndex) {
512 Array.Copy(m_data,m_offset,array,arrayIndex, m_length);
504 Array.Copy(m_data,m_offset,array,arrayIndex, m_length);
513 }
505 }
514
506
515 public bool Remove(T item) {
507 public bool Remove(T item) {
516 throw new NotSupportedException();
508 throw new NotSupportedException();
517 }
509 }
518
510
519 public int Count {
511 public int Count {
520 get {
512 get {
521 return m_length;
513 return m_length;
522 }
514 }
523 }
515 }
524
516
525 public bool IsReadOnly {
517 public bool IsReadOnly {
526 get {
518 get {
527 return true;
519 return true;
528 }
520 }
529 }
521 }
530
522
531 #endregion
523 #endregion
532
524
533 #region IEnumerable implementation
525 #region IEnumerable implementation
534
526
535 public IEnumerator<T> GetEnumerator() {
527 public IEnumerator<T> GetEnumerator() {
536 for (int i = m_offset; i < m_length + m_offset; i++)
528 for (int i = m_offset; i < m_length + m_offset; i++)
537 yield return m_data[i];
529 yield return m_data[i];
538 }
530 }
539
531
540 #endregion
532 #endregion
541
533
542 #region IEnumerable implementation
534 #region IEnumerable implementation
543
535
544 IEnumerator IEnumerable.GetEnumerator() {
536 IEnumerator IEnumerable.GetEnumerator() {
545 return GetEnumerator();
537 return GetEnumerator();
546 }
538 }
547
539
548 #endregion
540 #endregion
549 }
541 }
550
542
551 #region IEnumerable implementation
543 #region IEnumerable implementation
552
544
553 class Enumerator : IEnumerator<T> {
545 class Enumerator : IEnumerator<T> {
554 Chunk m_current;
546 Chunk m_current;
555 int m_pos = -1;
547 int m_pos = -1;
556
548
557 public Enumerator(Chunk fisrt) {
549 public Enumerator(Chunk fisrt) {
558 m_current = fisrt;
550 m_current = fisrt;
559 }
551 }
560
552
561 #region IEnumerator implementation
553 #region IEnumerator implementation
562
554
563 public bool MoveNext() {
555 public bool MoveNext() {
564 if (m_current == null)
556 if (m_current == null)
565 return false;
557 return false;
566
558
567 if (m_pos == -1)
559 if (m_pos == -1)
568 m_pos = m_current.Low;
560 m_pos = m_current.Low;
569 else
561 else
570 m_pos++;
562 m_pos++;
571
563
572 if (m_pos == m_current.Hi) {
564 if (m_pos == m_current.Hi) {
573
565
574 m_current = m_pos == m_current.Size ? m_current.next : null;
566 m_current = m_pos == m_current.Size ? m_current.next : null;
575
567
576 m_pos = 0;
568 m_pos = 0;
577
569
578 if (m_current == null)
570 if (m_current == null)
579 return false;
571 return false;
580 }
572 }
581
573
582 return true;
574 return true;
583 }
575 }
584
576
585 public void Reset() {
577 public void Reset() {
586 throw new NotSupportedException();
578 throw new NotSupportedException();
587 }
579 }
588
580
589 object IEnumerator.Current {
581 object IEnumerator.Current {
590 get {
582 get {
591 return Current;
583 return Current;
592 }
584 }
593 }
585 }
594
586
595 #endregion
587 #endregion
596
588
597 #region IDisposable implementation
589 #region IDisposable implementation
598
590
599 public void Dispose() {
591 public void Dispose() {
600 }
592 }
601
593
602 #endregion
594 #endregion
603
595
604 #region IEnumerator implementation
596 #region IEnumerator implementation
605
597
606 public T Current {
598 public T Current {
607 get {
599 get {
608 if (m_pos == -1 || m_current == null)
600 if (m_pos == -1 || m_current == null)
609 throw new InvalidOperationException();
601 throw new InvalidOperationException();
610 return m_current.GetAt(m_pos);
602 return m_current.GetAt(m_pos);
611 }
603 }
612 }
604 }
613
605
614 #endregion
606 #endregion
615 }
607 }
616
608
617 public IEnumerator<T> GetEnumerator() {
609 public IEnumerator<T> GetEnumerator() {
618 return new Enumerator(m_first);
610 return new Enumerator(m_first);
619 }
611 }
620
612
621 #endregion
613 #endregion
622
614
623 #region IEnumerable implementation
615 #region IEnumerable implementation
624
616
625 IEnumerator IEnumerable.GetEnumerator() {
617 IEnumerator IEnumerable.GetEnumerator() {
626 return GetEnumerator();
618 return GetEnumerator();
627 }
619 }
628
620
629 #endregion
621 #endregion
630 }
622 }
631 }
623 }
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