Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component baltzo_datafileloader
[Package baltzo]

Provide a concrete baltzo::Loader for Zoneinfo binary files. More...

Namespaces

namespace  baltzo

Detailed Description

Outline
Purpose:
Provide a concrete baltzo::Loader for Zoneinfo binary files.
Classes:
baltzo::DataFileLoader concrete baltzo::Loader for Zoneinfo binary data
See also:
Component baltzo_zoneinfobinaryreader, Component baltzo_zoneinfoutil
Description:
This component provides a mechanism, baltzo::DataFileLoader, that is a concrete implementation of the baltzo::Loader protocol for loading, into a baltzo::Zoneinfo object, the properties of a time zone described in a Zoneinfo binary database file. The following inheritance hierarchy diagram shows the classes involved and their methods:
   ,----------------------.
  ( baltzo::DataFileLoader )
   `----------------------'
              |      ctor
              |      configureRootPath
              |      configureRootPathIfPlausible
              |      loadTimeZoneFilePath
              |      rootPath
              |      isRootPathPlausible
              V
       ,--------------.
      ( baltzo::Loader )
       `--------------'
                     dtor
                     loadTimeZone
A baltzo::DataFileLoader is supplied a file-system location using the configureRootPath method. This location should correspond to the root directory of a hierarchy containing Zoneinfo binary data files, where each Zoneinfo time-zone identifier indicates a relative path from the root directory to the binary data file containing the information for that time zone. Accordingly, baltzo::DataFileLoader provides a method that, given a time-zone identifier, will open the corresponding data file (relative to the root directory tree supplied at construction), and load, into a baltzo::Zoneinfo object, the data from that file.
Zoneinfo (TZ Database) Files:
The Zoneinfo database, also referred to as either the TZ database or the Olson database (after its creator, Arthur Olson), is a standard public-domain time-zone information distribution used by many software systems (including a number of Unix variants and the Java Runtime Environment). Information about the Zoneinfo database can be found online at http://www.twinsun.com/tz/tz-link.htm, including the time-zone rules for the supported time zones, and source code for the zic compiler (for compiling those rules into the binary representation used by this component). See baltzo_zoneinfobinaryreader for more information about the binary file format.
Directory Hierarchy:
Zoneinfo database files are typically held in a standard file-system directory hierarchy. Zoneinfo time-zone identifiers (e.g., "America/New_York") serve not only as an identifier, but as a relative path (using the UNIX file separator, /) to the file containing data for the time zone. So, given a hypothetical root directory "/etc/time_zones", the time-zone data file for "America/New_York" will be located in "/etc/time_zones/America/New_York".
Thread Safety:
baltzo::DataFileLoader is const thread-safe, meaning that accessors may be invoked concurrently from different threads, but it is not safe to access or modify a baltzo::DataFileLoader in one thread while another thread modifies the same object.
Usage:
The following examples illustrate how to use a baltzo::DataFileLoader to load the Zoneinfo time-zone data for a time zone.
Example 1: Prologue: Creating a Example Data File:
First we need to create one time-zone data file on which to operate. In practice, clients should not generate data files in this manner. Data files are typically created using the zic compiler -- a publicly available tool provided as part of the standard Zoneinfo distribution (see http://www.twinsun.com/tz/tz-link.htm) -- and deployed in a standard directory location (see baltzo_defaultzoneinfocache).
We start by defining static binary data for "Asia/Bangkok", (chosen because it is relatively small):
  const char ASIA_BANGKOK_DATA[] = {
    0x54, 0x5a, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
    0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
    0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0xa2, 0x6a, 0x67, 0xc4,
    0x01, 0x00, 0x00, 0x5e, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x62, 0x70, 0x00,
    0x04, 0x42, 0x4d, 0x54, 0x00, 0x49, 0x43, 0x54, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x54, 0x5a, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0c, 0xff, 0xff, 0xff,
    0xff, 0x56, 0xb6, 0x85, 0xc4, 0xff, 0xff, 0xff, 0xff, 0xa2, 0x6a, 0x67,
    0xc4, 0x01, 0x02, 0x00, 0x00, 0x5e, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x5e,
    0x3c, 0x00, 0x04, 0x00, 0x00, 0x62, 0x70, 0x00, 0x08, 0x4c, 0x4d, 0x54,
    0x00, 0x42, 0x4d, 0x54, 0x00, 0x49, 0x43, 0x54, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x0a, 0x49, 0x43, 0x54, 0x2d, 0x37, 0x0a
  };
Then we create a testing sub-directory "test/Asia" that will hold the data file for Bangkok. Note that "Asia/Bangkok" is the time-zone identifier for Bangkok and "Asia/Bangkok" also serves as a relative path (from our "./test" sub-directory) to that data file.
  #ifdef BSLS_PLATFORM_OS_WINDOWS
  const char *TEST_DIRECTORY = "test\\Asia";
  const char *TEST_FILE      = "test\\Asia\\Bangkok";
  #else
  const char *TEST_DIRECTORY = "test/Asia";
  const char *TEST_FILE      = "test/Asia/Bangkok";
  #endif
  int rc = bdls::FileUtil::createDirectories(TEST_DIRECTORY, true);
  assert(0 == rc);
Now we create a file for Bangkok and write the binary time-zone data to that file.
  bsl::ofstream outputFile(TEST_FILE, bsl::ofstream::binary);
  assert(outputFile.is_open());
  outputFile.write(ASIA_BANGKOK_DATA, sizeof(ASIA_BANGKOK_DATA));
  assert(outputFile);
  outputFile.close();
The file Bangkok should now appear in the Asia sub-directory, under out test directory.
Example 2: Using a baltzo::DataFileLoader to Load a Zoneinfo File:
In this example we demonstrate how to use a baltzo::DataFileLoader to load a time-zone data file into a baltzo::Zoneinfo object. We start by creating a baltzo::DataFileLoader object, loader, and configure it with the relative path "test" which we created in Example 1 (Prologue).
  baltzo::DataFileLoader loader;
  loader.configureRootPath("test");
Then we use the loadTimeZoneFilePath method to verify that loader will correctly locate the test data file we've created:
  const char *BANGKOK_ID = "Asia/Bangkok";
  bsl::string bangkokDataPath;
  rc = loader.loadTimeZoneFilePath(&bangkokDataPath, BANGKOK_ID);
  assert(0         == rc);
  assert(TEST_FILE == bangkokDataPath);  // Note 'TEST_FILE' from Example 1.
Now we create a baltzo::Zoneinfo object, timeZone, and load it using loader:
  baltzo::Zoneinfo timeZone;
  rc = loader.loadTimeZone(&timeZone, BANGKOK_ID);
  assert(0 == rc);
Finally we confirm that certain properties of the timezone object are in agreement with the properties defined in the binary data (see baltzo_zoneinfobinaryreader): (1) That the object's identifier is "Asia/Bangkok", and (2) the object contains three local time descriptors, "LMT" (Local Mean Time), "BMT" (Bangkok Mean Time) and "ICT" (Indochina Time), in that order:
  assert(BANGKOK_ID == timeZone.identifier());
  baltzo::Zoneinfo::LocalTimeDescriptorConstIterator iterator =
                                                  timeZone.descriptorBegin();
  assert("LMT" == iterator->description());
  ++iterator;
  assert("BMT" == iterator->description());
  ++iterator;
  assert("ICT" == iterator->description());
The timeZone object can now be use for time-zone calculations. See baltzo_zoneinfoutil.
Epilogue: Removing the Created Files:
The file hierarchy we created Example 1 solely for Example 2, is no longer needed, and is removed by:
  int rc = bdls::FileUtil::remove(TEST_DIRECTORY, true);
  assert(0 == rc);