Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/sun/util/calendar/zi/Gen.java
38855 views
/*1* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425import java.io.IOException;26import java.io.File;27import java.io.FileOutputStream;28import java.io.DataOutputStream;29import java.io.RandomAccessFile;30import java.util.List;31import java.util.Map;32import java.util.Set;3334/**35* <code>Gen</code> is one of back-end classes of javazic, and generates36* ZoneInfoMappings and zone-specific file for each zone.37*/38class Gen extends BackEnd {3940/**41* Generates datafile in binary TLV format for each time zone.42* Regarding contents of output files, see {@link ZoneInfoFile}.43*44* @param Timezone45* @return 0 if no errors, or 1 if error occurred.46*/47int processZoneinfo(Timezone tz) {48try {49int size;50String outputDir = Main.getOutputDir();51String zonefile = ZoneInfoFile.getFileName(tz.getName());5253/* If outputDir doesn't end with file-separator, adds it. */54if (!outputDir.endsWith(File.separator)) {55outputDir += File.separatorChar;56}5758/* If zonefile includes file-separator, it's treated as part of59* pathname. And make directory if necessary.60*/61int index = zonefile.lastIndexOf(File.separatorChar);62if (index != -1) {63outputDir += zonefile.substring(0, index+1);64}65File outD = new File(outputDir);66outD.mkdirs();6768FileOutputStream fos =69new FileOutputStream(outputDir + zonefile.substring(index+1));70DataOutputStream dos = new DataOutputStream(fos);7172/* Output Label */73dos.write(ZoneInfoFile.JAVAZI_LABEL, 0,74ZoneInfoFile.JAVAZI_LABEL.length);7576/* Output Version of ZoneInfoFile */77dos.writeByte(ZoneInfoFile.JAVAZI_VERSION);7879List<Long> transitions = tz.getTransitions();80if (transitions != null) {81List<Integer> dstOffsets = tz.getDstOffsets();82List<Integer> offsets = tz.getOffsets();8384if ((dstOffsets == null && offsets != null) ||85(dstOffsets != null && offsets == null)) {86Main.panic("Data not exist. (dstOffsets or offsets)");87return 1;88}8990/* Output Transition records */91dos.writeByte(ZoneInfoFile.TAG_Transition);92size = transitions.size();93dos.writeShort((size * 8) & 0xFFFF);94int dstoffset;95for (int i = 0; i < size; i++) {96/* if DST offset is 0, this means DST isn't used.97* (NOT: offset's index is 0.)98*/99if ((dstoffset = dstOffsets.get(i).intValue()) == -1) {100dstoffset = 0;101}102103dos.writeLong((transitions.get(i).longValue() << 12)104| (dstoffset << 4)105| offsets.get(i).intValue());106107}108109/* Output data for GMTOffset */110List<Integer> gmtoffset = tz.getGmtOffsets();111dos.writeByte(ZoneInfoFile.TAG_Offset);112size = gmtoffset.size();113dos.writeShort((size * 4) & 0xFFFF);114for (int i = 0; i < size; i++) {115dos.writeInt(gmtoffset.get(i));116}117}118119/* Output data for SimpleTimeZone */120List<RuleRec> stz = tz.getLastRules();121if (stz != null) {122RuleRec[] rr = new RuleRec[2];123boolean wall = true;124125rr[0] = stz.get(0);126rr[1] = stz.get(1);127128dos.writeByte(ZoneInfoFile.TAG_SimpleTimeZone);129wall = rr[0].getTime().isWall() && rr[1].getTime().isWall();130if (wall) {131dos.writeShort(32);132} else {133dos.writeShort(40);134}135136for (int i = 0; i < 2; i++) {137dos.writeInt(rr[i].getMonthNum() - 1); // 0-based month number138dos.writeInt(rr[i].getDay().getDayForSimpleTimeZone());139dos.writeInt(rr[i].getDay().getDayOfWeekForSimpleTimeZoneInt());140dos.writeInt((int)rr[i].getTime().getTime());141if (!wall) {142dos.writeInt((rr[i].getTime().getType() & 0xFF) - 1);143}144}145}146147/* Output RawOffset */148dos.writeByte(ZoneInfoFile.TAG_RawOffset);149dos.writeShort(4);150dos.writeInt(tz.getRawOffset());151152/* Output willGMTOffsetChange flag */153if (tz.willGMTOffsetChange()) {154dos.writeByte(ZoneInfoFile.TAG_GMTOffsetWillChange);155dos.writeShort(1);156dos.writeByte(1);157}158159/* Output LastDSTSaving */160dos.writeByte(ZoneInfoFile.TAG_LastDSTSaving);161dos.writeShort(2);162dos.writeShort(tz.getLastDSTSaving()/1000);163164/* Output checksum */165dos.writeByte(ZoneInfoFile.TAG_CRC32);166dos.writeShort(4);167dos.writeInt(tz.getCRC32());168169fos.close();170dos.close();171} catch(IOException e) {172Main.panic("IO error: "+e.getMessage());173return 1;174}175176return 0;177}178179/**180* Generates ZoneInfoMappings in binary TLV format for each zone.181* Regarding contents of output files, see {@link ZoneInfoFile}.182*183* @param Mappings184* @return 0 if no errors, or 1 if error occurred.185*/186int generateSrc(Mappings map) {187try {188int index;189int block_size;190int roi_size;191long fp;192String outputDir = Main.getOutputDir();193194/* If outputDir doesn't end with file-separator, adds it. */195if (!outputDir.endsWith(File.separator)) {196outputDir += File.separatorChar;197}198199File outD = new File(outputDir);200outD.mkdirs();201202/* Open ZoneInfoMapping file to write. */203RandomAccessFile raf =204new RandomAccessFile(outputDir + ZoneInfoFile.JAVAZM_FILE_NAME, "rw");205206/* Whether rawOffsetIndex list exists or not. */207List<Integer> roi = map.getRawOffsetsIndex();208if (roi == null) {209Main.panic("Data not exist. (rawOffsetsIndex)");210return 1;211}212roi_size = roi.size();213214/* Whether rawOffsetIndexTable list exists or not. */215List<Set<String>> roit = map.getRawOffsetsIndexTable();216if (roit == null || roit.size() != roi_size) {217Main.panic("Data not exist. (rawOffsetsIndexTable) Otherwise, Invalid size");218return 1;219}220221/* Output Label */222raf.write(ZoneInfoFile.JAVAZM_LABEL, 0,223ZoneInfoFile.JAVAZM_LABEL.length);224225/* Output Version */226raf.writeByte(ZoneInfoFile.JAVAZM_VERSION);227228index = ZoneInfoFile.JAVAZM_LABEL.length + 2;229230/* Output Version of Olson's tzdata */231byte[] b = Main.getVersionName().getBytes("UTF-8");232raf.writeByte(ZoneInfoFile.TAG_TZDataVersion);233raf.writeShort((b.length+1) & 0xFFFF);234raf.write(b);235raf.writeByte(0x00);236index += b.length + 4;237238/* Output ID list. */239raf.writeByte(ZoneInfoFile.TAG_ZoneIDs);240block_size = 2;241raf.writeShort(block_size & 0xFFFF);242short nID = 0;243raf.writeShort(nID & 0xFFFF);244for (int i = 0; i < roi_size; i++) {245for (String key : roit.get(i)) {246byte size = (byte)key.getBytes("UTF-8").length;247raf.writeByte(size & 0xFF);248raf.write(key.getBytes("UTF-8"), 0, size);249block_size += 1 + size;250nID++;251}252}253fp = raf.getFilePointer();254raf.seek(index);255raf.writeShort((block_size) & 0xFFFF);256raf.writeShort(nID & 0xFFFF);257raf.seek(fp);258259/* Output sorted rawOffset list. */260raf.writeByte(ZoneInfoFile.TAG_RawOffsets);261index += 3 + block_size;262block_size = roi_size * 4;263raf.writeShort(block_size & 0xFFFF);264for (int i = 0; i < roi_size; i++) {265raf.writeInt(Integer.parseInt(roi.get(i).toString()));266}267268/* Output sorted rawOffsetIndex list. */269raf.writeByte(ZoneInfoFile.TAG_RawOffsetIndices);270index += 3 + block_size;271block_size = 0;272raf.writeShort(block_size & 0xFFFF);273int num;274for (int i = 0; i < roi_size; i++) {275num = roit.get(i).size();276block_size += num;277for (int j = 0; j < num; j++) {278raf.writeByte(i);279}280}281fp = raf.getFilePointer();282raf.seek(index);283raf.writeShort((block_size) & 0xFFFF);284raf.seek(fp);285286/* Whether alias list exists or not. */287Map<String,String> a = map.getAliases();288if (a == null) {289Main.panic("Data not exist. (aliases)");290return 0;291}292293/* Output ID list. */294raf.writeByte(ZoneInfoFile.TAG_ZoneAliases);295index += 3 + block_size;296block_size = 2;297raf.writeShort(block_size & 0xFFFF);298raf.writeShort(a.size() & 0xFFFF);299for (String key : a.keySet()) {300String alias = a.get(key);301byte key_size = (byte)key.length();302byte alias_size = (byte)alias.length();303raf.writeByte(key_size & 0xFF);304raf.write(key.getBytes("UTF-8"), 0, key_size);305raf.writeByte(alias_size & 0xFF);306raf.write(alias.getBytes("UTF-8"), 0, alias_size);307block_size += 2 + key_size + alias_size;308}309fp = raf.getFilePointer();310raf.seek(index);311raf.writeShort((block_size) & 0xFFFF);312raf.seek(fp);313314/* Output the exclude list if it exists. */315List<String> excludedZones = map.getExcludeList();316if (excludedZones != null) {317raf.writeByte(ZoneInfoFile.TAG_ExcludedZones);318index += 3 + block_size;319block_size = 2;320raf.writeShort(block_size & 0xFFFF); // place holder321raf.writeShort(excludedZones.size()); // the number of excluded zones322for (String name : excludedZones) {323byte size = (byte) name.length();324raf.writeByte(size); // byte length325raf.write(name.getBytes("UTF-8"), 0, size); // zone name326block_size += 1 + size;327}328fp = raf.getFilePointer();329raf.seek(index);330raf.writeShort(block_size & 0xFFFF);331raf.seek(fp);332}333334/* Close ZoneInfoMapping file. */335raf.close();336} catch(IOException e) {337Main.panic("IO error: "+e.getMessage());338return 1;339}340341return 0;342}343}344345346