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