|
| 1 | +/- |
| 2 | +Copyright (c) 2025 Lean FRO, LLC. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Fady Adal |
| 5 | +
|
| 6 | +Tests for BitVec ByteArray conversion operations. |
| 7 | +-/ |
| 8 | + |
| 9 | +open BitVec |
| 10 | + |
| 11 | +/-! ## Basic conversions (standard widths) -/ |
| 12 | + |
| 13 | +-- 16-bit conversions |
| 14 | +#guard (0x1234#16).toBytesLE.data = #[0x34, 0x12] |
| 15 | +#guard (0x1234#16).toBytesBE.data = #[0x12, 0x34] |
| 16 | + |
| 17 | +-- 8-bit conversions |
| 18 | +#guard (0xAB#8).toBytesLE.data = #[0xAB] |
| 19 | +#guard (0xAB#8).toBytesBE.data = #[0xAB] |
| 20 | + |
| 21 | +-- 32-bit conversions |
| 22 | +#guard (0xDEADBEEF#32).toBytesLE.data = #[0xEF, 0xBE, 0xAD, 0xDE] |
| 23 | +#guard (0xDEADBEEF#32).toBytesBE.data = #[0xDE, 0xAD, 0xBE, 0xEF] |
| 24 | + |
| 25 | +-- 64-bit conversions |
| 26 | +#guard (0x0123456789ABCDEF#64).toBytesLE.data = #[0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01] |
| 27 | +#guard (0x0123456789ABCDEF#64).toBytesBE.data = #[0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF] |
| 28 | + |
| 29 | +/-! ## Non-multiple-of-8 widths -/ |
| 30 | + |
| 31 | +-- 3-bit value (pads to 1 byte) |
| 32 | +#guard (0b101#3).toBytesLE.data = #[0b00000101] |
| 33 | +#guard (0b101#3).toBytesBE.data = #[0b00000101] |
| 34 | +#guard (0b101#3).toBytesLE.size = 1 |
| 35 | +#guard (0b101#3).toBytesBE.size = 1 |
| 36 | + |
| 37 | +-- 12-bit value (pads to 2 bytes) |
| 38 | +#guard (0xABC#12).toBytesLE.data = #[0xBC, 0x0A] |
| 39 | +#guard (0xABC#12).toBytesBE.data = #[0x0A, 0xBC] |
| 40 | +#guard (0xABC#12).toBytesLE.size = 2 |
| 41 | +#guard (0xABC#12).toBytesBE.size = 2 |
| 42 | + |
| 43 | +-- 20-bit value (pads to 3 bytes) |
| 44 | +#guard (0x12345#20).toBytesLE.data = #[0x45, 0x23, 0x01] |
| 45 | +#guard (0x12345#20).toBytesBE.data = #[0x01, 0x23, 0x45] |
| 46 | +#guard (0x12345#20).toBytesLE.size = 3 |
| 47 | +#guard (0x12345#20).toBytesBE.size = 3 |
| 48 | + |
| 49 | +/-! ## Edge cases -/ |
| 50 | + |
| 51 | +-- Empty bitvector (width 0) |
| 52 | +#guard (0#0).toBytesLE.size = 0 |
| 53 | +#guard (0#0).toBytesBE.size = 0 |
| 54 | + |
| 55 | +-- Single bit |
| 56 | +#guard (0b1#1).toBytesLE.data = #[0x01] |
| 57 | +#guard (0b0#1).toBytesLE.data = #[0x00] |
| 58 | +#guard (0b1#1).toBytesLE.size = 1 |
| 59 | +#guard (0b0#1).toBytesLE.size = 1 |
| 60 | + |
| 61 | +-- All zeros |
| 62 | +#guard (0x0000#16).toBytesLE.data = #[0x00, 0x00] |
| 63 | +#guard (0x0000#16).toBytesBE.data = #[0x00, 0x00] |
| 64 | + |
| 65 | +-- All ones |
| 66 | +#guard (0xFFFF#16).toBytesLE.data = #[0xFF, 0xFF] |
| 67 | +#guard (0xFFFF#16).toBytesBE.data = #[0xFF, 0xFF] |
| 68 | + |
| 69 | +/-! ## Size properties -/ |
| 70 | + |
| 71 | +#guard (0x12345678#32).toBytesLE.size = 4 |
| 72 | +#guard (0x12345678#32).toBytesBE.size = 4 |
| 73 | +#guard (0x123456#24).toBytesLE.size = 3 |
| 74 | +#guard (0x123456#24).toBytesBE.size = 3 |
| 75 | +#guard (0x12345#20).toBytesLE.size = 3 -- rounds up from 2.5 bytes |
| 76 | + |
| 77 | +/-! ## Round trips (LE) -/ |
| 78 | + |
| 79 | +#guard ofBytesLE (ByteArray.mk #[0x34, 0x12]) = 0x1234#16 |
| 80 | +#guard ofBytesLE (ByteArray.mk #[0xAB]) = 0xAB#8 |
| 81 | +#guard ofBytesLE (ByteArray.mk #[0xEF, 0xBE, 0xAD, 0xDE]) = 0xDEADBEEF#32 |
| 82 | + |
| 83 | +#guard ofBytesLE (0x1234#16).toBytesLE = 0x1234#16 |
| 84 | +#guard ofBytesLE (0xDEADBEEF#32).toBytesLE = 0xDEADBEEF#32 |
| 85 | +#guard ofBytesLE (0xAB#8).toBytesLE = 0xAB#8 |
| 86 | + |
| 87 | +-- Non-multiple-of-8 round trips |
| 88 | +#guard ofBytesLE (0xABC#12).toBytesLE = 0xABC#16 |
| 89 | +#guard ofBytesLE (0x12345#20).toBytesLE = 0x12345#24 |
| 90 | +#guard ofBytesLE (0b101#3).toBytesLE = 0b101#8 |
| 91 | + |
| 92 | +/-! ## Round trips (BE) -/ |
| 93 | + |
| 94 | +#guard ofBytesBE (ByteArray.mk #[0x12, 0x34]) = 0x1234#16 |
| 95 | +#guard ofBytesBE (ByteArray.mk #[0xAB]) = 0xAB#8 |
| 96 | +#guard ofBytesBE (ByteArray.mk #[0xDE, 0xAD, 0xBE, 0xEF]) = 0xDEADBEEF#32 |
| 97 | + |
| 98 | +#guard ofBytesBE (0x1234#16).toBytesBE = 0x1234#16 |
| 99 | +#guard ofBytesBE (0xDEADBEEF#32).toBytesBE = 0xDEADBEEF#32 |
| 100 | +#guard ofBytesBE (0xAB#8).toBytesBE = 0xAB#8 |
| 101 | + |
| 102 | +-- Non-multiple-of-8 round trips |
| 103 | +#guard ofBytesBE (0xABC#12).toBytesBE = 0xABC#16 |
| 104 | +#guard ofBytesBE (0x12345#20).toBytesBE = 0x12345#24 |
| 105 | +#guard ofBytesBE (0b101#3).toBytesBE = 0b101#8 |
| 106 | + |
| 107 | +/-! ## Endianness differences -/ |
| 108 | + |
| 109 | +-- Single byte: LE and BE are the same |
| 110 | +#guard (0xFF#8).toBytesLE = (0xFF#8).toBytesBE |
| 111 | +#guard (0xAB#8).toBytesLE = (0xAB#8).toBytesBE |
| 112 | + |
| 113 | +-- Multi-byte: LE and BE are different (unless palindrome) |
| 114 | +#guard (0x00FF#16).toBytesLE.data != (0x00FF#16).toBytesBE.data |
| 115 | +#guard (0x1234#16).toBytesLE.data != (0x1234#16).toBytesBE.data |
| 116 | + |
| 117 | + |
| 118 | +/-! ## Empty ByteArray handling -/ |
| 119 | + |
| 120 | +#guard ofBytesLE ByteArray.empty = 0#0 |
| 121 | + |
| 122 | +/-! ## Integration with other BitVec operations -/ |
| 123 | + |
| 124 | +-- Bitwise operations preserve round-trip |
| 125 | +#guard let x := 0b11001100#8 |
| 126 | + let y := 0b10101010#8 |
| 127 | + ofBytesLE ((x &&& y).toBytesLE) = x &&& y |
| 128 | + |
| 129 | +#guard let x := 0x1234#16 |
| 130 | + let y := 0x5678#16 |
| 131 | + ofBytesLE ((x ||| y).toBytesLE) = x ||| y |
| 132 | + |
| 133 | +-- Concatenation and ByteArray conversions |
| 134 | +#guard let x := 0xAB#8 |
| 135 | + let y := 0xCD#8 |
| 136 | + (x ++ y).toBytesLE.data = #[0xCD, 0xAB] |
| 137 | + |
| 138 | +#guard let x := 0xAB#8 |
| 139 | + let y := 0xCD#8 |
| 140 | + (x ++ y).toBytesBE.data = #[0xAB, 0xCD] |
| 141 | + |
| 142 | +/-! ## Large bitvectors -/ |
| 143 | + |
| 144 | +-- Size checks for large widths |
| 145 | +#guard let x := allOnes 256 |
| 146 | + x.toBytesLE.size = 32 |
| 147 | + |
| 148 | +#guard let x := allOnes 256 |
| 149 | + x.toBytesBE.size = 32 |
0 commit comments