http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/8777ab5f/thirdparty/date/include/date/tz_private.h ---------------------------------------------------------------------- diff --git a/thirdparty/date/include/date/tz_private.h b/thirdparty/date/include/date/tz_private.h new file mode 100644 index 0000000..1aaad8e --- /dev/null +++ b/thirdparty/date/include/date/tz_private.h @@ -0,0 +1,318 @@ +#ifndef TZ_PRIVATE_H +#define TZ_PRIVATE_H + +// The MIT License (MIT) +// +// Copyright (c) 2015, 2016 Howard Hinnant +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +// Our apologies. When the previous paragraph was written, lowercase had not yet +// been invented (that would involve another several millennia of evolution). +// We did not mean to shout. + +#if !defined(_MSC_VER) || (_MSC_VER >= 1900) +#include "tz.h" +#else +#include "date.h" +#include <vector> +#endif + +namespace date +{ + +namespace detail +{ + +#if !USE_OS_TZDB + +enum class tz {utc, local, standard}; + +//forward declare to avoid warnings in gcc 6.2 +class MonthDayTime; +std::istream& operator>>(std::istream& is, MonthDayTime& x); +std::ostream& operator<<(std::ostream& os, const MonthDayTime& x); + + +class MonthDayTime +{ +private: + struct pair + { +#if defined(_MSC_VER) && (_MSC_VER < 1900) + pair() : month_day_(date::jan / 1), weekday_(0U) {} + + pair(const date::month_day& month_day, const date::weekday& weekday) + : month_day_(month_day), weekday_(weekday) {} +#endif + + date::month_day month_day_; + date::weekday weekday_; + }; + + enum Type {month_day, month_last_dow, lteq, gteq}; + + Type type_{month_day}; + +#if !defined(_MSC_VER) || (_MSC_VER >= 1900) + union U +#else + struct U +#endif + { + date::month_day month_day_; + date::month_weekday_last month_weekday_last_; + pair month_day_weekday_; + +#if !defined(_MSC_VER) || (_MSC_VER >= 1900) + U() : month_day_{date::jan/1} {} +#else + U() : + month_day_(date::jan/1), + month_weekday_last_(date::month(0U), date::weekday_last(date::weekday(0U))) + {} + +#endif // !defined(_MSC_VER) || (_MSC_VER >= 1900) + + U& operator=(const date::month_day& x); + U& operator=(const date::month_weekday_last& x); + U& operator=(const pair& x); + } u; + + std::chrono::hours h_{0}; + std::chrono::minutes m_{0}; + std::chrono::seconds s_{0}; + tz zone_{tz::local}; + +public: + MonthDayTime() = default; + MonthDayTime(local_seconds tp, tz timezone); + MonthDayTime(const date::month_day& md, tz timezone); + + date::day day() const; + date::month month() const; + tz zone() const {return zone_;} + + void canonicalize(date::year y); + + sys_seconds + to_sys(date::year y, std::chrono::seconds offset, std::chrono::seconds save) const; + sys_days to_sys_days(date::year y) const; + + sys_seconds to_time_point(date::year y) const; + int compare(date::year y, const MonthDayTime& x, date::year yx, + std::chrono::seconds offset, std::chrono::minutes prev_save) const; + + friend std::istream& operator>>(std::istream& is, MonthDayTime& x); + friend std::ostream& operator<<(std::ostream& os, const MonthDayTime& x); +}; + +// A Rule specifies one or more set of datetimes without using an offset. +// Multiple dates are specified with multiple years. The years in effect +// go from starting_year_ to ending_year_, inclusive. starting_year_ <= +// ending_year_. save_ is in effect for times from the specified time +// onward, including the specified time. When the specified time is +// local, it uses the save_ from the chronologically previous Rule, or if +// there is none, 0. + +//forward declare to avoid warnings in gcc 6.2 +class Rule; +bool operator==(const Rule& x, const Rule& y); +bool operator<(const Rule& x, const Rule& y); +bool operator==(const Rule& x, const date::year& y); +bool operator<(const Rule& x, const date::year& y); +bool operator==(const date::year& x, const Rule& y); +bool operator<(const date::year& x, const Rule& y); +bool operator==(const Rule& x, const std::string& y); +bool operator<(const Rule& x, const std::string& y); +bool operator==(const std::string& x, const Rule& y); +bool operator<(const std::string& x, const Rule& y); +std::ostream& operator<<(std::ostream& os, const Rule& r); + +class Rule +{ +private: + std::string name_; + date::year starting_year_{0}; + date::year ending_year_{0}; + MonthDayTime starting_at_; + std::chrono::minutes save_{0}; + std::string abbrev_; + +public: + Rule() = default; + explicit Rule(const std::string& s); + Rule(const Rule& r, date::year starting_year, date::year ending_year); + + const std::string& name() const {return name_;} + const std::string& abbrev() const {return abbrev_;} + + const MonthDayTime& mdt() const {return starting_at_;} + const date::year& starting_year() const {return starting_year_;} + const date::year& ending_year() const {return ending_year_;} + const std::chrono::minutes& save() const {return save_;} + + static void split_overlaps(std::vector<Rule>& rules); + + friend bool operator==(const Rule& x, const Rule& y); + friend bool operator<(const Rule& x, const Rule& y); + friend bool operator==(const Rule& x, const date::year& y); + friend bool operator<(const Rule& x, const date::year& y); + friend bool operator==(const date::year& x, const Rule& y); + friend bool operator<(const date::year& x, const Rule& y); + friend bool operator==(const Rule& x, const std::string& y); + friend bool operator<(const Rule& x, const std::string& y); + friend bool operator==(const std::string& x, const Rule& y); + friend bool operator<(const std::string& x, const Rule& y); + + friend std::ostream& operator<<(std::ostream& os, const Rule& r); + +private: + date::day day() const; + date::month month() const; + static void split_overlaps(std::vector<Rule>& rules, std::size_t i, std::size_t& e); + static bool overlaps(const Rule& x, const Rule& y); + static void split(std::vector<Rule>& rules, std::size_t i, std::size_t k, + std::size_t& e); +}; + +inline bool operator!=(const Rule& x, const Rule& y) {return !(x == y);} +inline bool operator> (const Rule& x, const Rule& y) {return y < x;} +inline bool operator<=(const Rule& x, const Rule& y) {return !(y < x);} +inline bool operator>=(const Rule& x, const Rule& y) {return !(x < y);} + +inline bool operator!=(const Rule& x, const date::year& y) {return !(x == y);} +inline bool operator> (const Rule& x, const date::year& y) {return y < x;} +inline bool operator<=(const Rule& x, const date::year& y) {return !(y < x);} +inline bool operator>=(const Rule& x, const date::year& y) {return !(x < y);} + +inline bool operator!=(const date::year& x, const Rule& y) {return !(x == y);} +inline bool operator> (const date::year& x, const Rule& y) {return y < x;} +inline bool operator<=(const date::year& x, const Rule& y) {return !(y < x);} +inline bool operator>=(const date::year& x, const Rule& y) {return !(x < y);} + +inline bool operator!=(const Rule& x, const std::string& y) {return !(x == y);} +inline bool operator> (const Rule& x, const std::string& y) {return y < x;} +inline bool operator<=(const Rule& x, const std::string& y) {return !(y < x);} +inline bool operator>=(const Rule& x, const std::string& y) {return !(x < y);} + +inline bool operator!=(const std::string& x, const Rule& y) {return !(x == y);} +inline bool operator> (const std::string& x, const Rule& y) {return y < x;} +inline bool operator<=(const std::string& x, const Rule& y) {return !(y < x);} +inline bool operator>=(const std::string& x, const Rule& y) {return !(x < y);} + +struct zonelet +{ + enum tag {has_rule, has_save, is_empty}; + + std::chrono::seconds gmtoff_; + tag tag_ = has_rule; + +#if !defined(_MSC_VER) || (_MSC_VER >= 1900) + union U +#else + struct U +#endif + { + std::string rule_; + std::chrono::minutes save_; + + ~U() {} + U() {} + U(const U&) {} + U& operator=(const U&) = delete; + } u; + + std::string format_; + date::year until_year_{0}; + MonthDayTime until_date_; + sys_seconds until_utc_; + local_seconds until_std_; + local_seconds until_loc_; + std::chrono::minutes initial_save_{}; + std::string initial_abbrev_; + std::pair<const Rule*, date::year> first_rule_{nullptr, date::year::min()}; + std::pair<const Rule*, date::year> last_rule_{nullptr, date::year::max()}; + + ~zonelet(); + zonelet(); + zonelet(const zonelet& i); + zonelet& operator=(const zonelet&) = delete; +}; + +#else // USE_OS_TZDB + +struct ttinfo +{ + std::int32_t tt_gmtoff; + unsigned char tt_isdst; + unsigned char tt_abbrind; + unsigned char pad[2]; +}; + +static_assert(sizeof(ttinfo) == 8, ""); + +struct expanded_ttinfo +{ + std::chrono::seconds offset; + std::string abbrev; + bool is_dst; +}; + +struct transition +{ + sys_seconds timepoint; + const expanded_ttinfo* info; + + transition(sys_seconds tp, const expanded_ttinfo* i = nullptr) + : timepoint(tp) + , info(i) + {} + + friend + std::ostream& + operator<<(std::ostream& os, const transition& t) + { + using namespace date; + using namespace std::chrono; + using date::operator<<; + os << t.timepoint << "Z "; + if (t.info->offset >= seconds{0}) + os << '+'; + os << make_time(t.info->offset); + if (t.info->is_dst > 0) + os << " daylight "; + else + os << " standard "; + os << t.info->abbrev; + return os; + } +}; + +#endif // USE_OS_TZDB + +} // namespace detail + +} // namespace date + +#if defined(_MSC_VER) && (_MSC_VER < 1900) +#include "tz.h" +#endif + +#endif // TZ_PRIVATE_H
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/8777ab5f/thirdparty/date/src/ios.mm ---------------------------------------------------------------------- diff --git a/thirdparty/date/src/ios.mm b/thirdparty/date/src/ios.mm new file mode 100644 index 0000000..105e5c0 --- /dev/null +++ b/thirdparty/date/src/ios.mm @@ -0,0 +1,337 @@ +// +// The MIT License (MIT) +// +// Copyright (c) 2016 Alexander Kormanovsky +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + +#include "ios.h" + +#if TARGET_OS_IPHONE + +#include <Foundation/Foundation.h> + +#include <fstream> +#include <zlib.h> +#include <sys/stat.h> + +#ifndef TAR_DEBUG +# define TAR_DEBUG 0 +#endif + +#define INTERNAL_DIR "Library" +#define TZDATA_DIR "tzdata" +#define TARGZ_EXTENSION "tar.gz" + +#define TAR_BLOCK_SIZE 512 +#define TAR_TYPE_POSITION 156 +#define TAR_NAME_POSITION 0 +#define TAR_NAME_SIZE 100 +#define TAR_SIZE_POSITION 124 +#define TAR_SIZE_SIZE 12 + +namespace date +{ + namespace iOSUtils + { + + struct TarInfo + { + char objType; + std::string objName; + size_t realContentSize; // writable size without padding zeroes + size_t blocksContentSize; // adjusted size to 512 bytes blocks + bool success; + }; + + std::string convertCFStringRefPathToCStringPath(CFStringRef ref); + bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath); + TarInfo getTarObjectInfo(std::ifstream &readStream); + std::string getTarObject(std::ifstream &readStream, int64_t size); + bool writeFile(const std::string &tzdataPath, const std::string &fileName, + const std::string &data, size_t realContentSize); + + std::string + get_current_timezone() + { + CFTimeZoneRef tzRef = CFTimeZoneCopySystem(); + CFStringRef tzNameRef = CFTimeZoneGetName(tzRef); + CFIndex bufferSize = CFStringGetLength(tzNameRef) + 1; + char buffer[bufferSize]; + + if (CFStringGetCString(tzNameRef, buffer, bufferSize, kCFStringEncodingUTF8)) + { + CFRelease(tzRef); + return std::string(buffer); + } + + CFRelease(tzRef); + + return ""; + } + + std::string + get_tzdata_path() + { + CFURLRef homeUrlRef = CFCopyHomeDirectoryURL(); + CFStringRef homePath = CFURLCopyPath(homeUrlRef); + std::string path(std::string(convertCFStringRefPathToCStringPath(homePath)) + + INTERNAL_DIR + "/" + TZDATA_DIR); + std::string result_path(std::string(convertCFStringRefPathToCStringPath(homePath)) + + INTERNAL_DIR); + + if (access(path.c_str(), F_OK) == 0) + { +#if TAR_DEBUG + printf("tzdata dir exists\n"); +#endif + CFRelease(homeUrlRef); + CFRelease(homePath); + + return result_path; + } + + CFBundleRef mainBundle = CFBundleGetMainBundle(); + CFArrayRef paths = CFBundleCopyResourceURLsOfType(mainBundle, CFSTR(TARGZ_EXTENSION), + NULL); + + if (CFArrayGetCount(paths) != 0) + { + // get archive path, assume there is no other tar.gz in bundle + CFURLRef archiveUrl = static_cast<CFURLRef>(CFArrayGetValueAtIndex(paths, 0)); + CFStringRef archiveName = CFURLCopyPath(archiveUrl); + archiveUrl = CFBundleCopyResourceURL(mainBundle, archiveName, NULL, NULL); + + extractTzdata(homeUrlRef, archiveUrl, path); + + CFRelease(archiveUrl); + CFRelease(archiveName); + } + + CFRelease(homeUrlRef); + CFRelease(homePath); + CFRelease(paths); + + return result_path; + } + + std::string + convertCFStringRefPathToCStringPath(CFStringRef ref) + { + CFIndex bufferSize = CFStringGetMaximumSizeOfFileSystemRepresentation(ref); + char *buffer = new char[bufferSize]; + CFStringGetFileSystemRepresentation(ref, buffer, bufferSize); + auto result = std::string(buffer); + delete[] buffer; + return result; + } + + bool + extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath) + { + std::string TAR_TMP_PATH = "/tmp.tar"; + + CFStringRef homeStringRef = CFURLCopyPath(homeUrl); + auto homePath = convertCFStringRefPathToCStringPath(homeStringRef); + CFRelease(homeStringRef); + + CFStringRef archiveStringRef = CFURLCopyPath(archiveUrl); + auto archivePath = convertCFStringRefPathToCStringPath(archiveStringRef); + CFRelease(archiveStringRef); + + // create Library path + auto libraryPath = homePath + INTERNAL_DIR; + + // create tzdata path + auto tzdataPath = libraryPath + "/" + TZDATA_DIR; + + // -- replace %20 with " " + const std::string search = "%20"; + const std::string replacement = " "; + size_t pos = 0; + + while ((pos = archivePath.find(search, pos)) != std::string::npos) { + archivePath.replace(pos, search.length(), replacement); + pos += replacement.length(); + } + + gzFile tarFile = gzopen(archivePath.c_str(), "rb"); + + // create tar unpacking path + auto tarPath = libraryPath + TAR_TMP_PATH; + + // create tzdata directory + mkdir(destPath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + + // ======= extract tar ======== + + std::ofstream os(tarPath.c_str(), std::ofstream::out | std::ofstream::app); + unsigned int bufferLength = 1024 * 256; // 256Kb + unsigned char *buffer = (unsigned char *)malloc(bufferLength); + bool success = true; + + while (true) + { + int readBytes = gzread(tarFile, buffer, bufferLength); + + if (readBytes > 0) + { + os.write((char *) &buffer[0], readBytes); + } + else + if (readBytes == 0) + { + break; + } + else + if (readBytes == -1) + { + printf("decompression failed\n"); + success = false; + break; + } + else + { + printf("unexpected zlib state\n"); + success = false; + break; + } + } + + os.close(); + free(buffer); + gzclose(tarFile); + + if (!success) + { + remove(tarPath.c_str()); + return false; + } + + // ======== extract files ========= + + uint64_t location = 0; // Position in the file + + // get file size + struct stat stat_buf; + int res = stat(tarPath.c_str(), &stat_buf); + if (res != 0) + { + printf("error file size\n"); + remove(tarPath.c_str()); + return false; + } + int64_t tarSize = stat_buf.st_size; + + // create read stream + std::ifstream is(tarPath.c_str(), std::ifstream::in | std::ifstream::binary); + + // process files + while (location < tarSize) + { + TarInfo info = getTarObjectInfo(is); + + if (!info.success || info.realContentSize == 0) + { + break; // something wrong or all files are read + } + + switch (info.objType) + { + case '0': // file + case '\0': // + { + std::string obj = getTarObject(is, info.blocksContentSize); +#if TAR_DEBUG + size += info.realContentSize; + printf("#%i %s file size %lld written total %ld from %lld\n", ++count, + info.objName.c_str(), info.realContentSize, size, tarSize); +#endif + writeFile(tzdataPath, info.objName, obj, info.realContentSize); + location += info.blocksContentSize; + + break; + } + } + } + + remove(tarPath.c_str()); + + return true; + } + + TarInfo + getTarObjectInfo(std::ifstream &readStream) + { + int64_t length = TAR_BLOCK_SIZE; + char buffer[length]; + char type; + char name[TAR_NAME_SIZE + 1]; + char sizeBuf[TAR_SIZE_SIZE + 1]; + + readStream.read(buffer, length); + + memcpy(&type, &buffer[TAR_TYPE_POSITION], 1); + + memset(&name, '\0', TAR_NAME_SIZE + 1); + memcpy(&name, &buffer[TAR_NAME_POSITION], TAR_NAME_SIZE); + + memset(&sizeBuf, '\0', TAR_SIZE_SIZE + 1); + memcpy(&sizeBuf, &buffer[TAR_SIZE_POSITION], TAR_SIZE_SIZE); + size_t realSize = strtol(sizeBuf, NULL, 8); + size_t blocksSize = realSize + (TAR_BLOCK_SIZE - (realSize % TAR_BLOCK_SIZE)); + + return {type, std::string(name), realSize, blocksSize, true}; + } + + std::string + getTarObject(std::ifstream &readStream, int64_t size) + { + char buffer[size]; + readStream.read(buffer, size); + return std::string(buffer); + } + + bool + writeFile(const std::string &tzdataPath, const std::string &fileName, const std::string &data, + size_t realContentSize) + { + std::ofstream os(tzdataPath + "/" + fileName, std::ofstream::out | std::ofstream::binary); + + if (!os) { + return false; + } + + // trim empty space + char trimmedData[realContentSize + 1]; + memset(&trimmedData, '\0', realContentSize); + memcpy(&trimmedData, data.c_str(), realContentSize); + + // write + os.write(trimmedData, realContentSize); + os.close(); + + return true; + } + + } // namespace iOSUtils +} // namespace date + +#endif // TARGET_OS_IPHONE
