📄 pasn.cxx
字号:
BOOL PASNUnsignedInteger::Decode(const PBYTEArray & buffer, PINDEX & ptr, PASNObject::ASNType theType)
{
return DecodeASNUnsigned(buffer, ptr, value, theType);
}
void PASNUnsignedInteger::Encode(PBYTEArray & buffer, PASNObject::ASNType theType)
{
EncodeASNUnsigned(buffer, value, theType);
}
void PASNUnsignedInteger::PrintOn(ostream & strm) const
{
strm << GetTypeAsString()
<< " : "
<< value
<< endl;
}
WORD PASNUnsignedInteger::GetEncodedLength()
{
return GetASNUnsignedLength(value);
}
PString PASNUnsignedInteger::GetString() const
{
return PString(PString::Unsigned, (long)value);
}
PASNUnsigned PASNUnsignedInteger::GetUnsigned() const
{
return value;
}
//////////////////////////////////////////////////////////////////////////
//
// PASNObjectID
// A descendant of PASNObject which is a simple ASN ObjID type
//
PASNObjectID::PASNObjectID(PASNOid * val, BYTE theLen)
{
value.SetSize(theLen);
memcpy(value.GetPointer(theLen), val, theLen * sizeof(PASNOid));
}
PASNObjectID::PASNObjectID(const PString & str)
{
PINDEX strLen = str.GetLength();
PINDEX i = 0;
PINDEX len = 0;
while (i < strLen) {
// find the first non-dot character
while (str[i] == '.' && i < strLen)
i++;
// find the next dot
PINDEX j = str.Find('.', i);
// convert to a PASNOid
value.SetSize(len+1);
value.SetAt(len++, str(i, j).AsInteger());
i = j;
}
}
PASNObjectID::PASNObjectID(const PBYTEArray & buffer)
{
PINDEX ptr = 0;
Decode(buffer, ptr);
}
PASNObjectID::PASNObjectID(const PBYTEArray & buffer, PINDEX & ptr)
{
Decode(buffer, ptr);
}
void PASNObjectID::PrintOn(ostream & strm) const
{
strm << "ObjectId: ";
for (PINDEX i = 0 ; i < value.GetSize(); i++) {
strm << value[i];
if (i != value.GetSize()-1)
strm << '.';
}
strm << endl;
}
void PASNObjectID::Encode(PBYTEArray & buffer)
{
PBYTEArray eObjId;
PINDEX offs = 0;
PASNOid subId, mask, testmask;
int bits, testbits;
PINDEX objIdLen = value.GetSize();
PASNOid *objId = value.GetPointer();
if (objIdLen < 2) {
eObjId [offs++] = 0;
objIdLen = 0;
} else {
eObjId [offs++] = (BYTE)(objId[1] + (objId[0] * 40));
objIdLen -= 2;
objId += 2;
}
while (objIdLen-- > 0) {
subId = *objId++;
if (subId < 128)
eObjId [offs++] = (BYTE)subId;
else {
mask = 0x7F; /* handle subid == 0 case */
bits = 0;
/* testmask *MUST* !!!! be of an unsigned type */
for (testmask = 0x7F, testbits = 0;
testmask != 0;
testmask <<= 7, testbits += 7) {
if (subId & testmask) { /* if any bits set */
mask = testmask;
bits = testbits;
}
}
/* mask can't be zero here */
for(;mask != 0x7F; mask >>= 7, bits -= 7) {
/* fix a mask that got truncated above */
if (mask == 0x1E00000)
mask = 0xFE00000;
eObjId [offs++] = (u_char)(((subId & mask) >> bits) | ASN_BIT8);
}
eObjId [offs++] = (u_char)(subId & mask);
}
}
PINDEX s = eObjId.GetSize();
EncodeASNHeader (buffer, ObjectID, (WORD)s);
offs = buffer.GetSize();
for (PINDEX i = 0; i < s; i++)
buffer [offs + i] = eObjId[i];
}
WORD PASNObjectID::GetEncodedLength()
{
PASNOid subId, mask, testmask;
int bits, testbits;
PINDEX objIdLen = value.GetSize();
WORD theLen = 0;
PASNOid *objId = value.GetPointer();
if (objIdLen < 2) {
theLen++;
objIdLen = 0;
} else {
theLen++;
objIdLen -= 2;
objId += 2;
}
while (objIdLen-- > 0) {
subId = *objId++;
if (subId < 128)
theLen++;
else {
mask = 0x7F; /* handle subid == 0 case */
bits = 0;
/* testmask *MUST* !!!! be of an unsigned type */
for (testmask = 0x7F, testbits = 0;
testmask != 0;
testmask <<= 7, testbits += 7) {
if (subId & testmask) { /* if any bits set */
mask = testmask;
bits = testbits;
}
}
/* mask can't be zero here */
for(;mask != 0x7F; mask >>= 7, bits -= 7) {
/* fix a mask that got truncated above */
if (mask == 0x1E00000)
mask = 0xFE00000;
theLen++;
}
theLen++;
}
}
return (WORD)(theLen + GetASNHeaderLength(theLen));
}
PASNObject::ASNType PASNObjectID::GetType() const
{
return ObjectID;
}
PString PASNObjectID::GetTypeAsString() const
{
return PString("Object ID");
}
PString PASNObjectID::GetString() const
{
PStringStream str;
for (PINDEX i = 0; i < value.GetSize(); i++) {
if (i > 0)
str << '.';
str << value[i];
}
return str;
}
BOOL PASNObjectID::Decode(const PBYTEArray & buffer, PINDEX & offs)
{
BYTE type = buffer[offs++];
PAssert(type == (ASN_OBJECT_ID | ASN_UNIVERSAL | ASN_PRIMITIVE),
"Attempt to decode non-objectID");
PASNOid subId;
WORD dataLen;
if (!DecodeASNLength(buffer, offs, dataLen))
return FALSE;
value.SetSize(2);
// handle zero length strings correctly
if (dataLen != 0) {
// start at the second identifier in the buffer, because we will later
// expand the first number into the first two IDs
PINDEX i = 1;
PINDEX s = buffer.GetSize();
while (dataLen > 0) {
subId = 0;
do { /* shift and add in low order 7 bits */
if (dataLen == 0 || offs >= s)
return FALSE;
subId = (subId << 7) + (buffer[offs] & ~ASN_BIT8);
dataLen--;
} while (buffer[offs++] & ASN_BIT8);
value.SetAt(i++, subId);
}
/*
* The first two subidentifiers are encoded into the first component
* with the value (X * 40) + Y, where:
* X is the value of the first subidentifier.
* Y is the value of the second subidentifier.
*/
subId = value[1];
if (subId == 0x2B) {
value[0] = 1;
value[1] = 3;
} else {
value[1] = subId % 40;
value[0] = (subId - value[1]) / 40;
}
}
return TRUE;
}
PObject * PASNObjectID::Clone() const
{
return new PASNObjectID(*this);
}
//////////////////////////////////////////////////////////////////////////
//
// PASNSequence
// A descendant of PASNObject which is the complex sequence type
//
PASNSequence::PASNSequence()
{
encodedLen = 0;
type = ASNTypeToType[Sequence];
asnType = Sequence;
}
PASNSequence::PASNSequence(BYTE selector)
{
encodedLen = 0;
PAssert(selector < ASN_CONSTRUCTOR, "Sequence selector too big");
type = (BYTE)(ASNTypeToType[Choice] | selector);
asnType = Choice;
}
void PASNSequence::Append(PASNObject * obj)
{
sequence.Append(obj);
}
void PASNSequence::AppendInteger(PASNInt value)
{
Append(new PASNInteger(value));
}
void PASNSequence::AppendString (const PString & str)
{
Append(new PASNString(str));
}
void PASNSequence::AppendObjectID(const PString & str)
{
Append(new PASNObjectID(str));
}
void PASNSequence::AppendObjectID(PASNOid * val, BYTE len)
{
Append(new PASNObjectID(val, len));
}
void PASNSequence::PrintOn(ostream & strm) const
{
strm << "Sequence:" << endl;
for (PINDEX i = 0; i < sequence.GetSize(); i++)
strm << sequence[i];
strm << "End Sequence" << endl;
}
void PASNSequence::Encode(PBYTEArray & buffer)
{
// calculate the length of the sequence, if it hasn't already been done
if (encodedLen == 0)
(void)GetEncodedLength();
// create the header for the sequence. Note that seqLen was calculated
// by the call to GetEncodedLength above
EncodeASNSequenceStart(buffer, type, seqLen);
// now encode the sequence itself
for (PINDEX i = 0; i < sequence.GetSize(); i++)
sequence[i].Encode(buffer);
}
BOOL PASNSequence::Encode(PBYTEArray & buffer, PINDEX maxLen)
{
// calculate the length of the sequence, if it hasn't already been done
if (encodedLen == 0)
(void)GetEncodedLength();
// create the header for the sequence. Note that seqLen was calculated
// by the call to GetEncodedLength above
EncodeASNSequenceStart(buffer, type, seqLen);
// now encode the sequence itself
for (PINDEX i = 0; i < sequence.GetSize(); i++) {
sequence[i].Encode(buffer);
if (buffer.GetSize() > maxLen)
return FALSE;
}
return TRUE;
}
WORD PASNSequence::GetEncodedLength()
{
// calculate the length of the sequence
if (encodedLen == 0) {
seqLen = 0;
for (PINDEX i = 0; i < sequence.GetSize(); i++)
seqLen = (WORD)(seqLen + sequence[i].GetEncodedLength());
encodedLen = (WORD)(GetASNSequenceStartLength(seqLen) + seqLen);
}
return encodedLen;
}
PASNObject::ASNType PASNSequence::GetType() const
{
return asnType;
}
int PASNSequence::GetChoice() const
{
return type;
}
PString PASNSequence::GetTypeAsString() const
{
return PString("Sequence");
}
PASNSequence::PASNSequence(const PBYTEArray & buffer)
{
PINDEX ptr = 0;
if (!Decode(buffer, ptr))
sequence.RemoveAll();
}
PASNSequence::PASNSequence(const PBYTEArray & buffer, PINDEX & ptr)
{
if (!Decode(buffer, ptr))
sequence.RemoveAll();
}
BOOL PASNSequence::Decode(const PBYTEArray & buffer, PINDEX & ptr)
{
PINDEX s = buffer.GetSize();
BYTE c;
// all sequences start with a sequence start
if (ptr >= s)
return FALSE;
// get the sequence header
c = buffer[ptr++];
if (c == (ASN_CONSTRUCTOR | ASN_SEQUENCE))
asnType = Sequence;
else if ((c & ~ASN_EXTENSION_ID) == (ASN_CONSTRUCTOR | ASN_CONTEXT)) {
type = (BYTE)(c & ASN_EXTENSION_ID);
asnType = Choice;
} else
return FALSE;
// get the sequence length
WORD len;
if (!DecodeASNLength(buffer, ptr, len))
return FALSE;
// check the length
if (ptr + len > s)
return FALSE;
// set new length
s = ptr + len;
// now decode the elements
BOOL ok = TRUE;
while (ptr < s && ok) {
c = buffer[ptr];
if ((c & ~ASN_EXTENSION_ID) == (ASN_CONSTRUCTOR | ASN_CONTEXT))
sequence.Append(new PASNSequence(buffer, ptr));
else switch (c) {
// Integer
case ASN_INTEGER | ASN_UNIVERSAL | ASN_PRIMITIVE:
sequence.Append(new PASNInteger(buffer, ptr));
break;
// Octet String
case ASN_OCTET_STR | ASN_UNIVERSAL | ASN_PRIMITIVE:
sequence.Append(new PASNString(buffer, ptr));
break;
// NULL
case ASN_NULL | ASN_UNIVERSAL | ASN_PRIMITIVE:
sequence.Append(new PASNNull(buffer, ptr));
break;
// Object ID
case ASN_OBJECT_ID | ASN_UNIVERSAL | ASN_PRIMITIVE:
sequence.Append(new PASNObjectID(buffer, ptr));
break;
// Sequence
case ASN_CONSTRUCTOR | ASN_SEQUENCE:
sequence.Append(new PASNSequence(buffer, ptr));
break;
// TimeTicks
case ASN_APPLICATION | 3:
sequence.Append(new PASNTimeTicks(buffer, ptr));
break;
// Counter
case ASN_APPLICATION | 1:
sequence.Append(new PASNCounter(buffer, ptr));
break;
// Gauge
case ASN_APPLICATION | 2:
sequence.Append(new PASNGauge(buffer, ptr));
break;
// IP Address
case ASN_APPLICATION | 0:
sequence.Append(new PASNIPAddress(buffer, ptr));
break;
default:
return TRUE;
}
}
return ok;
}
PINDEX PASNSequence::GetSize() const
{
return sequence.GetSize();
}
PASNObject & PASNSequence::operator [] (PINDEX idx) const
{
return sequence[idx];
}
const PASNSequence & PASNSequence::GetSequence() const
{
return *this;
}
PString PASNTimeTicks::GetTypeAsString() const
{
return PString("TimeTicks");
}
PString PASNCounter::GetTypeAsString() const
{
return PString("Counter");
}
PString PASNGauge::GetTypeAsString() const
{
return PString("Gauge");
}
PString PASNIPAddress::GetTypeAsString() const
{
return PString("IPAddress");
}
PString PASNIPAddress::GetString() const
{
PINDEX len = value.GetSize();
if (len == 0)
return "(empty)";
if (len < 4) {
PString out = "Hex";
for (PINDEX i = 0; i < len; i++)
out &= psprintf("%02x", (BYTE)value[i]);
return out;
}
return psprintf("%i.%i.%i.%i",
(BYTE)value[0], (BYTE)value[1],
(BYTE)value[2], (BYTE)value[3]);
}
PASNIPAddress::PASNIPAddress(const PString & str)
: PASNString("")
{
value.SetSize(4);
PIPSocket::Address addr;
if (!PIPSocket::GetHostAddress(str, addr))
addr = 0;
int i;
for (i = 0; i < 4; i++)
value[i] = addr[i];
valueLen = 4;
}
PIPSocket::Address PASNIPAddress::GetIPAddress () const
{
return PIPSocket::Address((BYTE)value[0], (BYTE)value[1],
(BYTE)value[2], (BYTE)value[3]);
}
PASNNull::PASNNull()
{
}
PASNNull::PASNNull(const PBYTEArray & buffer, PINDEX & ptr)
{
PAssert(((buffer.GetSize() - ptr) >= 2) &&
(buffer[ptr+0] == 0x05) &&
(buffer[ptr+1] == 0x00),
"Attempt to decode non-null");
ptr += 2 ;
}
void PASNNull::PrintOn(ostream & strm) const
{
strm << "Null"
<< endl;
}
void PASNNull::Encode(PBYTEArray & buffer)
{
EncodeASNHeader(buffer, Null, 0);
}
WORD PASNNull::GetEncodedLength()
{
return 2;
}
PObject * PASNNull::Clone() const
{
return new PASNNull();
}
PASNObject::ASNType PASNNull::GetType() const
{
return Null;
}
PString PASNNull::GetTypeAsString() const
{
return PString("Null");
}
PString PASNNull::GetString() const
{
return PString();
}
// End Of File ///////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -