[1280] | 1 | using System.Xml;
|
---|
| 2 | using System.Collections.Generic;
|
---|
| 3 | using System;
|
---|
| 4 | using System.Collections;
|
---|
| 5 | using System.IO;
|
---|
| 6 |
|
---|
| 7 | namespace Persistence {
|
---|
| 8 | public class XmlParser : IEnumerable<IParseToken> {
|
---|
| 9 |
|
---|
[1330] | 10 | private readonly XmlReader reader;
|
---|
[1280] | 11 | private delegate IEnumerator<IParseToken> Handler();
|
---|
[1330] | 12 | private readonly Dictionary<string, Handler> handlers;
|
---|
[1280] | 13 |
|
---|
[1330] | 14 | public XmlParser(TextReader input) {
|
---|
| 15 | XmlReaderSettings settings = new XmlReaderSettings {
|
---|
| 16 | ConformanceLevel = ConformanceLevel.Document,
|
---|
| 17 | IgnoreWhitespace = true,
|
---|
| 18 | IgnoreComments = true
|
---|
| 19 | };
|
---|
| 20 | reader = XmlReader.Create(input, settings);
|
---|
| 21 | handlers = new Dictionary<string, Handler> {
|
---|
| 22 | {"PRIMITIVE", ParsePrimitive},
|
---|
| 23 | {"COMPOSITE", ParseComposite},
|
---|
| 24 | {"REFERENCE", ParseReference},
|
---|
| 25 | {"NULL", ParseNull}
|
---|
| 26 | };
|
---|
[1280] | 27 | }
|
---|
| 28 | public IEnumerator<IParseToken> GetEnumerator() {
|
---|
[1330] | 29 | while (reader.Read()) {
|
---|
[1280] | 30 | if (!reader.IsStartElement()) {
|
---|
| 31 | break;
|
---|
| 32 | }
|
---|
| 33 | IEnumerator<IParseToken> iterator;
|
---|
| 34 | try {
|
---|
| 35 | iterator = handlers[reader.Name].Invoke();
|
---|
| 36 | }
|
---|
| 37 | catch (KeyNotFoundException) {
|
---|
| 38 | throw new InvalidOperationException(String.Format(
|
---|
| 39 | "No handler for XML tag \"{0}\" installed",
|
---|
| 40 | reader.Name));
|
---|
| 41 | }
|
---|
| 42 | while (iterator.MoveNext()) {
|
---|
| 43 | yield return iterator.Current;
|
---|
| 44 | }
|
---|
| 45 | }
|
---|
| 46 | }
|
---|
| 47 | private IEnumerator<IParseToken> ParsePrimitive() {
|
---|
[1330] | 48 | int? id = null;
|
---|
| 49 | string idString = reader.GetAttribute("id");
|
---|
| 50 | if (idString != null)
|
---|
| 51 | id = int.Parse(idString);
|
---|
[1280] | 52 | yield return new Primitive(
|
---|
[1330] | 53 | reader.GetAttribute("name"),
|
---|
| 54 | Type.GetType(reader.GetAttribute("type")),
|
---|
| 55 | reader.ReadString(),
|
---|
| 56 | id);
|
---|
[1280] | 57 | }
|
---|
| 58 | private IEnumerator<IParseToken> ParseComposite() {
|
---|
[1338] | 59 | string name = reader.GetAttribute("name");
|
---|
[1330] | 60 | Type type = Type.GetType(reader.GetAttribute("type"));
|
---|
| 61 | int id = int.Parse(reader.GetAttribute("id"));
|
---|
[1280] | 62 | yield return new CompositeStart(name, type, id);
|
---|
[1330] | 63 | IEnumerator<IParseToken> iterator = GetEnumerator();
|
---|
[1280] | 64 | while (iterator.MoveNext())
|
---|
| 65 | yield return iterator.Current;
|
---|
| 66 | yield return new CompositeEnd(name, type, id);
|
---|
| 67 | }
|
---|
| 68 | private IEnumerator<IParseToken> ParseReference() {
|
---|
| 69 | yield return new Reference(
|
---|
[1330] | 70 | reader.GetAttribute("name"),
|
---|
| 71 | int.Parse(reader.GetAttribute("ref")));
|
---|
[1280] | 72 | }
|
---|
| 73 | private IEnumerator<IParseToken> ParseNull() {
|
---|
[1330] | 74 | yield return new Null(reader.GetAttribute("name"));
|
---|
[1280] | 75 | }
|
---|
| 76 | IEnumerator IEnumerable.GetEnumerator() {
|
---|
[1330] | 77 | return GetEnumerator();
|
---|
[1280] | 78 | }
|
---|
| 79 | }
|
---|
| 80 | }
|
---|