Free cookie consent management tool by TermsFeed Policy Generator

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

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

Stronger typing for formatters with the help of generics. Separate format and serial data type. (#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.Core.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        new XmlString(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      if (idString != null)
72        id = int.Parse(idString);
73      int typeId = int.Parse(reader.GetAttribute("typeId"));
74      yield return new BeginToken(name, typeId, id);
75      IEnumerator<ISerializationToken> iterator = GetEnumerator();
76      while (iterator.MoveNext())
77        yield return iterator.Current;
78      yield return new EndToken(name, typeId, id);
79    }
80
81    private IEnumerator<ISerializationToken> ParseReference() {
82      yield return new ReferenceToken(
83        reader.GetAttribute("name"),
84        int.Parse(reader.GetAttribute("ref")));
85    }
86
87    private IEnumerator<ISerializationToken> ParseNull() {
88      yield return new NullReferenceToken(reader.GetAttribute("name"));
89    }
90
91    private IEnumerator<ISerializationToken> ParseMetaInfo() {
92      yield return new MetaInfoBeginToken();
93      IEnumerator<ISerializationToken> iterator = GetEnumerator();
94      while (iterator.MoveNext())
95        yield return iterator.Current;
96      yield return new MetaInfoEndToken();
97    }
98
99    IEnumerator IEnumerable.GetEnumerator() {
100      return GetEnumerator();
101    }
102
103    public static List<TypeMapping> ParseTypeCache(TextReader reader) {
104      var typeCache = new List<TypeMapping>();
105      XmlReader xmlReader = XmlReader.Create(reader);
106      while ( xmlReader.Read() ) {
107        if (xmlReader.Name == XmlStrings.TYPE) {
108          typeCache.Add(new TypeMapping(
109            int.Parse(xmlReader.GetAttribute("id")),
110            xmlReader.GetAttribute("typeName"),
111            xmlReader.GetAttribute("serializer")));
112        }
113      }
114      return typeCache;
115    }
116
117    public static object DeSerialize(string filename) {
118      ZipFile zipFile = new ZipFile(filename);     
119      Deserializer deSerializer = new Deserializer(
120        ParseTypeCache(
121        new StreamReader(
122          zipFile.GetInputStream(zipFile.GetEntry("typecache.xml")))));
123      XmlParser parser = new XmlParser(
124        new StreamReader(zipFile.GetInputStream(zipFile.GetEntry("data.xml"))));
125      return deSerializer.Deserialize(parser);     
126    }
127  } 
128}
Note: See TracBrowser for help on using the repository browser.