1071 lines · 34.9 KB · Java
RawDownload
    }     /**     * Gets a ZoneInfo with the given GMT offset. The object     * has its ID in the format of GMT{+|-}hh:mm.     *     * @param originalId the given custom id (before normalized such as "GMT+9")     * @param gmtOffset GMT offset <em>in milliseconds</em>     * @return a ZoneInfo constructed with the given GMT offset     */    public static ZoneInfo getCustomTimeZone(String originalId, int gmtOffset) {        String id = toCustomID(gmtOffset);         ZoneInfo zi = getFromCache(id);        if (zi == null) {            zi = new ZoneInfo(id, gmtOffset);            zi = addToCache(id, zi);            if (!id.equals(originalId)) {                zi = addToCache(originalId, zi);            }        }        return (ZoneInfo) zi.clone();    }     public static String toCustomID(int gmtOffset) {        char sign;        int offset = gmtOffset / 60000;         if (offset >= 0) {            sign = '+';        } else {            sign = '-';            offset = -offset;        }        int hh = offset / 60;        int mm = offset % 60;         char[] buf = new char[] { 'G', 'M', 'T', sign, '0', '0', ':', '0', '0' };        if (hh >= 10) {            buf[4] += hh / 10;        }        buf[5] += hh % 10;        if (mm != 0) {            buf[7] += mm / 10;            buf[8] += mm % 10;        }        return new String(buf);    }     /**     * @return a ZoneInfo instance created for the specified id, or     * null if there is no time zone data file found for the specified     * id.     */    public static ZoneInfo getZoneInfo(String id) {        ZoneInfo zi = getFromCache(id);        if (zi == null) {            zi = createZoneInfo(id);            if (zi == null) {                return null;            }            zi = addToCache(id, zi);        }        return (ZoneInfo) zi.clone();    }     synchronized static ZoneInfo getFromCache(String id) {        if (zoneInfoObjects == null) {            return null;        }        return zoneInfoObjects.get(id);    }     synchronized static ZoneInfo addToCache(String id, ZoneInfo zi) {        if (zoneInfoObjects == null) {            zoneInfoObjects = new HashMap<String, ZoneInfo>();        } else {            ZoneInfo zone = zoneInfoObjects.get(id);            if (zone != null) {                return zone;            }        }        zoneInfoObjects.put(id, zi);        return zi;    }     private static ZoneInfo createZoneInfo(String id) {        byte[] buf = readZoneInfoFile(getFileName(id));        if (buf == null) {            return null;        }         int index = 0;        int filesize = buf.length;        int rawOffset = 0;        int dstSavings = 0;        int checksum = 0;        boolean willGMTOffsetChange = false;        long[] transitions = null;        int[] offsets = null;        int[] simpleTimeZoneParams = null;         try {            for (index = 0; index < JAVAZI_LABEL.length; index++) {                if (buf[index] != JAVAZI_LABEL[index]) {                    System.err.println("ZoneInfo: wrong magic number: " + id);                    return null;                }            }            if (buf[index++] > JAVAZI_VERSION) {                System.err.println("ZoneInfo: incompatible version ("                                   + buf[index - 1] + "): " + id);                return null;            }             while (index < filesize) {                byte tag = buf[index++];                int  len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF);                 if (filesize < index+len) {                    break;                }                 switch (tag) {                case TAG_CRC32:                    {                        int val = buf[index++] & 0xff;                        val = (val << 8) + (buf[index++] & 0xff);                        val = (val << 8) + (buf[index++] & 0xff);                        val = (val << 8) + (buf[index++] & 0xff);                        checksum = val;                    }                    break;                 case TAG_LastDSTSaving:                    {                        short val = (short)(buf[index++] & 0xff);                        val = (short)((val << 8) + (buf[index++] & 0xff));                        dstSavings = val * 1000;                    }                    break;                 case TAG_RawOffset:                    {                        int val = buf[index++] & 0xff;                        val = (val << 8) + (buf[index++] & 0xff);                        val = (val << 8) + (buf[index++] & 0xff);                        val = (val << 8) + (buf[index++] & 0xff);                        rawOffset = val;                    }                    break;                 case TAG_Transition:                    {                        int n = len / 8;                        transitions = new long[n];                        for (int i = 0; i < n; i ++) {                            long val = buf[index++] & 0xff;                            val = (val << 8) + (buf[index++] & 0xff);                            val = (val << 8) + (buf[index++] & 0xff);                            val = (val << 8) + (buf[index++] & 0xff);                            val = (val << 8) + (buf[index++] & 0xff);                            val = (val << 8) + (buf[index++] & 0xff);                            val = (val << 8) + (buf[index++] & 0xff);                            val = (val << 8) + (buf[index++] & 0xff);                            transitions[i] = val;                        }                    }                    break;                 case TAG_Offset:                    {                        int n = len / 4;                        offsets = new int[n];                        for (int i = 0; i < n; i ++) {                            int val = buf[index++] & 0xff;                            val = (val << 8) + (buf[index++] & 0xff);                            val = (val << 8) + (buf[index++] & 0xff);                            val = (val << 8) + (buf[index++] & 0xff);                            offsets[i] = val;                        }                    }                    break;                 case TAG_SimpleTimeZone:                    {                        if (len != 32 && len != 40) {                            System.err.println("ZoneInfo: wrong SimpleTimeZone parameter size");                            return null;                        }                        int n = len / 4;                        simpleTimeZoneParams = new int[n];                        for (int i = 0; i < n; i++) {                            int val = buf[index++] & 0xff;                            val = (val << 8) + (buf[index++] & 0xff);                            val = (val << 8) + (buf[index++] & 0xff);                            val = (val << 8) + (buf[index++] & 0xff);                            simpleTimeZoneParams[i] = val;                        }                    }                    break;                 case TAG_GMTOffsetWillChange:                    {                        if (len != 1) {                            System.err.println("ZoneInfo: wrong byte length for TAG_GMTOffsetWillChange");                        }                        willGMTOffsetChange = buf[index++] == 1;                    }                    break;                 default:                    System.err.println("ZoneInfo: unknown tag < " + tag + ">. ignored.");                    index += len;                    break;                }            }        } catch (Exception e) {            System.err.println("ZoneInfo: corrupted zoneinfo file: " + id);            return null;        }         if (index != filesize) {            System.err.println("ZoneInfo: wrong file size: " + id);            return null;        }         return new ZoneInfo(id, rawOffset, dstSavings, checksum,                            transitions, offsets, simpleTimeZoneParams,                            willGMTOffsetChange);    }     private volatile static SoftReference<List<String>> zoneIDs = null;     static List<String> getZoneIDs() {        List<String> ids = null;         SoftReference<List<String>> cache = zoneIDs;        if (cache != null) {            ids = cache.get();            if (ids != null) {                return ids;            }        }         byte[] buf = null;        buf = getZoneInfoMappings();        int index = JAVAZM_LABEL_LENGTH + 1;        int filesize = buf.length;         try {        loop:            while (index < filesize) {                byte tag = buf[index++];                int     len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF);                 switch (tag) {                case TAG_ZoneIDs:                    {                        int n = (buf[index++] << 8) + (buf[index++] & 0xFF);                        ids = new ArrayList<String>(n);                         for (int i = 0; i < n; i++) {                            byte m = buf[index++];                            ids.add(new String(buf, index, m, "UTF-8"));                            index += m;                        }                    }                    break loop;                 default:                    index += len;                    break;                }            }        } catch (Exception e) {            System.err.println("ZoneInfo: corrupted " + JAVAZM_FILE_NAME);        }         zoneIDs = new SoftReference<List<String>>(ids);        return ids;    }     /**     * @return an alias table in HashMap where a key is an alias ID     * (e.g., "PST") and its value is a real time zone ID (e.g.,     * "America/Los_Angeles").     */    static Map<String, String> getZoneAliases() {        byte[] buf = getZoneInfoMappings();        int index = JAVAZM_LABEL_LENGTH + 1;        int filesize = buf.length;        Map<String, String> aliases = null;         try {        loop:            while (index < filesize) {                byte tag = buf[index++];                int     len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF);                 switch (tag) {                case TAG_ZoneAliases:                    {                        int n = (buf[index++] << 8) + (buf[index++] & 0xFF);                        aliases = new HashMap<String, String>(n);                        for (int i = 0; i < n; i++) {                            byte m = buf[index++];                            String name = new String(buf, index, m, "UTF-8");                            index += m;                            m = buf[index++];                            String realName = new String(buf, index, m, "UTF-8");                            index += m;                            aliases.put(name, realName);                        }                    }                    break loop;                 default:                    index += len;                    break;                }            }        } catch (Exception e) {            System.err.println("ZoneInfo: corrupted " + JAVAZM_FILE_NAME);            return null;        }        return aliases;    }     private volatile static SoftReference<List<String>> excludedIDs = null;    private volatile static boolean hasNoExcludeList = false;     /**     * @return a List of zone IDs for zones that will change their GMT     * offsets in some future time.     *     * @since 1.6     */    static List<String> getExcludedZones() {        if (hasNoExcludeList) {            return null;        }         List<String> excludeList = null;         SoftReference<List<String>> cache = excludedIDs;        if (cache != null) {            excludeList = cache.get();            if (excludeList != null) {                return excludeList;            }        }         byte[] buf = getZoneInfoMappings();        int index = JAVAZM_LABEL_LENGTH + 1;        int filesize = buf.length;         try {          loop:            while (index < filesize) {                byte tag = buf[index++];                int     len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF);                 switch (tag) {                case TAG_ExcludedZones:                    {                        int n = (buf[index++] << 8) + (buf[index++] & 0xFF);                        excludeList = new ArrayList<String>();                        for (int i = 0; i < n; i++) {                            byte m = buf[index++];                            String name = new String(buf, index, m, "UTF-8");                            index += m;                            excludeList.add(name);                        }                    }                    break loop;                 default:                    index += len;                    break;                }            }        } catch (Exception e) {            System.err.println("ZoneInfo: corrupted " + JAVAZM_FILE_NAME);            return null;        }         if (excludeList != null) {            excludedIDs = new SoftReference<List<String>>(excludeList);        } else {            hasNoExcludeList = true;        }        return excludeList;    }     private volatile static SoftReference<byte[]> rawOffsetIndices = null;     static byte[] getRawOffsetIndices() {        byte[] indices = null;         SoftReference<byte[]> cache = rawOffsetIndices;        if (cache != null) {            indices = cache.get();            if (indices != null) {                return indices;            }        }         byte[] buf = getZoneInfoMappings();        int index = JAVAZM_LABEL_LENGTH + 1;        int filesize = buf.length;         try {        loop:            while (index < filesize) {                byte tag = buf[index++];                int     len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF);                 switch (tag) {                case TAG_RawOffsetIndices:                    {                        indices = new byte[len];                        for (int i = 0; i < len; i++) {                            indices[i] = buf[index++];                        }                    }                    break loop;                 default:                    index += len;                    break;                }            }        } catch (ArrayIndexOutOfBoundsException e) {            System.err.println("ZoneInfo: corrupted " + JAVAZM_FILE_NAME);        }         rawOffsetIndices = new SoftReference<byte[]>(indices);        return indices;    }     private volatile static SoftReference<int[]> rawOffsets = null;     static int[] getRawOffsets() {        int[] offsets = null;         SoftReference<int[]> cache = rawOffsets;        if (cache != null) {            offsets = cache.get();            if (offsets != null) {                return offsets;            }        }         byte[] buf = getZoneInfoMappings();        int index = JAVAZM_LABEL_LENGTH + 1;        int filesize = buf.length;         try {        loop:            while (index < filesize) {                byte tag = buf[index++];                int     len = ((buf[index++] & 0xFF) << 8) + (buf[index++] & 0xFF);                 switch (tag) {                case TAG_RawOffsets:                    {                        int n = len/4;                        offsets = new int[n];                        for (int i = 0; i < n; i++) {                            int val = buf[index++] & 0xff;                            val = (val << 8) + (buf[index++] & 0xff);                            val = (val << 8) + (buf[index++] & 0xff);                            val = (val << 8) + (buf[index++] & 0xff);                            offsets[i] = val;                        }                    }                    break loop;                 default:                    index += len;                    break;                }            }        } catch (ArrayIndexOutOfBoundsException e) {            System.err.println("ZoneInfo: corrupted " + JAVAZM_FILE_NAME);        }         rawOffsets = new SoftReference<int[]>(offsets);        return offsets;    }     private volatile static SoftReference<byte[]> zoneInfoMappings = null;     private static byte[] getZoneInfoMappings() {        byte[] data;         SoftReference<byte[]> cache = zoneInfoMappings;        if (cache != null) {            data = cache.get();

Lines 501–1000 of 1071. Previous lines