📄 dcasnberdecoder.cpp
字号:
/****************************************************************************************
* Copyrights 2006,深圳天源迪科信息技术股份有限公司
*
* All rights reserved.
*
* Filename: DCAsnBerDecoder.cpp
* Indentifier:
* Description:
* Version: V1.0
* Author: wangbin
* Finished: 2007年6月20日
* History:
******************************************************************************************/
#include "dicasnutil/DCAsnBerDecoder.h"
/*******************************************************************************************/
namespace dicasn1p
{
/*******************************************************************************************/
void tlv_tree_fix(arg_t *arg,DCTreeNode<DCBerTlv> *root)
{
root->data->reference = arg->expr;
if (root->data->reference == NULL)
{
return;
}
arg_t child_arg;
child_arg.asn = arg->asn;
child_arg.mod = NULL;
child_arg.expr = arg->expr;
asn1p_expr_t *real_type;
if(arg->expr->expr_type == A1TC_REFERENCE)
{
real_type = asn1f_find_terminal_type(&child_arg,arg->expr);
}
else
{
real_type = arg->expr;
}
if(root->data->constructed &&real_type)
{
asn1p_expr_t *child_type;
DCTreeNode<DCBerTlv> *node;
switch(real_type->expr_type)
{
case ASN_CONSTR_CHOICE: /* CHOICE */
node = root;
if (node->depth)
{
node = node->head;
}
child_type = find_child_member_by_tag(real_type,node->data->tag);
child_arg.expr = child_type;
tlv_tree_fix(&child_arg,node);
break;
case ASN_CONSTR_SEQUENCE: /* SEQUENCE */
case ASN_CONSTR_SET: /* SET */
DCASN1P_NODE_FOR (node,root)
{
child_type = find_child_member_by_tag(real_type,node->data->tag);
child_arg.expr = child_type;
tlv_tree_fix(&child_arg,node);
}
break;
case ASN_CONSTR_SEQUENCE_OF: /* SEQUENCE OF */
case ASN_CONSTR_SET_OF: /* SET OF */
DCASN1P_NODE_FOR (node,root)
{
child_arg.expr = TQ_FIRST(&(real_type->members) );
tlv_tree_fix(&child_arg,node);
}
break;
}
}
}
asn1p_expr_t * find_child_member_by_tag( asn1p_expr_t* node,int tag )
{
if(! node->expr_type&ASN_CONSTR_MASK )
return NULL;
asn1p_expr_t *child;
TQ_FOR(child,&(node->members),next)
{
if (child->tag.tag_value == tag)
{
return child;
}
}
return NULL;
}
DCTreeNode<DCBerTlv> * find_child_member_by_name(DCTreeNode<DCBerTlv> *node,const char *childName)
{
if(!childName || strcmp(childName,"*") == 0)
{
return node->head;
}
DCTreeNode<DCBerTlv> * child;
DCASN1P_NODE_FOR(child,node)
{
if(child->data->reference && child->data->reference->Identifier &&
strcmp(child->data->reference->Identifier,childName)==0 )
return child;
}
return NULL;
}
DCTreeNode<DCBerTlv> * find_sibling_member_by_name(DCTreeNode<DCBerTlv> *node,const char *siblingName)
{
if(!siblingName || strcmp(siblingName,"*") == 0)
{
return node->next;
}
DCTreeNode<DCBerTlv> *sibling = node->next;
for (;sibling;sibling = sibling->next)
{
if(sibling->data->reference && sibling->data->reference->Identifier &&
strcmp(sibling->data->reference->Identifier,siblingName) )
return sibling;
}
return NULL;
}
DCTreeNode<DCBerTlv> * find_child_member_by_path( DCTreeNode<DCBerTlv> *node,const char *path )
{
char name[128];
size_t len = strlen(path);
if(len == 0)
return node;
if(!strchr(path,'.') && !strchr(path,'/') )
{
return match_member_name(node,path);
}
DCTreeNode<DCBerTlv> *child;
DCTreeNode<DCBerTlv> *res = NULL;
for (int i=0;i<=len;++i)
{
if(path[i]=='.' || path[i]=='/' )
{
memcpy(name,path,i);
name[i] = 0;
if (match_member_name(node,name))
{
DCASN1P_NODE_FOR(child,node)
{
if( res = find_child_member_by_path(child,path+i+1) )
{
return res;
}
}
}
break;
}
}
return NULL;
}
DCTreeNode<DCBerTlv> * match_member_name( DCTreeNode<DCBerTlv> *node,const char *name )
{
if (strcmp(name,"*")==0 )
{
return node;
}
if (node->data->reference &&node->data->reference->Identifier &&
strcmp(node->data->reference->Identifier,name) == 0)
{
return node;
}
return NULL;
}
enum asn_tag_class asn_tag_class_to_ber( enum asn1p_tag_class_e v_asn_class )
{
switch(v_asn_class)
{
case TC_NOCLASS:
case TC_UNIVERSAL:
return ASN_TAG_CLASS_UNIVERSAL;
case TC_APPLICATION:
return ASN_TAG_CLASS_APPLICATION;
case TC_CONTEXT_SPECIFIC:
return ASN_TAG_CLASS_CONTEXT;
case TC_PRIVATE:
return ASN_TAG_CLASS_PRIVATE;
}
return ASN_TAG_CLASS_UNIVERSAL;
}
/*******************************************************************************************/
DCAsnBerValue::DCAsnBerValue()
{
}
DCAsnBerValue::~DCAsnBerValue()
{
clear();
}
DCAsnBerValue* DCAsnBerValue::fromExpr( arg_t *p_arg,int depth )
{
DCAsnBerValue* newValue = NULL;
asn1p_expr_t *expr = p_arg->expr;
asn1p_expr_t *origin_expr = expr;
arg_t new_arg;
memset(&new_arg,0,sizeof(new_arg) );
new_arg.asn = p_arg->asn;
expr = asn1f_find_terminal_type(&new_arg,expr);
switch(expr->expr_type)
{
case A1TC_INVALID: /* Invalid type */
case A1TC_REFERENCE: /* Reference to the type defined elsewhere */
case A1TC_EXPORTVAR: /* We're exporting this definition */
break;
case A1TC_EXTENSIBLE: /* An extension marker "..." */
break;
case A1TC_COMPONENTS_OF: /* COMPONENTS OF clause */
case A1TC_VALUESET: /* Value set definition */
case A1TC_CLASSDEF: /* Information Object Class */
case A1TC_INSTANCE: /* Instance of Object Class */
case A1TC_CLASSFIELD_TFS: /* TypeFieldSpec */
case A1TC_CLASSFIELD_FTVFS: /* FixedTypeValueFieldSpec */
case A1TC_CLASSFIELD_VTVFS: /* VariableTypeValueFieldSpec */
case A1TC_CLASSFIELD_FTVSFS: /* FixedTypeValueSetFieldSpec */
case A1TC_CLASSFIELD_VTVSFS: /* VariableTypeValueSetFieldSpec */
case A1TC_CLASSFIELD_OFS: /* ObjectFieldSpec */
case A1TC_CLASSFIELD_OSFS: /* ObjectSetFieldSpec */
break;
case ASN_CONSTR_SEQUENCE: /* SEQUENCE */
newValue = new DCStructValue(DCStructValue::TYPE_SEQUENCE);
break;
case ASN_CONSTR_CHOICE: /* CHOICE */
newValue = new DCChoiceValue(DCStructValue::TYPE_CHOICE);
break;
case ASN_CONSTR_SET: /* SET */
newValue = new DCStructValue(DCStructValue::TYPE_SET);
break;
case ASN_CONSTR_SEQUENCE_OF: /* SEQUENCE OF */
newValue = new DCArrayValue(DCStructValue::TYPE_SEQUENCE_OF);
break;
case ASN_CONSTR_SET_OF: /* SET OF */
newValue = new DCArrayValue(DCStructValue::TYPE_SET_OF);
break;
case ASN_TYPE_ANY: /* ANY (deprecated) */
newValue = new DCBasicValue(DCBasicValue::TYPE_ANY);
break;
case A1TC_UNIVERVAL: /* A value of an ENUMERATED: INTEGER or BS */
case A1TC_BITVECTOR: /* A plain collection of bits */
case A1TC_OPAQUE: /* Opaque data encoded as a bitvector */
case ASN_BASIC_BOOLEAN:
case ASN_BASIC_NULL:
case ASN_BASIC_INTEGER:
case ASN_BASIC_REAL:
case ASN_BASIC_ENUMERATED:
case ASN_BASIC_BIT_STRING:
case ASN_BASIC_OCTET_STRING:
case ASN_BASIC_OBJECT_IDENTIFIER:
case ASN_BASIC_RELATIVE_OID:
case ASN_BASIC_EXTERNAL:
case ASN_BASIC_EMBEDDED_PDV:
newValue = new DCBasicValue(DCBasicValue::TYPE_INT);
break;
case ASN_BASIC_UTCTime:
case ASN_BASIC_GeneralizedTime:
newValue = new DCBasicValue(DCBasicValue::TYPE_UTCTIME);
break;
case ASN_BASIC_CHARACTER_STRING:
case ASN_STRING_IA5String:
case ASN_STRING_PrintableString:
case ASN_STRING_VisibleString:
case ASN_STRING_ISO646String: /* aka VisibleString */
case ASN_STRING_NumericString:
case ASN_STRING_UniversalString:
case ASN_STRING_BMPString:
case ASN_STRING_UTF8String:
case ASN_STRING_GeneralString:
case ASN_STRING_GraphicString:
case ASN_STRING_TeletexString:
case ASN_STRING_T61String:
case ASN_STRING_VideotexString:
case ASN_STRING_ObjectDescriptor:
newValue = new DCBasicValue(DCBasicValue::TYPE_STRING);
break;
}
if (newValue)
{
newValue->reference = origin_expr;
newValue->depth = depth;
newValue->asn = p_arg->asn;
if (origin_expr->Identifier)
{
newValue->name = origin_expr->Identifier;
}
struct asn1p_type_tag_s s_tag;
int nRet;
nRet = asn1f_fetch_outmost_tag(p_arg->asn,origin_expr->module,origin_expr,&s_tag,AFT_FETCH_OUTMOST);
if(nRet == 0)
{
newValue->tag = (int)s_tag.tag_value;
newValue->tag_class = asn_tag_class_to_ber(s_tag.tag_class);
}
if (expr->expr_type & ASN_CONSTR_MASK)
{
asn1p_expr_t * child;
DCAsnBerValue* childValue;
switch(expr->expr_type)
{
case ASN_CONSTR_SEQUENCE_OF:
case ASN_CONSTR_SET_OF:
new_arg.expr = TQ_FIRST(&expr->members);
childValue = fromExpr(&new_arg,depth +1 );
if (childValue)
{
((DCArrayValue*)newValue)->member_type = childValue;
}
break;
case ASN_CONSTR_CHOICE:
TQ_FOR(child,&(expr->members),next)
{
new_arg.expr = child;
childValue = fromExpr(&new_arg,depth +1);
if (childValue)
{
((DCChoiceValue*)newValue)->member_types.push_back(childValue);
}
}
break;
default:
TQ_FOR(child,&(expr->members),next)
{
new_arg.expr = child;
childValue = fromExpr(&new_arg,depth +1);
if (childValue)
{
((DCStructValue*)newValue)->members.push_back(childValue);
}
}
break;
}
}
}
return newValue;
}
int DCAsnBerValue::fromRoot( DCBerTlvNode* root )
{
root->data->reference = reference;
switch(value_type)
{
case TYPE_BASIC:
return fromNode(root);
}
return fromNode(root->head);
}
void DCAsnBerValue::clear() /*=0*/
{
}
/************************************* DCBasicValue ******************************************************/
DCBasicValue::DCBasicValue( T_basicType type )
{
this->type = type;
value_type = TYPE_BASIC;
buf = NULL;
size = 0;
}
int DCBasicValue::fromNode( DCBerTlvNode* first )
{
if (first && first->data)
{
buf = first->data->value;
size = first->data->length;
}
return 0;
}
void DCBasicValue::clear()
{
}
/************************************* DCStructValue ******************************************************/
DCStructValue::DCStructValue( T_structType type )
{
this->type = type;
value_type = TYPE_STRUCT;
}
int DCStructValue::fromNode( DCBerTlvNode* first )
{
if (first && first->data)
{
int imember = 0;
DCBerTlvNode* oldfirst;
switch(type)
{
case TYPE_SEQUENCE:
for (imember=0;imember<members.size() && first;++imember)
{
if (members[imember]->tag == first->data->tag && members[imember]->tag_class == first->data->tag_class)
{
members[imember]->fromRoot(first);
first = first->next;
}
}
break;
case TYPE_SET:
oldfirst = first;
for (imember=0;imember<members.size();++imember)
{
first = oldfirst;
while (first)
{
if (members[imember]->tag == first->data->tag && members[imember]->tag_class == first->data->tag_class)
{
members[imember]->fromRoot(first);
break;
}
first = first->next;
}
}
break;
default:
return -1;
}
}
return 0;
}
void DCStructValue::clear()
{
for (int i=0;i<members.size(); ++i)
{
delete members[i];
}
members.clear();
}
/******************************** DCArrayValue ***********************************************************/
DCArrayValue::DCArrayValue( T_structType type ):DCStructValue(type)
{
}
int DCArrayValue::fromNode( DCBerTlvNode* first )
{
DCStructValue::clear();
DCAsnBerValue *value;
arg_t arg;
arg.asn = asn;
arg.expr = member_type->reference;
while (first)
{
first->data->reference = reference;
value = fromExpr(&arg,member_type->depth);
if (value)
{
value->fromRoot(first);
members.push_back(value);
}
first = first->next;
}
return 0;
}
void DCArrayValue::clear()
{
DCStructValue::clear();
delete member_type;
}
/*******************************************************************************************/
DCChoiceValue::DCChoiceValue( T_structType type ):DCStructValue(type)
{
}
int DCChoiceValue::fromNode( DCBerTlvNode* first )
{
members.clear();
for (int i=0;i<member_types.size();++i)
{
if (member_types[i]->tag == first->data->tag && member_types[i]->tag_class == first->data->tag_class)
{
member_types[i]->fromRoot(first);
members.push_back(member_types[i]);
break;
}
}
return 0;
}
void DCChoiceValue::clear()
{
for (int i=0;i<member_types.size(); ++i)
{
delete member_types[i];
}
member_types.clear();
}
/*******************************************************************************************/
}
/*******************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -