| // Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| package com.android.tools.r8.dex; | |
| import static com.android.tools.r8.dex.Constants.DEX_MAGIC_SIZE; | |
| import static org.junit.Assert.assertEquals; | |
| import static org.junit.Assert.assertTrue; | |
| import com.android.tools.r8.origin.Origin; | |
| import com.android.tools.r8.utils.AndroidApiLevel; | |
| import com.android.tools.r8.utils.EncodedValueUtils; | |
| import java.util.Arrays; | |
| import java.util.Collection; | |
| import org.junit.Assert; | |
| import org.junit.Test; | |
| import org.junit.runner.RunWith; | |
| import org.junit.runners.Parameterized; | |
| import org.junit.runners.Parameterized.Parameters; | |
| @RunWith(Parameterized.class) | |
| public class EncodedFloatingValueTest { | |
| private final double value; | |
| public EncodedFloatingValueTest(double value) { | |
| this.value = value; | |
| } | |
| @Parameters(name = "{0}") | |
| public static Collection<Double> data() { | |
| return Arrays.asList( | |
| 0.0, | |
| 1.0, | |
| 0.5, | |
| Double.longBitsToDouble(1), // Lowest bit is 1 in double | |
| Double.longBitsToDouble(0x10), // Bits on byte boundary are 1. | |
| Double.longBitsToDouble(0x08), | |
| Double.longBitsToDouble(4607071218809329336L), // Test a real long (regression). | |
| (double) (Float.intBitsToFloat(1)), // Lowest bit is 1 in float | |
| (double) (Float.intBitsToFloat(0x10)), // Bits on byte boundary are 1 | |
| (double) (Float.intBitsToFloat(0x08)) | |
| ); | |
| } | |
| // Create a DexReader with correct file magic followed by the argument bytes. Positions the | |
| // DexReader after the file magic. | |
| private DexReader createDexFileWithContent(byte[] bytes) { | |
| DexOutputBuffer buffer = new DexOutputBuffer(); | |
| buffer.putBytes(Constants.DEX_FILE_MAGIC_PREFIX); | |
| buffer.putBytes(AndroidApiLevel.B.getDexVersion().getBytes()); | |
| buffer.putByte(Constants.DEX_FILE_MAGIC_SUFFIX); | |
| buffer.putBytes(bytes); | |
| DexReader dexReader = new DexReader(Origin.unknown(), buffer.asArray()); | |
| dexReader.position(DEX_MAGIC_SIZE); | |
| return dexReader; | |
| } | |
| @Test | |
| public void testEncodeDecodeDouble() { | |
| byte[] bytes = EncodedValueUtils.encodeDouble(value); | |
| assertTrue(bytes.length <= Double.BYTES); | |
| DexReader dexReader = createDexFileWithContent(bytes); | |
| Assert.assertEquals(value, EncodedValueUtils.parseDouble(dexReader, bytes.length), 0.0); | |
| } | |
| @Test | |
| public void testEncodeDecodeFloat() { | |
| byte[] bytes = EncodedValueUtils.encodeFloat((float) value); | |
| assertTrue(bytes.length <= Float.BYTES); | |
| DexReader dexReader = createDexFileWithContent(bytes); | |
| Assert.assertEquals((float) value, EncodedValueUtils.parseFloat(dexReader, bytes.length), 0.0f); | |
| } | |
| @Test | |
| public void testEncodeDecodeDoubleWithDexBuffer() { | |
| DexOutputBuffer buffer = new DexOutputBuffer(); | |
| int length = EncodedValueUtils.putDouble(buffer, value); | |
| assertTrue(length <= Double.BYTES); | |
| byte[] bytes = buffer.asArray(); | |
| DexReader dexReader = createDexFileWithContent(bytes); | |
| assertEquals(value, EncodedValueUtils.parseDouble(dexReader, length), 0.0); | |
| } | |
| @Test | |
| public void testEncodeDecodeFloatWithDexBuffer() { | |
| DexOutputBuffer buffer = new DexOutputBuffer(); | |
| int length = EncodedValueUtils.putFloat(buffer, (float) value); | |
| assertTrue(length <= Float.BYTES); | |
| byte[] bytes = buffer.asArray(); | |
| DexReader dexReader = createDexFileWithContent(bytes); | |
| assertEquals((float) value, EncodedValueUtils.parseFloat(dexReader, length), 0.0f); | |
| } | |
| } |