////////////////////////////////////////////////////////////////////////// // Database ////////////////////////////////////////////////////////////////////////// // // TimeZone database format: // // ftz // { // u8 magic ("fantz 02") // utf summary // u1 numPrefixes // utf[] prefixes // u2 numIndexItems // indexItems[] // sorted by name // { // u1 prefix id // utf name // u4 fileOffset // } // timeZones[] // { // u2 numRules // rules[] // { // u2 startYear // i4 utcOffset (seconds) // utf stdAbbr // i4 dstOffset (seconds); if zero rest is skipped // [ // utf dstAbbr // dstTime dstStart // dstTime dstEnd // ] // } // } // // dstTime // { // u1 month // u1 onMode 'd', 'l', '>', '<' (date, last, >=, and <=) // u1 onWeekday (0-6) // u1 onDay // i4 atTime (seconds) // u1 atMode 'w' , 's', 'u' (wall, standad, universal) // } // // The timezone database is generated by the "/adm/buildtz.fan" // script. Refer to the "zic.8.txt" source file the code // distribution of the Olson database to further describe // model of the original data. // /// <summary> /// Load the name and file offset list from file into memory. /// </summary> static void loadIndex() { DataReader reader = new DataReader(new BufferedStream(dbFile.OpenRead())); try { // check magic "fantz 02" long magic = reader.ReadLong(); if (magic != 0x66616e747a203032L) throw new IOException("Invalid magic 0x" + magic.ToString("X").ToLower()); reader.ReadUTF(); // load prefixes int numPrefixes = reader.ReadByte(); prefixes = new string[numPrefixes]; for (int i=0; i<numPrefixes; ++i) prefixes[i] = reader.ReadUTF(); // load the zones and verify in sort order int num = reader.ReadUnsignedShort(); indexPrefixes = new byte[num]; indexNames = new string[num]; indexOffsets = new int[num]; for (int i=0; i<num; ++i) { indexPrefixes[i] = reader.ReadByte(); indexNames[i] = reader.ReadUTF(); indexOffsets[i] = reader.ReadInt(); if (i != 0 && String.Compare(indexNames[i-1], indexNames[i], StringComparison.Ordinal) >= 0) throw new IOException("Index not sorted"); } } finally { reader.Close(); } }