195395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler// Copyright 2017 The Bazel Authors. All rights reserved.
295395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler//
395395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler// Licensed under the Apache License, Version 2.0 (the "License");
495395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler// you may not use this file except in compliance with the License.
595395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler// You may obtain a copy of the License at
695395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler//
795395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler//    http://www.apache.org/licenses/LICENSE-2.0
895395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler//
995395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler// Unless required by applicable law or agreed to in writing, software
1095395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler// distributed under the License is distributed on an "AS IS" BASIS,
1195395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1295395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler// See the License for the specific language governing permissions and
1395395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler// limitations under the License.
1495395ef8bc57dab3c5b356b5fd91c3d175c33d0fGooglerpackage com.google.devtools.build.android.desugar;
1595395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler
1659adc3acdd6a3dd50fa2ffae0cba2370209c86d6kmbimport static com.google.common.base.Preconditions.checkArgument;
1759adc3acdd6a3dd50fa2ffae0cba2370209c86d6kmb
1895395ef8bc57dab3c5b356b5fd91c3d175c33d0fGooglerimport com.google.common.io.ByteStreams;
1995395ef8bc57dab3c5b356b5fd91c3d175c33d0fGooglerimport java.io.BufferedOutputStream;
2095395ef8bc57dab3c5b356b5fd91c3d175c33d0fGooglerimport java.io.IOException;
2195395ef8bc57dab3c5b356b5fd91c3d175c33d0fGooglerimport java.io.InputStream;
2295395ef8bc57dab3c5b356b5fd91c3d175c33d0fGooglerimport java.nio.file.Files;
2395395ef8bc57dab3c5b356b5fd91c3d175c33d0fGooglerimport java.nio.file.Path;
2495395ef8bc57dab3c5b356b5fd91c3d175c33d0fGooglerimport java.util.zip.CRC32;
2595395ef8bc57dab3c5b356b5fd91c3d175c33d0fGooglerimport java.util.zip.ZipEntry;
2695395ef8bc57dab3c5b356b5fd91c3d175c33d0fGooglerimport java.util.zip.ZipOutputStream;
2795395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler
2895395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler/** Output provider is a zip file. */
2995395ef8bc57dab3c5b356b5fd91c3d175c33d0fGooglerpublic class ZipOutputFileProvider implements OutputFileProvider {
3095395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler
3195395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler  private final ZipOutputStream out;
3295395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler
3395395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler  public ZipOutputFileProvider(Path root) throws IOException {
3495395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler    out = new ZipOutputStream(new BufferedOutputStream(Files.newOutputStream(root)));
3595395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler  }
3695395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler
3795395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler  @Override
3895395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler  public void copyFrom(String filename, InputFileProvider inputFileProvider) throws IOException {
3995395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler    // TODO(bazel-team): Avoid de- and re-compressing resource files
4095395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler    out.putNextEntry(inputFileProvider.getZipEntry(filename));
4195395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler    try (InputStream is = inputFileProvider.getInputStream(filename)) {
4295395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler      ByteStreams.copy(is, out);
4395395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler    }
4495395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler    out.closeEntry();
4595395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler  }
4695395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler
4795395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler  @Override
4895395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler  public void write(String filename, byte[] content) throws IOException {
4959adc3acdd6a3dd50fa2ffae0cba2370209c86d6kmb    checkArgument(filename.equals(DESUGAR_DEPS_FILENAME) || filename.endsWith(".class"),
5059adc3acdd6a3dd50fa2ffae0cba2370209c86d6kmb        "Expect file to be copied: %s", filename);
5195395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler    writeStoredEntry(out, filename, content);
5295395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler  }
5395395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler
5495395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler  @Override
5595395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler  public void close() throws IOException {
5695395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler    out.close();
5795395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler  }
5895395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler
5995395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler  private static void writeStoredEntry(ZipOutputStream out, String filename, byte[] content)
6095395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler      throws IOException {
6195395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler    // Need to pre-compute checksum for STORED (uncompressed) entries)
6295395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler    CRC32 checksum = new CRC32();
6395395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler    checksum.update(content);
6495395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler
6595395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler    ZipEntry result = new ZipEntry(filename);
6695395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler    result.setTime(0L); // Use stable timestamp Jan 1 1980
6795395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler    result.setCrc(checksum.getValue());
6895395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler    result.setSize(content.length);
6995395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler    result.setCompressedSize(content.length);
7095395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler    // Write uncompressed, since this is just an intermediary artifact that
7195395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler    // we will convert to .dex
7295395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler    result.setMethod(ZipEntry.STORED);
7395395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler
7495395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler    out.putNextEntry(result);
7595395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler    out.write(content);
7695395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler    out.closeEntry();
7795395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler  }
7895395ef8bc57dab3c5b356b5fd91c3d175c33d0fGoogler}
79