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