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 }