Added class for encoding and decoding ASN.1 tags.

git-svn-id: http://voip.null.ro/svn/yate@4668 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
oana 2011-11-01 08:49:08 +00:00
parent a8022a8b9f
commit edfe3b2760
2 changed files with 220 additions and 0 deletions

View File

@ -1186,6 +1186,71 @@ int ASNLib::encodeSet(DataBlock& data, bool tagCheck)
return len.length();
}
/**
* AsnTag
*/
void AsnTag::decode(AsnTag& tag, DataBlock& data)
{
XDebug(s_libName.c_str(),DebugAll,"AsnTag::decode()");
tag.classType((Class)(data[0] & 0xc0));
tag.type((Type)(data[0] & 0x20));
unsigned int code = 0;
code |= data[0] & 0x1f;
unsigned int len = 1;
if (IS_EXTENSION_ID(code) && data.length() >= 2) { // extended tag
code = 0;
while (len < data.length() && (data[len] & ASN_BIT8) == ASN_BIT8) {
code = code << 8;
code |= (data[len] & 0x7f);
len++;
}
code |= data[len] & 0x7f;
}
tag.code(code);
tag.encode();
}
void AsnTag::encode(Class clas, Type type, unsigned int code, DataBlock& data)
{
XDebug(s_libName.c_str(),DebugAll,"AsnTag::encode(clas=0x%x, type=0x%x, code=%u)",clas,type,code);
if (code < 31) {
u_int8_t tag = clas | type | code;
data.insert(DataBlock(&tag,sizeof(tag)));
}
else {
u_int8_t last = clas | type | 31;
data.append(&last,sizeof(last));
int size = sizeof(unsigned int);
bool start = false;
while (size > 1) {
u_int8_t msb = (code >> ((size - 1) * 8));
if (start) {
msb |= 0x80;
data.append(&msb,sizeof(msb));
}
else {
if (msb == 0) {
size--;
continue;
}
else {
start = true;
msb |= 0x80;
data.append(&msb,sizeof(msb));
}
}
size--;
}
last = code;
data.append(&last,sizeof(last));
}
#ifdef XDEBUG
String str;
str.hexify(data.data(),data.length(),' ');
XDebug(s_libName.c_str(),DebugAll,"AsnTag::encode(clas=0x%x, type=0x%x, code=%u) tag=%s",clas,type,code,str.c_str());
#endif
}
/**
* ASNObjId

View File

@ -539,6 +539,161 @@ private:
DataBlock m_ids;
};
/**
* Class AsnTag
* @short Class for ASN.1 tags
*/
class AsnTag {
public:
/**
* ASN.1 Tag class types enum
*/
enum Class {
Universal = 0x00,
Application = 0x40,
Context = 0x80,
Private = 0xc0,
};
/**
* ASN.1 Type of tag enum
*/
enum Type {
Primitive = 0x00,
Constructor = 0x20,
};
/**
* Constructor
*/
inline AsnTag()
: m_class(Universal), m_type(Primitive), m_code(0)
{ }
/**
* Constructor
* @param clas Class of the ASN.1 Tag
* @param type Type of the ASN.1 Tag
* @param code Code ot the ASN.1 Tag
*/
inline AsnTag(Class clas, Type type, unsigned int code)
: m_class(clas), m_type(type), m_code(code)
{
encode();
}
/**
* Destructor
*/
inline ~AsnTag()
{}
/**
* Decode an ASN.1 tag from the given data
* @param tag Tag to fill
* @param data Data from which the tag should be filled
*/
static void decode(AsnTag& tag, DataBlock& data);
/**
* Encode an ASN.1 tag and put the encoded form into the given data
* @param clas Class of the tag
* @param type Type of the tag
* @param code Tag code
* @param data DataBlock into which to insert the encoded tag
*/
static void encode(Class clas, Type type, unsigned int code, DataBlock& data);
/**
* Encode self
*/
inline void encode()
{ AsnTag::encode(m_class,m_type,m_code,m_coding); }
/**
* Equality operator
*/
inline bool operator==(const AsnTag& tag) const
{
return (m_class == tag.classType() && m_type == tag.type() && m_code == tag.code());
}
/**
* Inequality operator
*/
inline bool operator!=(const AsnTag& tag) const
{
return !(m_class == tag.classType() && m_type == tag.type() && m_code == tag.code());
}
/**
* Assignment operator
*/
inline AsnTag& operator=(const AsnTag& value)
{
m_class = value.classType();
m_type = value.type();
m_code = value.code();
encode();
return *this;
}
/**
* Get the tag class
* @return The class of the tag
*/
inline const Class classType() const
{ return m_class; }
/**
* Set the tag class
* @param clas The clas to set for the tag
*/
inline void classType(Class clas)
{ m_class = clas; }
/**
* Get the tag type
* @return The type of the tag
*/
inline const Type type() const
{ return m_type; }
/**
* Set the tag type
* @param type The type to set for the tag
*/
inline void type(Type type)
{ m_type = type; }
/**
* Get the tag code
* @return The code of the tag
*/
inline const unsigned int code() const
{ return m_code; }
/**
* Set the tag code
* @param code The code to set for the tag
*/
inline void code(unsigned int code)
{ m_code = code; }
/**
* Get the tag encoding
* @return The DataBlock containing the encoding for the tag
*/
inline const DataBlock& coding() const
{ return m_coding; }
private:
Class m_class;
Type m_type;
unsigned int m_code;
DataBlock m_coding;
};
/**
* Class ASNLib
* @short Class containing functions for decoding/encoding ASN.1 basic data types