| // 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 com.android.tools.r8.origin.Origin; |
| import com.android.tools.r8.utils.AndroidApiLevel; |
| import com.android.tools.r8.utils.LebUtils; |
| 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; |
| |
| /** |
| * Test for encoding and decoding Leb128 |
| */ |
| @RunWith(Parameterized.class) |
| public class Leb128Test { |
| private final int value; |
| |
| public Leb128Test(int value) { |
| this.value = value; |
| } |
| |
| @Parameters(name = "{0}") |
| public static Collection<Integer> data() { |
| return Arrays.asList( |
| 0, |
| 0x3f, // Uses 6 bits |
| 0x7f, // Uses 7 bits |
| 0xff, // Uses 8 bits |
| 0x3ff, // Uses 14 bits |
| 0x407f, // Uses 15 bits with 7 consecutive 0s. |
| Integer.MIN_VALUE, // 10...0 pattern |
| 0xffffffc0, // 1..1000000 |
| 0xffffff80, // 1..10000000 |
| 0xffffff00, // 1..100000000 |
| 0xffffc07f, // Uses 15 bits with 7 consecutive 0s. |
| Integer.MIN_VALUE + 1 |
| ); |
| } |
| |
| // 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 encodeDecodeLeb128TestWithDexBuffer() { |
| if (value < 0) { |
| return; |
| } |
| DexOutputBuffer buffer = new DexOutputBuffer(); |
| LebUtils.putUleb128(buffer, value); |
| Assert.assertEquals(buffer.position(), LebUtils.sizeAsUleb128(value)); |
| DexReader reader = createDexFileWithContent(buffer.asArray()); |
| Assert.assertEquals(value, LebUtils.parseUleb128(reader)); |
| } |
| |
| @Test |
| public void encodeDecodeLeb128Test() { |
| if (value < 0) { |
| return; |
| } |
| byte[] encoded = LebUtils.encodeUleb128(value); |
| Assert.assertEquals(encoded.length, LebUtils.sizeAsUleb128(value)); |
| DexReader reader = createDexFileWithContent(encoded); |
| Assert.assertEquals(value, LebUtils.parseUleb128(reader)); |
| } |
| |
| @Test |
| public void encodeDecodeSLeb128TestWithDexBuffer() { |
| DexOutputBuffer buffer = new DexOutputBuffer(); |
| LebUtils.putSleb128(buffer, value); |
| Assert.assertEquals(buffer.position(), LebUtils.sizeAsSleb128(value)); |
| DexReader reader = createDexFileWithContent(buffer.asArray()); |
| Assert.assertEquals(value, LebUtils.parseSleb128(reader)); |
| } |
| |
| |
| @Test |
| public void encodeDecodeSLeb128Test() { |
| byte[] encoded = LebUtils.encodeSleb128(value); |
| Assert.assertEquals(encoded.length, LebUtils.sizeAsSleb128(value)); |
| DexReader reader = createDexFileWithContent(encoded); |
| Assert.assertEquals(value, LebUtils.parseSleb128(reader)); |
| } |
| } |