Created
July 30, 2012 05:56
-
-
Save rpgmaker/3205192 to your computer and use it in GitHub Desktop.
XmlReaderEx (Initial Draft)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Runtime.InteropServices; | |
using System.Text.RegularExpressions; | |
namespace PServiceBus.Serializer.Xml { | |
public unsafe class XmlReaderEx : IDisposable { | |
private char* _chrs; | |
private string _elementName, _attributeTypeValue; | |
private bool _disposed, _isEndElement, _hasValue, _hasTypeAttribute; | |
private StringBuilder sb; | |
const int DefaultSBCapacity = 1024 << 1; | |
const string TypeStr = "Type"; | |
const char SpaceStr = ' ', GreaterStr = '>', LessStr = '<', BackSlash = '/', Null = '\0'; | |
private static Regex _typeRegex = new Regex(@"type=""(?<Type>[^""]+)""", RegexOptions.Compiled); | |
public XmlReaderEx(string xml) { | |
_chrs = (char*)Marshal.StringToHGlobalUni(xml); | |
sb = new StringBuilder(DefaultSBCapacity); | |
} | |
public string ElementName { get { return _elementName; } } | |
public string TypeAttribute { get { return _attributeTypeValue; } } | |
public bool IsEndElement { get { return _isEndElement; } } | |
public string GetValue() { | |
if (_isEndElement) return string.Empty; | |
sb.Clear().Append(*_chrs); | |
do { | |
++_chrs; | |
if (*_chrs == Null || *_chrs == LessStr) break; | |
sb.Append(*_chrs); | |
} while (true); | |
return sb.ToString(); | |
} | |
public bool Read(){ | |
if (*_chrs == Null) return false; | |
_elementName = _attributeTypeValue = null; | |
_hasTypeAttribute = _hasValue = _isEndElement = false; | |
sb.Clear(); | |
do { | |
++_chrs; | |
if (*_chrs == GreaterStr || *_chrs == Null) { | |
if (*_chrs != Null) ++_chrs; | |
break; | |
} | |
if (*_chrs == SpaceStr && _elementName == null) { | |
_elementName = sb.ToString(); | |
sb.Clear(); | |
_hasTypeAttribute = true; | |
_hasValue = false; | |
continue; | |
} | |
if (*_chrs != LessStr) { | |
sb.Append(*_chrs); | |
_hasValue = true; | |
} | |
} while (true); | |
if (_hasValue) { | |
var text = sb.ToString(); | |
if (_hasTypeAttribute) | |
_attributeTypeValue = _typeRegex.Match(text).Groups[TypeStr].Value; | |
else if (_elementName == null) | |
_elementName = text; | |
if (_elementName[0] == BackSlash) { | |
_isEndElement = true; | |
_elementName = _elementName.Substring(1); | |
} | |
} | |
return _hasValue; | |
} | |
public void MoveToEndElement(string name) { | |
do { | |
if (_elementName == name && _isEndElement) break; | |
} while (Read()); | |
} | |
protected void Dispose(bool disposing) { | |
if (_disposed) return; | |
if (disposing) | |
GC.SuppressFinalize(this); | |
_chrs = default(char*); | |
_disposed = true; | |
} | |
#region IDisposable Members | |
public void Dispose() { | |
Dispose(true); | |
} | |
#endregion | |
~XmlReaderEx() { | |
Dispose(false); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment