| // 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.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. |
| * |
| * 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. |
| */ |
| @KeepForSubclassing |
| public interface ProgramResource extends Resource { |
| |
| /** Type of program-format kinds. */ |
| @Keep |
| 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. */ |
| @Keep |
| 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. */ |
| @Keep |
| 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; |
| } |
| |
| @Override |
| public InputStream getByteStream() throws ResourceException { |
| return new ByteArrayInputStream(bytes); |
| } |
| |
| @Override |
| public byte[] getBytes() throws ResourceException { |
| return bytes; |
| } |
| |
| @Override |
| public Set<String> getClassDescriptors() { |
| return classDescriptors; |
| } |
| } |
| } |