##// END OF EJS Templates
Reworked cancelation handling, if the cancel handler isn't specified the OperationCanceledException will be handled by the error handler...
Reworked cancelation handling, if the cancel handler isn't specified the OperationCanceledException will be handled by the error handler Any unhandled OperationCanceledException will cause the promise cancelation

File last commit:

r180:c32688129f14 ref20160224
r187:dd4a3590f9c6 ref20160224
Show More
JSONXmlReader.cs
335 lines | 11.7 KiB | text/x-csharp | CSharpLexer
cin
JSON moved to Formats namespace...
r163 using Implab;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Xml;
cin
refactoring complete, JSONParser rewritten
r180 namespace Implab.Formats.JSON {
cin
JSON moved to Formats namespace...
r163 public class JSONXmlReader : XmlReader {
enum ValueContext {
Undefined,
ElementStart,
ElementValue,
ElementEnd,
ElementEmpty
}
struct LocalNameContext {
public string localName;
public bool isArray;
}
JSONParser m_parser;
ValueContext m_valueContext;
ReadState m_state = ReadState.Initial;
Stack<LocalNameContext> m_localNameStack = new Stack<LocalNameContext>();
LocalNameContext m_localName;
cin
refactoring complete, JSONParser rewritten
r180 int m_depthCorrection;
cin
JSON moved to Formats namespace...
r163
readonly string m_rootName;
readonly string m_prefix;
readonly string m_namespaceUri;
readonly bool m_flattenArrays;
readonly string m_arrayItemName;
readonly XmlNameTable m_nameTable;
JSONXmlReader(JSONParser parser, JSONXmlReaderOptions options) {
m_parser = parser;
if (options != null) {
m_prefix = options.NodesPrefix ?? String.Empty;
m_namespaceUri = options.NamespaceURI ?? String.Empty;
m_rootName = options.RootName ?? "json";
m_flattenArrays = options.FlattenArrays;
m_arrayItemName = options.ArrayItemName ?? "item";
m_nameTable = options.NameTable ?? new NameTable();
} else {
m_prefix = String.Empty;
m_namespaceUri = String.Empty;
m_rootName = "json";
m_flattenArrays = false;
m_arrayItemName = "item";
m_nameTable = new NameTable();
}
}
/// <summary>
/// Always 0, JSON doesn't support attributes
/// </summary>
public override int AttributeCount {
get { return 0; }
}
public override string BaseURI {
get { return String.Empty; }
}
public override int Depth {
get {
return m_localNameStack.Count + m_depthCorrection;
}
}
public override bool EOF {
get { return m_parser.EOF; }
}
/// <summary>
/// Always throws an exception
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
public override string GetAttribute(int i) {
throw new ArgumentOutOfRangeException();
}
/// <summary>
/// Always returns empty string
/// </summary>
/// <param name="name"></param>
/// <param name="namespaceURI"></param>
/// <returns></returns>
public override string GetAttribute(string name, string namespaceURI) {
return String.Empty;
}
/// <summary>
/// Always returns empty string
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public override string GetAttribute(string name) {
return String.Empty;
}
public override bool IsEmptyElement {
get { return m_parser.ElementType == JSONElementType.Value && m_valueContext == ValueContext.ElementEmpty; }
}
public override string LocalName {
get { return m_localName.localName; }
}
public override string LookupNamespace(string prefix) {
if (String.IsNullOrEmpty(prefix) || prefix == m_prefix)
return m_namespaceUri;
cin
refactoring complete, JSONParser rewritten
r180
return String.Empty;
cin
JSON moved to Formats namespace...
r163 }
public override bool MoveToAttribute(string name, string ns) {
return false;
}
public override bool MoveToAttribute(string name) {
return false;
}
public override bool MoveToElement() {
return false;
}
public override bool MoveToFirstAttribute() {
return false;
}
public override bool MoveToNextAttribute() {
return false;
}
public override XmlNameTable NameTable {
get { return m_nameTable; }
}
public override string NamespaceURI {
get { return m_namespaceUri; }
}
public override XmlNodeType NodeType {
get {
switch (m_parser.ElementType) {
case JSONElementType.BeginObject:
case JSONElementType.BeginArray:
return XmlNodeType.Element;
case JSONElementType.EndObject:
case JSONElementType.EndArray:
return XmlNodeType.EndElement;
case JSONElementType.Value:
switch (m_valueContext) {
case ValueContext.ElementStart:
case ValueContext.ElementEmpty:
return XmlNodeType.Element;
case ValueContext.ElementValue:
return XmlNodeType.Text;
case ValueContext.ElementEnd:
return XmlNodeType.EndElement;
default:
throw new InvalidOperationException();
}
default:
throw new InvalidOperationException();
}
}
}
public override string Prefix {
get { return m_prefix; }
}
public override bool Read() {
cin
refactoring complete, JSONParser rewritten
r180 if (m_state != ReadState.Interactive && m_state != ReadState.Initial)
cin
JSON moved to Formats namespace...
r163 return false;
if (m_state == ReadState.Initial)
cin
refactoring complete, JSONParser rewritten
r180 m_state = ReadState.Interactive;
cin
JSON moved to Formats namespace...
r163
try {
switch (m_parser.ElementType) {
case JSONElementType.Value:
switch (m_valueContext) {
case ValueContext.ElementStart:
SetLocalName(String.Empty);
m_valueContext = ValueContext.ElementValue;
return true;
case ValueContext.ElementValue:
RestoreLocalName();
m_valueContext = ValueContext.ElementEnd;
return true;
case ValueContext.ElementEmpty:
case ValueContext.ElementEnd:
RestoreLocalName();
break;
}
break;
case JSONElementType.EndArray:
case JSONElementType.EndObject:
RestoreLocalName();
break;
}
string itemName = m_parser.ElementType == JSONElementType.None ? m_rootName : m_flattenArrays ? m_localName.localName : m_arrayItemName;
while (m_parser.Read()) {
if (!String.IsNullOrEmpty(m_parser.ElementName))
itemName = m_parser.ElementName;
switch (m_parser.ElementType) {
case JSONElementType.BeginArray:
if (m_flattenArrays && !m_localName.isArray) {
m_depthCorrection--;
SetLocalName(itemName, true);
continue;
}
cin
refactoring complete, JSONParser rewritten
r180 SetLocalName(itemName, true);
cin
JSON moved to Formats namespace...
r163 break;
case JSONElementType.BeginObject:
SetLocalName(itemName);
break;
case JSONElementType.EndArray:
if (m_flattenArrays && !m_localNameStack.Peek().isArray) {
RestoreLocalName();
m_depthCorrection++;
continue;
}
break;
case JSONElementType.EndObject:
break;
case JSONElementType.Value:
SetLocalName(itemName);
m_valueContext = m_parser.ElementValue == null ? ValueContext.ElementEmpty : ValueContext.ElementStart;
break;
}
return true;
}
cin
refactoring complete, JSONParser rewritten
r180 m_state = ReadState.EndOfFile;
cin
JSON moved to Formats namespace...
r163 return false;
} catch {
cin
refactoring complete, JSONParser rewritten
r180 m_state = ReadState.Error;
cin
JSON moved to Formats namespace...
r163 throw;
}
}
public override bool ReadAttributeValue() {
return false;
}
public override ReadState ReadState {
get { return m_state; }
}
public override void ResolveEntity() {
// do nothing
}
public override string Value {
get {
if (m_parser.ElementValue == null)
return String.Empty;
if (Convert.GetTypeCode(m_parser.ElementValue) == TypeCode.Double)
return ((double)m_parser.ElementValue).ToString(CultureInfo.InvariantCulture);
cin
refactoring complete, JSONParser rewritten
r180 return m_parser.ElementValue.ToString();
cin
JSON moved to Formats namespace...
r163 }
}
void SetLocalName(string name) {
m_localNameStack.Push(m_localName);
m_localName.localName = name;
m_localName.isArray = false;
}
void SetLocalName(string name, bool isArray) {
m_localNameStack.Push(m_localName);
m_localName.localName = name;
m_localName.isArray = isArray;
}
void RestoreLocalName() {
m_localName = m_localNameStack.Pop();
}
public override void Close() {
}
protected override void Dispose(bool disposing) {
#if MONO
disposing = true;
#endif
if (disposing) {
m_parser.Dispose();
}
base.Dispose(disposing);
}
public static JSONXmlReader Create(string file, JSONXmlReaderOptions options) {
return Create(File.OpenText(file), options);
}
/// <summary>
/// Creates the XmlReader for the specified text stream with JSON data.
/// </summary>
/// <param name="reader">Text reader.</param>
/// <param name="options">Options.</param>
/// <remarks>
/// The reader will be disposed when the XmlReader is disposed.
/// </remarks>
public static JSONXmlReader Create(TextReader reader, JSONXmlReaderOptions options) {
cin
refactoring complete, JSONParser rewritten
r180 return new JSONXmlReader(new JSONParser(reader), options);
cin
JSON moved to Formats namespace...
r163 }
/// <summary>
/// Creates the XmlReader for the specified stream with JSON data.
/// </summary>
/// <param name="stream">Stream.</param>
/// <param name="options">Options.</param>
/// <remarks>
/// The stream will be disposed when the XmlReader is disposed.
/// </remarks>
public static JSONXmlReader Create(Stream stream, JSONXmlReaderOptions options) {
Safe.ArgumentNotNull(stream, "stream");
// HACK don't dispose StreaReader to keep stream opened
return Create(new StreamReader(stream), options);
}
}
}