mirror of
https://git.wownero.com/wownero/onion-wownero-blockchain-explorer.git
synced 2024-08-15 00:33:12 +00:00
Merge branch 'date_lib_added'
This commit is contained in:
commit
735de00f96
20 changed files with 17071 additions and 3429 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,3 +3,4 @@
|
|||
*.*~
|
||||
*.user
|
||||
.idea/
|
||||
cmake-build-debug/
|
||||
|
|
|
@ -172,4 +172,5 @@ target_link_libraries(${PROJECT_NAME}
|
|||
pthread
|
||||
unbound
|
||||
unwind
|
||||
curl
|
||||
dl)
|
||||
|
|
23
README.md
23
README.md
|
@ -8,7 +8,8 @@ Curently available Monero blockchain explorer websites have several limitations
|
|||
- are closed sourced,
|
||||
- are not available as hidden services,
|
||||
- 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
|
||||
|
@ -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
|
||||
- [mstch](https://github.com/no1msd/mstch) - C++ {{mustache}} templates
|
||||
- [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
|
||||
|
||||
|
@ -33,8 +35,8 @@ Tor users (testnet Monero network):
|
|||
Non tor users, can use its clearnet version (thanks to [Gingeropolous](https://github.com/Gingeropolous)):
|
||||
|
||||
- [http://explore.MoneroWorld.com](http://explore.moneroworld.com)
|
||||
|
||||
|
||||
|
||||
|
||||
## Onion Monero Blockchain Explorer features
|
||||
|
||||
The key features of the Onion Monero Blockchain Explorer are
|
||||
|
@ -45,7 +47,8 @@ The key features of the Onion Monero Blockchain Explorer are
|
|||
- made fully in C++,
|
||||
- the only explorer showing encrypted payments ID,
|
||||
- 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 transaction extra field,
|
||||
- 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 showing detailed information about mixins, such as, 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
|
||||
|
||||
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:
|
||||
- [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)
|
||||
|
@ -230,8 +234,11 @@ git clone https://github.com/moneroexamples/onion-monero-blockchain-explorer.git
|
|||
# enter the downloaded sourced code folder
|
||||
cd onion-monero-blockchain-explorer
|
||||
|
||||
# make a build folder and enter it
|
||||
mkdir build && cd build
|
||||
|
||||
# create the makefile
|
||||
cmake .
|
||||
cmake ..
|
||||
|
||||
# compile
|
||||
make
|
||||
|
|
|
@ -8,11 +8,11 @@ project(myext)
|
|||
set(SOURCE_HEADERS
|
||||
minicsv.h
|
||||
format.h
|
||||
dateparser.h)
|
||||
)
|
||||
|
||||
set(SOURCE_FILES
|
||||
format.cc
|
||||
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
668
ext/date/chrono_io.h
Normal 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
4823
ext/date/date.h
Normal file
File diff suppressed because it is too large
Load diff
49
ext/date/ios.h
Normal file
49
ext/date/ios.h
Normal 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
405
ext/date/ios.mm
Normal 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
3046
ext/date/julian.h
Normal file
File diff suppressed because it is too large
Load diff
3120
ext/date/tz.cpp
Normal file
3120
ext/date/tz.cpp
Normal file
File diff suppressed because it is too large
Load diff
1345
ext/date/tz.h
Normal file
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
265
ext/date/tz_private.h
Normal 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
|
|
@ -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
|
12
main.cpp
12
main.cpp
|
@ -223,12 +223,12 @@ int main(int ac, const char* av[]) {
|
|||
return xmrblocks.search(string(req.url_params.get("value")));
|
||||
});
|
||||
|
||||
// CROW_ROUTE(app, "/robots.txt")
|
||||
// ([&]() {
|
||||
// string text = "User-agent: *\n"
|
||||
// "Disallow: ";
|
||||
// return text;
|
||||
// });
|
||||
CROW_ROUTE(app, "/robots.txt")
|
||||
([&]() {
|
||||
string text = "User-agent: *\n"
|
||||
"Disallow: ";
|
||||
return text;
|
||||
});
|
||||
|
||||
CROW_ROUTE(app, "/autorefresh")
|
||||
([&]() {
|
||||
|
|
|
@ -451,7 +451,7 @@ namespace xmreg
|
|||
|
||||
|
||||
// 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>()));
|
||||
|
||||
|
|
6296
src/page.h
6296
src/page.h
File diff suppressed because it is too large
Load diff
|
@ -25,8 +25,8 @@
|
|||
{{^testnet}}
|
||||
<div class="center">
|
||||
<form action="/search" method="get" style="width:100%; margin-top:15px" class="style-1">
|
||||
<input type="text" name="value" size="100"
|
||||
placeholder="blk height, blk hash, tx hash, tx payment id, encrypted payment id, tx public key, input key image, and stealth address">
|
||||
<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, stealth address, and datetime">
|
||||
<input type="submit" value="Search">
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -143,23 +143,14 @@ namespace xmreg
|
|||
return bf::path(remove_trailing_path_separator(path_str));
|
||||
}
|
||||
|
||||
|
||||
string
|
||||
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;
|
||||
|
||||
char str_buff[TIME_LENGTH];
|
||||
|
||||
tm *tm_ptr;
|
||||
tm_ptr = localtime(×tamp);
|
||||
|
||||
size_t len;
|
||||
|
||||
len = std::strftime(str_buff, TIME_LENGTH, format, tm_ptr);
|
||||
|
||||
return string(str_buff, len);
|
||||
return date::format(format, date::floor<chrono::seconds>(sys_time));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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>
|
||||
timestamp_difference(uint64_t t1, uint64_t t2)
|
||||
{
|
||||
|
@ -890,5 +851,21 @@ namespace xmreg
|
|||
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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
311
src/tools.h
311
src/tools.h
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Created by marcin on 5/11/15.
|
||||
// Created by mwo on 5/11/15.
|
||||
//
|
||||
|
||||
#ifndef XMREG01_TOOLS_H
|
||||
|
@ -16,8 +16,8 @@
|
|||
#include "monero_headers.h"
|
||||
#include "tx_details.h"
|
||||
|
||||
#include "../ext/dateparser.h"
|
||||
#include "../ext/infix_iterator.h"
|
||||
#include "../ext/date/tz.h"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
@ -36,221 +36,208 @@
|
|||
*/
|
||||
namespace xmreg
|
||||
{
|
||||
using namespace cryptonote;
|
||||
using namespace crypto;
|
||||
using namespace std;
|
||||
|
||||
namespace bf = boost::filesystem;
|
||||
namespace pt = boost::posix_time;
|
||||
namespace gt = boost::gregorian;
|
||||
namespace lt = boost::local_time;
|
||||
using namespace cryptonote;
|
||||
using namespace crypto;
|
||||
using namespace std;
|
||||
|
||||
namespace bf = boost::filesystem;
|
||||
namespace pt = boost::posix_time;
|
||||
namespace gt = boost::gregorian;
|
||||
namespace lt = boost::local_time;
|
||||
|
||||
|
||||
struct outputs_visitor
|
||||
struct outputs_visitor
|
||||
{
|
||||
std::vector<crypto::public_key >& m_output_keys;
|
||||
|
||||
const Blockchain& m_bch;
|
||||
|
||||
outputs_visitor(std::vector<crypto::public_key>& output_keys, const Blockchain& bch) :
|
||||
m_output_keys(output_keys), m_bch(bch)
|
||||
{
|
||||
std::vector<crypto::public_key >& m_output_keys;
|
||||
}
|
||||
|
||||
const Blockchain& m_bch;
|
||||
|
||||
outputs_visitor(std::vector<crypto::public_key>& output_keys, const Blockchain& bch) :
|
||||
m_output_keys(output_keys), m_bch(bch)
|
||||
{
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
bool handle_output(uint64_t unlock_time, const crypto::public_key &pubkey)
|
||||
{
|
||||
m_output_keys.push_back(pubkey);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
bool
|
||||
parse_str_secret_key(const string& key_str, T& secret_key);
|
||||
|
||||
|
||||
bool
|
||||
get_tx_pub_key_from_str_hash(Blockchain& core_storage,
|
||||
const string& hash_str,
|
||||
transaction& tx);
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
bool
|
||||
parse_str_secret_key(const string& key_str, T& secret_key);
|
||||
|
||||
|
||||
bool
|
||||
get_tx_pub_key_from_str_hash(Blockchain& core_storage,
|
||||
const string& hash_str,
|
||||
transaction& tx);
|
||||
|
||||
bool
|
||||
parse_str_address(const string& address_str,
|
||||
account_public_address& address,
|
||||
bool testnet = false);
|
||||
|
||||
inline bool
|
||||
is_separator(char c);
|
||||
|
||||
string
|
||||
print_address(const account_public_address& address,
|
||||
bool
|
||||
parse_str_address(const string& address_str,
|
||||
account_public_address& address,
|
||||
bool testnet = false);
|
||||
|
||||
string
|
||||
print_sig (const signature& sig);
|
||||
inline bool
|
||||
is_separator(char c);
|
||||
|
||||
string
|
||||
remove_trailing_path_separator(const string& in_path);
|
||||
string
|
||||
print_address(const account_public_address& address,
|
||||
bool testnet = false);
|
||||
|
||||
bf::path
|
||||
remove_trailing_path_separator(const bf::path& in_path);
|
||||
string
|
||||
print_sig (const signature& sig);
|
||||
|
||||
string
|
||||
timestamp_to_str(time_t timestamp, const char* format = "%F %T");
|
||||
string
|
||||
remove_trailing_path_separator(const string& in_path);
|
||||
|
||||
bf::path
|
||||
remove_trailing_path_separator(const bf::path& in_path);
|
||||
|
||||
string
|
||||
timestamp_to_str(time_t timestamp, const char* format = "%F %T");
|
||||
|
||||
|
||||
ostream&
|
||||
operator<< (ostream& os, const account_public_address& addr);
|
||||
ostream&
|
||||
operator<< (ostream& os, const account_public_address& addr);
|
||||
|
||||
|
||||
string
|
||||
get_default_lmdb_folder(bool testnet = false);
|
||||
string
|
||||
get_default_lmdb_folder(bool testnet = false);
|
||||
|
||||
bool
|
||||
generate_key_image(const crypto::key_derivation& derivation,
|
||||
const std::size_t output_index,
|
||||
const crypto::secret_key& sec_key,
|
||||
const crypto::public_key& pub_key,
|
||||
crypto::key_image& key_img);
|
||||
bool
|
||||
generate_key_image(const crypto::key_derivation& derivation,
|
||||
const std::size_t output_index,
|
||||
const crypto::secret_key& sec_key,
|
||||
const crypto::public_key& pub_key,
|
||||
crypto::key_image& key_img);
|
||||
|
||||
bool
|
||||
get_blockchain_path(const boost::optional<string>& bc_path,
|
||||
bf::path& blockchain_path,
|
||||
bool testnet = false);
|
||||
bool
|
||||
get_blockchain_path(const boost::optional<string>& bc_path,
|
||||
bf::path& blockchain_path,
|
||||
bool testnet = false);
|
||||
|
||||
uint64_t
|
||||
sum_money_in_outputs(const transaction& tx);
|
||||
uint64_t
|
||||
sum_money_in_outputs(const transaction& tx);
|
||||
|
||||
uint64_t
|
||||
sum_money_in_inputs(const transaction& tx);
|
||||
uint64_t
|
||||
sum_money_in_inputs(const transaction& tx);
|
||||
|
||||
array<uint64_t, 2>
|
||||
sum_money_in_tx(const transaction& tx);
|
||||
array<uint64_t, 2>
|
||||
sum_money_in_tx(const transaction& tx);
|
||||
|
||||
array<uint64_t, 2>
|
||||
sum_money_in_txs(const vector<transaction>& txs);
|
||||
array<uint64_t, 2>
|
||||
sum_money_in_txs(const vector<transaction>& txs);
|
||||
|
||||
uint64_t
|
||||
sum_fees_in_txs(const vector<transaction>& txs);
|
||||
uint64_t
|
||||
sum_fees_in_txs(const vector<transaction>& txs);
|
||||
|
||||
uint64_t
|
||||
get_mixin_no(const transaction& tx);
|
||||
uint64_t
|
||||
get_mixin_no(const transaction& tx);
|
||||
|
||||
vector<uint64_t>
|
||||
get_mixin_no_in_txs(const vector<transaction>& txs);
|
||||
vector<uint64_t>
|
||||
get_mixin_no_in_txs(const vector<transaction>& txs);
|
||||
|
||||
vector<pair<txout_to_key, uint64_t>>
|
||||
get_ouputs(const transaction& tx);
|
||||
vector<pair<txout_to_key, uint64_t>>
|
||||
get_ouputs(const transaction& tx);
|
||||
|
||||
vector<tuple<txout_to_key, uint64_t, uint64_t>>
|
||||
get_ouputs_tuple(const transaction& tx);
|
||||
vector<tuple<txout_to_key, uint64_t, uint64_t>>
|
||||
get_ouputs_tuple(const transaction& tx);
|
||||
|
||||
vector<txin_to_key>
|
||||
get_key_images(const transaction& tx);
|
||||
vector<txin_to_key>
|
||||
get_key_images(const transaction& tx);
|
||||
|
||||
|
||||
bool
|
||||
get_payment_id(const vector<uint8_t>& extra,
|
||||
crypto::hash& payment_id,
|
||||
crypto::hash8& payment_id8);
|
||||
bool
|
||||
get_payment_id(const vector<uint8_t>& extra,
|
||||
crypto::hash& payment_id,
|
||||
crypto::hash8& payment_id8);
|
||||
|
||||
bool
|
||||
get_payment_id(const transaction& tx,
|
||||
crypto::hash& payment_id,
|
||||
crypto::hash8& payment_id8);
|
||||
bool
|
||||
get_payment_id(const transaction& tx,
|
||||
crypto::hash& payment_id,
|
||||
crypto::hash8& payment_id8);
|
||||
|
||||
|
||||
inline void
|
||||
enable_monero_log() {
|
||||
uint32_t log_level = 0;
|
||||
epee::log_space::get_set_log_detalisation_level(true, log_level);
|
||||
epee::log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL);
|
||||
}
|
||||
inline void
|
||||
enable_monero_log() {
|
||||
uint32_t log_level = 0;
|
||||
epee::log_space::get_set_log_detalisation_level(true, log_level);
|
||||
epee::log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
uint64_t
|
||||
estimate_bc_height(const string& date, const char* format = "%Y-%m-%d");
|
||||
inline double
|
||||
get_xmr(uint64_t core_amount)
|
||||
{
|
||||
return static_cast<double>(core_amount) / 1e12;
|
||||
}
|
||||
|
||||
array<size_t, 5>
|
||||
timestamp_difference(uint64_t t1, uint64_t t2);
|
||||
|
||||
inline double
|
||||
get_xmr(uint64_t core_amount)
|
||||
{
|
||||
return static_cast<double>(core_amount) / 1e12;
|
||||
}
|
||||
|
||||
array<size_t, 5>
|
||||
timestamp_difference(uint64_t t1, uint64_t t2);
|
||||
|
||||
string
|
||||
read(string filename);
|
||||
string
|
||||
read(string filename);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* prints an iterable such as vector
|
||||
*/
|
||||
template<typename T>
|
||||
void print_iterable(const T & elems) {
|
||||
/**
|
||||
* prints an iterable such as vector
|
||||
*/
|
||||
template<typename T>
|
||||
void print_iterable(const T & elems) {
|
||||
|
||||
infix_ostream_iterator<typename T::value_type>
|
||||
oiter(std::cout, ",");
|
||||
infix_ostream_iterator<typename T::value_type>
|
||||
oiter(std::cout, ",");
|
||||
|
||||
std::cout << "[";
|
||||
std::copy(elems.begin(), elems.end(),oiter);
|
||||
std::cout << "]" << std::endl;
|
||||
}
|
||||
std::cout << "[";
|
||||
std::copy(elems.begin(), elems.end(),oiter);
|
||||
std::cout << "]" << std::endl;
|
||||
}
|
||||
|
||||
pair<string, double>
|
||||
timestamps_time_scale(const vector<uint64_t>& timestamps,
|
||||
uint64_t timeN, uint64_t resolution = 80,
|
||||
uint64_t time0 = 1397818193 /* timestamp of the second block */);
|
||||
pair<string, double>
|
||||
timestamps_time_scale(const vector<uint64_t>& timestamps,
|
||||
uint64_t timeN, uint64_t resolution = 80,
|
||||
uint64_t time0 = 1397818193 /* timestamp of the second block */);
|
||||
|
||||
|
||||
time_t
|
||||
ptime_to_time_t(const pt::ptime& in_ptime);
|
||||
time_t
|
||||
ptime_to_time_t(const pt::ptime& in_ptime);
|
||||
|
||||
bool
|
||||
decode_ringct(const rct::rctSig & rv,
|
||||
const crypto::public_key pub,
|
||||
const crypto::secret_key &sec,
|
||||
unsigned int i,
|
||||
rct::key & mask,
|
||||
uint64_t & amount);
|
||||
bool
|
||||
decode_ringct(const rct::rctSig & rv,
|
||||
const crypto::public_key pub,
|
||||
const crypto::secret_key &sec,
|
||||
unsigned int i,
|
||||
rct::key & mask,
|
||||
uint64_t & amount);
|
||||
|
||||
bool
|
||||
url_decode(const std::string& in, std::string& out);
|
||||
bool
|
||||
url_decode(const std::string& in, std::string& out);
|
||||
|
||||
map<std::string, std::string>
|
||||
parse_crow_post_data(const string& req_body);
|
||||
map<std::string, std::string>
|
||||
parse_crow_post_data(const string& req_body);
|
||||
|
||||
bool
|
||||
get_dummy_account_keys(account_keys& dummy_keys, bool testnet = false);
|
||||
bool
|
||||
get_dummy_account_keys(account_keys& dummy_keys, bool testnet = false);
|
||||
|
||||
|
||||
// from wallet2::decrypt
|
||||
string
|
||||
decrypt(const std::string &ciphertext,
|
||||
const crypto::secret_key &skey,
|
||||
bool authenticated = true);
|
||||
// from wallet2::decrypt
|
||||
string
|
||||
decrypt(const std::string &ciphertext,
|
||||
const crypto::secret_key &skey,
|
||||
bool authenticated = true);
|
||||
|
||||
// based on
|
||||
// crypto::public_key wallet2::get_tx_pub_key_from_received_outs(const tools::wallet2::transfer_details &td) const
|
||||
public_key
|
||||
get_tx_pub_key_from_received_outs(const transaction &tx);
|
||||
// based on
|
||||
// crypto::public_key wallet2::get_tx_pub_key_from_received_outs(const tools::wallet2::transfer_details &td) const
|
||||
public_key
|
||||
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");
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue