| // Copyright (c) 2017, 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 com.android.tools.r8.ProgramResource; | |
| import com.android.tools.r8.ResourceException; | |
| import com.android.tools.r8.origin.Origin; | |
| import com.android.tools.r8.utils.LebUtils; | |
| import com.android.tools.r8.utils.StreamUtils; | |
| import java.io.IOException; | |
| /** | |
| * Base class for reading binary content. | |
| */ | |
| public abstract class BinaryReader { | |
| protected final Origin origin; | |
| protected final CompatByteBuffer buffer; | |
| protected BinaryReader(ProgramResource resource) throws ResourceException, IOException { | |
| this(resource.getOrigin(), StreamUtils.streamToByteArrayClose(resource.getByteStream())); | |
| } | |
| protected BinaryReader(Origin origin, byte[] bytes) { | |
| assert origin != null; | |
| this.origin = origin; | |
| buffer = CompatByteBuffer.wrap(bytes); | |
| } | |
| public Origin getOrigin() { | |
| return origin; | |
| } | |
| abstract void setByteOrder(); | |
| byte[] getByteArray(int size) { | |
| byte[] result = new byte[size]; | |
| buffer.get(result); | |
| return result; | |
| } | |
| int getUleb128() { | |
| return LebUtils.parseUleb128(this); | |
| } | |
| int getSleb128() { | |
| return LebUtils.parseSleb128(this); | |
| } | |
| int getUleb128p1() { | |
| return getUleb128() - 1; | |
| } | |
| int getUint() { | |
| int result = buffer.getInt(); | |
| assert result >= 0; // Ensure the java int didn't overflow. | |
| return result; | |
| } | |
| int getUshort() { | |
| int result = buffer.getShort() & 0xffff; | |
| assert result >= 0; // Ensure we have a non-negative number. | |
| return result; | |
| } | |
| short getShort() { | |
| return buffer.getShort(); | |
| } | |
| int getUint(int offset) { | |
| int result = buffer.getInt(offset); | |
| assert result >= 0; // Ensure the java int didn't overflow. | |
| return result; | |
| } | |
| public int getInt() { | |
| return buffer.getInt(); | |
| } | |
| int position() { | |
| return buffer.position(); | |
| } | |
| void position(int position) { | |
| buffer.position(position); | |
| } | |
| void align(int alignment) { | |
| assert (alignment & (alignment - 1)) == 0; // Check alignment is power of 2. | |
| int p = buffer.position(); | |
| p += (alignment - (p % alignment)) & (alignment - 1); | |
| buffer.position(p); | |
| } | |
| public byte get() { | |
| return buffer.get(); | |
| } | |
| int getUbyte() { | |
| int result = buffer.get() & 0xff; | |
| assert result >= 0; // Ensure we have a non-negative result. | |
| return result; | |
| } | |
| int end() { | |
| return buffer.capacity(); | |
| } | |
| } |