📄 asner.cxx
字号:
/*
* 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 < 40) {
value[0] = 0;
value[1] = subId;
}
else if (subId < 80) {
value[0] = 1;
value[1] = subId-40;
}
else {
value[0] = 2;
value[1] = subId-80;
}
return TRUE;
}
void PASN_ObjectId::CommonEncode(PBYTEArray & encodecObjectId) const
{
PINDEX length = value.GetSize();
const unsigned * objId = value;
if (length < 2) {
// Thise case is really illegal, but we have to do SOMETHING
encodecObjectId.SetSize(0);
return;
}
unsigned subId = (objId[0] * 40) + objId[1];
objId += 2;
PINDEX outputPosition = 0;
while (--length > 0) {
if (subId < 128)
encodecObjectId[outputPosition++] = (BYTE)subId;
else {
unsigned mask = 0x7F; /* handle subid == 0 case */
int bits = 0;
/* testmask *MUST* !!!! be of an unsigned type */
unsigned testmask = 0x7F;
int testbits = 0;
while (testmask != 0) {
if (subId & testmask) { /* if any bits set */
mask = testmask;
bits = testbits;
}
testmask <<= 7;
testbits += 7;
}
/* mask can't be zero here */
while (mask != 0x7F) {
/* fix a mask that got truncated above */
if (mask == 0x1E00000)
mask = 0xFE00000;
encodecObjectId[outputPosition++] = (BYTE)(((subId & mask) >> bits) | 0x80);
mask >>= 7;
bits -= 7;
}
encodecObjectId[outputPosition++] = (BYTE)(subId & mask);
}
if (length > 1)
subId = *objId++;
}
}
PINDEX PASN_ObjectId::GetDataLength() const
{
PBYTEArray dummy;
CommonEncode(dummy);
return dummy.GetSize();
}
BOOL PASN_ObjectId::Decode(PASN_Stream & strm)
{
return strm.ObjectIdDecode(*this);
}
void PASN_ObjectId::Encode(PASN_Stream & strm) const
{
strm.ObjectIdEncode(*this);
}
///////////////////////////////////////////////////////////////////////
PASN_BitString::PASN_BitString(unsigned nBits, const BYTE * buf)
: PASN_ConstrainedObject(UniversalBitString, UniversalTagClass),
totalBits(nBits),
bitData((totalBits+7)/8)
{
if (buf != NULL)
memcpy(bitData.GetPointer(), buf, bitData.GetSize());
}
PASN_BitString::PASN_BitString(unsigned tag, TagClass tagClass, unsigned nBits)
: PASN_ConstrainedObject(tag, tagClass),
totalBits(nBits),
bitData((totalBits+7)/8)
{
}
PASN_BitString::PASN_BitString(const PASN_BitString & other)
: PASN_ConstrainedObject(other),
bitData(other.bitData, other.bitData.GetSize())
{
totalBits = other.totalBits;
}
PASN_BitString & PASN_BitString::operator=(const PASN_BitString & other)
{
PASN_ConstrainedObject::operator=(other);
totalBits = other.totalBits;
bitData = PBYTEArray(other.bitData, other.bitData.GetSize());
return *this;
}
void PASN_BitString::SetData(unsigned nBits, const PBYTEArray & bytes)
{
if ((PINDEX)nBits >= MaximumStringSize)
return;
bitData = bytes;
SetSize(nBits);
}
void PASN_BitString::SetData(unsigned nBits, const BYTE * buf, PINDEX size)
{
if ((PINDEX)nBits >= MaximumStringSize)
return;
if (size == 0)
size = (nBits+7)/8;
memcpy(bitData.GetPointer(size), buf, size);
SetSize(nBits);
}
BOOL PASN_BitString::SetSize(unsigned nBits)
{
if (!CheckByteOffset(nBits))
return FALSE;
if (constraint == Unconstrained)
totalBits = nBits;
else if (totalBits < (unsigned)lowerLimit) {
if (lowerLimit < 0)
return FALSE;
totalBits = lowerLimit;
} else if ((unsigned)totalBits > upperLimit) {
if (upperLimit > (unsigned)MaximumSetSize)
return FALSE;
totalBits = upperLimit;
} else
totalBits = nBits;
return bitData.SetSize((totalBits+7)/8);
}
bool PASN_BitString::operator[](PINDEX bit) const
{
if ((unsigned)bit < totalBits)
return (bitData[bit>>3] & (1 << (7 - (bit&7)))) != 0;
return FALSE;
}
void PASN_BitString::Set(unsigned bit)
{
if (bit < totalBits)
bitData[(PINDEX)(bit>>3)] |= 1 << (7 - (bit&7));
}
void PASN_BitString::Clear(unsigned bit)
{
if (bit < totalBits)
bitData[(PINDEX)(bit>>3)] &= ~(1 << (7 - (bit&7)));
}
void PASN_BitString::Invert(unsigned bit)
{
if (bit < totalBits)
bitData[(PINDEX)(bit>>3)] ^= 1 << (7 - (bit&7));
}
PObject::Comparison PASN_BitString::Compare(const PObject & obj) const
{
PAssert(PIsDescendant(&obj, PASN_BitString), PInvalidCast);
const PASN_BitString & other = (const PASN_BitString &)obj;
if (totalBits < other.totalBits)
return LessThan;
if (totalBits > other.totalBits)
return GreaterThan;
return bitData.Compare(other.bitData);
}
PObject * PASN_BitString::Clone() const
{
PAssert(IsClass(PASN_BitString::Class()), PInvalidCast);
return new PASN_BitString(*this);
}
void PASN_BitString::PrintOn(ostream & strm) const
{
int indent = strm.precision() + 2;
_Ios_Fmtflags flags = strm.flags();
if (totalBits > 128)
strm << "Hex {\n"
<< hex << setfill('0') << resetiosflags(ios::floatfield) << setiosflags(ios::fixed)
<< setw(16) << setprecision(indent) << bitData
<< dec << setfill(' ') << resetiosflags(ios::floatfield)
<< setw(indent-1) << "}";
else if (totalBits > 32)
strm << "Hex:"
<< hex << setfill('0') << resetiosflags(ios::floatfield) << setiosflags(ios::fixed)
<< setprecision(2) << setw(16) << bitData
<< dec << setfill(' ') << resetiosflags(ios::floatfield);
else {
BYTE mask = 0x80;
PINDEX offset = 0;
for (unsigned i = 0; i < totalBits; i++) {
strm << ((bitData[offset]&mask) != 0 ? '1' : '0');
mask >>= 1;
if (mask == 0) {
mask = 0x80;
offset++;
}
}
}
strm.flags(flags);
}
void PASN_BitString::SetConstraintBounds(ConstraintType type, int lower, unsigned upper)
{
if (lower < 0)
return;
PASN_ConstrainedObject::SetConstraintBounds(type, lower, upper);
SetSize(GetSize());
}
PString PASN_BitString::GetTypeAsString() const
{
return "Bit String";
}
PINDEX PASN_BitString::GetDataLength() const
{
return (totalBits+7)/8 + 1;
}
BOOL PASN_BitString::Decode(PASN_Stream & strm)
{
return strm.BitStringDecode(*this);
}
void PASN_BitString::Encode(PASN_Stream & strm) const
{
strm.BitStringEncode(*this);
}
///////////////////////////////////////////////////////////////////////
PASN_OctetString::PASN_OctetString(const char * str, PINDEX size)
: PASN_ConstrainedObject(UniversalOctetString, UniversalTagClass)
{
if (str != NULL) {
if (size == 0)
size = ::strlen(str);
SetValue((const BYTE *)str, size);
}
}
PASN_OctetString::PASN_OctetString(unsigned tag, TagClass tagClass)
: PASN_ConstrainedObject(tag, tagClass)
{
}
PASN_OctetString::PASN_OctetString(const PASN_OctetString & other)
: PASN_ConstrainedObject(other),
value(other.value, other.GetSize())
{
}
PASN_OctetString & PASN_OctetString::operator=(const PASN_OctetString & other)
{
PASN_ConstrainedObject::operator=(other);
value = PBYTEArray(other.value, other.GetSize());
return *this;
}
PASN_OctetString & PASN_OctetString::operator=(const char * str)
{
if (str == NULL)
value.SetSize(lowerLimit);
else
SetValue((const BYTE *)str, strlen(str));
return *this;
}
PASN_OctetString & PASN_OctetString::operator=(const PString & str)
{
SetValue((const BYTE *)(const char *)str, str.GetSize()-1);
return *this;
}
PASN_OctetString & PASN_OctetString::operator=(const PBYTEArray & arr)
{
PINDEX len = arr.GetSize();
if ((unsigned)len > upperLimit || (int)len < lowerLimit)
SetValue(arr, len);
else
value = arr;
return *this;
}
void PASN_OctetString::SetValue(const BYTE * data, PINDEX len)
{
if ((unsigned)len > upperLimit)
len = upperLimit;
if (SetSize((int)len < lowerLimit ? lowerLimit : len))
memcpy(value.GetPointer(), data, len);
}
PString PASN_OctetString::AsString() const
{
if (value.IsEmpty())
return PString();
return PString((const char *)(const BYTE *)value, value.GetSize());
}
PObject::Comparison PASN_OctetString::Compare(const PObject & obj) const
{
PAssert(PIsDescendant(&obj, PASN_OctetString), PInvalidCast);
const PASN_OctetString & other = (const PASN_OctetString &)obj;
return value.Compare(other.value);
}
PObject * PASN_OctetString::Clone() const
{
PAssert(IsClass(PASN_OctetString::Class()), PInvalidCast);
return new PASN_OctetString(*this);
}
void PASN_OctetString::PrintOn(ostream & strm) const
{
int indent = strm.precision() + 2;
_Ios_Fmtflags flags = strm.flags();
strm << ' ' << value.GetSize() << " octets {\n"
<< hex << setfill('0') << resetiosflags(ios::floatfield)
<< setprecision(indent) << setw(16);
if (value.GetSize() <= 32 || (flags&ios::floatfield) != ios::fixed)
strm << value << '\n';
else {
PBYTEArray truncatedArray(value, 32);
strm << truncatedArray << '\n'
<< setfill(' ')
<< setw(indent+4) << "...\n";
}
strm << dec << setfill(' ')
<< setw(indent-1) << "}";
strm.flags(flags);
}
void PASN_OctetString::SetConstraintBounds(ConstraintType type, int lower, unsigned upper)
{
if (lower < 0)
return;
PASN_ConstrainedObject::SetConstraintBounds(type, lower, upper);
SetSize(GetSize());
}
PString PASN_OctetString::GetTypeAsString() const
{
return "Octet String";
}
PINDEX PASN_OctetString::GetDataLength() const
{
return value.GetSize();
}
BOOL PASN_OctetString::SetSize(PINDEX newSize)
{
if (!CheckByteOffset(newSize, MaximumStringSize))
return FALSE;
if (constraint != Unconstrained) {
if (newSize < (PINDEX)lowerLimit) {
if (lowerLimit < 0)
return FALSE;
newSize = lowerLimit;
} else if ((unsigned)newSize > upperLimit) {
if (upperLimit > (unsigned)MaximumStringSize)
return FALSE;
newSize = upperLimit;
}
}
return value.SetSize(newSize);
}
BOOL PASN_OctetString::Decode(PASN_Stream & strm)
{
return strm.OctetStringDecode(*this);
}
void PASN_OctetString::Encode(PASN_Stream & strm) const
{
strm.OctetStringEncode(*this);
}
///////////////////////////////////////////////////////////////////////
PASN_ConstrainedString::PASN_ConstrainedString(const char * canonical, PINDEX size,
unsigned tag, TagClass tagClass)
: PASN_ConstrainedObject(tag, tagClass)
{
canonicalSet = canonical;
canonicalSetSize = size;
canonicalSetBits = CountBits(size);
SetCharacterSet(canonicalSet, canonicalSetSize, Unconstrained);
}
PASN_ConstrainedString & PASN_ConstrainedString::operator=(const char * str)
{
if (str == NULL)
str = "";
PStringStream newValue;
PINDEX len = strlen(str);
// Can't copy any more characters than the upper constraint
if ((unsigned)len > upperLimit)
len = upperLimit;
// Now copy individual characters, if they are in character set constraint
for (PINDEX i = 0; i < len; i++) {
PINDEX sz = characterSet.GetSize();
if (sz == 0 || memchr(characterSet, str[i], sz) != NULL)
newValue << str[i];
}
// Make sure string meets minimum length constraint
while ((int)len < lowerLimit) {
newValue << characterSet[0];
len++;
}
value = newValue;
value.MakeMinimumSize();
return *this;
}
void PASN_ConstrainedString::SetCharacterSet(ConstraintType ctype, const char * set)
{
SetCharacterSet(set, strlen(set), ctype);
}
void PASN_ConstrainedString::SetCharacterSet(ConstraintType ctype, unsigned firstChar, unsigned lastChar)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -