|  | // 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"); | 
|  | } | 
|  | } | 
|  | } |