0
|
1 ???using System; |
|
2 using System.IO; |
|
3 using System.Text; |
|
4 using System.Collections.Generic; |
|
5 |
|
6 namespace UCIS.Pml { |
|
7 public class PmlBinaryRW : IPmlRW { |
|
8 private PmlBinaryReader pReader; |
|
9 private PmlBinaryWriter pWriter; |
|
10 |
|
11 public PmlBinaryRW(Stream Stream) { |
|
12 pReader = new PmlBinaryReader(Stream); |
|
13 pWriter = new PmlBinaryWriter(Stream); |
|
14 } |
|
15 public PmlBinaryRW(Stream Stream, Encoding Encoding) { |
|
16 pReader = new PmlBinaryReader(Stream, Encoding); |
|
17 pWriter = new PmlBinaryWriter(Stream, Encoding); |
|
18 } |
|
19 |
|
20 public PmlElement ReadMessage() { |
|
21 return pReader.ReadMessage(); |
|
22 } |
|
23 |
|
24 public void WriteMessage(PmlElement Message) { |
|
25 pWriter.WriteMessage(Message); |
|
26 } |
|
27 |
|
28 public PmlBinaryReader Reader { |
|
29 get { return pReader; } |
|
30 } |
|
31 public PmlBinaryWriter Writer { |
|
32 get { return pWriter; } |
|
33 } |
|
34 } |
|
35 |
|
36 public class PmlBinaryWriter : IPmlWriter { |
|
37 //private BinaryWriter pWriter; |
|
38 private Stream pStream; |
|
39 private Encoding pEncoding; |
|
40 |
|
41 /*public PmlBinaryWriter(BinaryWriter Writer) { |
|
42 pWriter = Writer; |
|
43 }*/ |
|
44 public PmlBinaryWriter(Stream Stream) { |
|
45 //pWriter = new BinaryWriter(Stream); |
|
46 pStream = Stream; |
|
47 pEncoding = Encoding.UTF8; |
|
48 } |
|
49 public PmlBinaryWriter(Stream Stream, Encoding Encoding) { |
|
50 //pWriter = new BinaryWriter(Stream, Encoding); |
|
51 pStream = Stream; |
|
52 pEncoding = Encoding; |
|
53 } |
|
54 |
|
55 /*public BinaryWriter BaseWriter { |
|
56 get { return pWriter; } |
|
57 set { pWriter = value; } |
|
58 }*/ |
|
59 |
|
60 public void WriteMessage(PmlElement Message) { |
|
61 MemoryStream stream = new MemoryStream(); |
|
62 BinaryWriter writer = new BinaryWriter(stream, pEncoding); |
|
63 WriteMessageTo(Message, writer); |
|
64 lock (pStream) { |
|
65 stream.WriteTo(pStream); |
|
66 pStream.Flush(); |
|
67 } |
|
68 } |
|
69 |
|
70 public static void WriteMessageTo(PmlElement Message, BinaryWriter Writer) { |
|
71 lock (Writer) { |
|
72 Writer.Write((byte)255); |
|
73 WriteElementTo(Message, Writer); |
|
74 Writer.Write((byte)255); |
|
75 Writer.Flush(); |
|
76 } |
|
77 } |
|
78 |
|
79 private static void WriteElementTo(PmlElement Element, BinaryWriter Writer) { |
|
80 //byte[] Buffer = null; |
|
81 if (Element == null) { |
|
82 //Writer.Write((byte)PmlElementType.Null); |
|
83 Writer.Write((byte)0); |
|
84 return; |
|
85 } |
|
86 //Writer.Write((byte)Element.Type); |
|
87 switch (Element.Type) { |
|
88 case PmlType.Null: |
|
89 Writer.Write((byte)0); |
|
90 break; |
|
91 case PmlType.Dictionary: |
|
92 Writer.Write((byte)1); |
|
93 foreach (KeyValuePair<string, PmlElement> Item in (PmlDictionary)Element) { |
|
94 Writer.Write((byte)1); |
|
95 Writer.Write(Item.Key); |
|
96 WriteElementTo(Item.Value, Writer); |
|
97 } |
|
98 Writer.Write((byte)0); |
|
99 break; |
|
100 case PmlType.Collection: |
|
101 Writer.Write((byte)2); |
|
102 foreach (PmlElement Item in (PmlCollection)Element) { |
|
103 Writer.Write((byte)1); |
|
104 WriteElementTo(Item, Writer); |
|
105 } |
|
106 Writer.Write((byte)0); |
|
107 break; |
|
108 case PmlType.Binary: { |
|
109 Writer.Write((byte)10); |
|
110 Byte[] Buffer = Element.ToByteArray(); |
|
111 if (Buffer == null) { |
|
112 Writer.Write((int)0); |
|
113 } else { |
|
114 Writer.Write((int)Buffer.Length); |
|
115 Writer.Write(Buffer); |
|
116 } |
|
117 } break; |
|
118 case PmlType.String: |
|
119 Writer.Write((byte)11); |
|
120 string Str = Element.ToString(); |
|
121 if (Str == null) { |
|
122 Writer.Write(""); |
|
123 } else { |
|
124 Writer.Write(Str); |
|
125 } |
|
126 |
|
127 break; |
|
128 case PmlType.Integer: |
|
129 Writer.Write((byte)20); |
|
130 PmlInteger RMInt = (PmlInteger)Element; |
|
131 if (RMInt.IsSigned) { |
|
132 Writer.Write((byte)1); |
|
133 Writer.Write((long)RMInt); |
|
134 } else { |
|
135 Writer.Write((byte)0); |
|
136 Writer.Write((ulong)RMInt); |
|
137 } |
|
138 break; |
|
139 default: |
|
140 Writer.Write((byte)0); |
|
141 Console.WriteLine("PmlBinaryRW: Can not encode PML type {0}", Element.Type); |
|
142 break; |
|
143 } |
|
144 } |
|
145 } |
|
146 |
|
147 public class PmlBinaryReader : IPmlReader { |
|
148 private BinaryReader pReader; |
|
149 |
|
150 public PmlBinaryReader(BinaryReader Reader) { |
|
151 pReader = Reader; |
|
152 } |
|
153 public PmlBinaryReader(Stream Stream) { |
|
154 pReader = new BinaryReader(Stream); |
|
155 } |
|
156 public PmlBinaryReader(Stream Stream, Encoding Encoding) { |
|
157 pReader = new BinaryReader(Stream, Encoding); |
|
158 } |
|
159 |
|
160 public BinaryReader BaseReader { |
|
161 get { return pReader; } |
|
162 set { pReader = value; } |
|
163 } |
|
164 |
|
165 public PmlElement ReadMessage() { |
|
166 return ReadMessageFrom(pReader); |
|
167 } |
|
168 |
|
169 public static PmlElement ReadMessageFrom(BinaryReader Reader) { |
|
170 PmlElement Element = null; |
|
171 lock (Reader) { |
|
172 if (Reader.ReadByte() != 255) { |
|
173 return null; |
|
174 } |
|
175 Element = ReadElementFrom(Reader); |
|
176 if (Reader.ReadByte() != 255) { |
|
177 return null; |
|
178 } |
|
179 } |
|
180 return Element; |
|
181 } |
|
182 |
|
183 private static PmlElement ReadElementFrom(BinaryReader Reader) { |
|
184 Byte EType = Reader.ReadByte(); |
|
185 switch (EType) { |
|
186 case 0: return new PmlNull(); |
|
187 case 1: |
|
188 PmlDictionary ElementD = new PmlDictionary(); |
|
189 do { |
|
190 byte B = Reader.ReadByte(); |
|
191 if (B == 0) return ElementD; |
|
192 else if (B == 1) ElementD.Add(Reader.ReadString(), ReadElementFrom(Reader)); |
|
193 else return null; |
|
194 } |
|
195 while (true); |
|
196 case 2: |
|
197 PmlCollection ElementC = new PmlCollection(); |
|
198 do { |
|
199 byte B = Reader.ReadByte(); |
|
200 if (B == 0) return ElementC; |
|
201 else if (B == 1) ElementC.Add(ReadElementFrom(Reader)); |
|
202 else return null; |
|
203 } |
|
204 while (true); |
|
205 case 10: |
|
206 int Len = 0; |
|
207 Len = Reader.ReadInt32(); |
|
208 return new PmlBinary(Reader.ReadBytes(Len)); |
|
209 case 11: |
|
210 return new PmlString(Reader.ReadString()); |
|
211 case 20: { |
|
212 byte B = Reader.ReadByte(); |
|
213 if (B == 0) return new PmlInteger(Reader.ReadUInt64()); |
|
214 else if (B == 1) return new PmlInteger(Reader.ReadInt64()); |
|
215 else return null; |
|
216 |
|
217 } |
|
218 default: |
|
219 throw new Exception("Unknown PML type code " + EType.ToString()); |
|
220 } |
|
221 } |
|
222 } |
|
223 } |