Mercurial > hg > ucis.core
comparison Pml/RW/PmlPHPRW.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.IO; | |
5 | |
6 namespace UCIS.Pml { | |
7 public class PmlPHPWriter : IPmlWriter { | |
8 private TextWriter pWriter; | |
9 | |
10 public static string GetMessageString(PmlElement Message) { | |
11 StringWriter Buffer = new StringWriter(); | |
12 WriteMessageTo(Message, Buffer); | |
13 return Buffer.ToString(); | |
14 } | |
15 | |
16 public PmlPHPWriter(TextWriter Writer) { | |
17 pWriter = Writer; | |
18 } | |
19 public PmlPHPWriter(Stream Writer, Encoding Encoding) { | |
20 pWriter = new StreamWriter(Writer, Encoding); | |
21 } | |
22 public PmlPHPWriter(StringBuilder StringBuilder) { | |
23 pWriter = new StringWriter(StringBuilder); | |
24 } | |
25 | |
26 public TextWriter BaseWriter { | |
27 get { return pWriter; } | |
28 set { pWriter = value; } | |
29 } | |
30 | |
31 public void WriteMessage(PmlElement Message) { | |
32 WriteMessageTo(Message, pWriter); | |
33 } | |
34 | |
35 public static void WriteMessageTo(PmlElement Message, TextWriter Writer) { | |
36 lock (Writer) { | |
37 WriteElementTo(Message, Writer); | |
38 Writer.Flush(); | |
39 } | |
40 } | |
41 | |
42 private static void WriteElementTo(PmlElement Element, TextWriter Writer) { | |
43 string Str; | |
44 if (Element == null) { | |
45 Writer.Write("N;"); | |
46 return; | |
47 } | |
48 switch (Element.Type) { | |
49 case PmlType.Null: | |
50 Writer.Write("N;"); | |
51 break; | |
52 case PmlType.String: | |
53 case PmlType.Binary: | |
54 Str = Element.ToString(); | |
55 Writer.Write("s:"); | |
56 Writer.Write(Encoding.UTF8.GetByteCount(Str).ToString()); | |
57 Writer.Write(":\""); | |
58 Writer.Write(Str); | |
59 Writer.Write("\";"); | |
60 break; | |
61 case PmlType.Integer: | |
62 Writer.Write("i:"); | |
63 Writer.Write(Element.ToString()); | |
64 Writer.Write(";"); | |
65 break; | |
66 case PmlType.Dictionary: | |
67 Writer.Write("a:"); | |
68 Writer.Write(((IDictionary<string, PmlElement>)Element).Count.ToString()); | |
69 Writer.Write(":{"); | |
70 foreach (KeyValuePair<string, PmlElement> Child in (IDictionary<string, PmlElement>)Element) { | |
71 Str = Child.Key; | |
72 Writer.Write("s:"); | |
73 Writer.Write(Encoding.UTF8.GetByteCount(Str).ToString()); | |
74 Writer.Write(":\""); | |
75 Writer.Write(Str); | |
76 Writer.Write("\";"); | |
77 WriteElementTo(Child.Value, Writer); | |
78 } | |
79 | |
80 Writer.Write("}"); | |
81 break; | |
82 case PmlType.Collection: | |
83 int I = 0; | |
84 Writer.Write("a:"); | |
85 Writer.Write(((ICollection<PmlElement>)Element).Count.ToString()); | |
86 Writer.Write(":{"); | |
87 foreach (PmlElement Child in (ICollection<PmlElement>)Element) { | |
88 Writer.Write("i:"); | |
89 Writer.Write(I.ToString()); | |
90 Writer.Write(";"); | |
91 WriteElementTo(Child, Writer); | |
92 I += 1; | |
93 } | |
94 | |
95 Writer.Write("}"); | |
96 break; | |
97 default: | |
98 Writer.Write("N;"); | |
99 break; | |
100 } | |
101 } | |
102 } | |
103 public class PmlPHPReader : IPmlReader { | |
104 private TextReader pReader; | |
105 | |
106 public static PmlElement GetMessageFromString(string Data) { | |
107 StringReader Buffer = new StringReader(Data); | |
108 return ReadMessageFrom(Buffer); | |
109 } | |
110 | |
111 public PmlPHPReader(TextReader Reader) { | |
112 pReader = Reader; | |
113 } | |
114 public PmlPHPReader(Stream Reader, Encoding Encoding) { | |
115 pReader = new StreamReader(Reader, Encoding); | |
116 } | |
117 public PmlPHPReader(string Data) { | |
118 pReader = new StringReader(Data); | |
119 } | |
120 | |
121 public TextReader BaseReader { | |
122 get { return pReader; } | |
123 set { pReader = value; } | |
124 } | |
125 | |
126 public PmlElement ReadMessage() { | |
127 return ReadMessageFrom(pReader); | |
128 } | |
129 | |
130 public static PmlElement ReadMessageFrom(TextReader Reader) { | |
131 lock (Reader) { | |
132 return ReadElementFrom(Reader); | |
133 } | |
134 } | |
135 | |
136 public class PhpSerializerException : Exception { | |
137 | |
138 public PhpSerializerException(int Position, char Read, char Expected) | |
139 : base("At position " + Position.ToString() + " expected " + Expected + " but got " + Read) { | |
140 } | |
141 } | |
142 | |
143 private static char ReadChar(TextReader Reader) { | |
144 char[] Buffer = new char[1]; | |
145 if (Reader.Read(Buffer, 0, 1) != 1) throw new EndOfStreamException(); | |
146 return Buffer[0]; | |
147 } | |
148 | |
149 private static string ReadNumber(TextReader Reader, char TerminatedBy) { | |
150 char Buffer = '\0'; | |
151 string S = ""; | |
152 do { | |
153 Buffer = ReadChar(Reader); | |
154 if (Buffer == TerminatedBy) break; | |
155 if (Buffer < '0' && Buffer > '9' && Buffer != '.' && Buffer != ',' && Buffer != '-' && Buffer != 'e') | |
156 throw new PhpSerializerException(0, Buffer, TerminatedBy); | |
157 S += Buffer; | |
158 } | |
159 while (true); | |
160 return S; | |
161 } | |
162 | |
163 private static void ReadExpect(TextReader Reader, char Expect) { | |
164 char Read = '\0'; | |
165 Read = ReadChar(Reader); | |
166 if (Read != Expect) throw new PhpSerializerException(0, Read, Expect); | |
167 } | |
168 | |
169 private static PmlElement ReadElementFrom(TextReader Reader) { | |
170 char Type = '\0'; | |
171 char Read = '\0'; | |
172 int KL; | |
173 Type = ReadChar(Reader); | |
174 switch (Type) { | |
175 case 'N': | |
176 ReadExpect(Reader, ';'); | |
177 return new PmlNull(); | |
178 case 'i': | |
179 ReadExpect(Reader, ':'); | |
180 return new PmlInteger(ReadNumber(Reader, ';')); | |
181 case 'd': | |
182 ReadExpect(Reader, ':'); | |
183 return new PmlString(ReadNumber(Reader, ';')); | |
184 //Return New PML.PMLNumber(ReadNumber(Reader, ";"c)) | |
185 case 's': | |
186 KL = 0; | |
187 char[] Buffer = null; | |
188 ReadExpect(Reader, ':'); | |
189 KL = int.Parse(ReadNumber(Reader, ':')); | |
190 Buffer = new Char[KL]; | |
191 ReadExpect(Reader, '"'); | |
192 Reader.ReadBlock(Buffer, 0, KL); | |
193 ReadExpect(Reader, '"'); | |
194 ReadExpect(Reader, ';'); | |
195 return new PmlString(new String(Buffer)); | |
196 case 'a': | |
197 PmlDictionary D = new PmlDictionary(); | |
198 int I = 0; | |
199 int L = 0; | |
200 KL = 0; | |
201 char[] K = null; | |
202 ReadExpect(Reader, ':'); | |
203 L = int.Parse(ReadNumber(Reader, ':')); | |
204 ReadExpect(Reader, '{'); | |
205 for (I = 1; I <= L; I++) { | |
206 Read = ReadChar(Reader); | |
207 switch (Read) { | |
208 case 'i': | |
209 ReadExpect(Reader, ':'); | |
210 K = ReadNumber(Reader, ';').ToCharArray(); | |
211 break; | |
212 case 's': | |
213 ReadExpect(Reader, ':'); | |
214 KL = int.Parse(ReadNumber(Reader, ':')); | |
215 K = new char[KL]; | |
216 ReadExpect(Reader, '"'); | |
217 Reader.ReadBlock(K, 0, KL); | |
218 ReadExpect(Reader, '"'); | |
219 ReadExpect(Reader, ';'); | |
220 break; | |
221 case 'd': | |
222 ReadExpect(Reader, ':'); | |
223 K = ReadNumber(Reader, ';').ToCharArray(); | |
224 break; | |
225 default: | |
226 throw new NotSupportedException("Only integer and string keys are supported, got: " + Read); | |
227 } | |
228 D.Add(new String(K), ReadElementFrom(Reader)); | |
229 } | |
230 | |
231 ReadExpect(Reader, '}'); | |
232 return D; | |
233 default: | |
234 throw new NotSupportedException("Unknown type: " + Type); | |
235 } | |
236 } | |
237 } | |
238 } |