Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/XmlParser.cs @ 1553

Last change on this file since 1553 was 1553, checked in by epitzer, 15 years ago

Replace final fixes for broken parent references with separation of instance creation with meta information. (#548)

File size: 4.6 KB
Line 
1using System.Xml;
2using System.Collections.Generic;
3using System;
4using System.Collections;
5using System.IO;
6using HeuristicLab.Persistence.Core;
7using HeuristicLab.Persistence.Interfaces;
8using ICSharpCode.SharpZipLib.Zip;
9using HeuristicLab.Persistence.Interfaces.Tokens;
10
11namespace HeuristicLab.Persistence.Default.Xml {
12
13  public class XmlParser : IEnumerable<ISerializationToken> {
14
15    private readonly XmlReader reader;
16    private delegate IEnumerator<ISerializationToken> Handler();
17    private readonly Dictionary<string, Handler> handlers;
18
19    public XmlParser(TextReader input) {
20      XmlReaderSettings settings = new XmlReaderSettings {
21                                       ConformanceLevel = ConformanceLevel.Document,
22                                       IgnoreWhitespace = true,
23                                       IgnoreComments = true
24                                     };
25      reader = XmlReader.Create(input, settings);
26      handlers = new Dictionary<string, Handler> {
27                     {XmlStrings.PRIMITIVE, ParsePrimitive},
28                     {XmlStrings.COMPOSITE, ParseComposite},
29                     {XmlStrings.REFERENCE, ParseReference},
30                     {XmlStrings.NULL, ParseNull},
31                     {XmlStrings.METAINFO, ParseMetaInfo},
32                   };
33    }
34
35    public IEnumerator<ISerializationToken> GetEnumerator() {
36      while (reader.Read()) {
37        if (!reader.IsStartElement()) {
38          break;
39        }
40        IEnumerator<ISerializationToken> iterator;
41        try {
42          iterator = handlers[reader.Name].Invoke();
43        }
44        catch (KeyNotFoundException) {
45          throw new InvalidOperationException(String.Format(
46            "No handler for XML tag \"{0}\" installed",
47            reader.Name));
48        }
49        while (iterator.MoveNext()) {
50          yield return iterator.Current;
51        }
52      }
53    }
54
55    private IEnumerator<ISerializationToken> ParsePrimitive() {
56      int? id = null;
57      string idString = reader.GetAttribute("id");
58      if (idString != null)
59        id = int.Parse(idString);
60      yield return new PrimitiveToken(
61        reader.GetAttribute("name"),
62        int.Parse(reader.GetAttribute("typeId")),
63        id,
64        reader.ReadString());       
65    }
66
67    private IEnumerator<ISerializationToken> ParseComposite() {
68      string name = reader.GetAttribute("name");           
69      string idString = reader.GetAttribute("id");
70      int? id = null;
71      int? typeId = null;
72      if (idString != null)
73        id = int.Parse(idString);
74        typeId = int.Parse(reader.GetAttribute("typeId"));
75      yield return new BeginToken(name, typeId, id);
76      IEnumerator<ISerializationToken> iterator = GetEnumerator();
77      while (iterator.MoveNext())
78        yield return iterator.Current;
79      yield return new EndToken(name, typeId, id);
80    }
81
82    private IEnumerator<ISerializationToken> ParseReference() {
83      yield return new ReferenceToken(
84        reader.GetAttribute("name"),
85        int.Parse(reader.GetAttribute("ref")));
86    }
87
88    private IEnumerator<ISerializationToken> ParseNull() {
89      yield return new NullReferenceToken(reader.GetAttribute("name"));
90    }
91
92    private IEnumerator<ISerializationToken> ParseMetaInfo() {
93      yield return new MetaInfoBeginToken();
94      IEnumerator<ISerializationToken> iterator = GetEnumerator();
95      while (iterator.MoveNext())
96        yield return iterator.Current;
97      yield return new MetaInfoEndToken();
98    }
99
100    IEnumerator IEnumerable.GetEnumerator() {
101      return GetEnumerator();
102    }
103
104    public static List<TypeMapping> ParseTypeCache(TextReader reader) {
105      var typeCache = new List<TypeMapping>();
106      XmlReader xmlReader = XmlReader.Create(reader);
107      while ( xmlReader.Read() ) {
108        if (xmlReader.Name == XmlStrings.TYPE) {
109          typeCache.Add(new TypeMapping(
110            int.Parse(xmlReader.GetAttribute("id")),
111            xmlReader.GetAttribute("typeName"),
112            xmlReader.GetAttribute("serializer")));
113        }
114      }
115      return typeCache;
116    }
117
118    public static object DeSerialize(string filename) {
119      ZipFile zipFile = new ZipFile(filename);     
120      Deserializer deSerializer = new Deserializer(
121        ParseTypeCache(
122        new StreamReader(
123          zipFile.GetInputStream(zipFile.GetEntry("typecache.xml")))));
124      XmlParser parser = new XmlParser(
125        new StreamReader(zipFile.GetInputStream(zipFile.GetEntry("data.xml"))));
126      return deSerializer.Deserialize(parser);     
127    }
128  } 
129}
Note: See TracBrowser for help on using the repository browser.