blob: 0d3961d438e4ff7395c7048fd843f49fa02eeb2b [file] [log] [blame]
vlmfa67ddc2004-06-03 03:38:44 +00001#include "asn1fix_internal.h"
2
3int asn1f_fix_bit_string_value(arg_t *arg, asn1p_expr_t *ttype);
4static void asn1f_BS_remove_trailing_zero_bits(asn1p_value_t *value);
5static int asn1f_BS_unparsed_convert(arg_t *arg, asn1p_value_t *value, asn1p_expr_t *ttype);
6
7int
8asn1f_fix_bit_string(arg_t *arg) {
9 asn1p_expr_t *expr = arg->expr;
10 int r_value = 0;
11 int ret;
12
13 if(expr->meta_type == AMT_VALUE) {
14 asn1p_expr_t *ttype;
15
16 DEBUG("%s(%s) for line %d", __func__,
17 expr->Identifier, expr->_lineno);
18
19 ttype = asn1f_find_terminal_type(arg, expr, 0);
20 if(ttype && ttype->expr_type == ASN_BASIC_BIT_STRING) {
21 ret = asn1f_fix_bit_string_value(arg, ttype);
22 RET2RVAL(ret, r_value);
23 }
24 }
25
26 return r_value;
27}
28
29int
30asn1f_fix_bit_string_value(arg_t *arg, asn1p_expr_t *ttype) {
31 asn1p_expr_t *expr = arg->expr;
32 int r_value = 0;
33
34 DEBUG("%s(%s) for line %d", __func__,
35 expr->Identifier, expr->_lineno);
36
37 switch(expr->value->type) {
38 case ATV_UNPARSED:
39 /*
40 * Most definitely we have something like
41 * value BitStringType1 ::= { a, b, c }
42 * which could not be parsed by the LALR parser, mostly
43 * because it requires knowledge about BitStringType1
44 * during the parsing. So, here's a little hack: we create
45 * a buffer containing the full specification of a module,
46 * which contains some pre-defined INTEGER type with the
47 * opaque definition "{ a, b, c }" from the bit string.
48 */
49 if(asn1f_BS_unparsed_convert(arg, expr->value, ttype)) {
50 r_value = -1;
51 break;
52 }
53 /* Fall through: remove trailing zero bits */
54 case ATV_BITVECTOR:
55 asn1f_BS_remove_trailing_zero_bits(expr->value);
56 break;
57 default:
58 break;
59 }
60
61 return r_value;
62}
63
64static void
65asn1f_BS_remove_trailing_zero_bits(asn1p_value_t *value) {
66 int lmfb = -1; /* Last meaningful byte position */
67 int bits; /* Number of bits in the BIT STRING value */
68 int b;
69
70 assert(value->type == ATV_BITVECTOR);
71
72 bits = value->value.binary_vector.size_in_bits;
73 /*
74 * Figure out the rightmost meaningful byte.
75 */
76 for(b = 0; b < ((bits + 7) >> 3); b++) {
77 uint8_t uc = value->value.binary_vector.bits[b];
78 if(uc && b > lmfb)
79 lmfb = b;
80 }
81 if(lmfb == -1) {
82 bits = 0;
83 } else {
84 uint8_t uc;
85 uc = value->value.binary_vector.bits[lmfb];
86 bits = (lmfb+1) * 8;
87 /*
88 * Squeeze the bit string width until the rightmost
89 * bit is set.
90 */
91 for(; uc && (uc & 1) == 0; uc >>= 1)
92 bits--;
93 if(uc == 0) {
94 bits = lmfb * 8;
95 }
96 }
97 value->value.binary_vector.size_in_bits = bits;
98}
99
100static int
101asn1f_BS_unparsed_convert(arg_t *arg, asn1p_value_t *value, asn1p_expr_t *ttype) {
102 asn1p_t *asn;
103 asn1p_module_t *mod;
104 asn1p_expr_t *V;
105 asn1p_expr_t *bit;
106 asn1_integer_t aI;
107 uint8_t *bitbuf;
108 int bits;
109 int psize;
110 char *p;
111 int ret;
112 int r_value = 0;
113
114 assert(value->type == ATV_UNPARSED);
115
116 psize = value->value.string.size + 64;
117 p = malloc(psize);
118 if(p == NULL)
119 return -1;
120
121 ret = snprintf(p, psize,
122 "M DEFINITIONS ::=\nBEGIN\n"
123 "V ::= INTEGER %s\n"
124 "END\n",
125 value->value.string.buf
126 );
127 assert(ret < psize);
128 psize = ret;
129
130 asn = asn1p_parse_buffer(p, psize, A1P_NOFLAGS);
131 free(p);
132 if(asn == NULL) {
133 FATAL("Cannot parse BIT STRING value %s "
134 "defined as %s at line %d",
135 arg->expr->Identifier,
136 value->value.string.buf,
137 arg->expr->_lineno
138 );
139 return -1;
140 }
141
142 mod = TQ_FIRST(&(asn->modules));
143 assert(mod);
144 V = TQ_FIRST(&(mod->members));
145 assert(V);
146 assert(strcmp(V->Identifier, "V") == 0);
147 assert(TQ_FIRST(&(V->members)));
148
149 /*
150 * Simple loop just to fetch the maximal bit position
151 * out of the BIT STRING value defined as NamedBitList.
152 */
153 aI = -1;
154 TQ_FOR(bit, &(V->members), next) {
155 asn1p_expr_t *bitdef;
156 bitdef = asn1f_lookup_child(ttype, bit->Identifier);
157 if(bitdef && bitdef->value
158 && bitdef->value->type == ATV_INTEGER) {
159 if(bitdef->value->value.v_integer > aI)
160 aI = bitdef->value->value.v_integer;
161 }
162 }
163
164 if(aI > 1024 * 1024 * 8) { /* One megabyte */
165 FATAL("Unsupportedly large BIT STRING value \"%s\" "
166 "defined at line %d "
167 "(larger than 1MByte)",
168 arg->expr->Identifier,
169 arg->expr->_lineno
170 );
171 asn1p_free(asn);
172 return -1;
173 }
174
175 bits = aI + 1; /* Number of bits is more than a last bit position */
176 bitbuf = calloc(1, 1 + ((bits + 7) / 8));
177 if(bitbuf == NULL) {
178 asn1p_free(asn);
179 return -1;
180 }
181
182 TQ_FOR(bit, &(V->members), next) {
183 asn1p_expr_t *bitdef;
184 int set_bit_pos;
185
186 if(bit->value) {
187 WARNING("Identifier \"%s\" at line %d "
188 "must not have a value",
189 bit->Identifier, bit->_lineno);
190 RET2RVAL(1, r_value);
191 }
192 bitdef = asn1f_lookup_child(ttype, bit->Identifier);
193 if(bitdef == NULL) {
194 FATAL("Identifier \"%s\" at line %d is not defined "
195 "in the \"%s\" type definition at line %d",
196 bit->Identifier,
197 bit->_lineno,
198 ttype->Identifier,
199 ttype->_lineno
200 );
201 RET2RVAL(-1, r_value);
202 continue;
203 }
204 if(bitdef->value == NULL
205 || bitdef->value->type != ATV_INTEGER) {
206 FATAL("Broken identifier "
207 "\"%s\" at line %d "
208 "referenced by \"%s\" at line %d",
209 bitdef->Identifier,
210 bitdef->_lineno,
211 arg->expr->Identifier,
212 arg->expr->_lineno
213 );
214 RET2RVAL(-1, r_value);
215 continue;
216 }
217
218 assert(bitdef->value->value.v_integer < bits);
219 set_bit_pos = bitdef->value->value.v_integer;
220 bitbuf[set_bit_pos>>3] |= 1 << (7-(set_bit_pos % 8));
221 }
222
223 asn1p_free(asn);
224 free(value->value.string.buf);
225 value->type = ATV_BITVECTOR;
226 value->value.binary_vector.bits = bitbuf;
227 value->value.binary_vector.size_in_bits = bits;
228
229 return r_value;
230}