📄 asnper.cxx
字号:
if (!strm.MultiBitDecode(8, theBits))
return FALSE;
value[0] = (BYTE)theBits;
if (!strm.MultiBitDecode(8, theBits))
return FALSE;
value[1] = (BYTE)theBits;
break;
default: // 16.7
return strm.BlockDecode(value.GetPointer(), nBytes) == nBytes;
}
return TRUE;
}
void PASN_OctetString::EncodePER(PPER_Stream & strm) const
{
// X.691 Section 16
PINDEX nBytes = value.GetSize();
ConstrainedLengthEncode(strm, nBytes);
if ((int)upperLimit != lowerLimit) {
strm.BlockEncode(value, nBytes);
return;
}
switch (nBytes) {
case 0 : // 16.5
break;
case 1 : // 16.6
strm.MultiBitEncode(value[0], 8);
break;
case 2 : // 16.6
strm.MultiBitEncode(value[0], 8);
strm.MultiBitEncode(value[1], 8);
break;
default: // 16.7
strm.BlockEncode(value, nBytes);
}
}
BOOL PPER_Stream::OctetStringDecode(PASN_OctetString & value)
{
return value.DecodePER(*this);
}
void PPER_Stream::OctetStringEncode(const PASN_OctetString & value)
{
value.EncodePER(*this);
}
///////////////////////////////////////////////////////////////////////
BOOL PASN_ConstrainedString::DecodePER(PPER_Stream & strm)
{
// X.691 Section 26
unsigned len;
if (!ConstrainedLengthDecode(strm, len))
return FALSE;
if (len == 0) { // 10.9.3.3
value.SetSize(1);
value[0] = '\0';
return TRUE;
}
unsigned nBits = strm.IsAligned() ? charSetAlignedBits : charSetUnalignedBits;
unsigned totalBits = upperLimit*nBits;
if (constraint == Unconstrained ||
(lowerLimit == (int)upperLimit ? (totalBits > 16) : (totalBits >= 16))) {
if (nBits == 8)
return strm.BlockDecode((BYTE *)value.GetPointer(len+1), len) == len;
if (strm.IsAligned())
strm.ByteAlign();
}
if ((PINDEX)len > MaximumStringSize)
return FALSE;
if (!value.SetSize(len+1))
return FALSE;
PINDEX i;
for (i = 0; i < (PINDEX)len; i++) {
unsigned theBits;
if (!strm.MultiBitDecode(nBits, theBits))
return FALSE;
if (nBits >= canonicalSetBits && canonicalSetBits > 4)
value[i] = (char)theBits;
else
value[i] = characterSet[(PINDEX)theBits];
}
value[i] = '\0';
return TRUE;
}
void PASN_ConstrainedString::EncodePER(PPER_Stream & strm) const
{
// X.691 Section 26
PINDEX len = value.GetSize()-1;
ConstrainedLengthEncode(strm, len);
if (len == 0) // 10.9.3.3
return;
unsigned nBits = strm.IsAligned() ? charSetAlignedBits : charSetUnalignedBits;
unsigned totalBits = upperLimit*nBits;
if (constraint == Unconstrained ||
(lowerLimit == (int)upperLimit ? (totalBits > 16) : (totalBits >= 16))) {
// 26.5.7
if (nBits == 8) {
strm.BlockEncode((const BYTE *)(const char *)value, len);
return;
}
if (strm.IsAligned())
strm.ByteAlign();
}
for (PINDEX i = 0; i < len; i++) {
if (nBits >= canonicalSetBits && canonicalSetBits > 4)
strm.MultiBitEncode(value[i], nBits);
else {
const void * ptr = memchr(characterSet, value[i], characterSet.GetSize());
PINDEX pos = 0;
if (ptr != NULL)
pos = ((const char *)ptr - (const char *)characterSet);
strm.MultiBitEncode(pos, nBits);
}
}
}
///////////////////////////////////////////////////////////////////////
BOOL PPER_Stream::ConstrainedStringDecode(PASN_ConstrainedString & value)
{
return value.DecodePER(*this);
}
void PPER_Stream::ConstrainedStringEncode(const PASN_ConstrainedString & value)
{
value.EncodePER(*this);
}
///////////////////////////////////////////////////////////////////////
BOOL PASN_BMPString::DecodePER(PPER_Stream & strm)
{
// X.691 Section 26
unsigned len;
if (!ConstrainedLengthDecode(strm, len))
return FALSE;
if ((PINDEX)len > MaximumStringSize)
return FALSE;
if (!value.SetSize(len))
return FALSE;
PINDEX nBits = strm.IsAligned() ? charSetAlignedBits : charSetUnalignedBits;
if ((constraint == Unconstrained || upperLimit*nBits > 16) && strm.IsAligned())
strm.ByteAlign();
for (PINDEX i = 0; i < (PINDEX)len; i++) {
unsigned theBits;
if (!strm.MultiBitDecode(nBits, theBits))
return FALSE;
if (characterSet.IsEmpty())
value[i] = (WORD)(theBits + firstChar);
else
value[i] = characterSet[(PINDEX)theBits];
}
return TRUE;
}
void PASN_BMPString::EncodePER(PPER_Stream & strm) const
{
// X.691 Section 26
PINDEX len = value.GetSize();
ConstrainedLengthEncode(strm, len);
PINDEX nBits = strm.IsAligned() ? charSetAlignedBits : charSetUnalignedBits;
if ((constraint == Unconstrained || upperLimit*nBits > 16) && strm.IsAligned())
strm.ByteAlign();
for (PINDEX i = 0; i < len; i++) {
if (characterSet.IsEmpty())
strm.MultiBitEncode(value[i] - firstChar, nBits);
else {
for (PINDEX pos = 0; pos < characterSet.GetSize(); pos++) {
if (characterSet[pos] == value[i]) {
strm.MultiBitEncode(pos, nBits);
break;
}
}
}
}
}
BOOL PPER_Stream::BMPStringDecode(PASN_BMPString & value)
{
return value.DecodePER(*this);
}
void PPER_Stream::BMPStringEncode(const PASN_BMPString & value)
{
value.EncodePER(*this);
}
///////////////////////////////////////////////////////////////////////
BOOL PASN_Choice::DecodePER(PPER_Stream & strm)
{
// X.691 Section 22
delete choice;
choice = NULL;
if (strm.IsAtEnd())
return FALSE;
if (extendable) {
if (strm.SingleBitDecode()) {
if (!strm.SmallUnsignedDecode(tag))
return FALSE;
tag += numChoices;
unsigned len;
if (!strm.LengthDecode(0, INT_MAX, len))
return FALSE;
BOOL ok;
if (CreateObject()) {
PINDEX nextPos = strm.GetPosition() + len;
ok = choice->Decode(strm);
strm.SetPosition(nextPos);
}
else {
PASN_OctetString * open_type = new PASN_OctetString;
open_type->SetConstraints(PASN_ConstrainedObject::FixedConstraint, len);
ok = open_type->Decode(strm);
if (open_type->GetSize() > 0)
choice = open_type;
else {
delete open_type;
ok = FALSE;
}
}
return ok;
}
}
if (numChoices < 2)
tag = 0;
else {
if (!strm.UnsignedDecode(0, numChoices-1, tag))
return FALSE;
}
return CreateObject() && choice->Decode(strm);
}
void PASN_Choice::EncodePER(PPER_Stream & strm) const
{
PAssert(CheckCreate(), PLogicError);
if (extendable) {
BOOL extended = tag >= numChoices;
strm.SingleBitEncode(extended);
if (extended) {
strm.SmallUnsignedEncode(tag - numChoices);
strm.AnyTypeEncode(choice);
return;
}
}
if (numChoices > 1)
strm.UnsignedEncode(tag, 0, numChoices-1);
choice->Encode(strm);
}
BOOL PPER_Stream::ChoiceDecode(PASN_Choice & value)
{
return value.DecodePER(*this);
}
void PPER_Stream::ChoiceEncode(const PASN_Choice & value)
{
value.EncodePER(*this);
}
///////////////////////////////////////////////////////////////////////
BOOL PASN_Sequence::PreambleDecodePER(PPER_Stream & strm)
{
// X.691 Section 18
if (extendable) {
if (strm.IsAtEnd())
return FALSE;
totalExtensions = strm.SingleBitDecode() ? -1 : 0; // 18.1
}
else
totalExtensions = 0;
return optionMap.Decode(strm); // 18.2
}
void PASN_Sequence::PreambleEncodePER(PPER_Stream & strm) const
{
// X.691 Section 18
if (extendable) {
BOOL hasExtensions = FALSE;
for (unsigned i = 0; i < extensionMap.GetSize(); i++) {
if (extensionMap[i]) {
hasExtensions = TRUE;
break;
}
}
strm.SingleBitEncode(hasExtensions); // 18.1
((PASN_Sequence*)this)->totalExtensions = hasExtensions ? -1 : 0;
}
optionMap.Encode(strm); // 18.2
}
BOOL PASN_Sequence::NoExtensionsToDecode(PPER_Stream & strm)
{
if (totalExtensions == 0)
return TRUE;
if (totalExtensions < 0) {
if (!extensionMap.DecodeSequenceExtensionBitmap(strm))
return FALSE;
totalExtensions = extensionMap.GetSize();
}
return FALSE;
}
BOOL PASN_Sequence::NoExtensionsToEncode(PPER_Stream & strm)
{
if (totalExtensions == 0)
return TRUE;
if (totalExtensions < 0) {
totalExtensions = extensionMap.GetSize();
extensionMap.EncodeSequenceExtensionBitmap(strm);
}
return FALSE;
}
BOOL PASN_Sequence::KnownExtensionDecodePER(PPER_Stream & strm, PINDEX fld, PASN_Object & field)
{
if (NoExtensionsToDecode(strm))
return TRUE;
if (!extensionMap[fld-optionMap.GetSize()])
return TRUE;
unsigned len;
if (!strm.LengthDecode(0, INT_MAX, len))
return FALSE;
PINDEX nextExtensionPosition = strm.GetPosition() + len;
BOOL ok = field.Decode(strm);
strm.SetPosition(nextExtensionPosition);
return ok;
}
void PASN_Sequence::KnownExtensionEncodePER(PPER_Stream & strm, PINDEX fld, const PASN_Object & field) const
{
if (((PASN_Sequence*)this)->NoExtensionsToEncode(strm))
return;
if (!extensionMap[fld-optionMap.GetSize()])
return;
strm.AnyTypeEncode(&field);
}
BOOL PASN_Sequence::UnknownExtensionsDecodePER(PPER_Stream & strm)
{
if (NoExtensionsToDecode(strm))
return TRUE;
if (totalExtensions <= knownExtensions)
return TRUE; // Already read them
PINDEX unknownCount = totalExtensions - knownExtensions;
if (fields.GetSize() >= unknownCount)
return TRUE; // Already read them
if (unknownCount > MaximumArraySize)
return FALSE;
if (!fields.SetSize(unknownCount))
return FALSE;
PINDEX i;
for (i = 0; i < fields.GetSize(); i++)
fields.SetAt(i, new PASN_OctetString);
for (i = knownExtensions; i < (PINDEX)extensionMap.GetSize(); i++) {
if (extensionMap[i])
if (!fields[i-knownExtensions].Decode(strm))
return FALSE;
}
return TRUE;
}
void PASN_Sequence::UnknownExtensionsEncodePER(PPER_Stream & strm) const
{
if (((PASN_Sequence*)this)->NoExtensionsToEncode(strm))
return;
int i;
for (i = knownExtensions; i < totalExtensions; i++) {
if (extensionMap[i]) {
PINDEX f = i - knownExtensions;
if (f < fields.GetSize())
fields[f].Encode(strm);
else {
PASN_OctetString dummy;
dummy.Encode(strm);
}
}
}
}
BOOL PPER_Stream::SequencePreambleDecode(PASN_Sequence & seq)
{
return seq.PreambleDecodePER(*this);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -