Merge change Icb96cddc into eclair

* changes:
  Cleanup installed binaries before the NDK build begins.
diff --git a/tools/zoneinfo/ZoneCompactor.java b/tools/zoneinfo/ZoneCompactor.java
index eea7dd4..3b5ddfa 100644
--- a/tools/zoneinfo/ZoneCompactor.java
+++ b/tools/zoneinfo/ZoneCompactor.java
@@ -48,8 +48,11 @@
     private static final int MAXNAME = 40;
 
     // Concatenate the contents of 'inFile' onto 'out'
-    private static void copyFile(File inFile, OutputStream out)
+    // and return the contents as a byte array.
+    private static byte[] copyFile(File inFile, OutputStream out)
         throws Exception {
+        byte[] ret = new byte[0];
+
         InputStream in = new FileInputStream(inFile);
         byte[] buf = new byte[8192];
         while (true) {
@@ -58,9 +61,14 @@
                 break;
             }
             out.write(buf, 0, nbytes);
+
+            byte[] nret = new byte[ret.length + nbytes];
+            System.arraycopy(ret, 0, nret, 0, ret.length);
+            System.arraycopy(buf, 0, nret, ret.length, nbytes);
+            ret = nret;
         }
         out.flush();
-        return;
+        return ret;
     }
     
     // Write a 32-bit integer in network byte order
@@ -96,12 +104,12 @@
                     starts.put(s, new Integer(start));
                     lengths.put(s, new Integer((int)length));
 
-                    TimeZone tz = TimeZone.getTimeZone(s);
+                    start += length;
+                    byte[] data = copyFile(f, zoneInfo);
+
+                    TimeZone tz = ZoneInfo.make(s, data);
                     int gmtOffset = tz.getRawOffset();
                     offsets.put(s, new Integer(gmtOffset));
-
-                    start += length;
-                    copyFile(f, zoneInfo);
                 }
             }
         }
diff --git a/tools/zoneinfo/ZoneInfo.java b/tools/zoneinfo/ZoneInfo.java
new file mode 100644
index 0000000..99507ae
--- /dev/null
+++ b/tools/zoneinfo/ZoneInfo.java
@@ -0,0 +1,272 @@
+/*
+ * 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/tools/zoneinfo/generate b/tools/zoneinfo/generate
index dbb7610..7cd8a26 100755
--- a/tools/zoneinfo/generate
+++ b/tools/zoneinfo/generate
@@ -20,7 +20,7 @@
     zic -d data $i
 done
 
-javac -target 1.5 ZoneCompactor.java
+javac -target 1.5 ZoneCompactor.java ZoneInfo.java
 
 (
     cat $version/* | grep '^Link' | awk '{print $1, $2, $3}'