1 // Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file 2 // for details. All rights reserved. Use of this source code is governed by a 3 // BSD-style license that can be found in the LICENSE file. 4 package com.android.tools.r8.dex; 5 6 import static com.android.tools.r8.dex.Constants.DEX_MAGIC_SIZE; 7 import static org.junit.Assert.assertEquals; 8 import static org.junit.Assert.assertTrue; 9 10 import com.android.tools.r8.utils.EncodedValueUtils; 11 import java.util.Arrays; 12 import java.util.Collection; 13 import org.junit.Assert; 14 import org.junit.Test; 15 import org.junit.runner.RunWith; 16 import org.junit.runners.Parameterized; 17 import org.junit.runners.Parameterized.Parameters; 18 19 @RunWith(Parameterized.class) 20 public class EncodedFloatingValueTest { 21 private final double value; 22 23 public EncodedFloatingValueTest(double value) { 24 this.value = value; 25 } 26 27 @Parameters(name = "{0}") 28 public static Collection<Double> data() { 29 return Arrays.asList( 30 0.0, 31 1.0, 32 0.5, 33 Double.longBitsToDouble(1), // Lowest bit is 1 in double 34 Double.longBitsToDouble(0x10), // Bits on byte boundary are 1. 35 Double.longBitsToDouble(0x08), 36 Double.longBitsToDouble(4607071218809329336L), // Test a real long (regression). 37 (double) (Float.intBitsToFloat(1)), // Lowest bit is 1 in float 38 (double) (Float.intBitsToFloat(0x10)), // Bits on byte boundary are 1 39 (double) (Float.intBitsToFloat(0x08)) 40 ); 41 } 42 43 // Create a DexFile with correct file magic followed by the argument bytes. Positions the 44 // DexFile after the file magic. 45 private DexFile createDexFileWithContent(byte[] bytes) { 46 DexOutputBuffer buffer = new DexOutputBuffer(); 47 buffer.putBytes(Constants.DEX_FILE_MAGIC_PREFIX); 48 buffer.putBytes(Constants.ANDROID_PRE_N_DEX_VERSION_BYTES); 49 buffer.putByte(Constants.DEX_FILE_MAGIC_SUFFIX); 50 buffer.putBytes(bytes); 51 DexFile dexFile = new DexFile(buffer.asArray()); 52 dexFile.position(DEX_MAGIC_SIZE); 53 return dexFile; 54 } 55 56 @Test 57 public void testEncodeDecodeDouble() { 58 byte[] bytes = EncodedValueUtils.encodeDouble(value); 59 assertTrue(bytes.length <= Double.BYTES); 60 DexFile dexFile = createDexFileWithContent(bytes); 61 Assert.assertEquals(value, EncodedValueUtils.parseDouble(dexFile, bytes.length), 0.0); 62 } 63 64 @Test 65 public void testEncodeDecodeFloat() { 66 byte[] bytes = EncodedValueUtils.encodeFloat((float) value); 67 assertTrue(bytes.length <= Float.BYTES); 68 DexFile dexFile = createDexFileWithContent(bytes); 69 Assert.assertEquals((float) value, EncodedValueUtils.parseFloat(dexFile, bytes.length), 0.0f); 70 } 71 72 @Test 73 public void testEncodeDecodeDoubleWithDexBuffer() { 74 DexOutputBuffer buffer = new DexOutputBuffer(); 75 int length = EncodedValueUtils.putDouble(buffer, value); 76 assertTrue(length <= Double.BYTES); 77 byte[] bytes = buffer.asArray(); 78 DexFile dexFile = createDexFileWithContent(bytes); 79 assertEquals(value, EncodedValueUtils.parseDouble(dexFile, length), 0.0); 80 } 81 82 @Test 83 public void testEncodeDecodeFloatWithDexBuffer() { 84 DexOutputBuffer buffer = new DexOutputBuffer(); 85 int length = EncodedValueUtils.putFloat(buffer, (float) value); 86 assertTrue(length <= Float.BYTES); 87 byte[] bytes = buffer.asArray(); 88 DexFile dexFile = createDexFileWithContent(bytes); 89 assertEquals((float) value, EncodedValueUtils.parseFloat(dexFile, length), 0.0f); 90 } 91 } 92