Added IsSupportingRTP function to simplify detecting when STUN supports RTP
[pwlib.git] / src / ptclib / asnxer.cxx
blobdcf43add5d07ad240e609ab5c1b01cf10f73291d
1 /*
2 * asnxer.cxx
4 * Abstract Syntax Notation 1 Encoding Rules
6 * Portable Windows Library
8 */
10 #include <ptclib/pxml.h>
12 ///////////////////////////////////////////////////////////////////////
14 BOOL PXER_Stream::NullDecode(PASN_Null &)
16 return TRUE;
20 void PXER_Stream::NullEncode(const PASN_Null &)
24 ///////////////////////////////////////////////////////////////////////
26 BOOL PXER_Stream::BooleanDecode(PASN_Boolean & value)
28 value = (position->GetElement("true") != 0);
29 return TRUE;
33 void PXER_Stream::BooleanEncode(const PASN_Boolean & value)
35 position->AddChild(new PXMLElement(position, value.GetValue() ? "true" : "false"));
38 ///////////////////////////////////////////////////////////////////////
40 BOOL PXER_Stream::IntegerDecode(PASN_Integer & value)
42 value = position->GetData().AsInteger();
43 return TRUE;
47 void PXER_Stream::IntegerEncode(const PASN_Integer & value)
49 position->AddChild(new PXMLData(position, value.GetValue()));
52 ///////////////////////////////////////////////////////////////////////
54 BOOL PASN_Enumeration::DecodeXER(PXER_Stream & strm)
56 value = strm.GetCurrentElement()->GetData().AsInteger();
57 return TRUE;
61 void PASN_Enumeration::EncodeXER(PXER_Stream & strm) const
63 PXMLElement * elem = strm.GetCurrentElement();
64 elem->AddChild(new PXMLData(elem, value));
68 BOOL PXER_Stream::EnumerationDecode(PASN_Enumeration & value)
70 return value.DecodeXER(*this);
74 void PXER_Stream::EnumerationEncode(const PASN_Enumeration & value)
76 value.EncodeXER(*this);
79 ///////////////////////////////////////////////////////////////////////
81 BOOL PXER_Stream::RealDecode(PASN_Real & value)
83 value = position->GetData().AsReal();
84 return TRUE;
88 void PXER_Stream::RealEncode(const PASN_Real & value)
90 position->AddChild(new PXMLData(position, PString(PString::Decimal, value.GetValue(), 10)));
93 ///////////////////////////////////////////////////////////////////////
95 BOOL PXER_Stream::ObjectIdDecode(PASN_ObjectId & value)
97 value.SetValue(position->GetData());
98 return TRUE;
102 void PXER_Stream::ObjectIdEncode(const PASN_ObjectId & value)
104 position->AddChild(new PXMLData(position, value.AsString()));
107 ///////////////////////////////////////////////////////////////////////
109 BOOL PXER_Stream::BitStringDecode(PASN_BitString & value)
111 PString bits = position->GetData();
112 PINDEX len = bits.GetLength();
114 value.SetSize(len);
116 for (PINDEX i = 0 ; i < len ; i++)
118 if (bits[i] == '1')
119 value.Set(i);
120 else if (bits[i] != '0')
121 return FALSE;
124 return TRUE;
128 void PXER_Stream::BitStringEncode(const PASN_BitString & value)
130 PString bits;
132 for (PINDEX i = 0 ; i < (PINDEX)value.GetSize() ; i++)
134 bits += (value[i] ? '1' : '0');
137 position->AddChild(new PXMLData(position, bits));
140 ///////////////////////////////////////////////////////////////////////
142 BOOL PXER_Stream::OctetStringDecode(PASN_OctetString & value)
144 char elem[3] = { 0, 0, 0 };
145 PString data = position->GetData();
146 PINDEX len = data.GetLength();
148 if (len % 2)
149 return FALSE;
151 BYTE * bin = value.GetPointer(len / 2);
152 unsigned octet;
154 for (PINDEX i = 0, j = 0 ; i < len ; i += 2, j++)
156 elem[0] = data[i];
157 elem[1] = data[i + 1];
158 sscanf(elem, "%x", &octet);
159 bin[j] = (BYTE)octet;
162 return TRUE;
166 void PXER_Stream::OctetStringEncode(const PASN_OctetString & value)
168 PString bin;
170 for (PINDEX i = 0 ; i < value.GetSize() ; i++)
172 unsigned v = (unsigned)value[i];
173 bin.sprintf("%02x", v);
176 position->AddChild(new PXMLData(position, bin));
179 ///////////////////////////////////////////////////////////////////////
181 BOOL PXER_Stream::ConstrainedStringDecode(PASN_ConstrainedString & value)
183 value = position->GetData();
184 return TRUE;
188 void PXER_Stream::ConstrainedStringEncode(const PASN_ConstrainedString & value)
190 position->AddChild(new PXMLData(position, value.GetValue()));
193 ///////////////////////////////////////////////////////////////////////
195 BOOL PXER_Stream::BMPStringDecode(PASN_BMPString &)
197 return FALSE;
201 void PXER_Stream::BMPStringEncode(const PASN_BMPString &)
205 ///////////////////////////////////////////////////////////////////////
207 BOOL PASN_Choice::DecodeXER(PXER_Stream & strm)
209 PXMLElement * elem = strm.GetCurrentElement();
210 PXMLElement * choice_elem = (PXMLElement *)elem->GetElement();
212 if (!choice_elem || !choice_elem->IsElement())
213 return FALSE;
215 for (PINDEX i = 0 ; i < names.GetSize() ; i++)
217 if (choice_elem->GetName() == names.GetDataAt(i))
219 tag = i;
220 if (!CreateObject())
221 return FALSE;
222 strm.SetCurrentElement(choice_elem);
223 BOOL res = choice->Decode(strm);
224 strm.SetCurrentElement(elem);
225 return res;
229 return FALSE;
233 void PASN_Choice::EncodeXER(PXER_Stream & strm) const
235 if (choice)
237 PXMLElement * elem = strm.GetCurrentElement();
238 strm.SetCurrentElement(elem->AddChild(new PXMLElement(elem, GetTagName())));
239 choice->Encode(strm);
240 strm.SetCurrentElement(elem);
244 ///////////////////////////////////////////////////////////////////////
246 BOOL PXER_Stream::ChoiceDecode(PASN_Choice & value)
248 return value.DecodeXER(*this);
252 void PXER_Stream::ChoiceEncode(const PASN_Choice & value)
254 value.EncodeXER(*this);
257 ///////////////////////////////////////////////////////////////////////
259 BOOL PASN_Sequence::PreambleDecodeXER(PXER_Stream &)
261 return TRUE;
265 void PASN_Sequence::PreambleEncodeXER(PXER_Stream &) const
270 BOOL PASN_Sequence::KnownExtensionDecodeXER(PXER_Stream &, PINDEX, PASN_Object &)
272 return TRUE;
276 void PASN_Sequence::KnownExtensionEncodeXER(PXER_Stream &, PINDEX, const PASN_Object &) const
281 BOOL PASN_Sequence::UnknownExtensionsDecodeXER(PXER_Stream &)
283 return TRUE;
287 void PASN_Sequence::UnknownExtensionsEncodeXER(PXER_Stream &) const
291 ///////////////////////////////////////////////////////////////////////
293 BOOL PXER_Stream::SequencePreambleDecode(PASN_Sequence & seq)
295 return seq.PreambleDecodeXER(*this);
299 void PXER_Stream::SequencePreambleEncode(const PASN_Sequence & seq)
301 seq.PreambleEncodeXER(*this);
305 BOOL PXER_Stream::SequenceKnownDecode(PASN_Sequence & seq, PINDEX fld, PASN_Object & field)
307 return seq.KnownExtensionDecodeXER(*this, fld, field);
311 void PXER_Stream::SequenceKnownEncode(const PASN_Sequence & seq, PINDEX fld, const PASN_Object & field)
313 seq.KnownExtensionEncodeXER(*this, fld, field);
317 BOOL PXER_Stream::SequenceUnknownDecode(PASN_Sequence & seq)
319 return seq.UnknownExtensionsDecodeXER(*this);
323 void PXER_Stream::SequenceUnknownEncode(const PASN_Sequence & seq)
325 seq.UnknownExtensionsEncodeXER(*this);
328 ///////////////////////////////////////////////////////////////////////
330 BOOL PXER_Stream::ArrayDecode(PASN_Array & array)
332 array.RemoveAll();
334 unsigned size = position->GetSize();
336 if (!array.SetSize(size))
337 return FALSE;
339 PXMLElement * elem = position;
340 BOOL res = TRUE;
342 for (PINDEX i = 0; i < (PINDEX)size; i++) {
343 position = (PXMLElement *)elem->GetElement(i);
345 if (!position->IsElement() || !array[i].Decode(*this)) {
346 res = FALSE;
347 break;
351 position = elem;
353 return res;
357 void PXER_Stream::ArrayEncode(const PASN_Array & array)
359 PINDEX size = array.GetSize();
360 PXMLElement * elem = position;
362 for (PINDEX i = 0; i < (PINDEX)size; i++) {
363 PString name = array[i].GetTypeAsString();
364 name.Replace(" ", "_", TRUE);
365 position = elem->AddChild(new PXMLElement(elem, name));
366 array[i].Encode(*this);
369 position = elem;
372 ///////////////////////////////////////////////////////////////////////
374 PXER_Stream::PXER_Stream(PXMLElement * elem)
375 : position(PAssertNULL(elem))
380 PXER_Stream::PXER_Stream(PXMLElement * elem, const PBYTEArray & bytes)
381 : PASN_Stream(bytes),
382 position(PAssertNULL(elem))
387 PXER_Stream::PXER_Stream(PXMLElement * elem, const BYTE * buf, PINDEX size)
388 : PASN_Stream(buf, size),
389 position(PAssertNULL(elem))
394 BOOL PXER_Stream::Read(PChannel &)
396 return FALSE;
400 BOOL PXER_Stream::Write(PChannel &)
402 return FALSE;