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

📄 pasn.cxx

📁 开源代码的pwlib的1.10.0版本,使用openh323的1.18.0版本毕备
💻 CXX
📖 第 1 页 / 共 2 页
字号:

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 + -