Hinnant date library added

This commit is contained in:
moneroexamples 2016-11-22 17:34:38 +08:00
parent 996ce2c847
commit a2c3c575ba
10 changed files with 13724 additions and 1 deletions

View File

@ -12,7 +12,8 @@ set(SOURCE_HEADERS
set(SOURCE_FILES
format.cc
dateparser.cpp)
dateparser.cpp
date/tz.cpp)
# make static library called libmyxrm
# that we are going to link to

668
ext/date/chrono_io.h Normal file
View File

@ -0,0 +1,668 @@
#ifndef CHRONO_IO_H
#define CHRONO_IO_H
// The MIT License (MIT)
//
// Copyright (c) 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 woud involve another several millennia of evolution).
// We did not mean to shout.
#include <chrono>
#include <cstddef>
#include <cstdint>
#include <iosfwd>
#include <ratio>
#include <string>
#include <type_traits>
namespace date
{
namespace detail
{
#if __cplusplus >= 201402
template <class CharT, std::size_t N>
class string_literal
{
CharT p_[N];
public:
using const_iterator = const CharT*;
string_literal(string_literal const&) = default;
string_literal& operator=(string_literal const&) = delete;
template <std::size_t N1 = 2,
class = std::enable_if_t<N1 == N>>
constexpr string_literal(CharT c) noexcept
: p_{c}
{
}
constexpr string_literal(const CharT(&a)[N]) noexcept
: p_{}
{
for (std::size_t i = 0; i < N; ++i)
p_[i] = a[i];
}
template <class U = CharT, class = std::enable_if_t<1 < sizeof(U)>>
constexpr string_literal(const char(&a)[N]) noexcept
: p_{}
{
for (std::size_t i = 0; i < N; ++i)
p_[i] = a[i];
}
template <class CharT2, class = std::enable_if_t<!std::is_same<CharT2, CharT>{}>>
constexpr string_literal(string_literal<CharT2, N> const& a) noexcept
: p_{}
{
for (std::size_t i = 0; i < N; ++i)
p_[i] = a[i];
}
template <std::size_t N1, std::size_t N2,
class = std::enable_if_t<N1 + N2 - 1 == N>>
constexpr string_literal(const string_literal<CharT, N1>& x,
const string_literal<CharT, N2>& y) noexcept
: p_{}
{
std::size_t i = 0;
for (; i < N1-1; ++i)
p_[i] = x[i];
for (std::size_t j = 0; j < N2; ++j, ++i)
p_[i] = y[j];
}
constexpr const CharT* data() const noexcept {return p_;}
constexpr std::size_t size() const noexcept {return N-1;}
constexpr const_iterator begin() const noexcept {return p_;}
constexpr const_iterator end() const noexcept {return p_ + N-1;}
constexpr CharT const& operator[](std::size_t n) const noexcept
{
return p_[n];
}
template <class Traits>
friend
std::basic_ostream<CharT, Traits>&
operator<<(std::basic_ostream<CharT, Traits>& os, const string_literal& s)
{
return os << s.p_;
}
};
template <class CharT1, class CharT2, std::size_t N1, std::size_t N2>
constexpr
inline
string_literal<std::conditional_t<sizeof(CharT2) <= sizeof(CharT1), CharT1, CharT2>,
N1 + N2 - 1>
operator+(const string_literal<CharT1, N1>& x, const string_literal<CharT2, N2>& y) noexcept
{
using CharT = std::conditional_t<sizeof(CharT2) <= sizeof(CharT1), CharT1, CharT2>;
return string_literal<CharT, N1 + N2 - 1>{string_literal<CharT, N1>{x},
string_literal<CharT, N2>{y}};
}
template <class CharT, std::size_t N>
constexpr
inline
string_literal<CharT, N>
msl(const CharT(&a)[N]) noexcept
{
return string_literal<CharT, N>{a};
}
template <class CharT,
class = std::enable_if_t<std::is_same<CharT, char>{} ||
std::is_same<CharT, wchar_t>{} ||
std::is_same<CharT, char16_t>{} ||
std::is_same<CharT, char32_t>{}>>
constexpr
inline
string_literal<CharT, 2>
msl(CharT c) noexcept
{
return string_literal<CharT, 2>{c};
}
constexpr
std::size_t
to_string_len(std::intmax_t i)
{
std::size_t r = 0;
do
{
i /= 10;
++r;
} while (i > 0);
return r;
}
template <std::intmax_t N>
constexpr
inline
std::enable_if_t
<
N < 10,
string_literal<char, to_string_len(N)+1>
>
msl() noexcept
{
return msl(char(N % 10 + '0'));
}
template <std::intmax_t N>
constexpr
inline
std::enable_if_t
<
10 <= N,
string_literal<char, to_string_len(N)+1>
>
msl() noexcept
{
return msl<N/10>() + msl(char(N % 10 + '0'));
}
template <class CharT, std::intmax_t N, std::intmax_t D>
constexpr
inline
std::enable_if_t
<
std::ratio<N, D>::type::den != 1,
string_literal<CharT, to_string_len(std::ratio<N, D>::type::num) +
to_string_len(std::ratio<N, D>::type::den) + 4>
>
msl(std::ratio<N, D>) noexcept
{
using R = typename std::ratio<N, D>::type;
return msl(CharT{'['}) + msl<R::num>() + msl(CharT{'/'}) +
msl<R::den>() + msl(CharT{']'});
}
template <class CharT, std::intmax_t N, std::intmax_t D>
constexpr
inline
std::enable_if_t
<
std::ratio<N, D>::type::den == 1,
string_literal<CharT, to_string_len(std::ratio<N, D>::type::num) + 3>
>
msl(std::ratio<N, D>) noexcept
{
using R = typename std::ratio<N, D>::type;
return msl(CharT{'['}) + msl<R::num>() + msl(CharT{']'});
}
template <class CharT>
constexpr
inline
auto
msl(std::atto) noexcept
{
return msl(CharT{'a'});
}
template <class CharT>
constexpr
inline
auto
msl(std::femto) noexcept
{
return msl(CharT{'f'});
}
template <class CharT>
constexpr
inline
auto
msl(std::pico) noexcept
{
return msl(CharT{'p'});
}
template <class CharT>
constexpr
inline
auto
msl(std::nano) noexcept
{
return msl(CharT{'n'});
}
template <class CharT>
constexpr
inline
std::enable_if_t
<
std::is_same<CharT, char>{},
string_literal<char, 3>
>
msl(std::micro) noexcept
{
return string_literal<char, 3>{"\xC2\xB5"};
}
template <class CharT>
constexpr
inline
std::enable_if_t
<
!std::is_same<CharT, char>{},
string_literal<CharT, 2>
>
msl(std::micro) noexcept
{
return string_literal<CharT, 2>{CharT{static_cast<unsigned char>('\xB5')}};
}
template <class CharT>
constexpr
inline
auto
msl(std::milli) noexcept
{
return msl(CharT{'m'});
}
template <class CharT>
constexpr
inline
auto
msl(std::centi) noexcept
{
return msl(CharT{'c'});
}
template <class CharT>
constexpr
inline
auto
msl(std::deci) noexcept
{
return msl(CharT{'d'});
}
template <class CharT>
constexpr
inline
auto
msl(std::deca) noexcept
{
return string_literal<CharT, 3>{"da"};
}
template <class CharT>
constexpr
inline
auto
msl(std::hecto) noexcept
{
return msl(CharT{'h'});
}
template <class CharT>
constexpr
inline
auto
msl(std::kilo) noexcept
{
return msl(CharT{'k'});
}
template <class CharT>
constexpr
inline
auto
msl(std::mega) noexcept
{
return msl(CharT{'M'});
}
template <class CharT>
constexpr
inline
auto
msl(std::giga) noexcept
{
return msl(CharT{'G'});
}
template <class CharT>
constexpr
inline
auto
msl(std::tera) noexcept
{
return msl(CharT{'T'});
}
template <class CharT>
constexpr
inline
auto
msl(std::peta) noexcept
{
return msl(CharT{'P'});
}
template <class CharT>
constexpr
inline
auto
msl(std::exa) noexcept
{
return msl(CharT{'E'});
}
template <class CharT, class Period>
constexpr
auto
get_units(Period p)
{
return msl<CharT>(p) + string_literal<CharT, 2>{"s"};
}
template <class CharT>
constexpr
auto
get_units(std::ratio<1>)
{
return string_literal<CharT, 2>{"s"};
}
template <class CharT>
constexpr
auto
get_units(std::ratio<60>)
{
return string_literal<CharT, 4>{"min"};
}
template <class CharT>
constexpr
auto
get_units(std::ratio<3600>)
{
return string_literal<CharT, 2>{"h"};
}
#else // __cplusplus < 201402
inline
std::string
to_string(std::uint64_t x)
{
return std::to_string(x);
}
template <class CharT>
std::basic_string<CharT>
to_string(std::uint64_t x)
{
auto y = std::to_string(x);
return std::basic_string<CharT>(y.begin(), y.end());
}
template <class CharT, std::intmax_t N, std::intmax_t D>
constexpr
inline
typename std::enable_if
<
std::ratio<N, D>::type::den != 1,
std::basic_string<CharT>
>::type
msl(std::ratio<N, D>) noexcept
{
using R = typename std::ratio<N, D>::type;
return std::basic_string<CharT>(1, '[') + to_string<CharT>(R::num) + CharT{'/'} +
to_string<CharT>(R::den) + CharT{']'};
}
template <class CharT, std::intmax_t N, std::intmax_t D>
constexpr
inline
typename std::enable_if
<
std::ratio<N, D>::type::den == 1,
std::basic_string<CharT>
>::type
msl(std::ratio<N, D>) noexcept
{
using R = typename std::ratio<N, D>::type;
return std::basic_string<CharT>(1, '[') + to_string<CharT>(R::num) + CharT{']'};
}
template <class CharT>
constexpr
inline
std::basic_string<CharT>
msl(std::atto) noexcept
{
return {'a'};
}
template <class CharT>
constexpr
inline
std::basic_string<CharT>
msl(std::femto) noexcept
{
return {'f'};
}
template <class CharT>
constexpr
inline
std::basic_string<CharT>
msl(std::pico) noexcept
{
return {'p'};
}
template <class CharT>
constexpr
inline
std::basic_string<CharT>
msl(std::nano) noexcept
{
return {'n'};
}
template <class CharT>
constexpr
inline
typename std::enable_if
<
std::is_same<CharT, char>::value,
std::string
>::type
msl(std::micro) noexcept
{
return "\xC2\xB5";
}
template <class CharT>
constexpr
inline
typename std::enable_if
<
!std::is_same<CharT, char>::value,
std::basic_string<CharT>
>::type
msl(std::micro) noexcept
{
return {CharT(static_cast<unsigned char>('\xB5'))};
}
template <class CharT>
constexpr
inline
std::basic_string<CharT>
msl(std::milli) noexcept
{
return {'m'};
}
template <class CharT>
constexpr
inline
std::basic_string<CharT>
msl(std::centi) noexcept
{
return {'c'};
}
template <class CharT>
constexpr
inline
std::basic_string<CharT>
msl(std::deci) noexcept
{
return {'d'};
}
template <class CharT>
constexpr
inline
std::basic_string<CharT>
msl(std::deca) noexcept
{
return {'d', 'a'};
}
template <class CharT>
constexpr
inline
std::basic_string<CharT>
msl(std::hecto) noexcept
{
return {'h'};
}
template <class CharT>
constexpr
inline
std::basic_string<CharT>
msl(std::kilo) noexcept
{
return {'k'};
}
template <class CharT>
constexpr
inline
std::basic_string<CharT>
msl(std::mega) noexcept
{
return {'M'};
}
template <class CharT>
constexpr
inline
std::basic_string<CharT>
msl(std::giga) noexcept
{
return {'G'};
}
template <class CharT>
constexpr
inline
std::basic_string<CharT>
msl(std::tera) noexcept
{
return {'T'};
}
template <class CharT>
constexpr
inline
std::basic_string<CharT>
msl(std::peta) noexcept
{
return {'P'};
}
template <class CharT>
constexpr
inline
std::basic_string<CharT>
msl(std::exa) noexcept
{
return {'E'};
}
template <class CharT, class Period>
std::basic_string<CharT>
get_units(Period p)
{
return msl<CharT>(p) + CharT{'s'};
}
template <class CharT>
std::basic_string<CharT>
get_units(std::ratio<1>)
{
return {'s'};
}
template <class CharT>
std::basic_string<CharT>
get_units(std::ratio<60>)
{
return {'m', 'i', 'n'};
}
template <class CharT>
std::basic_string<CharT>
get_units(std::ratio<3600>)
{
return {'h'};
}
#endif // __cplusplus >= 201402
} // namespace detail
template <class CharT, class Traits, class Rep, class Period>
inline
std::basic_ostream<CharT, Traits>&
operator<<(std::basic_ostream<CharT, Traits>& os,
const std::chrono::duration<Rep, Period>& d)
{
using namespace std::chrono;
return os << d.count()
<< detail::get_units<CharT>(typename Period::type{});
}
} // namespace date
#endif // CHRONO_IO_H

4823
ext/date/date.h Normal file

File diff suppressed because it is too large Load Diff

49
ext/date/ios.h Normal file
View File

@ -0,0 +1,49 @@
//
// ios.h
// DateTimeLib
//
// 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.
#ifndef ios_hpp
#define ios_hpp
#if __APPLE__
# include <TargetConditionals.h>
# if TARGET_OS_IPHONE
# include <string>
namespace date
{
namespace iOSUtils
{
std::string get_tzdata_path();
} // namespace iOSUtils
} // namespace date
# endif // TARGET_OS_IPHONE
#else // !__APPLE__
# define TARGET_OS_IPHONE 0
#endif // !__APPLE__
#endif // ios_hpp

405
ext/date/ios.mm Normal file
View File

@ -0,0 +1,405 @@
//
// 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 <iostream>
#include <zlib.h>
#include <sys/stat.h>
#ifndef TAR_DEBUG
# define TAR_DEBUG 0
#endif
#define INTERNAL_DIR "Library/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;
int64_t realContentSize; // writable size without padding zeroes
int64_t blocksContentSize; // adjusted size to 512 bytes blocks
bool success;
};
char* convertCFStringRefPathToCStringPath(CFStringRef ref);
bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath);
TarInfo getTarObjectInfo(CFReadStreamRef readStream, int64_t location);
std::string getTarObject(CFReadStreamRef readStream, int64_t size);
bool writeFile(CFURLRef tzdataUrl, std::string fileName, std::string data,
int64_t realContentSize);
std::string
date::iOSUtils::get_tzdata_path()
{
CFURLRef ref = CFCopyHomeDirectoryURL();
CFStringRef homePath = CFURLCopyPath(CFCopyHomeDirectoryURL());
std::string tzdata_path(std::string(convertCFStringRefPathToCStringPath(homePath)) +
INTERNAL_DIR);
if (access(tzdata_path.c_str(), F_OK) == 0)
{
#if TAR_DEBUG
printf("tzdata exists\n");
#endif
return tzdata_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(CFCopyHomeDirectoryURL(), archiveUrl, tzdata_path);
}
return tzdata_path;
}
char*
convertCFStringRefPathToCStringPath(CFStringRef ref)
{
CFIndex bufferSize = CFStringGetMaximumSizeOfFileSystemRepresentation(ref);
char *buffer = new char[bufferSize];
CFStringGetFileSystemRepresentation(ref, buffer, bufferSize);
return buffer;
}
bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath)
{
const char *TAR_TMP_PATH = "/tmp.tar";
// create Library path
CFStringRef libraryStr = CFStringCreateWithCString(NULL, "Library",
CFStringGetSystemEncoding());
CFURLRef libraryUrl = CFURLCreateCopyAppendingPathComponent(kCFAllocatorDefault,
homeUrl, libraryStr,
false);
// create tzdata path
CFStringRef tzdataPathRef = CFStringCreateWithCString(NULL, INTERNAL_DIR,
CFStringGetSystemEncoding());
CFURLRef tzdataPathUrl = CFURLCreateCopyAppendingPathComponent(NULL, homeUrl,
tzdataPathRef, false);
// create src archive path
CFStringRef archivePath = CFURLCopyPath(archiveUrl);
gzFile tarFile = gzopen(convertCFStringRefPathToCStringPath(archivePath), "rb");
// create tar unpacking path
CFStringRef tarName = CFStringCreateWithCString(NULL, TAR_TMP_PATH,
CFStringGetSystemEncoding());
CFURLRef tarUrl = CFURLCreateCopyAppendingPathComponent(NULL, libraryUrl, tarName,
false);
const char *tarPath = convertCFStringRefPathToCStringPath(CFURLCopyPath(tarUrl));
// create tzdata directory
mkdir(destPath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
// create stream
CFWriteStreamRef writeStream = CFWriteStreamCreateWithFile(NULL, tarUrl);
bool success = true;
if (!CFWriteStreamOpen(writeStream))
{
CFStreamError err = CFWriteStreamGetError(writeStream);
if (err.domain == kCFStreamErrorDomainPOSIX)
{
printf("kCFStreamErrorDomainPOSIX %i\n", err.error);
}
else if(err.domain == kCFStreamErrorDomainMacOSStatus)
{
printf("kCFStreamErrorDomainMacOSStatus %i\n", err.error);
}
success = false;
}
if (!success)
{
remove(tarPath);
return false;
}
// ======= extract tar ========
unsigned int bufferLength = 1024 * 256; // 256Kb
void *buffer = malloc(bufferLength);
while (true)
{
int readBytes = gzread(tarFile, buffer, bufferLength);
if (readBytes > 0)
{
CFIndex writtenBytes = CFWriteStreamWrite(writeStream, (unsigned char*)buffer,
readBytes);
if (writtenBytes < 0)
{
CFStreamError err = CFWriteStreamGetError(writeStream);
printf("write stream error %i\n", err.error);
success = false;
break;
}
}
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;
}
}
CFWriteStreamClose(writeStream);
CFRelease(writeStream);
free(buffer);
gzclose(tarFile);
if (!success)
{
remove(tarPath);
return false;
}
// ======== extract files =========
uint64_t location = 0; // Position in the file
// get file size
struct stat stat_buf;
int res = stat(tarPath, &stat_buf);
if (res != 0)
{
printf("error file size\n");
remove(tarPath);
return false;
}
int64_t tarSize = stat_buf.st_size;
// create read stream
CFReadStreamRef readStream = CFReadStreamCreateWithFile(kCFAllocatorDefault, tarUrl);
if (!CFReadStreamOpen(readStream))
{
CFStreamError err = CFReadStreamGetError(readStream);
if (err.domain == kCFStreamErrorDomainPOSIX)
{
printf("kCFStreamErrorDomainPOSIX %i", err.error);
}
else if(err.domain == kCFStreamErrorDomainMacOSStatus)
{
printf("kCFStreamErrorDomainMacOSStatus %i", err.error);
}
success = false;
}
if (!success)
{
CFRelease(readStream);
remove(tarPath);
return false;
}
int count = 0;
long size = 0;
// process files
while (location < tarSize)
{
TarInfo info = getTarObjectInfo(readStream, location);
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(readStream, 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(tzdataPathUrl, info.objName, obj, info.realContentSize);
location += info.blocksContentSize;
break;
}
}
}
CFReadStreamClose(readStream);
CFRelease(readStream);
remove(tarPath);
return true;
}
TarInfo
getTarObjectInfo(CFReadStreamRef readStream, int64_t location)
{
int64_t length = TAR_BLOCK_SIZE;
uint8_t buffer[length];
char type;
char name[TAR_NAME_SIZE + 1];
char sizeBuf[TAR_SIZE_SIZE + 1];
CFIndex bytesRead;
bool avail = CFReadStreamHasBytesAvailable(readStream);
bytesRead = CFReadStreamRead(readStream, buffer, length);
if (bytesRead < 0)
{
CFStreamError err = CFReadStreamGetError(readStream);
printf("error reading tar object info %i", err.error);
return {false};
}
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);
int64_t realSize = strtol(sizeBuf, NULL, 8);
int64_t blocksSize = realSize + (TAR_BLOCK_SIZE - (realSize % TAR_BLOCK_SIZE));
return {type, std::string(name), realSize, blocksSize, true};
}
std::string
getTarObject(CFReadStreamRef readStream, int64_t size)
{
uint8_t buffer[size];
CFIndex bytesRead = CFReadStreamRead(readStream, buffer, size);
if (bytesRead < 0)
{
CFStreamError err = CFReadStreamGetError(readStream);
printf("error reading tar object info %i", err.error);
}
return std::string((char *)buffer);
}
bool
writeFile(CFURLRef tzdataUrl, std::string fileName, std::string data,
int64_t realContentSize)
{
// create stream
CFStringRef fileNameRef = CFStringCreateWithCString(NULL, fileName.c_str(),
CFStringGetSystemEncoding());
CFURLRef url = CFURLCreateCopyAppendingPathComponent(NULL, tzdataUrl, fileNameRef,
false);
CFWriteStreamRef writeStream = CFWriteStreamCreateWithFile(NULL, url);
// open stream
if (!CFWriteStreamOpen(writeStream))
{
CFStreamError err = CFWriteStreamGetError(writeStream);
if (err.domain == kCFStreamErrorDomainPOSIX)
{
printf("kCFStreamErrorDomainPOSIX %i\n", err.error);
}
else if(err.domain == kCFStreamErrorDomainMacOSStatus)
{
printf("kCFStreamErrorDomainMacOSStatus %i\n", err.error);
}
CFRelease(writeStream);
return false;
}
// trim empty space
uint8_t trimmedData[realContentSize + 1];
memset(&trimmedData, '\0', realContentSize);
memcpy(&trimmedData, data.c_str(), realContentSize);
// write
CFIndex writtenBytes = CFWriteStreamWrite(writeStream, trimmedData, realContentSize);
if (writtenBytes < 0)
{
CFStreamError err = CFWriteStreamGetError(writeStream);
printf("write stream error %i\n", err.error);
}
CFWriteStreamClose(writeStream);
CFRelease(writeStream);
writeStream = NULL;
return true;
}
} // namespace iOSUtils
} // namespace date
#endif // TARGET_OS_IPHONE

3046
ext/date/julian.h Normal file

File diff suppressed because it is too large Load Diff

3120
ext/date/tz.cpp Normal file

File diff suppressed because it is too large Load Diff

1345
ext/date/tz.h Normal file

File diff suppressed because it is too large Load Diff

265
ext/date/tz_private.h Normal file
View File

@ -0,0 +1,265 @@
#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 woud 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
{
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 ineffect 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;
};
} // namespace detail
} // namespace date
#if defined(_MSC_VER) && (_MSC_VER < 1900)
#include "tz.h"
#endif
#endif // TZ_PRIVATE_H

View File

@ -18,6 +18,7 @@
#include "../ext/dateparser.h"
#include "../ext/infix_iterator.h"
#include "../ext/date/tz.h"
#include <boost/lexical_cast.hpp>
#include <boost/filesystem.hpp>