0
|
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 } |