~ubuntu-branches/ubuntu/gutsy/icu/gutsy-updates

« back to all changes in this revision

Viewing changes to source/i18n/tzdat.h

  • Committer: Package Import Robot
  • Author(s): Jay Berkenbilt
  • Date: 2005-11-19 11:29:31 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20051119112931-vcizkrp10tli4enw
Tags: 3.4-3
Explicitly build with g++ 3.4.  The current ICU fails its test suite
with 4.0 but not with 3.4.  Future versions should work properly with
4.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
**********************************************************************
3
 
*   Copyright (C) 1999-2001, International Business Machines
4
 
*   Corporation and others.  All Rights Reserved.
5
 
**********************************************************************
6
 
*   Date        Name        Description
7
 
*   11/24/99    aliu        Creation.
8
 
*   12/13/1999  srl         Padded OffsetIndex to 4 byte values
9
 
*   02/01/01    aliu        Added country index
10
 
**********************************************************************
11
 
*/
12
 
 
13
 
#ifndef TZDAT_H
14
 
#define TZDAT_H
15
 
 
16
 
#include "unicode/utypes.h"
17
 
 
18
 
/* This file defines the format of the memory-mapped data file
19
 
 * containing system time zone data for icu.  See also gentz
20
 
 * and tz.pl.
21
 
 *
22
 
 * The format is designed specifically to allow certain operations:
23
 
 *
24
 
 * 1. Performing a fast binary search by name, and locating the
25
 
 *    corresponding zone data.  This is the most important operation.
26
 
 *    It corresponds to the TimeZone::createTimeZone() method.
27
 
 *
28
 
 * 2. Performing a fast iteration over zones having a specific GMT
29
 
 *    offset.  For this operation, the zone data need not be
30
 
 *    retrieved, just the IDs.  This corresponds to the
31
 
 *    TimeZone::createAvailableIDs(int32_t) method.
32
 
 *
33
 
 * 3. Iterating over all zone IDs.  This corresponds to the
34
 
 *    TimeZone::createAvailableIDs() method.
35
 
 *
36
 
 * The createAvailableIDs() methods return arrays of pointers to
37
 
 * existing static UnicodeString IDs that it owns.  Thus
38
 
 * createAvailableIDs() needs a way to reference one of these IDs when
39
 
 * iterating.  Note that these IDs are _not_ stored in the
40
 
 * memory-mapped data file, so we cannot store offsets.  To solve this
41
 
 * problem, we define a canonical index number for each zone.  This
42
 
 * index number runs from 0..n-1, where n is the total number of
43
 
 * zones.  The name table is stored in index number order, and we
44
 
 * provide a table that is sorted by GMT offset with keys being GMT
45
 
 * offset values and values being canonical index numbers.
46
 
 *
47
 
 * (Later, we might change createAvailableIDs() to return char*
48
 
 * strings rather than UnicodeString pointers.  In that case, this
49
 
 * data structure could be modified to index into the name table
50
 
 * directly.)
51
 
 *
52
 
 * Any field with a name ending in "delta" is an offset value
53
 
 * from the first byte of the TZHeader structure, unless otherwise
54
 
 * specified.
55
 
 *
56
 
 * When using the name index table and the offset index table,
57
 
 * code can determine whether an indexed zone is a standard
58
 
 * zone or a DST zone by examining its delta.  If the delta is
59
 
 * less than dstDelta, it is a standard zone.  Otherwise it 
60
 
 * is a DST zone.
61
 
 */
62
 
 
63
 
// Information used to identify and validate the data
64
 
 
65
 
#define TZ_DATA_NAME "tz"
66
 
#define TZ_DATA_TYPE "dat"
67
 
 
68
 
// Fields in UDataInfo:
69
 
 
70
 
// TZ_SIG[] is encoded as numeric literals for compatibility with the HP compiler
71
 
static const uint8_t TZ_SIG_0 = 0x7a; // z
72
 
static const uint8_t TZ_SIG_1 = 0x6f; // o
73
 
static const uint8_t TZ_SIG_2 = 0x6e; // n
74
 
static const uint8_t TZ_SIG_3 = 0x65; // e
75
 
 
76
 
// This must match the version number at the top of tz.txt as
77
 
// well as the version number in the udata header.
78
 
static const int8_t TZ_FORMAT_VERSION = 4; // formatVersion[0]
79
 
 
80
 
struct TZHeader {    
81
 
    uint16_t versionYear;     // e.g. "1999j" -> 1999
82
 
    uint16_t versionSuffix;   // e.g. "1999j" -> 10
83
 
 
84
 
    uint32_t count;           // standardCount + dstCount
85
 
 
86
 
    uint32_t equivTableDelta;  // delta to equivalency group table
87
 
    uint32_t offsetIndexDelta; // delta to gmtOffset index table
88
 
 
89
 
    uint32_t countryIndexDelta; // delta to country code index table
90
 
 
91
 
    uint32_t nameIndexDelta;   // delta to name index table
92
 
    // The name index table is an array of 'count' 32-bit offsets from
93
 
    // the start of this header to equivalency group table entries.
94
 
 
95
 
    uint32_t nameTableDelta;   // delta to name (aka ID) table
96
 
    // The name table contains all zone IDs, in sort order, each name
97
 
    // terminated by a zero byte.
98
 
};
99
 
 
100
 
struct StandardZone {
101
 
    int32_t  gmtOffset;   // gmt offset in milliseconds
102
 
};
103
 
 
104
 
struct TZRule {
105
 
    uint8_t  month;  // month
106
 
    int8_t   dowim;  // dowim
107
 
    int8_t   dow;    // dow
108
 
    uint16_t time;   // time in minutes
109
 
    int8_t   mode;   // (w/s/u) == TimeZone::TimeMode enum as int
110
 
};
111
 
 
112
 
struct DSTZone {
113
 
    int32_t  gmtOffset;   // gmtoffset in milliseconds
114
 
    uint16_t dstSavings;  // savings in minutes
115
 
    TZRule   onsetRule;   // onset rule
116
 
    TZRule   ceaseRule;   // cease rule
117
 
};
118
 
 
119
 
/**
120
 
 * This variable-sized struct represents a time zone equivalency group.
121
 
 * This is a set of one or more zones that are identical in GMT offset
122
 
 * and rules, but differ in ID.  The struct has a variable size because
123
 
 * the standard zone has no rule data, and also because it contains a
124
 
 * variable number of index values listing the zones in the group.
125
 
 * The struct is padded to take up 4n bytes so that 4-byte integers
126
 
 * within the struct stay 4-aligned (namely, the gmtOffset members of
127
 
 * the zone structs).
128
 
 */
129
 
struct TZEquivalencyGroup {
130
 
    uint16_t nextEntryDelta;    // 0 for last entry
131
 
    uint8_t  isDST;             // != 0 for DSTZone
132
 
    uint8_t  reserved;
133
 
    union {
134
 
        struct {
135
 
            StandardZone zone;
136
 
            uint16_t     count;
137
 
            uint16_t     index; // There are actually 'count' uint16_t's here
138
 
        } s;
139
 
        struct {
140
 
            DSTZone      zone;
141
 
            uint16_t     count;
142
 
            uint16_t     index; // There are actually 'count' uint16_t's here
143
 
        } d;
144
 
    } u;
145
 
    // There may be two bytes of padding HERE to make the whole struct
146
 
    // have size 4n bytes.
147
 
};
148
 
 
149
 
/**
150
 
 * This variable-sized struct makes up the offset index table.  To get
151
 
 * from one table entry to the next, add the nextEntryDelta.  If the
152
 
 * nextEntryDelta is zero then this is the last entry.  The offset
153
 
 * index table is designed for sequential access, not random access.
154
 
 * Given the small number of distinct offsets (39 in 1999j), this
155
 
 * suffices.
156
 
 *
157
 
 * The value of default is the zone within this list that should be
158
 
 * selected as the default zone in the absence of any other
159
 
 * discriminating information.  This information comes from the file
160
 
 * tz.default.  Note that this is itself a zone number, like
161
 
 * those in the array starting at &zoneNumber.
162
 
 *
163
 
 * The gmtOffset field must be 4-aligned for some architectures.  To
164
 
 * ensure this, we do two things: 1. The entire struct is 4-aligned.
165
 
 * 2. The gmtOffset is placed at a 4-aligned position within the
166
 
 * struct.  3. The size of the whole structure is padded out to 4n
167
 
 * bytes.  We achieve this last condition by adding two bytes of
168
 
 * padding after the last zoneNumber, if count is _even_.  That is,
169
 
 * the struct size is 10+2count+padding, where padding is (count%2==0
170
 
 * ? 2:0).  See gentz for implementation.
171
 
 */
172
 
struct OffsetIndex {
173
 
    int32_t   gmtOffset;  // in ms - 4-aligned
174
 
    uint16_t  nextEntryDelta;
175
 
    uint16_t  defaultZone; // a zone number from 0..TZHeader.count-1
176
 
    uint16_t  count;
177
 
    uint16_t  zoneNumber; // There are actually 'count' uint16_t's here
178
 
    // Following the 'count' uint16_t's starting with zoneNumber,
179
 
    // there may be two bytes of padding to make the whole struct have
180
 
    // a size of 4n.  nextEntryDelta skips over any padding.
181
 
};
182
 
 
183
 
/**
184
 
 * This variable-sized struct makes up the country index table.  To get
185
 
 * from one table entry to the next, add the nextEntryDelta.  If the
186
 
 * nextEntryDelta is zero then this is the last entry.  The country
187
 
 * index table is designed for sequential access, not random access.
188
 
 *
189
 
 * The intcode is an integer representation of the two-letter country
190
 
 * code.  It is computed as (c1-'A')*32 + (c0-'A') where the country
191
 
 * code is a two-character string c1 c0, 'A' <= ci <= 'Z'.
192
 
 *
193
 
 * There are no 4-byte integers in this table, so we don't 4-align the
194
 
 * entries.
195
 
 */
196
 
struct CountryIndex {
197
 
    uint16_t  intcode; // see above
198
 
    uint16_t  nextEntryDelta;
199
 
    uint16_t  count;
200
 
    uint16_t  zoneNumber; // There are actually 'count' uint16_t's here
201
 
};
202
 
 
203
 
#endif