BDE 4.14.0 Production release
Loading...
Searching...
No Matches
baltzo_defaultzoneinfocache.h
Go to the documentation of this file.
1/// @file baltzo_defaultzoneinfocache.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// baltzo_defaultzoneinfocache.h -*-C++-*-
8#ifndef INCLUDED_BALTZO_DEFAULTZONEINFOCACHE
9#define INCLUDED_BALTZO_DEFAULTZONEINFOCACHE
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup baltzo_defaultzoneinfocache baltzo_defaultzoneinfocache
15/// @brief Provide facilities to manage a default Zoneinfo cache object.
16/// @addtogroup bal
17/// @{
18/// @addtogroup baltzo
19/// @{
20/// @addtogroup baltzo_defaultzoneinfocache
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#baltzo_defaultzoneinfocache-purpose"> Purpose</a>
25/// * <a href="#baltzo_defaultzoneinfocache-classes"> Classes </a>
26/// * <a href="#baltzo_defaultzoneinfocache-description"> Description </a>
27/// * <a href="#baltzo_defaultzoneinfocache-the-automatically-installed-default-cache-instance"> The Automatically-Installed Default-Cache Instance </a>
28/// * <a href="#baltzo_defaultzoneinfocache-default-time-zone-data-location"> Default Time Zone Data Location </a>
29/// * <a href="#baltzo_defaultzoneinfocache-thread-safety"> Thread Safety </a>
30/// * <a href="#baltzo_defaultzoneinfocache-usage"> Usage </a>
31/// * <a href="#baltzo_defaultzoneinfocache-example-1-accessing-the-default-zoneinfo-cache-object"> Example 1: Accessing the Default Zoneinfo Cache Object </a>
32/// * <a href="#baltzo_defaultzoneinfocache-example-2-installing-a-default-zoneinfo-cache-object"> Example 2: Installing a Default Zoneinfo Cache Object </a>
33///
34/// # Purpose {#baltzo_defaultzoneinfocache-purpose}
35/// Provide facilities to manage a default Zoneinfo cache object.
36///
37/// # Classes {#baltzo_defaultzoneinfocache-classes}
38///
39/// - baltzo::DefaultZoneinfoCache: default Zoneinfo cache utilities
40/// - baltzo::DefaultZoneinfoCacheScopedGuard: guard for default Zoneinfo cache
41///
42/// @see baltzo_zoneinfocache, baltzo_timezoneutil
43///
44/// # Description {#baltzo_defaultzoneinfocache-description}
45/// This component provides a namespace,
46/// `baltzo::DefaultZoneinfoCache`, for utility functions that install and
47/// access a default Zoneinfo cache object. In addition, this component
48/// provides a mechanism, `baltzo::DefaultZoneinfoCacheScopedGuard`, that
49/// facilities the temporary installation of the default Zoneinfo cache object
50/// (for the lifetime of the guard object).
51///
52/// Operations that convert a time value either from, or to, a local time
53/// representation, commonly require access to time-zone information provided
54/// from a `baltzo::ZoneinfoCache` object. Because a single set of time-zone
55/// data is generally applicable to an entire task, this component provides the
56/// installation and use of a process-wide default `baltzo::ZoneinfoCache`
57/// object (i.e., a Zoneinfo cache). See @ref baltzo_timezoneutil for examples of
58/// how operations may take advantage of this default cache. Note that the
59/// behavior is undefined unless this facility is used before `main` exits.
60///
61/// ## The Automatically-Installed Default-Cache Instance {#baltzo_defaultzoneinfocache-the-automatically-installed-default-cache-instance}
62///
63///
64/// If a `baltzo::ZoneinfoCache` object is not explicitly configured via the
65/// `setDefaultCache` method, the *first* call to `defaultCache` automatically
66/// initializes and returns a new Zoneinfo cache object (i.e., a default
67/// default-cache object). Subsequent calls to the `defaultCache` method return
68/// that same object, unless the default Zoneinfo cache object is reset via the
69/// `setDefaultCache` method.
70///
71/// Clients are encouraged to use this automatically configured default cache
72/// object unless there is a particular need to configure it explicitly.
73///
74/// ### Default Time Zone Data Location {#baltzo_defaultzoneinfocache-default-time-zone-data-location}
75///
76///
77/// The mechanism for automatically configuring a default Zoneinfo cache object
78/// first assumes that the TZ Database files are rooted in a directory
79/// specified by the `BDE_ZONEINFO_ROOT_PATH` environment variable. If
80/// `BDE_ZONEINFO_ROOT_PATH` is unset, the `baltzo::DefaultZoneinfoCache` will
81/// attempt to use one of a (priority ordered) sequence of several (platform
82/// specific) standard locations. Finally, if no standard directory exists that
83/// contains TZ Database files, the `baltzo::ZoneinfoCache` will use the current
84/// working directory.
85///
86/// If a TZ Database file is not available in the "configured" directory,
87/// requests for that time-zone's data will fail. Additional information about
88/// TZ Database files can be found in @ref baltzo_datafileloader .
89///
90/// ## Thread Safety {#baltzo_defaultzoneinfocache-thread-safety}
91///
92///
93/// The `baltzo::DefaultZoneinfoCache::defaultCache` method is *thread-safe*
94/// unless it is called concurrently with either the `setDefaultCache` method or
95/// the `putenv` POSIX function. Note that the `baltzo::ZoneinfoCache`
96/// singleton is, itself, fully thread-safe (see @ref baltzo_zoneinfocache ); it is
97/// only the installation of the default cache that is not thread-safe.
98///
99/// `baltzo::DefaultZoneinfoCache::setDefaultCache` is *not* *thread-safe*. The
100/// expected usage is that clients that choose to *explicitly* configure the
101/// default cache for their application (rather than using the automatically
102/// provided default cache) will set the default cache during the initialization
103/// of their application (while the application has a single thread).
104///
105/// The `baltzo::DefaultTimeZoneCacheScopedGuard` class is not, even *minimally*
106/// *thread-safe* meaning that its constructor cannot be invoked concurrently
107/// from multiple threads.
108///
109/// ## Usage {#baltzo_defaultzoneinfocache-usage}
110///
111///
112/// The following usage examples demonstrate configuring and accessing the
113/// default Zoneinfo cache object.
114///
115/// ### Example 1: Accessing the Default Zoneinfo Cache Object {#baltzo_defaultzoneinfocache-example-1-accessing-the-default-zoneinfo-cache-object}
116///
117///
118/// A common application of the `baltzo::DefaultZoneinfoCache` is to determine
119/// the appropriate time-zone information to use for an operation that accepts a
120/// Zoneinfo cache as an optional argument (e.g., see @ref baltzo_timezoneutil ).
121/// Note that this usage pattern is also seen for the default allocator (see
122/// @ref bslma_default ).
123///
124/// First, we declare a function, `getLocalTimeDescriptor`, that returns the
125/// local-time descriptor for a given time in a particular time zone. This
126/// method takes an optional `baltzo::ZoneinfoCache` address argument, via the
127/// default `zoneinfoCache` parameter. If `zoneinfoCache` is unspecified or 0,
128/// the default Zoneinfo cache is used for the operation:
129/// @code
130/// /// Load, into the specified `result`, the local time descriptor
131/// /// indicated by the specified `utcTime` and the specified `timeZoneId`.
132/// /// Return 0 on success, and a non-zero value otherwise. Optionally
133/// /// specify a `zoneinfoCache` used to retrieve time-zone information.
134/// /// If `zoneinfoCache` is 0, the currently installed default Zoneinfo
135/// /// cache is used.
136/// int getLocalTimeDescriptor(baltzo::LocalTimeDescriptor *result,
137/// const bdlt::Datetime& utcTime,
138/// const char *timeZoneId,
139/// baltzo::ZoneinfoCache *zoneinfoCache = 0)
140/// {
141/// @endcode
142/// We call the `baltzo::DefaultZoneinfoCache::defaultCache` method, which
143/// returns `zoneinfoCache` if `zoneinfoCache` is not 0, and the currently
144/// installed Zoneinfo cache otherwise.
145/// @code
146/// baltzo::ZoneinfoCache *cache =
147/// baltzo::DefaultZoneinfoCache::defaultCache(zoneinfoCache);
148/// BSLS_ASSERT(0 != cache);
149/// @endcode
150/// Then, now that we have a of Zoneinfo cache object, we access the time-zone
151/// data for `timeZoneId`, and obtain the local-time descriptor for `utcTime`:
152/// @code
153/// const baltzo::Zoneinfo *zoneinfo = cache->getZoneinfo(timeZoneId);
154/// if (0 == zoneinfo) {
155///
156/// // Data for `timeZoneId` is not available in the cache, so return
157/// // an error.
158///
159/// return 1; // RETURN
160/// }
161/// @endcode
162/// Now we invoke the `findTransitionForUtcTime` method on `zoneInfo` to obtain
163/// the transition holding the local time descriptor for the specified
164/// `utcTime`:
165/// @code
166/// baltzo::Zoneinfo::TransitionConstIterator it =
167/// zoneinfo->findTransitionForUtcTime(utcTime);
168/// *result = it->descriptor();
169/// return 0;
170/// }
171/// @endcode
172/// Note that `findTransitionForUtcTime` has undefined behavior if the supplied
173/// search time is earlier than that of the first transition in the Zoneinfo
174/// object. However a `baltzo::ZoneinfoCache` (from which we obtained
175/// `zoneinfo`) is guaranteed to return a well-formed `baltzo::Zoneinfo` (see
176/// `baltzo::ZoneinfoUtil::isWellFormed`), meaning that it contains a transition
177/// at the first representable `bdlt::Datetime` value, so the following call to
178/// `findTransitionForUtcTime` is guaranteed to have defined behavior.
179///
180/// Finally, we call our `getLocalDescriptor` defined above:
181/// @code
182/// baltzo::LocalTimeDescriptor result;
183/// int rc = getLocalTimeDescriptor(&result,
184/// bdlt::Datetime(bdlt::Date(2011, 03, 21),
185/// bdlt::Time(20, 57)),
186/// "America/New_York");
187/// assert(0 == rc);
188/// assert("EDT" == result.description());
189/// assert(true == result.dstInEffectFlag());
190/// assert(-14400 == result.utcOffsetInSeconds());
191/// @endcode
192/// Notice that since we did not specify the optional `baltzo::ZoneinfoCache`
193/// object, data will automatically come from the configured default
194/// `baltzo::ZoneinfoCache` object.
195///
196/// ### Example 2: Installing a Default Zoneinfo Cache Object {#baltzo_defaultzoneinfocache-example-2-installing-a-default-zoneinfo-cache-object}
197///
198///
199/// In this example we demonstrate how to configure the default time-zone cache
200/// for a process. Note that many application may not need to explicitly
201/// configure the default cache object, but can instead use the automatically
202/// configured default object. Also note that the default time-zone cache is
203/// intended to be configured by the *owner* of `main`. The default object
204/// should be set during the initialization of an application (while the task
205/// has a single thread) and unset just prior to termination (when there is
206/// similarly a single thread):
207/// @code
208/// int main(int argc, const char *argv[])
209/// {
210///
211/// // ...
212/// @endcode
213/// First, we create and configure a `baltzo::DataFileLoader` object:
214/// @code
215/// baltzo::DataFileLoader loader;
216/// loader.configureRootPath("./test");
217/// @endcode
218/// Then, we use `loader` to initialize a `baltzo::ZoneinfoCache` object:
219/// @code
220/// baltzo::ZoneinfoCache cache(&loader);
221/// @endcode
222/// Next, we create a `baltzo::DefaultZoneinfoCacheScopedGuard` to set the
223/// default Zoneinfo cache for the lifetime of the guard, and then verify the
224/// the address returned by the `defaultCache` method is correct:
225/// @code
226/// {
227/// baltzo::DefaultZoneinfoCacheScopedGuard guard(&cache);
228/// assert(&cache == baltzo::DefaultZoneinfoCache::defaultCache());
229///
230/// // ...
231/// @endcode
232/// Finally, at the end of this scope the `guard` is destroyed, and the default
233/// Zoneinfo cache is restored to its previous value:
234/// @code
235/// }
236/// assert(&cache != baltzo::DefaultZoneinfoCache::defaultCache());
237///
238/// // ...
239/// }
240/// @endcode
241/// @}
242/** @} */
243/** @} */
244
245/** @addtogroup bal
246 * @{
247 */
248/** @addtogroup baltzo
249 * @{
250 */
251/** @addtogroup baltzo_defaultzoneinfocache
252 * @{
253 */
254
255#include <balscm_version.h>
256
257#include <baltzo_zoneinfocache.h>
258
259#include <bsls_libraryfeatures.h>
260
261#include <bsl_vector.h>
262
263#include <vector>
264
265
266namespace baltzo {
267
268 // ==========================
269 // class DefaultZoneinfoCache
270 // ==========================
271
272/// This struct provides a namespace for functions that manage and access
273/// the default time-zone data cache.
275
276 private:
277 // PRIVATE CLASS METHODS
278
279 /// Return the address of the currently configured modifiable default
280 /// time-zone information (Zoneinfo) cache object.
281 static ZoneinfoCache *instance();
282
283 public:
284 // CLASS METHODS
285
286 /// Return the default `ZoneinfoCache` object for this process if the
287 /// optionally specified `cache` is 0, and `cache` otherwise. If
288 /// `cache` is 0, and the default Zoneinfo cache object has not been set
289 /// -- either explicitly with a call to `setDefaultCache`, or implicitly
290 /// through a prior call to this method -- then initialize a new
291 /// `ZoneinfoCache` object, set the default cache object to the newly
292 /// created object, and return its address.
293 static ZoneinfoCache *defaultCache(ZoneinfoCache *cache = 0);
294
295 /// Return a null terminated (C-style) string describing the default
296 /// file-system path of the (expected) root of the Zoneinfo Database
297 /// time-zone information files. The returned string will be the
298 /// current value of the `BDE_ZONEINFO_ROOT_PATH` environment variable,
299 /// if set, or else one of a (priority ordered) sequence of
300 /// (platform-specific) standard directories, if one of those
301 /// directories exists and contains a sub-set of expected files, and the
302 /// current directory, otherwise. The behavior is undefined if the
303 /// returned address is dereferenced after a subsequent call to the
304 /// `putenv` POSIX function to set the `BDE_ZONEINFO_ROOT_PATH`
305 /// environment variable.
306 static const char *defaultZoneinfoDataLocation();
307
309 bsl::vector<const char *> *locations);
311 std::vector<const char *> *locations);
312
313#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR
314 /// Load into the specified `locations`, the sequence of null
315 /// terminated C-style strings that characterizes the default paths for
316 /// Zoneinfo data, accessed by this class, on this platform.
318 std::pmr::vector<const char *> *locations);
319#endif
320
321 /// Set the address of the default `ZoneinfoCache` object to the
322 /// specified `cache`. Return the address of the default cache object
323 /// that was set by a previous call to this method, or 0 if no call to
324 /// this method was previously executed. The behavior is undefined
325 /// unless (1) `cache` remains valid until the last operation is
326 /// performed on this process's default cache, or a subsequent call to
327 /// `setDefaultCache`, and (2) this method is *not* called from one
328 /// thread while another thread is attempting to access the default time
329 /// zone cache instance (i.e., this method is *not* thread-safe). Note
330 /// that this method is intended for use *only* by the *owner* of `main`
331 /// (and for testing purposes) where the caller affirmatively takes
332 /// responsibility for the behavior of all clients of the default time
333 /// zone cache.
335};
336
337 // =====================================
338 // class DefaultZoneinfoCacheScopedGuard
339 // =====================================
340
341/// Upon construction, an object of this class saves the current default
342/// Zoneinfo cache and installs the user-specified Zoneinfo cache as the
343/// default. On destruction, the previous default Zoneinfo cache is
344/// restored. This class is not even *minimally* *thread* *safe*. For
345/// terminology see @ref bsldoc_glossary .
346///
347/// See @ref baltzo_defaultzoneinfocache
349
350 // DATA
351 ZoneinfoCache *d_previousCache_p; // original default Zoneinfo cache (to
352 // be restored on destruction)
353 private:
354 // NOT IMPLEMENTED
358
359 public:
360 // CREATORS
361
362 /// Create a scoped guard that installs the specified `cache` as the
363 /// default Zoneinfo cache. Note that the pre-existing default time
364 /// Zoneinfo cache is automatically restored on destruction of this
365 /// object.
367
368 /// Restore the default Zoneinfo cache that was in place when this
369 /// scoped guard was created, and destroy this guard.
371};
372
373// ============================================================================
374// INLINE DEFINITIONS
375// ============================================================================
376
377 // -------------------
378 // class ZoneinfoCache
379 // -------------------
380
381// CLASS METHODS
382inline
384{
385 return cache ? cache : instance();
386}
387
388 // -------------------------------------
389 // class DefaultZoneinfoCacheScopedGuard
390 // -------------------------------------
391
392// CREATORS
393inline
394DefaultZoneinfoCacheScopedGuard::DefaultZoneinfoCacheScopedGuard(
395 ZoneinfoCache *cache)
396: d_previousCache_p(DefaultZoneinfoCache::setDefaultCache(cache))
397{
398}
399
400inline
405
406} // close package namespace
407
408
409#endif
410
411// ----------------------------------------------------------------------------
412// Copyright 2018 Bloomberg Finance L.P.
413//
414// Licensed under the Apache License, Version 2.0 (the "License");
415// you may not use this file except in compliance with the License.
416// You may obtain a copy of the License at
417//
418// http://www.apache.org/licenses/LICENSE-2.0
419//
420// Unless required by applicable law or agreed to in writing, software
421// distributed under the License is distributed on an "AS IS" BASIS,
422// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
423// See the License for the specific language governing permissions and
424// limitations under the License.
425// ----------------------------- END-OF-FILE ----------------------------------
426
427/** @} */
428/** @} */
429/** @} */
Definition baltzo_defaultzoneinfocache.h:348
~DefaultZoneinfoCacheScopedGuard()
Definition baltzo_defaultzoneinfocache.h:401
Definition baltzo_zoneinfocache.h:232
Definition bslstl_vector.h:1025
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition baltzo_datafileloader.h:263
Definition baltzo_defaultzoneinfocache.h:274
static void loadDefaultZoneinfoDataLocations(bsl::vector< const char * > *locations)
static void loadDefaultZoneinfoDataLocations(std::vector< const char * > *locations)
static ZoneinfoCache * setDefaultCache(ZoneinfoCache *cache)
static ZoneinfoCache * defaultCache(ZoneinfoCache *cache=0)
Definition baltzo_defaultzoneinfocache.h:383
static const char * defaultZoneinfoDataLocation()