00001 /* 00002 ********************************************************************** 00003 * Copyright (C) 1999, International Business Machines 00004 * Corporation and others. All Rights Reserved. 00005 ********************************************************************** 00006 * Date Name Description 00007 * 11/24/99 aliu Creation. 00008 * 12/13/1999 srl Padded OffsetIndex to 4 byte values 00009 ********************************************************************** 00010 */ 00011 00012 #ifndef TZDAT_H 00013 #define TZDAT_H 00014 00015 #include "unicode/utypes.h" 00016 00017 /* This file defines the format of the memory-mapped data file 00018 * containing system time zone data for icu. See also gentz 00019 * and tz.pl. 00020 * 00021 * The format is designed specifically to allow certain operations: 00022 * 00023 * 1. Performing a fast binary search by name, and locating the 00024 * corresponding zone data. This is the most important operation. 00025 * It corresponds to the TimeZone::createTimeZone() method. 00026 * 00027 * 2. Performing a fast iteration over zones having a specific GMT 00028 * offset. For this operation, the zone data need not be 00029 * retrieved, just the IDs. This corresponds to the 00030 * TimeZone::createAvailableIDs(int32_t) method. 00031 * 00032 * 3. Iterating over all zone IDs. This corresponds to the 00033 * TimeZone::createAvailableIDs() method. 00034 * 00035 * The createAvailableIDs() methods return arrays of pointers to 00036 * existing static UnicodeString IDs that it owns. Thus 00037 * createAvailableIDs() needs a way to reference one of these IDs when 00038 * iterating. Note that these IDs are _not_ stored in the 00039 * memory-mapped data file, so we cannot store offsets. To solve this 00040 * problem, we define a canonical index number for each zone. This 00041 * index number runs from 0..n-1, where n is the total number of 00042 * zones. The name table is stored in index number order, and we 00043 * provide a table that is sorted by GMT offset with keys being GMT 00044 * offset values and values being canonical index numbers. 00045 * 00046 * (Later, we might change createAvailableIDs() to return char* 00047 * strings rather than UnicodeString pointers. In that case, this 00048 * data structure could be modified to index into the name table 00049 * directly.) 00050 * 00051 * In the following table, sizes are estimated sizes for a zone list 00052 * of about 200 standard and 200 DST zones, which is typical in 1999. 00053 * 00054 * [THIS IS OBSOLETE - Needs updating for format 3] 00055 * 0K TZHeader 00056 * 2K Standard zone table (StandardZone[]) 00057 * 4K DST zone table (Zone[]) 00058 * 2K Index table, sorted by name, 4 bytes / zone 00059 * This is a list of 'count' deltas sorted in ascending 00060 * lexicographic order of name string. 00061 * 1K Index table, sorted by gmtOffset then name. See 00062 * OffsetIndex struct. 00063 * 6K Name table - always last 00064 * This is all the zone names, in lexicographic order, 00065 * with zero bytes terminating each name. 00066 * 14K TOTAL 00067 * 00068 * Any field with a name ending in "delta" is an offset value 00069 * from the first byte of the TZHeader structure, unless otherwise 00070 * specified. 00071 * 00072 * When using the name index table and the offset index table, 00073 * code can determine whether an indexed zone is a standard 00074 * zone or a DST zone by examining its delta. If the delta is 00075 * less than dstDelta, it is a standard zone. Otherwise it 00076 * is a DST zone. 00077 */ 00078 00079 // Information used to identify and validate the data 00080 00081 #define TZ_DATA_NAME "tz" 00082 #define TZ_DATA_TYPE "dat" 00083 00084 // Fields in UDataInfo: 00085 00086 // TZ_SIG[] is encoded as numeric literals for compatibility with the HP compiler 00087 static const uint8_t TZ_SIG_0 = 0x7a; // z 00088 static const uint8_t TZ_SIG_1 = 0x6f; // o 00089 static const uint8_t TZ_SIG_2 = 0x6e; // n 00090 static const uint8_t TZ_SIG_3 = 0x65; // e 00091 00092 // This must match the version number at the top of tz.txt as 00093 // well as the version number in the udata header. 00094 static const int8_t TZ_FORMAT_VERSION = 3; // formatVersion[0] 00095 00096 struct TZHeader { 00097 uint16_t versionYear; // e.g. "1999j" -> 1999 00098 uint16_t versionSuffix; // e.g. "1999j" -> 10 00099 00100 uint32_t count; // standardCount + dstCount 00101 00102 uint32_t equivTableDelta; // delta to equivalency group table 00103 uint32_t offsetIndexDelta; // delta to gmtOffset index table 00104 00105 uint32_t nameIndexDelta; // delta to name index table 00106 // The name index table is an array of 'count' 32-bit offsets from 00107 // the start of this header to equivalency group table entries. 00108 00109 uint32_t nameTableDelta; // delta to name (aka ID) table 00110 // The name table contains all zone IDs, in sort order, each name 00111 // terminated by a zero byte. 00112 }; 00113 00114 struct StandardZone { 00115 int32_t gmtOffset; // gmt offset in milliseconds 00116 }; 00117 00118 struct TZRule { 00119 uint8_t month; // month 00120 int8_t dowim; // dowim 00121 int8_t dow; // dow 00122 uint16_t time; // time in minutes 00123 int8_t mode; // (w/s/u) == TimeZone::TimeMode enum as int 00124 }; 00125 00126 struct DSTZone { 00127 int32_t gmtOffset; // gmtoffset in milliseconds 00128 uint16_t dstSavings; // savings in minutes 00129 TZRule onsetRule; // onset rule 00130 TZRule ceaseRule; // cease rule 00131 }; 00132 00143 struct TZEquivalencyGroup { 00144 uint16_t nextEntryDelta; // 0 for last entry 00145 uint8_t isDST; // != 0 for DSTZone 00146 uint8_t reserved; 00147 union { 00148 struct { 00149 StandardZone zone; 00150 uint16_t count; 00151 uint16_t index; // There are actually 'count' uint16_t's here 00152 } s; 00153 struct { 00154 DSTZone zone; 00155 uint16_t count; 00156 uint16_t index; // There are actually 'count' uint16_t's here 00157 } d; 00158 } u; 00159 // There may be two bytes of padding HERE to make the whole struct 00160 // have size 4n bytes. 00161 }; 00162 00186 struct OffsetIndex { 00187 int32_t gmtOffset; // in ms - 4-aligned 00188 uint16_t nextEntryDelta; 00189 uint16_t defaultZone; // a zone number from 0..TZHeader.count-1 00190 uint16_t count; 00191 uint16_t zoneNumber; // There are actually 'count' uint16_t's here 00192 // Following the 'count' uint16_t's starting with zoneNumber, 00193 // there may be two bytes of padding to make the whole struct have 00194 // a size of 4n. nextEntryDelta skips over any padding. 00195 }; 00196 00197 #endif