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