/src/open5gs/lib/asn1c/common/INTEGER_aper.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>. |
3 | | * All rights reserved. |
4 | | * Redistribution and modifications are permitted subject to BSD license. |
5 | | */ |
6 | | #include <asn_internal.h> |
7 | | #include <INTEGER.h> |
8 | | |
9 | | /* Return ceil(log2(v)) for positive v. */ |
10 | | static unsigned |
11 | 15.1k | aper_log2_ceil_size(size_t v) { |
12 | 15.1k | unsigned bits = 0; |
13 | 15.1k | size_t power = 1; |
14 | | |
15 | 51.5k | while(power < v) { |
16 | 36.3k | power <<= 1; |
17 | 36.3k | bits++; |
18 | 36.3k | } |
19 | | |
20 | 15.1k | return bits; |
21 | 15.1k | } |
22 | | |
23 | | asn_dec_rval_t |
24 | | INTEGER_decode_aper(const asn_codec_ctx_t *opt_codec_ctx, |
25 | | const asn_TYPE_descriptor_t *td, |
26 | 173k | const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { |
27 | 173k | const asn_INTEGER_specifics_t *specs = (const asn_INTEGER_specifics_t *)td->specifics; |
28 | 173k | asn_dec_rval_t rval = { RC_OK, 0 }; |
29 | 173k | INTEGER_t *st = (INTEGER_t *)*sptr; |
30 | 173k | const asn_per_constraint_t *ct; |
31 | 173k | asn_per_constraint_t ct_ext_copy; /* Local copy for extension case */ |
32 | 173k | int repeat; |
33 | 173k | int inext = 0; /* Track if value is in extension part (outside constraint range) */ |
34 | | |
35 | 173k | (void)opt_codec_ctx; |
36 | | |
37 | 173k | if(!st) { |
38 | 5.43k | st = (INTEGER_t *)(*sptr = CALLOC(1, sizeof(*st))); |
39 | 5.43k | if(!st) ASN__DECODE_FAILED; |
40 | 5.43k | } |
41 | | |
42 | 173k | if(!constraints) constraints = td->encoding_constraints.per_constraints; |
43 | 173k | ct = constraints ? &constraints->value : 0; |
44 | | |
45 | 173k | if(ct && ct->flags & APC_EXTENSIBLE) { |
46 | 3.94k | inext = per_get_few_bits(pd, 1); |
47 | 3.94k | if(inext < 0) ASN__DECODE_STARVED; |
48 | 3.93k | if(inext) { |
49 | | /* |
50 | | * Value encoded in extension root's extension container. |
51 | | * |
52 | | * If the original constraint was semi-constrained (only lower_bound |
53 | | * present), treat the extension value as semi-constrained too: |
54 | | * preserve lower_bound while allowing unconstrained length (range_bits=-1). |
55 | | * |
56 | | * If the original constraint was fully constrained or unconstrained, |
57 | | * extension values MUST be treated as fully unconstrained here. |
58 | | */ |
59 | 741 | if(ct->flags & APC_SEMI_CONSTRAINED) { |
60 | 0 | ct_ext_copy = *ct; |
61 | 0 | ct_ext_copy.flags = APC_SEMI_CONSTRAINED; |
62 | 0 | ct_ext_copy.range_bits = -1; |
63 | 0 | ct_ext_copy.effective_bits = -1; |
64 | 0 | ct = &ct_ext_copy; |
65 | 741 | } else { |
66 | | /* keep previous behavior for other cases */ |
67 | 741 | ct = 0; |
68 | 741 | } |
69 | 741 | } |
70 | 3.93k | } |
71 | | |
72 | 173k | FREEMEM(st->buf); |
73 | 173k | st->buf = 0; |
74 | 173k | st->size = 0; |
75 | 173k | if(ct) { |
76 | 172k | if(ct->flags & APC_SEMI_CONSTRAINED) { |
77 | 0 | st->buf = (uint8_t *)CALLOC(1, 2); |
78 | 0 | if(!st->buf) ASN__DECODE_FAILED; |
79 | 0 | st->size = 1; |
80 | 172k | } else if(ct->flags & APC_CONSTRAINED && ct->range_bits >= 0) { |
81 | 172k | size_t size = (ct->range_bits + 7) >> 3; |
82 | 172k | st->buf = (uint8_t *)MALLOC(1 + size + 1); |
83 | 172k | if(!st->buf) ASN__DECODE_FAILED; |
84 | 172k | st->size = size; |
85 | 172k | } |
86 | 172k | } |
87 | | |
88 | | /* X.691, #12.2.2 */ |
89 | 173k | if(ct && ct->flags != APC_UNCONSTRAINED) { |
90 | | /* #10.5.6 */ |
91 | 172k | ASN_DEBUG("Integer with range %d bits", ct->range_bits); |
92 | 172k | if(ct->range_bits >= 0) { |
93 | 172k | if (ct->range_bits > 16) { |
94 | | /* X.691 13.2.6: constrained whole number with range > 65536. */ |
95 | 15.1k | size_t max_range_bytes = ((size_t)ct->range_bits + 7) >> 3; |
96 | | /* Length determinant is (len - 1) in ceil(log2(max_bytes)) bits. */ |
97 | 15.1k | unsigned length_bits = aper_log2_ceil_size(max_range_bytes); |
98 | 15.1k | int len_minus_one; |
99 | 15.1k | size_t len; |
100 | 15.1k | intmax_t value = 0; |
101 | | |
102 | 15.1k | len_minus_one = per_get_few_bits(pd, length_bits); |
103 | 15.1k | if(len_minus_one < 0) ASN__DECODE_STARVED; |
104 | 15.0k | len = (size_t)len_minus_one + 1; |
105 | 15.0k | if(len > max_range_bytes || len > sizeof(value)) ASN__DECODE_FAILED; |
106 | 15.0k | ASN_DEBUG("Constrained INTEGER>16 decode: range_bits=%d max_bytes=%" ASN_PRI_SIZE " len_bits=%u len=%" ASN_PRI_SIZE, |
107 | 15.0k | ct->range_bits, max_range_bytes, length_bits, len); |
108 | | |
109 | 15.0k | if(aper_get_align(pd) < 0) ASN__DECODE_FAILED; |
110 | | |
111 | 31.8k | while(len > 0) { |
112 | 16.8k | int buf = per_get_few_bits(pd, 8); |
113 | 16.8k | if(buf < 0) ASN__DECODE_STARVED; |
114 | 16.7k | if(value > (INTMAX_MAX >> 8)) ASN__DECODE_FAILED; |
115 | 16.7k | value = (value << 8) | buf; |
116 | 16.7k | len--; |
117 | 16.7k | } |
118 | | |
119 | 14.9k | if(ct->upper_bound < ct->lower_bound) { |
120 | 1 | ASN__DECODE_FAILED; |
121 | 1 | } |
122 | 14.9k | if(value < 0) { |
123 | | /* Offset must not be negative */ |
124 | 0 | ASN__DECODE_FAILED; |
125 | 14.9k | } else { |
126 | 14.9k | intmax_t range = ct->upper_bound - ct->lower_bound; |
127 | 14.9k | if(range < 0) ASN__DECODE_FAILED; |
128 | 14.9k | if((uintmax_t)value > (uintmax_t)range) { |
129 | 142 | ASN__DECODE_FAILED; |
130 | 142 | } |
131 | 14.9k | } |
132 | | |
133 | | /* Add lower bound; safe after the above checks */ |
134 | 14.8k | value += ct->lower_bound; |
135 | | |
136 | | /* Validate the decoded value is within the constraint bounds */ |
137 | 14.8k | if(specs && specs->field_unsigned) { |
138 | 8.37k | if((uintmax_t)value > (uintmax_t)ct->upper_bound) |
139 | 0 | ASN__DECODE_FAILED; |
140 | 8.37k | if(asn_umax2INTEGER(st, (uintmax_t)value)) |
141 | 0 | ASN__DECODE_FAILED; |
142 | 8.37k | } else { |
143 | 6.47k | if(value < ct->lower_bound || value > ct->upper_bound) |
144 | 0 | ASN__DECODE_FAILED; |
145 | 6.47k | if(asn_imax2INTEGER(st, value)) |
146 | 0 | ASN__DECODE_FAILED; |
147 | 6.47k | } |
148 | | |
149 | 14.8k | ASN_DEBUG("Got value %"ASN_PRIdMAX" + low %"ASN_PRIdMAX"", |
150 | 14.8k | value, (intmax_t)ct->lower_bound); |
151 | 157k | } else { |
152 | 157k | intmax_t value = 0; |
153 | 157k | if (ct->range_bits < 8) { |
154 | 946 | value = per_get_few_bits(pd, ct->range_bits); |
155 | 946 | if(value < 0) ASN__DECODE_STARVED; |
156 | 156k | } else if (ct->range_bits == 8) { |
157 | 11.9k | if (aper_get_align(pd) < 0) |
158 | 0 | ASN__DECODE_FAILED; |
159 | 11.9k | value = per_get_few_bits(pd, ct->range_bits); |
160 | 11.9k | if(value < 0) ASN__DECODE_STARVED; |
161 | 144k | } else { |
162 | | /* Align */ |
163 | 144k | if (aper_get_align(pd) < 0) |
164 | 0 | ASN__DECODE_FAILED; |
165 | 144k | value = per_get_few_bits(pd, 16); |
166 | 144k | if(value < 0) ASN__DECODE_STARVED; |
167 | 144k | } |
168 | 156k | value += ct->lower_bound; |
169 | | /* Validate the decoded value is within the constraint bounds */ |
170 | 156k | if(specs && specs->field_unsigned) { |
171 | 0 | if((uintmax_t)value > (uintmax_t)ct->upper_bound) |
172 | 0 | ASN__DECODE_FAILED; |
173 | 0 | if(asn_umax2INTEGER(st, (uintmax_t)value)) |
174 | 0 | ASN__DECODE_FAILED; |
175 | 156k | } else { |
176 | 156k | if(value < ct->lower_bound || value > ct->upper_bound) |
177 | 41 | ASN__DECODE_FAILED; |
178 | 156k | if(asn_imax2INTEGER(st, value)) |
179 | 0 | ASN__DECODE_FAILED; |
180 | 156k | } |
181 | 156k | ASN_DEBUG("Got value %"ASN_PRIdMAX" + low %"ASN_PRIdMAX"", |
182 | 156k | value, (intmax_t)ct->lower_bound); |
183 | 156k | } |
184 | 171k | return rval; |
185 | 172k | } |
186 | | /* Semi-constrained (range_bits < 0): fall through to unconstrained decoding */ |
187 | 172k | } else { |
188 | 741 | ASN_DEBUG("Decoding unconstrained integer %s", td->name); |
189 | 741 | } |
190 | | |
191 | | /* X.691, #12.2.3, #12.2.4 */ |
192 | 741 | do { |
193 | 741 | ssize_t len; |
194 | 741 | void *p; |
195 | 741 | int ret; |
196 | | |
197 | | /* Get the PER length */ |
198 | 741 | len = aper_get_length(pd, -1, -1, -1, &repeat); |
199 | 741 | if(len < 0) ASN__DECODE_STARVED; |
200 | | |
201 | 715 | p = REALLOC(st->buf, st->size + len + 1); |
202 | 715 | if(!p) ASN__DECODE_FAILED; |
203 | 715 | st->buf = (uint8_t *)p; |
204 | | |
205 | 715 | ret = per_get_many_bits(pd, &st->buf[st->size], 0, 8 * len); |
206 | 715 | if(ret < 0) ASN__DECODE_STARVED; |
207 | 688 | st->size += len; |
208 | 688 | } while(repeat); |
209 | 688 | st->buf[st->size] = 0; /* JIC */ |
210 | | |
211 | | /* #12.2.3 */ |
212 | 688 | if(ct && ct->lower_bound) { |
213 | | /* |
214 | | * TODO: replace by in-place arithmetics. |
215 | | */ |
216 | 0 | long value; |
217 | 0 | if(asn_INTEGER2long(st, &value)) |
218 | 0 | ASN__DECODE_FAILED; |
219 | 0 | if(asn_long2INTEGER(st, value + ct->lower_bound)) |
220 | 0 | ASN__DECODE_FAILED; |
221 | 0 | } |
222 | | |
223 | 688 | return rval; |
224 | 688 | } |
225 | | |
226 | | asn_enc_rval_t |
227 | | INTEGER_encode_aper(const asn_TYPE_descriptor_t *td, |
228 | | const asn_per_constraints_t *constraints, |
229 | 0 | const void *sptr, asn_per_outp_t *po) { |
230 | 0 | const asn_INTEGER_specifics_t *specs = (const asn_INTEGER_specifics_t *)td->specifics; |
231 | 0 | asn_enc_rval_t er = {0,0,0}; |
232 | 0 | const INTEGER_t *st = (const INTEGER_t *)sptr; |
233 | 0 | const uint8_t *buf; |
234 | 0 | const uint8_t *end; |
235 | 0 | const asn_per_constraint_t *ct; |
236 | 0 | asn_per_constraint_t ct_ext_copy; /* Local copy for extension case */ |
237 | 0 | intmax_t value = 0; |
238 | |
|
239 | 0 | if(!st || st->size == 0) ASN__ENCODE_FAILED; |
240 | | |
241 | 0 | if(!constraints) constraints = td->encoding_constraints.per_constraints; |
242 | 0 | ct = constraints ? &constraints->value : 0; |
243 | |
|
244 | 0 | er.encoded = 0; |
245 | |
|
246 | 0 | if(ct) { |
247 | 0 | int inext = 0; |
248 | 0 | if(specs && specs->field_unsigned) { |
249 | 0 | uintmax_t uval; |
250 | 0 | if(asn_INTEGER2umax(st, &uval)) |
251 | 0 | ASN__ENCODE_FAILED; |
252 | | /* Check proper range */ |
253 | 0 | if(ct->flags & APC_SEMI_CONSTRAINED) { |
254 | 0 | if(uval < (uintmax_t)ct->lower_bound) |
255 | 0 | inext = 1; |
256 | 0 | } else if(ct->range_bits >= 0) { |
257 | 0 | if(uval < (uintmax_t)ct->lower_bound |
258 | 0 | || uval > (uintmax_t)ct->upper_bound) |
259 | 0 | inext = 1; |
260 | 0 | } |
261 | 0 | ASN_DEBUG("Value %"ASN_PRIdMAX" (%02x/%"ASN_PRI_SIZE") lb %"ASN_PRIdMAX" ub %"ASN_PRIdMAX" %s", |
262 | 0 | uval, st->buf[0], st->size, |
263 | 0 | (intmax_t)ct->lower_bound, |
264 | 0 | (intmax_t)ct->upper_bound, |
265 | 0 | inext ? "ext" : "fix"); |
266 | 0 | value = uval; |
267 | 0 | } else { |
268 | 0 | if(asn_INTEGER2imax(st, &value)) ASN__ENCODE_FAILED; |
269 | | /* Check proper range */ |
270 | 0 | if(ct->flags & APC_SEMI_CONSTRAINED) { |
271 | 0 | if(value < ct->lower_bound) |
272 | 0 | inext = 1; |
273 | 0 | } else if(ct->range_bits >= 0) { |
274 | 0 | if(value < ct->lower_bound |
275 | 0 | || value > ct->upper_bound) |
276 | 0 | inext = 1; |
277 | 0 | } |
278 | 0 | ASN_DEBUG("Value %"ASN_PRIdMAX" (%02x/%"ASN_PRI_SIZE") lb %"ASN_PRIdMAX" ub %"ASN_PRIdMAX" %s", |
279 | 0 | value, st->buf[0], st->size, |
280 | 0 | (intmax_t)ct->lower_bound, |
281 | 0 | (intmax_t)ct->upper_bound, |
282 | 0 | inext ? "ext" : "fix"); |
283 | 0 | } |
284 | 0 | if(ct->flags & APC_EXTENSIBLE) { |
285 | 0 | if(per_put_few_bits(po, inext, 1)) |
286 | 0 | ASN__ENCODE_FAILED; |
287 | 0 | if(inext) { |
288 | 0 | if(ct->flags & APC_SEMI_CONSTRAINED) { |
289 | 0 | ct_ext_copy = *ct; |
290 | 0 | ct_ext_copy.flags = APC_SEMI_CONSTRAINED; |
291 | 0 | ct_ext_copy.range_bits = -1; |
292 | 0 | ct_ext_copy.effective_bits = -1; |
293 | 0 | ct = &ct_ext_copy; |
294 | 0 | } else { |
295 | 0 | ct = 0; |
296 | 0 | } |
297 | 0 | } |
298 | 0 | } else if(inext) { |
299 | 0 | ASN__ENCODE_FAILED; |
300 | 0 | } |
301 | 0 | } |
302 | | |
303 | | /* X.691, #12.2.2 */ |
304 | 0 | if(ct && ct->range_bits >= 0) { |
305 | 0 | uintmax_t v; |
306 | | |
307 | | /* #10.5.6 */ |
308 | 0 | ASN_DEBUG("Encoding integer %"ASN_PRIdMAX" (%"ASN_PRIdMAX") with range %d bits", |
309 | 0 | value, (intmax_t)(value - ct->lower_bound), |
310 | 0 | ct->range_bits); |
311 | |
|
312 | 0 | v = value - ct->lower_bound; |
313 | | |
314 | | /* #12 <= 8 -> alignment ? */ |
315 | 0 | int range = ct->upper_bound - ct->lower_bound + 1; |
316 | 0 | if (ct->range_bits < 8 || (ct->range_bits == 8 && range < 256)) { |
317 | 0 | if(per_put_few_bits(po, 0x00 | v, ct->range_bits)) |
318 | 0 | ASN__ENCODE_FAILED; |
319 | 0 | } else if (ct->range_bits == 8) { |
320 | 0 | if(aper_put_align(po) < 0) |
321 | 0 | ASN__ENCODE_FAILED; |
322 | 0 | if(per_put_few_bits(po, 0x00 | v, ct->range_bits)) |
323 | 0 | ASN__ENCODE_FAILED; |
324 | 0 | } else if (ct->range_bits <= 16) { |
325 | | /* Consume the bytes to align on octet */ |
326 | 0 | if(aper_put_align(po) < 0) |
327 | 0 | ASN__ENCODE_FAILED; |
328 | 0 | if(per_put_few_bits(po, 0x0000 | v, 16)) |
329 | 0 | ASN__ENCODE_FAILED; |
330 | 0 | } else { |
331 | | /* X.691 13.2.6: constrained whole number with range > 65536. */ |
332 | 0 | size_t max_range_bytes = ((size_t)ct->range_bits + 7) >> 3; |
333 | | /* Determinant width for (num_bytes - 1). */ |
334 | 0 | unsigned length_bits = aper_log2_ceil_size(max_range_bytes); |
335 | 0 | size_t num_bytes = 0; |
336 | 0 | uint8_t buf[sizeof(v)]; |
337 | 0 | uintmax_t tmp = v; |
338 | |
|
339 | 0 | do { |
340 | 0 | num_bytes++; |
341 | 0 | tmp >>= 8; |
342 | 0 | } while(tmp); |
343 | |
|
344 | 0 | if(num_bytes > max_range_bytes || num_bytes > sizeof(buf)) |
345 | 0 | ASN__ENCODE_FAILED; |
346 | 0 | ASN_DEBUG("Constrained INTEGER>16 encode: range_bits=%d max_bytes=%" ASN_PRI_SIZE " len_bits=%u len=%" ASN_PRI_SIZE " offset=%" ASN_PRIuMAX, |
347 | 0 | ct->range_bits, max_range_bytes, length_bits, num_bytes, v); |
348 | |
|
349 | 0 | if(per_put_few_bits(po, num_bytes - 1, length_bits)) |
350 | 0 | ASN__ENCODE_FAILED; |
351 | | |
352 | 0 | if(aper_put_align(po) < 0) |
353 | 0 | ASN__ENCODE_FAILED; |
354 | | |
355 | 0 | tmp = v; |
356 | 0 | { |
357 | 0 | size_t i; |
358 | 0 | for(i = 0; i < num_bytes; i++) { |
359 | 0 | buf[num_bytes - i - 1] = (uint8_t)(tmp & 0xff); |
360 | 0 | tmp >>= 8; |
361 | 0 | } |
362 | 0 | } |
363 | |
|
364 | 0 | if(per_put_many_bits(po, buf, 8 * num_bytes)) |
365 | 0 | ASN__ENCODE_FAILED; |
366 | 0 | } |
367 | 0 | ASN__ENCODED_OK(er); |
368 | 0 | } |
369 | | |
370 | 0 | if(ct && ct->lower_bound) { |
371 | 0 | ASN_DEBUG("Adjust lower bound to %"ASN_PRIdMAX"", (intmax_t)ct->lower_bound); |
372 | | /* |
373 | | * Encode semi-constrained integer by subtracting lower bound. |
374 | | * Per X.691, the value is encoded as (value - lower_bound), |
375 | | * which is always non-negative. |
376 | | */ |
377 | 0 | INTEGER_t adjusted_int; |
378 | 0 | memset(&adjusted_int, 0, sizeof(adjusted_int)); |
379 | |
|
380 | 0 | if(specs && specs->field_unsigned) { |
381 | 0 | uintmax_t uval; |
382 | 0 | if(asn_INTEGER2umax(st, &uval)) |
383 | 0 | ASN__ENCODE_FAILED; |
384 | | /* Check that value is >= lower_bound to avoid underflow */ |
385 | 0 | if(uval < (uintmax_t)ct->lower_bound) |
386 | 0 | ASN__ENCODE_FAILED; |
387 | 0 | uval -= (uintmax_t)ct->lower_bound; |
388 | 0 | if(asn_umax2INTEGER(&adjusted_int, uval)) { |
389 | 0 | ASN_STRUCT_RESET(asn_DEF_INTEGER, &adjusted_int); |
390 | 0 | ASN__ENCODE_FAILED; |
391 | 0 | } |
392 | 0 | } else { |
393 | 0 | intmax_t sval; |
394 | 0 | if(asn_INTEGER2imax(st, &sval)) |
395 | 0 | ASN__ENCODE_FAILED; |
396 | | /* Check that value is >= lower_bound */ |
397 | 0 | if(sval < ct->lower_bound) |
398 | 0 | ASN__ENCODE_FAILED; |
399 | 0 | sval -= ct->lower_bound; |
400 | 0 | if(asn_imax2INTEGER(&adjusted_int, sval)) { |
401 | 0 | ASN_STRUCT_RESET(asn_DEF_INTEGER, &adjusted_int); |
402 | 0 | ASN__ENCODE_FAILED; |
403 | 0 | } |
404 | 0 | } |
405 | | |
406 | | /* Encode the adjusted value using unconstrained encoding */ |
407 | 0 | buf = adjusted_int.buf; |
408 | 0 | end = adjusted_int.buf + adjusted_int.size; |
409 | 0 | while(buf < end) { |
410 | 0 | int need_eom = 0; |
411 | 0 | ssize_t mayEncode = aper_put_length(po, -1, -1, end - buf, &need_eom); |
412 | 0 | if(mayEncode < 0) { |
413 | 0 | ASN_STRUCT_RESET(asn_DEF_INTEGER, &adjusted_int); |
414 | 0 | ASN__ENCODE_FAILED; |
415 | 0 | } |
416 | 0 | if(per_put_many_bits(po, buf, 8 * mayEncode)) { |
417 | 0 | ASN_STRUCT_RESET(asn_DEF_INTEGER, &adjusted_int); |
418 | 0 | ASN__ENCODE_FAILED; |
419 | 0 | } |
420 | 0 | buf += mayEncode; |
421 | 0 | if(need_eom && (aper_put_length(po, -1, -1, 0, NULL) < 0)) { |
422 | 0 | ASN_STRUCT_RESET(asn_DEF_INTEGER, &adjusted_int); |
423 | 0 | ASN__ENCODE_FAILED; |
424 | 0 | } |
425 | 0 | } |
426 | | |
427 | 0 | ASN_STRUCT_RESET(asn_DEF_INTEGER, &adjusted_int); |
428 | 0 | ASN__ENCODED_OK(er); |
429 | 0 | } |
430 | | |
431 | 0 | for(buf = st->buf, end = st->buf + st->size; buf < end;) { |
432 | 0 | int need_eom = 0; |
433 | 0 | ssize_t mayEncode = aper_put_length(po, -1, -1, end - buf, &need_eom); |
434 | 0 | if(mayEncode < 0) |
435 | 0 | ASN__ENCODE_FAILED; |
436 | 0 | if(per_put_many_bits(po, buf, 8 * mayEncode)) |
437 | 0 | ASN__ENCODE_FAILED; |
438 | 0 | buf += mayEncode; |
439 | 0 | if(need_eom && (aper_put_length(po, -1, -1, 0, NULL) < 0)) |
440 | 0 | ASN__ENCODE_FAILED; |
441 | 0 | } |
442 | | |
443 | 0 | ASN__ENCODED_OK(er); |
444 | 0 | } |