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

📄 perencoder.cxx

📁 asn格式文件的编译器
💻 CXX
字号:
/* * PEREncoder.cxx * * Abstract Syntax Notation 1 Encoding Rules * * Copyright (c) 1993-1998 Equivalence Pty. Ltd. * * Copyright (c) 2001 Institute for Information Industry, Taiwan, Republic of China  * (http://www.iii.org.tw/iiia/ewelcome.htm) * * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is Portable Windows Library. * * The Initial Developer of the Original Code is Equivalence Pty. Ltd. * * Portions are Copyright (C) 1993 Free Software Foundation, Inc. * All Rights Reserved. * * Contributor(s): Huang-Ming Huang * * The code is adapted from asner.cxx of PWLib, but the dependancy on PWLib has * been removed. * * $Log: PEREncoder.cxx,v $ * Revision 1.7  2002/07/19 05:48:07  btrummer * If an illegal character is found in do_visit(const AbstractString&), * false is returned now to abort the encoding. * * Revision 1.6  2002/07/19 05:43:39  btrummer * Aaargh! If encodeConstrainedLength() fails in do_visit(const OCTET_STRING&), * false must be returned rather than true. * * Revision 1.5  2002/07/18 10:42:17  btrummer * Removed the assert statement from do_visit(const OCTET_STRING& value). * Replaced the assert in do_visit(const CHOICE& value) with an if-clause. * * Revision 1.4  2002/07/18 06:53:33  btrummer * Added range checks for PEREncoder's encodeLength(), encodeUnsigned() * and encodeConstrainedLength(). Encoding an object which violates its * length constraint will fail now. * * Revision 1.3  2002/07/02 04:45:13  mangelo * Modify for VC.Net and GCC 3.1 * * Revision 1.2  2001/10/05 19:11:50  mangelo * Added Log * * 2001/06/26 Huang-Ming Huang  * Version 2.1 Reimplemented to minimize the code size. * * 2001/05/01 * Fixed problem with en/decoding more than 16 extension fields in a sequence  * in accordance with PWLib asner.cxx Revision 1.41. *  */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include "asn1.h"namespace ASN1 {extern unsigned CountBits(unsigned range);void PEREncoder::encodeBitMap(const std::vector<char>& bitData, unsigned nBits){    int idx = 0;    unsigned bitsLeft = nBits;    while (bitsLeft >= 8) {        encodeMultiBit(bitData[idx++],8);        bitsLeft -= 8;    }        if (bitsLeft > 0)        encodeMultiBit(bitData[idx] >> (8 - bitsLeft),bitsLeft);}inline void PEREncoder::byteAlign(){    if (bitOffset != 8)        bitOffset = 8;}bool PEREncoder::do_visit(const Null&){	return true;}bool PEREncoder::do_visit(const BOOLEAN& value){  // X.931 Section 11  encodeSingleBit((bool)value);  return true;}bool PEREncoder::do_visit(const INTEGER& integer){  // X.931 Sections 12  unsigned value = (unsigned) integer.getValue();  if (encodeConstraint(integer, (int)value)) { //  12.1    unsigned nBytes;    unsigned adjusted_value = (integer.getConstraintType() == FixedConstraint ? 								value - integer.getLowerLimit() : value);	unsigned nBits;    if (adjusted_value == 0)      nBits = 1;    else if (integer.getConstraintType() != FixedConstraint )		if ((int)value < 0)			nBits = CountBits( (~value) +1);		else			nBits = CountBits(value+1) +1;	else      nBits = CountBits(adjusted_value+1);    nBytes = (nBits+7)/8;    encodeLength(nBytes, 0, INT_MAX);    encodeMultiBit(adjusted_value, nBytes*8);    return true;  }    if (static_cast<unsigned>(integer.getLowerLimit()) == integer.getUpperLimit()) // 12.2.1    return true;  // 12.2.2 which devolves to 10.5  return encodeUnsigned(value, integer.getLowerLimit(), integer.getUpperLimit());}bool PEREncoder::do_visit(const ENUMERATED& value){  if (value.extendable()) {  // 13.3    bool extended = value.asInt() > value.getMaximum();    encodeSingleBit(extended);    if (extended) {      encodeSmallUnsigned(1+value.asInt());      return encodeUnsigned(value.asInt(), 0, value.asInt());    }  }  return encodeUnsigned(value.asInt(), 0, value.getMaximum());  // 13.2}bool PEREncoder::do_visit(const OBJECT_IDENTIFIER& value){  // X.691 Section 23  std::vector<char> eObjId;  value.encodeCommon(eObjId);  if (!encodeLength(eObjId.size(), 0, 255))    return false;  encodeBlock(&eObjId.front(), eObjId.size());  return true;}bool PEREncoder::do_visit(const BIT_STRING& value){  // X.691 Section 15  if (!encodeConstrainedLength(value, value.size()))    return false;  if (value.size() == 0)    return true;  if (value.size() > 16 && aligned())    encodeBlock(&*value.getData().begin(), (value.size()+7)/8);   // 15.9  else {// 15.8    encodeBitMap(value.getData(), value.size());  }  return true;}bool PEREncoder::do_visit(const OCTET_STRING& value){  // X.691 Section 16  unsigned nBytes = value.size();  if (!encodeConstrainedLength(value, nBytes))    return false;  switch (nBytes) {    case 0 :  // 16.5      break;    case 1 :  // 16.6      encodeMultiBit(value[0], 8);      break;    case 2 :  // 16.6      encodeMultiBit(value[0], 8);      encodeMultiBit(value[1], 8);      break;    default: // 16.7      encodeBlock(&*value.begin(), nBytes);  }  return true;}bool PEREncoder::do_visit(const AbstractString& value){  // X.691 Section 26  unsigned len = value.size();  if (!encodeConstrainedLength(value, len))    return false;  unsigned nBits = value.getNumBits(aligned());  if (value.getConstraintType() == Unconstrained || value.getUpperLimit()*nBits > 16) {    if (nBits == 8) {      encodeBlock(value.c_str(), len);      return true;    }    if (aligned())      byteAlign();  }  for (unsigned i = 0; i < len; i++) {    if (nBits >= value.getCanonicalSetBits() && value.getCanonicalSetBits() > 4)      encodeMultiBit(value[i], nBits);    else {      const void * ptr = memchr(value.getCharacterSet(), value[i], value.getCharacterSetSize());      if (ptr == NULL)        return false;      unsigned pos = ((const char *)ptr - value.getCharacterSet());      encodeMultiBit(pos, nBits);    }  }  return true;}bool PEREncoder::do_visit(const BMPString& value){  // X.691 Section 26  unsigned len = value.size();  if (!encodeConstrainedLength(value, len))    return false;  unsigned nBits = value.getNumBits(aligned());  if ((value.getConstraintType() == Unconstrained || value.getUpperLimit()*nBits > 16) && aligned())    byteAlign();  for (unsigned i = 0; i < len; i++)       encodeMultiBit(value[i] - value.getFirstChar(), nBits);  return true;}bool PEREncoder::do_visit(const CHOICE& value){  if (value.currentSelection() < 0)    return false;  if (value.extendable()) {    bool extended = value.currentSelection() >= static_cast<int>(value.getNumChoices());    encodeSingleBit(extended);    if (extended) {      encodeSmallUnsigned(value.currentSelection() - value.getNumChoices());      return encodeAnyType(value.getSelection());    }  }  if (value.getNumChoices() > 1)    if (!encodeUnsigned(value.currentSelection(), 0, value.getNumChoices()-1))      return false;  return value.getSelection()->accept(*this);}bool PEREncoder::do_visit(const SEQUENCE_OF_Base& value){  unsigned sz = value.size();  if (!encodeConstrainedLength(value, sz))    return false;  SEQUENCE_OF_Base::const_iterator first = value.begin(), last = value.end();	for (; first != last; ++first)		if (!(*first)->accept(*this))			return false;  return true;}bool PEREncoder::do_visit(const OpenData& value){	return encodeAnyType(&value.get_data());}bool PEREncoder::do_visit(const GeneralizedTime& value){	std::string notion(value.get());	encodeLength(notion.size(), 0, UINT_MAX);	encodeBlock(&*notion.begin(), notion.size());	return true;}bool PEREncoder::preVisitExtensionRoots(const SEQUENCE& value) {  // X.691 Section 18  if (value.extendable()) {    bool hasExtensions = false;    for (unsigned i = 0; i < value.extensionMap.size(); i++) {      if (value.extensionMap[i]) {        hasExtensions = true;        break;      }    }    encodeSingleBit(hasExtensions);  // 18.1  }  encodeBitMap(value.optionMap.bitData, value.optionMap.size());// 18.2  return true;}bool PEREncoder::visitExtensionRoot(const SEQUENCE& value, int index){	return value.fields[index]->accept(*this);}bool PEREncoder::preVisitExtensions(const SEQUENCE& value){  int totalExtensions = value.extensionMap.size();  encodeSmallUnsigned(totalExtensions-1);  encodeBitMap(value.extensionMap.bitData, value.extensionMap.size());  return true;}bool PEREncoder::visitKnownExtension(const SEQUENCE& value, int index){  return encodeAnyType(value.fields[index]);}bool PEREncoder::encodeConstrainedLength(const ConstrainedObject & obj, unsigned length) {  return (encodeConstraint(obj, length) ? // 26.4          encodeLength(length, 0, INT_MAX) :          encodeLength(length, obj.getLowerLimit(), obj.getUpperLimit()));}bool PEREncoder::encodeConstraint(const ConstrainedObject & obj, unsigned value) {  if (!obj.extendable())    return obj.getConstraintType() != FixedConstraint;  bool needsExtending = value > obj.getUpperLimit();  if (!needsExtending) {    if (obj.getLowerLimit() < 0) {      if ((int)value < obj.getLowerLimit())        needsExtending = true;    }    else {      if (value < (unsigned)obj.getLowerLimit())        needsExtending = true;    }  }  encodeSingleBit(needsExtending);  return needsExtending || obj.getConstraintType() < FixedConstraint;}void PEREncoder::encodeSingleBit(bool value){  if (bitOffset == 8)      encodedBuffer.push_back(0);  bitOffset--;  if (value)    encodedBuffer.back() |= 1 << bitOffset;  if (bitOffset == 0)    byteAlign();}void PEREncoder::encodeMultiBit(unsigned value, unsigned nBits){  if (nBits == 0)    return;  if (bitOffset == 8)      encodedBuffer.push_back(0);  // Make sure value is in bounds of bit available.  if (nBits < sizeof(int)*8)    value &= ((1 << nBits) - 1);  if (nBits < bitOffset) {    bitOffset -= nBits;    encodedBuffer.back() |= value << bitOffset;    return;  }  nBits -= bitOffset;  encodedBuffer.back() |= (char)(value >> nBits);  bitOffset = 8;  while (nBits >= 8) {    nBits -= 8;    encodedBuffer.push_back(value >> nBits) ;  }  if (nBits > 0) {    bitOffset = 8 - nBits;    encodedBuffer.push_back((value & ((1 << nBits)-1)) << bitOffset);  }}void PEREncoder::encodeSmallUnsigned(unsigned value){  if (value < 64) {    encodeMultiBit(value, 7);    return;  }  encodeSingleBit(true);// 10.6.2  unsigned len = 4;  if (value < 256)    len = 1;  else if (value < 65536)    len = 2;  else if (value < 0x1000000)    len = 3;  encodeLength(len, 0, INT_MAX);  // 10.9  byteAlign();  encodeMultiBit(value, len*8);}bool PEREncoder::encodeLength(unsigned len, unsigned lower, unsigned upper){  if (len < lower || len > upper)    return false;  // X.691 section 10.9  if (upper != INT_MAX && !alignedFlag) {    assert(upper - lower < 0x10000);  // 10.9.4.2 unsupperted    encodeMultiBit(len - lower, CountBits(upper - lower + 1));   // 10.9.4.1    return true;  }  if (upper < 65536)  // 10.9.3.3    return encodeUnsigned(len, lower, upper);  byteAlign();  if (len < 128) {    encodeMultiBit(len, 8);   // 10.9.3.6    return true;  }  encodeSingleBit(true);  if (len < 0x2000) {    encodeMultiBit(len, 15);    // 10.9.3.7    return true;  }  encodeSingleBit(true);  assert(len < 0x2000);  // 10.9.3.8 unsupported  return true;}bool PEREncoder::encodeUnsigned(unsigned value, unsigned lower, unsigned upper){  if (value < lower || value > upper)    return false;  // X.691 section 10.5  if (lower == upper) // 10.5.4    return true;  unsigned range = (upper - lower) + 1;  unsigned nBits = CountBits(range);  unsigned adjusted_value = value - lower;  if (alignedFlag && (range == 0 || range > 255)) { // not 10.5.6 and not 10.5.7.1    if (nBits > 16) {                           // not 10.5.7.4      int numBytes = adjusted_value == 0 ? 1 : (((CountBits(adjusted_value + 1))+7)/8);      if (!encodeLength(numBytes, 1, (nBits+7)/8))    // 12.2.6        return false;      nBits = numBytes*8;    }    else if (nBits > 8)      // not 10.5.7.2      nBits = 16;            // 10.5.7.3    byteAlign();             // 10.7.5.2 - 10.7.5.4  }  encodeMultiBit(adjusted_value, nBits);  return true;}bool PEREncoder::encodeAnyType(const AbstractData * value){  OpenBuf buf;  PEREncoder subEncoder(buf);  if (value != NULL)    if (!value->accept(subEncoder))		return false;  if (buf.size() == 0)				   // Make sure extension has at least one    subEncoder.encodeSingleBit(false); // byte in its ANY type encoding.  unsigned nBytes = buf.size();  encodeLength(nBytes, 0, INT_MAX);  encodeBlock(&*buf.begin(), nBytes);  return true;}void PEREncoder::encodeByte(unsigned value){  byteAlign();  encodedBuffer.push_back(value);}void PEREncoder::encodeBlock(const char * bufptr, unsigned nBytes){	if (nBytes == 0) 		return; 	byteAlign();	encodedBuffer.insert(encodedBuffer.end(), bufptr, bufptr + nBytes);}}

⌨️ 快捷键说明

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