Mercurial > hg > ucis.core
comparison Pml/RW/PmlXmlRW.cs @ 0:3ab940a0c7a0
Initial commit
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Tue, 11 Sep 2012 16:28:53 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:3ab940a0c7a0 |
---|---|
1 using System; | |
2 using System.Collections.Generic; | |
3 using System.Text; | |
4 using System.Xml; | |
5 using System.IO; | |
6 using UCIS.Pml; | |
7 | |
8 namespace UCIS.Pml { | |
9 public class PmlXmlRW : IPmlRW { | |
10 private PmlXmlReader pReader; | |
11 private PmlXmlWriter pWriter; | |
12 | |
13 public PmlXmlRW(Stream Stream) { | |
14 pReader = new PmlXmlReader(Stream); | |
15 pWriter = new PmlXmlWriter(Stream); | |
16 } | |
17 public PmlXmlRW(Stream Stream, Encoding Encoding) { | |
18 pReader = new PmlXmlReader(Stream); | |
19 pWriter = new PmlXmlWriter(Stream, Encoding); | |
20 } | |
21 | |
22 public PmlElement ReadMessage() { | |
23 return pReader.ReadMessage(); | |
24 } | |
25 | |
26 public void WriteMessage(PmlElement Message) { | |
27 pWriter.WriteMessage(Message); | |
28 } | |
29 } | |
30 | |
31 public class PmlXmlWriter : IPmlWriter { | |
32 private Stream pStream; | |
33 private XmlWriterSettings pXMLConfig; | |
34 | |
35 public PmlXmlWriter(Stream Stream, Encoding Encoding) { | |
36 pXMLConfig = CreateXMLSettings(Encoding); | |
37 | |
38 pStream = Stream; | |
39 } | |
40 public PmlXmlWriter(Stream Stream) | |
41 : this(Stream, Encoding.UTF8) { | |
42 } | |
43 | |
44 private static XmlWriterSettings CreateXMLSettings() { | |
45 return CreateXMLSettings(null); | |
46 } | |
47 private static XmlWriterSettings CreateXMLSettings(Encoding Encoding) { | |
48 XmlWriterSettings XMLConfig = new XmlWriterSettings(); | |
49 if (Encoding == null) Encoding = Encoding.UTF8; | |
50 XMLConfig.ConformanceLevel = ConformanceLevel.Document; | |
51 XMLConfig.NewLineHandling = NewLineHandling.Entitize; | |
52 XMLConfig.OmitXmlDeclaration = true; | |
53 XMLConfig.CheckCharacters = true; | |
54 XMLConfig.Encoding = Encoding; | |
55 XMLConfig.CloseOutput = false; | |
56 return XMLConfig; | |
57 } | |
58 | |
59 public void WriteMessage(PmlElement Message) { | |
60 WriteMessageToStream(Message, pStream); | |
61 pStream.WriteByte(0); | |
62 pStream.Flush(); | |
63 } | |
64 | |
65 public static void WriteMessageToFile(PmlElement Message, string Filename) { | |
66 FileStream F = File.Create(Filename); | |
67 WriteMessageToStream(Message, F); | |
68 F.Close(); | |
69 } | |
70 | |
71 public static void WriteMessageToStream(PmlElement Message, Stream Stream) { | |
72 WriteMessageToStream(Message, Stream, CreateXMLSettings()); | |
73 } | |
74 | |
75 public static void WriteMessageToStream(PmlElement Message, Stream Stream, XmlWriterSettings Settings) { | |
76 XmlWriter Writer = System.Xml.XmlWriter.Create(Stream, Settings); | |
77 Writer.WriteStartDocument(); | |
78 Writer.WriteStartElement("msg"); | |
79 WriteElementTo(Message, Writer); | |
80 Writer.WriteEndElement(); | |
81 Writer.WriteEndDocument(); | |
82 Writer.Flush(); | |
83 Writer.Close(); | |
84 } | |
85 | |
86 private static void WriteElementTo(PmlElement Element, System.Xml.XmlWriter Writer) { | |
87 switch (Element.Type) { | |
88 case PmlType.Binary: | |
89 Writer.WriteAttributeString("type", "binary"); | |
90 byte[] Bytes = Element.ToByteArray(); | |
91 Writer.WriteBase64(Bytes, 0, Bytes.Length); | |
92 break; | |
93 case PmlType.Collection: | |
94 Writer.WriteAttributeString("type", "collection"); | |
95 foreach (PmlElement Child in (PmlCollection)Element) { | |
96 Writer.WriteStartElement("item"); | |
97 WriteElementTo(Child, Writer); | |
98 Writer.WriteEndElement(); | |
99 } | |
100 | |
101 break; | |
102 case PmlType.Dictionary: | |
103 Writer.WriteAttributeString("type", "dictionary"); | |
104 foreach (KeyValuePair<string, PmlElement> Child in (PmlDictionary)Element) { | |
105 Writer.WriteStartElement(Child.Key); | |
106 WriteElementTo(Child.Value, Writer); | |
107 Writer.WriteEndElement(); | |
108 } | |
109 | |
110 break; | |
111 case PmlType.Integer: | |
112 Writer.WriteAttributeString("type", "integer"); | |
113 Writer.WriteString(Element.ToString()); | |
114 break; | |
115 case PmlType.Null: | |
116 Writer.WriteAttributeString("type", "null"); | |
117 break; | |
118 case PmlType.String: | |
119 Writer.WriteAttributeString("type", "string"); | |
120 Writer.WriteString(Element.ToString()); | |
121 break; | |
122 } | |
123 } | |
124 } | |
125 | |
126 public class PmlXmlReader : IPmlReader { | |
127 private BinaryReader pReader; | |
128 private System.Xml.XmlReaderSettings pXMLSettings; | |
129 | |
130 public PmlXmlReader(Stream Stream) | |
131 : this(new BinaryReader(Stream)) { | |
132 } | |
133 | |
134 public PmlXmlReader(BinaryReader Reader) { | |
135 pReader = Reader; | |
136 pXMLSettings = new System.Xml.XmlReaderSettings(); | |
137 pXMLSettings.ConformanceLevel = System.Xml.ConformanceLevel.Document; | |
138 pXMLSettings.CloseInput = true; | |
139 pXMLSettings.IgnoreComments = true; | |
140 pXMLSettings.IgnoreProcessingInstructions = true; | |
141 pXMLSettings.IgnoreWhitespace = true; | |
142 pXMLSettings.ValidationType = System.Xml.ValidationType.None; | |
143 pXMLSettings.ValidationFlags = System.Xml.Schema.XmlSchemaValidationFlags.None; | |
144 pXMLSettings.CheckCharacters = true; | |
145 } | |
146 | |
147 public BinaryReader BaseReader { | |
148 get { return pReader; } | |
149 set { pReader = value; } | |
150 } | |
151 | |
152 private XmlDocument ReadXMLDocument() { | |
153 System.Xml.XmlDocument Doc = new System.Xml.XmlDocument(); | |
154 MemoryStream Buffer = default(MemoryStream); | |
155 System.Xml.XmlReader XMLReader = default(System.Xml.XmlReader); | |
156 byte B = 0; | |
157 Buffer = new MemoryStream(); | |
158 do { | |
159 B = pReader.ReadByte(); | |
160 if (B == 0) break; | |
161 Buffer.WriteByte(B); | |
162 } | |
163 while (true); | |
164 Buffer.Flush(); | |
165 Buffer.Seek(0, SeekOrigin.Begin); | |
166 | |
167 XMLReader = System.Xml.XmlReader.Create(Buffer, pXMLSettings); | |
168 Doc.Load(XMLReader); | |
169 XMLReader.Close(); | |
170 return Doc; | |
171 } | |
172 | |
173 public PmlElement ReadMessage() { | |
174 System.Xml.XmlDocument Doc = default(System.Xml.XmlDocument); | |
175 Doc = ReadXMLDocument(); | |
176 if (Doc == null) return null; | |
177 return ReadElement(Doc.FirstChild); | |
178 } | |
179 | |
180 public static PmlElement ReadElement(System.Xml.XmlNode X) { | |
181 PmlType pType; | |
182 bool pTypeFound = false; | |
183 pType = PmlType.Null; | |
184 pTypeFound = true; | |
185 if (X.Attributes != null && X.Attributes.Count > 0 && X.Attributes["type"] != null) { | |
186 switch (X.Attributes["type"].Value.ToLowerInvariant()) { | |
187 case "binary": | |
188 pType = PmlType.Binary; | |
189 break; | |
190 case "collection": | |
191 pType = PmlType.Collection; | |
192 break; | |
193 case "dictionary": | |
194 pType = PmlType.Dictionary; | |
195 break; | |
196 case "string": | |
197 pType = PmlType.String; | |
198 break; | |
199 case "null": | |
200 pType = PmlType.Null; | |
201 break; | |
202 case "integer": | |
203 pType = PmlType.Integer; | |
204 break; | |
205 default: | |
206 pTypeFound = false; | |
207 break; | |
208 } | |
209 } else { | |
210 pTypeFound = false; | |
211 } | |
212 | |
213 if (!pTypeFound) { | |
214 if (X.HasChildNodes) { | |
215 if (X.ChildNodes.Count == 1 && X.FirstChild.NodeType == System.Xml.XmlNodeType.Text) { | |
216 Int64 dummy; | |
217 UInt64 dummyu; | |
218 if (Int64.TryParse(X.FirstChild.Value, out dummy) || UInt64.TryParse(X.FirstChild.Value, out dummyu)) { | |
219 pType = PmlType.Integer; | |
220 } else { | |
221 pType = PmlType.String; | |
222 } | |
223 } else if (X.FirstChild.Name == "item") { | |
224 pType = PmlType.Collection; | |
225 } else { | |
226 pType = PmlType.Dictionary; | |
227 } | |
228 } else { | |
229 pType = PmlType.Null; | |
230 } | |
231 } | |
232 | |
233 switch (pType) { | |
234 case PmlType.Null: | |
235 return new PmlNull(); | |
236 case PmlType.Binary: | |
237 if (X.FirstChild == null) { | |
238 return new PmlBinary(new byte[0]); | |
239 } else { | |
240 return new PmlBinary(Convert.FromBase64String(X.FirstChild.Value)); | |
241 } | |
242 case PmlType.Integer: | |
243 return new PmlInteger(X.FirstChild.Value); | |
244 case PmlType.String: | |
245 if (X.FirstChild == null) { | |
246 return new PmlString(""); | |
247 } else { | |
248 return new PmlString(X.FirstChild.Value); | |
249 } | |
250 case PmlType.Collection: | |
251 PmlCollection C = new PmlCollection(); | |
252 foreach (XmlNode N in X.ChildNodes) { | |
253 C.Add(ReadElement(N)); | |
254 } | |
255 | |
256 return C; | |
257 case PmlType.Dictionary: | |
258 PmlDictionary D = new PmlDictionary(); | |
259 foreach (XmlNode N in X.ChildNodes) { | |
260 D.Add(N.Name, ReadElement(N)); | |
261 } | |
262 | |
263 return D; | |
264 default: | |
265 return null; | |
266 } | |
267 } | |
268 } | |
269 } |