| // 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; | |
| import com.android.tools.r8.keepanno.annotations.KeepForApi; | |
| import com.android.tools.r8.origin.Origin; | |
| import com.android.tools.r8.origin.PathOrigin; | |
| import com.android.tools.r8.utils.StreamUtils; | |
| import java.io.ByteArrayInputStream; | |
| import java.io.IOException; | |
| import java.io.InputStream; | |
| import java.nio.file.Files; | |
| import java.nio.file.Path; | |
| import java.util.Set; | |
| /** | |
| * Represents program application resources. | |
| * | |
| * <p>The content kind or format of a program resource can be either a Java class-file or an Android | |
| * DEX file. In both cases, the resource must be able to provide the content as a byte stream. A | |
| * resource may optionally include a set describing the class descriptors for each type that is | |
| * defined by the resource. | |
| */ | |
| @KeepForApi | |
| public interface ProgramResource extends Resource { | |
| /** Type of program-format kinds. */ | |
| @KeepForApi | |
| enum Kind { | |
| /** Format-kind for Java class-file resources. */ | |
| CF, | |
| /** Format-kind for Android dex-file resources. */ | |
| DEX, | |
| } | |
| /** | |
| * Create a program resource for a given file. | |
| * | |
| * <p>The origin of a file resource is the path of the file. | |
| */ | |
| static ProgramResource fromFile(Kind kind, Path file) { | |
| return new FileResource(kind, file, null); | |
| } | |
| /** | |
| * Create a program resource for a given type, content and type descriptor. | |
| * | |
| * <p>The origin must be supplied upon construction. If no reasonable origin | |
| * exits, use {@code Origin.unknown()}. | |
| */ | |
| static ProgramResource fromBytes( | |
| Origin origin, Kind kind, byte[] bytes, Set<String> typeDescriptors) { | |
| return new ByteResource(origin, kind, bytes, typeDescriptors); | |
| } | |
| /** Get the program format-kind of the resource. */ | |
| Kind getKind(); | |
| /** Get the bytes of the program resource. */ | |
| InputStream getByteStream() throws ResourceException; | |
| /** Optional getter to obtain the bytes of the program resource as an array. */ | |
| default byte[] getBytes() throws ResourceException { | |
| try { | |
| return StreamUtils.streamToByteArrayClose(getByteStream()); | |
| } catch (IOException e) { | |
| throw new ResourceException(getOrigin(), e); | |
| } | |
| } | |
| /** | |
| * Get the set of class descriptors for classes defined by this resource. | |
| * | |
| * <p>This is not deprecated and will remain after Resource::getClassDescriptors is removed. | |
| * | |
| * @return Set of class descriptors defined by the resource or null if unknown. | |
| */ | |
| Set<String> getClassDescriptors(); | |
| /** File-based program resource. */ | |
| @KeepForApi | |
| class FileResource implements ProgramResource { | |
| private final Origin origin; | |
| private final Kind kind; | |
| private final Path file; | |
| private final Set<String> classDescriptors; | |
| private FileResource(Kind kind, Path file, Set<String> classDescriptors) { | |
| this.origin = new PathOrigin(file); | |
| this.kind = kind; | |
| this.file = file; | |
| this.classDescriptors = classDescriptors; | |
| } | |
| @Override | |
| public Origin getOrigin() { | |
| return origin; | |
| } | |
| @Override | |
| public Kind getKind() { | |
| return kind; | |
| } | |
| @Override | |
| public InputStream getByteStream() throws ResourceException { | |
| try { | |
| return Files.newInputStream(file); | |
| } catch (IOException e) { | |
| throw new ResourceException(getOrigin(), e); | |
| } | |
| } | |
| @Override | |
| public byte[] getBytes() throws ResourceException { | |
| try { | |
| return Files.readAllBytes(file); | |
| } catch (IOException e) { | |
| throw new ResourceException(getOrigin(), e); | |
| } | |
| } | |
| @Override | |
| public Set<String> getClassDescriptors() { | |
| return classDescriptors; | |
| } | |
| } | |
| /** Byte-content based program resource. */ | |
| @KeepForApi | |
| class ByteResource implements ProgramResource { | |
| private final Origin origin; | |
| private final Kind kind; | |
| private final byte[] bytes; | |
| private final Set<String> classDescriptors; | |
| private ByteResource(Origin origin, Kind kind, byte[] bytes, Set<String> classDescriptors) { | |
| assert bytes != null; | |
| this.origin = origin; | |
| this.kind = kind; | |
| this.bytes = bytes; | |
| this.classDescriptors = classDescriptors; | |
| } | |
| @Override | |
| public Origin getOrigin() { | |
| return origin; | |
| } | |
| @Override | |
| public Kind getKind() { | |
| return kind; | |
| } | |
| @SuppressWarnings("RedundantThrows") | |
| @Override | |
| public InputStream getByteStream() throws ResourceException { | |
| return new ByteArrayInputStream(bytes); | |
| } | |
| @SuppressWarnings("RedundantThrows") | |
| @Override | |
| public byte[] getBytes() throws ResourceException { | |
| return bytes; | |
| } | |
| @Override | |
| public Set<String> getClassDescriptors() { | |
| return classDescriptors; | |
| } | |
| } | |
| } |