From eb06129c5c569897a897f9ec9ee300560ec3b436 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Fri, 19 Oct 2012 12:05:24 -0700 Subject: [PATCH] Switch bionic over to using libcore's copy of libcore.util.ZoneInfo. Bug: 7012465 Change-Id: I1225494c5d77a20fd48be1e904d8695ef95860e3 --- libc/tools/zoneinfo/ZoneCompactor.java | 75 +++++-- libc/tools/zoneinfo/ZoneInfo.java | 272 ------------------------- libc/tools/zoneinfo/generate | 4 +- 3 files changed, 61 insertions(+), 290 deletions(-) delete mode 100644 libc/tools/zoneinfo/ZoneInfo.java diff --git a/libc/tools/zoneinfo/ZoneCompactor.java b/libc/tools/zoneinfo/ZoneCompactor.java index b6577486c..814ef5b98 100644 --- a/libc/tools/zoneinfo/ZoneCompactor.java +++ b/libc/tools/zoneinfo/ZoneCompactor.java @@ -1,6 +1,9 @@ import java.io.*; +import java.nio.ByteOrder; import java.util.*; +import libcore.io.BufferIterator; +import libcore.util.ZoneInfo; // usage: java ZoneCompiler // @@ -30,27 +33,66 @@ import java.util.*; // public class ZoneCompactor { + public static class ByteArrayBufferIteratorBE extends BufferIterator { + private final byte[] bytes; + private int offset = 0; - // Zone name synonyms - Map links = new HashMap(); + public ByteArrayBufferIteratorBE(byte[] bytes) { + this.bytes = bytes; + this.offset = 0; + } - // File starting bytes by zone name - Map starts = new HashMap(); + public void seek(int offset) { + this.offset = offset; + } - // File lengths by zone name - Map lengths = new HashMap(); + public void skip(int byteCount) { + this.offset += byteCount; + } - // Raw GMT offsets by zone name - Map offsets = new HashMap(); - int start = 0; + public void readByteArray(byte[] dst, int dstOffset, int byteCount) { + System.arraycopy(bytes, offset, dst, dstOffset, byteCount); + offset += byteCount; + } + + public byte readByte() { + return bytes[offset++]; + } + + public int readInt() { + return ((readByte() & 0xff) << 24) | ((readByte() & 0xff) << 16) | ((readByte() & 0xff) << 8) | (readByte() & 0xff); + } + + public void readIntArray(int[] dst, int dstOffset, int intCount) { + for (int i = 0; i < intCount; ++i) { + dst[dstOffset++] = readInt(); + } + } + + public short readShort() { + throw new UnsupportedOperationException(); + } + } // Maximum number of characters in a zone name, including '\0' terminator private static final int MAXNAME = 40; + // Zone name synonyms + private Map links = new HashMap(); + + // File starting bytes by zone name + private Map starts = new HashMap(); + + // File lengths by zone name + private Map lengths = new HashMap(); + + // Raw GMT offsets by zone name + private Map offsets = new HashMap(); + private int start = 0; + // Concatenate the contents of 'inFile' onto 'out' // and return the contents as a byte array. - private static byte[] copyFile(File inFile, OutputStream out) - throws Exception { + private static byte[] copyFile(File inFile, OutputStream out) throws Exception { byte[] ret = new byte[0]; InputStream in = new FileInputStream(inFile); @@ -70,7 +112,7 @@ public class ZoneCompactor { out.flush(); return ret; } - + // Write a 32-bit integer in network byte order private void writeInt(OutputStream os, int x) throws IOException { os.write((x >> 24) & 0xff); @@ -79,14 +121,13 @@ public class ZoneCompactor { os.write( x & 0xff); } - public ZoneCompactor(String setupFilename, String dirName) - throws Exception { + public ZoneCompactor(String setupFilename, String dirName) throws Exception { File zoneInfoFile = new File("zoneinfo.dat"); zoneInfoFile.delete(); OutputStream zoneInfo = new FileOutputStream(zoneInfoFile); BufferedReader rdr = new BufferedReader(new FileReader(setupFilename)); - + String s; while ((s = rdr.readLine()) != null) { s = s.trim(); @@ -107,7 +148,8 @@ public class ZoneCompactor { start += length; byte[] data = copyFile(f, zoneInfo); - TimeZone tz = ZoneInfo.make(s, data); + BufferIterator it = new ByteArrayBufferIteratorBE(data); + TimeZone tz = ZoneInfo.makeTimeZone(s, it); int gmtOffset = tz.getRawOffset(); offsets.put(s, new Integer(gmtOffset)); } @@ -162,5 +204,4 @@ public class ZoneCompactor { } new ZoneCompactor(args[0], args[1]); } - } diff --git a/libc/tools/zoneinfo/ZoneInfo.java b/libc/tools/zoneinfo/ZoneInfo.java deleted file mode 100644 index 99507ae1a..000000000 --- a/libc/tools/zoneinfo/ZoneInfo.java +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright (C) 2007 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. - */ - -import java.io.IOException; -import java.util.Arrays; -import java.util.Date; -import java.util.TimeZone; - -/** - * Copied from ZoneInfo and ZoneInfoDB in dalvik. - * {@hide} - */ -public class ZoneInfo extends TimeZone { - - private static final long MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000; - private static final long MILLISECONDS_PER_400_YEARS = - MILLISECONDS_PER_DAY * (400 * 365 + 100 - 3); - - private static final long UNIX_OFFSET = 62167219200000L; - - private static final int[] NORMAL = new int[] { - 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, - }; - - private static final int[] LEAP = new int[] { - 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, - }; - - private static String nullName(byte[] data, int where, int off) { - if (off < 0) - return null; - - int end = where + off; - while (end < data.length && data[end] != '\0') - end++; - - return new String(data, where + off, end - (where + off)); - } - - public static ZoneInfo make(String name, byte[] data) { - int ntransition = read4(data, 32); - int ngmtoff = read4(data, 36); - int base = 44; - - int[] transitions = new int[ntransition]; - for (int i = 0; i < ntransition; i++) - transitions[i] = read4(data, base + 4 * i); - base += 4 * ntransition; - - byte[] type = new byte[ntransition]; - for (int i = 0; i < ntransition; i++) - type[i] = data[base + i]; - base += ntransition; - - int[] gmtoff = new int[ngmtoff]; - byte[] isdst = new byte[ngmtoff]; - byte[] abbrev = new byte[ngmtoff]; - for (int i = 0; i < ngmtoff; i++) { - gmtoff[i] = read4(data, base + 6 * i); - isdst[i] = data[base + 6 * i + 4]; - abbrev[i] = data[base + 6 * i + 5]; - } - - base += 6 * ngmtoff; - - return new ZoneInfo(name, transitions, type, gmtoff, isdst, abbrev, data, base); - } - - private static int read4(byte[] data, int off) { - return ((data[off ] & 0xFF) << 24) | - ((data[off + 1] & 0xFF) << 16) | - ((data[off + 2] & 0xFF) << 8) | - ((data[off + 3] & 0xFF) << 0); - } - - /*package*/ ZoneInfo(String name, int[] transitions, byte[] type, - int[] gmtoff, byte[] isdst, byte[] abbrev, - byte[] data, int abbrevoff) { - mTransitions = transitions; - mTypes = type; - mGmtOffs = gmtoff; - mIsDsts = isdst; - mUseDst = false; - setID(name); - - // Find the latest GMT and non-GMT offsets for their abbreviations - - int lastdst; - for (lastdst = mTransitions.length - 1; lastdst >= 0; lastdst--) { - if (mIsDsts[mTypes[lastdst] & 0xFF] != 0) - break; - } - - int laststd; - for (laststd = mTransitions.length - 1; laststd >= 0; laststd--) { - if (mIsDsts[mTypes[laststd] & 0xFF] == 0) - break; - } - - if (lastdst >= 0) { - mDaylightName = nullName(data, abbrevoff, - abbrev[mTypes[lastdst] & 0xFF]); - } - if (laststd >= 0) { - mStandardName = nullName(data, abbrevoff, - abbrev[mTypes[laststd] & 0xFF]); - } - - // Use the latest non-DST offset if any as the raw offset - - if (laststd < 0) { - laststd = 0; - } - - if (laststd >= mTypes.length) { - mRawOffset = mGmtOffs[0]; - } else { - mRawOffset = mGmtOffs[mTypes[laststd] & 0xFF]; - } - - // Subtract the raw offset from all offsets so it can be changed - // and affect them too. - // Find whether there exist any observances of DST. - - for (int i = 0; i < mGmtOffs.length; i++) { - mGmtOffs[i] -= mRawOffset; - - if (mIsDsts[i] != 0) { - mUseDst = true; - } - } - - mRawOffset *= 1000; - } - - @Override - public int getOffset(@SuppressWarnings("unused") int era, - int year, int month, int day, - @SuppressWarnings("unused") int dayOfWeek, - int millis) { - // XXX This assumes Gregorian always; Calendar switches from - // Julian to Gregorian in 1582. What calendar system are the - // arguments supposed to come from? - - long calc = (year / 400) * MILLISECONDS_PER_400_YEARS; - year %= 400; - - calc += year * (365 * MILLISECONDS_PER_DAY); - calc += ((year + 3) / 4) * MILLISECONDS_PER_DAY; - - if (year > 0) - calc -= ((year - 1) / 100) * MILLISECONDS_PER_DAY; - - boolean isLeap = (year == 0 || (year % 4 == 0 && year % 100 != 0)); - int[] mlen = isLeap ? LEAP : NORMAL; - - calc += mlen[month] * MILLISECONDS_PER_DAY; - calc += (day - 1) * MILLISECONDS_PER_DAY; - calc += millis; - - calc -= mRawOffset; - calc -= UNIX_OFFSET; - - return getOffset(calc); - } - - @Override - public int getOffset(long when) { - int unix = (int) (when / 1000); - int trans = Arrays.binarySearch(mTransitions, unix); - - if (trans == ~0) { - return mGmtOffs[0] * 1000 + mRawOffset; - } - if (trans < 0) { - trans = ~trans - 1; - } - - return mGmtOffs[mTypes[trans] & 0xFF] * 1000 + mRawOffset; - } - - @Override - public int getRawOffset() { - return mRawOffset; - } - - @Override - public void setRawOffset(int off) { - mRawOffset = off; - } - - @Override - public boolean inDaylightTime(Date when) { - int unix = (int) (when.getTime() / 1000); - int trans = Arrays.binarySearch(mTransitions, unix); - - if (trans == ~0) { - return mIsDsts[0] != 0; - } - if (trans < 0) { - trans = ~trans - 1; - } - - return mIsDsts[mTypes[trans] & 0xFF] != 0; - } - - @Override - public boolean useDaylightTime() { - return mUseDst; - } - - private int mRawOffset; - private int[] mTransitions; - private int[] mGmtOffs; - private byte[] mTypes; - private byte[] mIsDsts; - private boolean mUseDst; - private String mDaylightName; - private String mStandardName; - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof ZoneInfo)) { - return false; - } - ZoneInfo other = (ZoneInfo) obj; - return mUseDst == other.mUseDst - && (mDaylightName == null ? other.mDaylightName == null : - mDaylightName.equals(other.mDaylightName)) - && (mStandardName == null ? other.mStandardName == null : - mStandardName.equals(other.mStandardName)) - && mRawOffset == other.mRawOffset - // Arrays.equals returns true if both arrays are null - && Arrays.equals(mGmtOffs, other.mGmtOffs) - && Arrays.equals(mIsDsts, other.mIsDsts) - && Arrays.equals(mTypes, other.mTypes) - && Arrays.equals(mTransitions, other.mTransitions); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((mDaylightName == null) ? 0 : - mDaylightName.hashCode()); - result = prime * result + Arrays.hashCode(mGmtOffs); - result = prime * result + Arrays.hashCode(mIsDsts); - result = prime * result + mRawOffset; - result = prime * result + ((mStandardName == null) ? 0 : - mStandardName.hashCode()); - result = prime * result + Arrays.hashCode(mTransitions); - result = prime * result + Arrays.hashCode(mTypes); - result = prime * result + (mUseDst ? 1231 : 1237); - return result; - } -} diff --git a/libc/tools/zoneinfo/generate b/libc/tools/zoneinfo/generate index ab2617ff9..fd4e6d09b 100755 --- a/libc/tools/zoneinfo/generate +++ b/libc/tools/zoneinfo/generate @@ -89,9 +89,11 @@ def upgrade_to(ftp, filename): setup.close() print 'Calling ZoneCompactor...' + libcore_src_dir = '%s/../libcore/luni/src/main/java/' % bionic_dir subprocess.check_call(['javac', '-d', '.', '%s/ZoneCompactor.java' % bionic_libc_tools_zoneinfo_dir, - '%s/ZoneInfo.java' % bionic_libc_tools_zoneinfo_dir]) + '%s/libcore/util/ZoneInfo.java' % libcore_src_dir, + '%s/libcore/io/BufferIterator.java' % libcore_src_dir]) subprocess.check_call(['java', 'ZoneCompactor', 'setup', 'data']) print 'Updating bionic from %s to %s...' % (current_tzdata_version(), version)