1 #include "asn1fix_internal.h"
3 static int asn1f_fix_bit_string_type(arg_t *arg);
4 static int asn1f_fix_bit_string_value(arg_t *arg, asn1p_expr_t *ttype);
5 static void asn1f_BS_remove_trailing_zero_bits(asn1p_value_t *value);
6 static int asn1f_BS_unparsed_convert(arg_t *arg, asn1p_value_t *value, asn1p_expr_t *ttype);
9 asn1f_fix_bit_string(arg_t *arg) {
10 asn1p_expr_t *expr = arg->expr;
14 if(expr->meta_type == AMT_VALUE) {
17 DEBUG("(%s) for line %d", expr->Identifier, expr->_lineno);
19 ttype = asn1f_find_terminal_type(arg, expr);
20 if(ttype && ttype->expr_type == ASN_BASIC_BIT_STRING) {
21 ret = asn1f_fix_bit_string_value(arg, ttype);
22 RET2RVAL(ret, r_value);
26 if(expr->meta_type == AMT_TYPE
27 && expr->expr_type == ASN_BASIC_BIT_STRING) {
28 ret = asn1f_fix_bit_string_type(arg);
29 RET2RVAL(ret, r_value);
35 static int _compare_value(asn1p_expr_t *expr1, asn1p_expr_t *expr2) {
36 return expr2->value->value.v_integer - expr1->value->value.v_integer;
40 asn1f_fix_bit_string_type(arg_t *arg) {
41 asn1p_expr_t *expr = arg->expr;
46 TQ_FOR(v, &(expr->members), next) {
47 if(v->expr_type == A1TC_EXTENSIBLE) {
48 FATAL("Extension marker (...) is not allowed "
49 "as a BIT STRING NamedBit at line %d ",
53 if(v->expr_type != A1TC_UNIVERVAL) {
54 FATAL("BIT STRING value at line %d "
55 "is not an identifier", v->_lineno);
60 if(v->value == NULL) {
61 FATAL("BIT STRING NamedBit value at line %d "
62 "must be explicitly specified in braces",
65 } else if(v->value->type == ATV_REFERENCED) {
66 /* Resolve the value */
67 if(asn1f_value_resolve(arg, v, 0))
70 if(v->value->type != ATV_INTEGER
71 || v->value->value.v_integer < 0) {
72 FATAL("BIT STRING NamedBit value at line %d: "
73 "non-negative integer value expected",
78 /* Check value uniqueness as per 21.4 */
79 ret = asn1f_check_unique_expr_child(arg, v,
80 _compare_value, "value");
81 RET2RVAL(ret, r_value);
82 /* Check identifier uniqueness as per 21.5 */
83 ret = asn1f_check_unique_expr_child(arg, v, 0, "identifier");
84 RET2RVAL(ret, r_value);
91 asn1f_fix_bit_string_value(arg_t *arg, asn1p_expr_t *ttype) {
92 asn1p_expr_t *expr = arg->expr;
95 DEBUG("(%s) for line %d",
96 expr->Identifier, expr->_lineno);
98 switch(expr->value->type) {
101 * Most definitely we have something like
102 * value BitStringType1 ::= { a, b, c }
103 * which could not be parsed by the LALR parser, mostly
104 * because it requires knowledge about BitStringType1
105 * during the parsing. So, here's a little hack: we create
106 * a buffer containing the full specification of a module,
107 * which contains some pre-defined INTEGER type with the
108 * opaque definition "{ a, b, c }" from the bit string.
110 if(asn1f_BS_unparsed_convert(arg, expr->value, ttype)) {
114 /* Fall through: remove trailing zero bits */
117 asn1f_BS_remove_trailing_zero_bits(expr->value);
127 asn1f_BS_remove_trailing_zero_bits(asn1p_value_t *value) {
128 int lmfb = -1; /* Last meaningful byte position */
129 int bits; /* Number of bits in the BIT STRING value */
132 assert(value->type == ATV_BITVECTOR);
134 bits = value->value.binary_vector.size_in_bits;
136 * Figure out the rightmost meaningful byte.
138 for(b = 0; b < ((bits + 7) >> 3); b++) {
139 uint8_t uc = value->value.binary_vector.bits[b];
147 uc = value->value.binary_vector.bits[lmfb];
150 * Squeeze the bit string width until the rightmost
153 for(; uc && (uc & 1) == 0; uc >>= 1)
159 value->value.binary_vector.size_in_bits = bits;
163 asn1f_BS_unparsed_convert(arg_t *arg, asn1p_value_t *value, asn1p_expr_t *ttype) {
176 assert(value->type == ATV_UNPARSED);
178 psize = value->value.string.size + sizeof("M DEFINITIONS ::= BEGIN V ::= BIT STRING END") + 32;
183 ret = snprintf(p, psize,
184 "M DEFINITIONS ::=\nBEGIN\n"
185 "V ::= #BIT STRING %s\n"
187 value->value.string.buf
192 asn = asn1p_parse_buffer(p, psize, arg->expr->module->source_file_name,
193 arg->expr->_lineno, A1P_EXTENDED_VALUES);
196 FATAL("Cannot parse BIT STRING value %s "
197 "defined as %s at line %d",
198 arg->expr->Identifier,
199 value->value.string.buf,
205 mod = TQ_FIRST(&(asn->modules));
207 V = TQ_FIRST(&(mod->members));
209 assert(strcmp(V->Identifier, "V") == 0);
212 * Simple loop just to fetch the maximal bit position
213 * out of the BIT STRING value defined as NamedBitList.
216 TQ_FOR(bit, &(V->members), next) {
217 asn1p_expr_t *bitdef;
218 bitdef = asn1f_lookup_child(ttype, bit->Identifier);
219 if(bitdef && bitdef->value
220 && bitdef->value->type == ATV_INTEGER) {
221 if(bitdef->value->value.v_integer > aI)
222 aI = bitdef->value->value.v_integer;
226 if(aI > 1024 * 1024 * 8) { /* One megabyte */
227 FATAL("Unsupportedly large BIT STRING value \"%s\" "
228 "defined at line %d "
229 "(larger than 1MByte)",
230 arg->expr->Identifier,
237 bits = aI + 1; /* Number of bits is more than a last bit position */
238 bitbuf = calloc(1, 1 + ((bits + 7) / 8));
244 TQ_FOR(bit, &(V->members), next) {
245 asn1p_expr_t *bitdef;
249 WARNING("Identifier \"%s\" at line %d "
250 "must not have a value",
251 bit->Identifier, bit->_lineno);
252 RET2RVAL(1, r_value);
254 bitdef = asn1f_lookup_child(ttype, bit->Identifier);
256 FATAL("Identifier \"%s\" at line %d is not defined "
257 "in the \"%s\" type definition at line %d",
263 RET2RVAL(-1, r_value);
266 if(bitdef->value == NULL
267 || bitdef->value->type != ATV_INTEGER) {
268 FATAL("Broken identifier "
270 "referenced by \"%s\" at line %d",
273 arg->expr->Identifier,
276 RET2RVAL(-1, r_value);
280 assert(bitdef->value->value.v_integer < bits);
281 set_bit_pos = bitdef->value->value.v_integer;
282 bitbuf[set_bit_pos>>3] |= 1 << (7-(set_bit_pos % 8));
286 free(value->value.string.buf);
287 value->type = ATV_BITVECTOR;
288 value->value.binary_vector.bits = bitbuf;
289 value->value.binary_vector.size_in_bits = bits;