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

📄 berencoder.cxx

📁 asn格式文件的编译器
💻 CXX
字号:
/* * BEREncoder.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: BEREncoder.cxx,v $ * Revision 1.4  2002/07/02 04:45:13  mangelo * Modify for VC.Net and GCC 3.1 * * Revision 1.3  2001/10/05 19:08:12  mangelo * Added Log * * 2001/06/26 Huang-Ming Huang  * Version 2.1 Reimplemented to minimize the code size. * */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include "asn1.h"namespace ASN1 {extern unsigned CountBits(unsigned range);class PrimitiveChecker : public ConstVisitor{private:	bool do_visit(const AbstractData& value) { return true; }	bool do_visit(const CHOICE& value) { 		assert(value.currentSelection() >= 0) ;		return value.getSelection()->accept(*this);	}	bool do_visit(const OpenData& value) { 		assert(value.has_data());		return value.get_data().accept(*this); 	}	bool do_visit(const SEQUENCE_OF_Base& value) { return false; }	bool preVisitExtensionRoots(const SEQUENCE& value) { return false; }};unsigned getIntegerDataLength(int value){  // create a mask which is the top nine bits of a DWORD, or 0xFF800000  // on a big endian machine  int shift = (sizeof(value)-1)*8-1;  // remove all sequences of nine 0's or 1's at the start of the value  while (shift > 0 && ((value >> shift)&0x1ff) == (value < 0 ? 0x1ff : 0))    shift -= 8;  return (shift+9)/8;}unsigned getDataLength(const AbstractData& data);unsigned getObjectLength(const AbstractData& data, unsigned tag);class DataLengthCounter : public ConstVisitor{public:	DataLengthCounter() : length(0) {}    unsigned getDataLen() const { 		return length; 	}	unsigned getObjectLen(unsigned tag) const {		int len = 1;		        unsigned tagVal = tag & 0xFFFF;		if (tagVal >= 31)			len += (CountBits(tagVal)+6)/7;				int  dataLen = getDataLen();				if (dataLen < 128)			len++;		else			len += (CountBits(dataLen)+7)/8 + 1;				return len + dataLen;			}private:	bool do_visit(const Null& value) {		return true; 	}	bool do_visit(const BOOLEAN& value) { 		++length;		return true; 	}	bool do_visit(const INTEGER& value) { 		length += getIntegerDataLength(value.getValue());		return true; 	}	bool do_visit(const ENUMERATED& value) { 		length += getIntegerDataLength(value.asInt());		return true; 	}	bool do_visit(const OBJECT_IDENTIFIER& value) { 		std::vector<char> dummy;		value.encodeCommon(dummy);		length += dummy.size();		return true; 	}	bool do_visit(const BIT_STRING& value) { 	    length += (value.size()+7)/8 + 1;		return true; 	}	bool do_visit(const OCTET_STRING& value) {		length += value.size();		return true;	}	bool do_visit(const AbstractString& value) { 		length += value.size();		return true; 	}	bool do_visit(const BMPString& value) { 		length += value.size()*2;		return true; 	}	bool do_visit(const CHOICE& value) { 	  if (value.currentSelection() >=0 )  {		length +=  getObjectLength(*value.getSelection(),value.getSelectionTag());	  }	  return true; 	}	bool do_visit(const OpenData& value) { 		length += (value.has_data() ? getDataLength(value.get_data()) : 0);		return true; 	}	bool do_visit(const GeneralizedTime& value) { 		length += value.get().size();		return true; 	}	bool do_visit(const SEQUENCE_OF_Base& value) {		SEQUENCE_OF_Base::const_iterator first = value.begin(), last = value.end();		for (; first != last; ++first)			length += ASN1::getObjectLength(**first, (*first)->getTag()); 		return true; 	}	bool preVisitExtensionRoots(const SEQUENCE& value) { 		return true; 	}	bool visitExtensionRoot(const SEQUENCE& value, int index) {		length += ASN1::getObjectLength(*value.getField(index), value.getFieldTag(index));		return true; 	}	bool VisitExtensions(const SEQUENCE& value) { 		return true;	}	bool visitKnownExtension(const SEQUENCE& value, int index) { 		length += ASN1::getObjectLength(*value.getField(index), value.getFieldTag(index));		return true; 	}	unsigned length,tag;};unsigned getDataLength(const AbstractData& data){	DataLengthCounter counter;	data.accept(counter);	return counter.getDataLen();}unsigned getObjectLength(const AbstractData& data, unsigned tag){	DataLengthCounter counter;	data.accept(counter);	if (tag == 0 || (tag ==0xffffffff && data.getTag() ==0))			return counter.getDataLen();	return counter.getObjectLen(tag);}inline void BEREncoder::encodeByte(unsigned value){  encodedBuffer.push_back(value);}inline void BEREncoder::encodeBlock(const char * bufptr, unsigned nBytes){  encodedBuffer.insert(encodedBuffer.end(), bufptr, bufptr + nBytes);}bool BEREncoder::do_visit(const Null& value){  encodeHeader(value);  return true;}bool BEREncoder::do_visit(const BOOLEAN& value){  encodeHeader(value);  encodeByte(!value ? '\x00' : '\xff');  return true;}bool BEREncoder::do_visit(const INTEGER& value){  encodeHeader(value);  // output the integer bits  for (int count = getIntegerDataLength(value.getValue())-1; count >= 0; count--)    encodeByte(value.getValue() >> (count*8));  return true;}bool BEREncoder::do_visit(const ENUMERATED& value){  encodeHeader(value);  // output the integer bits  for (int count = getIntegerDataLength(value.asInt())-1; count >= 0; count--)    encodeByte(value.asInt() >> (count*8));  return true;}bool BEREncoder::do_visit(const OBJECT_IDENTIFIER& value){  encodeHeader(value);  std::vector<char> data;  value.encodeCommon(data);  encodeBlock(&data.front(), data.size());    return true;}bool BEREncoder::do_visit(const BIT_STRING& value){  encodeHeader(value);  if (value.size() == 0)    encodeByte(0);  else {    encodeByte(8-value.size()%8);    encodeBlock(&*value.getData().begin(), (value.size()+7)/8);  }  return true;}bool BEREncoder::do_visit(const OCTET_STRING& value){  encodeHeader(value);  encodeBlock(&value[0], value.size());  return true;}bool BEREncoder::do_visit(const AbstractString& value){  encodeHeader(value);  encodeBlock((const char*)value.c_str(), value.size());  return true;}bool BEREncoder::do_visit(const BMPString& value){  encodeHeader(value);  for (unsigned i = 0; i < value.size(); ++i)  {    encodeByte(value[i] >> 8);    encodeByte(value[i]);  }  return true;}bool BEREncoder::do_visit(const CHOICE& value){	if (value.currentSelection() != CHOICE::unselected_)	{		if (tag != 0 && (tag!=0xffffffff || value.getTag() !=0))			encodeHeader(value);		tag = value.getSelectionTag();		return value.getSelection()->accept(*this);	}	return false;}bool BEREncoder::do_visit(const SEQUENCE_OF_Base& value){  encodeHeader(value);  SEQUENCE_OF_Base::const_iterator first       = value.begin(), last = value.end();	for (; first != last; ++first)	{		tag = 0xFFFFFFFF;		if (!(*first)->accept(*this))			return false;	}  return true;}bool BEREncoder::do_visit(const OpenData& value){    if (tag == 0xFFFFFFFF)         tag = value.getTag();    if (tag != 0)        encodeHeader(value);    tag = 0xFFFFFFFF;        if (value.has_data())        return value.get_data().accept(*this);    else if (value.has_buf())    {        encodeBlock(&*value.get_buf().begin(), value.get_buf().size());        return true;    }    return false;}bool BEREncoder::do_visit(const GeneralizedTime& value){  encodeHeader(value);  std::string data(value.get());  encodeBlock((const char*)data.c_str(), data.size());  return true;}bool BEREncoder::preVisitExtensionRoots(const SEQUENCE& value) {	encodeHeader(value);	return true;}bool BEREncoder::visitExtensionRoot(const SEQUENCE& value, int index){    tag = value.getFieldTag(index);	return value.getField(index)->accept(*this);}bool BEREncoder::visitKnownExtension(const SEQUENCE& value, int index){    tag = value.getFieldTag(index);	return value.getField(index)->accept(*this);}void BEREncoder::encodeHeader(const AbstractData & obj){  unsigned obj_tag = (tag == 0xFFFFFFFF) ? obj.getTag() : tag;  char ident = (char)(obj_tag >> 16);  PrimitiveChecker checker;  if (!obj.accept(checker))    ident |= 0x20;  unsigned tagNumber = obj_tag & 0xffff;  if (tagNumber < 31)    encodeByte(ident|tagNumber);  else {    encodeByte(ident|31);    unsigned count = (CountBits(tagNumber)+6)/7;    while (count-- > 1)      encodeByte((tagNumber >> (count*7))&0x7f);    encodeByte(tagNumber & 0x7f);  }  unsigned len = getDataLength(obj);  if (len < 128)    encodeByte(len);  else {    unsigned count = (CountBits(len+1)+7)/8;    encodeByte(count|0x80);    while (count-- > 0)      encodeByte(len >> (count*8));  }}} // namespace ASN1

⌨️ 快捷键说明

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