📄 pasn.cxx
字号:
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 + -