1 /*
2  * asnxer.cxx
3  *
4  * Abstract Syntax Notation 1 Encoding Rules
5  *
6  * Portable Windows Library
7  *
8  */
9 
10 #include <ptclib/pxml.h>
11 
12 ///////////////////////////////////////////////////////////////////////
13 
NullDecode(PASN_Null &)14 PBoolean PXER_Stream::NullDecode(PASN_Null &)
15 {
16   return PTrue;
17 }
18 
19 
NullEncode(const PASN_Null &)20 void PXER_Stream::NullEncode(const PASN_Null &)
21 {
22 }
23 
24 ///////////////////////////////////////////////////////////////////////
25 
BooleanDecode(PASN_Boolean & value)26 PBoolean PXER_Stream::BooleanDecode(PASN_Boolean & value)
27 {
28   value = (position->GetElement("true") != 0);
29   return PTrue;
30 }
31 
32 
BooleanEncode(const PASN_Boolean & value)33 void PXER_Stream::BooleanEncode(const PASN_Boolean & value)
34 {
35   position->AddChild(new PXMLElement(position, value.GetValue() ? "true" : "false"));
36 }
37 
38 ///////////////////////////////////////////////////////////////////////
39 
IntegerDecode(PASN_Integer & value)40 PBoolean PXER_Stream::IntegerDecode(PASN_Integer & value)
41 {
42   value = position->GetData().AsInteger();
43   return PTrue;
44 }
45 
46 
IntegerEncode(const PASN_Integer & value)47 void PXER_Stream::IntegerEncode(const PASN_Integer & value)
48 {
49   position->AddChild(new PXMLData(position, value.GetValue()));
50 }
51 
52 ///////////////////////////////////////////////////////////////////////
53 
DecodeXER(PXER_Stream & strm)54 PBoolean PASN_Enumeration::DecodeXER(PXER_Stream & strm)
55 {
56   value = strm.GetCurrentElement()->GetData().AsInteger();
57   return PTrue;
58 }
59 
60 
EncodeXER(PXER_Stream & strm) const61 void PASN_Enumeration::EncodeXER(PXER_Stream & strm) const
62 {
63   PXMLElement * elem = strm.GetCurrentElement();
64   elem->AddChild(new PXMLData(elem, value));
65 }
66 
67 
EnumerationDecode(PASN_Enumeration & value)68 PBoolean PXER_Stream::EnumerationDecode(PASN_Enumeration & value)
69 {
70   return value.DecodeXER(*this);
71 }
72 
73 
EnumerationEncode(const PASN_Enumeration & value)74 void PXER_Stream::EnumerationEncode(const PASN_Enumeration & value)
75 {
76   value.EncodeXER(*this);
77 }
78 
79 ///////////////////////////////////////////////////////////////////////
80 
RealDecode(PASN_Real & value)81 PBoolean PXER_Stream::RealDecode(PASN_Real & value)
82 {
83   value = position->GetData().AsReal();
84   return PTrue;
85 }
86 
87 
RealEncode(const PASN_Real & value)88 void PXER_Stream::RealEncode(const PASN_Real & value)
89 {
90   position->AddChild(new PXMLData(position, PString(PString::Decimal, value.GetValue(), 10)));
91 }
92 
93 ///////////////////////////////////////////////////////////////////////
94 
ObjectIdDecode(PASN_ObjectId & value)95 PBoolean PXER_Stream::ObjectIdDecode(PASN_ObjectId & value)
96 {
97   value.SetValue(position->GetData());
98   return PTrue;
99 }
100 
101 
ObjectIdEncode(const PASN_ObjectId & value)102 void PXER_Stream::ObjectIdEncode(const PASN_ObjectId & value)
103 {
104   position->AddChild(new PXMLData(position, value.AsString()));
105 }
106 
107 ///////////////////////////////////////////////////////////////////////
108 
BitStringDecode(PASN_BitString & value)109 PBoolean PXER_Stream::BitStringDecode(PASN_BitString & value)
110 {
111   PString bits = position->GetData();
112   PINDEX len = bits.GetLength();
113 
114   value.SetSize(len);
115 
116   for (PINDEX i = 0 ; i < len ; i++)
117   {
118     if (bits[i] == '1')
119       value.Set(i);
120     else if (bits[i] != '0')
121       return PFalse;
122   }
123 
124   return PTrue;
125 }
126 
127 
BitStringEncode(const PASN_BitString & value)128 void PXER_Stream::BitStringEncode(const PASN_BitString & value)
129 {
130   PString bits;
131 
132   for (PINDEX i = 0 ; i < (PINDEX)value.GetSize() ; i++)
133   {
134     bits += (value[i] ? '1' : '0');
135   }
136 
137   position->AddChild(new PXMLData(position, bits));
138 }
139 
140 ///////////////////////////////////////////////////////////////////////
141 
OctetStringDecode(PASN_OctetString & value)142 PBoolean PXER_Stream::OctetStringDecode(PASN_OctetString & value)
143 {
144   char elem[3] = { 0, 0, 0 };
145   PString data = position->GetData();
146   PINDEX len = data.GetLength();
147 
148   if (len % 2)
149     return PFalse;
150 
151   BYTE * bin = value.GetPointer(len / 2);
152   unsigned octet;
153 
154   for (PINDEX i = 0, j = 0 ; i < len ; i += 2, j++)
155   {
156     elem[0] = data[i];
157     elem[1] = data[i + 1];
158     sscanf(elem, "%x", &octet);
159     bin[j] = (BYTE)octet;
160   }
161 
162   return PTrue;
163 }
164 
165 
OctetStringEncode(const PASN_OctetString & value)166 void PXER_Stream::OctetStringEncode(const PASN_OctetString & value)
167 {
168   PString bin;
169 
170   for (PINDEX i = 0 ; i < value.GetSize() ; i++)
171   {
172     unsigned v = (unsigned)value[i];
173     bin.sprintf("%02x", v);
174   }
175 
176   position->AddChild(new PXMLData(position, bin));
177 }
178 
179 ///////////////////////////////////////////////////////////////////////
180 
ConstrainedStringDecode(PASN_ConstrainedString & value)181 PBoolean PXER_Stream::ConstrainedStringDecode(PASN_ConstrainedString & value)
182 {
183   value = position->GetData();
184   return PTrue;
185 }
186 
187 
ConstrainedStringEncode(const PASN_ConstrainedString & value)188 void PXER_Stream::ConstrainedStringEncode(const PASN_ConstrainedString & value)
189 {
190   position->AddChild(new PXMLData(position, value.GetValue()));
191 }
192 
193 ///////////////////////////////////////////////////////////////////////
194 
BMPStringDecode(PASN_BMPString &)195 PBoolean PXER_Stream::BMPStringDecode(PASN_BMPString &)
196 {
197   return PFalse;
198 }
199 
200 
BMPStringEncode(const PASN_BMPString &)201 void PXER_Stream::BMPStringEncode(const PASN_BMPString &)
202 {
203 }
204 
205 ///////////////////////////////////////////////////////////////////////
206 
DecodeXER(PXER_Stream & strm)207 PBoolean PASN_Choice::DecodeXER(PXER_Stream & strm)
208 {
209   PXMLElement * elem = strm.GetCurrentElement();
210   PXMLElement * choice_elem = (PXMLElement *)elem->GetElement();
211 
212   if (!choice_elem || !choice_elem->IsElement())
213     return PFalse;
214 
215   for (unsigned int i = 0 ; i < namesCount ; i++)
216   {
217     if (choice_elem->GetName() == names[i].name)
218     {
219       tag = names[i].value;
220       if (!CreateObject())
221         return PFalse;
222       strm.SetCurrentElement(choice_elem);
223       PBoolean res = choice->Decode(strm);
224       strm.SetCurrentElement(elem);
225       return res;
226     }
227   }
228 
229   return PFalse;
230 }
231 
232 
EncodeXER(PXER_Stream & strm) const233 void PASN_Choice::EncodeXER(PXER_Stream & strm) const
234 {
235   if (choice)
236   {
237     PXMLElement * elem = strm.GetCurrentElement();
238     strm.SetCurrentElement(elem->AddChild(new PXMLElement(elem, GetTagName())));
239     choice->Encode(strm);
240     strm.SetCurrentElement(elem);
241   }
242 }
243 
244 ///////////////////////////////////////////////////////////////////////
245 
ChoiceDecode(PASN_Choice & value)246 PBoolean PXER_Stream::ChoiceDecode(PASN_Choice & value)
247 {
248   return value.DecodeXER(*this);
249 }
250 
251 
ChoiceEncode(const PASN_Choice & value)252 void PXER_Stream::ChoiceEncode(const PASN_Choice & value)
253 {
254   value.EncodeXER(*this);
255 }
256 
257 ///////////////////////////////////////////////////////////////////////
258 
PreambleDecodeXER(PXER_Stream &)259 PBoolean PASN_Sequence::PreambleDecodeXER(PXER_Stream &)
260 {
261   return PTrue;
262 }
263 
264 
PreambleEncodeXER(PXER_Stream &) const265 void PASN_Sequence::PreambleEncodeXER(PXER_Stream &) const
266 {
267 }
268 
269 
KnownExtensionDecodeXER(PXER_Stream &,PINDEX,PASN_Object &)270 PBoolean PASN_Sequence::KnownExtensionDecodeXER(PXER_Stream &, PINDEX, PASN_Object &)
271 {
272   return PTrue;
273 }
274 
275 
KnownExtensionEncodeXER(PXER_Stream &,PINDEX,const PASN_Object &) const276 void PASN_Sequence::KnownExtensionEncodeXER(PXER_Stream &, PINDEX, const PASN_Object &) const
277 {
278 }
279 
280 
UnknownExtensionsDecodeXER(PXER_Stream &)281 PBoolean PASN_Sequence::UnknownExtensionsDecodeXER(PXER_Stream &)
282 {
283   return PTrue;
284 }
285 
286 
UnknownExtensionsEncodeXER(PXER_Stream &) const287 void PASN_Sequence::UnknownExtensionsEncodeXER(PXER_Stream &) const
288 {
289 }
290 
291 ///////////////////////////////////////////////////////////////////////
292 
SequencePreambleDecode(PASN_Sequence & seq)293 PBoolean PXER_Stream::SequencePreambleDecode(PASN_Sequence & seq)
294 {
295   return seq.PreambleDecodeXER(*this);
296 }
297 
298 
SequencePreambleEncode(const PASN_Sequence & seq)299 void PXER_Stream::SequencePreambleEncode(const PASN_Sequence & seq)
300 {
301   seq.PreambleEncodeXER(*this);
302 }
303 
304 
SequenceKnownDecode(PASN_Sequence & seq,PINDEX fld,PASN_Object & field)305 PBoolean PXER_Stream::SequenceKnownDecode(PASN_Sequence & seq, PINDEX fld, PASN_Object & field)
306 {
307   return seq.KnownExtensionDecodeXER(*this, fld, field);
308 }
309 
310 
SequenceKnownEncode(const PASN_Sequence & seq,PINDEX fld,const PASN_Object & field)311 void PXER_Stream::SequenceKnownEncode(const PASN_Sequence & seq, PINDEX fld, const PASN_Object & field)
312 {
313   seq.KnownExtensionEncodeXER(*this, fld, field);
314 }
315 
316 
SequenceUnknownDecode(PASN_Sequence & seq)317 PBoolean PXER_Stream::SequenceUnknownDecode(PASN_Sequence & seq)
318 {
319   return seq.UnknownExtensionsDecodeXER(*this);
320 }
321 
322 
SequenceUnknownEncode(const PASN_Sequence & seq)323 void PXER_Stream::SequenceUnknownEncode(const PASN_Sequence & seq)
324 {
325   seq.UnknownExtensionsEncodeXER(*this);
326 }
327 
328 ///////////////////////////////////////////////////////////////////////
329 
ArrayDecode(PASN_Array & array)330 PBoolean PXER_Stream::ArrayDecode(PASN_Array & array)
331 {
332   array.RemoveAll();
333 
334   unsigned size = position->GetSize();
335 
336   if (!array.SetSize(size))
337     return PFalse;
338 
339   PXMLElement * elem = position;
340   PBoolean res = PTrue;
341 
342   for (PINDEX i = 0; i < (PINDEX)size; i++) {
343     position = (PXMLElement *)elem->GetElement(i);
344 
345     if (!position->IsElement() || !array[i].Decode(*this)) {
346       res = PFalse;
347       break;
348     }
349   }
350 
351   position = elem;
352 
353   return res;
354 }
355 
356 
ArrayEncode(const PASN_Array & array)357 void PXER_Stream::ArrayEncode(const PASN_Array & array)
358 {
359   PINDEX size = array.GetSize();
360   PXMLElement * elem = position;
361 
362   for (PINDEX i = 0; i < (PINDEX)size; i++) {
363     PString name = array[i].GetTypeAsString();
364     name.Replace(" ", "_", PTrue);
365     position = elem->AddChild(new PXMLElement(elem, name));
366     array[i].Encode(*this);
367   }
368 
369   position = elem;
370 }
371 
372 ///////////////////////////////////////////////////////////////////////
373 
PXER_Stream(PXMLElement * elem)374 PXER_Stream::PXER_Stream(PXMLElement * elem)
375   : position(PAssertNULL(elem))
376 {
377 }
378 
379 
PXER_Stream(PXMLElement * elem,const PBYTEArray & bytes)380 PXER_Stream::PXER_Stream(PXMLElement * elem, const PBYTEArray & bytes)
381   : PASN_Stream(bytes),
382     position(PAssertNULL(elem))
383 {
384 }
385 
386 
PXER_Stream(PXMLElement * elem,const BYTE * buf,PINDEX size)387 PXER_Stream::PXER_Stream(PXMLElement * elem, const BYTE * buf, PINDEX size)
388   : PASN_Stream(buf, size),
389     position(PAssertNULL(elem))
390 {
391 }
392 
393 
Read(PChannel &)394 PBoolean PXER_Stream::Read(PChannel &)
395 {
396   return PFalse;
397 }
398 
399 
Write(PChannel &)400 PBoolean PXER_Stream::Write(PChannel &)
401 {
402   return PFalse;
403 }
404