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