Mercurial > hg > ucis.core
comparison Pml/RW/PmlBinaryRW.cs @ 0:3ab940a0c7a0
Initial commit
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Tue, 11 Sep 2012 16:28:53 +0200 |
parents | |
children | 28dc7d535036 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:3ab940a0c7a0 |
---|---|
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 } |