2 * Copyright (c) 2003-2017 Lev Walkin <vlm@lionet.info>.
4 * Redistribution and modifications are permitted subject to BSD license.
6 #include <asn_internal.h>
7 #include <OCTET_STRING.h>
11 * OCTET STRING basic type description.
13 static const ber_tlv_tag_t asn_DEF_OCTET_STRING_tags[] = {
14 (ASN_TAG_CLASS_UNIVERSAL | (4 << 2))
16 asn_OCTET_STRING_specifics_t asn_SPC_OCTET_STRING_specs = {
17 sizeof(OCTET_STRING_t),
18 offsetof(OCTET_STRING_t, _asn_ctx),
21 asn_TYPE_operation_t asn_OP_OCTET_STRING = {
23 #if !defined(ASN_DISABLE_PRINT_SUPPORT)
24 OCTET_STRING_print, /* OCTET STRING generally means a non-ascii sequence */
27 #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
29 #if !defined(ASN_DISABLE_BER_SUPPORT)
30 OCTET_STRING_decode_ber,
31 OCTET_STRING_encode_der,
35 #endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
36 #if !defined(ASN_DISABLE_XER_SUPPORT)
37 OCTET_STRING_decode_xer_hex,
38 OCTET_STRING_encode_xer,
42 #endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
43 #if !defined(ASN_DISABLE_JER_SUPPORT)
44 OCTET_STRING_encode_jer,
47 #endif /* !defined(ASN_DISABLE_JER_SUPPORT) */
48 #if !defined(ASN_DISABLE_OER_SUPPORT)
49 OCTET_STRING_decode_oer,
50 OCTET_STRING_encode_oer,
54 #endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
55 #if !defined(ASN_DISABLE_UPER_SUPPORT)
56 OCTET_STRING_decode_uper, /* Unaligned PER decoder */
57 OCTET_STRING_encode_uper, /* Unaligned PER encoder */
61 #endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
62 #if !defined(ASN_DISABLE_APER_SUPPORT)
63 OCTET_STRING_decode_aper, /* Aligned PER decoder */
64 OCTET_STRING_encode_aper, /* Aligned PER encoder */
68 #endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
69 #if !defined(ASN_DISABLE_RFILL_SUPPORT)
70 OCTET_STRING_random_fill,
73 #endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
74 0 /* Use generic outmost tag fetcher */
76 asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = {
77 "OCTET STRING", /* Canonical name */
78 "OCTET_STRING", /* XML tag name */
80 asn_DEF_OCTET_STRING_tags,
81 sizeof(asn_DEF_OCTET_STRING_tags)
82 / sizeof(asn_DEF_OCTET_STRING_tags[0]),
83 asn_DEF_OCTET_STRING_tags, /* Same as above */
84 sizeof(asn_DEF_OCTET_STRING_tags)
85 / sizeof(asn_DEF_OCTET_STRING_tags[0]),
87 #if !defined(ASN_DISABLE_OER_SUPPORT)
89 #endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
90 #if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
92 #endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
93 asn_generic_no_constraint
95 0, 0, /* No members */
96 &asn_SPC_OCTET_STRING_specs
100 OCTET_STRING_free(const asn_TYPE_descriptor_t *td, void *sptr,
101 enum asn_struct_free_method method) {
102 OCTET_STRING_t *st = (OCTET_STRING_t *)sptr;
107 ASN_DEBUG("Freeing %s as OCTET STRING", td->name);
114 #if !defined(ASN_DISABLE_BER_SUPPORT)
115 const asn_OCTET_STRING_specifics_t *specs;
116 asn_struct_ctx_t *ctx;
118 specs = td->specifics
119 ? (const asn_OCTET_STRING_specifics_t *)td->specifics
120 : &asn_SPC_OCTET_STRING_specs;
121 ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
124 * Remove decode-time stack.
127 stck = (struct _stack *)ctx->ptr;
130 struct _stack_el *sel = stck->tail;
131 stck->tail = sel->prev;
136 #endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
139 case ASFM_FREE_EVERYTHING:
142 case ASFM_FREE_UNDERLYING:
144 case ASFM_FREE_UNDERLYING_AND_RESET:
147 ? ((const asn_OCTET_STRING_specifics_t *)(td->specifics))
149 : sizeof(OCTET_STRING_t));
155 * Conversion routines.
158 OCTET_STRING_fromBuf(OCTET_STRING_t *st, const char *str, int len) {
161 if(st == 0 || (str == 0 && len)) {
167 * Clear the OCTET STRING.
176 /* Determine the original string size, if not explicitly given */
180 /* Allocate and fill the memory */
181 buf = MALLOC(len + 1);
185 memcpy(buf, str, len);
186 ((uint8_t *)buf)[len] = '\0'; /* Couldn't use memcpy(len+1)! */
188 st->buf = (uint8_t *)buf;
195 OCTET_STRING_new_fromBuf(const asn_TYPE_descriptor_t *td, const char *str,
197 const asn_OCTET_STRING_specifics_t *specs =
198 td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics
199 : &asn_SPC_OCTET_STRING_specs;
202 st = (OCTET_STRING_t *)CALLOC(1, specs->struct_size);
203 if(st && str && OCTET_STRING_fromBuf(st, str, len)) {
212 * Lexicographically compare the common prefix of both strings,
213 * and if it is the same return -1 for the smallest string.
216 OCTET_STRING_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
218 const asn_OCTET_STRING_specifics_t *specs = td->specifics;
219 const OCTET_STRING_t *a = aptr;
220 const OCTET_STRING_t *b = bptr;
223 assert(!specs || specs->subvariant != ASN_OSUBV_BIT);
226 size_t common_prefix_size = a->size <= b->size ? a->size : b->size;
227 int ret = memcmp(a->buf, b->buf, common_prefix_size);
229 /* Figure out which string with equal prefixes is longer. */
230 if(a->size < b->size) {
232 } else if(a->size > b->size) {
238 return ret < 0 ? -1 : 1;
240 } else if(!a && !b) {
250 #if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
252 OCTET_STRING_per_get_characters(asn_per_data_t *po, uint8_t *buf,
253 size_t units, unsigned int bpc, unsigned int unit_bits,
254 long lb, long ub, const asn_per_constraints_t *pc) {
255 uint8_t *end = buf + units * bpc;
257 ASN_DEBUG("Expanding %d characters into (%ld..%ld):%d",
258 (int)units, lb, ub, unit_bits);
261 if((unsigned long)ub <= ((unsigned long)2 << (unit_bits - 1))) {
262 /* Decode without translation */
264 } else if(pc && pc->code2value) {
266 return 1; /* FATAL: can't have constrained
267 * UniversalString with more than
268 * 16 million code points */
269 for(; buf < end; buf += bpc) {
271 int code = per_get_few_bits(po, unit_bits);
272 if(code < 0) return -1; /* WMORE */
273 value = pc->code2value(code);
275 ASN_DEBUG("Code %d (0x%02x) is"
276 " not in map (%ld..%ld)",
278 return 1; /* FATAL */
281 case 1: *buf = value; break;
282 case 2: buf[0] = value >> 8; buf[1] = value; break;
283 case 4: buf[0] = value >> 24; buf[1] = value >> 16;
284 buf[2] = value >> 8; buf[3] = value; break;
290 /* Shortcut the no-op copying to the aligned structure */
291 if(lb == 0 && (unit_bits == 8 * bpc)) {
292 return per_get_many_bits(po, buf, 0, unit_bits * units);
295 for(; buf < end; buf += bpc) {
296 int32_t code = per_get_few_bits(po, unit_bits);
297 int32_t ch = code + lb;
298 if(code < 0) return -1; /* WMORE */
300 ASN_DEBUG("Code %d is out of range (%ld..%ld)",
302 return 1; /* FATAL */
305 case 1: *buf = ch; break;
306 case 2: buf[0] = ch >> 8; buf[1] = ch; break;
307 case 4: buf[0] = ch >> 24; buf[1] = ch >> 16;
308 buf[2] = ch >> 8; buf[3] = ch; break;
316 OCTET_STRING_per_put_characters(asn_per_outp_t *po, const uint8_t *buf,
317 size_t units, unsigned int bpc, unsigned int unit_bits,
318 long lb, long ub, const asn_per_constraints_t *pc) {
319 const uint8_t *end = buf + units * bpc;
321 ASN_DEBUG("Squeezing %d characters into (%ld..%ld):%d (%d bpc)",
322 (int)units, lb, ub, unit_bits, bpc);
325 if((unsigned long)ub <= ((unsigned long)2 << (unit_bits - 1))) {
328 } else if(pc && pc->value2code) {
329 for(; buf < end; buf += bpc) {
333 case 1: value = *(const uint8_t *)buf; break;
334 case 2: value = (buf[0] << 8) | buf[1]; break;
335 case 4: value = (buf[0] << 24) | (buf[1] << 16)
336 | (buf[2] << 8) | buf[3]; break;
339 code = pc->value2code(value);
341 ASN_DEBUG("Character %d (0x%02x) is"
342 " not in map (%ld..%ld)",
346 if(per_put_few_bits(po, code, unit_bits))
351 /* Shortcut the no-op copying to the aligned structure */
352 if(lb == 0 && (unit_bits == 8 * bpc)) {
353 return per_put_many_bits(po, buf, unit_bits * units);
356 for(ub -= lb; buf < end; buf += bpc) {
361 value = *(const uint8_t *)buf;
364 value = (buf[0] << 8) | buf[1];
367 value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
373 if(ch < 0 || ch > ub) {
374 ASN_DEBUG("Character %d (0x%02x) is out of range (%ld..%ld)", *buf,
378 if(per_put_few_bits(po, ch, unit_bits)) return -1;
383 #endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */