Merge branch 'date_lib_added'

master
moneroexamples 8 years ago
commit 735de00f96

1
.gitignore vendored

@ -3,3 +3,4 @@
*.*~ *.*~
*.user *.user
.idea/ .idea/
cmake-build-debug/

@ -172,4 +172,5 @@ target_link_libraries(${PROJECT_NAME}
pthread pthread
unbound unbound
unwind unwind
curl
dl) dl)

@ -8,7 +8,8 @@ Curently available Monero blockchain explorer websites have several limitations
- are closed sourced, - are closed sourced,
- are not available as hidden services, - are not available as hidden services,
- provide only basic search capabilities, - provide only basic search capabilities,
- can't identify users outputs based on provided Monero address and viewkey. - can't identify users outputs based on provided Monero address and viewkey, or private tx key,
- do not support Monero testnet, i.e., they dont work with RingCT transactions
In this example, these limitations are addressed by development of In this example, these limitations are addressed by development of
@ -18,7 +19,8 @@ an Onion Monero Blockchain Explorer. The example not only shows how to use Moner
- [lmdb++](https://github.com/bendiken/lmdbxx) - C++ wrapper for the LMDB - [lmdb++](https://github.com/bendiken/lmdbxx) - C++ wrapper for the LMDB
- [mstch](https://github.com/no1msd/mstch) - C++ {{mustache}} templates - [mstch](https://github.com/no1msd/mstch) - C++ {{mustache}} templates
- [rapidjson](https://github.com/miloyip/rapidjson) - C++ JSON parser/generator - [rapidjson](https://github.com/miloyip/rapidjson) - C++ JSON parser/generator
- [date](https://github.com/HowardHinnant/date) - C++ date and time library
- [fmt](https://github.com/fmtlib/fmt) - Small, safe and fast string formatting library
## Address ## Address
@ -45,7 +47,8 @@ The key features of the Onion Monero Blockchain Explorer are
- made fully in C++, - made fully in C++,
- the only explorer showing encrypted payments ID, - the only explorer showing encrypted payments ID,
- the only explorer with the ability to search by encrypted payments ID, tx public - the only explorer with the ability to search by encrypted payments ID, tx public
and private keys, stealth addresses, input key images, and private keys, stealth addresses, input key images, block timestamps
(UTC time, e.g., 2016-11-23 14:03:05)
- the only explorer showing ring signatures, - the only explorer showing ring signatures,
- the only explorer showing transaction extra field, - the only explorer showing transaction extra field,
- the only explorer showing public components of Monero addresses, - the only explorer showing public components of Monero addresses,
@ -53,13 +56,14 @@ The key features of the Onion Monero Blockchain Explorer are
- the only explorer that can be used to prove that you send Monero to someone, - the only explorer that can be used to prove that you send Monero to someone,
- the only explorer showing detailed information about mixins, such as, mixins' - the only explorer showing detailed information about mixins, such as, mixins'
age, timescale, mixin of mixins, age, timescale, mixin of mixins,
- the only explorer showing number of amount output indices. - the only explorer showing number of amount output indices,
- the only explorer supporting Monero testnet network and RingCT.
## Prerequisite ## Prerequisite
Everything here was done and tested using Monero 0.9.4 on Ubuntu 16.04 x86_64. Everything here was done and tested using Monero 0.9.4 on Ubuntu 16.04 x86_64.
Instruction for Monero 0.9 compilation and Monero headers and libraries setup are Instruction for Monero 0.10 compilation and Monero headers and libraries setup are
as shown here: as shown here:
- [Compile Monero 0.9 on Ubuntu 16.04 x64](https://github.com/moneroexamples/compile-monero-09-on-ubuntu-16-04) - [Compile Monero 0.9 on Ubuntu 16.04 x64](https://github.com/moneroexamples/compile-monero-09-on-ubuntu-16-04)
- [lmdbcpp-monero](https://github.com/moneroexamples/lmdbcpp-monero.git) - [lmdbcpp-monero](https://github.com/moneroexamples/lmdbcpp-monero.git)
@ -230,8 +234,11 @@ git clone https://github.com/moneroexamples/onion-monero-blockchain-explorer.git
# enter the downloaded sourced code folder # enter the downloaded sourced code folder
cd onion-monero-blockchain-explorer cd onion-monero-blockchain-explorer
# make a build folder and enter it
mkdir build && cd build
# create the makefile # create the makefile
cmake . cmake ..
# compile # compile
make make

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

@ -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

File diff suppressed because it is too large Load Diff

@ -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

@ -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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -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

@ -1,35 +0,0 @@
//
// Created by marcin on 22/11/15.
//
#include "dateparser.h"
dateparser::dateparser(std::string fmt)
{
// set format
using namespace boost::local_time;
local_time_input_facet* input_facet = new local_time_input_facet();
input_facet->format(fmt.c_str());
ss.imbue(std::locale(ss.getloc(), input_facet));
}
bool
dateparser::operator()(std::string const& text)
{
ss.clear();
ss.str(text);
bool ok = bool(ss >> pt);
if (ok)
{
auto tm = to_tm(pt);
year = tm.tm_year;
month = tm.tm_mon + 1; // for 1-based (1:jan, .. 12:dec)
day = tm.tm_mday;
}
return ok;
}

@ -1,27 +0,0 @@
//
// Created by marcin on 22/11/15.
//
#ifndef XMR2CSV_DATEPARSER_H
#define XMR2CSV_DATEPARSER_H
#include <iostream>
#include <boost/date_time/local_time/local_time.hpp>
// taken from: http://stackoverflow.com/a/19482908/248823
struct dateparser
{
boost::posix_time::ptime pt;
unsigned year, month, day;
dateparser(std::string fmt);
bool
operator()(std::string const& text);
private:
std::stringstream ss;
};
#endif //XMR2CSV_DATEPARSER_H

@ -223,12 +223,12 @@ int main(int ac, const char* av[]) {
return xmrblocks.search(string(req.url_params.get("value"))); return xmrblocks.search(string(req.url_params.get("value")));
}); });
// CROW_ROUTE(app, "/robots.txt") CROW_ROUTE(app, "/robots.txt")
// ([&]() { ([&]() {
// string text = "User-agent: *\n" string text = "User-agent: *\n"
// "Disallow: "; "Disallow: ";
// return text; return text;
// }); });
CROW_ROUTE(app, "/autorefresh") CROW_ROUTE(app, "/autorefresh")
([&]() { ([&]() {

@ -451,7 +451,7 @@ namespace xmreg
// set cursor the the first item // set cursor the the first item
if (cr.get(key_to_find, info_val, MDB_SET)) if (cr.get(key_to_find, info_val, MDB_SET_RANGE))
{ {
out_infos.push_back(*(info_val.data<output_info>())); out_infos.push_back(*(info_val.data<output_info>()));

@ -2203,37 +2203,6 @@ namespace xmreg {
// such search start with "aoi_", e.g., "aoi_444-23.00" // such search start with "aoi_", e.g., "aoi_444-23.00"
bool search_for_amount_output_idx = (search_text.substr(0, 4) == "aoi_"); bool search_for_amount_output_idx = (search_text.substr(0, 4) == "aoi_");
// check if date given in format: 2005-04-55
// this is 10 characters
if (search_text.length() == 19)
{
uint64_t estimated_blk_height {0};
// first parse the string date into boost's ptime object
dateparser parser {"%Y-%m-%d %H:%M:%S"};
if (parser(search_text))
{
// seems we have a correct date!
// so try to estimate block height from it.
cout << "timestamp: " << xmreg::ptime_to_time_t(parser.pt) << endl;
// estimate blockchain height from the start date provided
estimated_blk_height = xmreg::estimate_bc_height(search_text);
result_html = show_block(estimated_blk_height);
// nasty check if output is "Cant get" as a sign of
// a not found tx. Later need to think of something better.
if (result_html.find("Cant get") == string::npos)
{
return result_html;
}
}
}
// first check if searching for block of given height // first check if searching for block of given height
if (search_text.size() < 12 && if (search_text.size() < 12 &&
(search_for_global_output_idx == false (search_for_global_output_idx == false
@ -2365,6 +2334,39 @@ namespace xmreg {
mylmdb = make_unique<xmreg::MyLMDB>(lmdb2_path); mylmdb = make_unique<xmreg::MyLMDB>(lmdb2_path);
// check if date given in format: 2015-04-15 12:02:33
// this is 19 characters
if (search_text.length() == 19)
{
uint64_t estimated_blk_height {0};
// first parse the string to date::sys_seconds and then to timestamp
// since epoch
uint64_t blk_timestamp_utc = parse(search_text).time_since_epoch().count();
if (blk_timestamp_utc)
{
// seems we have a correct date!
// so try to estimate block height from it.
//
// to find block we can use our lmdb outputs_info table
// its indexes are timestamps.
vector<xmreg::output_info> out_infos;
if (mylmdb->get_output_info(blk_timestamp_utc, out_infos))
{
// since many outputs can be in a single block
// just get the first one to obtained its block
uint64_t found_blk_height = core_storage->get_db()
.get_tx_block_height(out_infos.at(0).tx_hash);
return show_block(found_blk_height);
}
}
}
mylmdb->search(search_text, mylmdb->search(search_text,
tx_search_results["key_images"], tx_search_results["key_images"],
@ -3617,10 +3619,10 @@ namespace xmreg {
} }
} }
} }
return mixin_no; return mixin_no;
} }
string string
get_full_page(string& middle) get_full_page(string& middle)
{ {
@ -3638,6 +3640,15 @@ namespace xmreg {
+ footer_html; + footer_html;
} }
string
get_full_page(string& middle)
{
return xmreg::read(TMPL_HEADER)
+ middle
+ xmreg::read(TMPL_FOOTER);
}
void void
add_css_style(mstch::map& context) add_css_style(mstch::map& context)
{ {
@ -3646,7 +3657,6 @@ namespace xmreg {
}}; }};
} }
}; };
} }

@ -25,8 +25,8 @@
{{^testnet}} {{^testnet}}
<div class="center"> <div class="center">
<form action="/search" method="get" style="width:100%; margin-top:15px" class="style-1"> <form action="/search" method="get" style="width:100%; margin-top:15px" class="style-1">
<input type="text" name="value" size="100" <input type="text" name="value" size="120"
placeholder="blk height, blk hash, tx hash, tx payment id, encrypted payment id, tx public key, input key image, and stealth address"> placeholder="blk height, blk hash, tx hash, tx payment id, encrypted payment id, tx public key, input key image, stealth address, and datetime">
<input type="submit" value="Search"> <input type="submit" value="Search">
</form> </form>
</div> </div>

@ -143,23 +143,14 @@ namespace xmreg
return bf::path(remove_trailing_path_separator(path_str)); return bf::path(remove_trailing_path_separator(path_str));
} }
string string
timestamp_to_str(time_t timestamp, const char* format) timestamp_to_str(time_t timestamp, const char* format)
{ {
auto a_time_point = chrono::system_clock::from_time_t(timestamp);
auto utc = date::to_utc_time(chrono::system_clock::from_time_t(timestamp));
auto sys_time = date::to_sys_time(utc);
const int TIME_LENGTH = 60; return date::format(format, date::floor<chrono::seconds>(sys_time));
char str_buff[TIME_LENGTH];
tm *tm_ptr;
tm_ptr = localtime(&timestamp);
size_t len;
len = std::strftime(str_buff, TIME_LENGTH, format, tm_ptr);
return string(str_buff, len);
} }
@ -516,36 +507,6 @@ namespace xmreg
} }
/**
* Rough estimate of block height from the time provided
*
*/
uint64_t
estimate_bc_height(const string& date, const char* format)
{
const pt::ptime MONERO_START {gt::date(2014,04,18)};
const uint64_t MONERO_BLOCK_TIME {60}; // seconds
dateparser parser {format};
if (!parser(date))
{
throw runtime_error(string("Date format is incorrect: ") + date);
}
pt::ptime requested_date = parser.pt;
if (requested_date < MONERO_START)
{
return 0;
}
pt::time_duration td = requested_date - MONERO_START;
return static_cast<uint64_t>(td.total_seconds()) / MONERO_BLOCK_TIME;
}
array<size_t, 5> array<size_t, 5>
timestamp_difference(uint64_t t1, uint64_t t2) timestamp_difference(uint64_t t1, uint64_t t2)
{ {
@ -890,5 +851,21 @@ namespace xmreg
return null_pkey; return null_pkey;
} }
date::sys_seconds
parse(const std::string& str, string format)
{
std::istringstream in(str);
date::sys_seconds tp;
in >> date::parse(format, tp);
if (in.fail())
{
in.clear();
in.str(str);
in >> date::parse(format, tp);
}
return tp;
}
} }

@ -1,5 +1,5 @@
// //
// Created by marcin on 5/11/15. // Created by mwo on 5/11/15.
// //
#ifndef XMREG01_TOOLS_H #ifndef XMREG01_TOOLS_H
@ -16,8 +16,8 @@
#include "monero_headers.h" #include "monero_headers.h"
#include "tx_details.h" #include "tx_details.h"
#include "../ext/dateparser.h"
#include "../ext/infix_iterator.h" #include "../ext/infix_iterator.h"
#include "../ext/date/tz.h"
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
@ -36,6 +36,7 @@
*/ */
namespace xmreg namespace xmreg
{ {
using namespace cryptonote; using namespace cryptonote;
using namespace crypto; using namespace crypto;
using namespace std; using namespace std;
@ -59,25 +60,12 @@ namespace xmreg
bool handle_output(uint64_t unlock_time, const crypto::public_key &pubkey) bool handle_output(uint64_t unlock_time, const crypto::public_key &pubkey)
{ {
//check tx unlock time
// if (!m_bch.is_tx_spendtime_unlocked(unlock_time))
// {
// LOG_PRINT_L1("One of outputs for one of inputs has wrong tx.unlock_time = " << unlock_time);
// return false;
// }
m_output_keys.push_back(pubkey); m_output_keys.push_back(pubkey);
return true; return true;
} }
}; };
template <typename T> template <typename T>
bool bool
parse_str_secret_key(const string& key_str, T& secret_key); parse_str_secret_key(const string& key_str, T& secret_key);
@ -182,10 +170,6 @@ namespace xmreg
} }
uint64_t
estimate_bc_height(const string& date, const char* format = "%Y-%m-%d");
inline double inline double
get_xmr(uint64_t core_amount) get_xmr(uint64_t core_amount)
{ {
@ -252,6 +236,9 @@ namespace xmreg
public_key public_key
get_tx_pub_key_from_received_outs(const transaction &tx); get_tx_pub_key_from_received_outs(const transaction &tx);
date::sys_seconds
parse(const std::string& str, string format="%Y-%m-%d %H:%M:%S");
} }
#endif //XMREG01_TOOLS_H #endif //XMREG01_TOOLS_H

Loading…
Cancel
Save