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

📄 asn1fix_crange.c

📁 RSA加密/解密算法源码 asn1c-0.9.12
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "asn1fix_internal.h"#include "asn1fix_constraint.h"#include "asn1fix_crange.h"#undef	FATAL#define	FATAL(fmt, args...)	do {			\		fprintf(stderr, "FATAL: ");		\		fprintf(stderr, fmt, ##args);		\		fprintf(stderr, "\n");			\	} while(0)voidasn1constraint_range_free(asn1cnst_range_t *cr) {	if(cr) {		int i;		if(cr->elements) {			for(i = 0; i < cr->el_count; i++)				asn1constraint_range_free(cr->elements[i]);			free(cr->elements);		}		free(cr);	}}#define	_range_free(foo)	asn1constraint_range_free(foo)static asn1cnst_range_t *_range_new() {	asn1cnst_range_t *r;	r = calloc(1, sizeof(*r));	if(r) {		r->left.type = ARE_MIN;		r->right.type = ARE_MAX;	}	return r;}static void _range_remove_element(asn1cnst_range_t *range, int idx) {	assert(idx >= 0 && idx < range->el_count);	assert(!range->elements[idx]->elements);	_range_free(range->elements[idx]);	memmove(&range->elements[idx],		&range->elements[idx + 1],		(range->el_count - idx - 1)			* sizeof(range->elements[0])	);	range->el_count--;	range->elements[range->el_count] = 0;	/* JIC */	if(range->el_count == 0) {		range->el_size = 0;		free(range->elements);		range->elements = 0;	}}static int _range_insert(asn1cnst_range_t *into, asn1cnst_range_t *cr) {	assert(!cr->elements);	if(into->el_count == into->el_size) {		void *p;		int n = into->el_size?(into->el_size << 1):4;		p = realloc(into->elements, n * sizeof(into->elements[0]));		if(p) {			into->el_size = n;			into->elements = p;		} else {			assert(p);			return -1;		}	}	into->elements[into->el_count++] = cr;	return 0;}static asn1cnst_range_t *_range_clone(const asn1cnst_range_t *range) {	asn1cnst_range_t *clone;	int i;	clone = _range_new();	if(!clone) return NULL;	*clone = *range;	clone->elements = 0;	clone->el_count = 0;	clone->el_size = 0;	for(i = 0; i < range->el_count; i++) {		asn1cnst_range_t *r = _range_clone(range->elements[i]);		if(!r || _range_insert(clone, r)) {			_range_free(clone);			_range_free(r);			return NULL;		}	}	return clone;}static int_edge_compare(const asn1cnst_edge_t *el, const asn1cnst_edge_t *er) {	switch(el->type) {	case ARE_MIN:		switch(er->type) {		case ARE_MIN: return 0;		case ARE_MAX: return -1;		case ARE_VALUE: return -1;		}		break;	case ARE_MAX:		switch(er->type) {		case ARE_MIN: return 1;		case ARE_MAX: return 0;		case ARE_VALUE: return 1;		}		break;	case ARE_VALUE:		switch(er->type) {		case ARE_MIN: return 1;		case ARE_MAX: return -1;		case ARE_VALUE:			if(el->value < er->value)				return -1;			if(el->value > er->value)				return 1;			return 0;		}		break;	}	return 0;}static int_range_compare(const void *a, const void *b) {	const asn1cnst_range_t *ra = *(const asn1cnst_range_t * const *)a;	const asn1cnst_range_t *rb = *(const asn1cnst_range_t * const *)b;	int ret;	ret = _edge_compare(&ra->left, &rb->left);	if(!ret) {		ret = _edge_compare(&ra->right, &rb->right);	}	return ret;}static char *_edge_value(const asn1cnst_edge_t *edge) {	static char buf[128];	*buf = '\0';	switch(edge->type) {	case ARE_MIN:	strcpy(buf, "MIN"); break;	case ARE_MAX:	strcpy(buf, "MAX"); break;	case ARE_VALUE:		snprintf(buf, sizeof(buf), "%" PRIdASN, edge->value);	}	return buf;}static void_range_print(const asn1cnst_range_t *range) {	if(_edge_compare(&range->left, &range->right)) {		printf("(%s.", _edge_value(&range->left));		printf(".%s", _edge_value(&range->right));	} else {		printf("(%s", _edge_value(&range->left));	}	if(range->extensible) {		printf(",...)");	} else {		printf(")");	}	if(range->incompatible) printf("/I");	if(range->not_PER_visible) printf("/!V");	if(range->el_count) {		int i;		printf("-=>");		for(i = 0; i < range->el_count; i++)			_range_print(range->elements[i]);	}}static int_edge_is_within(const asn1cnst_range_t *range, const asn1cnst_edge_t *edge) {	int i;	for(i = -1; i < range->el_count; i++) {		const asn1cnst_range_t *r;		if(i == -1) {			if(range->el_count) continue;			r = range;		} else {			r = range->elements[i];		}		if(_edge_compare(&r->left, edge) <= 0		&& _edge_compare(&r->right, edge) >= 0)			return 1;	}	return 0;}static int_check_edges_within(const asn1cnst_range_t *range, const asn1cnst_range_t *r) {	if(!_edge_is_within(range, &r->left)) {		FATAL("Constraint value %s at line %d "			"is not within "			"a parent constraint range",			_edge_value(&r->left),			r->left.lineno		);		return -1;	}	if(!_edge_is_within(range, &r->right)) {		FATAL("Constraint value %s at line %d "			"is not within "			"a parent constraint range",			_edge_value(&r->right),			r->right.lineno		);		return -1;	}	return 0;}static int _range_merge_in(asn1cnst_range_t *into, asn1cnst_range_t *cr) {	asn1cnst_range_t *r;	int prev_count = into->el_count;	int i;	into->not_PER_visible |= cr->not_PER_visible;	into->extensible |= cr->extensible;	/*	 * Add the element OR all its children "into".	 */	for(i = -1; i < cr->el_count; i++) {		if(i == -1) {			if(cr->el_count) continue;			r = cr;		} else {			r = cr->elements[i];		}		if(_range_insert(into, r)) {			into->el_count = prev_count;	/* Undo */			return -1;		}	}	if(cr->el_count) {		cr->el_count = 0;		_range_free(cr);	} else {		/* This range is linked into "into". */	}	return 0;}static int _range_fill(asn1p_value_t *val, const asn1cnst_range_t *minmax, asn1cnst_edge_t *edge, asn1cnst_range_t *range, enum asn1p_constraint_type_e type, int lineno) {	unsigned char *p, *pend;	edge->lineno = lineno;	switch(val->type) {	case ATV_INTEGER:		if(type != ACT_EL_RANGE && type != ACT_CT_SIZE) {			FATAL("Integer %" PRIdASN " value invalid "				"for %s constraint at line %d",				val->value.v_integer,				asn1p_constraint_type2str(type), lineno);			return -1;		}		edge->type = ARE_VALUE;		edge->value = val->value.v_integer;		return 0;	case ATV_MIN:		if(type != ACT_EL_RANGE && type != ACT_CT_SIZE) {			FATAL("MIN invalid for %s constraint at line %d",				asn1p_constraint_type2str(type), lineno);			return -1;		}		edge->type = ARE_MIN;		if(minmax) *edge = minmax->left;		edge->lineno = lineno;	/* Restore lineno */		return 0;	case ATV_MAX:		if(type != ACT_EL_RANGE && type != ACT_CT_SIZE) {			FATAL("MAX invalid for %s constraint at line %d",				asn1p_constraint_type2str(type), lineno);			return -1;		}		edge->type = ARE_MAX;		if(minmax) *edge = minmax->right;		edge->lineno = lineno;	/* Restore lineno */		return 0;	case ATV_FALSE:	case ATV_TRUE:		if(type != ACT_EL_RANGE) {			FATAL("%s is invalid for %s constraint at line %d",				val->type==ATV_TRUE?"TRUE":"FALSE",				asn1p_constraint_type2str(type),				lineno);			return -1;		}		edge->type = ARE_VALUE;		edge->value = (val->type==ATV_TRUE);		return 0;	case ATV_STRING:		if(type != ACT_CT_FROM)			return 0;		break;	case ATV_REFERENCED:		FATAL("Unresolved constraint element \"%s\" at line %d",			asn1f_printable_reference(val->value.reference),			lineno);		return -1;	default:		FATAL("Unrecognized constraint element at line %d",			lineno);		return -1;	}	assert(val->type == ATV_STRING);	p = val->value.string.buf;	pend = p + val->value.string.size;	if(p == pend) return 0;	edge->type = ARE_VALUE;	if(val->value.string.size == 1) {		edge->value = *p;	} else {		/*		 * Else this is a set:		 * (FROM("abcdef"))		 * However, (FROM("abc".."def")) is forbidden.		 * See also 47.4.4.		 */		asn1c_integer_t vmin, vmax;		vmin = vmax = *p;		for(; p < pend; p++) {			asn1cnst_range_t *nr = _range_new();			int ret;			assert(nr);			if(*p < vmin) vmin = *p;			if(*p > vmax) vmax = *p;			ret = _range_insert(range, nr);			assert(ret == 0);			nr->left.type = ARE_VALUE;			nr->left.value = *p;			nr->left.lineno = lineno;			nr->right = nr->left;		}		edge->value = (edge == &range->right) ? vmin : vmax;	}	return 0;}/* * Check if ranges contain common elements. */static int_range_overlap(const asn1cnst_range_t *ra, const asn1cnst_range_t *rb) {	int lr, rl;	const asn1cnst_edge_t *ra_l = &ra->left;	const asn1cnst_edge_t *ra_r = &ra->right;	const asn1cnst_edge_t *rb_l = &rb->left;	const asn1cnst_edge_t *rb_r = &rb->right;	assert(_edge_compare(ra_l, ra_r) <= 0);	assert(_edge_compare(rb_l, rb_r) <= 0);	lr = _edge_compare(ra_l, rb_r);	rl = _edge_compare(ra_r, rb_l);	/*	 * L:       |---|	 * R: |---|	 */	if(lr > 0) return 0;	/*	 * L: |---|	 * R:       |---|	 */	if(rl < 0) return 0;	return 1;}/* * (MIN..20) x (10..15) = (MIN..9,10..15,16..20) */static asn1cnst_range_t *_range_split(asn1cnst_range_t *ra, const asn1cnst_range_t *rb) {	asn1cnst_range_t *range, *nr;	int ll, rr;	assert(ra);	assert(rb);	assert(!ra->el_count);	assert(!rb->el_count);	if(!_range_overlap(ra, rb)) {		errno = 0;		return 0;	}	ll = _edge_compare(&ra->left, &rb->left);	rr = _edge_compare(&ra->right, &rb->right);	/*	 * L:   |---|	 * R: |-------|	 */	if(ll >= 0 && rr <= 0) {		errno = 0;		return 0;	}	range = _range_new();	assert(range);	nr = _range_new();	assert(nr);	/*	 * L: |---...	 * R:   |--..	 */	if(ll < 0) {		nr->left = ra->left;		nr->right = rb->left;		if(nr->right.type == ARE_VALUE)			nr->right.value--;		_range_insert(range, nr);		nr = _range_new();		assert(nr);	}	/*	 * L: ...---|	 * R: ..--|	 */	if(rr > 0) {		nr->left = rb->right;		nr->right = ra->right;		if(nr->left.type == ARE_VALUE)			nr->left.value++;		_range_insert(range, nr);		nr = _range_new();		assert(nr);	}	/*	 * L:  |---|	 * R: |-----|	 */	nr->left = ra->left;	nr->right = ra->right;	if(_edge_compare(&ra->left, &rb->left) < 0)		nr->left = rb->left;	if(_edge_compare(&ra->right, &rb->right) > 0)		nr->right = rb->right;	_range_insert(range, nr);	return range;}static int_range_intersection(asn1cnst_range_t *range, const asn1cnst_range_t *with, int strict_edge_check) {	int ret;	int i, j;	assert(!range->incompatible);	/* Propagate errors */	range->extensible |= with->extensible;	range->not_PER_visible |= with->not_PER_visible;	range->empty_constraint |= with->empty_constraint;	if(range->empty_constraint) {		/* No use in intersecting empty constraints */		return 0;	}	/*	 * This is an AND operation.	 */	/* If this is the only element, insert it into itself as a child */	if(range->el_count == 0) {

⌨️ 快捷键说明

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