Lev Walkin | ae1422b | 2013-03-24 02:08:42 -0700 | [diff] [blame] | 1 | #include <stdio.h> |
| 2 | #include <assert.h> |
| 3 | |
Lev Walkin | ae1422b | 2013-03-24 02:08:42 -0700 | [diff] [blame] | 4 | #include <INTEGER.h> |
| 5 | #include <INTEGER.c> |
| 6 | #include <per_support.c> |
| 7 | #include <per_support.h> |
| 8 | |
| 9 | static int FailOut(const void *data, size_t size, void *op_key) { |
Lev Walkin | 9736348 | 2016-01-24 19:23:02 -0800 | [diff] [blame] | 10 | (void)data; |
| 11 | (void)size; |
| 12 | (void)op_key; |
Lev Walkin | ae1422b | 2013-03-24 02:08:42 -0700 | [diff] [blame] | 13 | assert(!"UNREACHABLE"); |
| 14 | return 0; |
| 15 | } |
| 16 | |
| 17 | static void normalize(asn_per_outp_t *po) { |
| 18 | if(po->nboff >= 8) { |
| 19 | po->buffer += (po->nboff >> 3); |
| 20 | po->nbits -= (po->nboff & ~0x07); |
| 21 | po->nboff &= 0x07; |
| 22 | } |
| 23 | } |
| 24 | |
| 25 | static void |
| 26 | check_per_encode_constrained(int lineno, int unsigned_, long value, long lbound, unsigned long ubound, int bit_range) { |
| 27 | INTEGER_t st; |
| 28 | INTEGER_t *reconstructed_st = 0; |
Wim Lewis | fb6344e | 2014-07-28 12:16:01 -0700 | [diff] [blame] | 29 | struct asn_INTEGER_specifics_s specs; |
Wim Lewis | 18c2ec9 | 2014-07-29 11:30:10 -0700 | [diff] [blame] | 30 | struct asn_per_constraints_s cts; |
Lev Walkin | ae1422b | 2013-03-24 02:08:42 -0700 | [diff] [blame] | 31 | asn_enc_rval_t enc_rval; |
| 32 | asn_dec_rval_t dec_rval; |
| 33 | asn_per_outp_t po; |
| 34 | asn_per_data_t pd; |
Lev Walkin | ae1422b | 2013-03-24 02:08:42 -0700 | [diff] [blame] | 35 | |
Lev Walkin | 20a01f9 | 2013-03-28 00:22:08 -0700 | [diff] [blame] | 36 | if(unsigned_) |
| 37 | printf("%d: Recoding %s %lu [%ld..%lu]\n", lineno, |
| 38 | unsigned_ ? "unsigned" : "signed", value, lbound, ubound); |
| 39 | else |
| 40 | printf("%d: Recoding %s %ld [%ld..%lu]\n", lineno, |
| 41 | unsigned_ ? "unsigned" : "signed", value, lbound, ubound); |
Lev Walkin | ae1422b | 2013-03-24 02:08:42 -0700 | [diff] [blame] | 42 | |
| 43 | memset(&st, 0, sizeof(st)); |
| 44 | memset(&po, 0, sizeof(po)); |
| 45 | memset(&pd, 0, sizeof(pd)); |
| 46 | memset(&cts, 0, sizeof(cts)); |
| 47 | memset(&specs, 0, sizeof(specs)); |
| 48 | |
| 49 | cts.value.flags = APC_CONSTRAINED; |
| 50 | cts.value.range_bits = bit_range; |
| 51 | cts.value.effective_bits = bit_range; |
| 52 | cts.value.lower_bound = lbound; |
| 53 | cts.value.upper_bound = ubound; |
| 54 | |
Lev Walkin | 20a01f9 | 2013-03-28 00:22:08 -0700 | [diff] [blame] | 55 | if(unsigned_) |
| 56 | asn_ulong2INTEGER(&st, (unsigned long)value); |
| 57 | else |
| 58 | asn_long2INTEGER(&st, value); |
Lev Walkin | ae1422b | 2013-03-24 02:08:42 -0700 | [diff] [blame] | 59 | |
| 60 | po.buffer = po.tmpspace; |
| 61 | po.nboff = 0; |
| 62 | po.nbits = 8 * sizeof(po.tmpspace); |
| 63 | po.outper = FailOut; |
| 64 | |
| 65 | specs.field_width = sizeof(long); |
| 66 | specs.field_unsigned = unsigned_; |
| 67 | |
| 68 | asn_DEF_INTEGER.specifics = &specs; |
| 69 | enc_rval = INTEGER_encode_uper(&asn_DEF_INTEGER, &cts, &st, &po); |
| 70 | assert(enc_rval.encoded == 0); |
| 71 | |
| 72 | normalize(&po); |
| 73 | |
| 74 | assert(po.buffer == &po.tmpspace[bit_range / 8]); |
Lev Walkin | 20a01f9 | 2013-03-28 00:22:08 -0700 | [diff] [blame] | 75 | |
| 76 | if(unsigned_) { |
| 77 | unsigned long recovered_value = |
| 78 | ((uint32_t)po.tmpspace[0] << 24) |
| 79 | | ((uint32_t)po.tmpspace[1] << 16) |
| 80 | | ((uint32_t)po.tmpspace[2] << 8) |
| 81 | | ((uint32_t)po.tmpspace[3] << 0); |
| 82 | recovered_value >>= (32 - bit_range); |
| 83 | recovered_value += cts.value.lower_bound; |
| 84 | assert(recovered_value == (unsigned long)value); |
| 85 | } else { |
| 86 | long recovered_value = |
| 87 | ((uint32_t)po.tmpspace[0] << 24) |
| 88 | | ((uint32_t)po.tmpspace[1] << 16) |
| 89 | | ((uint32_t)po.tmpspace[2] << 8) |
| 90 | | ((uint32_t)po.tmpspace[3] << 0); |
| 91 | recovered_value = (unsigned long)recovered_value >> (32 - bit_range); |
| 92 | recovered_value += cts.value.lower_bound; |
| 93 | assert((long)recovered_value == value); |
| 94 | } |
Lev Walkin | 9736348 | 2016-01-24 19:23:02 -0800 | [diff] [blame] | 95 | assert(po.nboff == (size_t)((bit_range == 32) ? 0 : (8 - (32 - bit_range)))); |
Lev Walkin | ae1422b | 2013-03-24 02:08:42 -0700 | [diff] [blame] | 96 | assert(po.nbits == 8 * (sizeof(po.tmpspace) - (po.buffer-po.tmpspace))); |
| 97 | assert(po.flushed_bytes == 0); |
| 98 | |
| 99 | pd.buffer = po.tmpspace; |
| 100 | pd.nboff = 0; |
| 101 | pd.nbits = 8 * (po.buffer - po.tmpspace) + po.nboff; |
| 102 | pd.moved = 0; |
| 103 | dec_rval = INTEGER_decode_uper(0, &asn_DEF_INTEGER, &cts, |
| 104 | (void **)&reconstructed_st, &pd); |
Lev Walkin | 20a01f9 | 2013-03-28 00:22:08 -0700 | [diff] [blame] | 105 | assert(dec_rval.code == RC_OK); |
| 106 | if(unsigned_) { |
| 107 | unsigned long reconstructed_value = 0; |
| 108 | asn_INTEGER2ulong(reconstructed_st, &reconstructed_value); |
| 109 | assert(reconstructed_value == (unsigned long)value); |
| 110 | } else { |
| 111 | long reconstructed_value = 0; |
| 112 | asn_INTEGER2long(reconstructed_st, &reconstructed_value); |
| 113 | assert(reconstructed_value == value); |
| 114 | } |
Lev Walkin | ae1422b | 2013-03-24 02:08:42 -0700 | [diff] [blame] | 115 | } |
| 116 | |
| 117 | #define CHECK(u, v, l, r, b) \ |
| 118 | check_per_encode_constrained(__LINE__, u, v, l, r, b) |
| 119 | |
| 120 | int |
| 121 | main() { |
| 122 | int unsigned_; |
| 123 | for(unsigned_ = 0; unsigned_ < 2; unsigned_++) { |
| 124 | int u = unsigned_; |
| 125 | |
| 126 | /* Encode a signed 0x8babab into a range constrained by 0..2^29-1 */ |
| 127 | CHECK(u, 0x8babab, 0, 536870911UL, 29); |
| 128 | CHECK(u, 0x8babab, 0, 1073741823UL, 30); |
| 129 | CHECK(u, 0x8babab, 0, 2147483647UL, 31); |
Lev Walkin | ae1422b | 2013-03-24 02:08:42 -0700 | [diff] [blame] | 130 | |
| 131 | CHECK(u, 0x8babab, 10, 536870901UL, 29); |
| 132 | CHECK(u, 0x8babab, 10, 1073741803UL, 30); |
| 133 | CHECK(u, 0x8babab, 10, 2147483607UL, 31); |
Lev Walkin | ae1422b | 2013-03-24 02:08:42 -0700 | [diff] [blame] | 134 | |
| 135 | CHECK(0, 0x8babab, -10, 536870901UL, 29); |
| 136 | CHECK(0, 0x8babab, -10, 1073741803UL, 30); |
| 137 | CHECK(0, 0x8babab, -10, 2147483607UL, 31); |
Lev Walkin | ae1422b | 2013-03-24 02:08:42 -0700 | [diff] [blame] | 138 | |
| 139 | CHECK(u, 11, 10, 536870901UL, 29); |
| 140 | CHECK(u, 11, 10, 1073741803UL, 30); |
| 141 | CHECK(u, 11, 10, 2147483607UL, 31); |
Lev Walkin | ae1422b | 2013-03-24 02:08:42 -0700 | [diff] [blame] | 142 | |
| 143 | CHECK(0, 1, -10, 536870901UL, 29); |
| 144 | CHECK(0, 1, -10, 1073741803UL, 30); |
| 145 | CHECK(0, 1, -10, 2147483607UL, 31); |
Lev Walkin | ae1422b | 2013-03-24 02:08:42 -0700 | [diff] [blame] | 146 | |
| 147 | CHECK(u, 10, 10, 536870901UL, 29); |
| 148 | CHECK(u, 10, 10, 1073741803UL, 30); |
| 149 | CHECK(u, 10, 10, 2147483607UL, 31); |
Lev Walkin | ae1422b | 2013-03-24 02:08:42 -0700 | [diff] [blame] | 150 | |
| 151 | CHECK(0, 0, -10, 536870901UL, 29); |
| 152 | CHECK(0, 0, -10, 1073741803UL, 30); |
| 153 | CHECK(0, 0, -10, 2147483607UL, 31); |
Lev Walkin | ae1422b | 2013-03-24 02:08:42 -0700 | [diff] [blame] | 154 | |
| 155 | CHECK(0, -1, -10, 536870901UL, 29); |
| 156 | CHECK(0, -1, -10, 1073741803UL, 30); |
| 157 | CHECK(0, -1, -10, 2147483607UL, 31); |
Lev Walkin | ae1422b | 2013-03-24 02:08:42 -0700 | [diff] [blame] | 158 | |
| 159 | CHECK(0, -10, -10, 536870901UL, 29); |
| 160 | CHECK(0, -10, -10, 1073741803UL, 30); |
| 161 | CHECK(0, -10, -10, 2147483607UL, 31); |
Lev Walkin | ae1422b | 2013-03-24 02:08:42 -0700 | [diff] [blame] | 162 | |
| 163 | CHECK(u, 536870901UL, 10, 536870901UL, 29); |
| 164 | CHECK(u, 1073741803UL, 10, 1073741803UL, 30); |
| 165 | CHECK(u, 2147483607UL, 10, 2147483607UL, 31); |
Lev Walkin | ae1422b | 2013-03-24 02:08:42 -0700 | [diff] [blame] | 166 | |
| 167 | CHECK(0, 536870901UL, -10, 536870901UL, 29); |
| 168 | CHECK(0, 1073741803UL, -10, 1073741803UL, 30); |
| 169 | CHECK(0, 2147483607UL, -10, 2147483607UL, 31); |
Lev Walkin | ae1422b | 2013-03-24 02:08:42 -0700 | [diff] [blame] | 170 | |
Lev Walkin | b1d85e3 | 2013-03-28 00:32:49 -0700 | [diff] [blame] | 171 | CHECK(0, -2147483648, -2147483648, 2147483647, 32); |
| 172 | CHECK(0, -10, -2147483648, 2147483647, 32); |
| 173 | CHECK(0, -1, -2147483648, 2147483647, 32); |
| 174 | CHECK(0, 0, -2147483648, 2147483647, 32); |
| 175 | CHECK(0, 1, -2147483648, 2147483647, 32); |
| 176 | CHECK(0, 10, -2147483648, 2147483647, 32); |
| 177 | CHECK(0, 2147483647, -2147483648, 2147483647, 32); |
Lev Walkin | 20a01f9 | 2013-03-28 00:22:08 -0700 | [diff] [blame] | 178 | |
Lev Walkin | b1d85e3 | 2013-03-28 00:32:49 -0700 | [diff] [blame] | 179 | CHECK(1, 0, 0, 4294967295UL, 32); |
| 180 | CHECK(1, 1, 0, 4294967295UL, 32); |
| 181 | CHECK(1, 10, 0, 4294967295UL, 32); |
| 182 | CHECK(1, 2000000000, 0, 4294967295UL, 32); |
| 183 | CHECK(1, 2147483647, 0, 4294967295UL, 32); |
| 184 | CHECK(1, 2147483648, 0, 4294967295UL, 32); |
| 185 | CHECK(1, 4000000000, 0, 4294967295UL, 32); |
| 186 | CHECK(1, 4294967295UL, 0, 4294967295UL, 32); |
Lev Walkin | 20a01f9 | 2013-03-28 00:22:08 -0700 | [diff] [blame] | 187 | |
Lev Walkin | b1d85e3 | 2013-03-28 00:32:49 -0700 | [diff] [blame] | 188 | CHECK(1, 10, 10, 4294967285UL, 32); |
| 189 | CHECK(1, 11, 10, 4294967285UL, 32); |
| 190 | |
| 191 | if(sizeof(long) > sizeof(uint32_t)) { |
| 192 | CHECK(0, 0, -10, 4294967285UL, 32); |
| 193 | CHECK(0, 1, -10, 4294967285UL, 32); |
| 194 | CHECK(0, -1, -10, 4294967285UL, 32); |
| 195 | CHECK(0, -10, -10, 4294967285UL, 32); |
| 196 | CHECK(0, -10, -10, 4294967285UL, 32); |
| 197 | CHECK(0, 0x8babab, -10, 4294967285UL, 32); |
Lev Walkin | 20a01f9 | 2013-03-28 00:22:08 -0700 | [diff] [blame] | 198 | |
| 199 | CHECK(u, 0x8babab, 0, 4294967295UL, 32); |
| 200 | CHECK(u, 11, 10, 4294967205UL, 32); |
| 201 | CHECK(u, 10, 10, 4294967205UL, 32); |
Lev Walkin | b1d85e3 | 2013-03-28 00:32:49 -0700 | [diff] [blame] | 202 | CHECK(u, 4294967205UL, 10, 4294967285UL, 32); |
Lev Walkin | 20a01f9 | 2013-03-28 00:22:08 -0700 | [diff] [blame] | 203 | |
Lev Walkin | b1d85e3 | 2013-03-28 00:32:49 -0700 | [diff] [blame] | 204 | CHECK(0, 4294967205UL, -10, 4294967285UL, 32); |
Lev Walkin | 20a01f9 | 2013-03-28 00:22:08 -0700 | [diff] [blame] | 205 | CHECK(u, 4294967295UL, 1, 4294967295UL, 32); |
| 206 | |
| 207 | CHECK(u, 2000000000, 0, 4294967295UL, 32); |
| 208 | CHECK(u, 2147483647, 0, 4294967295UL, 32); |
| 209 | CHECK(u, 2147483648, 0, 4294967295UL, 32); |
| 210 | CHECK(u, 4000000000, 0, 4294967295UL, 32); |
| 211 | } |
Lev Walkin | ae1422b | 2013-03-24 02:08:42 -0700 | [diff] [blame] | 212 | } |
| 213 | |
| 214 | return 0; |
| 215 | } |