⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asnper.cxx

📁 开源代码的pwlib的1.10.0版本,使用openh323的1.18.0版本毕备
💻 CXX
📖 第 1 页 / 共 3 页
字号:
/*
 * asnper.cxx
 *
 * Abstract Syntax Notation 1 Encoding Rules
 *
 * Portable Windows Library
 *
 * $Log: asnper.cxx,v $
 * Revision 1.10  2004/07/11 12:33:47  csoutheren
 * Added guards against illegal PDU values causing crashes
 *
 * Revision 1.9  2004/03/23 04:53:57  csoutheren
 * Fixed problem with incorrect encoding of ASN NULL under some circumstances
 * Thanks to Ed Day of Objective Systems
 *
 * Revision 1.8  2004/01/17 17:43:42  csoutheren
 * Fixed problem with the upper limit on various constrained types not being correctly enforced
 *
 * Revision 1.7  2004/01/17 09:23:43  csoutheren
 * Fixed problem with the upper limit on constrained unsigned integers not being correctly enforced
 *
 * Revision 1.6  2003/12/14 10:21:29  rjongbloed
 * Fixed bug in length incorrectlty decoded from ASN and (apparently) rare circumstances. Thanks pangxg@hotmail.com.
 * Cleaned up return values to be BOOL rather than int for some functions.
 *
 * Revision 1.5  2003/12/03 03:50:03  csoutheren
 * Reversed last change as it broke decoding in some circumstances
 *
 *
 */

///////////////////////////////////////////////////////////////////////

BOOL PPER_Stream::NullDecode(PASN_Null &)
{
  return TRUE;
}


void PPER_Stream::NullEncode(const PASN_Null &)
{
}

///////////////////////////////////////////////////////////////////////

BOOL PASN_ConstrainedObject::ConstrainedLengthDecode(PPER_Stream & strm, unsigned & length)
{
  // The execution order is important in the following. The SingleBitDecode() function
  // must be called if extendable is TRUE, no matter what.
  if ((extendable && strm.SingleBitDecode()) || constraint == Unconstrained)
    return strm.LengthDecode(0, INT_MAX, length);
  else
    return strm.LengthDecode(lowerLimit, upperLimit, length);
}


void PASN_ConstrainedObject::ConstrainedLengthEncode(PPER_Stream & strm, unsigned length) const
{
  if (ConstraintEncode(strm, length)) // 26.4
    strm.LengthEncode(length, 0, INT_MAX);
  else
    strm.LengthEncode(length, lowerLimit, upperLimit);
}


BOOL PASN_ConstrainedObject::ConstraintEncode(PPER_Stream & strm, unsigned value) const
{
  if (!extendable)
    return constraint != FixedConstraint;

  BOOL needsExtending = value > upperLimit;

  if (!needsExtending) {
    if (lowerLimit < 0) {
      if ((int)value < lowerLimit)
        needsExtending = TRUE;
    }
    else {
      if (value < (unsigned)lowerLimit)
        needsExtending = TRUE;
    }
  }

  strm.SingleBitEncode(needsExtending);

  return needsExtending;
}

///////////////////////////////////////////////////////////////////////

BOOL PPER_Stream::BooleanDecode(PASN_Boolean & value)
{
  if (IsAtEnd())
    return FALSE;

  // X.691 Section 11
  value = (BOOL)SingleBitDecode();
  return TRUE;
}


void PPER_Stream::BooleanEncode(const PASN_Boolean & value)
{
  // X.691 Section 11
  SingleBitEncode((BOOL)value);
}

BOOL PPER_Stream::IntegerDecode(PASN_Integer & value)
{
  return value.DecodePER(*this);
}


void PPER_Stream::IntegerEncode(const PASN_Integer & value)
{
  value.EncodePER(*this);
}

///////////////////////////////////////////////////////////////////////

BOOL PASN_Integer::DecodePER(PPER_Stream & strm)
{
  // X.691 Sections 12

  switch (constraint) {
    case FixedConstraint : // 12.2.1 & 12.2.2
      break;

    case ExtendableConstraint :
      if (!strm.SingleBitDecode()) //  12.1
        break;
      // Fall into default case for unconstrained or partially constrained

    default : // 12.2.6
      unsigned len;
      if (!strm.LengthDecode(0, INT_MAX, len))
        return FALSE;

      len *= 8;
      if (!strm.MultiBitDecode(len, value))
        return FALSE;

      if (IsUnsigned())
        value += lowerLimit;
      else if ((value&(1<<(len-1))) != 0) // Negative
        value |= UINT_MAX << len;         // Sign extend
      return TRUE;
  }

  if ((unsigned)lowerLimit != upperLimit)  // 12.2.2
    return strm.UnsignedDecode(lowerLimit, upperLimit, value); // which devolves to 10.5

  // 12.2.1
  value = lowerLimit;
  return TRUE;
}


void PASN_Integer::EncodePER(PPER_Stream & strm) const
{
  // X.691 Sections 12

  //  12.1
  if (ConstraintEncode(strm, (int)value)) {
    // 12.2.6
    unsigned adjusted_value = value - lowerLimit;

    PINDEX nBits = 1; // Allow for sign bit
    if (IsUnsigned())
      nBits = CountBits(adjusted_value+1);
    else if ((int)adjusted_value > 0)
      nBits += CountBits(adjusted_value+1);
    else
      nBits += CountBits(-(int)adjusted_value+1);

    // Round up to nearest number of whole octets
    PINDEX nBytes = (nBits+7)/8;
    strm.LengthEncode(nBytes, 0, INT_MAX);
    strm.MultiBitEncode(adjusted_value, nBytes*8);
    return;
  }

  if ((unsigned)lowerLimit == upperLimit) // 12.2.1
    return;

  // 12.2.2 which devolves to 10.5
  strm.UnsignedEncode(value, lowerLimit, upperLimit);
}

///////////////////////////////////////////////////////////////////////

BOOL PPER_Stream::EnumerationDecode(PASN_Enumeration & value)
{
  return value.DecodePER(*this);
}


void PPER_Stream::EnumerationEncode(const PASN_Enumeration & value)
{
  value.EncodePER(*this);
}


BOOL PASN_Enumeration::DecodePER(PPER_Stream & strm)
{
  // X.691 Section 13

  if (extendable) {  // 13.3
    if (strm.SingleBitDecode()) {
      unsigned len = 0;
      return strm.SmallUnsignedDecode(len) &&
             len > 0 &&
             strm.UnsignedDecode(0, len-1, value);
    }
  }

  return strm.UnsignedDecode(0, maxEnumValue, value);  // 13.2
}


void PASN_Enumeration::EncodePER(PPER_Stream & strm) const
{
  // X.691 Section 13

  if (extendable) {  // 13.3
    BOOL extended = value > maxEnumValue;
    strm.SingleBitEncode(extended);
    if (extended) {
      strm.SmallUnsignedEncode(1+value);
      strm.UnsignedEncode(value, 0, value);
      return;
    }
  }

  strm.UnsignedEncode(value, 0, maxEnumValue);  // 13.2
}

///////////////////////////////////////////////////////////////////////

BOOL PPER_Stream::RealDecode(PASN_Real &)
{
  // X.691 Section 14

  if (IsAtEnd())
    return FALSE;

  unsigned len;
  if (!MultiBitDecode(8, len))
    return FALSE;

  PAssertAlways(PUnimplementedFunction);
  byteOffset += len+1;
  return TRUE;
}


void PPER_Stream::RealEncode(const PASN_Real &)
{
  // X.691 Section 14

  MultiBitEncode(0, 8);
  PAssertAlways(PUnimplementedFunction);
  MultiBitEncode(0, 8);
}

///////////////////////////////////////////////////////////////////////

BOOL PPER_Stream::ObjectIdDecode(PASN_ObjectId & value)
{
  // X.691 Section 23

  unsigned dataLen;
  if (!LengthDecode(0, 255, dataLen))
    return FALSE;

  ByteAlign();
  return value.CommonDecode(*this, dataLen);
}


void PPER_Stream::ObjectIdEncode(const PASN_ObjectId & value)
{
  // X.691 Section 23

  PBYTEArray eObjId;
  value.CommonEncode(eObjId);
  LengthEncode(eObjId.GetSize(), 0, 255);
  BlockEncode(eObjId, eObjId.GetSize());
}

///////////////////////////////////////////////////////////////////////

BOOL PASN_BitString::DecodeSequenceExtensionBitmap(PPER_Stream & strm)
{
  if (!strm.SmallUnsignedDecode(totalBits))
    return FALSE;

  totalBits++;

  if (!SetSize(totalBits))
    return FALSE;

  if (totalBits > strm.GetBitsLeft())
    return FALSE;

  unsigned theBits;

  PINDEX idx = 0;
  unsigned bitsLeft = totalBits;
  while (bitsLeft >= 8) {
    if (!strm.MultiBitDecode(8, theBits))
      return FALSE;
    bitData[idx++] = (BYTE)theBits;
    bitsLeft -= 8;
  }

  if (bitsLeft > 0) {
    if (!strm.MultiBitDecode(bitsLeft, theBits))
      return FALSE;
    bitData[idx] = (BYTE)(theBits << (8-bitsLeft));
  }

  return TRUE;
}


void PASN_BitString::EncodeSequenceExtensionBitmap(PPER_Stream & strm) const
{
  PAssert(totalBits > 0, PLogicError);

  unsigned bitsLeft = totalBits;
  while (bitsLeft > 1 && !(*this)[bitsLeft-1])
    bitsLeft--;

  strm.SmallUnsignedEncode(bitsLeft-1);

  PINDEX idx = 0;
  while (bitsLeft >= 8) {
    strm.MultiBitEncode(bitData[idx++], 8);
    bitsLeft -= 8;
  }

  if (bitsLeft > 0)
    strm.MultiBitEncode(bitData[idx] >> (8 - bitsLeft), bitsLeft);
}


BOOL PASN_BitString::DecodePER(PPER_Stream & strm)
{
  // X.691 Section 15

  if (!ConstrainedLengthDecode(strm, totalBits))
    return FALSE;

  if (!SetSize(totalBits))
    return FALSE;

  if (totalBits == 0)
    return TRUE;   // 15.7

  if (totalBits > strm.GetBitsLeft())
    return FALSE;

  if (totalBits > 16) {
    unsigned nBytes = (totalBits+7)/8;
    return strm.BlockDecode(bitData.GetPointer(), nBytes) == nBytes;   // 15.9
  }

  unsigned theBits;
  if (totalBits <= 8) {
    if (!strm.MultiBitDecode(totalBits, theBits))
      return FALSE;

    bitData[0] = (BYTE)(theBits << (8-totalBits));
  }
  else {  // 15.8
    if (!strm.MultiBitDecode(8, theBits))
      return FALSE;

    bitData[0] = (BYTE)theBits;

    if (!strm.MultiBitDecode(totalBits-8, theBits))
      return FALSE;

    bitData[1] = (BYTE)(theBits << (16-totalBits));
  }

  return TRUE;
}


void PASN_BitString::EncodePER(PPER_Stream & strm) const
{
  // X.691 Section 15

  ConstrainedLengthEncode(strm, totalBits);

  if (totalBits == 0)
    return;

  if (totalBits > 16)
    strm.BlockEncode(bitData, (totalBits+7)/8);   // 15.9
  else if (totalBits <= 8)  // 15.8
    strm.MultiBitEncode(bitData[0] >> (8 - totalBits), totalBits);
  else {
    strm.MultiBitEncode(bitData[0], 8);
    strm.MultiBitEncode(bitData[1] >> (16 - totalBits), totalBits-8);
  }
}

///////////////////////////////////////////////////////////////////////

BOOL PPER_Stream::BitStringDecode(PASN_BitString & value)
{
  return value.DecodePER(*this);
}


void PPER_Stream::BitStringEncode(const PASN_BitString & value)
{
  value.EncodePER(*this);
}

///////////////////////////////////////////////////////////////////////

BOOL PASN_OctetString::DecodeSubType(PASN_Object & obj) const
{
  PPER_Stream stream = GetValue();
  return obj.Decode(stream);
}


void PASN_OctetString::EncodeSubType(const PASN_Object & obj)
{
  PPER_Stream stream;
  obj.Encode(stream);
  stream.CompleteEncoding();
  SetValue(stream);
}

BOOL PASN_OctetString::DecodePER(PPER_Stream & strm)
{
  // X.691 Section 16

  unsigned nBytes;
  if (!ConstrainedLengthDecode(strm, nBytes))
    return FALSE;

  if (!SetSize(nBytes))   // 16.5
    return FALSE;

  if ((int)upperLimit != lowerLimit)
    return strm.BlockDecode(value.GetPointer(), nBytes) == nBytes;

  unsigned theBits;
  switch (nBytes) {
    case 0 :
      break;

    case 1 :  // 16.6
      if (!strm.MultiBitDecode(8, theBits))
        return FALSE;
      value[0] = (BYTE)theBits;
      break;

    case 2 :  // 16.6

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -