blob: 3550c6f9f616ee74cb0332fe83293bbd204db0d7 [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package libcore.tzdata.update.tools;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import libcore.tzdata.update.ConfigBundle;
/**
* A class for creating a {@link ConfigBundle} containing timezone update data.
*/
public final class TzDataBundleBuilder {
private String tzDataVersion;
private StringBuilder checksumsFileContent = new StringBuilder();
private File zoneInfoFile;
private File icuTzDataFile;
public TzDataBundleBuilder setTzDataVersion(String tzDataVersion) {
this.tzDataVersion = tzDataVersion;
return this;
}
public TzDataBundleBuilder addChecksum(String fileName, long checksum) {
checksumsFileContent.append(Long.toString(checksum))
.append(',')
.append(fileName)
.append('\n');
return this;
}
public TzDataBundleBuilder addBionicTzData(File zoneInfoFile) {
this.zoneInfoFile = zoneInfoFile;
return this;
}
public TzDataBundleBuilder addIcuTzData(File icuTzDataFile) {
this.icuTzDataFile = icuTzDataFile;
return this;
}
/**
* Builds a {@link libcore.tzdata.update.ConfigBundle}.
*/
public ConfigBundle build() throws IOException {
if (tzDataVersion == null) {
throw new IllegalStateException("Missing tzDataVersion");
}
if (zoneInfoFile == null) {
throw new IllegalStateException("Missing zoneInfo file");
}
return buildUnvalidated();
}
// For use in tests.
public TzDataBundleBuilder clearChecksumEntries() {
checksumsFileContent.setLength(0);
return this;
}
// For use in tests.
public TzDataBundleBuilder clearBionicTzData() {
this.zoneInfoFile = null;
return this;
}
/**
* For use in tests. Use {@link #build()}.
*/
public ConfigBundle buildUnvalidated() throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ZipOutputStream zos = new ZipOutputStream(baos)) {
addZipEntry(zos, ConfigBundle.CHECKSUMS_FILE_NAME,
checksumsFileContent.toString().getBytes(StandardCharsets.UTF_8));
if (tzDataVersion != null) {
addZipEntry(zos, ConfigBundle.TZ_DATA_VERSION_FILE_NAME,
tzDataVersion.getBytes(StandardCharsets.UTF_8));
}
if (zoneInfoFile != null) {
addZipEntry(zos, ConfigBundle.ZONEINFO_FILE_NAME,
readFileAsByteArray(zoneInfoFile));
}
if (icuTzDataFile != null) {
addZipEntry(zos, ConfigBundle.ICU_DATA_FILE_NAME,
readFileAsByteArray(icuTzDataFile));
}
}
return new ConfigBundle(baos.toByteArray());
}
private static void addZipEntry(ZipOutputStream zos, String name, byte[] content)
throws IOException {
ZipEntry zipEntry = new ZipEntry(name);
zipEntry.setSize(content.length);
zos.putNextEntry(zipEntry);
zos.write(content);
zos.closeEntry();
}
/**
* Returns the contents of 'path' as a byte array.
*/
public static byte[] readFileAsByteArray(File file) throws IOException {
byte[] buffer = new byte[8192];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (FileInputStream fis = new FileInputStream(file)) {
int count;
while ((count = fis.read(buffer)) != -1) {
baos.write(buffer, 0, count);
}
}
return baos.toByteArray();
}
}