blob: 19c81e725a6a46be7fc65e80f7e12ba2b973b1f6 [file] [log] [blame]
vlmfa67ddc2004-06-03 03:38:44 +00001/*-
2 * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
3 * Redistribution and modifications are permitted subject to BSD license.
4 */
vlm39ba4c42004-09-22 16:06:28 +00005#include <asn_internal.h>
vlmfa67ddc2004-06-03 03:38:44 +00006#include <BIT_STRING.h>
vlm6678cb12004-09-26 13:10:40 +00007#include <asn_internal.h>
vlmfa67ddc2004-06-03 03:38:44 +00008
9/*
10 * BIT STRING basic type description.
11 */
vlmef6355b2004-09-29 13:26:15 +000012static ber_tlv_tag_t asn_DEF_BIT_STRING_tags[] = {
vlmfa67ddc2004-06-03 03:38:44 +000013 (ASN_TAG_CLASS_UNIVERSAL | (3 << 2))
14};
vlmef6355b2004-09-29 13:26:15 +000015asn_TYPE_descriptor_t asn_DEF_BIT_STRING = {
vlmfa67ddc2004-06-03 03:38:44 +000016 "BIT STRING",
vlm39ba4c42004-09-22 16:06:28 +000017 OCTET_STRING_free, /* Implemented in terms of OCTET STRING */
18 BIT_STRING_print,
vlmfa67ddc2004-06-03 03:38:44 +000019 BIT_STRING_constraint,
20 OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
21 OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
vlm39ba4c42004-09-22 16:06:28 +000022 0, /* Not implemented yet */
23 BIT_STRING_encode_xer,
vlmfa67ddc2004-06-03 03:38:44 +000024 0, /* Use generic outmost tag fetcher */
vlmef6355b2004-09-29 13:26:15 +000025 asn_DEF_BIT_STRING_tags,
26 sizeof(asn_DEF_BIT_STRING_tags)
27 / sizeof(asn_DEF_BIT_STRING_tags[0]),
28 asn_DEF_BIT_STRING_tags, /* Same as above */
29 sizeof(asn_DEF_BIT_STRING_tags)
30 / sizeof(asn_DEF_BIT_STRING_tags[0]),
vlme413c122004-08-20 13:23:42 +000031 0, 0, /* No members */
vlm6678cb12004-09-26 13:10:40 +000032 (void *)1 /* Special indicator that this is a BIT STRING */
vlmfa67ddc2004-06-03 03:38:44 +000033};
34
35/*
36 * BIT STRING generic constraint.
37 */
38int
vlmef6355b2004-09-29 13:26:15 +000039BIT_STRING_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
vlmfa67ddc2004-06-03 03:38:44 +000040 asn_app_consume_bytes_f *app_errlog, void *app_key) {
vlmda674682004-08-11 09:07:36 +000041 const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
vlmfa67ddc2004-06-03 03:38:44 +000042
43 if(st && st->buf) {
44 if(st->size) {
45 if(st->size == 1 && st->buf[0] != 0) {
vlme3f0f282004-08-11 09:44:13 +000046 _ASN_ERRLOG(app_errlog, app_key,
vlm758530a2004-08-22 13:47:59 +000047 "%s: invalid padding byte (%s:%d)",
48 td->name, __FILE__, __LINE__);
vlmfa67ddc2004-06-03 03:38:44 +000049 return -1;
50 }
51 } else {
vlme3f0f282004-08-11 09:44:13 +000052 _ASN_ERRLOG(app_errlog, app_key,
vlm758530a2004-08-22 13:47:59 +000053 "%s: no padding byte (%s:%d)",
54 td->name, __FILE__, __LINE__);
vlmfa67ddc2004-06-03 03:38:44 +000055 return -1;
56 }
57 } else {
vlme3f0f282004-08-11 09:44:13 +000058 _ASN_ERRLOG(app_errlog, app_key,
vlm758530a2004-08-22 13:47:59 +000059 "%s: value not given (%s:%d)",
60 td->name, __FILE__, __LINE__);
vlmfa67ddc2004-06-03 03:38:44 +000061 return -1;
62 }
63
64 return 0;
65}
66
vlm39ba4c42004-09-22 16:06:28 +000067static char *_bit_pattern[16] = {
68 "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
69 "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"
70};
71
72asn_enc_rval_t
vlmef6355b2004-09-29 13:26:15 +000073BIT_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
vlm39ba4c42004-09-22 16:06:28 +000074 int ilevel, enum xer_encoder_flags_e flags,
75 asn_app_consume_bytes_f *cb, void *app_key) {
76 asn_enc_rval_t er;
77 char scratch[128];
78 char *p = scratch;
79 char *scend = scratch + (sizeof(scratch) - 10);
80 const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
vlmef1b4c02004-09-23 22:06:26 +000081 int xcan = (flags & XER_F_CANONICAL);
vlm39ba4c42004-09-22 16:06:28 +000082 uint8_t *buf;
83 uint8_t *end;
84
85 if(!st || !st->buf)
86 _ASN_ENCODE_FAILED;
87
88 er.encoded = 0;
89
90 buf = st->buf;
91 end = buf + st->size - 1; /* Last byte is special */
92
93 /*
94 * Binary dump
95 */
96 for(buf++; buf < end; buf++) {
97 int v = *buf;
vlmef1b4c02004-09-23 22:06:26 +000098 int nline = xcan?0:((((buf - st->buf) - 1) % 8) == 0);
vlm39ba4c42004-09-22 16:06:28 +000099 if(p >= scend || nline) {
100 er.encoded += p - scratch;
101 _ASN_CALLBACK(scratch, p - scratch);
102 p = scratch;
103 if(nline) _i_ASN_TEXT_INDENT(1, ilevel);
104 }
105 memcpy(p + 0, _bit_pattern[v >> 4], 4);
106 memcpy(p + 4, _bit_pattern[v & 0x0f], 4);
107 p += 8;
108 }
109
vlmef1b4c02004-09-23 22:06:26 +0000110 if(!xcan && (((buf - st->buf) - 1) % 8) == 0)
111 _i_ASN_TEXT_INDENT(1, ilevel);
vlm1827a1c2004-09-24 20:56:25 +0000112 er.encoded += p - scratch;
113 _ASN_CALLBACK(scratch, p - scratch);
114 p = scratch;
vlm39ba4c42004-09-22 16:06:28 +0000115
vlm1827a1c2004-09-24 20:56:25 +0000116 if(buf == end) {
vlm39ba4c42004-09-22 16:06:28 +0000117 int v = *buf;
118 int mbit = st->buf[0]; /* bits to skip from the right */
119 int i;
120 for(i = 7; i >= mbit; i--)
vlmef6355b2004-09-29 13:26:15 +0000121 *p++ = (v & (1 << i)) ? 0x31 : 0x30;
vlm39ba4c42004-09-22 16:06:28 +0000122 er.encoded += p - scratch;
123 _ASN_CALLBACK(scratch, p - scratch);
124 }
125
vlm1827a1c2004-09-24 20:56:25 +0000126 if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
vlmef1b4c02004-09-23 22:06:26 +0000127
vlm39ba4c42004-09-22 16:06:28 +0000128 return er;
vlm84d551b2004-10-03 09:13:02 +0000129cb_failed:
130 _ASN_ENCODE_FAILED;
vlm39ba4c42004-09-22 16:06:28 +0000131}
132
133
vlmfa67ddc2004-06-03 03:38:44 +0000134/*
135 * BIT STRING specific contents printer.
136 */
137int
vlmef6355b2004-09-29 13:26:15 +0000138BIT_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
vlmfa67ddc2004-06-03 03:38:44 +0000139 asn_app_consume_bytes_f *cb, void *app_key) {
vlm1ff928d2004-08-11 08:10:13 +0000140 static const char *h2c = "0123456789ABCDEF";
vlmfa67ddc2004-06-03 03:38:44 +0000141 char scratch[64];
vlmda674682004-08-11 09:07:36 +0000142 const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
vlmfa67ddc2004-06-03 03:38:44 +0000143 uint8_t *buf;
144 uint8_t *end;
145 char *p = scratch;
146
vlmb42843a2004-06-05 08:17:50 +0000147 (void)td; /* Unused argument */
148
vlm6678cb12004-09-26 13:10:40 +0000149 if(!st || !st->buf)
150 return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
vlmfa67ddc2004-06-03 03:38:44 +0000151
vlm6678cb12004-09-26 13:10:40 +0000152 ilevel++;
vlmfa67ddc2004-06-03 03:38:44 +0000153 buf = st->buf;
154 end = buf + st->size;
155
156 /*
157 * Hexadecimal dump.
158 */
159 for(buf++; buf < end; buf++) {
vlmef1b4c02004-09-23 22:06:26 +0000160 if(((buf - st->buf) - 1) % 16 == 0 && (st->size > 17)
161 && buf != st->buf+1) {
vlm6678cb12004-09-26 13:10:40 +0000162 _i_INDENT(1);
vlmfa67ddc2004-06-03 03:38:44 +0000163 /* Dump the string */
vlm6678cb12004-09-26 13:10:40 +0000164 if(cb(scratch, p - scratch, app_key) < 0) return -1;
vlmfa67ddc2004-06-03 03:38:44 +0000165 p = scratch;
166 }
167 *p++ = h2c[*buf >> 4];
168 *p++ = h2c[*buf & 0x0F];
169 *p++ = 0x20;
170 }
vlmfa67ddc2004-06-03 03:38:44 +0000171
vlmef1b4c02004-09-23 22:06:26 +0000172 if(p > scratch) {
173 p--; /* Eat the tailing space */
174
175 if((st->size > 17)) {
vlm6678cb12004-09-26 13:10:40 +0000176 _i_INDENT(1);
vlmef1b4c02004-09-23 22:06:26 +0000177 }
178
179 /* Dump the incomplete 16-bytes row */
vlm6678cb12004-09-26 13:10:40 +0000180 if(cb(scratch, p - scratch, app_key) < 0)
vlmef1b4c02004-09-23 22:06:26 +0000181 return -1;
182 }
183
184 return 0;
vlmfa67ddc2004-06-03 03:38:44 +0000185}
186