2 * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
3 * Redistribution and modifications are permitted subject to BSD license.
5 #include <asn_internal.h>
6 #include <BIT_STRING.h>
9 * BIT STRING basic type description.
11 static const ber_tlv_tag_t asn_DEF_BIT_STRING_tags[] = {
12 (ASN_TAG_CLASS_UNIVERSAL | (3 << 2))
14 asn_OCTET_STRING_specifics_t asn_SPC_BIT_STRING_specs = {
16 offsetof(BIT_STRING_t, _asn_ctx),
19 asn_TYPE_operation_t asn_OP_BIT_STRING = {
20 OCTET_STRING_free, /* Implemented in terms of OCTET STRING */
21 #if !defined(ASN_DISABLE_PRINT_SUPPORT)
25 #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
27 #if !defined(ASN_DISABLE_BER_SUPPORT)
28 OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
29 OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
33 #endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
34 #if !defined(ASN_DISABLE_XER_SUPPORT)
35 OCTET_STRING_decode_xer_binary,
36 BIT_STRING_encode_xer,
40 #endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
41 #if !defined(ASN_DISABLE_JER_SUPPORT)
42 BIT_STRING_encode_jer,
45 #endif /* !defined(ASN_DISABLE_JER_SUPPORT) */
46 #if !defined(ASN_DISABLE_OER_SUPPORT)
47 BIT_STRING_decode_oer,
48 BIT_STRING_encode_oer,
52 #endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
53 #if !defined(ASN_DISABLE_UPER_SUPPORT)
54 BIT_STRING_decode_uper, /* Unaligned PER decoder */
55 BIT_STRING_encode_uper, /* Unaligned PER encoder */
59 #endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
60 #if !defined(ASN_DISABLE_APER_SUPPORT)
61 OCTET_STRING_decode_aper, /* Aligned PER decoder */
62 OCTET_STRING_encode_aper, /* Aligned PER encoder */
66 #endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
67 #if !defined(ASN_DISABLE_RFILL_SUPPORT)
68 BIT_STRING_random_fill,
71 #endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
72 0 /* Use generic outmost tag fetcher */
74 asn_TYPE_descriptor_t asn_DEF_BIT_STRING = {
78 asn_DEF_BIT_STRING_tags,
79 sizeof(asn_DEF_BIT_STRING_tags)
80 / sizeof(asn_DEF_BIT_STRING_tags[0]),
81 asn_DEF_BIT_STRING_tags, /* Same as above */
82 sizeof(asn_DEF_BIT_STRING_tags)
83 / sizeof(asn_DEF_BIT_STRING_tags[0]),
85 #if !defined(ASN_DISABLE_OER_SUPPORT)
87 #endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
88 #if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
90 #endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
93 0, 0, /* No members */
94 &asn_SPC_BIT_STRING_specs
98 * BIT STRING generic constraint.
101 BIT_STRING_constraint(const asn_TYPE_descriptor_t *td, const void *sptr,
102 asn_app_constraint_failed_f *ctfailcb, void *app_key) {
103 const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
106 if((st->size == 0 && st->bits_unused)
107 || st->bits_unused < 0 || st->bits_unused > 7) {
108 ASN__CTFAIL(app_key, td, sptr,
109 "%s: invalid padding byte (%s:%d)",
110 td->name, __FILE__, __LINE__);
114 ASN__CTFAIL(app_key, td, sptr,
115 "%s: value not given (%s:%d)",
116 td->name, __FILE__, __LINE__);
124 * Non-destructively remove the trailing 0-bits from the given bit string.
127 BIT_STRING__compactify(const BIT_STRING_t *st, BIT_STRING_t *tmp) {
130 const uint8_t *c_buf;
135 assert(st->bits_unused == 0);
138 for(b = &st->buf[st->size - 1]; b > st->buf && *b == 0; b--) {
141 /* b points to the last byte which may contain data */
146 if(v & 0x0F) unused -= 4;
147 if(v & 0x33) unused -= 2;
148 if(v & 0x55) unused -= 1;
149 tmp->size = b-st->buf + 1;
150 tmp->bits_unused = unused;
152 tmp->size = b-st->buf;
153 tmp->bits_unused = 0;
156 assert(b >= st->buf);
159 unconst.c_buf = st->buf;
160 tmp->buf = unconst.nc_buf;
165 * Lexicographically compare the common prefix of both strings,
166 * and if it is the same return -1 for the smallest string.
169 BIT_STRING_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
172 * Remove information about trailing bits, since
173 * X.680 (08/2015) #22.7 "ensure that different semantics are not"
174 * "associated with [values that differ only in] the trailing 0 bits."
176 BIT_STRING_t compact_a, compact_b;
177 const BIT_STRING_t *a = BIT_STRING__compactify(aptr, &compact_a);
178 const BIT_STRING_t *b = BIT_STRING__compactify(bptr, &compact_b);
179 const asn_OCTET_STRING_specifics_t *specs = td->specifics;
182 assert(specs && specs->subvariant == ASN_OSUBV_BIT);
185 size_t common_prefix_size = a->size <= b->size ? a->size : b->size;
186 int ret = memcmp(a->buf, b->buf, common_prefix_size);
188 /* Figure out which string with equal prefixes is longer. */
189 if(a->size < b->size) {
191 } else if(a->size > b->size) {
194 /* Figure out how many unused bits */
195 if(a->bits_unused > b->bits_unused) {
197 } else if(a->bits_unused < b->bits_unused) {
206 } else if(!a && !b) {