Created
July 31, 2012 04:32
-
-
Save rpgmaker/3213638 to your computer and use it in GitHub Desktop.
XmlReaderEx (Working 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; | |
private StringBuilder sb; | |
const int DefaultSBCapacity = 30; | |
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; | |
var current = *_chrs; | |
sb.Clear().Append(current); | |
do { | |
current = *(++_chrs); | |
if (current == LessStr || current == Null) break; | |
sb.Append(current); | |
} while (true); | |
return sb.ToString(); | |
} | |
public bool Read(){ | |
if (*_chrs == Null) return false; | |
_attributeTypeValue = null; | |
_isEndElement = false; | |
sb.Clear(); | |
char current = Null; | |
bool hasValue = false, hasTypeAttribute = false; | |
string elementName = null; | |
do { | |
current = *(++_chrs); | |
if (current == GreaterStr || current == Null) { | |
if (current != Null) ++_chrs; | |
break; | |
} | |
if (current == SpaceStr && elementName == null) { | |
elementName = sb.ToString(); | |
sb.Clear(); | |
hasTypeAttribute = true; | |
hasValue = false; | |
continue; | |
} | |
if (current != LessStr) { | |
sb.Append(current); | |
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); | |
} | |
} | |
_elementName = elementName; | |
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