// baltzo_testloader.h -*-C++-*- #ifndef INCLUDED_BALTZO_TESTLOADER #define INCLUDED_BALTZO_TESTLOADER #include <bsls_ident.h> BSLS_IDENT("$Id: $") //@PURPOSE: Provide a test implementation of the 'baltzo::Loader' protocol. // //@CLASSES: // baltzo::TestLoader: concrete implementation of 'baltzo::Loader' protocol // //@SEE_ALSO: baltzo_loader, baltzo_zoneinfo // //@DESCRIPTION: This component provides 'baltzo::TestLoader', a concrete test // implementation of the 'baltzo::Loader' protocol for loading a // 'baltzo::Zoneinfo' object. The following inheritance hierarchy diagram // shows the classes involved and their methods: //.. // ,------------------. // ( baltzo::TestLoader ) // `------------------' // | ctor // | setTimeZone // V // ,--------------. // ( baltzo::Loader ) // `--------------' // dtor // loadTimeZone //.. // This test implementation maintains a mapping of time-zone identifiers to // 'baltzo::Zoneinfo' objects. Clients can associate a time-zone object with a // time-zone identifier using the 'setTimeZone' method. A subsequent call to // the protocol method 'loadTimeZone' for that time-zone identifier will return // the supplied 'baltzo::Zoneinfo' object. // ///Usage ///----- // The following examples demonstrate how to populate a 'baltzo::TestLoader' // with time.zone information, and then access that information through the // 'baltzo::Loader' protocol. // ///Example 1: Populating a 'baltzo::TestLoader' with Time-Zone Information ///- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // We start by creating a 'baltzo::Zoneinfo' object, which we will eventually // populate with a subset of data for "America/New_York": //.. // baltzo::Zoneinfo newYorkTimeZone; //.. // Next, we populate 'newYorkTimeZone' with the correct time-zone identifier // and two types of local time (standard time, and daylight-saving time): //.. // const char *NEW_YORK_ID = "America/New_York"; // newYorkTimeZone.setIdentifier(NEW_YORK_ID); // // baltzo::LocalTimeDescriptor est(-5 * 60 * 60, false, "EST"); // baltzo::LocalTimeDescriptor edt(-4 * 60 * 60, true, "EDT"); //.. // Then, we create a series of transitions between these local time // descriptors for the years 2007-2011. Note that the United States // transitions to daylight saving time on the second Sunday in March, at 2am // local time (7am UTC), and transitions back to standard time on the first // Sunday in November at 2am local time (6am UTC). Also note, that these rules // for generating transitions was different prior to 2007, and may be changed // at some point in the future. //.. // bdlt::Time edtTime(7, 0, 0); // UTC transition time // bdlt::Time estTime(6, 0, 0); // UTC transition time // static const int edtDays[5] = { 11, 9, 8, 14, 13 }; // static const int estDays[5] = { 4, 2, 1, 7, 6 }; // for (int year = 2007; year < 2012; ++year) { // int edtDay = edtDays[year - 2007]; // int estDay = estDays[year - 2007]; // // bdlt::Datetime edtTransition(bdlt::Date(year, 3, edtDay), edtTime); // bdlt::Datetime estTransition(bdlt::Date(year, 11, estDay), estTime); // // bsls::Types::Int64 edtTransitionT = // bdlt::EpochUtil::convertToTimeT64(edtTransition); // // bsls::Types::Int64 estTransitionT = // bdlt::EpochUtil::convertToTimeT64(estTransition); //.. // Now, having created values representing the daylight saving time // transitions (in UTC), we insert the transitions into the 'baltzo::Zoneinfo' // object 'newYorkTimeZone': //.. // newYorkTimeZone.addTransition(edtTransitionT, edt); // newYorkTimeZone.addTransition(estTransitionT, est); // } //.. // Now, we create a 'baltzo::TestLoader' object and configure it with // 'newYorkTimeZone', which the test loader will associate with the identifier // 'newYorkTimeZone.identifier()' (whose value is "America/New_York"): //.. // baltzo::TestLoader testLoader; // testLoader.setTimeZone(newYorkTimeZone); //.. // ///Example 2: Accessing Time-Zone Information From a 'baltzo::TestLoader' /// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // In the next example, we will use the 'baltzo::TestLoader' we initialized in // the preceding example, to load time-zone information for New York via the // 'baltzo::Loader' protocol. // // We start by creating a 'baltzo::Loader' reference to 'testLoader': //.. // baltzo::Loader& loader = testLoader; //.. // Now we used the protocol method 'loadTimeZone' to load time-zone // information for New York: //.. // baltzo::Zoneinfo resultNewYork; // int status = loader.loadTimeZone(&resultNewYork, "America/New_York"); // assert(0 == status); //.. // Finally, we verify that the returned time-zone information, // 'resultNewYork', is equivalent to 'newYorkTimeZone', which we we used to // configure 'testLoader': //.. // assert(newYorkTimeZone == resultNewYork); //.. #include <balscm_version.h> #include <baltzo_loader.h> #include <baltzo_zoneinfo.h> #include <bslma_default.h> #include <bslma_stdallocator.h> #include <bslma_usesbslmaallocator.h> #include <bslmf_nestedtraitdeclaration.h> #include <bsl_iosfwd.h> #include <bsl_map.h> #include <bsl_string.h> namespace BloombergLP { namespace baltzo { // ================ // class TestLoader // ================ class TestLoader: public Loader { // This class provides a concrete test implementation of the 'Loader' // protocol (an abstract interface) for obtaining a time zone. This test // implementation maintains a mapping of time-zone identifiers to // 'Zoneinfo' objects. Time zone information objects are associated with a // time-zone identifier using the 'setTimeZone' method, and can be // subsequently accessed by calling the protocol method 'loadTimeZone' with // the same identifier. private: typedef bsl::map<bsl::string, Zoneinfo> TimeZoneMap; // A 'TimeZoneMap' is a type that maps a string time-zone identifier to // information about that time zone. // DATA TimeZoneMap d_timeZones; // set of time zones maintained by this test // loader private: // NOT IMPLEMENTED TestLoader(const TestLoader&); TestLoader& operator=(const TestLoader&); public: // TYPES typedef bsl::allocator<char> allocator_type; // TRAITS BSLMF_NESTED_TRAIT_DECLARATION(TestLoader, bslma::UsesBslmaAllocator); // CREATORS TestLoader(); explicit TestLoader(const allocator_type& allocator); // Create a 'TestLoader' object. Optionally specify an 'allocator' // (e.g., the address of a 'bslma::Allocator' object) to supply memory; // otherwise, the default allocator is used. By default the test // loader will return 'ErrorCode::k_UNSUPPORTED_ID' for all time-zone // identifiers. virtual ~TestLoader(); // Destroy this 'TestLoader' object; // MANIPULATORS void setTimeZone(const Zoneinfo& timeZone); // Set, to the specified 'timeZone', the time-zone information that // will be returned by 'loadTimeZone' for the identifier // 'timeZone.identifier()'. int setTimeZone(const char *timeZoneId, const char *timeZoneData, int timeZoneDataNumBytes); // Set the time-zone data this test loader will return for the // specified 'timeZoneId' to the Zoneinfo value defined by reading the // specified 'timeZoneData' buffer, holding data in the Zoneinfo // standard binary file format, of at least the specified // 'timeZoneDataNumBytes'. Return 0 on success, or a negative value // if an error occurs. The behavior is undefined unless // 'timeZoneData' contains at least 'timeZoneDataNumBytes' bytes. virtual int loadTimeZone(Zoneinfo *result, const char *timeZoneId); // Load into the specified 'result' the time-zone information for the // time-zone identified by the specified 'timeZoneId'. Return 0 on // success, and a non-zero value otherwise. A return status of // 'ErrorCode::k_UNSUPPORTED_ID' indicates that 'timeZoneId' is not // recognized. If an error occurs during the operation, 'result' will // be left in a valid but unspecified state. // ACCESSORS // Aspects allocator_type get_allocator() const; // Return the allocator used by this object to supply memory. Note // that if no allocator was supplied at construction the default // allocator in effect at construction is used. bsl::ostream& print(bsl::ostream& stream, int level = 0, int spacesPerLevel = 4) const; // Write the set of time zones maintained by this object to the // specified output 'stream' in a human-readable format, and return a // reference to 'stream'. Optionally specify an initial indentation // 'level', whose absolute value is incremented recursively for nested // objects. If 'level' is specified, optionally specify // 'spacesPerLevel', whose absolute value indicates the number of // spaces per indentation level for this and all of its nested objects. // If 'level' is negative, suppress indentation of the first line. If // 'spacesPerLevel' is negative, format the entire output on one line, // suppressing all but the initial indentation (as governed by // 'level'). If 'stream' is not valid on entry, this operation has no // effect. Note that the format is not fully specified, and can change // without notice. }; // FREE OPERATORS bsl::ostream& operator<<(bsl::ostream& stream, const TestLoader& loader); // Write the set of time zones maintained by the specified 'loader' to the // specified output 'stream' in a single-line format, and return a // reference to 'stream'. If 'stream' is not valid on entry, this // operation has no effect. Note that this human-readable format is not // fully specified, can change without notice, and is logically equivalent // to: //.. // print(stream, 0, -1); //.. // ============================================================================ // INLINE DEFINITIONS // ============================================================================ // ---------------- // class TestLoader // ---------------- // CREATORS inline TestLoader::TestLoader() : d_timeZones() { } inline TestLoader::TestLoader(const allocator_type& allocator) : d_timeZones(allocator) { } // ACCESSORS inline TestLoader::allocator_type TestLoader::get_allocator() const { return d_timeZones.get_allocator(); } } // close package namespace // FREE FUNCTIONS inline bsl::ostream& baltzo::operator<<(bsl::ostream& stream, const TestLoader& loader) { return loader.print(stream, 0, -1); } } // close enterprise namespace #endif // ---------------------------------------------------------------------------- // Copyright 2018 Bloomberg Finance L.P. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ----------------------------- END-OF-FILE ----------------------------------