X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=libasn1fix%2Fasn1fix_bitstring.c;fp=libasn1fix%2Fasn1fix_bitstring.c;h=0000000000000000000000000000000000000000;hb=7bfd112193698e9340c01e9260e3f14889f0cbe0;hp=e5f80cd1440709630fd2aba217716c064ddd5624;hpb=0c91129502aa163bb0e1d6d0ca7c807560ffb588;p=com%2Fasn1c.git diff --git a/libasn1fix/asn1fix_bitstring.c b/libasn1fix/asn1fix_bitstring.c deleted file mode 100644 index e5f80cd..0000000 --- a/libasn1fix/asn1fix_bitstring.c +++ /dev/null @@ -1,292 +0,0 @@ -#include "asn1fix_internal.h" - -static int asn1f_fix_bit_string_type(arg_t *arg); -static int asn1f_fix_bit_string_value(arg_t *arg, asn1p_expr_t *ttype); -static void asn1f_BS_remove_trailing_zero_bits(asn1p_value_t *value); -static int asn1f_BS_unparsed_convert(arg_t *arg, asn1p_value_t *value, asn1p_expr_t *ttype); - -int -asn1f_fix_bit_string(arg_t *arg) { - asn1p_expr_t *expr = arg->expr; - int r_value = 0; - int ret; - - if(expr->meta_type == AMT_VALUE) { - asn1p_expr_t *ttype; - - DEBUG("(%s) for line %d", expr->Identifier, expr->_lineno); - - ttype = asn1f_find_terminal_type(arg, expr); - if(ttype && ttype->expr_type == ASN_BASIC_BIT_STRING) { - ret = asn1f_fix_bit_string_value(arg, ttype); - RET2RVAL(ret, r_value); - } - } - - if(expr->meta_type == AMT_TYPE - && expr->expr_type == ASN_BASIC_BIT_STRING) { - ret = asn1f_fix_bit_string_type(arg); - RET2RVAL(ret, r_value); - } - - return r_value; -} - -static int _compare_value(asn1p_expr_t *expr1, asn1p_expr_t *expr2) { - return expr2->value->value.v_integer - expr1->value->value.v_integer; -} - -static int -asn1f_fix_bit_string_type(arg_t *arg) { - asn1p_expr_t *expr = arg->expr; - asn1p_expr_t *v; - int r_value = 0; - int ret; - - TQ_FOR(v, &(expr->members), next) { - if(v->expr_type == A1TC_EXTENSIBLE) { - FATAL("Extension marker (...) is not allowed " - "as a BIT STRING NamedBit at line %d ", - v->_lineno); - return -1; - } - if(v->expr_type != A1TC_UNIVERVAL) { - FATAL("BIT STRING value at line %d " - "is not an identifier", v->_lineno); - return -1; - } - - /* 21.1 */ - if(v->value == NULL) { - FATAL("BIT STRING NamedBit value at line %d " - "must be explicitly specified in braces", - v->_lineno); - return -1; - } else if(v->value->type == ATV_REFERENCED) { - /* Resolve the value */ - if(asn1f_value_resolve(arg, v, 0)) - return -1; - } - if(v->value->type != ATV_INTEGER - || v->value->value.v_integer < 0) { - FATAL("BIT STRING NamedBit value at line %d: " - "non-negative integer value expected", - v->_lineno); - return -1; - } - - /* Check value uniqueness as per 21.4 */ - ret = asn1f_check_unique_expr_child(arg, v, - _compare_value, "value"); - RET2RVAL(ret, r_value); - /* Check identifier uniqueness as per 21.5 */ - ret = asn1f_check_unique_expr_child(arg, v, 0, "identifier"); - RET2RVAL(ret, r_value); - } - - return r_value; -} - -static int -asn1f_fix_bit_string_value(arg_t *arg, asn1p_expr_t *ttype) { - asn1p_expr_t *expr = arg->expr; - int r_value = 0; - - DEBUG("(%s) for line %d", - expr->Identifier, expr->_lineno); - - switch(expr->value->type) { - case ATV_UNPARSED: - /* - * Most definitely we have something like - * value BitStringType1 ::= { a, b, c } - * which could not be parsed by the LALR parser, mostly - * because it requires knowledge about BitStringType1 - * during the parsing. So, here's a little hack: we create - * a buffer containing the full specification of a module, - * which contains some pre-defined INTEGER type with the - * opaque definition "{ a, b, c }" from the bit string. - */ - if(asn1f_BS_unparsed_convert(arg, expr->value, ttype)) { - r_value = -1; - break; - } - /* Fall through: remove trailing zero bits */ - /* Fall through */ - case ATV_BITVECTOR: - asn1f_BS_remove_trailing_zero_bits(expr->value); - break; - default: - break; - } - - return r_value; -} - -static void -asn1f_BS_remove_trailing_zero_bits(asn1p_value_t *value) { - int lmfb = -1; /* Last meaningful byte position */ - int bits; /* Number of bits in the BIT STRING value */ - int b; - - assert(value->type == ATV_BITVECTOR); - - bits = value->value.binary_vector.size_in_bits; - /* - * Figure out the rightmost meaningful byte. - */ - for(b = 0; b < ((bits + 7) >> 3); b++) { - uint8_t uc = value->value.binary_vector.bits[b]; - if(uc && b > lmfb) - lmfb = b; - } - if(lmfb == -1) { - bits = 0; - } else { - uint8_t uc; - uc = value->value.binary_vector.bits[lmfb]; - bits = (lmfb+1) * 8; - /* - * Squeeze the bit string width until the rightmost - * bit is set. - */ - for(; uc && (uc & 1) == 0; uc >>= 1) - bits--; - if(uc == 0) { - bits = lmfb * 8; - } - } - value->value.binary_vector.size_in_bits = bits; -} - -static int -asn1f_BS_unparsed_convert(arg_t *arg, asn1p_value_t *value, asn1p_expr_t *ttype) { - asn1p_t *asn; - asn1p_module_t *mod; - asn1p_expr_t *V; - asn1p_expr_t *bit; - asn1c_integer_t aI; - uint8_t *bitbuf; - int bits; - int psize; - char *p; - int ret; - int r_value = 0; - - assert(value->type == ATV_UNPARSED); - - psize = value->value.string.size + sizeof("M DEFINITIONS ::= BEGIN V ::= BIT STRING END") + 32; - p = malloc(psize); - if(p == NULL) - return -1; - - ret = snprintf(p, psize, - "M DEFINITIONS ::=\nBEGIN\n" - "V ::= #BIT STRING %s\n" - "END\n", - value->value.string.buf - ); - assert(ret < psize); - psize = ret; - - asn = asn1p_parse_buffer(p, psize, arg->expr->module->source_file_name, - arg->expr->_lineno, A1P_EXTENDED_VALUES); - free(p); - if(asn == NULL) { - FATAL("Cannot parse BIT STRING value %s " - "defined as %s at line %d", - arg->expr->Identifier, - value->value.string.buf, - arg->expr->_lineno - ); - return -1; - } - - mod = TQ_FIRST(&(asn->modules)); - assert(mod); - V = TQ_FIRST(&(mod->members)); - assert(V); - assert(strcmp(V->Identifier, "V") == 0); - - /* - * Simple loop just to fetch the maximal bit position - * out of the BIT STRING value defined as NamedBitList. - */ - aI = -1; - TQ_FOR(bit, &(V->members), next) { - asn1p_expr_t *bitdef; - bitdef = asn1f_lookup_child(ttype, bit->Identifier); - if(bitdef && bitdef->value - && bitdef->value->type == ATV_INTEGER) { - if(bitdef->value->value.v_integer > aI) - aI = bitdef->value->value.v_integer; - } - } - - if(aI > 1024 * 1024 * 8) { /* One megabyte */ - FATAL("Unsupportedly large BIT STRING value \"%s\" " - "defined at line %d " - "(larger than 1MByte)", - arg->expr->Identifier, - arg->expr->_lineno - ); - asn1p_delete(asn); - return -1; - } - - bits = aI + 1; /* Number of bits is more than a last bit position */ - bitbuf = calloc(1, 1 + ((bits + 7) / 8)); - if(bitbuf == NULL) { - asn1p_delete(asn); - return -1; - } - - TQ_FOR(bit, &(V->members), next) { - asn1p_expr_t *bitdef; - int set_bit_pos; - - if(bit->value) { - WARNING("Identifier \"%s\" at line %d " - "must not have a value", - bit->Identifier, bit->_lineno); - RET2RVAL(1, r_value); - } - bitdef = asn1f_lookup_child(ttype, bit->Identifier); - if(bitdef == NULL) { - FATAL("Identifier \"%s\" at line %d is not defined " - "in the \"%s\" type definition at line %d", - bit->Identifier, - bit->_lineno, - ttype->Identifier, - ttype->_lineno - ); - RET2RVAL(-1, r_value); - continue; - } - if(bitdef->value == NULL - || bitdef->value->type != ATV_INTEGER) { - FATAL("Broken identifier " - "\"%s\" at line %d " - "referenced by \"%s\" at line %d", - bitdef->Identifier, - bitdef->_lineno, - arg->expr->Identifier, - arg->expr->_lineno - ); - RET2RVAL(-1, r_value); - continue; - } - - assert(bitdef->value->value.v_integer < bits); - set_bit_pos = bitdef->value->value.v_integer; - bitbuf[set_bit_pos>>3] |= 1 << (7-(set_bit_pos % 8)); - } - - asn1p_delete(asn); - free(value->value.string.buf); - value->type = ATV_BITVECTOR; - value->value.binary_vector.bits = bitbuf; - value->value.binary_vector.size_in_bits = bits; - - return r_value; -}