Mercurial > hg > ucis.core
annotate Pml/RW/PmlBinaryRW.cs @ 1:28dc7d535036
Small improvements, introduced PacketStream
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Mon, 07 Jan 2013 16:43:28 +0100 |
parents | 3ab940a0c7a0 |
children |
rev | line source |
---|---|
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 Stream pStream; | |
38 private Encoding pEncoding; | |
39 | |
40 public PmlBinaryWriter(Stream Stream) { | |
41 pStream = Stream; | |
42 pEncoding = Encoding.UTF8; | |
43 } | |
44 public PmlBinaryWriter(Stream Stream, Encoding Encoding) { | |
45 pStream = Stream; | |
46 pEncoding = Encoding; | |
47 } | |
48 | |
49 public void WriteMessage(PmlElement Message) { | |
50 MemoryStream stream = new MemoryStream(); | |
51 BinaryWriter writer = new BinaryWriter(stream, pEncoding); | |
52 WriteMessageTo(Message, writer); | |
53 lock (pStream) { | |
54 stream.WriteTo(pStream); | |
55 pStream.Flush(); | |
56 } | |
57 } | |
58 | |
1
28dc7d535036
Small improvements, introduced PacketStream
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
59 public static Byte[] EncodeMessage(PmlElement message) { |
28dc7d535036
Small improvements, introduced PacketStream
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
60 MemoryStream stream = new MemoryStream(); |
28dc7d535036
Small improvements, introduced PacketStream
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
61 BinaryWriter writer = new BinaryWriter(stream, Encoding.UTF8); |
28dc7d535036
Small improvements, introduced PacketStream
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
62 WriteMessageTo(message, writer); |
28dc7d535036
Small improvements, introduced PacketStream
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
63 return stream.ToArray(); |
28dc7d535036
Small improvements, introduced PacketStream
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
64 } |
28dc7d535036
Small improvements, introduced PacketStream
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
65 |
0 | 66 public static void WriteMessageTo(PmlElement Message, BinaryWriter Writer) { |
67 lock (Writer) { | |
68 Writer.Write((byte)255); | |
69 WriteElementTo(Message, Writer); | |
70 Writer.Write((byte)255); | |
71 Writer.Flush(); | |
72 } | |
73 } | |
74 | |
75 private static void WriteElementTo(PmlElement Element, BinaryWriter Writer) { | |
76 if (Element == null) { | |
77 Writer.Write((byte)0); | |
78 return; | |
79 } | |
80 switch (Element.Type) { | |
81 case PmlType.Null: | |
82 Writer.Write((byte)0); | |
83 break; | |
84 case PmlType.Dictionary: | |
85 Writer.Write((byte)1); | |
86 foreach (KeyValuePair<string, PmlElement> Item in (PmlDictionary)Element) { | |
87 Writer.Write((byte)1); | |
88 Writer.Write(Item.Key); | |
89 WriteElementTo(Item.Value, Writer); | |
90 } | |
91 Writer.Write((byte)0); | |
92 break; | |
93 case PmlType.Collection: | |
94 Writer.Write((byte)2); | |
95 foreach (PmlElement Item in (PmlCollection)Element) { | |
96 Writer.Write((byte)1); | |
97 WriteElementTo(Item, Writer); | |
98 } | |
99 Writer.Write((byte)0); | |
100 break; | |
101 case PmlType.Binary: { | |
102 Writer.Write((byte)10); | |
103 Byte[] Buffer = Element.ToByteArray(); | |
104 if (Buffer == null) { | |
105 Writer.Write((int)0); | |
106 } else { | |
107 Writer.Write((int)Buffer.Length); | |
108 Writer.Write(Buffer); | |
109 } | |
110 } break; | |
111 case PmlType.String: | |
112 Writer.Write((byte)11); | |
113 string Str = Element.ToString(); | |
114 if (Str == null) { | |
1
28dc7d535036
Small improvements, introduced PacketStream
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
115 Writer.Write(String.Empty); |
0 | 116 } else { |
117 Writer.Write(Str); | |
118 } | |
119 | |
120 break; | |
121 case PmlType.Integer: | |
122 Writer.Write((byte)20); | |
123 PmlInteger RMInt = (PmlInteger)Element; | |
124 if (RMInt.IsSigned) { | |
125 Writer.Write((byte)1); | |
126 Writer.Write((long)RMInt); | |
127 } else { | |
128 Writer.Write((byte)0); | |
129 Writer.Write((ulong)RMInt); | |
130 } | |
131 break; | |
132 default: | |
133 Writer.Write((byte)0); | |
134 Console.WriteLine("PmlBinaryRW: Can not encode PML type {0}", Element.Type); | |
135 break; | |
136 } | |
137 } | |
138 } | |
139 | |
140 public class PmlBinaryReader : IPmlReader { | |
141 private BinaryReader pReader; | |
142 | |
143 public PmlBinaryReader(BinaryReader Reader) { | |
144 pReader = Reader; | |
145 } | |
146 public PmlBinaryReader(Stream Stream) { | |
147 pReader = new BinaryReader(Stream); | |
148 } | |
149 public PmlBinaryReader(Stream Stream, Encoding Encoding) { | |
150 pReader = new BinaryReader(Stream, Encoding); | |
151 } | |
152 | |
153 public BinaryReader BaseReader { | |
154 get { return pReader; } | |
155 set { pReader = value; } | |
156 } | |
157 | |
158 public PmlElement ReadMessage() { | |
159 return ReadMessageFrom(pReader); | |
160 } | |
161 | |
1
28dc7d535036
Small improvements, introduced PacketStream
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
162 public static PmlElement DecodeMessage(Byte[] message) { |
28dc7d535036
Small improvements, introduced PacketStream
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
163 using (MemoryStream ms = new MemoryStream(message)) { |
28dc7d535036
Small improvements, introduced PacketStream
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
164 using (BinaryReader reader = new BinaryReader(ms, Encoding.UTF8)) { |
28dc7d535036
Small improvements, introduced PacketStream
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
165 return ReadMessageFrom(reader); |
28dc7d535036
Small improvements, introduced PacketStream
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
166 } |
28dc7d535036
Small improvements, introduced PacketStream
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
167 } |
28dc7d535036
Small improvements, introduced PacketStream
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
168 } |
28dc7d535036
Small improvements, introduced PacketStream
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
169 |
0 | 170 public static PmlElement ReadMessageFrom(BinaryReader Reader) { |
171 PmlElement Element = null; | |
172 lock (Reader) { | |
173 if (Reader.ReadByte() != 255) { | |
174 return null; | |
175 } | |
176 Element = ReadElementFrom(Reader); | |
177 if (Reader.ReadByte() != 255) { | |
178 return null; | |
179 } | |
180 } | |
181 return Element; | |
182 } | |
183 | |
184 private static PmlElement ReadElementFrom(BinaryReader Reader) { | |
185 Byte EType = Reader.ReadByte(); | |
186 switch (EType) { | |
187 case 0: return new PmlNull(); | |
188 case 1: | |
189 PmlDictionary ElementD = new PmlDictionary(); | |
190 do { | |
191 byte B = Reader.ReadByte(); | |
192 if (B == 0) return ElementD; | |
193 else if (B == 1) ElementD.Add(Reader.ReadString(), ReadElementFrom(Reader)); | |
194 else return null; | |
195 } | |
196 while (true); | |
197 case 2: | |
198 PmlCollection ElementC = new PmlCollection(); | |
199 do { | |
200 byte B = Reader.ReadByte(); | |
201 if (B == 0) return ElementC; | |
202 else if (B == 1) ElementC.Add(ReadElementFrom(Reader)); | |
203 else return null; | |
204 } | |
205 while (true); | |
206 case 10: | |
207 int Len = 0; | |
208 Len = Reader.ReadInt32(); | |
209 return new PmlBinary(Reader.ReadBytes(Len)); | |
210 case 11: | |
211 return new PmlString(Reader.ReadString()); | |
212 case 20: { | |
213 byte B = Reader.ReadByte(); | |
214 if (B == 0) return new PmlInteger(Reader.ReadUInt64()); | |
215 else if (B == 1) return new PmlInteger(Reader.ReadInt64()); | |
216 else return null; | |
217 } | |
218 default: | |
219 throw new Exception("Unknown PML type code " + EType.ToString()); | |
220 } | |
221 } | |
222 } | |
223 } |