SIM-115: update simulator to use latest E2SM KPM version 3
[sim/e2-interface.git] / e2sim / asn1c / BIT_STRING.c
1 /*-
2  * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
3  * Redistribution and modifications are permitted subject to BSD license.
4  */
5 #include <asn_internal.h>
6 #include <BIT_STRING.h>
7
8 /*
9  * BIT STRING basic type description.
10  */
11 static const ber_tlv_tag_t asn_DEF_BIT_STRING_tags[] = {
12     (ASN_TAG_CLASS_UNIVERSAL | (3 << 2))
13 };
14 asn_OCTET_STRING_specifics_t asn_SPC_BIT_STRING_specs = {
15     sizeof(BIT_STRING_t),
16     offsetof(BIT_STRING_t, _asn_ctx),
17     ASN_OSUBV_BIT
18 };
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)
22     BIT_STRING_print,
23 #else
24     0,
25 #endif  /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
26     BIT_STRING_compare,
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 */
30 #else
31     0,
32     0,
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,
37 #else
38     0,
39     0,
40 #endif  /* !defined(ASN_DISABLE_XER_SUPPORT) */
41 #if !defined(ASN_DISABLE_JER_SUPPORT)
42     BIT_STRING_encode_jer,
43 #else
44     0,
45 #endif  /* !defined(ASN_DISABLE_JER_SUPPORT) */
46 #if !defined(ASN_DISABLE_OER_SUPPORT)
47     BIT_STRING_decode_oer,
48     BIT_STRING_encode_oer,
49 #else
50     0,
51     0,
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 */
56 #else
57     0,
58     0,
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 */
63 #else
64     0,
65     0,
66 #endif  /* !defined(ASN_DISABLE_APER_SUPPORT) */
67 #if !defined(ASN_DISABLE_RFILL_SUPPORT)
68     BIT_STRING_random_fill,
69 #else
70     0,
71 #endif  /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
72     0  /* Use generic outmost tag fetcher */
73 };
74 asn_TYPE_descriptor_t asn_DEF_BIT_STRING = {
75     "BIT STRING",
76     "BIT_STRING",
77     &asn_OP_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]),
84     {
85 #if !defined(ASN_DISABLE_OER_SUPPORT)
86         0,
87 #endif  /* !defined(ASN_DISABLE_OER_SUPPORT) */
88 #if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
89         0,
90 #endif  /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
91         BIT_STRING_constraint
92     },
93     0, 0,  /* No members */
94     &asn_SPC_BIT_STRING_specs
95 };
96
97 /*
98  * BIT STRING generic constraint.
99  */
100 int
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;
104
105         if(st && st->buf) {
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__);
111                         return -1;
112                 }
113         } else {
114                 ASN__CTFAIL(app_key, td, sptr,
115                         "%s: value not given (%s:%d)",
116                         td->name, __FILE__, __LINE__);
117                 return -1;
118         }
119
120         return 0;
121 }
122
123 /*
124  * Non-destructively remove the trailing 0-bits from the given bit string.
125  */
126 const BIT_STRING_t *
127 BIT_STRING__compactify(const BIT_STRING_t *st, BIT_STRING_t *tmp) {
128     const uint8_t *b;
129     union {
130         const uint8_t *c_buf;
131         uint8_t *nc_buf;
132     } unconst;
133
134     if(st->size == 0) {
135         assert(st->bits_unused == 0);
136         return st;
137     } else {
138         for(b = &st->buf[st->size - 1]; b > st->buf && *b == 0; b--) {
139             ;
140         }
141         /* b points to the last byte which may contain data */
142         if(*b) {
143             int unused = 7;
144             uint8_t v = *b;
145             v &= -(int8_t)v;
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;
151         } else {
152             tmp->size = b-st->buf;
153             tmp->bits_unused = 0;
154         }
155
156         assert(b >= st->buf);
157     }
158
159     unconst.c_buf = st->buf;
160     tmp->buf = unconst.nc_buf;
161     return tmp;
162 }
163
164 /*
165  * Lexicographically compare the common prefix of both strings,
166  * and if it is the same return -1 for the smallest string.
167  */
168 int
169 BIT_STRING_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
170                    const void *bptr) {
171     /*
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."
175      */
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;
180
181     (void)specs;
182     assert(specs && specs->subvariant == ASN_OSUBV_BIT);
183
184     if(a && b) {
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);
187         if(ret == 0) {
188             /* Figure out which string with equal prefixes is longer. */
189             if(a->size < b->size) {
190                 return -1;
191             } else if(a->size > b->size) {
192                 return 1;
193             } else {
194                 /* Figure out how many unused bits */
195                 if(a->bits_unused > b->bits_unused) {
196                     return -1;
197                 } else if(a->bits_unused < b->bits_unused) {
198                     return 1;
199                 } else {
200                     return 0;
201                 }
202             }
203         } else {
204             return ret;
205         }
206     } else if(!a && !b) {
207         return 0;
208     } else if(!a) {
209         return -1;
210     } else {
211         return 1;
212     }
213 }