00001 // Copyright 2016 Google Inc. All Rights Reserved. 00002 // 00003 // Licensed under the Apache License, Version 2.0 (the "License"); 00004 // you may not use this file except in compliance with the License. 00005 // You may obtain a copy of the License at 00006 // 00007 // https://www.apache.org/licenses/LICENSE-2.0 00008 // 00009 // Unless required by applicable law or agreed to in writing, software 00010 // distributed under the License is distributed on an "AS IS" BASIS, 00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00012 // See the License for the specific language governing permissions and 00013 // limitations under the License. 00014 00015 #ifndef ABSL_TIME_INTERNAL_CCTZ_ZONE_INFO_SOURCE_H_ 00016 #define ABSL_TIME_INTERNAL_CCTZ_ZONE_INFO_SOURCE_H_ 00017 00018 #include <cstddef> 00019 #include <functional> 00020 #include <memory> 00021 #include <string> 00022 00023 namespace absl { 00024 namespace time_internal { 00025 namespace cctz { 00026 00027 // A stdio-like interface for providing zoneinfo data for a particular zone. 00028 class ZoneInfoSource { 00029 public: 00030 virtual ~ZoneInfoSource(); 00031 00032 virtual std::size_t Read(void* ptr, std::size_t size) = 0; // like fread() 00033 virtual int Skip(std::size_t offset) = 0; // like fseek() 00034 00035 // Until the zoneinfo data supports versioning information, we provide 00036 // a way for a ZoneInfoSource to indicate it out-of-band. The default 00037 // implementation returns an empty std::string. 00038 virtual std::string Version() const; 00039 }; 00040 00041 } // namespace cctz 00042 } // namespace time_internal 00043 } // namespace absl 00044 00045 namespace absl { 00046 namespace time_internal { 00047 namespace cctz_extension { 00048 00049 // A function-pointer type for a factory that returns a ZoneInfoSource 00050 // given the name of a time zone and a fallback factory. Returns null 00051 // when the data for the named zone cannot be found. 00052 using ZoneInfoSourceFactory = 00053 std::unique_ptr<absl::time_internal::cctz::ZoneInfoSource> (*)( 00054 const std::string&, 00055 const std::function<std::unique_ptr<absl::time_internal::cctz::ZoneInfoSource>( 00056 const std::string&)>&); 00057 00058 // The user can control the mapping of zone names to zoneinfo data by 00059 // providing a definition for cctz_extension::zone_info_source_factory. 00060 // For example, given functions my_factory() and my_other_factory() that 00061 // can return a ZoneInfoSource for a named zone, we could inject them into 00062 // cctz::load_time_zone() with: 00063 // 00064 // namespace cctz_extension { 00065 // namespace { 00066 // std::unique_ptr<cctz::ZoneInfoSource> CustomFactory( 00067 // const std::string& name, 00068 // const std::function<std::unique_ptr<cctz::ZoneInfoSource>( 00069 // const std::string& name)>& fallback_factory) { 00070 // if (auto zip = my_factory(name)) return zip; 00071 // if (auto zip = fallback_factory(name)) return zip; 00072 // if (auto zip = my_other_factory(name)) return zip; 00073 // return nullptr; 00074 // } 00075 // } // namespace 00076 // ZoneInfoSourceFactory zone_info_source_factory = CustomFactory; 00077 // } // namespace cctz_extension 00078 // 00079 // This might be used, say, to use zoneinfo data embedded in the program, 00080 // or read from a (possibly compressed) file archive, or both. 00081 // 00082 // cctz_extension::zone_info_source_factory() will be called: 00083 // (1) from the same thread as the cctz::load_time_zone() call, 00084 // (2) only once for any zone name, and 00085 // (3) serially (i.e., no concurrent execution). 00086 // 00087 // The fallback factory obtains zoneinfo data by reading files in ${TZDIR}, 00088 // and it is used automatically when no zone_info_source_factory definition 00089 // is linked into the program. 00090 extern ZoneInfoSourceFactory zone_info_source_factory; 00091 00092 } // namespace cctz_extension 00093 } // namespace time_internal 00094 } // namespace absl 00095 00096 #endif // ABSL_TIME_INTERNAL_CCTZ_ZONE_INFO_SOURCE_H_