Home | History | Annotate | Download | only in desugar
      1 // Copyright 2017 The Bazel Authors. All rights reserved.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //    http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 package com.google.devtools.build.android.desugar;
     15 
     16 import static com.google.common.base.Preconditions.checkArgument;
     17 
     18 import com.google.common.io.ByteStreams;
     19 import java.io.BufferedOutputStream;
     20 import java.io.IOException;
     21 import java.io.InputStream;
     22 import java.nio.file.Files;
     23 import java.nio.file.Path;
     24 import java.util.zip.CRC32;
     25 import java.util.zip.ZipEntry;
     26 import java.util.zip.ZipOutputStream;
     27 
     28 /** Output provider is a zip file. */
     29 public class ZipOutputFileProvider implements OutputFileProvider {
     30 
     31   private final ZipOutputStream out;
     32 
     33   public ZipOutputFileProvider(Path root) throws IOException {
     34     out = new ZipOutputStream(new BufferedOutputStream(Files.newOutputStream(root)));
     35   }
     36 
     37   @Override
     38   public void copyFrom(String filename, InputFileProvider inputFileProvider) throws IOException {
     39     // TODO(bazel-team): Avoid de- and re-compressing resource files
     40     out.putNextEntry(inputFileProvider.getZipEntry(filename));
     41     try (InputStream is = inputFileProvider.getInputStream(filename)) {
     42       ByteStreams.copy(is, out);
     43     }
     44     out.closeEntry();
     45   }
     46 
     47   @Override
     48   public void write(String filename, byte[] content) throws IOException {
     49     checkArgument(filename.equals(DESUGAR_DEPS_FILENAME) || filename.endsWith(".class"),
     50         "Expect file to be copied: %s", filename);
     51     writeStoredEntry(out, filename, content);
     52   }
     53 
     54   @Override
     55   public void close() throws IOException {
     56     out.close();
     57   }
     58 
     59   private static void writeStoredEntry(ZipOutputStream out, String filename, byte[] content)
     60       throws IOException {
     61     // Need to pre-compute checksum for STORED (uncompressed) entries)
     62     CRC32 checksum = new CRC32();
     63     checksum.update(content);
     64 
     65     ZipEntry result = new ZipEntry(filename);
     66     result.setTime(0L); // Use stable timestamp Jan 1 1980
     67     result.setCrc(checksum.getValue());
     68     result.setSize(content.length);
     69     result.setCompressedSize(content.length);
     70     // Write uncompressed, since this is just an intermediary artifact that
     71     // we will convert to .dex
     72     result.setMethod(ZipEntry.STORED);
     73 
     74     out.putNextEntry(result);
     75     out.write(content);
     76     out.closeEntry();
     77   }
     78 }
     79