| // 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 static com.android.tools.r8.dex.Constants.VDEX_NUMBER_OF_DEX_FILES_OFFSET; |
| |
| import com.android.tools.r8.errors.CompilationError; |
| import com.google.common.collect.ImmutableList; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| /** |
| * Parse a VDEX and isolate the different dex files it contains. |
| */ |
| public class VDexParser { |
| |
| private VDexReader vDexReader; |
| private List<byte[]> dexFiles = new ArrayList<>(); |
| |
| public void close() { |
| vDexReader = null; |
| dexFiles = ImmutableList.of(); |
| } |
| |
| public VDexParser(VDexReader vDexReader) { |
| this.vDexReader = vDexReader; |
| vDexReader.setByteOrder(); |
| parseDexFiles(); |
| } |
| |
| public List<byte[]> getDexFiles() { |
| return dexFiles; |
| } |
| |
| private void parseDexFiles() { |
| vDexReader.position(VDEX_NUMBER_OF_DEX_FILES_OFFSET); |
| int numberOfDexFiles = vDexReader.getUint(); |
| int dexSize = vDexReader.getUint(); |
| int verifierDepsSize = vDexReader.getUint(); |
| int quickeningInfoSize = vDexReader.getUint(); |
| |
| int offset = VDexReader.firstDexOffset(numberOfDexFiles); |
| int totalDexSize = 0; |
| for (int i = 0; i < numberOfDexFiles; i++) { |
| int size = vDexReader.getUint(offset + Constants.FILE_SIZE_OFFSET); |
| vDexReader.position(offset); |
| dexFiles.add(vDexReader.getByteArray(size)); |
| totalDexSize += size; |
| offset += size; |
| } |
| if (totalDexSize != dexSize) { |
| throw new CompilationError("Invalid vdex file. Mismatch in total dex files size"); |
| } |
| } |
| } |