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

📄 asn1fix_param.c

📁 ASN.1解析解码工具,可以解析各种ASN.1格式的文件,并对相应的BER文件解码
💻 C
字号:
#include "asn1fix/asn1fix_internal.h"typedef struct resolver_arg {	asn1p_expr_t	  *(*resolver)(asn1p_expr_t *, void *arg);	arg_t		  *arg;	asn1p_expr_t	  *original_expr;	asn1p_paramlist_t *lhs_params;	asn1p_expr_t	  *rhs_pspecs;} resolver_arg_t;static asn1p_expr_t *resolve_expr(asn1p_expr_t *, void *resolver_arg);static int compare_specializations(arg_t *, asn1p_expr_t *a, asn1p_expr_t *b);static asn1p_expr_t *find_target_specialization_byref(resolver_arg_t *rarg, asn1p_ref_t *ref);static asn1p_expr_t *find_target_specialization_bystr(resolver_arg_t *rarg, char *str);asn1p_expr_t *asn1f_parameterization_fork(arg_t *arg, asn1p_expr_t *expr, asn1p_expr_t *rhs_pspecs) {	resolver_arg_t rarg;	/* resolver argument */	asn1p_expr_t *exc;	/* expr clone */	asn1p_expr_t *rpc;	/* rhs_pspecs clone */	void *p;	struct asn1p_pspec_s *pspec;	int npspecs;	assert(rhs_pspecs);	assert(expr->lhs_params);	assert(expr->parent_expr == 0);	DEBUG("Forking parameterization at %d for %s (%d alr)",		rhs_pspecs->_lineno, expr->Identifier,		expr->specializations.pspecs_count);	/*	 * Find if this exact specialization has been used already.	 */	for(npspecs = 0;		npspecs < expr->specializations.pspecs_count;			npspecs++) {		if(compare_specializations(arg, rhs_pspecs,			expr->specializations.pspec[npspecs].rhs_pspecs) == 0) {			DEBUG("Reused parameterization for %s",				expr->Identifier);			return expr->specializations.pspec[npspecs].my_clone;		}	}	rarg.resolver = resolve_expr;	rarg.arg = arg;	rarg.original_expr = expr;	rarg.lhs_params = expr->lhs_params;	rarg.rhs_pspecs = rhs_pspecs;	exc = asn1p_expr_clone_with_resolver(expr, resolve_expr, &rarg);	rpc = asn1p_expr_clone(rhs_pspecs, 0);	assert(exc && rpc);	/*	 * Create a new specialization.	 */	npspecs = expr->specializations.pspecs_count;	p = realloc(expr->specializations.pspec,			(npspecs + 1) * sizeof(expr->specializations.pspec[0]));	assert(p);	expr->specializations.pspec = p;	pspec = &expr->specializations.pspec[npspecs];	memset(pspec, 0, sizeof *pspec);	pspec->rhs_pspecs = rpc;	pspec->my_clone = exc;	exc->spec_index = npspecs;	DEBUG("Forked new parameterization for %s", expr->Identifier);	/* Commit */	expr->specializations.pspecs_count = npspecs + 1;	return exc;}static intcompare_specializations(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b) {	asn1p_expr_t *ac = TQ_FIRST(&a->members);	asn1p_expr_t *bc = TQ_FIRST(&b->members);	for(;ac && bc; ac = TQ_NEXT(ac, next), bc = TQ_NEXT(bc, next)) {	  retry:		if(ac == bc) continue;		if(ac->meta_type != bc->meta_type) break;		if(ac->expr_type != bc->expr_type) break;		if(!ac->reference && !bc->reference)			continue;		if(ac->reference) {			ac = asn1f_lookup_symbol(arg,				ac->module, ac->rhs_pspecs, ac->reference);			if(!ac) break;		}		if(bc->reference) {			bc = asn1f_lookup_symbol(arg,				bc->module, bc->rhs_pspecs, bc->reference);			if(!bc) break;		}	  goto retry;	}	if(ac || bc)		/* Specializations do not match: different size option sets */		return -1;	return 0;}static asn1p_expr_t *resolve_expr(asn1p_expr_t *expr_to_resolve, void *resolver_arg) {	resolver_arg_t *rarg = resolver_arg;	arg_t *arg = rarg->arg;	asn1p_expr_t *expr;	asn1p_expr_t *nex;	DEBUG("Resolving %s (meta %d)",		expr_to_resolve->Identifier, expr_to_resolve->meta_type);	if(expr_to_resolve->meta_type == AMT_TYPEREF) {		expr = find_target_specialization_byref(rarg,				expr_to_resolve->reference);		if(!expr) return NULL;	} else if(expr_to_resolve->meta_type == AMT_VALUE) {		assert(expr_to_resolve->value);		expr = find_target_specialization_bystr(rarg,				expr_to_resolve->Identifier);		if(!expr) return NULL;	} else {		errno = ESRCH;		return NULL;	}	DEBUG("Found target %s (%d/%x)",		expr->Identifier, expr->meta_type, expr->expr_type);	if(expr->meta_type == AMT_TYPE	|| expr->meta_type == AMT_VALUE	|| expr->meta_type == AMT_VALUESET) {		DEBUG("Target is a simple type %s",			ASN_EXPR_TYPE2STR(expr->expr_type));		nex = asn1p_expr_clone(expr, 0);		free(nex->Identifier);		nex->Identifier = expr_to_resolve->Identifier			? strdup(expr_to_resolve->Identifier) : 0;		return nex;	} else {		FATAL("Feature not implemented for %s (%d/%x), "			"please contact the asn1c author",			rarg->original_expr->Identifier,			expr->meta_type, expr->expr_type);		errno = EPERM;		return NULL;	}	return NULL;}static asn1p_expr_t *find_target_specialization_byref(resolver_arg_t *rarg, asn1p_ref_t *ref) {	char *refstr;	if(!ref || ref->comp_count != 1) {		errno = ESRCH;		return NULL;	}	refstr = ref->components[0].name;	/* T */	return find_target_specialization_bystr(rarg, refstr);}static asn1p_expr_t *find_target_specialization_bystr(resolver_arg_t *rarg, char *refstr) {	arg_t *arg = rarg->arg;	asn1p_expr_t *target;	int i;	target = TQ_FIRST(&rarg->rhs_pspecs->members);	for(i = 0; i < rarg->lhs_params->params_count;			i++, target = TQ_NEXT(target, next)) {		struct asn1p_param_s *param = &rarg->lhs_params->params[i];		if(!target) break;		if(strcmp(param->argument, refstr))			continue;		return target;	}	if(i != rarg->lhs_params->params_count) {		FATAL("Parameterization of %s failed: "			"parameters number mismatch",				rarg->original_expr->Identifier);		errno = EPERM;		return NULL;	}	errno = ESRCH;	return NULL;}

⌨️ 快捷键说明

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