1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 import java.util.zip.CRC32; 18 import java.util.Random; 19 import java.nio.ByteBuffer; 20 21 /** 22 * The ART compiler can use intrinsics for the java.util.zip.CRC32 methods: 23 * private native static int update(int crc, int b) 24 * private native static int updateBytes(int crc, byte[] b, int off, int len) 25 * 26 * As the methods are private it is not possible to check the use of intrinsics 27 * for them directly. 28 * The tests check that correct checksums are produced. 29 */ 30 public class Main { Main()31 public Main() { 32 } 33 CRC32Byte(int value)34 public static long CRC32Byte(int value) { 35 CRC32 crc32 = new CRC32(); 36 crc32.update(value); 37 return crc32.getValue(); 38 } 39 CRC32BytesUsingUpdateInt(int... values)40 public static long CRC32BytesUsingUpdateInt(int... values) { 41 CRC32 crc32 = new CRC32(); 42 for (int value : values) { 43 crc32.update(value); 44 } 45 return crc32.getValue(); 46 } 47 assertEqual(long expected, long actual)48 public static void assertEqual(long expected, long actual) { 49 if (expected != actual) { 50 throw new Error("Expected: " + expected + ", found: " + actual); 51 } 52 } 53 assertEqual(boolean expected, boolean actual)54 private static void assertEqual(boolean expected, boolean actual) { 55 if (expected != actual) { 56 throw new Error("Expected: " + expected + ", found: " + actual); 57 } 58 } 59 TestCRC32Update()60 private static void TestCRC32Update() { 61 // public void update(int b) 62 // 63 // Tests for checksums of the byte 0x0 64 // Check that only the low eight bits of the argument are used. 65 assertEqual(0xD202EF8DL, CRC32Byte(0x0)); 66 assertEqual(0xD202EF8DL, CRC32Byte(0x0100)); 67 assertEqual(0xD202EF8DL, CRC32Byte(0x010000)); 68 assertEqual(0xD202EF8DL, CRC32Byte(0x01000000)); 69 assertEqual(0xD202EF8DL, CRC32Byte(0xff00)); 70 assertEqual(0xD202EF8DL, CRC32Byte(0xffff00)); 71 assertEqual(0xD202EF8DL, CRC32Byte(0xffffff00)); 72 assertEqual(0xD202EF8DL, CRC32Byte(0x1200)); 73 assertEqual(0xD202EF8DL, CRC32Byte(0x123400)); 74 assertEqual(0xD202EF8DL, CRC32Byte(0x12345600)); 75 assertEqual(0xD202EF8DL, CRC32Byte(Integer.MIN_VALUE)); 76 77 // Tests for checksums of the byte 0x1 78 // Check that only the low eight bits of the argument are used. 79 assertEqual(0xA505DF1BL, CRC32Byte(0x1)); 80 assertEqual(0xA505DF1BL, CRC32Byte(0x0101)); 81 assertEqual(0xA505DF1BL, CRC32Byte(0x010001)); 82 assertEqual(0xA505DF1BL, CRC32Byte(0x01000001)); 83 assertEqual(0xA505DF1BL, CRC32Byte(0xff01)); 84 assertEqual(0xA505DF1BL, CRC32Byte(0xffff01)); 85 assertEqual(0xA505DF1BL, CRC32Byte(0xffffff01)); 86 assertEqual(0xA505DF1BL, CRC32Byte(0x1201)); 87 assertEqual(0xA505DF1BL, CRC32Byte(0x123401)); 88 assertEqual(0xA505DF1BL, CRC32Byte(0x12345601)); 89 90 // Tests for checksums of the byte 0x0f 91 // Check that only the low eight bits of the argument are used. 92 assertEqual(0x42BDF21CL, CRC32Byte(0x0f)); 93 assertEqual(0x42BDF21CL, CRC32Byte(0x010f)); 94 assertEqual(0x42BDF21CL, CRC32Byte(0x01000f)); 95 assertEqual(0x42BDF21CL, CRC32Byte(0x0100000f)); 96 assertEqual(0x42BDF21CL, CRC32Byte(0xff0f)); 97 assertEqual(0x42BDF21CL, CRC32Byte(0xffff0f)); 98 assertEqual(0x42BDF21CL, CRC32Byte(0xffffff0f)); 99 assertEqual(0x42BDF21CL, CRC32Byte(0x120f)); 100 assertEqual(0x42BDF21CL, CRC32Byte(0x12340f)); 101 assertEqual(0x42BDF21CL, CRC32Byte(0x1234560f)); 102 103 // Tests for checksums of the byte 0xff 104 // Check that only the low eight bits of the argument are used. 105 assertEqual(0xFF000000L, CRC32Byte(0x00ff)); 106 assertEqual(0xFF000000L, CRC32Byte(0x01ff)); 107 assertEqual(0xFF000000L, CRC32Byte(0x0100ff)); 108 assertEqual(0xFF000000L, CRC32Byte(0x010000ff)); 109 assertEqual(0xFF000000L, CRC32Byte(0x0000ffff)); 110 assertEqual(0xFF000000L, CRC32Byte(0x00ffffff)); 111 assertEqual(0xFF000000L, CRC32Byte(0xffffffff)); 112 assertEqual(0xFF000000L, CRC32Byte(0x12ff)); 113 assertEqual(0xFF000000L, CRC32Byte(0x1234ff)); 114 assertEqual(0xFF000000L, CRC32Byte(0x123456ff)); 115 assertEqual(0xFF000000L, CRC32Byte(Integer.MAX_VALUE)); 116 117 // Tests for sequences 118 // Check that only the low eight bits of the values are used. 119 assertEqual(0xFF41D912L, CRC32BytesUsingUpdateInt(0, 0, 0)); 120 assertEqual(0xFF41D912L, 121 CRC32BytesUsingUpdateInt(0x0100, 0x010000, 0x01000000)); 122 assertEqual(0xFF41D912L, 123 CRC32BytesUsingUpdateInt(0xff00, 0xffff00, 0xffffff00)); 124 assertEqual(0xFF41D912L, 125 CRC32BytesUsingUpdateInt(0x1200, 0x123400, 0x12345600)); 126 127 assertEqual(0x909FB2F2L, CRC32BytesUsingUpdateInt(1, 1, 1)); 128 assertEqual(0x909FB2F2L, 129 CRC32BytesUsingUpdateInt(0x0101, 0x010001, 0x01000001)); 130 assertEqual(0x909FB2F2L, 131 CRC32BytesUsingUpdateInt(0xff01, 0xffff01, 0xffffff01)); 132 assertEqual(0x909FB2F2L, 133 CRC32BytesUsingUpdateInt(0x1201, 0x123401, 0x12345601)); 134 135 assertEqual(0xE33A9F71L, CRC32BytesUsingUpdateInt(0x0f, 0x0f, 0x0f)); 136 assertEqual(0xE33A9F71L, 137 CRC32BytesUsingUpdateInt(0x010f, 0x01000f, 0x0100000f)); 138 assertEqual(0xE33A9F71L, 139 CRC32BytesUsingUpdateInt(0xff0f, 0xffff0f, 0xffffff0f)); 140 assertEqual(0xE33A9F71L, 141 CRC32BytesUsingUpdateInt(0x120f, 0x12340f, 0x1234560f)); 142 143 assertEqual(0xFFFFFF00L, CRC32BytesUsingUpdateInt(0x0ff, 0x0ff, 0x0ff)); 144 assertEqual(0xFFFFFF00L, 145 CRC32BytesUsingUpdateInt(0x01ff, 0x0100ff, 0x010000ff)); 146 assertEqual(0xFFFFFF00L, 147 CRC32BytesUsingUpdateInt(0x00ffff, 0x00ffffff, 0xffffffff)); 148 assertEqual(0xFFFFFF00L, 149 CRC32BytesUsingUpdateInt(0x12ff, 0x1234ff, 0x123456ff)); 150 151 assertEqual(0xB6CC4292L, CRC32BytesUsingUpdateInt(0x01, 0x02)); 152 153 assertEqual(0xB2DE047CL, 154 CRC32BytesUsingUpdateInt(0x0, -1, Integer.MIN_VALUE, Integer.MAX_VALUE)); 155 } 156 CRC32ByteArray(byte[] bytes, int off, int len)157 private static long CRC32ByteArray(byte[] bytes, int off, int len) { 158 CRC32 crc32 = new CRC32(); 159 crc32.update(bytes, off, len); 160 return crc32.getValue(); 161 } 162 163 // This is used to test we generate correct code for constant offsets. 164 // In this case the offset is 0. CRC32ByteArray(byte[] bytes)165 private static long CRC32ByteArray(byte[] bytes) { 166 CRC32 crc32 = new CRC32(); 167 crc32.update(bytes); 168 return crc32.getValue(); 169 } 170 CRC32ByteAndByteArray(int value, byte[] bytes)171 private static long CRC32ByteAndByteArray(int value, byte[] bytes) { 172 CRC32 crc32 = new CRC32(); 173 crc32.update(value); 174 crc32.update(bytes); 175 return crc32.getValue(); 176 } 177 CRC32ByteArrayAndByte(byte[] bytes, int value)178 private static long CRC32ByteArrayAndByte(byte[] bytes, int value) { 179 CRC32 crc32 = new CRC32(); 180 crc32.update(bytes); 181 crc32.update(value); 182 return crc32.getValue(); 183 } 184 CRC32ByteArrayThrowsAIOOBE(byte[] bytes, int off, int len)185 private static boolean CRC32ByteArrayThrowsAIOOBE(byte[] bytes, int off, int len) { 186 try { 187 CRC32 crc32 = new CRC32(); 188 crc32.update(bytes, off, len); 189 } catch (ArrayIndexOutOfBoundsException ex) { 190 return true; 191 } 192 return false; 193 } 194 CRC32ByteArrayThrowsNPE()195 private static boolean CRC32ByteArrayThrowsNPE() { 196 try { 197 CRC32 crc32 = new CRC32(); 198 crc32.update(null, 0, 0); 199 return false; 200 } catch (NullPointerException e) {} 201 202 try { 203 CRC32 crc32 = new CRC32(); 204 crc32.update(null, 1, 2); 205 return false; 206 } catch (NullPointerException e) {} 207 208 try { 209 CRC32 crc32 = new CRC32(); 210 crc32.update((byte[])null); 211 return false; 212 } catch (NullPointerException e) {} 213 214 return true; 215 } 216 CRC32BytesUsingUpdateInt(byte[] bytes, int off, int len)217 private static long CRC32BytesUsingUpdateInt(byte[] bytes, int off, int len) { 218 CRC32 crc32 = new CRC32(); 219 while (len-- > 0) { 220 crc32.update(bytes[off++]); 221 } 222 return crc32.getValue(); 223 } 224 TestCRC32UpdateBytes()225 private static void TestCRC32UpdateBytes() { 226 assertEqual(0L, CRC32ByteArray(new byte[] {})); 227 assertEqual(0L, CRC32ByteArray(new byte[] {}, 0, 0)); 228 assertEqual(0L, CRC32ByteArray(new byte[] {0}, 0, 0)); 229 assertEqual(0L, CRC32ByteArray(new byte[] {0}, 1, 0)); 230 assertEqual(0L, CRC32ByteArray(new byte[] {0, 0}, 1, 0)); 231 232 assertEqual(true, CRC32ByteArrayThrowsNPE()); 233 assertEqual(true, CRC32ByteArrayThrowsAIOOBE(new byte[] {}, -1, 0)); 234 assertEqual(true, CRC32ByteArrayThrowsAIOOBE(new byte[] {0}, -1, 1)); 235 assertEqual(true, CRC32ByteArrayThrowsAIOOBE(new byte[] {0}, 0, -1)); 236 assertEqual(true, CRC32ByteArrayThrowsAIOOBE(new byte[] {}, 0, -1)); 237 assertEqual(true, CRC32ByteArrayThrowsAIOOBE(new byte[] {}, 1, 0)); 238 assertEqual(true, CRC32ByteArrayThrowsAIOOBE(new byte[] {}, -1, 1)); 239 assertEqual(true, CRC32ByteArrayThrowsAIOOBE(new byte[] {}, 1, -1)); 240 assertEqual(true, CRC32ByteArrayThrowsAIOOBE(new byte[] {}, 0, 1)); 241 assertEqual(true, CRC32ByteArrayThrowsAIOOBE(new byte[] {}, 0, 10)); 242 assertEqual(true, CRC32ByteArrayThrowsAIOOBE(new byte[] {0}, 0, 10)); 243 assertEqual(true, CRC32ByteArrayThrowsAIOOBE(new byte[] {}, 10, 10)); 244 assertEqual(true, CRC32ByteArrayThrowsAIOOBE(new byte[] {0, 0, 0, 0}, 2, 3)); 245 assertEqual(true, CRC32ByteArrayThrowsAIOOBE(new byte[] {0, 0, 0, 0}, 3, 2)); 246 247 assertEqual(CRC32Byte(0), CRC32ByteArray(new byte[] {0})); 248 assertEqual(CRC32Byte(0), CRC32ByteArray(new byte[] {0}, 0, 1)); 249 assertEqual(CRC32Byte(1), CRC32ByteArray(new byte[] {1})); 250 assertEqual(CRC32Byte(1), CRC32ByteArray(new byte[] {1}, 0, 1)); 251 assertEqual(CRC32Byte(0x0f), CRC32ByteArray(new byte[] {0x0f})); 252 assertEqual(CRC32Byte(0x0f), CRC32ByteArray(new byte[] {0x0f}, 0, 1)); 253 assertEqual(CRC32Byte(0xff), CRC32ByteArray(new byte[] {-1})); 254 assertEqual(CRC32Byte(0xff), CRC32ByteArray(new byte[] {-1}, 0, 1)); 255 assertEqual(CRC32BytesUsingUpdateInt(0, 0, 0), 256 CRC32ByteArray(new byte[] {0, 0, 0})); 257 assertEqual(CRC32BytesUsingUpdateInt(0, 0, 0), 258 CRC32ByteArray(new byte[] {0, 0, 0}, 0, 3)); 259 assertEqual(CRC32BytesUsingUpdateInt(1, 1, 1), 260 CRC32ByteArray(new byte[] {1, 1, 1})); 261 assertEqual(CRC32BytesUsingUpdateInt(1, 1, 1), 262 CRC32ByteArray(new byte[] {1, 1, 1}, 0, 3)); 263 assertEqual(CRC32BytesUsingUpdateInt(0x0f, 0x0f, 0x0f), 264 CRC32ByteArray(new byte[] {0x0f, 0x0f, 0x0f})); 265 assertEqual(CRC32BytesUsingUpdateInt(0x0f, 0x0f, 0x0f), 266 CRC32ByteArray(new byte[] {0x0f, 0x0f, 0x0f}, 0, 3)); 267 assertEqual(CRC32BytesUsingUpdateInt(0xff, 0xff, 0xff), 268 CRC32ByteArray(new byte[] {-1, -1, -1})); 269 assertEqual(CRC32BytesUsingUpdateInt(0xff, 0xff, 0xff), 270 CRC32ByteArray(new byte[] {-1, -1, -1}, 0, 3)); 271 assertEqual(CRC32BytesUsingUpdateInt(1, 2), 272 CRC32ByteArray(new byte[] {1, 2})); 273 assertEqual(CRC32BytesUsingUpdateInt(1, 2), 274 CRC32ByteArray(new byte[] {1, 2}, 0, 2)); 275 assertEqual( 276 CRC32BytesUsingUpdateInt(0, -1, Byte.MIN_VALUE, Byte.MAX_VALUE), 277 CRC32ByteArray(new byte[] {0, -1, Byte.MIN_VALUE, Byte.MAX_VALUE})); 278 assertEqual( 279 CRC32BytesUsingUpdateInt(0, -1, Byte.MIN_VALUE, Byte.MAX_VALUE), 280 CRC32ByteArray(new byte[] {0, -1, Byte.MIN_VALUE, Byte.MAX_VALUE}, 0, 4)); 281 282 assertEqual(CRC32BytesUsingUpdateInt(0, 0, 0), 283 CRC32ByteAndByteArray(0, new byte[] {0, 0})); 284 assertEqual(CRC32BytesUsingUpdateInt(1, 1, 1), 285 CRC32ByteAndByteArray(1, new byte[] {1, 1})); 286 assertEqual(CRC32BytesUsingUpdateInt(0x0f, 0x0f, 0x0f), 287 CRC32ByteAndByteArray(0x0f, new byte[] {0x0f, 0x0f})); 288 assertEqual(CRC32BytesUsingUpdateInt(0xff, 0xff, 0xff), 289 CRC32ByteAndByteArray(-1, new byte[] {-1, -1})); 290 assertEqual(CRC32BytesUsingUpdateInt(1, 2, 3), 291 CRC32ByteAndByteArray(1, new byte[] {2, 3})); 292 assertEqual( 293 CRC32BytesUsingUpdateInt(0, -1, Byte.MIN_VALUE, Byte.MAX_VALUE), 294 CRC32ByteAndByteArray(0, new byte[] {-1, Byte.MIN_VALUE, Byte.MAX_VALUE})); 295 296 assertEqual(CRC32BytesUsingUpdateInt(0, 0, 0), 297 CRC32ByteArrayAndByte(new byte[] {0, 0}, 0)); 298 assertEqual(CRC32BytesUsingUpdateInt(1, 1, 1), 299 CRC32ByteArrayAndByte(new byte[] {1, 1}, 1)); 300 assertEqual(CRC32BytesUsingUpdateInt(0x0f, 0x0f, 0x0f), 301 CRC32ByteArrayAndByte(new byte[] {0x0f, 0x0f}, 0x0f)); 302 assertEqual(CRC32BytesUsingUpdateInt(0xff, 0xff, 0xff), 303 CRC32ByteArrayAndByte(new byte[] {-1, -1}, -1)); 304 assertEqual(CRC32BytesUsingUpdateInt(1, 2, 3), 305 CRC32ByteArrayAndByte(new byte[] {1, 2}, 3)); 306 assertEqual( 307 CRC32BytesUsingUpdateInt(0, -1, Byte.MIN_VALUE, Byte.MAX_VALUE), 308 CRC32ByteArrayAndByte(new byte[] {0, -1, Byte.MIN_VALUE}, Byte.MAX_VALUE)); 309 310 byte[] bytes = new byte[128 * 1024]; 311 Random rnd = new Random(0); 312 rnd.nextBytes(bytes); 313 314 assertEqual(CRC32BytesUsingUpdateInt(bytes, 0, bytes.length), 315 CRC32ByteArray(bytes)); 316 assertEqual(CRC32BytesUsingUpdateInt(bytes, 0, 8 * 1024), 317 CRC32ByteArray(bytes, 0, 8 * 1024)); 318 319 int off = rnd.nextInt(bytes.length / 2); 320 for (int len = 0; len <= 16; ++len) { 321 assertEqual(CRC32BytesUsingUpdateInt(bytes, off, len), 322 CRC32ByteArray(bytes, off, len)); 323 } 324 325 // Check there are no issues with unaligned accesses. 326 for (int o = 1; o < 8; ++o) { 327 for (int l = 0; l <= 16; ++l) { 328 assertEqual(CRC32BytesUsingUpdateInt(bytes, o, l), 329 CRC32ByteArray(bytes, o, l)); 330 } 331 } 332 333 int len = bytes.length / 2; 334 assertEqual(CRC32BytesUsingUpdateInt(bytes, 0, len - 1), 335 CRC32ByteArray(bytes, 0, len - 1)); 336 assertEqual(CRC32BytesUsingUpdateInt(bytes, 0, len), 337 CRC32ByteArray(bytes, 0, len)); 338 assertEqual(CRC32BytesUsingUpdateInt(bytes, 0, len + 1), 339 CRC32ByteArray(bytes, 0, len + 1)); 340 341 len = rnd.nextInt(bytes.length + 1); 342 off = rnd.nextInt(bytes.length - len); 343 assertEqual(CRC32BytesUsingUpdateInt(bytes, off, len), 344 CRC32ByteArray(bytes, off, len)); 345 } 346 CRC32ByteBuffer(byte[] bytes, int off, int len)347 private static long CRC32ByteBuffer(byte[] bytes, int off, int len) { 348 ByteBuffer buf = ByteBuffer.wrap(bytes, 0, off + len); 349 buf.position(off); 350 CRC32 crc32 = new CRC32(); 351 crc32.update(buf); 352 return crc32.getValue(); 353 } 354 TestCRC32UpdateByteBuffer()355 private static void TestCRC32UpdateByteBuffer() { 356 assertEqual(0L, CRC32ByteBuffer(new byte[] {}, 0, 0)); 357 assertEqual(0L, CRC32ByteBuffer(new byte[] {0}, 0, 0)); 358 assertEqual(0L, CRC32ByteBuffer(new byte[] {0}, 1, 0)); 359 assertEqual(0L, CRC32ByteBuffer(new byte[] {0, 0}, 1, 0)); 360 361 assertEqual(CRC32Byte(0), CRC32ByteBuffer(new byte[] {0}, 0, 1)); 362 assertEqual(CRC32Byte(1), CRC32ByteBuffer(new byte[] {1}, 0, 1)); 363 assertEqual(CRC32Byte(0x0f), CRC32ByteBuffer(new byte[] {0x0f}, 0, 1)); 364 assertEqual(CRC32Byte(0xff), CRC32ByteBuffer(new byte[] {-1}, 0, 1)); 365 assertEqual(CRC32BytesUsingUpdateInt(0, 0, 0), 366 CRC32ByteBuffer(new byte[] {0, 0, 0}, 0, 3)); 367 assertEqual(CRC32BytesUsingUpdateInt(1, 1, 1), 368 CRC32ByteBuffer(new byte[] {1, 1, 1}, 0, 3)); 369 assertEqual(CRC32BytesUsingUpdateInt(0x0f, 0x0f, 0x0f), 370 CRC32ByteBuffer(new byte[] {0x0f, 0x0f, 0x0f}, 0, 3)); 371 assertEqual(CRC32BytesUsingUpdateInt(0xff, 0xff, 0xff), 372 CRC32ByteBuffer(new byte[] {-1, -1, -1}, 0, 3)); 373 assertEqual(CRC32BytesUsingUpdateInt(1, 2), 374 CRC32ByteBuffer(new byte[] {1, 2}, 0, 2)); 375 assertEqual( 376 CRC32BytesUsingUpdateInt(0, -1, Byte.MIN_VALUE, Byte.MAX_VALUE), 377 CRC32ByteBuffer(new byte[] {0, -1, Byte.MIN_VALUE, Byte.MAX_VALUE}, 0, 4)); 378 379 byte[] bytes = new byte[128 * 1024]; 380 Random rnd = new Random(0); 381 rnd.nextBytes(bytes); 382 383 assertEqual(CRC32BytesUsingUpdateInt(bytes, 0, 8 * 1024), 384 CRC32ByteBuffer(bytes, 0, 8 * 1024)); 385 386 int off = rnd.nextInt(bytes.length / 2); 387 for (int len = 0; len <= 16; ++len) { 388 assertEqual(CRC32BytesUsingUpdateInt(bytes, off, len), 389 CRC32ByteBuffer(bytes, off, len)); 390 } 391 392 // Check there are no issues with unaligned accesses. 393 for (int o = 1; o < 8; ++o) { 394 for (int l = 0; l <= 16; ++l) { 395 assertEqual(CRC32BytesUsingUpdateInt(bytes, o, l), 396 CRC32ByteBuffer(bytes, o, l)); 397 } 398 } 399 400 int len = bytes.length / 2; 401 assertEqual(CRC32BytesUsingUpdateInt(bytes, 0, len - 1), 402 CRC32ByteBuffer(bytes, 0, len - 1)); 403 assertEqual(CRC32BytesUsingUpdateInt(bytes, 0, len), 404 CRC32ByteBuffer(bytes, 0, len)); 405 assertEqual(CRC32BytesUsingUpdateInt(bytes, 0, len + 1), 406 CRC32ByteBuffer(bytes, 0, len + 1)); 407 408 len = rnd.nextInt(bytes.length + 1); 409 off = rnd.nextInt(bytes.length - len); 410 assertEqual(CRC32BytesUsingUpdateInt(bytes, off, len), 411 CRC32ByteBuffer(bytes, off, len)); 412 } 413 CRC32DirectByteBuffer(byte[] bytes, int off, int len)414 private static long CRC32DirectByteBuffer(byte[] bytes, int off, int len) { 415 final int total_len = off + len; 416 ByteBuffer buf = ByteBuffer.allocateDirect(total_len).put(bytes, 0, total_len); 417 buf.position(off); 418 CRC32 crc32 = new CRC32(); 419 crc32.update(buf); 420 return crc32.getValue(); 421 } 422 CRC32ByteAndDirectByteBuffer(int value, byte[] bytes)423 private static long CRC32ByteAndDirectByteBuffer(int value, byte[] bytes) { 424 ByteBuffer buf = ByteBuffer.allocateDirect(bytes.length).put(bytes); 425 buf.position(0); 426 CRC32 crc32 = new CRC32(); 427 crc32.update(value); 428 crc32.update(buf); 429 return crc32.getValue(); 430 } 431 CRC32DirectByteBufferAndByte(byte[] bytes, int value)432 private static long CRC32DirectByteBufferAndByte(byte[] bytes, int value) { 433 ByteBuffer buf = ByteBuffer.allocateDirect(bytes.length).put(bytes); 434 buf.position(0); 435 CRC32 crc32 = new CRC32(); 436 crc32.update(buf); 437 crc32.update(value); 438 return crc32.getValue(); 439 } 440 TestCRC32UpdateDirectByteBuffer()441 private static void TestCRC32UpdateDirectByteBuffer() { 442 assertEqual(0L, CRC32DirectByteBuffer(new byte[] {}, 0, 0)); 443 assertEqual(0L, CRC32DirectByteBuffer(new byte[] {0}, 0, 0)); 444 assertEqual(0L, CRC32DirectByteBuffer(new byte[] {0}, 1, 0)); 445 assertEqual(0L, CRC32DirectByteBuffer(new byte[] {0, 0}, 1, 0)); 446 447 assertEqual(CRC32Byte(0), CRC32DirectByteBuffer(new byte[] {0}, 0, 1)); 448 assertEqual(CRC32Byte(1), CRC32DirectByteBuffer(new byte[] {1}, 0, 1)); 449 assertEqual(CRC32Byte(0x0f), CRC32DirectByteBuffer(new byte[] {0x0f}, 0, 1)); 450 assertEqual(CRC32Byte(0xff), CRC32DirectByteBuffer(new byte[] {-1}, 0, 1)); 451 assertEqual(CRC32BytesUsingUpdateInt(0, 0, 0), 452 CRC32DirectByteBuffer(new byte[] {0, 0, 0}, 0, 3)); 453 assertEqual(CRC32BytesUsingUpdateInt(1, 1, 1), 454 CRC32DirectByteBuffer(new byte[] {1, 1, 1}, 0, 3)); 455 assertEqual(CRC32BytesUsingUpdateInt(0x0f, 0x0f, 0x0f), 456 CRC32DirectByteBuffer(new byte[] {0x0f, 0x0f, 0x0f}, 0, 3)); 457 assertEqual(CRC32BytesUsingUpdateInt(0xff, 0xff, 0xff), 458 CRC32DirectByteBuffer(new byte[] {-1, -1, -1}, 0, 3)); 459 assertEqual(CRC32BytesUsingUpdateInt(1, 2), 460 CRC32DirectByteBuffer(new byte[] {1, 2}, 0, 2)); 461 assertEqual( 462 CRC32BytesUsingUpdateInt(0, -1, Byte.MIN_VALUE, Byte.MAX_VALUE), 463 CRC32DirectByteBuffer(new byte[] {0, -1, Byte.MIN_VALUE, Byte.MAX_VALUE}, 0, 4)); 464 465 assertEqual(CRC32BytesUsingUpdateInt(0, 0, 0), 466 CRC32ByteAndDirectByteBuffer(0, new byte[] {0, 0})); 467 assertEqual(CRC32BytesUsingUpdateInt(1, 1, 1), 468 CRC32ByteAndDirectByteBuffer(1, new byte[] {1, 1})); 469 assertEqual(CRC32BytesUsingUpdateInt(0x0f, 0x0f, 0x0f), 470 CRC32ByteAndDirectByteBuffer(0x0f, new byte[] {0x0f, 0x0f})); 471 assertEqual(CRC32BytesUsingUpdateInt(0xff, 0xff, 0xff), 472 CRC32ByteAndDirectByteBuffer(-1, new byte[] {-1, -1})); 473 assertEqual(CRC32BytesUsingUpdateInt(1, 2, 3), 474 CRC32ByteAndDirectByteBuffer(1, new byte[] {2, 3})); 475 assertEqual( 476 CRC32BytesUsingUpdateInt(0, -1, Byte.MIN_VALUE, Byte.MAX_VALUE), 477 CRC32ByteAndDirectByteBuffer(0, new byte[] {-1, Byte.MIN_VALUE, Byte.MAX_VALUE})); 478 479 assertEqual(CRC32BytesUsingUpdateInt(0, 0, 0), 480 CRC32DirectByteBufferAndByte(new byte[] {0, 0}, 0)); 481 assertEqual(CRC32BytesUsingUpdateInt(1, 1, 1), 482 CRC32DirectByteBufferAndByte(new byte[] {1, 1}, 1)); 483 assertEqual(CRC32BytesUsingUpdateInt(0x0f, 0x0f, 0x0f), 484 CRC32DirectByteBufferAndByte(new byte[] {0x0f, 0x0f}, 0x0f)); 485 assertEqual(CRC32BytesUsingUpdateInt(0xff, 0xff, 0xff), 486 CRC32DirectByteBufferAndByte(new byte[] {-1, -1}, -1)); 487 assertEqual(CRC32BytesUsingUpdateInt(1, 2, 3), 488 CRC32DirectByteBufferAndByte(new byte[] {1, 2}, 3)); 489 assertEqual( 490 CRC32BytesUsingUpdateInt(0, -1, Byte.MIN_VALUE, Byte.MAX_VALUE), 491 CRC32DirectByteBufferAndByte(new byte[] {0, -1, Byte.MIN_VALUE}, Byte.MAX_VALUE)); 492 493 byte[] bytes = new byte[128 * 1024]; 494 Random rnd = new Random(0); 495 rnd.nextBytes(bytes); 496 497 assertEqual(CRC32BytesUsingUpdateInt(bytes, 0, bytes.length), 498 CRC32DirectByteBuffer(bytes, 0, bytes.length)); 499 assertEqual(CRC32BytesUsingUpdateInt(bytes, 0, 8 * 1024), 500 CRC32DirectByteBuffer(bytes, 0, 8 * 1024)); 501 502 int off = rnd.nextInt(bytes.length / 2); 503 for (int len = 0; len <= 16; ++len) { 504 assertEqual(CRC32BytesUsingUpdateInt(bytes, off, len), 505 CRC32DirectByteBuffer(bytes, off, len)); 506 } 507 508 // Check there are no issues with unaligned accesses. 509 for (int o = 1; o < 8; ++o) { 510 for (int l = 0; l <= 16; ++l) { 511 assertEqual(CRC32BytesUsingUpdateInt(bytes, o, l), 512 CRC32DirectByteBuffer(bytes, o, l)); 513 } 514 } 515 516 int len = bytes.length / 2; 517 assertEqual(CRC32BytesUsingUpdateInt(bytes, 0, len - 1), 518 CRC32DirectByteBuffer(bytes, 0, len - 1)); 519 assertEqual(CRC32BytesUsingUpdateInt(bytes, 0, len), 520 CRC32DirectByteBuffer(bytes, 0, len)); 521 assertEqual(CRC32BytesUsingUpdateInt(bytes, 0, len + 1), 522 CRC32DirectByteBuffer(bytes, 0, len + 1)); 523 524 len = rnd.nextInt(bytes.length + 1); 525 off = rnd.nextInt(bytes.length - len); 526 assertEqual(CRC32BytesUsingUpdateInt(bytes, off, len), 527 CRC32DirectByteBuffer(bytes, off, len)); 528 } 529 main(String args[])530 public static void main(String args[]) { 531 TestCRC32Update(); 532 TestCRC32UpdateBytes(); 533 TestCRC32UpdateByteBuffer(); 534 TestCRC32UpdateDirectByteBuffer(); 535 } 536 } 537