1 // Copyright 2016 Google Inc. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef ABSL_TIME_INTERNAL_CCTZ_ZONE_INFO_SOURCE_H_ 16 #define ABSL_TIME_INTERNAL_CCTZ_ZONE_INFO_SOURCE_H_ 17 18 #include <cstddef> 19 #include <functional> 20 #include <memory> 21 #include <string> 22 23 #include "absl/base/config.h" 24 25 namespace absl { 26 ABSL_NAMESPACE_BEGIN 27 namespace time_internal { 28 namespace cctz { 29 30 // A stdio-like interface for providing zoneinfo data for a particular zone. 31 class ZoneInfoSource { 32 public: 33 virtual ~ZoneInfoSource(); 34 35 virtual std::size_t Read(void* ptr, std::size_t size) = 0; // like fread() 36 virtual int Skip(std::size_t offset) = 0; // like fseek() 37 38 // Until the zoneinfo data supports versioning information, we provide 39 // a way for a ZoneInfoSource to indicate it out-of-band. The default 40 // implementation returns an empty string. 41 virtual std::string Version() const; 42 }; 43 44 } // namespace cctz 45 } // namespace time_internal 46 ABSL_NAMESPACE_END 47 } // namespace absl 48 49 namespace absl { 50 ABSL_NAMESPACE_BEGIN 51 namespace time_internal { 52 namespace cctz_extension { 53 54 // A function-pointer type for a factory that returns a ZoneInfoSource 55 // given the name of a time zone and a fallback factory. Returns null 56 // when the data for the named zone cannot be found. 57 using ZoneInfoSourceFactory = 58 std::unique_ptr<absl::time_internal::cctz::ZoneInfoSource> (*)( 59 const std::string&, 60 const std::function<std::unique_ptr< 61 absl::time_internal::cctz::ZoneInfoSource>(const std::string&)>&); 62 63 // The user can control the mapping of zone names to zoneinfo data by 64 // providing a definition for cctz_extension::zone_info_source_factory. 65 // For example, given functions my_factory() and my_other_factory() that 66 // can return a ZoneInfoSource for a named zone, we could inject them into 67 // cctz::load_time_zone() with: 68 // 69 // namespace cctz_extension { 70 // namespace { 71 // std::unique_ptr<cctz::ZoneInfoSource> CustomFactory( 72 // const std::string& name, 73 // const std::function<std::unique_ptr<cctz::ZoneInfoSource>( 74 // const std::string& name)>& fallback_factory) { 75 // if (auto zip = my_factory(name)) return zip; 76 // if (auto zip = fallback_factory(name)) return zip; 77 // if (auto zip = my_other_factory(name)) return zip; 78 // return nullptr; 79 // } 80 // } // namespace 81 // ZoneInfoSourceFactory zone_info_source_factory = CustomFactory; 82 // } // namespace cctz_extension 83 // 84 // This might be used, say, to use zoneinfo data embedded in the program, 85 // or read from a (possibly compressed) file archive, or both. 86 // 87 // cctz_extension::zone_info_source_factory() will be called: 88 // (1) from the same thread as the cctz::load_time_zone() call, 89 // (2) only once for any zone name, and 90 // (3) serially (i.e., no concurrent execution). 91 // 92 // The fallback factory obtains zoneinfo data by reading files in ${TZDIR}, 93 // and it is used automatically when no zone_info_source_factory definition 94 // is linked into the program. 95 extern ZoneInfoSourceFactory zone_info_source_factory; 96 97 } // namespace cctz_extension 98 } // namespace time_internal 99 ABSL_NAMESPACE_END 100 } // namespace absl 101 102 #endif // ABSL_TIME_INTERNAL_CCTZ_ZONE_INFO_SOURCE_H_ 103