1 /*
2  * Copyright (C) 2017 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 package com.android.internal.util;
18 
19 import static com.android.internal.util.BitUtils.bytesToBEInt;
20 import static com.android.internal.util.BitUtils.bytesToLEInt;
21 import static com.android.internal.util.BitUtils.getUint16;
22 import static com.android.internal.util.BitUtils.getUint32;
23 import static com.android.internal.util.BitUtils.getUint8;
24 import static com.android.internal.util.BitUtils.packBits;
25 import static com.android.internal.util.BitUtils.uint16;
26 import static com.android.internal.util.BitUtils.uint32;
27 import static com.android.internal.util.BitUtils.uint8;
28 import static com.android.internal.util.BitUtils.unpackBits;
29 
30 import static org.junit.Assert.assertEquals;
31 import static org.junit.Assert.assertTrue;
32 
33 import androidx.test.filters.SmallTest;
34 import androidx.test.runner.AndroidJUnit4;
35 
36 import org.junit.Test;
37 import org.junit.runner.RunWith;
38 
39 import java.nio.ByteBuffer;
40 import java.util.Arrays;
41 import java.util.Random;
42 
43 @SmallTest
44 @RunWith(AndroidJUnit4.class)
45 public class BitUtilsTest {
46 
47     @Test
testUnsignedByteWideningConversions()48     public void testUnsignedByteWideningConversions() {
49         byte b0 = 0;
50         byte b1 = 1;
51         byte bm1 = -1;
52         assertEquals(0, uint8(b0));
53         assertEquals(1, uint8(b1));
54         assertEquals(127, uint8(Byte.MAX_VALUE));
55         assertEquals(128, uint8(Byte.MIN_VALUE));
56         assertEquals(255, uint8(bm1));
57         assertEquals(255, uint8((byte)255));
58     }
59 
60     @Test
testUnsignedShortWideningConversions()61     public void testUnsignedShortWideningConversions() {
62         short s0 = 0;
63         short s1 = 1;
64         short sm1 = -1;
65         assertEquals(0, uint16(s0));
66         assertEquals(1, uint16(s1));
67         assertEquals(32767, uint16(Short.MAX_VALUE));
68         assertEquals(32768, uint16(Short.MIN_VALUE));
69         assertEquals(65535, uint16(sm1));
70         assertEquals(65535, uint16((short)65535));
71     }
72 
73     @Test
testUnsignedShortComposition()74     public void testUnsignedShortComposition() {
75         byte b0 = 0;
76         byte b1 = 1;
77         byte b2 = 2;
78         byte b10 = 10;
79         byte b16 = 16;
80         byte b128 = -128;
81         byte b224 = -32;
82         byte b255 = -1;
83         assertEquals(0x0000, uint16(b0, b0));
84         assertEquals(0xffff, uint16(b255, b255));
85         assertEquals(0x0a01, uint16(b10, b1));
86         assertEquals(0x8002, uint16(b128, b2));
87         assertEquals(0x01ff, uint16(b1, b255));
88         assertEquals(0x80ff, uint16(b128, b255));
89         assertEquals(0xe010, uint16(b224, b16));
90     }
91 
92     @Test
testUnsignedIntWideningConversions()93     public void testUnsignedIntWideningConversions() {
94         assertEquals(0, uint32(0));
95         assertEquals(1, uint32(1));
96         assertEquals(2147483647L, uint32(Integer.MAX_VALUE));
97         assertEquals(2147483648L, uint32(Integer.MIN_VALUE));
98         assertEquals(4294967295L, uint32(-1));
99         assertEquals(4294967295L, uint32((int)4294967295L));
100     }
101 
102     @Test
testBytesToInt()103     public void testBytesToInt() {
104         assertEquals(0x00000000, bytesToBEInt(bytes(0, 0, 0, 0)));
105         assertEquals(0xffffffff, bytesToBEInt(bytes(255, 255, 255, 255)));
106         assertEquals(0x0a000001, bytesToBEInt(bytes(10, 0, 0, 1)));
107         assertEquals(0x0a000002, bytesToBEInt(bytes(10, 0, 0, 2)));
108         assertEquals(0x0a001fff, bytesToBEInt(bytes(10, 0, 31, 255)));
109         assertEquals(0xe0000001, bytesToBEInt(bytes(224, 0, 0, 1)));
110 
111         assertEquals(0x00000000, bytesToLEInt(bytes(0, 0, 0, 0)));
112         assertEquals(0x01020304, bytesToLEInt(bytes(4, 3, 2, 1)));
113         assertEquals(0xffff0000, bytesToLEInt(bytes(0, 0, 255, 255)));
114     }
115 
116     @Test
testUnsignedGetters()117     public void testUnsignedGetters() {
118         ByteBuffer b = ByteBuffer.allocate(4);
119         b.putInt(0xffff);
120 
121         assertEquals(0x0, getUint8(b, 0));
122         assertEquals(0x0, getUint8(b, 1));
123         assertEquals(0xff, getUint8(b, 2));
124         assertEquals(0xff, getUint8(b, 3));
125 
126         assertEquals(0x0, getUint16(b, 0));
127         assertEquals(0xffff, getUint16(b, 2));
128 
129         b.rewind();
130         b.putInt(0xffffffff);
131         assertEquals(0xffffffffL, getUint32(b, 0));
132     }
133 
134     @Test
testBitsPacking()135     public void testBitsPacking() {
136         BitPackingTestCase[] testCases = {
137             new BitPackingTestCase(0, ints()),
138             new BitPackingTestCase(1, ints(0)),
139             new BitPackingTestCase(2, ints(1)),
140             new BitPackingTestCase(3, ints(0, 1)),
141             new BitPackingTestCase(4, ints(2)),
142             new BitPackingTestCase(6, ints(1, 2)),
143             new BitPackingTestCase(9, ints(0, 3)),
144             new BitPackingTestCase(~Long.MAX_VALUE, ints(63)),
145             new BitPackingTestCase(~Long.MAX_VALUE + 1, ints(0, 63)),
146             new BitPackingTestCase(~Long.MAX_VALUE + 2, ints(1, 63)),
147         };
148         for (BitPackingTestCase tc : testCases) {
149             int[] got = unpackBits(tc.packedBits);
150             assertTrue(
151                     "unpackBits("
152                             + tc.packedBits
153                             + "): expected "
154                             + Arrays.toString(tc.bits)
155                             + " but got "
156                             + Arrays.toString(got),
157                     Arrays.equals(tc.bits, got));
158         }
159         for (BitPackingTestCase tc : testCases) {
160             long got = packBits(tc.bits);
161             assertEquals(
162                     "packBits("
163                             + Arrays.toString(tc.bits)
164                             + "): expected "
165                             + tc.packedBits
166                             + " but got "
167                             + got,
168                     tc.packedBits,
169                     got);
170         }
171 
172         long[] moreTestCases = {
173             0, 1, -1, 23895, -908235, Long.MAX_VALUE, Long.MIN_VALUE, new Random().nextLong(),
174         };
175         for (long l : moreTestCases) {
176             assertEquals(l, packBits(unpackBits(l)));
177         }
178     }
179 
bytes(int b1, int b2, int b3, int b4)180     static byte[] bytes(int b1, int b2, int b3, int b4) {
181         return new byte[] {b(b1), b(b2), b(b3), b(b4)};
182     }
183 
b(int i)184     static byte b(int i) {
185         return (byte) i;
186     }
187 
ints(int... array)188     static int[] ints(int... array) {
189         return array;
190     }
191 
192     static class BitPackingTestCase {
193         final int[] bits;
194         final long packedBits;
195 
BitPackingTestCase(long packedBits, int[] bits)196         BitPackingTestCase(long packedBits, int[] bits) {
197             this.bits = bits;
198             this.packedBits = packedBits;
199         }
200     }
201 }
202