📄 dcbertlv.cpp
字号:
/****************************************************************************************
* Copyrights 2006,深圳天源迪科信息技术股份有限公司
*
* All rights reserved.
*
* Filename: DCBerTlv.h
* Indentifier:
* Description:
* Version: V1.0
* Author: wangbin
* Finished: 2007年6月18日
* History:
******************************************************************************************/
#include "dicasnutil/DCBerTlv.h"
#include "dicasnutil/DCAsnParser.h"
namespace dicasn1p
{
DCBerTlv::DCBerTlv(size_t buf_len,size_t max_len)
{
m_read_len = 0;
m_buf_len = buf_len;
m_max_len = max_len;
m_buf = (char*)malloc(m_buf_len);
m_status = none;
value = NULL;
reference = NULL;
}
DCBerTlv::~DCBerTlv()
{
release();
if(m_buf)
{
free(m_buf);
m_buf = NULL;
}
}
ssize_t DCBerTlv::fromBuffer( const void* bufptr,size_t buflen )
{
const char *databuf = (char*)bufptr;
ssize_t nRet = 0;
ssize_t lastused = 0;
ber_tlv_tag_t tag;
ber_tlv_len_t len;
do
{
if(none == m_status)
{
release();
lastused = ber_fetch_tag(databuf,buflen,&tag);
if (0 == lastused)
{
save(databuf,buflen);
break;
}
else if (0 > lastused)
{
nRet = -1;
break;
}
else
{
this->constructed = BER_TLV_CONSTRUCTED(databuf);
this->tag_class = (enum asn_tag_class)BER_TAG_CLASS(tag);
this->tag = BER_TAG_VALUE(tag);
databuf += lastused;
buflen -= lastused;
clear();
m_status = read_len;
}
}
if(read_tag == m_status)
{
size_t reallen = save(databuf,buflen);
lastused = ber_fetch_tag(m_buf,m_read_len ,&tag);
if(0 == lastused)
{
break;
}
else if (0 > lastused)
{
nRet = -1;
break;
}
else
{
this->constructed = BER_TLV_CONSTRUCTED(m_buf);
this->tag_class = (enum asn_tag_class)BER_TAG_CLASS(tag);
this->tag = BER_TAG_VALUE(tag);
databuf += lastused + reallen - m_read_len ;
buflen -= lastused + reallen - m_read_len ;
clear();
m_status = read_len;
}
}
if(read_len == m_status)
{
size_t reallen = 0;
if(0 == m_read_len)
{
lastused = ber_fetch_length(this->constructed,databuf,buflen,&len);
if(0 == lastused)
{
reallen = save(databuf,buflen);
}
}
else
{
reallen = save(databuf,buflen);
lastused = ber_fetch_length(this->constructed,m_buf,m_read_len,&len);
}
if(0 == lastused)
{
break;
}
else if (0 > lastused)
{
nRet = -1;
break;
}
else
{
databuf += lastused + reallen - m_read_len ;
buflen -= lastused + reallen - m_read_len ;
clear();
this->length = len;
m_status = read_value;
}
}
if (read_value == m_status)
{
size_t reallen = DICASN_MIN(buflen,this->length - m_read_len);
if (0 == m_read_len )
{
value = (char*)malloc(this->length);
}
memcpy(value+m_read_len,databuf,reallen);
m_read_len += reallen;
if(this->length == m_read_len)
{
finish();
nRet = databuf - (char*)bufptr + reallen;
}
}
} while(0);
return nRet;
}
void DCBerTlv::release()
{
if(value)
free(value);
value = NULL;
m_read_len = 0;
}
size_t DCBerTlv::save( const char* bufptr,size_t buflen )
{
size_t reallen = DICASN_MIN(buflen,m_buf_len-m_read_len);
memcpy(m_buf + m_read_len,bufptr,reallen);
m_read_len += reallen;
// printf("save:[%X]\n",*(unsigned char*)bufptr);
return reallen;
}
void DCBerTlv::finish()
{
m_status = none;
clear();
}
void DCBerTlv::clear()
{
m_read_len = 0;
}
const char * DCBerTlv::getTagInfo()
{
m_sRetValue[0] = 0;
char tmp[64];
switch(tag_class)
{
case ASN_TAG_CLASS_UNIVERSAL:
get_universal_tag_name(tmp,64,tag);
asn1p_expr_snprintf(m_sRetValue,DICASN1P_DCBerTlv_RETURN_BUFFER_LEN,"universal:[%s]", tmp);
break;
case ASN_TAG_CLASS_CONTEXT:
if (reference && reference->Identifier)
{
asn1p_expr_snprintf(m_sRetValue,DICASN1P_DCBerTlv_RETURN_BUFFER_LEN,"ref:[%s]",reference->Identifier);
}
else
{
strcpy(m_sRetValue,"ASN_TAG_CLASS_CONTEXT");
}
break;
}
// ber_tlv_tag_snprint(BER_TAG_ORIGINAL(tag_class,tag),m_sRetValue,RETURN_BUFFER_LEN);
return m_sRetValue;
}
/*------------------------------------------------------------------------------------------------*/
ssize_t buffer_to_tlv_tree( const void* bufptr,size_t buflen,DCTreeNode<DCBerTlv> **pRoot )
{
DCBerTlv *tlv;
DCTreeNode<DCBerTlv> * root = *pRoot;
if (!root)
{
tlv = new DCBerTlv();
root = new DCTreeNode<DCBerTlv>(tlv);
*pRoot = root;
}
else
{
tlv = root->data;
}
ssize_t nRet = tlv->fromBuffer(bufptr,buflen);
if(nRet > 0)
{
if (tlv->constructed)
{
size_t used = 0,lastused = 0,length = tlv->length;
do
{
DCBerTlv *childTlv;
DCTreeNode<DCBerTlv> *child;
childTlv = new DCBerTlv();
child = root->addChild(childTlv);
lastused = buffer_to_tlv_tree(tlv->value + used,tlv->length - used,&child);
if(lastused <0)
{
nRet = -1;
break;
}
used += lastused;
} while(used < length);
}
}
return nRet;
}
void tlv_tree_free( DCTreeNode<DCBerTlv> *root )
{
if (NULL == root)
{
return;
}
DCTreeNode<DCBerTlv> *node;
DCASN1P_NODE_FOR (node,root)
{
tlv_tree_free(node);
}
delete root->data;
}
int get_universal_tag_name( char *name,size_t namelen,asn1c_integer_t tag_value )
{
name[0] = 0;
switch(ASN_UNIVERSAL_TAG2TYPE(tag_value) )
{
case ASN_BASIC_BOOLEAN: strncpy(name,"ASN_BASIC_BOOLEAN",namelen); break;
case ASN_BASIC_INTEGER: strncpy(name,"ASN_BASIC_INTEGER",namelen); break;
case ASN_BASIC_BIT_STRING: strncpy(name,"ASN_BASIC_BIT_STRING",namelen); break;
case ASN_BASIC_OCTET_STRING: strncpy(name,"ASN_BASIC_OCTET_STRING",namelen); break;
case ASN_BASIC_NULL: strncpy(name,"ASN_BASIC_NULL",namelen); break;
case ASN_BASIC_OBJECT_IDENTIFIER: strncpy(name,"ASN_BASIC_OBJECT_IDENTIFIER",namelen); break;
case ASN_STRING_ObjectDescriptor: strncpy(name,"ASN_STRING_ObjectDescriptor",namelen); break;
case ASN_BASIC_EXTERNAL: strncpy(name,"ASN_BASIC_EXTERNAL",namelen); break;
case ASN_BASIC_REAL: strncpy(name,"ASN_BASIC_REAL",namelen); break;
case ASN_BASIC_ENUMERATED: strncpy(name,"ASN_BASIC_ENUMERATED",namelen); break;
case ASN_BASIC_EMBEDDED_PDV: strncpy(name,"ASN_BASIC_EMBEDDED_PDV",namelen); break;
case ASN_STRING_UTF8String: strncpy(name,"ASN_STRING_UTF8String",namelen); break;
case ASN_BASIC_RELATIVE_OID: strncpy(name,"ASN_BASIC_RELATIVE_OID",namelen); break;
case ASN_CONSTR_SEQUENCE: /* Or SEQUENCE OF */ strncpy(name,"ASN_CONSTR_SEQUENCE",namelen); break;
case ASN_CONSTR_SET: /* Or SET OF */ strncpy(name,"ASN_CONSTR_SET",namelen); break;
case ASN_STRING_NumericString: /* " "|"0".."9" */ strncpy(name,"ASN_STRING_NumericString",namelen); break;
case ASN_STRING_PrintableString: strncpy(name,"ASN_STRING_PrintableString",namelen); break;
case ASN_STRING_TeletexString: strncpy(name,"ASN_STRING_TeletexString",namelen); break;
case ASN_STRING_VideotexString: strncpy(name,"ASN_STRING_VideotexString",namelen); break;
case ASN_STRING_IA5String: strncpy(name,"ASN_STRING_IA5String",namelen); break;
case ASN_BASIC_UTCTime: strncpy(name,"ASN_BASIC_UTCTime",namelen); break;
case ASN_BASIC_GeneralizedTime: strncpy(name,"ASN_BASIC_GeneralizedTime",namelen); break;
case ASN_STRING_GraphicString: strncpy(name,"ASN_STRING_GraphicString",namelen); break;
case ASN_STRING_VisibleString: strncpy(name,"ASN_STRING_VisibleString",namelen); break;
case ASN_STRING_GeneralString: strncpy(name,"ASN_STRING_GeneralString",namelen); break;
case ASN_STRING_UniversalString: /* 32-bit UCS-4 */ strncpy(name,"ASN_STRING_UniversalString",namelen); break;
case ASN_BASIC_CHARACTER_STRING: strncpy(name,"ASN_BASIC_CHARACTER_STRING",namelen); break;
case ASN_STRING_BMPString: /* 16-bit UCS-2 */ strncpy(name,"ASN_STRING_BMPString",namelen); break;
}
name[namelen-1] = 0;
return 0;
}
/*------------------------------------------------------------------------------------------------*/
DCTlvFileBuf::DCTlvFileBuf( FILE *fp )
{
m_fp = fp;
m_used = 0;
m_length = 0;
}
DCTlvFileBuf::~DCTlvFileBuf()
{
}
DCTreeNode<DCBerTlv> * DCTlvFileBuf::read_tlv_tree()
{
ssize_t lastused = 0;
DCTreeNode<DCBerTlv> *root = NULL;
if (m_used >= m_length)
{
if (0 == read_file() )
{
return NULL;
}
}
while ( (lastused = buffer_to_tlv_tree(m_buf + m_used,m_length - m_used,&root) ) == 0 )
{
if (0 == read_file() )
{
tlv_tree_free(root);
return NULL;
}
}
if (lastused <0)
{
throw DCDecodeException("decode error! [%s][%d]",__FILE__,__LINE__);
}
m_used += lastused;
return root;
}
int DCTlvFileBuf::read_file()
{
m_length = fread(m_buf,1,DICASN1P_TREE_BUF_SIZE,m_fp);
if (0 >= m_length)
{
return 0;
}
m_used = 0;
return m_length;
}
/*------------------------------------------------------------------------------------------------*/
DCDecodeException::DCDecodeException( const char *fmt,... )
{
va_list vlist;
va_start(vlist,fmt);
vsnprintf(m_buf,512,fmt,vlist);
m_buf[511] = 0;
va_end(vlist);
}
const char * DCDecodeException::what()
{
return m_buf;
}
/*------------------------------------------------------------------------------------------------*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -