Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/XmlGenerator.cs @ 1570

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

Streamline XML generation with StringBuilders (#548)

File size: 6.2 KB
Line 
1using System.Collections.Generic;
2using System;
3using System.Text;
4using HeuristicLab.Persistence.Interfaces;
5using HeuristicLab.Persistence.Core;
6using System.IO;
7using ICSharpCode.SharpZipLib.Zip;
8using HeuristicLab.Tracing;
9using log4net;
10using HeuristicLab.Persistence.Core.Tokens;
11
12namespace HeuristicLab.Persistence.Default.Xml {
13
14  struct XmlStrings {
15    public const string PRIMITIVE = "PRIMITVE";
16    public const string COMPOSITE = "COMPOSITE";
17    public const string REFERENCE = "REFERENCE";
18    public const string NULL = "NULL";
19    public const string TYPECACHE = "TYPECACHE";
20    public const string TYPE = "TYPE";
21    public const string METAINFO = "METAINFO";
22  }
23
24  public class XmlGenerator : GeneratorBase<string> {
25
26    private int depth;
27    private int Depth {
28      get {
29        return depth;
30      }
31      set {
32        depth = value;
33        prefix = new string(' ', depth * 2);
34      }
35    }
36
37    private string prefix;
38
39
40    public XmlGenerator() {
41      Depth = 0;
42    }
43
44    private enum NodeType { Start, End, Inline } ;
45
46    private static void AddXmlTagContent(StringBuilder sb, string name, Dictionary<string, object> attributes) {
47      sb.Append(name);
48      foreach (var attribute in attributes) {
49        if (attribute.Value != null && !string.IsNullOrEmpty(attribute.Value.ToString())) {
50          sb.Append(' ');
51          sb.Append(attribute.Key);
52          sb.Append("=\"");
53          sb.Append(attribute.Value);
54          sb.Append('"');
55        }
56      }
57    }
58
59    private static void AddXmlStartTag(StringBuilder sb, string name, Dictionary<string, object> attributes) {
60      sb.Append('<');
61      AddXmlTagContent(sb, name, attributes);
62      sb.Append('>');
63    }
64
65    private static void AddXmlInlineTag(StringBuilder sb, string name, Dictionary<string, object> attributes) {
66      sb.Append('<');
67      AddXmlTagContent(sb, name, attributes);
68      sb.Append("/>");
69    }
70
71    private static void AddXmlEndTag(StringBuilder sb, string name) {
72      sb.Append("</");
73      sb.Append(name);
74      sb.Append(">");
75    }
76
77    private string CreateNodeStart(string name, Dictionary<string, object> attributes) {
78      StringBuilder sb = new StringBuilder();
79      sb.Append(prefix);
80      Depth += 1;
81      AddXmlStartTag(sb, name, attributes);
82      sb.Append("\r\n");
83      return sb.ToString();
84    }
85
86    private string CreateNodeStart(string name) {
87      return CreateNodeStart(name, new Dictionary<string, object>());
88    }
89
90    private string CreateNodeEnd(string name) {
91      Depth -= 1;
92      StringBuilder sb = new StringBuilder();
93      sb.Append(prefix);
94      AddXmlEndTag(sb, name);
95      sb.Append("\r\n");
96      return sb.ToString();
97    }
98
99    private string CreateNode(string name, Dictionary<string, object> attributes) {
100      StringBuilder sb = new StringBuilder();
101      sb.Append(prefix);
102      AddXmlInlineTag(sb, name, attributes);
103      sb.Append("\r\n");
104      return sb.ToString();
105    }
106
107    private string CreateNode(string name, Dictionary<string, object> attributes, string content) {
108      StringBuilder sb = new StringBuilder();
109      sb.Append(prefix);
110      AddXmlStartTag(sb, name, attributes);
111      sb.Append(content);
112      sb.Append("</").Append(name).Append(">\r\n");
113      return sb.ToString();
114    }
115
116    protected override string Format(BeginToken beginToken) {
117      return CreateNodeStart(
118        XmlStrings.COMPOSITE,
119        new Dictionary<string, object> {
120          {"name", beginToken.Name},
121          {"typeId", beginToken.TypeId},
122          {"id", beginToken.Id}});
123    }
124
125    protected override string Format(EndToken endToken) {
126      return CreateNodeEnd(XmlStrings.COMPOSITE);
127    }
128
129    protected override string Format(PrimitiveToken dataToken) {
130      return CreateNode(XmlStrings.PRIMITIVE,
131        new Dictionary<string, object> {
132            {"typeId", dataToken.TypeId},
133            {"name", dataToken.Name},
134            {"id", dataToken.Id}},
135        ((XmlString)dataToken.SerialData).Data);
136    }
137
138    protected override string Format(ReferenceToken refToken) {
139      return CreateNode(XmlStrings.REFERENCE,
140        new Dictionary<string, object> {
141          {"ref", refToken.Id},
142          {"name", refToken.Name}});
143    }
144
145    protected override string Format(NullReferenceToken nullRefToken) {
146      return CreateNode(XmlStrings.NULL,
147        new Dictionary<string, object>{
148          {"name", nullRefToken.Name}});
149    }
150
151    protected override string Format(MetaInfoBeginToken metaInfoBeginToken) {
152      return CreateNodeStart(XmlStrings.METAINFO);
153    }
154
155    protected override string Format(MetaInfoEndToken metaInfoEndToken) {
156      return CreateNodeEnd(XmlStrings.METAINFO);
157    }
158
159    public IEnumerable<string> Format(List<TypeMapping> typeCache) {
160      yield return CreateNodeStart(XmlStrings.TYPECACHE);
161      foreach (var mapping in typeCache)
162        yield return CreateNode(
163          XmlStrings.TYPE,
164          mapping.GetDict());
165      yield return CreateNodeEnd(XmlStrings.TYPECACHE);
166    }
167
168    public static void Serialize(object o, string filename) {
169      Serialize(o, filename, ConfigurationService.Instance.GetDefaultConfig(new XmlFormat()));
170    }
171
172    public static void Serialize(object obj, string filename, Configuration config) {
173      Serializer serializer = new Serializer(obj, config);
174      XmlGenerator generator = new XmlGenerator();
175      ZipOutputStream zipStream = new ZipOutputStream(File.Create(filename));
176      zipStream.SetLevel(9);
177      zipStream.PutNextEntry(new ZipEntry("data.xml"));
178      StreamWriter writer = new StreamWriter(zipStream);
179      ILog logger = Logger.GetDefaultLogger();
180      foreach (ISerializationToken token in serializer) {
181        string line = generator.Format(token);
182        writer.Write(line);
183        logger.Debug(line.TrimEnd());
184      }
185      writer.Flush();
186      zipStream.PutNextEntry(new ZipEntry("typecache.xml"));
187      writer = new StreamWriter(zipStream);
188      foreach (string line in generator.Format(serializer.TypeCache)) {
189        writer.WriteLine(line);
190        logger.Debug(line.TrimEnd());
191      }
192      writer.Flush();
193      zipStream.Close();
194    }
195
196  }
197}
Note: See TracBrowser for help on using the repository browser.