mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Reorganize source files
This commit is contained in:
@@ -22,7 +22,7 @@
|
||||
|
||||
#include <ripple/overlay/Peer.h>
|
||||
#include <ripple/shamap/SHAMap.h>
|
||||
#include <beast/clock/abstract_clock.h>
|
||||
#include <ripple/beast/clock/abstract_clock.h>
|
||||
#include <ripple/core/Stoppable.h>
|
||||
#include <memory>
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
#include <ripple/protocol/HashPrefix.h>
|
||||
#include <ripple/protocol/types.h>
|
||||
#include <ripple/beast/core/LexicalCast.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <boost/optional.hpp>
|
||||
#include <cassert>
|
||||
#include <utility>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <ripple/protocol/HashPrefix.h>
|
||||
#include <ripple/protocol/PublicKey.h>
|
||||
#include <ripple/protocol/SecretKey.h>
|
||||
#include <beast/hash/hash_append.h>
|
||||
#include <ripple/beast/hash/hash_append.h>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
#include <ripple/unity/git_id.h>
|
||||
#include <ripple/websocket/MakeServer.h>
|
||||
#include <ripple/crypto/csprng.h>
|
||||
#include <beast/asio/io_latency_probe.h>
|
||||
#include <ripple/beast/asio/io_latency_probe.h>
|
||||
#include <ripple/beast/core/LexicalCast.h>
|
||||
#include <boost/asio/signal_set.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
@@ -36,11 +36,11 @@
|
||||
#include <ripple/rpc/RPCHandler.h>
|
||||
#include <ripple/server/Role.h>
|
||||
#include <ripple/protocol/BuildInfo.h>
|
||||
#include <beast/clock/basic_seconds_clock.h>
|
||||
#include <ripple/beast/clock/basic_seconds_clock.h>
|
||||
#include <ripple/beast/core/Time.h>
|
||||
#include <beast/unit_test.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <ripple/beast/utility/Debug.h>
|
||||
#include <beast/streams/debug_ostream.h>
|
||||
#include <beast/detail/stream/debug_ostream.hpp>
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
#include <boost/program_options.hpp>
|
||||
#include <cstdlib>
|
||||
@@ -194,7 +194,7 @@ static int runUnitTests(
|
||||
std::string const& argument)
|
||||
{
|
||||
using namespace beast::unit_test;
|
||||
beast::debug_ostream stream;
|
||||
beast::detail::debug_ostream stream;
|
||||
reporter r (stream);
|
||||
r.arg(argument);
|
||||
bool const failed (r.run_each_if (
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include <ripple/app/misc/impl/AccountTxPaging.h>
|
||||
#include <ripple/protocol/types.h>
|
||||
#include <ripple/test/jtx.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <ripple/protocol/SecretKey.h>
|
||||
#include <ripple/protocol/digest.h>
|
||||
#include <ripple/protocol/TxFlags.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
|
||||
namespace ripple
|
||||
{
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/test/jtx.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace test {
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/test/jtx.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace test {
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/app/misc/HashRouter.h>
|
||||
#include <ripple/basics/chrono.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace test {
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/app/tx/impl/OfferStream.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/test/jtx.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <algorithm>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include <ripple/rpc/RipplePathFind.h>
|
||||
#include <ripple/rpc/RPCHandler.h>
|
||||
#include <ripple/test/jtx.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <chrono>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/app/tx/impl/Taker.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <ripple/beast/core/LexicalCast.h>
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
#define RIPPLE_BASICS_BASICCONFIG_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/contract.h>
|
||||
#include <beast/unit_test/const_container.h>
|
||||
#include <beast/ci_char_traits.h>
|
||||
#include <beast/detail/const_container.hpp>
|
||||
#include <beast/detail/ci_char_traits.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <map>
|
||||
@@ -40,8 +40,8 @@ using IniFileSections = std::map<std::string, std::vector<std::string>>;
|
||||
A configuration file contains zero or more sections.
|
||||
*/
|
||||
class Section
|
||||
: public beast::const_container <
|
||||
std::map <std::string, std::string, beast::ci_less>>
|
||||
: public beast::detail::const_container <
|
||||
std::map <std::string, std::string, beast::detail::ci_less>>
|
||||
{
|
||||
private:
|
||||
std::string name_;
|
||||
@@ -165,7 +165,7 @@ public:
|
||||
class BasicConfig
|
||||
{
|
||||
private:
|
||||
std::map <std::string, Section, beast::ci_less> map_;
|
||||
std::map <std::string, Section, beast::detail::ci_less> map_;
|
||||
|
||||
public:
|
||||
/** Returns `true` if a section with the given name exists. */
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
#include <ripple/basics/hardened_hash.h>
|
||||
#include <ripple/basics/UnorderedContainers.h>
|
||||
#include <beast/clock/abstract_clock.h>
|
||||
#include <ripple/beast/clock/abstract_clock.h>
|
||||
#include <ripple/beast/insight/Insight.h>
|
||||
#include <mutex>
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#define RIPPLE_BASICS_LOG_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/UnorderedContainers.h>
|
||||
#include <beast/ci_char_traits.h>
|
||||
#include <beast/detail/ci_char_traits.hpp>
|
||||
#include <ripple/beast/utility/Journal.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <map>
|
||||
@@ -148,7 +148,7 @@ private:
|
||||
std::mutex mutable mutex_;
|
||||
std::map <std::string,
|
||||
std::unique_ptr<beast::Journal::Sink>,
|
||||
beast::ci_less> sinks_;
|
||||
beast::detail::ci_less> sinks_;
|
||||
beast::severities::Severity thresh_;
|
||||
File file_;
|
||||
bool silent_ = false;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <ripple/basics/hardened_hash.h>
|
||||
#include <ripple/basics/Log.h>
|
||||
#include <ripple/basics/UnorderedContainers.h>
|
||||
#include <beast/clock/abstract_clock.h>
|
||||
#include <ripple/beast/clock/abstract_clock.h>
|
||||
#include <ripple/beast/insight/Insight.h>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#ifndef RIPPLE_BASICS_TESTSUITE_H_INCLUDED
|
||||
#define RIPPLE_BASICS_TESTSUITE_H_INCLUDED
|
||||
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <string>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
#define RIPPLE_BASICS_UNORDEREDCONTAINERS_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/hardened_hash.h>
|
||||
#include <beast/hash/hash_append.h>
|
||||
#include <beast/hash/uhash.h>
|
||||
#include <beast/hash/xxhasher.h>
|
||||
#include <ripple/beast/hash/hash_append.h>
|
||||
#include <ripple/beast/hash/uhash.h>
|
||||
#include <ripple/beast/hash/xxhasher.h>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
#ifndef RIPPLE_BASICS_CHRONO_H_INCLUDED
|
||||
#define RIPPLE_BASICS_CHRONO_H_INCLUDED
|
||||
|
||||
#include <beast/clock/abstract_clock.h>
|
||||
#include <beast/clock/basic_seconds_clock.h>
|
||||
#include <beast/clock/manual_clock.h>
|
||||
#include <ripple/beast/clock/abstract_clock.h>
|
||||
#include <ripple/beast/clock/basic_seconds_clock.h>
|
||||
#include <ripple/beast/clock/manual_clock.h>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
#ifndef RIPPLE_BASICS_HARDENED_HASH_H_INCLUDED
|
||||
#define RIPPLE_BASICS_HARDENED_HASH_H_INCLUDED
|
||||
|
||||
#include <beast/hash/hash_append.h>
|
||||
#include <beast/hash/xxhasher.h>
|
||||
#include <ripple/beast/hash/hash_append.h>
|
||||
#include <ripple/beast/hash/xxhasher.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/basics/contract.h>
|
||||
#include <ripple/basics/impl/CheckLibraryVersionsImpl.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <ripple/beast/core/SemanticVersion.h>
|
||||
#include <boost/version.hpp>
|
||||
#include <openssl/opensslv.h>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/basics/Log.h>
|
||||
#include <ripple/basics/RangeSet.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <ripple/beast/core/LexicalCast.h>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <cassert>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include <ripple/basics/ResolverAsio.h>
|
||||
#include <ripple/basics/Log.h>
|
||||
#include <ripple/beast/net/IPAddressConversion.h>
|
||||
#include <beast/asio/placeholders.h>
|
||||
#include <beast/placeholders.hpp>
|
||||
#include <ripple/beast/core/WaitableEvent.h>
|
||||
#include <boost/asio.hpp>
|
||||
#include <atomic>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include <ripple/basics/StringUtilities.h>
|
||||
#include <ripple/basics/ToString.h>
|
||||
#include <ripple/beast/core/LexicalCast.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/asio/ip/address.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
#define RIPPLE_BASICS_RANDOM_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/win32_workaround.h>
|
||||
#include <beast/xor_shift_engine.h>
|
||||
#include <beast/is_call_possible.h>
|
||||
#include <ripple/beast/xor_shift_engine.h>
|
||||
#include <beast/detail/is_call_possible.hpp>
|
||||
#include <boost/thread/tss.hpp>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
@@ -50,7 +50,7 @@ namespace detail {
|
||||
// Determines if a type can be called like an Engine
|
||||
template <class Engine, class Result = typename Engine::result_type>
|
||||
using is_engine =
|
||||
beast::is_call_possible<Engine, Result()>;
|
||||
beast::detail::is_call_possible<Engine, Result()>;
|
||||
}
|
||||
|
||||
/** Return the default random engine.
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/basics/CheckLibraryVersions.h>
|
||||
#include <ripple/basics/impl/CheckLibraryVersionsImpl.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace version {
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/basics/chrono.h>
|
||||
#include <ripple/basics/KeyCache.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <beast/clock/manual_clock.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <ripple/beast/clock/manual_clock.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/basics/RangeSet.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/basics/StringUtilities.h>
|
||||
#include <ripple/basics/ToString.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/basics/chrono.h>
|
||||
#include <ripple/basics/TaggedCache.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <beast/clock/manual_clock.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <ripple/beast/clock/manual_clock.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/basics/contract.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <string>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/basics/hardened_hash.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/basics/mulDiv.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace test {
|
||||
|
||||
244
src/ripple/beast/asio/io_latency_probe.h
Normal file
244
src/ripple/beast/asio/io_latency_probe.h
Normal file
@@ -0,0 +1,244 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_ASIO_IO_LATENCY_PROBE_H_INCLUDED
|
||||
#define BEAST_ASIO_IO_LATENCY_PROBE_H_INCLUDED
|
||||
|
||||
#include <boost/asio/deadline_timer.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <chrono>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** Measures handler latency on an io_service queue. */
|
||||
template <class Clock>
|
||||
class io_latency_probe
|
||||
{
|
||||
private:
|
||||
using duration = typename Clock::duration;
|
||||
using time_point = typename Clock::time_point;
|
||||
|
||||
std::recursive_mutex m_mutex;
|
||||
std::condition_variable_any m_cond;
|
||||
std::size_t m_count;
|
||||
duration const m_period;
|
||||
boost::asio::io_service& m_ios;
|
||||
boost::asio::deadline_timer m_timer;
|
||||
bool m_cancel;
|
||||
|
||||
public:
|
||||
io_latency_probe (duration const& period,
|
||||
boost::asio::io_service& ios)
|
||||
: m_count (1)
|
||||
, m_period (period)
|
||||
, m_ios (ios)
|
||||
, m_timer (m_ios)
|
||||
, m_cancel (false)
|
||||
{
|
||||
}
|
||||
|
||||
~io_latency_probe ()
|
||||
{
|
||||
std::unique_lock <decltype (m_mutex)> lock (m_mutex);
|
||||
cancel (lock, true);
|
||||
}
|
||||
|
||||
/** Return the io_service associated with the latency probe. */
|
||||
/** @{ */
|
||||
boost::asio::io_service& get_io_service ()
|
||||
{
|
||||
return m_ios;
|
||||
}
|
||||
|
||||
boost::asio::io_service const& get_io_service () const
|
||||
{
|
||||
return m_ios;
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/** Cancel all pending i/o.
|
||||
Any handlers which have already been queued will still be called.
|
||||
*/
|
||||
/** @{ */
|
||||
void cancel ()
|
||||
{
|
||||
std::unique_lock <decltype(m_mutex)> lock (m_mutex);
|
||||
cancel (lock, true);
|
||||
}
|
||||
|
||||
void cancel_async ()
|
||||
{
|
||||
std::unique_lock <decltype(m_mutex)> lock (m_mutex);
|
||||
cancel (lock, false);
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/** Measure one sample of i/o latency.
|
||||
Handler will be called with this signature:
|
||||
void Handler (Duration d);
|
||||
*/
|
||||
template <class Handler>
|
||||
void sample_one (Handler&& handler)
|
||||
{
|
||||
std::lock_guard <decltype(m_mutex)> lock (m_mutex);
|
||||
if (m_cancel)
|
||||
throw std::logic_error ("io_latency_probe is canceled");
|
||||
m_ios.post (sample_op <Handler> (
|
||||
std::forward <Handler> (handler),
|
||||
Clock::now(), false, this));
|
||||
}
|
||||
|
||||
/** Initiate continuous i/o latency sampling.
|
||||
Handler will be called with this signature:
|
||||
void Handler (std::chrono::milliseconds);
|
||||
*/
|
||||
template <class Handler>
|
||||
void sample (Handler&& handler)
|
||||
{
|
||||
std::lock_guard <decltype(m_mutex)> lock (m_mutex);
|
||||
if (m_cancel)
|
||||
throw std::logic_error ("io_latency_probe is canceled");
|
||||
m_ios.post (sample_op <Handler> (
|
||||
std::forward <Handler> (handler),
|
||||
Clock::now(), true, this));
|
||||
}
|
||||
|
||||
private:
|
||||
void cancel (std::unique_lock <decltype (m_mutex)>& lock,
|
||||
bool wait)
|
||||
{
|
||||
if (! m_cancel)
|
||||
{
|
||||
--m_count;
|
||||
m_cancel = true;
|
||||
}
|
||||
|
||||
if (wait)
|
||||
#ifdef BOOST_NO_CXX11_LAMBDAS
|
||||
while (m_count != 0)
|
||||
m_cond.wait (lock);
|
||||
#else
|
||||
m_cond.wait (lock, [this] {
|
||||
return this->m_count == 0; });
|
||||
#endif
|
||||
}
|
||||
|
||||
void addref ()
|
||||
{
|
||||
std::lock_guard <decltype(m_mutex)> lock (m_mutex);
|
||||
++m_count;
|
||||
}
|
||||
|
||||
void release ()
|
||||
{
|
||||
std::lock_guard <decltype(m_mutex)> lock (m_mutex);
|
||||
if (--m_count == 0)
|
||||
m_cond.notify_all ();
|
||||
}
|
||||
|
||||
template <class Handler>
|
||||
struct sample_op
|
||||
{
|
||||
Handler m_handler;
|
||||
time_point m_start;
|
||||
bool m_repeat;
|
||||
io_latency_probe* m_probe;
|
||||
|
||||
sample_op (Handler const& handler, time_point const& start,
|
||||
bool repeat, io_latency_probe* probe)
|
||||
: m_handler (handler)
|
||||
, m_start (start)
|
||||
, m_repeat (repeat)
|
||||
, m_probe (probe)
|
||||
{
|
||||
m_probe->addref();
|
||||
}
|
||||
|
||||
sample_op (sample_op const& other)
|
||||
: m_handler (other.m_handler)
|
||||
, m_start (other.m_start)
|
||||
, m_probe (other.m_probe)
|
||||
{
|
||||
m_probe->addref();
|
||||
}
|
||||
|
||||
~sample_op ()
|
||||
{
|
||||
m_probe->release();
|
||||
}
|
||||
|
||||
void operator() () const
|
||||
{
|
||||
typename Clock::time_point const now (Clock::now());
|
||||
typename Clock::duration const elapsed (now - m_start);
|
||||
|
||||
m_handler (elapsed);
|
||||
|
||||
{
|
||||
std::lock_guard <decltype (m_probe->m_mutex)
|
||||
> lock (m_probe->m_mutex);
|
||||
if (m_probe->m_cancel)
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_repeat)
|
||||
{
|
||||
// Calculate when we want to sample again, and
|
||||
// adjust for the expected latency.
|
||||
//
|
||||
typename Clock::time_point const when (
|
||||
now + m_probe->m_period - 2 * elapsed);
|
||||
|
||||
if (when <= now)
|
||||
{
|
||||
// The latency is too high to maintain the desired
|
||||
// period so don't bother with a timer.
|
||||
//
|
||||
m_probe->m_ios.post (sample_op <Handler> (
|
||||
m_handler, now, m_repeat, m_probe));
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::posix_time::microseconds mms (
|
||||
std::chrono::duration_cast <
|
||||
std::chrono::microseconds> (
|
||||
when - now).count ());
|
||||
m_probe->m_timer.expires_from_now (mms);
|
||||
m_probe->m_timer.async_wait (sample_op <Handler> (
|
||||
m_handler, now, m_repeat, m_probe));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void operator () (boost::system::error_code const& ec)
|
||||
{
|
||||
typename Clock::time_point const now (Clock::now());
|
||||
m_probe->m_ios.post (sample_op <Handler> (
|
||||
m_handler, now, m_repeat, m_probe));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
71
src/ripple/beast/asio/ssl_bundle.h
Normal file
71
src/ripple/beast/asio/ssl_bundle.h
Normal file
@@ -0,0 +1,71 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_ASIO_SSL_BUNDLE_H_INCLUDED
|
||||
#define BEAST_ASIO_SSL_BUNDLE_H_INCLUDED
|
||||
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/ssl/context.hpp>
|
||||
#include <boost/asio/ssl/stream.hpp>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
/** Work-around for non-movable boost::ssl::stream.
|
||||
This allows ssl::stream to be movable and allows the stream to
|
||||
construct from an already-existing socket.
|
||||
*/
|
||||
struct ssl_bundle
|
||||
{
|
||||
using socket_type = boost::asio::ip::tcp::socket;
|
||||
using stream_type = boost::asio::ssl::stream <socket_type&>;
|
||||
using shared_context = std::shared_ptr<boost::asio::ssl::context>;
|
||||
|
||||
template <class... Args>
|
||||
ssl_bundle (shared_context const& context_, Args&&... args);
|
||||
|
||||
// DEPRECATED
|
||||
template <class... Args>
|
||||
ssl_bundle (boost::asio::ssl::context& context_, Args&&... args);
|
||||
|
||||
shared_context context;
|
||||
socket_type socket;
|
||||
stream_type stream;
|
||||
};
|
||||
|
||||
template <class... Args>
|
||||
ssl_bundle::ssl_bundle (shared_context const& context_, Args&&... args)
|
||||
: socket(std::forward<Args>(args)...)
|
||||
, stream (socket, *context_)
|
||||
{
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
ssl_bundle::ssl_bundle (boost::asio::ssl::context& context_, Args&&... args)
|
||||
: socket(std::forward<Args>(args)...)
|
||||
, stream (socket, context_)
|
||||
{
|
||||
}
|
||||
|
||||
} // asio
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
72
src/ripple/beast/asio/ssl_error.h
Normal file
72
src/ripple/beast/asio/ssl_error.h
Normal file
@@ -0,0 +1,72 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_ASIO_SSL_ERROR_H_INCLUDED
|
||||
#define BEAST_ASIO_SSL_ERROR_H_INCLUDED
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
//#include <boost/asio/error.hpp> // Causes error with WinSock.h
|
||||
#include <boost/asio/ssl/error.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** Returns a human readable message if the error code is SSL related. */
|
||||
template<class = void>
|
||||
std::string
|
||||
error_message_with_ssl(boost::system::error_code const& ec)
|
||||
{
|
||||
std::string error;
|
||||
|
||||
if (ec.category() == boost::asio::error::get_ssl_category())
|
||||
{
|
||||
error = " ("
|
||||
+ boost::lexical_cast<std::string>(ERR_GET_LIB (ec.value ()))
|
||||
+ ","
|
||||
+ boost::lexical_cast<std::string>(ERR_GET_FUNC (ec.value ()))
|
||||
+ ","
|
||||
+ boost::lexical_cast<std::string>(ERR_GET_REASON (ec.value ()))
|
||||
+ ") ";
|
||||
|
||||
// This buffer must be at least 120 bytes, most examples use 256.
|
||||
// https://www.openssl.org/docs/crypto/ERR_error_string.html
|
||||
char buf[256];
|
||||
::ERR_error_string_n(ec.value (), buf, sizeof(buf));
|
||||
error += buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
error = ec.message();
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/** Returns `true` if the error code is a SSL "short read." */
|
||||
inline
|
||||
bool
|
||||
is_short_read(boost::system::error_code const& ec)
|
||||
{
|
||||
return (ec.category() == boost::asio::error::get_ssl_category())
|
||||
&& (ERR_GET_REASON(ec.value()) == SSL_R_SHORT_READ);
|
||||
}
|
||||
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
111
src/ripple/beast/clock/abstract_clock.h
Normal file
111
src/ripple/beast/clock/abstract_clock.h
Normal file
@@ -0,0 +1,111 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_CHRONO_ABSTRACT_CLOCK_H_INCLUDED
|
||||
#define BEAST_CHRONO_ABSTRACT_CLOCK_H_INCLUDED
|
||||
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** Abstract interface to a clock.
|
||||
|
||||
This makes now() a member function instead of a static member, so
|
||||
an instance of the class can be dependency injected, facilitating
|
||||
unit tests where time may be controlled.
|
||||
|
||||
An abstract_clock inherits all the nested types of the Clock
|
||||
template parameter.
|
||||
|
||||
Example:
|
||||
|
||||
@code
|
||||
|
||||
struct Implementation
|
||||
{
|
||||
using clock_type = abstract_clock <std::chrono::steady_clock>;
|
||||
clock_type& clock_;
|
||||
explicit Implementation (clock_type& clock)
|
||||
: clock_(clock)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
@endcode
|
||||
|
||||
@tparam Clock A type meeting these requirements:
|
||||
http://en.cppreference.com/w/cpp/concept/Clock
|
||||
*/
|
||||
template <class Clock>
|
||||
class abstract_clock
|
||||
{
|
||||
public:
|
||||
using rep = typename Clock::rep;
|
||||
using period = typename Clock::period;
|
||||
using duration = typename Clock::duration;
|
||||
using time_point = typename Clock::time_point;
|
||||
using clock_type = Clock;
|
||||
|
||||
static bool const is_steady = Clock::is_steady;
|
||||
|
||||
virtual ~abstract_clock() = default;
|
||||
|
||||
/** Returns the current time. */
|
||||
virtual time_point now() const = 0;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class Facade, class Clock>
|
||||
struct abstract_clock_wrapper
|
||||
: public abstract_clock<Facade>
|
||||
{
|
||||
using typename abstract_clock<Facade>::duration;
|
||||
using typename abstract_clock<Facade>::time_point;
|
||||
|
||||
time_point
|
||||
now() const override
|
||||
{
|
||||
return Clock::now();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Returns a global instance of an abstract clock.
|
||||
@tparam Facade A type meeting these requirements:
|
||||
http://en.cppreference.com/w/cpp/concept/Clock
|
||||
@tparam Clock The actual concrete clock to use.
|
||||
*/
|
||||
template<class Facade, class Clock = Facade>
|
||||
abstract_clock<Facade>&
|
||||
get_abstract_clock()
|
||||
{
|
||||
static detail::abstract_clock_wrapper<Facade, Clock> clock;
|
||||
return clock;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
217
src/ripple/beast/clock/basic_seconds_clock.h
Normal file
217
src/ripple/beast/clock/basic_seconds_clock.h
Normal file
@@ -0,0 +1,217 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_CHRONO_BASIC_SECONDS_CLOCK_H_INCLUDED
|
||||
#define BEAST_CHRONO_BASIC_SECONDS_CLOCK_H_INCLUDED
|
||||
|
||||
#include <ripple/beast/clock/chrono_util.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
namespace beast {
|
||||
|
||||
namespace detail {
|
||||
|
||||
class seconds_clock_worker
|
||||
{
|
||||
public:
|
||||
virtual void sample () = 0;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Updates the clocks
|
||||
class seconds_clock_thread
|
||||
{
|
||||
public:
|
||||
using mutex = std::mutex;
|
||||
using cond_var = std::condition_variable;
|
||||
using lock_guard = std::lock_guard <mutex>;
|
||||
using unique_lock = std::unique_lock <mutex>;
|
||||
using clock_type = std::chrono::steady_clock;
|
||||
using seconds = std::chrono::seconds;
|
||||
using thread = std::thread;
|
||||
using workers = std::vector <seconds_clock_worker*>;
|
||||
|
||||
bool stop_;
|
||||
mutex mutex_;
|
||||
cond_var cond_;
|
||||
workers workers_;
|
||||
thread thread_;
|
||||
|
||||
seconds_clock_thread ()
|
||||
: stop_ (false)
|
||||
{
|
||||
thread_ = thread (std::bind(
|
||||
&seconds_clock_thread::run, this));
|
||||
}
|
||||
|
||||
~seconds_clock_thread ()
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
void add (seconds_clock_worker& w)
|
||||
{
|
||||
lock_guard lock (mutex_);
|
||||
workers_.push_back (&w);
|
||||
}
|
||||
|
||||
void remove (seconds_clock_worker& w)
|
||||
{
|
||||
lock_guard lock (mutex_);
|
||||
workers_.erase (std::find (
|
||||
workers_.begin (), workers_.end(), &w));
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
if (thread_.joinable())
|
||||
{
|
||||
{
|
||||
lock_guard lock (mutex_);
|
||||
stop_ = true;
|
||||
}
|
||||
cond_.notify_all();
|
||||
thread_.join();
|
||||
}
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
unique_lock lock (mutex_);;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
for (auto iter : workers_)
|
||||
iter->sample();
|
||||
|
||||
using namespace std::chrono;
|
||||
clock_type::time_point const when (
|
||||
floor <seconds> (
|
||||
clock_type::now().time_since_epoch()) +
|
||||
seconds (1));
|
||||
|
||||
if (cond_.wait_until (lock, when, [this]{ return stop_; }))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static seconds_clock_thread& instance ()
|
||||
{
|
||||
static seconds_clock_thread singleton;
|
||||
return singleton;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Called before main exits to terminate the utility thread.
|
||||
This is a workaround for Visual Studio 2013:
|
||||
http://connect.microsoft.com/VisualStudio/feedback/details/786016/creating-a-global-c-object-that-used-thread-join-in-its-destructor-causes-a-lockup
|
||||
http://stackoverflow.com/questions/10915233/stdthreadjoin-hangs-if-called-after-main-exits-when-using-vs2012-rc
|
||||
*/
|
||||
inline
|
||||
void
|
||||
basic_seconds_clock_main_hook()
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
detail::seconds_clock_thread::instance().stop();
|
||||
#endif
|
||||
}
|
||||
|
||||
/** A clock whose minimum resolution is one second.
|
||||
|
||||
The purpose of this class is to optimize the performance of the now()
|
||||
member function call. It uses a dedicated thread that wakes up at least
|
||||
once per second to sample the requested trivial clock.
|
||||
|
||||
@tparam Clock A type meeting these requirements:
|
||||
http://en.cppreference.com/w/cpp/concept/Clock
|
||||
*/
|
||||
template <class Clock>
|
||||
class basic_seconds_clock
|
||||
{
|
||||
public:
|
||||
using rep = typename Clock::rep;
|
||||
using period = typename Clock::period;
|
||||
using duration = typename Clock::duration;
|
||||
using time_point = typename Clock::time_point;
|
||||
|
||||
static bool const is_steady = Clock::is_steady;
|
||||
|
||||
static time_point now()
|
||||
{
|
||||
// Make sure the thread is constructed before the
|
||||
// worker otherwise we will crash during destruction
|
||||
// of objects with static storage duration.
|
||||
struct initializer
|
||||
{
|
||||
initializer ()
|
||||
{
|
||||
detail::seconds_clock_thread::instance();
|
||||
}
|
||||
};
|
||||
static initializer init;
|
||||
|
||||
struct worker : detail::seconds_clock_worker
|
||||
{
|
||||
time_point m_now;
|
||||
std::mutex mutex_;
|
||||
|
||||
worker()
|
||||
: m_now(Clock::now())
|
||||
{
|
||||
detail::seconds_clock_thread::instance().add(*this);
|
||||
}
|
||||
|
||||
~worker()
|
||||
{
|
||||
detail::seconds_clock_thread::instance().remove(*this);
|
||||
}
|
||||
|
||||
time_point now()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex_);
|
||||
return m_now;
|
||||
}
|
||||
|
||||
void sample()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex_);
|
||||
m_now = Clock::now();
|
||||
}
|
||||
};
|
||||
|
||||
static worker w;
|
||||
|
||||
return w.now();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
68
src/ripple/beast/clock/chrono_util.h
Normal file
68
src/ripple/beast/clock/chrono_util.h
Normal file
@@ -0,0 +1,68 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_CHRONO_CHRONO_UTIL_H_INCLUDED
|
||||
#define BEAST_CHRONO_CHRONO_UTIL_H_INCLUDED
|
||||
|
||||
// From Howard Hinnant
|
||||
// http://home.roadrunner.com/~hinnant/duration_io/chrono_util.html
|
||||
|
||||
#if !defined(_MSC_FULL_VER) || (_MSC_FULL_VER <= 190023506)
|
||||
// round down
|
||||
template <class To, class Rep, class Period>
|
||||
To floor(std::chrono::duration <Rep, Period> const& d)
|
||||
{
|
||||
To t = std::chrono::duration_cast<To>(d);
|
||||
if (t > d)
|
||||
--t;
|
||||
return t;
|
||||
}
|
||||
|
||||
// round to nearest, to even on tie
|
||||
template <class To, class Rep, class Period>
|
||||
To round (std::chrono::duration <Rep, Period> const& d)
|
||||
{
|
||||
To t0 = std::chrono::duration_cast<To>(d);
|
||||
To t1 = t0;
|
||||
++t1;
|
||||
auto diff0 = d - t0;
|
||||
auto diff1 = t1 - d;
|
||||
if (diff0 == diff1)
|
||||
{
|
||||
if (t0.count() & 1)
|
||||
return t1;
|
||||
return t0;
|
||||
}
|
||||
else if (diff0 < diff1)
|
||||
return t0;
|
||||
return t1;
|
||||
}
|
||||
|
||||
// round up
|
||||
template <class To, class Rep, class Period>
|
||||
To ceil (std::chrono::duration <Rep, Period> const& d)
|
||||
{
|
||||
To t = std::chrono::duration_cast<To>(d);
|
||||
if (t < d)
|
||||
++t;
|
||||
return t;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
100
src/ripple/beast/clock/manual_clock.h
Normal file
100
src/ripple/beast/clock/manual_clock.h
Normal file
@@ -0,0 +1,100 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_CHRONO_MANUAL_CLOCK_H_INCLUDED
|
||||
#define BEAST_CHRONO_MANUAL_CLOCK_H_INCLUDED
|
||||
|
||||
#include <ripple/beast/clock/abstract_clock.h>
|
||||
#include <cassert>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** Manual clock implementation.
|
||||
|
||||
This concrete class implements the @ref abstract_clock interface and
|
||||
allows the time to be advanced manually, mainly for the purpose of
|
||||
providing a clock in unit tests.
|
||||
|
||||
@tparam Clock A type meeting these requirements:
|
||||
http://en.cppreference.com/w/cpp/concept/Clock
|
||||
*/
|
||||
template <class Clock>
|
||||
class manual_clock
|
||||
: public abstract_clock<Clock>
|
||||
{
|
||||
public:
|
||||
using typename abstract_clock<Clock>::rep;
|
||||
using typename abstract_clock<Clock>::duration;
|
||||
using typename abstract_clock<Clock>::time_point;
|
||||
|
||||
private:
|
||||
time_point now_;
|
||||
|
||||
public:
|
||||
explicit
|
||||
manual_clock (time_point const& now = time_point(duration(0)))
|
||||
: now_(now)
|
||||
{
|
||||
}
|
||||
|
||||
time_point
|
||||
now() const override
|
||||
{
|
||||
return now_;
|
||||
}
|
||||
|
||||
/** Set the current time of the manual clock. */
|
||||
void
|
||||
set (time_point const& when)
|
||||
{
|
||||
assert(! Clock::is_steady || when >= now_);
|
||||
now_ = when;
|
||||
}
|
||||
|
||||
/** Convenience for setting the time in seconds from epoch. */
|
||||
template <class Integer>
|
||||
void
|
||||
set(Integer seconds_from_epoch)
|
||||
{
|
||||
set(time_point(duration(
|
||||
std::chrono::seconds(seconds_from_epoch))));
|
||||
}
|
||||
|
||||
/** Advance the clock by a duration. */
|
||||
template <class Rep, class Period>
|
||||
void
|
||||
advance(std::chrono::duration<Rep, Period> const& elapsed)
|
||||
{
|
||||
assert(! Clock::is_steady ||
|
||||
(now_ + elapsed) >= now_);
|
||||
now_ += elapsed;
|
||||
}
|
||||
|
||||
/** Convenience for advancing the clock by one second. */
|
||||
manual_clock&
|
||||
operator++ ()
|
||||
{
|
||||
advance(std::chrono::seconds(1));
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
93
src/ripple/beast/clock/tests/beast_abstract_clock_test.cpp
Normal file
93
src/ripple/beast/clock/tests/beast_abstract_clock_test.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
// MODULES: ../impl/chrono_io.cpp
|
||||
|
||||
#include <ripple/beast/clock/abstract_clock.h>
|
||||
#include <ripple/beast/clock/manual_clock.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
namespace beast {
|
||||
|
||||
class abstract_clock_test : public unit_test::suite
|
||||
{
|
||||
public:
|
||||
template <class Clock>
|
||||
void test (abstract_clock<Clock>& c)
|
||||
{
|
||||
{
|
||||
auto const t1 (c.now ());
|
||||
std::this_thread::sleep_for (
|
||||
std::chrono::milliseconds (1500));
|
||||
auto const t2 (c.now ());
|
||||
|
||||
std::stringstream ss;
|
||||
ss <<
|
||||
"t1= " << t1.time_since_epoch().count() <<
|
||||
", t2= " << t2.time_since_epoch().count() <<
|
||||
", elapsed= " << (t2 - t1).count();
|
||||
log << ss.str();
|
||||
}
|
||||
}
|
||||
|
||||
void test_manual ()
|
||||
{
|
||||
using clock_type = manual_clock<std::chrono::steady_clock>;
|
||||
clock_type c;
|
||||
|
||||
std::stringstream ss;
|
||||
|
||||
ss << "now() = " << c.now().time_since_epoch().count() << std::endl;
|
||||
|
||||
c.set (clock_type::time_point (std::chrono::seconds(1)));
|
||||
ss << "now() = " << c.now().time_since_epoch().count() << std::endl;
|
||||
|
||||
c.set (clock_type::time_point (std::chrono::seconds(2)));
|
||||
ss << "now() = " << c.now().time_since_epoch().count() << std::endl;
|
||||
|
||||
log << ss.str();
|
||||
}
|
||||
|
||||
void run ()
|
||||
{
|
||||
log << "steady_clock";
|
||||
test (get_abstract_clock<
|
||||
std::chrono::steady_clock>());
|
||||
|
||||
log << "system_clock";
|
||||
test (get_abstract_clock<
|
||||
std::chrono::system_clock>());
|
||||
|
||||
log << "high_resolution_clock";
|
||||
test (get_abstract_clock<
|
||||
std::chrono::high_resolution_clock>());
|
||||
|
||||
log << "manual_clock";
|
||||
test_manual ();
|
||||
|
||||
pass ();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE_MANUAL(abstract_clock,chrono,beast);
|
||||
|
||||
}
|
||||
@@ -17,47 +17,24 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/beast/net/URL.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
|
||||
#include <ripple/beast/clock/basic_seconds_clock.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
class URL_test : public unit_test::suite
|
||||
class basic_seconds_clock_test : public unit_test::suite
|
||||
{
|
||||
public:
|
||||
void check_url_parsing (std::string const& url, bool expected)
|
||||
{
|
||||
auto result = parse_URL (url);
|
||||
|
||||
expect (result.first == expected,
|
||||
(expected ? "Failed to parse " : "Succeeded in parsing ") + url);
|
||||
expect (to_string (result.second) == url);
|
||||
}
|
||||
|
||||
void test_url_parsing ()
|
||||
{
|
||||
char const* const urls[] =
|
||||
{
|
||||
"http://en.wikipedia.org/wiki/URI#Examples_of_URI_references",
|
||||
"ftp://ftp.funet.fi/pub/standards/RFC/rfc959.txt"
|
||||
"ftp://test:test@example.com:21/path/specifier/is/here"
|
||||
"http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference.html",
|
||||
"foo://username:password@example.com:8042/over/there/index.dtb?type=animal&name=narwhal#nose",
|
||||
};
|
||||
|
||||
testcase ("URL parsing");
|
||||
|
||||
for (auto url : urls)
|
||||
check_url_parsing (url, true);
|
||||
}
|
||||
|
||||
void
|
||||
run ()
|
||||
run()
|
||||
{
|
||||
test_url_parsing ();
|
||||
basic_seconds_clock <
|
||||
std::chrono::steady_clock>::now ();
|
||||
pass ();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(URL,http,beast);
|
||||
BEAST_DEFINE_TESTSUITE(basic_seconds_clock,chrono,beast);
|
||||
|
||||
}
|
||||
@@ -23,8 +23,8 @@
|
||||
#include <ripple/beast/container/detail/aged_container_iterator.h>
|
||||
#include <ripple/beast/container/detail/aged_associative_container.h>
|
||||
#include <ripple/beast/container/aged_container.h>
|
||||
#include <beast/clock/abstract_clock.h>
|
||||
#include <beast/empty_base_optimization.h>
|
||||
#include <ripple/beast/clock/abstract_clock.h>
|
||||
#include <beast/detail/empty_base_optimization.hpp>
|
||||
#include <boost/intrusive/list.hpp>
|
||||
#include <boost/intrusive/set.hpp>
|
||||
#include <boost/version.hpp>
|
||||
@@ -33,7 +33,7 @@
|
||||
#include <initializer_list>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <beast/cxx17/type_traits.h> // <type_traits>
|
||||
#include <ripple/beast/cxx17/type_traits.h> // <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace beast {
|
||||
@@ -445,13 +445,13 @@ public:
|
||||
|
||||
// A set iterator (IsMap==false) is always const
|
||||
// because the elements of a set are immutable.
|
||||
using iterator = detail::aged_container_iterator<
|
||||
using iterator = beast::detail::aged_container_iterator<
|
||||
! IsMap, typename cont_type::iterator>;
|
||||
using const_iterator = detail::aged_container_iterator<
|
||||
using const_iterator = beast::detail::aged_container_iterator<
|
||||
true, typename cont_type::iterator>;
|
||||
using reverse_iterator = detail::aged_container_iterator<
|
||||
using reverse_iterator = beast::detail::aged_container_iterator<
|
||||
! IsMap, typename cont_type::reverse_iterator>;
|
||||
using const_reverse_iterator = detail::aged_container_iterator<
|
||||
using const_reverse_iterator = beast::detail::aged_container_iterator<
|
||||
true, typename cont_type::reverse_iterator>;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -468,13 +468,13 @@ public:
|
||||
public:
|
||||
// A set iterator (IsMap==false) is always const
|
||||
// because the elements of a set are immutable.
|
||||
using iterator = detail::aged_container_iterator<
|
||||
using iterator = beast::detail::aged_container_iterator<
|
||||
! IsMap, typename list_type::iterator>;
|
||||
using const_iterator = detail::aged_container_iterator<
|
||||
using const_iterator = beast::detail::aged_container_iterator<
|
||||
true, typename list_type::iterator>;
|
||||
using reverse_iterator = detail::aged_container_iterator<
|
||||
using reverse_iterator = beast::detail::aged_container_iterator<
|
||||
! IsMap, typename list_type::reverse_iterator>;
|
||||
using const_reverse_iterator = detail::aged_container_iterator<
|
||||
using const_reverse_iterator = beast::detail::aged_container_iterator<
|
||||
true, typename list_type::reverse_iterator>;
|
||||
|
||||
iterator begin ()
|
||||
@@ -966,16 +966,16 @@ public:
|
||||
// enable_if prevents erase (reverse_iterator pos) from compiling
|
||||
template <bool is_const, class Iterator, class Base,
|
||||
class = std::enable_if_t<!is_boost_reverse_iterator<Iterator>::value>>
|
||||
detail::aged_container_iterator <false, Iterator, Base>
|
||||
erase (detail::aged_container_iterator <is_const, Iterator, Base> pos);
|
||||
beast::detail::aged_container_iterator <false, Iterator, Base>
|
||||
erase (beast::detail::aged_container_iterator <is_const, Iterator, Base> pos);
|
||||
|
||||
// enable_if prevents erase (reverse_iterator first, reverse_iterator last)
|
||||
// from compiling
|
||||
template <bool is_const, class Iterator, class Base,
|
||||
class = std::enable_if_t<!is_boost_reverse_iterator<Iterator>::value>>
|
||||
detail::aged_container_iterator <false, Iterator, Base>
|
||||
erase (detail::aged_container_iterator <is_const, Iterator, Base> first,
|
||||
detail::aged_container_iterator <is_const, Iterator, Base> last);
|
||||
beast::detail::aged_container_iterator <false, Iterator, Base>
|
||||
erase (beast::detail::aged_container_iterator <is_const, Iterator, Base> first,
|
||||
beast::detail::aged_container_iterator <is_const, Iterator, Base> last);
|
||||
|
||||
template <class K>
|
||||
auto
|
||||
@@ -991,7 +991,7 @@ public:
|
||||
template <bool is_const, class Iterator, class Base,
|
||||
class = std::enable_if_t<!is_boost_reverse_iterator<Iterator>::value>>
|
||||
void
|
||||
touch (detail::aged_container_iterator <is_const, Iterator, Base> pos)
|
||||
touch (beast::detail::aged_container_iterator <is_const, Iterator, Base> pos)
|
||||
{
|
||||
touch (pos, clock().now());
|
||||
}
|
||||
@@ -1220,7 +1220,7 @@ private:
|
||||
template <bool is_const, class Iterator, class Base,
|
||||
class = std::enable_if_t<!is_boost_reverse_iterator<Iterator>::value>>
|
||||
void
|
||||
touch (detail::aged_container_iterator <
|
||||
touch (beast::detail::aged_container_iterator <
|
||||
is_const, Iterator, Base> pos,
|
||||
typename clock_type::time_point const& now);
|
||||
|
||||
@@ -1768,27 +1768,27 @@ emplace_hint (const_iterator hint, Args&&... args) ->
|
||||
template <bool IsMulti, bool IsMap, class Key, class T,
|
||||
class Clock, class Compare, class Allocator>
|
||||
template <bool is_const, class Iterator, class Base, class>
|
||||
detail::aged_container_iterator <false, Iterator, Base>
|
||||
beast::detail::aged_container_iterator <false, Iterator, Base>
|
||||
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
|
||||
erase (detail::aged_container_iterator <is_const, Iterator, Base> pos)
|
||||
erase (beast::detail::aged_container_iterator <is_const, Iterator, Base> pos)
|
||||
{
|
||||
unlink_and_delete_element(&*((pos++).iterator()));
|
||||
return detail::aged_container_iterator <
|
||||
return beast::detail::aged_container_iterator <
|
||||
false, Iterator, Base> (pos.iterator());
|
||||
}
|
||||
|
||||
template <bool IsMulti, bool IsMap, class Key, class T,
|
||||
class Clock, class Compare, class Allocator>
|
||||
template <bool is_const, class Iterator, class Base, class>
|
||||
detail::aged_container_iterator <false, Iterator, Base>
|
||||
beast::detail::aged_container_iterator <false, Iterator, Base>
|
||||
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
|
||||
erase (detail::aged_container_iterator <is_const, Iterator, Base> first,
|
||||
detail::aged_container_iterator <is_const, Iterator, Base> last)
|
||||
erase (beast::detail::aged_container_iterator <is_const, Iterator, Base> first,
|
||||
beast::detail::aged_container_iterator <is_const, Iterator, Base> last)
|
||||
{
|
||||
for (; first != last;)
|
||||
unlink_and_delete_element(&*((first++).iterator()));
|
||||
|
||||
return detail::aged_container_iterator <
|
||||
return beast::detail::aged_container_iterator <
|
||||
false, Iterator, Base> (first.iterator());
|
||||
}
|
||||
|
||||
@@ -1884,7 +1884,7 @@ template <bool IsMulti, bool IsMap, class Key, class T,
|
||||
template <bool is_const, class Iterator, class Base, class>
|
||||
void
|
||||
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
|
||||
touch (detail::aged_container_iterator <
|
||||
touch (beast::detail::aged_container_iterator <
|
||||
is_const, Iterator, Base> pos,
|
||||
typename clock_type::time_point const& now)
|
||||
{
|
||||
@@ -1923,7 +1923,7 @@ swap_data (aged_ordered_container& other) noexcept
|
||||
|
||||
template <bool IsMulti, bool IsMap, class Key, class T,
|
||||
class Clock, class Compare, class Allocator>
|
||||
struct is_aged_container <detail::aged_ordered_container <
|
||||
struct is_aged_container <beast::detail::aged_ordered_container <
|
||||
IsMulti, IsMap, Key, T, Clock, Compare, Allocator>>
|
||||
: std::true_type
|
||||
{
|
||||
@@ -1934,9 +1934,9 @@ struct is_aged_container <detail::aged_ordered_container <
|
||||
template <bool IsMulti, bool IsMap, class Key, class T,
|
||||
class Clock, class Compare, class Allocator>
|
||||
void swap (
|
||||
detail::aged_ordered_container <IsMulti, IsMap,
|
||||
beast::detail::aged_ordered_container <IsMulti, IsMap,
|
||||
Key, T, Clock, Compare, Allocator>& lhs,
|
||||
detail::aged_ordered_container <IsMulti, IsMap,
|
||||
beast::detail::aged_ordered_container <IsMulti, IsMap,
|
||||
Key, T, Clock, Compare, Allocator>& rhs) noexcept
|
||||
{
|
||||
lhs.swap (rhs);
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
#include <ripple/beast/container/detail/aged_container_iterator.h>
|
||||
#include <ripple/beast/container/detail/aged_associative_container.h>
|
||||
#include <ripple/beast/container/aged_container.h>
|
||||
#include <beast/clock/abstract_clock.h>
|
||||
#include <beast/empty_base_optimization.h>
|
||||
#include <ripple/beast/clock/abstract_clock.h>
|
||||
#include <beast/detail/empty_base_optimization.hpp>
|
||||
#include <boost/intrusive/list.hpp>
|
||||
#include <boost/intrusive/unordered_set.hpp>
|
||||
#include <algorithm>
|
||||
@@ -618,14 +618,14 @@ public:
|
||||
|
||||
// A set iterator (IsMap==false) is always const
|
||||
// because the elements of a set are immutable.
|
||||
using iterator= detail::aged_container_iterator <!IsMap,
|
||||
using iterator= beast::detail::aged_container_iterator <!IsMap,
|
||||
typename cont_type::iterator>;
|
||||
using const_iterator = detail::aged_container_iterator <true,
|
||||
using const_iterator = beast::detail::aged_container_iterator <true,
|
||||
typename cont_type::iterator>;
|
||||
|
||||
using local_iterator = detail::aged_container_iterator <!IsMap,
|
||||
using local_iterator = beast::detail::aged_container_iterator <!IsMap,
|
||||
typename cont_type::local_iterator>;
|
||||
using const_local_iterator = detail::aged_container_iterator <true,
|
||||
using const_local_iterator = beast::detail::aged_container_iterator <true,
|
||||
typename cont_type::local_iterator>;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -642,13 +642,13 @@ public:
|
||||
public:
|
||||
// A set iterator (IsMap==false) is always const
|
||||
// because the elements of a set are immutable.
|
||||
using iterator = detail::aged_container_iterator <
|
||||
using iterator = beast::detail::aged_container_iterator <
|
||||
! IsMap, typename list_type::iterator>;
|
||||
using const_iterator = detail::aged_container_iterator <
|
||||
using const_iterator = beast::detail::aged_container_iterator <
|
||||
true, typename list_type::iterator>;
|
||||
using reverse_iterator = detail::aged_container_iterator <
|
||||
using reverse_iterator = beast::detail::aged_container_iterator <
|
||||
! IsMap, typename list_type::reverse_iterator>;
|
||||
using const_reverse_iterator = detail::aged_container_iterator <
|
||||
using const_reverse_iterator = beast::detail::aged_container_iterator <
|
||||
true, typename list_type::reverse_iterator>;
|
||||
|
||||
iterator begin ()
|
||||
@@ -1143,15 +1143,15 @@ public:
|
||||
}
|
||||
|
||||
template <bool is_const, class Iterator, class Base>
|
||||
detail::aged_container_iterator <false, Iterator, Base>
|
||||
erase (detail::aged_container_iterator <
|
||||
beast::detail::aged_container_iterator <false, Iterator, Base>
|
||||
erase (beast::detail::aged_container_iterator <
|
||||
is_const, Iterator, Base> pos);
|
||||
|
||||
template <bool is_const, class Iterator, class Base>
|
||||
detail::aged_container_iterator <false, Iterator, Base>
|
||||
erase (detail::aged_container_iterator <
|
||||
beast::detail::aged_container_iterator <false, Iterator, Base>
|
||||
erase (beast::detail::aged_container_iterator <
|
||||
is_const, Iterator, Base> first,
|
||||
detail::aged_container_iterator <
|
||||
beast::detail::aged_container_iterator <
|
||||
is_const, Iterator, Base> last);
|
||||
|
||||
template <class K>
|
||||
@@ -1164,7 +1164,7 @@ public:
|
||||
|
||||
template <bool is_const, class Iterator, class Base>
|
||||
void
|
||||
touch (detail::aged_container_iterator <
|
||||
touch (beast::detail::aged_container_iterator <
|
||||
is_const, Iterator, Base> pos)
|
||||
{
|
||||
touch (pos, clock().now());
|
||||
@@ -1459,7 +1459,7 @@ private:
|
||||
|
||||
template <bool is_const, class Iterator, class Base>
|
||||
void
|
||||
touch (detail::aged_container_iterator <
|
||||
touch (beast::detail::aged_container_iterator <
|
||||
is_const, Iterator, Base> pos,
|
||||
typename clock_type::time_point const& now)
|
||||
{
|
||||
@@ -2297,32 +2297,32 @@ emplace_hint (const_iterator /*hint*/, Args&&... args) ->
|
||||
template <bool IsMulti, bool IsMap, class Key, class T,
|
||||
class Clock, class Hash, class KeyEqual, class Allocator>
|
||||
template <bool is_const, class Iterator, class Base>
|
||||
detail::aged_container_iterator <false, Iterator, Base>
|
||||
beast::detail::aged_container_iterator <false, Iterator, Base>
|
||||
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
|
||||
Hash, KeyEqual, Allocator>::
|
||||
erase (detail::aged_container_iterator <
|
||||
erase (beast::detail::aged_container_iterator <
|
||||
is_const, Iterator, Base> pos)
|
||||
{
|
||||
unlink_and_delete_element(&*((pos++).iterator()));
|
||||
return detail::aged_container_iterator <
|
||||
return beast::detail::aged_container_iterator <
|
||||
false, Iterator, Base> (pos.iterator());
|
||||
}
|
||||
|
||||
template <bool IsMulti, bool IsMap, class Key, class T,
|
||||
class Clock, class Hash, class KeyEqual, class Allocator>
|
||||
template <bool is_const, class Iterator, class Base>
|
||||
detail::aged_container_iterator <false, Iterator, Base>
|
||||
beast::detail::aged_container_iterator <false, Iterator, Base>
|
||||
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
|
||||
Hash, KeyEqual, Allocator>::
|
||||
erase (detail::aged_container_iterator <
|
||||
erase (beast::detail::aged_container_iterator <
|
||||
is_const, Iterator, Base> first,
|
||||
detail::aged_container_iterator <
|
||||
beast::detail::aged_container_iterator <
|
||||
is_const, Iterator, Base> last)
|
||||
{
|
||||
for (; first != last;)
|
||||
unlink_and_delete_element(&*((first++).iterator()));
|
||||
|
||||
return detail::aged_container_iterator <
|
||||
return beast::detail::aged_container_iterator <
|
||||
false, Iterator, Base> (first.iterator());
|
||||
}
|
||||
|
||||
@@ -2510,7 +2510,7 @@ insert_unchecked (value_type const& value) ->
|
||||
|
||||
template <bool IsMulti, bool IsMap, class Key, class T,
|
||||
class Clock, class Hash, class KeyEqual, class Allocator>
|
||||
struct is_aged_container <detail::aged_unordered_container <
|
||||
struct is_aged_container <beast::detail::aged_unordered_container <
|
||||
IsMulti, IsMap, Key, T, Clock, Hash, KeyEqual, Allocator>>
|
||||
: std::true_type
|
||||
{
|
||||
@@ -2521,9 +2521,9 @@ struct is_aged_container <detail::aged_unordered_container <
|
||||
template <bool IsMulti, bool IsMap, class Key, class T, class Clock,
|
||||
class Hash, class KeyEqual, class Allocator>
|
||||
void swap (
|
||||
detail::aged_unordered_container <IsMulti, IsMap,
|
||||
beast::detail::aged_unordered_container <IsMulti, IsMap,
|
||||
Key, T, Clock, Hash, KeyEqual, Allocator>& lhs,
|
||||
detail::aged_unordered_container <IsMulti, IsMap,
|
||||
beast::detail::aged_unordered_container <IsMulti, IsMap,
|
||||
Key, T, Clock, Hash, KeyEqual, Allocator>& rhs) noexcept
|
||||
{
|
||||
lhs.swap (rhs);
|
||||
@@ -2533,7 +2533,7 @@ void swap (
|
||||
template <bool IsMulti, bool IsMap, class Key, class T,
|
||||
class Clock, class Hash, class KeyEqual, class Allocator,
|
||||
class Rep, class Period>
|
||||
std::size_t expire (detail::aged_unordered_container <
|
||||
std::size_t expire (beast::detail::aged_unordered_container <
|
||||
IsMulti, IsMap, Key, T, Clock, Hash, KeyEqual, Allocator>& c,
|
||||
std::chrono::duration <Rep, Period> const& age) noexcept
|
||||
{
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/clock/manual_clock.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <ripple/beast/clock/manual_clock.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
|
||||
#include <ripple/beast/container/aged_set.h>
|
||||
#include <ripple/beast/container/aged_map.h>
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <beast/xor_shift_engine.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <ripple/beast/xor_shift_engine.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ class ListIterator : public std::iterator <
|
||||
std::bidirectional_iterator_tag, std::size_t>
|
||||
{
|
||||
public:
|
||||
using value_type = typename detail::CopyConst <
|
||||
using value_type = typename beast::detail::CopyConst <
|
||||
N, typename N::value_type>::type;
|
||||
using pointer = value_type*;
|
||||
using reference = value_type&;
|
||||
|
||||
@@ -257,7 +257,7 @@ static double getStartupTime()
|
||||
{
|
||||
StaticInitializer ()
|
||||
{
|
||||
when = detail::monotonicCurrentTimeInSeconds();
|
||||
when = beast::detail::monotonicCurrentTimeInSeconds();
|
||||
}
|
||||
|
||||
double when;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <ripple/beast/core/LexicalCast.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
92
src/ripple/beast/crypto/detail/mac_facade.h
Normal file
92
src/ripple/beast/crypto/detail/mac_facade.h
Normal file
@@ -0,0 +1,92 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_CRYPTO_MAC_FACADE_H_INCLUDED
|
||||
#define BEAST_CRYPTO_MAC_FACADE_H_INCLUDED
|
||||
|
||||
#include <ripple/beast/crypto/secure_erase.h>
|
||||
#include <ripple/beast/hash/endian.h>
|
||||
#include <type_traits>
|
||||
#include <array>
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
// Message Authentication Code (MAC) facade
|
||||
template <class Context, bool Secure>
|
||||
class mac_facade
|
||||
{
|
||||
private:
|
||||
Context ctx_;
|
||||
|
||||
public:
|
||||
static beast::endian const endian =
|
||||
beast::endian::native;
|
||||
|
||||
static std::size_t const digest_size =
|
||||
Context::digest_size;
|
||||
|
||||
using result_type =
|
||||
std::array<std::uint8_t, digest_size>;
|
||||
|
||||
mac_facade() noexcept
|
||||
{
|
||||
init(ctx_);
|
||||
}
|
||||
|
||||
~mac_facade()
|
||||
{
|
||||
erase(std::integral_constant<
|
||||
bool, Secure>{});
|
||||
}
|
||||
|
||||
void
|
||||
operator()(void const* data,
|
||||
std::size_t size) noexcept
|
||||
{
|
||||
update(ctx_, data, size);
|
||||
}
|
||||
|
||||
explicit
|
||||
operator result_type() noexcept
|
||||
{
|
||||
result_type digest;
|
||||
finish(ctx_, &digest[0]);
|
||||
return digest;
|
||||
}
|
||||
|
||||
private:
|
||||
inline
|
||||
void
|
||||
erase (std::false_type) noexcept
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
erase (std::true_type) noexcept
|
||||
{
|
||||
secure_erase(&ctx_, sizeof(ctx_));
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
429
src/ripple/beast/crypto/detail/ripemd_context.h
Normal file
429
src/ripple/beast/crypto/detail/ripemd_context.h
Normal file
@@ -0,0 +1,429 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_CRYPTO_RIPEMD_CONTEXT_H_INCLUDED
|
||||
#define BEAST_CRYPTO_RIPEMD_CONTEXT_H_INCLUDED
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
// Based on
|
||||
// https://code.google.com/p/blockchain/source/browse/trunk/RIPEMD160.cpp
|
||||
/*
|
||||
Copyright (c) Katholieke Universiteit Leuven
|
||||
1996 All Rights Reserved
|
||||
|
||||
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.
|
||||
*/
|
||||
// This implementation has been modified from the
|
||||
// original. It has been updated for C++11.
|
||||
|
||||
struct ripemd160_context
|
||||
{
|
||||
static unsigned int const block_size = 64;
|
||||
static unsigned int const digest_size = 20;
|
||||
|
||||
unsigned int tot_len;
|
||||
unsigned int len;
|
||||
unsigned char block[256];
|
||||
std::uint32_t h[5];
|
||||
};
|
||||
|
||||
// ROL(x, n) cyclically rotates x over n bits to the left
|
||||
// x must be of an unsigned 32 bits type and 0 <= n < 32.
|
||||
#define BEAST_RIPEMD_ROL(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||
|
||||
// the five basic functions F(), G() and H()
|
||||
#define BEAST_RIPEMD_F(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define BEAST_RIPEMD_G(x, y, z) (((x) & (y)) | (~(x) & (z)))
|
||||
#define BEAST_RIPEMD_H(x, y, z) (((x) | ~(y)) ^ (z))
|
||||
#define BEAST_RIPEMD_I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
|
||||
#define BEAST_RIPEMD_J(x, y, z) ((x) ^ ((y) | ~(z)))
|
||||
|
||||
// the ten basic operations FF() through III()
|
||||
#define BEAST_RIPEMD_FF(a, b, c, d, e, x, s) { \
|
||||
(a) += BEAST_RIPEMD_F((b), (c), (d)) + (x); \
|
||||
(a) = BEAST_RIPEMD_ROL((a), (s)) + (e); \
|
||||
(c) = BEAST_RIPEMD_ROL((c), 10); }
|
||||
#define BEAST_RIPEMD_GG(a, b, c, d, e, x, s) { \
|
||||
(a) += BEAST_RIPEMD_G((b), (c), (d)) + (x) + 0x5a827999UL; \
|
||||
(a) = BEAST_RIPEMD_ROL((a), (s)) + (e); \
|
||||
(c) = BEAST_RIPEMD_ROL((c), 10); }
|
||||
#define BEAST_RIPEMD_HH(a, b, c, d, e, x, s) { \
|
||||
(a) += BEAST_RIPEMD_H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
|
||||
(a) = BEAST_RIPEMD_ROL((a), (s)) + (e); \
|
||||
(c) = BEAST_RIPEMD_ROL((c), 10); }
|
||||
#define BEAST_RIPEMD_II(a, b, c, d, e, x, s) { \
|
||||
(a) += BEAST_RIPEMD_I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
|
||||
(a) = BEAST_RIPEMD_ROL((a), (s)) + (e); \
|
||||
(c) = BEAST_RIPEMD_ROL((c), 10); }
|
||||
#define BEAST_RIPEMD_JJ(a, b, c, d, e, x, s) { \
|
||||
(a) += BEAST_RIPEMD_J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
|
||||
(a) = BEAST_RIPEMD_ROL((a), (s)) + (e); \
|
||||
(c) = BEAST_RIPEMD_ROL((c), 10); }
|
||||
#define BEAST_RIPEMD_FFF(a, b, c, d, e, x, s) { \
|
||||
(a) += BEAST_RIPEMD_F((b), (c), (d)) + (x); \
|
||||
(a) = BEAST_RIPEMD_ROL((a), (s)) + (e); \
|
||||
(c) = BEAST_RIPEMD_ROL((c), 10); }
|
||||
#define BEAST_RIPEMD_GGG(a, b, c, d, e, x, s) { \
|
||||
(a) += BEAST_RIPEMD_G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
|
||||
(a) = BEAST_RIPEMD_ROL((a), (s)) + (e); \
|
||||
(c) = BEAST_RIPEMD_ROL((c), 10); }
|
||||
#define BEAST_RIPEMD_HHH(a, b, c, d, e, x, s) { \
|
||||
(a) += BEAST_RIPEMD_H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
|
||||
(a) = BEAST_RIPEMD_ROL((a), (s)) + (e); \
|
||||
(c) = BEAST_RIPEMD_ROL((c), 10); }
|
||||
#define BEAST_RIPEMD_III(a, b, c, d, e, x, s) { \
|
||||
(a) += BEAST_RIPEMD_I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
|
||||
(a) = BEAST_RIPEMD_ROL((a), (s)) + (e); \
|
||||
(c) = BEAST_RIPEMD_ROL((c), 10); }
|
||||
#define BEAST_RIPEMD_JJJ(a, b, c, d, e, x, s) { \
|
||||
(a) += BEAST_RIPEMD_J((b), (c), (d)) + (x) + 0x50a28be6UL;\
|
||||
(a) = BEAST_RIPEMD_ROL((a), (s)) + (e); \
|
||||
(c) = BEAST_RIPEMD_ROL((c), 10); }
|
||||
|
||||
template <class = void>
|
||||
void ripemd_load (std::array<std::uint32_t, 16>& X,
|
||||
unsigned char const* p)
|
||||
{
|
||||
for(int i = 0; i < 16; ++i)
|
||||
{
|
||||
X[i] =
|
||||
((std::uint32_t) *((p)+3) << 24) |
|
||||
((std::uint32_t) *((p)+2) << 16) |
|
||||
((std::uint32_t) *((p)+1) << 8) |
|
||||
((std::uint32_t) * (p));
|
||||
p += 4;
|
||||
}
|
||||
}
|
||||
|
||||
template <class = void>
|
||||
void ripemd_compress (ripemd160_context& ctx,
|
||||
std::array<std::uint32_t, 16>& X) noexcept
|
||||
{
|
||||
std::uint32_t aa = ctx.h[0];
|
||||
std::uint32_t bb = ctx.h[1];
|
||||
std::uint32_t cc = ctx.h[2];
|
||||
std::uint32_t dd = ctx.h[3];
|
||||
std::uint32_t ee = ctx.h[4];
|
||||
std::uint32_t aaa = ctx.h[0];
|
||||
std::uint32_t bbb = ctx.h[1];
|
||||
std::uint32_t ccc = ctx.h[2];
|
||||
std::uint32_t ddd = ctx.h[3];
|
||||
std::uint32_t eee = ctx.h[4];
|
||||
|
||||
// round 1
|
||||
BEAST_RIPEMD_FF(aa, bb, cc, dd, ee, X[ 0], 11);
|
||||
BEAST_RIPEMD_FF(ee, aa, bb, cc, dd, X[ 1], 14);
|
||||
BEAST_RIPEMD_FF(dd, ee, aa, bb, cc, X[ 2], 15);
|
||||
BEAST_RIPEMD_FF(cc, dd, ee, aa, bb, X[ 3], 12);
|
||||
BEAST_RIPEMD_FF(bb, cc, dd, ee, aa, X[ 4], 5);
|
||||
BEAST_RIPEMD_FF(aa, bb, cc, dd, ee, X[ 5], 8);
|
||||
BEAST_RIPEMD_FF(ee, aa, bb, cc, dd, X[ 6], 7);
|
||||
BEAST_RIPEMD_FF(dd, ee, aa, bb, cc, X[ 7], 9);
|
||||
BEAST_RIPEMD_FF(cc, dd, ee, aa, bb, X[ 8], 11);
|
||||
BEAST_RIPEMD_FF(bb, cc, dd, ee, aa, X[ 9], 13);
|
||||
BEAST_RIPEMD_FF(aa, bb, cc, dd, ee, X[10], 14);
|
||||
BEAST_RIPEMD_FF(ee, aa, bb, cc, dd, X[11], 15);
|
||||
BEAST_RIPEMD_FF(dd, ee, aa, bb, cc, X[12], 6);
|
||||
BEAST_RIPEMD_FF(cc, dd, ee, aa, bb, X[13], 7);
|
||||
BEAST_RIPEMD_FF(bb, cc, dd, ee, aa, X[14], 9);
|
||||
BEAST_RIPEMD_FF(aa, bb, cc, dd, ee, X[15], 8);
|
||||
|
||||
// round 2
|
||||
BEAST_RIPEMD_GG(ee, aa, bb, cc, dd, X[ 7], 7);
|
||||
BEAST_RIPEMD_GG(dd, ee, aa, bb, cc, X[ 4], 6);
|
||||
BEAST_RIPEMD_GG(cc, dd, ee, aa, bb, X[13], 8);
|
||||
BEAST_RIPEMD_GG(bb, cc, dd, ee, aa, X[ 1], 13);
|
||||
BEAST_RIPEMD_GG(aa, bb, cc, dd, ee, X[10], 11);
|
||||
BEAST_RIPEMD_GG(ee, aa, bb, cc, dd, X[ 6], 9);
|
||||
BEAST_RIPEMD_GG(dd, ee, aa, bb, cc, X[15], 7);
|
||||
BEAST_RIPEMD_GG(cc, dd, ee, aa, bb, X[ 3], 15);
|
||||
BEAST_RIPEMD_GG(bb, cc, dd, ee, aa, X[12], 7);
|
||||
BEAST_RIPEMD_GG(aa, bb, cc, dd, ee, X[ 0], 12);
|
||||
BEAST_RIPEMD_GG(ee, aa, bb, cc, dd, X[ 9], 15);
|
||||
BEAST_RIPEMD_GG(dd, ee, aa, bb, cc, X[ 5], 9);
|
||||
BEAST_RIPEMD_GG(cc, dd, ee, aa, bb, X[ 2], 11);
|
||||
BEAST_RIPEMD_GG(bb, cc, dd, ee, aa, X[14], 7);
|
||||
BEAST_RIPEMD_GG(aa, bb, cc, dd, ee, X[11], 13);
|
||||
BEAST_RIPEMD_GG(ee, aa, bb, cc, dd, X[ 8], 12);
|
||||
|
||||
// round 3
|
||||
BEAST_RIPEMD_HH(dd, ee, aa, bb, cc, X[ 3], 11);
|
||||
BEAST_RIPEMD_HH(cc, dd, ee, aa, bb, X[10], 13);
|
||||
BEAST_RIPEMD_HH(bb, cc, dd, ee, aa, X[14], 6);
|
||||
BEAST_RIPEMD_HH(aa, bb, cc, dd, ee, X[ 4], 7);
|
||||
BEAST_RIPEMD_HH(ee, aa, bb, cc, dd, X[ 9], 14);
|
||||
BEAST_RIPEMD_HH(dd, ee, aa, bb, cc, X[15], 9);
|
||||
BEAST_RIPEMD_HH(cc, dd, ee, aa, bb, X[ 8], 13);
|
||||
BEAST_RIPEMD_HH(bb, cc, dd, ee, aa, X[ 1], 15);
|
||||
BEAST_RIPEMD_HH(aa, bb, cc, dd, ee, X[ 2], 14);
|
||||
BEAST_RIPEMD_HH(ee, aa, bb, cc, dd, X[ 7], 8);
|
||||
BEAST_RIPEMD_HH(dd, ee, aa, bb, cc, X[ 0], 13);
|
||||
BEAST_RIPEMD_HH(cc, dd, ee, aa, bb, X[ 6], 6);
|
||||
BEAST_RIPEMD_HH(bb, cc, dd, ee, aa, X[13], 5);
|
||||
BEAST_RIPEMD_HH(aa, bb, cc, dd, ee, X[11], 12);
|
||||
BEAST_RIPEMD_HH(ee, aa, bb, cc, dd, X[ 5], 7);
|
||||
BEAST_RIPEMD_HH(dd, ee, aa, bb, cc, X[12], 5);
|
||||
|
||||
// round 4
|
||||
BEAST_RIPEMD_II(cc, dd, ee, aa, bb, X[ 1], 11);
|
||||
BEAST_RIPEMD_II(bb, cc, dd, ee, aa, X[ 9], 12);
|
||||
BEAST_RIPEMD_II(aa, bb, cc, dd, ee, X[11], 14);
|
||||
BEAST_RIPEMD_II(ee, aa, bb, cc, dd, X[10], 15);
|
||||
BEAST_RIPEMD_II(dd, ee, aa, bb, cc, X[ 0], 14);
|
||||
BEAST_RIPEMD_II(cc, dd, ee, aa, bb, X[ 8], 15);
|
||||
BEAST_RIPEMD_II(bb, cc, dd, ee, aa, X[12], 9);
|
||||
BEAST_RIPEMD_II(aa, bb, cc, dd, ee, X[ 4], 8);
|
||||
BEAST_RIPEMD_II(ee, aa, bb, cc, dd, X[13], 9);
|
||||
BEAST_RIPEMD_II(dd, ee, aa, bb, cc, X[ 3], 14);
|
||||
BEAST_RIPEMD_II(cc, dd, ee, aa, bb, X[ 7], 5);
|
||||
BEAST_RIPEMD_II(bb, cc, dd, ee, aa, X[15], 6);
|
||||
BEAST_RIPEMD_II(aa, bb, cc, dd, ee, X[14], 8);
|
||||
BEAST_RIPEMD_II(ee, aa, bb, cc, dd, X[ 5], 6);
|
||||
BEAST_RIPEMD_II(dd, ee, aa, bb, cc, X[ 6], 5);
|
||||
BEAST_RIPEMD_II(cc, dd, ee, aa, bb, X[ 2], 12);
|
||||
|
||||
// round 5
|
||||
BEAST_RIPEMD_JJ(bb, cc, dd, ee, aa, X[ 4], 9);
|
||||
BEAST_RIPEMD_JJ(aa, bb, cc, dd, ee, X[ 0], 15);
|
||||
BEAST_RIPEMD_JJ(ee, aa, bb, cc, dd, X[ 5], 5);
|
||||
BEAST_RIPEMD_JJ(dd, ee, aa, bb, cc, X[ 9], 11);
|
||||
BEAST_RIPEMD_JJ(cc, dd, ee, aa, bb, X[ 7], 6);
|
||||
BEAST_RIPEMD_JJ(bb, cc, dd, ee, aa, X[12], 8);
|
||||
BEAST_RIPEMD_JJ(aa, bb, cc, dd, ee, X[ 2], 13);
|
||||
BEAST_RIPEMD_JJ(ee, aa, bb, cc, dd, X[10], 12);
|
||||
BEAST_RIPEMD_JJ(dd, ee, aa, bb, cc, X[14], 5);
|
||||
BEAST_RIPEMD_JJ(cc, dd, ee, aa, bb, X[ 1], 12);
|
||||
BEAST_RIPEMD_JJ(bb, cc, dd, ee, aa, X[ 3], 13);
|
||||
BEAST_RIPEMD_JJ(aa, bb, cc, dd, ee, X[ 8], 14);
|
||||
BEAST_RIPEMD_JJ(ee, aa, bb, cc, dd, X[11], 11);
|
||||
BEAST_RIPEMD_JJ(dd, ee, aa, bb, cc, X[ 6], 8);
|
||||
BEAST_RIPEMD_JJ(cc, dd, ee, aa, bb, X[15], 5);
|
||||
BEAST_RIPEMD_JJ(bb, cc, dd, ee, aa, X[13], 6);
|
||||
|
||||
// parallel round 1
|
||||
BEAST_RIPEMD_JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8);
|
||||
BEAST_RIPEMD_JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9);
|
||||
BEAST_RIPEMD_JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9);
|
||||
BEAST_RIPEMD_JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
|
||||
BEAST_RIPEMD_JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
|
||||
BEAST_RIPEMD_JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
|
||||
BEAST_RIPEMD_JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
|
||||
BEAST_RIPEMD_JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5);
|
||||
BEAST_RIPEMD_JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7);
|
||||
BEAST_RIPEMD_JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7);
|
||||
BEAST_RIPEMD_JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8);
|
||||
BEAST_RIPEMD_JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
|
||||
BEAST_RIPEMD_JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
|
||||
BEAST_RIPEMD_JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
|
||||
BEAST_RIPEMD_JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
|
||||
BEAST_RIPEMD_JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6);
|
||||
|
||||
// parallel round 2
|
||||
BEAST_RIPEMD_III(eee, aaa, bbb, ccc, ddd, X[ 6], 9);
|
||||
BEAST_RIPEMD_III(ddd, eee, aaa, bbb, ccc, X[11], 13);
|
||||
BEAST_RIPEMD_III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
|
||||
BEAST_RIPEMD_III(bbb, ccc, ddd, eee, aaa, X[ 7], 7);
|
||||
BEAST_RIPEMD_III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
|
||||
BEAST_RIPEMD_III(eee, aaa, bbb, ccc, ddd, X[13], 8);
|
||||
BEAST_RIPEMD_III(ddd, eee, aaa, bbb, ccc, X[ 5], 9);
|
||||
BEAST_RIPEMD_III(ccc, ddd, eee, aaa, bbb, X[10], 11);
|
||||
BEAST_RIPEMD_III(bbb, ccc, ddd, eee, aaa, X[14], 7);
|
||||
BEAST_RIPEMD_III(aaa, bbb, ccc, ddd, eee, X[15], 7);
|
||||
BEAST_RIPEMD_III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
|
||||
BEAST_RIPEMD_III(ddd, eee, aaa, bbb, ccc, X[12], 7);
|
||||
BEAST_RIPEMD_III(ccc, ddd, eee, aaa, bbb, X[ 4], 6);
|
||||
BEAST_RIPEMD_III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
|
||||
BEAST_RIPEMD_III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
|
||||
BEAST_RIPEMD_III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
|
||||
|
||||
// parallel round 3
|
||||
BEAST_RIPEMD_HHH(ddd, eee, aaa, bbb, ccc, X[15], 9);
|
||||
BEAST_RIPEMD_HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7);
|
||||
BEAST_RIPEMD_HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
|
||||
BEAST_RIPEMD_HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
|
||||
BEAST_RIPEMD_HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8);
|
||||
BEAST_RIPEMD_HHH(ddd, eee, aaa, bbb, ccc, X[14], 6);
|
||||
BEAST_RIPEMD_HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6);
|
||||
BEAST_RIPEMD_HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
|
||||
BEAST_RIPEMD_HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
|
||||
BEAST_RIPEMD_HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
|
||||
BEAST_RIPEMD_HHH(ddd, eee, aaa, bbb, ccc, X[12], 5);
|
||||
BEAST_RIPEMD_HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
|
||||
BEAST_RIPEMD_HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
|
||||
BEAST_RIPEMD_HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
|
||||
BEAST_RIPEMD_HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7);
|
||||
BEAST_RIPEMD_HHH(ddd, eee, aaa, bbb, ccc, X[13], 5);
|
||||
|
||||
// parallel round 4
|
||||
BEAST_RIPEMD_GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
|
||||
BEAST_RIPEMD_GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5);
|
||||
BEAST_RIPEMD_GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8);
|
||||
BEAST_RIPEMD_GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
|
||||
BEAST_RIPEMD_GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
|
||||
BEAST_RIPEMD_GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
|
||||
BEAST_RIPEMD_GGG(bbb, ccc, ddd, eee, aaa, X[15], 6);
|
||||
BEAST_RIPEMD_GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
|
||||
BEAST_RIPEMD_GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6);
|
||||
BEAST_RIPEMD_GGG(ddd, eee, aaa, bbb, ccc, X[12], 9);
|
||||
BEAST_RIPEMD_GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
|
||||
BEAST_RIPEMD_GGG(bbb, ccc, ddd, eee, aaa, X[13], 9);
|
||||
BEAST_RIPEMD_GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
|
||||
BEAST_RIPEMD_GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5);
|
||||
BEAST_RIPEMD_GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
|
||||
BEAST_RIPEMD_GGG(ccc, ddd, eee, aaa, bbb, X[14], 8);
|
||||
|
||||
// parallel round 5
|
||||
BEAST_RIPEMD_FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8);
|
||||
BEAST_RIPEMD_FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5);
|
||||
BEAST_RIPEMD_FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
|
||||
BEAST_RIPEMD_FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9);
|
||||
BEAST_RIPEMD_FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
|
||||
BEAST_RIPEMD_FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5);
|
||||
BEAST_RIPEMD_FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
|
||||
BEAST_RIPEMD_FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6);
|
||||
BEAST_RIPEMD_FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8);
|
||||
BEAST_RIPEMD_FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
|
||||
BEAST_RIPEMD_FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6);
|
||||
BEAST_RIPEMD_FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5);
|
||||
BEAST_RIPEMD_FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
|
||||
BEAST_RIPEMD_FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
|
||||
BEAST_RIPEMD_FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
|
||||
BEAST_RIPEMD_FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
|
||||
|
||||
// combine results
|
||||
ddd += cc + ctx.h[1]; // final result for h[0]
|
||||
ctx.h[1] = ctx.h[2] + dd + eee;
|
||||
ctx.h[2] = ctx.h[3] + ee + aaa;
|
||||
ctx.h[3] = ctx.h[4] + aa + bbb;
|
||||
ctx.h[4] = ctx.h[0] + bb + ccc;
|
||||
ctx.h[0] = ddd;
|
||||
}
|
||||
|
||||
template <class = void>
|
||||
void init (ripemd160_context& ctx) noexcept
|
||||
{
|
||||
ctx.len = 0;
|
||||
ctx.tot_len = 0;
|
||||
ctx.h[0] = 0x67452301UL;
|
||||
ctx.h[1] = 0xefcdab89UL;
|
||||
ctx.h[2] = 0x98badcfeUL;
|
||||
ctx.h[3] = 0x10325476UL;
|
||||
ctx.h[4] = 0xc3d2e1f0UL;
|
||||
}
|
||||
|
||||
template <class = void>
|
||||
void update (ripemd160_context& ctx,
|
||||
void const* message, std::size_t size) noexcept
|
||||
{
|
||||
auto const pm = reinterpret_cast<
|
||||
unsigned char const*>(message);
|
||||
unsigned int block_nb;
|
||||
unsigned int new_len, rem_len, tmp_len;
|
||||
const unsigned char *shifted_message;
|
||||
tmp_len = ripemd160_context::block_size - ctx.len;
|
||||
rem_len = size < tmp_len ? size : tmp_len;
|
||||
std::memcpy(&ctx.block[ctx.len], pm, rem_len);
|
||||
if (ctx.len + size < ripemd160_context::block_size) {
|
||||
ctx.len += size;
|
||||
return;
|
||||
}
|
||||
new_len = size - rem_len;
|
||||
block_nb = new_len / ripemd160_context::block_size;
|
||||
shifted_message = pm + rem_len;
|
||||
std::array<std::uint32_t, 16> X;
|
||||
ripemd_load(X, ctx.block);
|
||||
ripemd_compress(ctx, X);
|
||||
for (int i = 0; i < block_nb; ++i)
|
||||
{
|
||||
ripemd_load(X, shifted_message +
|
||||
i * ripemd160_context::block_size);
|
||||
ripemd_compress(ctx, X);
|
||||
}
|
||||
rem_len = new_len % ripemd160_context::block_size;
|
||||
std::memcpy(ctx.block, &shifted_message[
|
||||
block_nb * ripemd160_context::block_size],
|
||||
rem_len);
|
||||
ctx.len = rem_len;
|
||||
ctx.tot_len += (block_nb + 1) *
|
||||
ripemd160_context::block_size;
|
||||
}
|
||||
|
||||
template <class = void>
|
||||
void finish (ripemd160_context& ctx,
|
||||
void* digest) noexcept
|
||||
{
|
||||
std::array<std::uint32_t, 16> X;
|
||||
X.fill(0);
|
||||
// put leftovers into X
|
||||
auto p = &ctx.block[0];
|
||||
// uint8_t i goes into word X[i div 4] at pos. 8*(i mod 4)
|
||||
for (int i = 0; i < ctx.len; ++i)
|
||||
X[i >> 2] ^= (std::uint32_t) *p++ << (8 * (i & 3));
|
||||
ctx.tot_len += ctx.len;
|
||||
// append the bit m_n == 1
|
||||
X[(ctx.tot_len>>2)&15] ^=
|
||||
(uint32_t)1 << (8*(ctx.tot_len&3) + 7);
|
||||
// length goes to next block?
|
||||
if ((ctx.tot_len & 63) > 55)
|
||||
{
|
||||
ripemd_compress(ctx, X);
|
||||
X.fill(0);
|
||||
}
|
||||
// append length in bits*/
|
||||
X[14] = ctx.tot_len << 3;
|
||||
X[15] = (ctx.tot_len >> 29) | (0 << 3);
|
||||
ripemd_compress(ctx, X);
|
||||
|
||||
std::uint8_t* pd = reinterpret_cast<
|
||||
std::uint8_t*>(digest);
|
||||
for (std::uint32_t i = 0; i < 20; i += 4)
|
||||
{
|
||||
pd[i] = (std::uint8_t)(ctx.h[i>>2]); // implicit cast to uint8_t
|
||||
pd[i+1] = (std::uint8_t)(ctx.h[i>>2] >> 8); // extracts the 8 least
|
||||
pd[i+2] = (std::uint8_t)(ctx.h[i>>2] >> 16); // significant bits.
|
||||
pd[i+3] = (std::uint8_t)(ctx.h[i>>2] >> 24);
|
||||
}
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
428
src/ripple/beast/crypto/detail/sha2_context.h
Normal file
428
src/ripple/beast/crypto/detail/sha2_context.h
Normal file
@@ -0,0 +1,428 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_CRYPTO_SHA512_CONTEXT_H_INCLUDED
|
||||
#define BEAST_CRYPTO_SHA512_CONTEXT_H_INCLUDED
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
// Based on https://github.com/ogay/sha2
|
||||
// This implementation has been modified from the
|
||||
// original. It has been updated for C++11.
|
||||
|
||||
/*
|
||||
* Updated to C++, zedwood.com 2012
|
||||
* Based on Olivier Gay's version
|
||||
* See Modified BSD License below:
|
||||
*
|
||||
* FIPS 180-2 SHA-224/256/384/512 implementation
|
||||
* Issue date: 04/30/2005
|
||||
* http://www.ouah.org/ogay/sha2/
|
||||
*
|
||||
* Copyright (C) 2005, 2007 Olivier Gay <olivier.gay@a3.epfl.ch>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
struct sha256_context
|
||||
{
|
||||
static unsigned int const block_size = 64;
|
||||
static unsigned int const digest_size = 32;
|
||||
|
||||
unsigned int tot_len;
|
||||
unsigned int len;
|
||||
unsigned char block[2 * block_size];
|
||||
std::uint32_t h[8];
|
||||
};
|
||||
|
||||
struct sha512_context
|
||||
{
|
||||
static unsigned int const block_size = 128;
|
||||
static unsigned int const digest_size = 64;
|
||||
|
||||
unsigned int tot_len;
|
||||
unsigned int len;
|
||||
unsigned char block[2 * block_size];
|
||||
std::uint64_t h[8];
|
||||
};
|
||||
|
||||
#define BEAST_SHA2_SHFR(x, n) (x >> n)
|
||||
#define BEAST_SHA2_ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n)))
|
||||
#define BEAST_SHA2_ROTL(x, n) ((x << n) | (x >> ((sizeof(x) << 3) - n)))
|
||||
#define BEAST_SHA2_CH(x, y, z) ((x & y) ^ (~x & z))
|
||||
#define BEAST_SHA2_MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
|
||||
#define BEAST_SHA256_F1(x) (BEAST_SHA2_ROTR(x, 2) ^ BEAST_SHA2_ROTR(x, 13) ^ BEAST_SHA2_ROTR(x, 22))
|
||||
#define BEAST_SHA256_F2(x) (BEAST_SHA2_ROTR(x, 6) ^ BEAST_SHA2_ROTR(x, 11) ^ BEAST_SHA2_ROTR(x, 25))
|
||||
#define BEAST_SHA256_F3(x) (BEAST_SHA2_ROTR(x, 7) ^ BEAST_SHA2_ROTR(x, 18) ^ BEAST_SHA2_SHFR(x, 3))
|
||||
#define BEAST_SHA256_F4(x) (BEAST_SHA2_ROTR(x, 17) ^ BEAST_SHA2_ROTR(x, 19) ^ BEAST_SHA2_SHFR(x, 10))
|
||||
#define BEAST_SHA512_F1(x) (BEAST_SHA2_ROTR(x, 28) ^ BEAST_SHA2_ROTR(x, 34) ^ BEAST_SHA2_ROTR(x, 39))
|
||||
#define BEAST_SHA512_F2(x) (BEAST_SHA2_ROTR(x, 14) ^ BEAST_SHA2_ROTR(x, 18) ^ BEAST_SHA2_ROTR(x, 41))
|
||||
#define BEAST_SHA512_F3(x) (BEAST_SHA2_ROTR(x, 1) ^ BEAST_SHA2_ROTR(x, 8) ^ BEAST_SHA2_SHFR(x, 7))
|
||||
#define BEAST_SHA512_F4(x) (BEAST_SHA2_ROTR(x, 19) ^ BEAST_SHA2_ROTR(x, 61) ^ BEAST_SHA2_SHFR(x, 6))
|
||||
#define BEAST_SHA2_PACK32(str, x) \
|
||||
{ \
|
||||
*(x) = \
|
||||
((std::uint32_t) *((str) + 3) ) \
|
||||
| ((std::uint32_t) *((str) + 2) << 8) \
|
||||
| ((std::uint32_t) *((str) + 1) << 16) \
|
||||
| ((std::uint32_t) *((str) + 0) << 24); \
|
||||
}
|
||||
#define BEAST_SHA2_UNPACK32(x, str) \
|
||||
{ \
|
||||
*((str) + 3) = (std::uint8_t) ((x) ); \
|
||||
*((str) + 2) = (std::uint8_t) ((x) >> 8); \
|
||||
*((str) + 1) = (std::uint8_t) ((x) >> 16); \
|
||||
*((str) + 0) = (std::uint8_t) ((x) >> 24); \
|
||||
}
|
||||
#define BEAST_SHA2_PACK64(str, x) \
|
||||
{ \
|
||||
*(x) = \
|
||||
((std::uint64_t) *((str) + 7) ) \
|
||||
| ((std::uint64_t) *((str) + 6) << 8) \
|
||||
| ((std::uint64_t) *((str) + 5) << 16) \
|
||||
| ((std::uint64_t) *((str) + 4) << 24) \
|
||||
| ((std::uint64_t) *((str) + 3) << 32) \
|
||||
| ((std::uint64_t) *((str) + 2) << 40) \
|
||||
| ((std::uint64_t) *((str) + 1) << 48) \
|
||||
| ((std::uint64_t) *((str) + 0) << 56); \
|
||||
}
|
||||
#define BEAST_SHA2_UNPACK64(x, str) \
|
||||
{ \
|
||||
*((str) + 7) = (std::uint8_t) ((x) ); \
|
||||
*((str) + 6) = (std::uint8_t) ((x) >> 8); \
|
||||
*((str) + 5) = (std::uint8_t) ((x) >> 16); \
|
||||
*((str) + 4) = (std::uint8_t) ((x) >> 24); \
|
||||
*((str) + 3) = (std::uint8_t) ((x) >> 32); \
|
||||
*((str) + 2) = (std::uint8_t) ((x) >> 40); \
|
||||
*((str) + 1) = (std::uint8_t) ((x) >> 48); \
|
||||
*((str) + 0) = (std::uint8_t) ((x) >> 56); \
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// SHA256
|
||||
|
||||
template <class = void>
|
||||
void sha256_transform (sha256_context& ctx,
|
||||
unsigned char const* message,
|
||||
unsigned int block_nb) noexcept
|
||||
{
|
||||
static unsigned long long const K[64] = {
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
||||
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
||||
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
|
||||
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
|
||||
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
||||
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
|
||||
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
|
||||
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
||||
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||||
};
|
||||
std::uint32_t w[64];
|
||||
std::uint32_t wv[8];
|
||||
std::uint32_t t1, t2;
|
||||
unsigned char const* sub_block;
|
||||
int i, j;
|
||||
for (i = 0; i < (int) block_nb; i++) {
|
||||
sub_block = message + (i << 6);
|
||||
for (j = 0; j < 16; j++)
|
||||
BEAST_SHA2_PACK32(&sub_block[j << 2], &w[j]);
|
||||
for (j = 16; j < 64; j++)
|
||||
w[j] = BEAST_SHA256_F4(
|
||||
w[j - 2]) + w[j - 7] +
|
||||
BEAST_SHA256_F3(w[j - 15]) +
|
||||
w[j - 16];
|
||||
for (j = 0; j < 8; j++)
|
||||
wv[j] = ctx.h[j];
|
||||
for (j = 0; j < 64; j++) {
|
||||
t1 = wv[7] + BEAST_SHA256_F2(wv[4]) +
|
||||
BEAST_SHA2_CH(wv[4], wv[5], wv[6]) +
|
||||
K[j] + w[j];
|
||||
t2 = BEAST_SHA256_F1(wv[0]) +
|
||||
BEAST_SHA2_MAJ(wv[0], wv[1], wv[2]);
|
||||
wv[7] = wv[6];
|
||||
wv[6] = wv[5];
|
||||
wv[5] = wv[4];
|
||||
wv[4] = wv[3] + t1;
|
||||
wv[3] = wv[2];
|
||||
wv[2] = wv[1];
|
||||
wv[1] = wv[0];
|
||||
wv[0] = t1 + t2;
|
||||
}
|
||||
for (j = 0; j < 8; j++)
|
||||
ctx.h[j] += wv[j];
|
||||
}
|
||||
}
|
||||
|
||||
template <class = void>
|
||||
void init (sha256_context& ctx) noexcept
|
||||
{
|
||||
ctx.len = 0;
|
||||
ctx.tot_len = 0;
|
||||
ctx.h[0] = 0x6a09e667;
|
||||
ctx.h[1] = 0xbb67ae85;
|
||||
ctx.h[2] = 0x3c6ef372;
|
||||
ctx.h[3] = 0xa54ff53a;
|
||||
ctx.h[4] = 0x510e527f;
|
||||
ctx.h[5] = 0x9b05688c;
|
||||
ctx.h[6] = 0x1f83d9ab;
|
||||
ctx.h[7] = 0x5be0cd19;
|
||||
}
|
||||
|
||||
template <class = void>
|
||||
void update (sha256_context& ctx,
|
||||
void const* message, std::size_t size) noexcept
|
||||
{
|
||||
auto const pm = reinterpret_cast<
|
||||
unsigned char const*>(message);
|
||||
unsigned int block_nb;
|
||||
unsigned int new_len, rem_len, tmp_len;
|
||||
const unsigned char *shifted_message;
|
||||
tmp_len = sha256_context::block_size - ctx.len;
|
||||
rem_len = size < tmp_len ? size : tmp_len;
|
||||
std::memcpy(&ctx.block[ctx.len], pm, rem_len);
|
||||
if (ctx.len + size < sha256_context::block_size) {
|
||||
ctx.len += size;
|
||||
return;
|
||||
}
|
||||
new_len = size - rem_len;
|
||||
block_nb = new_len / sha256_context::block_size;
|
||||
shifted_message = pm + rem_len;
|
||||
sha256_transform(ctx, ctx.block, 1);
|
||||
sha256_transform(ctx, shifted_message, block_nb);
|
||||
rem_len = new_len % sha256_context::block_size;
|
||||
std::memcpy(ctx.block, &shifted_message[
|
||||
block_nb << 6], rem_len);
|
||||
ctx.len = rem_len;
|
||||
ctx.tot_len += (block_nb + 1) << 6;
|
||||
}
|
||||
|
||||
template <class = void>
|
||||
void finish (sha256_context& ctx,
|
||||
void* digest) noexcept
|
||||
{
|
||||
auto const pd = reinterpret_cast<
|
||||
unsigned char*>(digest);
|
||||
unsigned int block_nb;
|
||||
unsigned int pm_len;
|
||||
unsigned int len_b;
|
||||
int i;
|
||||
block_nb = (1 + ((sha256_context::block_size - 9) <
|
||||
(ctx.len % sha256_context::block_size)));
|
||||
len_b = (ctx.tot_len + ctx.len) << 3;
|
||||
pm_len = block_nb << 6;
|
||||
std::memset(ctx.block + ctx.len, 0, pm_len - ctx.len);
|
||||
ctx.block[ctx.len] = 0x80;
|
||||
BEAST_SHA2_UNPACK32(len_b, ctx.block + pm_len - 4);
|
||||
sha256_transform(ctx, ctx.block, block_nb);
|
||||
for (i = 0 ; i < 8; i++)
|
||||
BEAST_SHA2_UNPACK32(ctx.h[i], &pd[i << 2]);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// SHA512
|
||||
|
||||
template <class = void>
|
||||
void sha512_transform (sha512_context& ctx,
|
||||
unsigned char const* message,
|
||||
unsigned int block_nb) noexcept
|
||||
{
|
||||
static unsigned long long const K[80] = {
|
||||
0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
|
||||
0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
|
||||
0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
|
||||
0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
|
||||
0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
|
||||
0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
|
||||
0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
|
||||
0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
|
||||
0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
|
||||
0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
|
||||
0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
|
||||
0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
|
||||
0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
|
||||
0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
|
||||
0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
|
||||
0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
|
||||
0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
|
||||
0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
|
||||
0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
|
||||
0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
|
||||
0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
|
||||
0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
|
||||
0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
|
||||
0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
|
||||
0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
|
||||
0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
|
||||
0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
|
||||
0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
|
||||
0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
|
||||
0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
|
||||
0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
|
||||
0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
|
||||
0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
|
||||
0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
|
||||
0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
|
||||
0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
|
||||
0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
|
||||
0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
|
||||
0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
|
||||
0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL};
|
||||
|
||||
std::uint64_t w[80];
|
||||
std::uint64_t wv[8];
|
||||
std::uint64_t t1, t2;
|
||||
unsigned char const* sub_block;
|
||||
int i, j;
|
||||
for (i = 0; i < (int) block_nb; i++)
|
||||
{
|
||||
sub_block = message + (i << 7);
|
||||
for (j = 0; j < 16; j++)
|
||||
BEAST_SHA2_PACK64(&sub_block[j << 3], &w[j]);
|
||||
for (j = 16; j < 80; j++)
|
||||
w[j] = BEAST_SHA512_F4(
|
||||
w[j - 2]) + w[j - 7] +
|
||||
BEAST_SHA512_F3(w[j - 15]) +
|
||||
w[j - 16];
|
||||
for (j = 0; j < 8; j++)
|
||||
wv[j] = ctx.h[j];
|
||||
for (j = 0; j < 80; j++) {
|
||||
t1 = wv[7] + BEAST_SHA512_F2(wv[4]) +
|
||||
BEAST_SHA2_CH(wv[4], wv[5], wv[6]) +
|
||||
K[j] + w[j];
|
||||
t2 = BEAST_SHA512_F1(wv[0]) +
|
||||
BEAST_SHA2_MAJ(wv[0], wv[1], wv[2]);
|
||||
wv[7] = wv[6];
|
||||
wv[6] = wv[5];
|
||||
wv[5] = wv[4];
|
||||
wv[4] = wv[3] + t1;
|
||||
wv[3] = wv[2];
|
||||
wv[2] = wv[1];
|
||||
wv[1] = wv[0];
|
||||
wv[0] = t1 + t2;
|
||||
}
|
||||
for (j = 0; j < 8; j++)
|
||||
ctx.h[j] += wv[j];
|
||||
}
|
||||
}
|
||||
|
||||
template <class = void>
|
||||
void init (sha512_context& ctx) noexcept
|
||||
{
|
||||
ctx.len = 0;
|
||||
ctx.tot_len = 0;
|
||||
ctx.h[0] = 0x6a09e667f3bcc908ULL;
|
||||
ctx.h[1] = 0xbb67ae8584caa73bULL;
|
||||
ctx.h[2] = 0x3c6ef372fe94f82bULL;
|
||||
ctx.h[3] = 0xa54ff53a5f1d36f1ULL;
|
||||
ctx.h[4] = 0x510e527fade682d1ULL;
|
||||
ctx.h[5] = 0x9b05688c2b3e6c1fULL;
|
||||
ctx.h[6] = 0x1f83d9abfb41bd6bULL;
|
||||
ctx.h[7] = 0x5be0cd19137e2179ULL;
|
||||
}
|
||||
|
||||
template <class = void>
|
||||
void update (sha512_context& ctx,
|
||||
void const* message, std::size_t size) noexcept
|
||||
{
|
||||
auto const pm = reinterpret_cast<
|
||||
unsigned char const*>(message);
|
||||
unsigned int block_nb;
|
||||
unsigned int new_len, rem_len, tmp_len;
|
||||
const unsigned char *shifted_message;
|
||||
tmp_len = sha512_context::block_size - ctx.len;
|
||||
rem_len = size < tmp_len ? size : tmp_len;
|
||||
std::memcpy(&ctx.block[ctx.len], pm, rem_len);
|
||||
if (ctx.len + size < sha512_context::block_size) {
|
||||
ctx.len += size;
|
||||
return;
|
||||
}
|
||||
new_len = size - rem_len;
|
||||
block_nb = new_len / sha512_context::block_size;
|
||||
shifted_message = pm + rem_len;
|
||||
sha512_transform(ctx, ctx.block, 1);
|
||||
sha512_transform(ctx, shifted_message, block_nb);
|
||||
rem_len = new_len % sha512_context::block_size;
|
||||
std::memcpy(ctx.block, &shifted_message[
|
||||
block_nb << 7], rem_len);
|
||||
ctx.len = rem_len;
|
||||
ctx.tot_len += (block_nb + 1) << 7;
|
||||
}
|
||||
|
||||
template <class = void>
|
||||
void finish (sha512_context& ctx,
|
||||
void* digest) noexcept
|
||||
{
|
||||
auto const pd = reinterpret_cast<
|
||||
unsigned char*>(digest);
|
||||
unsigned int block_nb;
|
||||
unsigned int pm_len;
|
||||
unsigned int len_b;
|
||||
int i;
|
||||
block_nb = 1 + ((sha512_context::block_size - 17) <
|
||||
(ctx.len % sha512_context::block_size));
|
||||
len_b = (ctx.tot_len + ctx.len) << 3;
|
||||
pm_len = block_nb << 7;
|
||||
std::memset(ctx.block + ctx.len, 0, pm_len - ctx.len);
|
||||
ctx.block[ctx.len] = 0x80;
|
||||
BEAST_SHA2_UNPACK32(len_b, ctx.block + pm_len - 4);
|
||||
sha512_transform(ctx, ctx.block, block_nb);
|
||||
for (i = 0 ; i < 8; i++)
|
||||
BEAST_SHA2_UNPACK64(ctx.h[i], &pd[i << 3]);
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
37
src/ripple/beast/crypto/ripemd.h
Normal file
37
src/ripple/beast/crypto/ripemd.h
Normal file
@@ -0,0 +1,37 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_CRYPTO_RIPEMD_H_INCLUDED
|
||||
#define BEAST_CRYPTO_RIPEMD_H_INCLUDED
|
||||
|
||||
#include <ripple/beast/crypto/detail/mac_facade.h>
|
||||
#include <ripple/beast/crypto/detail/ripemd_context.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
using ripemd160_hasher = detail::mac_facade<
|
||||
detail::ripemd160_context, false>;
|
||||
|
||||
// secure version
|
||||
using ripemd160_hasher_s = detail::mac_facade<
|
||||
detail::ripemd160_context, true>;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
87
src/ripple/beast/crypto/secure_erase.h
Normal file
87
src/ripple/beast/crypto/secure_erase.h
Normal file
@@ -0,0 +1,87 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_CRYPTO_SECURE_ERASE_H_INCLUDED
|
||||
#define BEAST_CRYPTO_SECURE_ERASE_H_INCLUDED
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <new>
|
||||
|
||||
namespace beast {
|
||||
|
||||
namespace detail {
|
||||
|
||||
class secure_erase_impl
|
||||
{
|
||||
private:
|
||||
struct base
|
||||
{
|
||||
virtual void operator()(
|
||||
void* dest, std::size_t bytes) const = 0;
|
||||
};
|
||||
|
||||
struct impl : base
|
||||
{
|
||||
void operator()(
|
||||
void* dest, std::size_t bytes) const override
|
||||
{
|
||||
char volatile* volatile p =
|
||||
const_cast<volatile char*>(
|
||||
reinterpret_cast<char*>(dest));
|
||||
if (bytes == 0)
|
||||
return;
|
||||
do
|
||||
{
|
||||
*p = 0;
|
||||
}
|
||||
while(*p++ == 0 && --bytes);
|
||||
}
|
||||
};
|
||||
|
||||
char buf_[sizeof(impl)];
|
||||
base& erase_;
|
||||
|
||||
public:
|
||||
secure_erase_impl()
|
||||
: erase_(*new(buf_) impl)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(
|
||||
void* dest, std::size_t bytes) const
|
||||
{
|
||||
return erase_(dest, bytes);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/** Guaranteed to fill memory with zeroes */
|
||||
template <class = void>
|
||||
void
|
||||
secure_erase (void* dest, std::size_t bytes)
|
||||
{
|
||||
static detail::secure_erase_impl const erase;
|
||||
erase(dest, bytes);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
44
src/ripple/beast/crypto/sha2.h
Normal file
44
src/ripple/beast/crypto/sha2.h
Normal file
@@ -0,0 +1,44 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_CRYPTO_SHA2_H_INCLUDED
|
||||
#define BEAST_CRYPTO_SHA2_H_INCLUDED
|
||||
|
||||
#include <ripple/beast/crypto/detail/mac_facade.h>
|
||||
#include <ripple/beast/crypto/detail/sha2_context.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
using sha256_hasher = detail::mac_facade<
|
||||
detail::sha256_context, false>;
|
||||
|
||||
// secure version
|
||||
using sha256_hasher_s = detail::mac_facade<
|
||||
detail::sha256_context, true>;
|
||||
|
||||
using sha512_hasher = detail::mac_facade<
|
||||
detail::sha512_context, false>;
|
||||
|
||||
// secure version
|
||||
using sha512_hasher_s = detail::mac_facade<
|
||||
detail::sha512_context, true>;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
56
src/ripple/beast/cxx17/type_traits.h
Normal file
56
src/ripple/beast/cxx17/type_traits.h
Normal file
@@ -0,0 +1,56 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_CXX17_TYPE_TRAITS_H_INCLUDED
|
||||
#define BEAST_CXX17_TYPE_TRAITS_H_INCLUDED
|
||||
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace std {
|
||||
|
||||
#ifndef _MSC_VER
|
||||
|
||||
template<class...>
|
||||
using void_t = void;
|
||||
|
||||
template<bool B>
|
||||
using bool_constant = std::integral_constant<bool, B>;
|
||||
|
||||
#endif
|
||||
|
||||
// Ideas from Howard Hinnant
|
||||
//
|
||||
// Specializations of is_constructible for pair and tuple which
|
||||
// work around an apparent defect in the standard that causes well
|
||||
// formed expressions involving pairs or tuples of non default-constructible
|
||||
// types to generate compile errors.
|
||||
//
|
||||
template <class T, class U>
|
||||
struct is_constructible <pair <T, U>>
|
||||
: integral_constant <bool,
|
||||
is_default_constructible <T>::value &&
|
||||
is_default_constructible <U>::value>
|
||||
{
|
||||
};
|
||||
|
||||
} // std
|
||||
|
||||
#endif
|
||||
465
src/ripple/beast/deprecated_http.h
Normal file
465
src/ripple/beast/deprecated_http.h
Normal file
@@ -0,0 +1,465 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_DEPRECATED_HTTP_H
|
||||
#define BEAST_DEPRECATED_HTTP_H
|
||||
|
||||
#include <beast/http/method.hpp>
|
||||
#include <beast/http/headers.hpp>
|
||||
#include <beast/http/basic_parser.hpp>
|
||||
#include <beast/http/detail/writes.hpp>
|
||||
#include <beast/detail/ci_char_traits.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/asio/streambuf.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace beast {
|
||||
namespace deprecated_http {
|
||||
|
||||
/** Container for the HTTP content-body. */
|
||||
class body
|
||||
{
|
||||
private:
|
||||
using buffer_type = boost::asio::streambuf;
|
||||
|
||||
// Hack: use unique_ptr because streambuf cant be moved
|
||||
std::unique_ptr <buffer_type> buf_;
|
||||
|
||||
public:
|
||||
using const_buffers_type = buffer_type::const_buffers_type;
|
||||
|
||||
body();
|
||||
body (body&& other);
|
||||
body& operator= (body&& other);
|
||||
|
||||
body (body const&) = delete;
|
||||
body& operator= (body const&) = delete;
|
||||
|
||||
template <class = void>
|
||||
void
|
||||
clear();
|
||||
|
||||
void
|
||||
write (void const* data, std::size_t bytes);
|
||||
|
||||
template <class ConstBufferSequence>
|
||||
void
|
||||
write (ConstBufferSequence const& buffers);
|
||||
|
||||
std::size_t
|
||||
size() const;
|
||||
|
||||
const_buffers_type
|
||||
data() const;
|
||||
};
|
||||
|
||||
template <class = void>
|
||||
std::string
|
||||
to_string (body const& b)
|
||||
{
|
||||
std::string s;
|
||||
auto const& data (b.data());
|
||||
auto const n (boost::asio::buffer_size (data));
|
||||
s.resize (n);
|
||||
boost::asio::buffer_copy (
|
||||
boost::asio::buffer (&s[0], n), data);
|
||||
return s;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
inline
|
||||
body::body()
|
||||
: buf_ (std::make_unique <buffer_type>())
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
body::body (body&& other)
|
||||
: buf_ (std::move(other.buf_))
|
||||
{
|
||||
other.clear();
|
||||
}
|
||||
|
||||
inline
|
||||
body&
|
||||
body::operator= (body&& other)
|
||||
{
|
||||
buf_ = std::move(other.buf_);
|
||||
other.clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class>
|
||||
void
|
||||
body::clear()
|
||||
{
|
||||
buf_ = std::make_unique <buffer_type>();
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
body::write (void const* data, std::size_t bytes)
|
||||
{
|
||||
buf_->commit (boost::asio::buffer_copy (buf_->prepare (bytes),
|
||||
boost::asio::const_buffers_1 (data, bytes)));
|
||||
}
|
||||
|
||||
template <class ConstBufferSequence>
|
||||
void
|
||||
body::write (ConstBufferSequence const& buffers)
|
||||
{
|
||||
for (auto const& buffer : buffers)
|
||||
write (boost::asio::buffer_cast <void const*> (buffer),
|
||||
boost::asio::buffer_size (buffer));
|
||||
}
|
||||
|
||||
inline
|
||||
std::size_t
|
||||
body::size() const
|
||||
{
|
||||
return buf_->size();
|
||||
}
|
||||
|
||||
inline
|
||||
auto
|
||||
body::data() const
|
||||
-> const_buffers_type
|
||||
{
|
||||
return buf_->data();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
inline
|
||||
std::pair<int, int>
|
||||
http_1_0()
|
||||
{
|
||||
return std::pair<int, int>(1, 0);
|
||||
}
|
||||
|
||||
inline
|
||||
std::pair<int, int>
|
||||
http_1_1()
|
||||
{
|
||||
return std::pair<int, int>(1, 1);
|
||||
}
|
||||
|
||||
class message
|
||||
{
|
||||
private:
|
||||
bool request_;
|
||||
|
||||
// request
|
||||
beast::http::method_t method_;
|
||||
std::string url_;
|
||||
|
||||
// response
|
||||
int status_;
|
||||
std::string reason_;
|
||||
|
||||
// message
|
||||
std::pair<int, int> version_;
|
||||
bool keep_alive_;
|
||||
bool upgrade_;
|
||||
|
||||
public:
|
||||
~message() = default;
|
||||
message (message const&) = default;
|
||||
message (message&& other) = default;
|
||||
message& operator= (message const&) = default;
|
||||
message& operator= (message&& other) = default;
|
||||
|
||||
template <class = void>
|
||||
message();
|
||||
|
||||
// Memberspace
|
||||
beast::http::headers<std::allocator<char>> headers;
|
||||
|
||||
bool
|
||||
request() const
|
||||
{
|
||||
return request_;
|
||||
}
|
||||
|
||||
void
|
||||
request (bool value)
|
||||
{
|
||||
request_ = value;
|
||||
}
|
||||
|
||||
// Request
|
||||
|
||||
void
|
||||
method (beast::http::method_t http_method)
|
||||
{
|
||||
method_ = http_method;
|
||||
}
|
||||
|
||||
beast::http::method_t
|
||||
method() const
|
||||
{
|
||||
return method_;
|
||||
}
|
||||
|
||||
void
|
||||
url (std::string const& s)
|
||||
{
|
||||
url_ = s;
|
||||
}
|
||||
|
||||
std::string const&
|
||||
url() const
|
||||
{
|
||||
return url_;
|
||||
}
|
||||
|
||||
/** Returns `false` if this is not the last message.
|
||||
When keep_alive returns `false`:
|
||||
* Server roles respond with a "Connection: close" header.
|
||||
* Client roles close the connection.
|
||||
*/
|
||||
bool
|
||||
keep_alive() const
|
||||
{
|
||||
return keep_alive_;
|
||||
}
|
||||
|
||||
/** Set the keep_alive setting. */
|
||||
void
|
||||
keep_alive (bool value)
|
||||
{
|
||||
keep_alive_ = value;
|
||||
}
|
||||
|
||||
/** Returns `true` if this is an HTTP Upgrade message.
|
||||
@note Upgrade messages have no content body.
|
||||
*/
|
||||
bool
|
||||
upgrade() const
|
||||
{
|
||||
return upgrade_;
|
||||
}
|
||||
|
||||
/** Set the upgrade setting. */
|
||||
void
|
||||
upgrade (bool value)
|
||||
{
|
||||
upgrade_ = value;
|
||||
}
|
||||
|
||||
int
|
||||
status() const
|
||||
{
|
||||
return status_;
|
||||
}
|
||||
|
||||
void
|
||||
status (int code)
|
||||
{
|
||||
status_ = code;
|
||||
}
|
||||
|
||||
std::string const&
|
||||
reason() const
|
||||
{
|
||||
return reason_;
|
||||
}
|
||||
|
||||
void
|
||||
reason (std::string const& text)
|
||||
{
|
||||
reason_ = text;
|
||||
}
|
||||
|
||||
// Message
|
||||
|
||||
void
|
||||
version (int major, int minor)
|
||||
{
|
||||
version_ = std::make_pair (major, minor);
|
||||
}
|
||||
|
||||
void
|
||||
version (std::pair<int, int> p)
|
||||
{
|
||||
version_ = p;
|
||||
}
|
||||
|
||||
std::pair<int, int>
|
||||
version() const
|
||||
{
|
||||
return version_;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class>
|
||||
message::message()
|
||||
: request_ (true)
|
||||
, method_ (beast::http::method_t::http_get)
|
||||
, url_ ("/")
|
||||
, status_ (200)
|
||||
, version_ (1, 1)
|
||||
, keep_alive_ (false)
|
||||
, upgrade_ (false)
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class Streambuf>
|
||||
void
|
||||
write (Streambuf& stream, message const& m)
|
||||
{
|
||||
if (m.request())
|
||||
{
|
||||
http::detail::write (stream, to_string(m.method()));
|
||||
http::detail::write (stream, " ");
|
||||
http::detail::write (stream, m.url());
|
||||
http::detail::write (stream, " HTTP/");
|
||||
http::detail::write (stream, std::to_string(m.version().first));
|
||||
http::detail::write (stream, ".");
|
||||
http::detail::write (stream, std::to_string(m.version().second));
|
||||
}
|
||||
else
|
||||
{
|
||||
http::detail::write (stream, "HTTP/");
|
||||
http::detail::write (stream, std::to_string(m.version().first));
|
||||
http::detail::write (stream, ".");
|
||||
http::detail::write (stream, std::to_string(m.version().second));
|
||||
http::detail::write (stream, " ");
|
||||
http::detail::write (stream, std::to_string(m.status()));
|
||||
http::detail::write (stream, " ");
|
||||
http::detail::write (stream, m.reason());
|
||||
}
|
||||
http::detail::write (stream, "\r\n");
|
||||
write_fields(stream, m.headers);
|
||||
http::detail::write (stream, "\r\n");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class parser
|
||||
: public beast::http::basic_parser<parser>
|
||||
{
|
||||
// friend class basic_parser<parser>;
|
||||
|
||||
message& m_;
|
||||
std::function<void(void const*, std::size_t)> write_body_;
|
||||
|
||||
public:
|
||||
parser(parser&&) = default;
|
||||
parser(parser const&) = delete;
|
||||
parser& operator=(parser&&) = delete;
|
||||
parser& operator=(parser const&) = delete;
|
||||
|
||||
/** Construct a parser for HTTP request or response.
|
||||
The headers plus request or status line are stored in message.
|
||||
The content-body, if any, is passed as a series of calls to
|
||||
the write_body function. Transfer encodings are applied before
|
||||
any data is passed to the write_body function.
|
||||
*/
|
||||
parser(std::function<void(void const*, std::size_t)> write_body,
|
||||
message& m, bool request)
|
||||
: basic_parser(request)
|
||||
, m_(m)
|
||||
, write_body_(std::move(write_body))
|
||||
{
|
||||
m_.request(request);
|
||||
}
|
||||
|
||||
parser(message& m, body& b, bool request)
|
||||
: basic_parser(request)
|
||||
, m_(m)
|
||||
{
|
||||
write_body_ = [&b](void const* data, std::size_t size)
|
||||
{
|
||||
b.write(data, size);
|
||||
};
|
||||
m_.request(request);
|
||||
}
|
||||
|
||||
//private:
|
||||
void
|
||||
on_start()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
on_headers_complete(error_code&)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
on_request(http::method_t method, std::string const& url,
|
||||
int major, int minor, bool keep_alive, bool upgrade)
|
||||
{
|
||||
m_.method(method);
|
||||
m_.url(url);
|
||||
m_.version(major, minor);
|
||||
m_.keep_alive(keep_alive);
|
||||
m_.upgrade(upgrade);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
on_response(int status, std::string const& text,
|
||||
int major, int minor, bool keep_alive, bool upgrade)
|
||||
{
|
||||
m_.status(status);
|
||||
m_.reason(text);
|
||||
m_.version(major, minor);
|
||||
m_.keep_alive(keep_alive);
|
||||
m_.upgrade(upgrade);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
on_field(std::string const& field, std::string const& value)
|
||||
{
|
||||
m_.headers.insert(field, value);
|
||||
}
|
||||
|
||||
void
|
||||
on_body(void const* data, std::size_t bytes, error_code&)
|
||||
{
|
||||
write_body_(data, bytes);
|
||||
}
|
||||
|
||||
void
|
||||
on_complete()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} // deprecated_http
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
52
src/ripple/beast/hash/endian.h
Normal file
52
src/ripple/beast/hash/endian.h
Normal file
@@ -0,0 +1,52 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2014, Howard Hinnant <howard.hinnant@gmail.com>,
|
||||
Vinnie Falco <vinnie.falco@gmail.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_HASH_ENDIAN_H_INCLUDED
|
||||
#define BEAST_HASH_ENDIAN_H_INCLUDED
|
||||
|
||||
namespace beast {
|
||||
|
||||
// endian provides answers to the following questions:
|
||||
// 1. Is this system big or little endian?
|
||||
// 2. Is the "desired endian" of some class or function the same as the
|
||||
// native endian?
|
||||
enum class endian
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
big = 1,
|
||||
little = 0,
|
||||
native = little
|
||||
#else
|
||||
native = __BYTE_ORDER__,
|
||||
little = __ORDER_LITTLE_ENDIAN__,
|
||||
big = __ORDER_BIG_ENDIAN__
|
||||
#endif
|
||||
};
|
||||
|
||||
static_assert(endian::native == endian::little ||
|
||||
endian::native == endian::big,
|
||||
"endian::native shall be one of endian::little or endian::big");
|
||||
|
||||
static_assert(endian::big != endian::little,
|
||||
"endian::big and endian::little shall have different values");
|
||||
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
70
src/ripple/beast/hash/fnv1a.h
Normal file
70
src/ripple/beast/hash/fnv1a.h
Normal file
@@ -0,0 +1,70 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2014, Howard Hinnant <howard.hinnant@gmail.com>,
|
||||
Vinnie Falco <vinnie.falco@gmail.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_HASH_FNV1A_H_INCLUDED
|
||||
#define BEAST_HASH_FNV1A_H_INCLUDED
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace beast {
|
||||
|
||||
// See http://www.isthe.com/chongo/tech/comp/fnv/
|
||||
//
|
||||
class fnv1a
|
||||
{
|
||||
private:
|
||||
std::uint64_t state_ = 14695981039346656037ULL;
|
||||
|
||||
public:
|
||||
using result_type = std::size_t;
|
||||
|
||||
fnv1a() = default;
|
||||
|
||||
template <class Seed,
|
||||
std::enable_if_t<
|
||||
std::is_unsigned<Seed>::value>* = nullptr>
|
||||
explicit
|
||||
fnv1a (Seed seed)
|
||||
{
|
||||
append (&seed, sizeof(seed));
|
||||
}
|
||||
|
||||
void
|
||||
operator() (void const* key, std::size_t len) noexcept
|
||||
{
|
||||
unsigned char const* p =
|
||||
static_cast<unsigned char const*>(key);
|
||||
unsigned char const* const e = p + len;
|
||||
for (; p < e; ++p)
|
||||
state_ = (state_ ^ *p) * 1099511628211ULL;
|
||||
}
|
||||
|
||||
explicit
|
||||
operator std::size_t() noexcept
|
||||
{
|
||||
return static_cast<std::size_t>(state_);
|
||||
}
|
||||
};
|
||||
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
516
src/ripple/beast/hash/hash_append.h
Normal file
516
src/ripple/beast/hash/hash_append.h
Normal file
@@ -0,0 +1,516 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2014, Howard Hinnant <howard.hinnant@gmail.com>,
|
||||
Vinnie Falco <vinnie.falco@gmail.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_HASH_HASH_APPEND_H_INCLUDED
|
||||
#define BEAST_HASH_HASH_APPEND_H_INCLUDED
|
||||
|
||||
#include <ripple/beast/hash/endian.h>
|
||||
#include <ripple/beast/hash/meta.h>
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <system_error>
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace beast {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class T>
|
||||
/*constexpr*/
|
||||
inline
|
||||
void
|
||||
reverse_bytes(T& t)
|
||||
{
|
||||
unsigned char* bytes = static_cast<unsigned char*>(std::memmove(std::addressof(t),
|
||||
std::addressof(t),
|
||||
sizeof(T)));
|
||||
for (unsigned i = 0; i < sizeof(T)/2; ++i)
|
||||
std::swap(bytes[i], bytes[sizeof(T)-1-i]);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
/*constexpr*/
|
||||
inline
|
||||
void
|
||||
maybe_reverse_bytes(T& t, std::false_type)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
/*constexpr*/
|
||||
inline
|
||||
void
|
||||
maybe_reverse_bytes(T& t, std::true_type)
|
||||
{
|
||||
reverse_bytes(t);
|
||||
}
|
||||
|
||||
template <class T, class Hasher>
|
||||
/*constexpr*/
|
||||
inline
|
||||
void
|
||||
maybe_reverse_bytes(T& t, Hasher&)
|
||||
{
|
||||
maybe_reverse_bytes(t, std::integral_constant<bool,
|
||||
Hasher::endian != endian::native>{});
|
||||
}
|
||||
|
||||
} // detail
|
||||
|
||||
// is_uniquely_represented<T>
|
||||
|
||||
// A type T is contiguously hashable if for all combinations of two values of
|
||||
// a type, say x and y, if x == y, then it must also be true that
|
||||
// memcmp(addressof(x), addressof(y), sizeof(T)) == 0. I.e. if x == y,
|
||||
// then x and y have the same bit pattern representation.
|
||||
|
||||
template <class T>
|
||||
struct is_uniquely_represented
|
||||
: public std::integral_constant<bool, std::is_integral<T>::value ||
|
||||
std::is_enum<T>::value ||
|
||||
std::is_pointer<T>::value>
|
||||
{};
|
||||
|
||||
template <class T>
|
||||
struct is_uniquely_represented<T const>
|
||||
: public is_uniquely_represented<T>
|
||||
{};
|
||||
|
||||
template <class T>
|
||||
struct is_uniquely_represented<T volatile>
|
||||
: public is_uniquely_represented<T>
|
||||
{};
|
||||
|
||||
template <class T>
|
||||
struct is_uniquely_represented<T const volatile>
|
||||
: public is_uniquely_represented<T>
|
||||
{};
|
||||
|
||||
// is_uniquely_represented<std::pair<T, U>>
|
||||
|
||||
template <class T, class U>
|
||||
struct is_uniquely_represented<std::pair<T, U>>
|
||||
: public std::integral_constant<bool, is_uniquely_represented<T>::value &&
|
||||
is_uniquely_represented<U>::value &&
|
||||
sizeof(T) + sizeof(U) == sizeof(std::pair<T, U>)>
|
||||
{
|
||||
};
|
||||
|
||||
// is_uniquely_represented<std::tuple<T...>>
|
||||
|
||||
template <class ...T>
|
||||
struct is_uniquely_represented<std::tuple<T...>>
|
||||
: public std::integral_constant<bool,
|
||||
static_and<is_uniquely_represented<T>::value...>::value &&
|
||||
static_sum<sizeof(T)...>::value == sizeof(std::tuple<T...>)>
|
||||
{
|
||||
};
|
||||
|
||||
// is_uniquely_represented<T[N]>
|
||||
|
||||
template <class T, std::size_t N>
|
||||
struct is_uniquely_represented<T[N]>
|
||||
: public is_uniquely_represented<T>
|
||||
{
|
||||
};
|
||||
|
||||
// is_uniquely_represented<std::array<T, N>>
|
||||
|
||||
template <class T, std::size_t N>
|
||||
struct is_uniquely_represented<std::array<T, N>>
|
||||
: public std::integral_constant<bool, is_uniquely_represented<T>::value &&
|
||||
sizeof(T)*N == sizeof(std::array<T, N>)>
|
||||
{
|
||||
};
|
||||
|
||||
/** Metafunction returning `true` if the type can be hashed in one call.
|
||||
|
||||
For `is_contiguously_hashable<T>::value` to be true, then for every
|
||||
combination of possible values of `T` held in `x` and `y`,
|
||||
if `x == y`, then it must be true that `memcmp(&x, &y, sizeof(T))`
|
||||
return 0; i.e. that `x` and `y` are represented by the same bit pattern.
|
||||
|
||||
For example: A two's complement `int` should be contiguously hashable.
|
||||
Every bit pattern produces a unique value that does not compare equal to
|
||||
any other bit pattern's value. A IEEE floating point should not be
|
||||
contiguously hashable because -0. and 0. have different bit patterns,
|
||||
though they compare equal.
|
||||
*/
|
||||
/** @{ */
|
||||
template <class T, class HashAlgorithm>
|
||||
struct is_contiguously_hashable
|
||||
: public std::integral_constant<bool, is_uniquely_represented<T>::value &&
|
||||
(sizeof(T) == 1 ||
|
||||
HashAlgorithm::endian == endian::native)>
|
||||
{};
|
||||
|
||||
template <class T, std::size_t N, class HashAlgorithm>
|
||||
struct is_contiguously_hashable<T[N], HashAlgorithm>
|
||||
: public std::integral_constant<bool, is_uniquely_represented<T[N]>::value &&
|
||||
(sizeof(T) == 1 ||
|
||||
HashAlgorithm::endian == endian::native)>
|
||||
{};
|
||||
/** @} */
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Logically concatenate input data to a `Hasher`.
|
||||
|
||||
Hasher requirements:
|
||||
|
||||
`X` is the type `Hasher`
|
||||
`h` is a value of type `x`
|
||||
`p` is a value convertible to `void const*`
|
||||
`n` is a value of type `std::size_t`, greater than zero
|
||||
|
||||
Expression:
|
||||
`h.append (p, n);`
|
||||
Throws:
|
||||
Never
|
||||
Effect:
|
||||
Adds the input data to the hasher state.
|
||||
|
||||
Expression:
|
||||
`static_cast<std::size_t>(j)`
|
||||
Throws:
|
||||
Never
|
||||
Effect:
|
||||
Returns the reslting hash of all the input data.
|
||||
*/
|
||||
/** @{ */
|
||||
|
||||
// scalars
|
||||
|
||||
template <class Hasher, class T>
|
||||
inline
|
||||
std::enable_if_t
|
||||
<
|
||||
is_contiguously_hashable<T, Hasher>::value
|
||||
>
|
||||
hash_append(Hasher& h, T const& t) noexcept
|
||||
{
|
||||
h(std::addressof(t), sizeof(t));
|
||||
}
|
||||
|
||||
template <class Hasher, class T>
|
||||
inline
|
||||
std::enable_if_t
|
||||
<
|
||||
!is_contiguously_hashable<T, Hasher>::value &&
|
||||
(std::is_integral<T>::value || std::is_pointer<T>::value || std::is_enum<T>::value)
|
||||
>
|
||||
hash_append(Hasher& h, T t) noexcept
|
||||
{
|
||||
detail::reverse_bytes(t);
|
||||
h(std::addressof(t), sizeof(t));
|
||||
}
|
||||
|
||||
template <class Hasher, class T>
|
||||
inline
|
||||
std::enable_if_t
|
||||
<
|
||||
std::is_floating_point<T>::value
|
||||
>
|
||||
hash_append(Hasher& h, T t) noexcept
|
||||
{
|
||||
if (t == 0)
|
||||
t = 0;
|
||||
detail::maybe_reverse_bytes(t, h);
|
||||
h(&t, sizeof(t));
|
||||
}
|
||||
|
||||
template <class Hasher>
|
||||
inline
|
||||
void
|
||||
hash_append(Hasher& h, std::nullptr_t) noexcept
|
||||
{
|
||||
void const* p = nullptr;
|
||||
detail::maybe_reverse_bytes(p, h);
|
||||
h(&p, sizeof(p));
|
||||
}
|
||||
|
||||
// Forward declarations for ADL purposes
|
||||
|
||||
template <class Hasher, class T, std::size_t N>
|
||||
std::enable_if_t
|
||||
<
|
||||
!is_contiguously_hashable<T, Hasher>::value
|
||||
>
|
||||
hash_append(Hasher& h, T (&a)[N]) noexcept;
|
||||
|
||||
template <class Hasher, class CharT, class Traits, class Alloc>
|
||||
std::enable_if_t
|
||||
<
|
||||
!is_contiguously_hashable<CharT, Hasher>::value
|
||||
>
|
||||
hash_append(Hasher& h, std::basic_string<CharT, Traits, Alloc> const& s) noexcept;
|
||||
|
||||
template <class Hasher, class CharT, class Traits, class Alloc>
|
||||
std::enable_if_t
|
||||
<
|
||||
is_contiguously_hashable<CharT, Hasher>::value
|
||||
>
|
||||
hash_append(Hasher& h, std::basic_string<CharT, Traits, Alloc> const& s) noexcept;
|
||||
|
||||
template <class Hasher, class T, class U>
|
||||
std::enable_if_t
|
||||
<
|
||||
!is_contiguously_hashable<std::pair<T, U>, Hasher>::value
|
||||
>
|
||||
hash_append (Hasher& h, std::pair<T, U> const& p) noexcept;
|
||||
|
||||
template <class Hasher, class T, class Alloc>
|
||||
std::enable_if_t
|
||||
<
|
||||
!is_contiguously_hashable<T, Hasher>::value
|
||||
>
|
||||
hash_append(Hasher& h, std::vector<T, Alloc> const& v) noexcept;
|
||||
|
||||
template <class Hasher, class T, class Alloc>
|
||||
std::enable_if_t
|
||||
<
|
||||
is_contiguously_hashable<T, Hasher>::value
|
||||
>
|
||||
hash_append(Hasher& h, std::vector<T, Alloc> const& v) noexcept;
|
||||
|
||||
template <class Hasher, class T, std::size_t N>
|
||||
std::enable_if_t
|
||||
<
|
||||
!is_contiguously_hashable<std::array<T, N>, Hasher>::value
|
||||
>
|
||||
hash_append(Hasher& h, std::array<T, N> const& a) noexcept;
|
||||
|
||||
template <class Hasher, class ...T>
|
||||
std::enable_if_t
|
||||
<
|
||||
!is_contiguously_hashable<std::tuple<T...>, Hasher>::value
|
||||
>
|
||||
hash_append(Hasher& h, std::tuple<T...> const& t) noexcept;
|
||||
|
||||
template <class Hasher, class Key, class T, class Hash, class Pred, class Alloc>
|
||||
void
|
||||
hash_append(Hasher& h, std::unordered_map<Key, T, Hash, Pred, Alloc> const& m);
|
||||
|
||||
template <class Hasher, class Key, class Hash, class Pred, class Alloc>
|
||||
void
|
||||
hash_append(Hasher& h, std::unordered_set<Key, Hash, Pred, Alloc> const& s);
|
||||
|
||||
template <class Hasher, class T0, class T1, class ...T>
|
||||
void
|
||||
hash_append (Hasher& h, T0 const& t0, T1 const& t1, T const& ...t) noexcept;
|
||||
|
||||
// c-array
|
||||
|
||||
template <class Hasher, class T, std::size_t N>
|
||||
std::enable_if_t
|
||||
<
|
||||
!is_contiguously_hashable<T, Hasher>::value
|
||||
>
|
||||
hash_append(Hasher& h, T (&a)[N]) noexcept
|
||||
{
|
||||
for (auto const& t : a)
|
||||
hash_append(h, t);
|
||||
}
|
||||
|
||||
// basic_string
|
||||
|
||||
template <class Hasher, class CharT, class Traits, class Alloc>
|
||||
inline
|
||||
std::enable_if_t
|
||||
<
|
||||
!is_contiguously_hashable<CharT, Hasher>::value
|
||||
>
|
||||
hash_append(Hasher& h, std::basic_string<CharT, Traits, Alloc> const& s) noexcept
|
||||
{
|
||||
for (auto c : s)
|
||||
hash_append(h, c);
|
||||
hash_append(h, s.size());
|
||||
}
|
||||
|
||||
template <class Hasher, class CharT, class Traits, class Alloc>
|
||||
inline
|
||||
std::enable_if_t
|
||||
<
|
||||
is_contiguously_hashable<CharT, Hasher>::value
|
||||
>
|
||||
hash_append(Hasher& h, std::basic_string<CharT, Traits, Alloc> const& s) noexcept
|
||||
{
|
||||
h(s.data(), s.size()*sizeof(CharT));
|
||||
hash_append(h, s.size());
|
||||
}
|
||||
|
||||
// pair
|
||||
|
||||
template <class Hasher, class T, class U>
|
||||
inline
|
||||
std::enable_if_t
|
||||
<
|
||||
!is_contiguously_hashable<std::pair<T, U>, Hasher>::value
|
||||
>
|
||||
hash_append (Hasher& h, std::pair<T, U> const& p) noexcept
|
||||
{
|
||||
hash_append (h, p.first, p.second);
|
||||
}
|
||||
|
||||
// vector
|
||||
|
||||
template <class Hasher, class T, class Alloc>
|
||||
inline
|
||||
std::enable_if_t
|
||||
<
|
||||
!is_contiguously_hashable<T, Hasher>::value
|
||||
>
|
||||
hash_append(Hasher& h, std::vector<T, Alloc> const& v) noexcept
|
||||
{
|
||||
for (auto const& t : v)
|
||||
hash_append(h, t);
|
||||
hash_append(h, v.size());
|
||||
}
|
||||
|
||||
template <class Hasher, class T, class Alloc>
|
||||
inline
|
||||
std::enable_if_t
|
||||
<
|
||||
is_contiguously_hashable<T, Hasher>::value
|
||||
>
|
||||
hash_append(Hasher& h, std::vector<T, Alloc> const& v) noexcept
|
||||
{
|
||||
h(v.data(), v.size()*sizeof(T));
|
||||
hash_append(h, v.size());
|
||||
}
|
||||
|
||||
// array
|
||||
|
||||
template <class Hasher, class T, std::size_t N>
|
||||
std::enable_if_t
|
||||
<
|
||||
!is_contiguously_hashable<std::array<T, N>, Hasher>::value
|
||||
>
|
||||
hash_append(Hasher& h, std::array<T, N> const& a) noexcept
|
||||
{
|
||||
for (auto const& t : a)
|
||||
hash_append(h, t);
|
||||
}
|
||||
|
||||
// tuple
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline
|
||||
void
|
||||
for_each_item(...) noexcept
|
||||
{
|
||||
}
|
||||
|
||||
template <class Hasher, class T>
|
||||
inline
|
||||
int
|
||||
hash_one(Hasher& h, T const& t) noexcept
|
||||
{
|
||||
hash_append(h, t);
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class Hasher, class ...T, std::size_t ...I>
|
||||
inline
|
||||
void
|
||||
tuple_hash(Hasher& h, std::tuple<T...> const& t, std::index_sequence<I...>) noexcept
|
||||
{
|
||||
for_each_item(hash_one(h, std::get<I>(t))...);
|
||||
}
|
||||
|
||||
} // detail
|
||||
|
||||
template <class Hasher, class ...T>
|
||||
inline
|
||||
std::enable_if_t
|
||||
<
|
||||
!is_contiguously_hashable<std::tuple<T...>, Hasher>::value
|
||||
>
|
||||
hash_append(Hasher& h, std::tuple<T...> const& t) noexcept
|
||||
{
|
||||
detail::tuple_hash(h, t, std::index_sequence_for<T...>{});
|
||||
}
|
||||
|
||||
// shared_ptr
|
||||
|
||||
template <class Hasher, class T>
|
||||
inline
|
||||
void
|
||||
hash_append (Hasher& h, std::shared_ptr<T> const& p) noexcept
|
||||
{
|
||||
hash_append(h, p.get());
|
||||
}
|
||||
|
||||
// chrono
|
||||
|
||||
template <class Hasher, class Rep, class Period>
|
||||
inline
|
||||
void
|
||||
hash_append (Hasher& h, std::chrono::duration<Rep, Period> const& d) noexcept
|
||||
{
|
||||
hash_append(h, d.count());
|
||||
}
|
||||
|
||||
template <class Hasher, class Clock, class Duration>
|
||||
inline
|
||||
void
|
||||
hash_append (Hasher& h, std::chrono::time_point<Clock, Duration> const& tp) noexcept
|
||||
{
|
||||
hash_append(h, tp.time_since_epoch());
|
||||
}
|
||||
|
||||
// variadic
|
||||
|
||||
template <class Hasher, class T0, class T1, class ...T>
|
||||
inline
|
||||
void
|
||||
hash_append (Hasher& h, T0 const& t0, T1 const& t1, T const& ...t) noexcept
|
||||
{
|
||||
hash_append(h, t0);
|
||||
hash_append(h, t1, t...);
|
||||
}
|
||||
|
||||
// error_code
|
||||
|
||||
template <class HashAlgorithm>
|
||||
inline
|
||||
void
|
||||
hash_append(HashAlgorithm& h, std::error_code const& ec)
|
||||
{
|
||||
hash_append(h, ec.value(), &ec.category());
|
||||
}
|
||||
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
85
src/ripple/beast/hash/impl/hash_speed_test.cpp
Normal file
85
src/ripple/beast/hash/impl/hash_speed_test.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#if BEAST_INCLUDE_BEASTCONFIG
|
||||
#include <BeastConfig.h>
|
||||
#endif
|
||||
#include <beast/container/fnv1a.h>
|
||||
#include <beast/container/siphash.h>
|
||||
#include <beast/container/xxhasher.h>
|
||||
#include <beast/rngfill.h>
|
||||
#include <beast/xor_shift_engine.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <random>
|
||||
|
||||
namespace beast {
|
||||
|
||||
class hash_speed_test : public beast::unit_test::suite
|
||||
{
|
||||
public:
|
||||
using clock_type =
|
||||
std::chrono::high_resolution_clock;
|
||||
template <class Hasher, std::size_t KeySize>
|
||||
void
|
||||
test (std::string const& what, std::size_t n)
|
||||
{
|
||||
using namespace std;
|
||||
using namespace std::chrono;
|
||||
xor_shift_engine g(1);
|
||||
array<std::uint8_t, KeySize> key;
|
||||
auto const start = clock_type::now();
|
||||
while(n--)
|
||||
{
|
||||
rngfill (key, g);
|
||||
Hasher h;
|
||||
h.append(key.data(), KeySize);
|
||||
volatile size_t temp =
|
||||
static_cast<std::size_t>(h);
|
||||
(void)temp;
|
||||
}
|
||||
auto const elapsed = clock_type::now() - start;
|
||||
log << setw(12) << what << " " <<
|
||||
duration<double>(elapsed) << "s";
|
||||
}
|
||||
|
||||
void
|
||||
run()
|
||||
{
|
||||
enum
|
||||
{
|
||||
N = 100000000
|
||||
};
|
||||
|
||||
#if ! BEAST_NO_XXHASH
|
||||
test<xxhasher,32> ("xxhash", N);
|
||||
#endif
|
||||
test<fnv1a,32> ("fnv1a", N);
|
||||
test<siphash,32> ("siphash", N);
|
||||
pass();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE_MANUAL(hash_speed,container,beast);
|
||||
|
||||
} // beast
|
||||
165
src/ripple/beast/hash/impl/siphash.cpp
Normal file
165
src/ripple/beast/hash/impl/siphash.cpp
Normal file
@@ -0,0 +1,165 @@
|
||||
//------------------------------- siphash.h ------------------------------------
|
||||
//
|
||||
// This software is in the public domain. The only restriction on its use is
|
||||
// that no one can remove it from the public domain by claiming ownership of it,
|
||||
// including the original authors.
|
||||
//
|
||||
// There is no warranty of correctness on the software contained herein. Use
|
||||
// at your own risk.
|
||||
//
|
||||
// Derived from:
|
||||
//
|
||||
// SipHash reference C implementation
|
||||
//
|
||||
// Written in 2012 by Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com>
|
||||
// Daniel J. Bernstein <djb@cr.yp.to>
|
||||
//
|
||||
// To the extent possible under law, the author(s) have dedicated all copyright
|
||||
// and related and neighboring rights to this software to the public domain
|
||||
// worldwide. This software is distributed without any warranty.
|
||||
//
|
||||
// You should have received a copy of the CC0 Public Domain Dedication along
|
||||
// with this software. If not, see
|
||||
// <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <ripple/beast/hash/siphash.h>
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
// namespace acme is used to demonstrate example code. It is not proposed.
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
using u64 = std::uint64_t;
|
||||
using u32 = std::uint32_t;
|
||||
using u8 = std::uint8_t;
|
||||
|
||||
inline
|
||||
u64
|
||||
rotl(u64 x, u64 b)
|
||||
{
|
||||
return (x << b) | (x >> (64 - b));
|
||||
}
|
||||
|
||||
inline
|
||||
u64
|
||||
u8to64_le(const u8* p)
|
||||
{
|
||||
#if BEAST_LITTLE_ENDIAN
|
||||
return *static_cast<u64 const*>(static_cast<void const*>(p));
|
||||
#else
|
||||
return static_cast<u64>(p[7]) << 56 | static_cast<u64>(p[6]) << 48 |
|
||||
static_cast<u64>(p[5]) << 40 | static_cast<u64>(p[4]) << 32 |
|
||||
static_cast<u64>(p[3]) << 24 | static_cast<u64>(p[2]) << 16 |
|
||||
static_cast<u64>(p[1]) << 8 | static_cast<u64>(p[0]);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
sipround(u64& v0, u64& v1, u64& v2, u64& v3)
|
||||
{
|
||||
v0 += v1;
|
||||
v1 = rotl(v1, 13);
|
||||
v1 ^= v0;
|
||||
v0 = rotl(v0, 32);
|
||||
v2 += v3;
|
||||
v3 = rotl(v3, 16);
|
||||
v3 ^= v2;
|
||||
v0 += v3;
|
||||
v3 = rotl(v3, 21);
|
||||
v3 ^= v0;
|
||||
v2 += v1;
|
||||
v1 = rotl(v1, 17);
|
||||
v1 ^= v2;
|
||||
v2 = rotl(v2, 32);
|
||||
}
|
||||
|
||||
} // detail
|
||||
|
||||
siphash::siphash(std::uint64_t k0, std::uint64_t k1) noexcept
|
||||
{
|
||||
v3_ ^= k1;
|
||||
v2_ ^= k0;
|
||||
v1_ ^= k1;
|
||||
v0_ ^= k0;
|
||||
}
|
||||
|
||||
void
|
||||
siphash::operator() (void const* key, std::size_t inlen) noexcept
|
||||
{
|
||||
using namespace detail;
|
||||
u8 const* in = static_cast<const u8*>(key);
|
||||
total_length_ += inlen;
|
||||
if (bufsize_ + inlen < 8)
|
||||
{
|
||||
std::copy(in, in+inlen, buf_ + bufsize_);
|
||||
bufsize_ += inlen;
|
||||
return;
|
||||
}
|
||||
if (bufsize_ > 0)
|
||||
{
|
||||
auto t = 8 - bufsize_;
|
||||
std::copy(in, in+t, buf_ + bufsize_);
|
||||
u64 m = u8to64_le( buf_ );
|
||||
v3_ ^= m;
|
||||
sipround(v0_, v1_, v2_, v3_);
|
||||
sipround(v0_, v1_, v2_, v3_);
|
||||
v0_ ^= m;
|
||||
in += t;
|
||||
inlen -= t;
|
||||
}
|
||||
bufsize_ = inlen & 7;
|
||||
u8 const* const end = in + (inlen - bufsize_);
|
||||
for ( ; in != end; in += 8 )
|
||||
{
|
||||
u64 m = u8to64_le( in );
|
||||
v3_ ^= m;
|
||||
sipround(v0_, v1_, v2_, v3_);
|
||||
sipround(v0_, v1_, v2_, v3_);
|
||||
v0_ ^= m;
|
||||
}
|
||||
std::copy(end, end + bufsize_, buf_);
|
||||
}
|
||||
|
||||
siphash::operator std::size_t() noexcept
|
||||
{
|
||||
using namespace detail;
|
||||
std::size_t b = static_cast<u64>(total_length_) << 56;
|
||||
switch(bufsize_)
|
||||
{
|
||||
case 7:
|
||||
b |= static_cast<u64>(buf_[6]) << 48;
|
||||
case 6:
|
||||
b |= static_cast<u64>(buf_[5]) << 40;
|
||||
case 5:
|
||||
b |= static_cast<u64>(buf_[4]) << 32;
|
||||
case 4:
|
||||
b |= static_cast<u64>(buf_[3]) << 24;
|
||||
case 3:
|
||||
b |= static_cast<u64>(buf_[2]) << 16;
|
||||
case 2:
|
||||
b |= static_cast<u64>(buf_[1]) << 8;
|
||||
case 1:
|
||||
b |= static_cast<u64>(buf_[0]);
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
v3_ ^= b;
|
||||
sipround(v0_, v1_, v2_, v3_);
|
||||
sipround(v0_, v1_, v2_, v3_);
|
||||
v0_ ^= b;
|
||||
v2_ ^= 0xff;
|
||||
sipround(v0_, v1_, v2_, v3_);
|
||||
sipround(v0_, v1_, v2_, v3_);
|
||||
sipround(v0_, v1_, v2_, v3_);
|
||||
sipround(v0_, v1_, v2_, v3_);
|
||||
b = v0_ ^ v1_ ^ v2_ ^ v3_;
|
||||
return b;
|
||||
}
|
||||
|
||||
} // beast
|
||||
361
src/ripple/beast/hash/impl/spookyv2.cpp
Normal file
361
src/ripple/beast/hash/impl/spookyv2.cpp
Normal file
@@ -0,0 +1,361 @@
|
||||
// Spooky Hash
|
||||
// A 128-bit noncryptographic hash, for checksums and table lookup
|
||||
// By Bob Jenkins. Public domain.
|
||||
// Oct 31 2010: published framework, disclaimer ShortHash isn't right
|
||||
// Nov 7 2010: disabled ShortHash
|
||||
// Oct 31 2011: replace End, ShortMix, ShortEnd, enable ShortHash again
|
||||
// April 10 2012: buffer overflow on platforms without unaligned reads
|
||||
// July 12 2012: was passing out variables in final to in/out in short
|
||||
// July 30 2012: I reintroduced the buffer overflow
|
||||
// August 5 2012: SpookyV2: d = should be d += in short hash, and remove extra mix from long hash
|
||||
|
||||
#include <memory.h>
|
||||
#include <ripple/beast/hash/impl/spookyv2.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4127) // conditional expression is constant
|
||||
#pragma warning (disable: 4244) // conversion from 'size_t' to 'uint8', possible loss of data
|
||||
#endif
|
||||
|
||||
#define ALLOW_UNALIGNED_READS 1
|
||||
|
||||
//
|
||||
// short hash ... it could be used on any message,
|
||||
// but it's used by Spooky just for short messages.
|
||||
//
|
||||
void SpookyHash::Short(
|
||||
const void *message,
|
||||
size_t length,
|
||||
uint64 *hash1,
|
||||
uint64 *hash2)
|
||||
{
|
||||
uint64 buf[2*sc_numVars];
|
||||
union
|
||||
{
|
||||
const uint8 *p8;
|
||||
uint32 *p32;
|
||||
uint64 *p64;
|
||||
size_t i;
|
||||
} u;
|
||||
|
||||
u.p8 = (const uint8 *)message;
|
||||
|
||||
if (!ALLOW_UNALIGNED_READS && (u.i & 0x7))
|
||||
{
|
||||
memcpy(buf, message, length);
|
||||
u.p64 = buf;
|
||||
}
|
||||
|
||||
size_t remainder = length%32;
|
||||
uint64 a=*hash1;
|
||||
uint64 b=*hash2;
|
||||
uint64 c=sc_const;
|
||||
uint64 d=sc_const;
|
||||
|
||||
if (length > 15)
|
||||
{
|
||||
const uint64 *end = u.p64 + (length/32)*4;
|
||||
|
||||
// handle all complete sets of 32 bytes
|
||||
for (; u.p64 < end; u.p64 += 4)
|
||||
{
|
||||
c += u.p64[0];
|
||||
d += u.p64[1];
|
||||
ShortMix(a,b,c,d);
|
||||
a += u.p64[2];
|
||||
b += u.p64[3];
|
||||
}
|
||||
|
||||
//Handle the case of 16+ remaining bytes.
|
||||
if (remainder >= 16)
|
||||
{
|
||||
c += u.p64[0];
|
||||
d += u.p64[1];
|
||||
ShortMix(a,b,c,d);
|
||||
u.p64 += 2;
|
||||
remainder -= 16;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle the last 0..15 bytes, and its length
|
||||
d += ((uint64)length) << 56;
|
||||
switch (remainder)
|
||||
{
|
||||
case 15:
|
||||
d += ((uint64)u.p8[14]) << 48;
|
||||
case 14:
|
||||
d += ((uint64)u.p8[13]) << 40;
|
||||
case 13:
|
||||
d += ((uint64)u.p8[12]) << 32;
|
||||
case 12:
|
||||
d += u.p32[2];
|
||||
c += u.p64[0];
|
||||
break;
|
||||
case 11:
|
||||
d += ((uint64)u.p8[10]) << 16;
|
||||
case 10:
|
||||
d += ((uint64)u.p8[9]) << 8;
|
||||
case 9:
|
||||
d += (uint64)u.p8[8];
|
||||
case 8:
|
||||
c += u.p64[0];
|
||||
break;
|
||||
case 7:
|
||||
c += ((uint64)u.p8[6]) << 48;
|
||||
case 6:
|
||||
c += ((uint64)u.p8[5]) << 40;
|
||||
case 5:
|
||||
c += ((uint64)u.p8[4]) << 32;
|
||||
case 4:
|
||||
c += u.p32[0];
|
||||
break;
|
||||
case 3:
|
||||
c += ((uint64)u.p8[2]) << 16;
|
||||
case 2:
|
||||
c += ((uint64)u.p8[1]) << 8;
|
||||
case 1:
|
||||
c += (uint64)u.p8[0];
|
||||
break;
|
||||
case 0:
|
||||
c += sc_const;
|
||||
d += sc_const;
|
||||
}
|
||||
ShortEnd(a,b,c,d);
|
||||
*hash1 = a;
|
||||
*hash2 = b;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// do the whole hash in one call
|
||||
void SpookyHash::Hash128(
|
||||
const void *message,
|
||||
size_t length,
|
||||
uint64 *hash1,
|
||||
uint64 *hash2)
|
||||
{
|
||||
if (length < sc_bufSize)
|
||||
{
|
||||
Short(message, length, hash1, hash2);
|
||||
return;
|
||||
}
|
||||
|
||||
uint64 h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11;
|
||||
uint64 buf[sc_numVars];
|
||||
uint64 *end;
|
||||
union
|
||||
{
|
||||
const uint8 *p8;
|
||||
uint64 *p64;
|
||||
size_t i;
|
||||
} u;
|
||||
size_t remainder;
|
||||
|
||||
h0=h3=h6=h9 = *hash1;
|
||||
h1=h4=h7=h10 = *hash2;
|
||||
h2=h5=h8=h11 = sc_const;
|
||||
|
||||
u.p8 = (const uint8 *)message;
|
||||
end = u.p64 + (length/sc_blockSize)*sc_numVars;
|
||||
|
||||
// handle all whole sc_blockSize blocks of bytes
|
||||
if (ALLOW_UNALIGNED_READS || ((u.i & 0x7) == 0))
|
||||
{
|
||||
while (u.p64 < end)
|
||||
{
|
||||
Mix(u.p64, h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11);
|
||||
u.p64 += sc_numVars;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (u.p64 < end)
|
||||
{
|
||||
memcpy(buf, u.p64, sc_blockSize);
|
||||
Mix(buf, h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11);
|
||||
u.p64 += sc_numVars;
|
||||
}
|
||||
}
|
||||
|
||||
// handle the last partial block of sc_blockSize bytes
|
||||
remainder = (length - ((const uint8 *)end-(const uint8 *)message));
|
||||
memcpy(buf, end, remainder);
|
||||
memset(((uint8 *)buf)+remainder, 0, sc_blockSize-remainder);
|
||||
((uint8 *)buf)[sc_blockSize-1] =
|
||||
static_cast<uint8>(remainder);
|
||||
|
||||
// do some final mixing
|
||||
End(buf, h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11);
|
||||
*hash1 = h0;
|
||||
*hash2 = h1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// init spooky state
|
||||
void SpookyHash::Init(uint64 seed1, uint64 seed2)
|
||||
{
|
||||
m_length = 0;
|
||||
m_remainder = 0;
|
||||
m_state[0] = seed1;
|
||||
m_state[1] = seed2;
|
||||
}
|
||||
|
||||
|
||||
// add a message fragment to the state
|
||||
void SpookyHash::Update(const void *message, size_t length)
|
||||
{
|
||||
uint64 h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11;
|
||||
size_t newLength = length + m_remainder;
|
||||
uint8 remainder;
|
||||
union
|
||||
{
|
||||
const uint8 *p8;
|
||||
uint64 *p64;
|
||||
size_t i;
|
||||
} u;
|
||||
const uint64 *end;
|
||||
|
||||
// Is this message fragment too short? If it is, stuff it away.
|
||||
if (newLength < sc_bufSize)
|
||||
{
|
||||
memcpy(&((uint8 *)m_data)[m_remainder], message, length);
|
||||
m_length = length + m_length;
|
||||
m_remainder = (uint8)newLength;
|
||||
return;
|
||||
}
|
||||
|
||||
// init the variables
|
||||
if (m_length < sc_bufSize)
|
||||
{
|
||||
h0=h3=h6=h9 = m_state[0];
|
||||
h1=h4=h7=h10 = m_state[1];
|
||||
h2=h5=h8=h11 = sc_const;
|
||||
}
|
||||
else
|
||||
{
|
||||
h0 = m_state[0];
|
||||
h1 = m_state[1];
|
||||
h2 = m_state[2];
|
||||
h3 = m_state[3];
|
||||
h4 = m_state[4];
|
||||
h5 = m_state[5];
|
||||
h6 = m_state[6];
|
||||
h7 = m_state[7];
|
||||
h8 = m_state[8];
|
||||
h9 = m_state[9];
|
||||
h10 = m_state[10];
|
||||
h11 = m_state[11];
|
||||
}
|
||||
m_length = length + m_length;
|
||||
|
||||
// if we've got anything stuffed away, use it now
|
||||
if (m_remainder)
|
||||
{
|
||||
uint8 prefix = sc_bufSize-m_remainder;
|
||||
memcpy(&(((uint8 *)m_data)[m_remainder]), message, prefix);
|
||||
u.p64 = m_data;
|
||||
Mix(u.p64, h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11);
|
||||
Mix(&u.p64[sc_numVars], h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11);
|
||||
u.p8 = ((const uint8 *)message) + prefix;
|
||||
length -= prefix;
|
||||
}
|
||||
else
|
||||
{
|
||||
u.p8 = (const uint8 *)message;
|
||||
}
|
||||
|
||||
// handle all whole blocks of sc_blockSize bytes
|
||||
end = u.p64 + (length/sc_blockSize)*sc_numVars;
|
||||
remainder = (uint8)(length-((const uint8 *)end-u.p8));
|
||||
if (ALLOW_UNALIGNED_READS || (u.i & 0x7) == 0)
|
||||
{
|
||||
while (u.p64 < end)
|
||||
{
|
||||
Mix(u.p64, h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11);
|
||||
u.p64 += sc_numVars;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (u.p64 < end)
|
||||
{
|
||||
memcpy(m_data, u.p8, sc_blockSize);
|
||||
Mix(m_data, h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11);
|
||||
u.p64 += sc_numVars;
|
||||
}
|
||||
}
|
||||
|
||||
// stuff away the last few bytes
|
||||
m_remainder = remainder;
|
||||
memcpy(m_data, end, remainder);
|
||||
|
||||
// stuff away the variables
|
||||
m_state[0] = h0;
|
||||
m_state[1] = h1;
|
||||
m_state[2] = h2;
|
||||
m_state[3] = h3;
|
||||
m_state[4] = h4;
|
||||
m_state[5] = h5;
|
||||
m_state[6] = h6;
|
||||
m_state[7] = h7;
|
||||
m_state[8] = h8;
|
||||
m_state[9] = h9;
|
||||
m_state[10] = h10;
|
||||
m_state[11] = h11;
|
||||
}
|
||||
|
||||
|
||||
// report the hash for the concatenation of all message fragments so far
|
||||
void SpookyHash::Final(uint64 *hash1, uint64 *hash2)
|
||||
{
|
||||
// init the variables
|
||||
if (m_length < sc_bufSize)
|
||||
{
|
||||
*hash1 = m_state[0];
|
||||
*hash2 = m_state[1];
|
||||
Short( m_data, m_length, hash1, hash2);
|
||||
return;
|
||||
}
|
||||
|
||||
const uint64 *data = (const uint64 *)m_data;
|
||||
uint8 remainder = m_remainder;
|
||||
|
||||
uint64 h0 = m_state[0];
|
||||
uint64 h1 = m_state[1];
|
||||
uint64 h2 = m_state[2];
|
||||
uint64 h3 = m_state[3];
|
||||
uint64 h4 = m_state[4];
|
||||
uint64 h5 = m_state[5];
|
||||
uint64 h6 = m_state[6];
|
||||
uint64 h7 = m_state[7];
|
||||
uint64 h8 = m_state[8];
|
||||
uint64 h9 = m_state[9];
|
||||
uint64 h10 = m_state[10];
|
||||
uint64 h11 = m_state[11];
|
||||
|
||||
if (remainder >= sc_blockSize)
|
||||
{
|
||||
// m_data can contain two blocks; handle any whole first block
|
||||
Mix(data, h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11);
|
||||
data += sc_numVars;
|
||||
remainder -= sc_blockSize;
|
||||
}
|
||||
|
||||
// mix in the last partial block, and the length mod sc_blockSize
|
||||
memset(&((uint8 *)data)[remainder], 0, (sc_blockSize-remainder));
|
||||
|
||||
((uint8 *)data)[sc_blockSize-1] = remainder;
|
||||
|
||||
// do some final mixing
|
||||
End(data, h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11);
|
||||
|
||||
*hash1 = h0;
|
||||
*hash2 = h1;
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
301
src/ripple/beast/hash/impl/spookyv2.h
Normal file
301
src/ripple/beast/hash/impl/spookyv2.h
Normal file
@@ -0,0 +1,301 @@
|
||||
//
|
||||
// SpookyHash: a 128-bit noncryptographic hash function
|
||||
// By Bob Jenkins, public domain
|
||||
// Oct 31 2010: alpha, framework + SpookyHash::Mix appears right
|
||||
// Oct 31 2011: alpha again, Mix only good to 2^^69 but rest appears right
|
||||
// Dec 31 2011: beta, improved Mix, tested it for 2-bit deltas
|
||||
// Feb 2 2012: production, same bits as beta
|
||||
// Feb 5 2012: adjusted definitions of uint* to be more portable
|
||||
// Mar 30 2012: 3 bytes/cycle, not 4. Alpha was 4 but wasn't thorough enough.
|
||||
// August 5 2012: SpookyV2 (different results)
|
||||
//
|
||||
// Up to 3 bytes/cycle for long messages. Reasonably fast for short messages.
|
||||
// All 1 or 2 bit deltas achieve avalanche within 1% bias per output bit.
|
||||
//
|
||||
// This was developed for and tested on 64-bit x86-compatible processors.
|
||||
// It assumes the processor is little-endian. There is a macro
|
||||
// controlling whether unaligned reads are allowed (by default they are).
|
||||
// This should be an equally good hash on big-endian machines, but it will
|
||||
// compute different results on them than on little-endian machines.
|
||||
//
|
||||
// Google's CityHash has similar specs to SpookyHash, and CityHash is faster
|
||||
// on new Intel boxes. MD4 and MD5 also have similar specs, but they are orders
|
||||
// of magnitude slower. CRCs are two or more times slower, but unlike
|
||||
// SpookyHash, they have nice math for combining the CRCs of pieces to form
|
||||
// the CRCs of wholes. There are also cryptographic hashes, but those are even
|
||||
// slower than MD5.
|
||||
//
|
||||
|
||||
#ifndef BEAST_HASH_SPOOKYV2_H_INCLUDED
|
||||
#define BEAST_HASH_SPOOKYV2_H_INCLUDED
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define INLINE __forceinline
|
||||
typedef unsigned __int64 uint64;
|
||||
typedef unsigned __int32 uint32;
|
||||
typedef unsigned __int16 uint16;
|
||||
typedef unsigned __int8 uint8;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
# define INLINE inline
|
||||
typedef uint64_t uint64;
|
||||
typedef uint32_t uint32;
|
||||
typedef uint16_t uint16;
|
||||
typedef uint8_t uint8;
|
||||
#endif
|
||||
|
||||
|
||||
class SpookyHash
|
||||
{
|
||||
public:
|
||||
//
|
||||
// SpookyHash: hash a single message in one call, produce 128-bit output
|
||||
//
|
||||
static void Hash128(
|
||||
const void *message, // message to hash
|
||||
size_t length, // length of message in bytes
|
||||
uint64 *hash1, // in/out: in seed 1, out hash value 1
|
||||
uint64 *hash2); // in/out: in seed 2, out hash value 2
|
||||
|
||||
//
|
||||
// Hash64: hash a single message in one call, return 64-bit output
|
||||
//
|
||||
static uint64 Hash64(
|
||||
const void *message, // message to hash
|
||||
size_t length, // length of message in bytes
|
||||
uint64 seed) // seed
|
||||
{
|
||||
uint64 hash1 = seed;
|
||||
Hash128(message, length, &hash1, &seed);
|
||||
return hash1;
|
||||
}
|
||||
|
||||
//
|
||||
// Hash32: hash a single message in one call, produce 32-bit output
|
||||
//
|
||||
static uint32 Hash32(
|
||||
const void *message, // message to hash
|
||||
size_t length, // length of message in bytes
|
||||
uint32 seed) // seed
|
||||
{
|
||||
uint64 hash1 = seed, hash2 = seed;
|
||||
Hash128(message, length, &hash1, &hash2);
|
||||
return (uint32)hash1;
|
||||
}
|
||||
|
||||
//
|
||||
// Init: initialize the context of a SpookyHash
|
||||
//
|
||||
void Init(
|
||||
uint64 seed1, // any 64-bit value will do, including 0
|
||||
uint64 seed2); // different seeds produce independent hashes
|
||||
|
||||
//
|
||||
// Update: add a piece of a message to a SpookyHash state
|
||||
//
|
||||
void Update(
|
||||
const void *message, // message fragment
|
||||
size_t length); // length of message fragment in bytes
|
||||
|
||||
|
||||
//
|
||||
// Final: compute the hash for the current SpookyHash state
|
||||
//
|
||||
// This does not modify the state; you can keep updating it afterward
|
||||
//
|
||||
// The result is the same as if SpookyHash() had been called with
|
||||
// all the pieces concatenated into one message.
|
||||
//
|
||||
void Final(
|
||||
uint64 *hash1, // out only: first 64 bits of hash value.
|
||||
uint64 *hash2); // out only: second 64 bits of hash value.
|
||||
|
||||
//
|
||||
// left rotate a 64-bit value by k bytes
|
||||
//
|
||||
static INLINE uint64 Rot64(uint64 x, int k)
|
||||
{
|
||||
return (x << k) | (x >> (64 - k));
|
||||
}
|
||||
|
||||
//
|
||||
// This is used if the input is 96 bytes long or longer.
|
||||
//
|
||||
// The internal state is fully overwritten every 96 bytes.
|
||||
// Every input bit appears to cause at least 128 bits of entropy
|
||||
// before 96 other bytes are combined, when run forward or backward
|
||||
// For every input bit,
|
||||
// Two inputs differing in just that input bit
|
||||
// Where "differ" means xor or subtraction
|
||||
// And the base value is random
|
||||
// When run forward or backwards one Mix
|
||||
// I tried 3 pairs of each; they all differed by at least 212 bits.
|
||||
//
|
||||
static INLINE void Mix(
|
||||
const uint64 *data,
|
||||
uint64 &s0, uint64 &s1, uint64 &s2, uint64 &s3,
|
||||
uint64 &s4, uint64 &s5, uint64 &s6, uint64 &s7,
|
||||
uint64 &s8, uint64 &s9, uint64 &s10,uint64 &s11)
|
||||
{
|
||||
s0 += data[0]; s2 ^= s10; s11 ^= s0; s0 = Rot64(s0,11); s11 += s1;
|
||||
s1 += data[1]; s3 ^= s11; s0 ^= s1; s1 = Rot64(s1,32); s0 += s2;
|
||||
s2 += data[2]; s4 ^= s0; s1 ^= s2; s2 = Rot64(s2,43); s1 += s3;
|
||||
s3 += data[3]; s5 ^= s1; s2 ^= s3; s3 = Rot64(s3,31); s2 += s4;
|
||||
s4 += data[4]; s6 ^= s2; s3 ^= s4; s4 = Rot64(s4,17); s3 += s5;
|
||||
s5 += data[5]; s7 ^= s3; s4 ^= s5; s5 = Rot64(s5,28); s4 += s6;
|
||||
s6 += data[6]; s8 ^= s4; s5 ^= s6; s6 = Rot64(s6,39); s5 += s7;
|
||||
s7 += data[7]; s9 ^= s5; s6 ^= s7; s7 = Rot64(s7,57); s6 += s8;
|
||||
s8 += data[8]; s10 ^= s6; s7 ^= s8; s8 = Rot64(s8,55); s7 += s9;
|
||||
s9 += data[9]; s11 ^= s7; s8 ^= s9; s9 = Rot64(s9,54); s8 += s10;
|
||||
s10 += data[10]; s0 ^= s8; s9 ^= s10; s10 = Rot64(s10,22); s9 += s11;
|
||||
s11 += data[11]; s1 ^= s9; s10 ^= s11; s11 = Rot64(s11,46); s10 += s0;
|
||||
}
|
||||
|
||||
//
|
||||
// Mix all 12 inputs together so that h0, h1 are a hash of them all.
|
||||
//
|
||||
// For two inputs differing in just the input bits
|
||||
// Where "differ" means xor or subtraction
|
||||
// And the base value is random, or a counting value starting at that bit
|
||||
// The final result will have each bit of h0, h1 flip
|
||||
// For every input bit,
|
||||
// with probability 50 +- .3%
|
||||
// For every pair of input bits,
|
||||
// with probability 50 +- 3%
|
||||
//
|
||||
// This does not rely on the last Mix() call having already mixed some.
|
||||
// Two iterations was almost good enough for a 64-bit result, but a
|
||||
// 128-bit result is reported, so End() does three iterations.
|
||||
//
|
||||
static INLINE void EndPartial(
|
||||
uint64 &h0, uint64 &h1, uint64 &h2, uint64 &h3,
|
||||
uint64 &h4, uint64 &h5, uint64 &h6, uint64 &h7,
|
||||
uint64 &h8, uint64 &h9, uint64 &h10,uint64 &h11)
|
||||
{
|
||||
h11+= h1; h2 ^= h11; h1 = Rot64(h1,44);
|
||||
h0 += h2; h3 ^= h0; h2 = Rot64(h2,15);
|
||||
h1 += h3; h4 ^= h1; h3 = Rot64(h3,34);
|
||||
h2 += h4; h5 ^= h2; h4 = Rot64(h4,21);
|
||||
h3 += h5; h6 ^= h3; h5 = Rot64(h5,38);
|
||||
h4 += h6; h7 ^= h4; h6 = Rot64(h6,33);
|
||||
h5 += h7; h8 ^= h5; h7 = Rot64(h7,10);
|
||||
h6 += h8; h9 ^= h6; h8 = Rot64(h8,13);
|
||||
h7 += h9; h10^= h7; h9 = Rot64(h9,38);
|
||||
h8 += h10; h11^= h8; h10= Rot64(h10,53);
|
||||
h9 += h11; h0 ^= h9; h11= Rot64(h11,42);
|
||||
h10+= h0; h1 ^= h10; h0 = Rot64(h0,54);
|
||||
}
|
||||
|
||||
static INLINE void End(
|
||||
const uint64 *data,
|
||||
uint64 &h0, uint64 &h1, uint64 &h2, uint64 &h3,
|
||||
uint64 &h4, uint64 &h5, uint64 &h6, uint64 &h7,
|
||||
uint64 &h8, uint64 &h9, uint64 &h10,uint64 &h11)
|
||||
{
|
||||
h0 += data[0]; h1 += data[1]; h2 += data[2]; h3 += data[3];
|
||||
h4 += data[4]; h5 += data[5]; h6 += data[6]; h7 += data[7];
|
||||
h8 += data[8]; h9 += data[9]; h10 += data[10]; h11 += data[11];
|
||||
EndPartial(h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11);
|
||||
EndPartial(h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11);
|
||||
EndPartial(h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11);
|
||||
}
|
||||
|
||||
//
|
||||
// The goal is for each bit of the input to expand into 128 bits of
|
||||
// apparent entropy before it is fully overwritten.
|
||||
// n trials both set and cleared at least m bits of h0 h1 h2 h3
|
||||
// n: 2 m: 29
|
||||
// n: 3 m: 46
|
||||
// n: 4 m: 57
|
||||
// n: 5 m: 107
|
||||
// n: 6 m: 146
|
||||
// n: 7 m: 152
|
||||
// when run forwards or backwards
|
||||
// for all 1-bit and 2-bit diffs
|
||||
// with diffs defined by either xor or subtraction
|
||||
// with a base of all zeros plus a counter, or plus another bit, or random
|
||||
//
|
||||
static INLINE void ShortMix(uint64 &h0, uint64 &h1, uint64 &h2, uint64 &h3)
|
||||
{
|
||||
h2 = Rot64(h2,50); h2 += h3; h0 ^= h2;
|
||||
h3 = Rot64(h3,52); h3 += h0; h1 ^= h3;
|
||||
h0 = Rot64(h0,30); h0 += h1; h2 ^= h0;
|
||||
h1 = Rot64(h1,41); h1 += h2; h3 ^= h1;
|
||||
h2 = Rot64(h2,54); h2 += h3; h0 ^= h2;
|
||||
h3 = Rot64(h3,48); h3 += h0; h1 ^= h3;
|
||||
h0 = Rot64(h0,38); h0 += h1; h2 ^= h0;
|
||||
h1 = Rot64(h1,37); h1 += h2; h3 ^= h1;
|
||||
h2 = Rot64(h2,62); h2 += h3; h0 ^= h2;
|
||||
h3 = Rot64(h3,34); h3 += h0; h1 ^= h3;
|
||||
h0 = Rot64(h0,5); h0 += h1; h2 ^= h0;
|
||||
h1 = Rot64(h1,36); h1 += h2; h3 ^= h1;
|
||||
}
|
||||
|
||||
//
|
||||
// Mix all 4 inputs together so that h0, h1 are a hash of them all.
|
||||
//
|
||||
// For two inputs differing in just the input bits
|
||||
// Where "differ" means xor or subtraction
|
||||
// And the base value is random, or a counting value starting at that bit
|
||||
// The final result will have each bit of h0, h1 flip
|
||||
// For every input bit,
|
||||
// with probability 50 +- .3% (it is probably better than that)
|
||||
// For every pair of input bits,
|
||||
// with probability 50 +- .75% (the worst case is approximately that)
|
||||
//
|
||||
static INLINE void ShortEnd(uint64 &h0, uint64 &h1, uint64 &h2, uint64 &h3)
|
||||
{
|
||||
h3 ^= h2; h2 = Rot64(h2,15); h3 += h2;
|
||||
h0 ^= h3; h3 = Rot64(h3,52); h0 += h3;
|
||||
h1 ^= h0; h0 = Rot64(h0,26); h1 += h0;
|
||||
h2 ^= h1; h1 = Rot64(h1,51); h2 += h1;
|
||||
h3 ^= h2; h2 = Rot64(h2,28); h3 += h2;
|
||||
h0 ^= h3; h3 = Rot64(h3,9); h0 += h3;
|
||||
h1 ^= h0; h0 = Rot64(h0,47); h1 += h0;
|
||||
h2 ^= h1; h1 = Rot64(h1,54); h2 += h1;
|
||||
h3 ^= h2; h2 = Rot64(h2,32); h3 += h2;
|
||||
h0 ^= h3; h3 = Rot64(h3,25); h0 += h3;
|
||||
h1 ^= h0; h0 = Rot64(h0,63); h1 += h0;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
//
|
||||
// Short is used for messages under 192 bytes in length
|
||||
// Short has a low startup cost, the normal mode is good for long
|
||||
// keys, the cost crossover is at about 192 bytes. The two modes were
|
||||
// held to the same quality bar.
|
||||
//
|
||||
static void Short(
|
||||
const void *message, // message (array of bytes, not necessarily aligned)
|
||||
size_t length, // length of message (in bytes)
|
||||
uint64 *hash1, // in/out: in the seed, out the hash value
|
||||
uint64 *hash2); // in/out: in the seed, out the hash value
|
||||
|
||||
// number of uint64's in internal state
|
||||
static const size_t sc_numVars = 12;
|
||||
|
||||
// size of the internal state
|
||||
static const size_t sc_blockSize = sc_numVars*8;
|
||||
|
||||
// size of buffer of unhashed data, in bytes
|
||||
static const size_t sc_bufSize = 2*sc_blockSize;
|
||||
|
||||
//
|
||||
// sc_const: a constant which:
|
||||
// * is not zero
|
||||
// * is odd
|
||||
// * is a not-very-regular mix of 1's and 0's
|
||||
// * does not need any other special mathematical properties
|
||||
//
|
||||
static const uint64 sc_const = 0xdeadbeefdeadbeefUL;
|
||||
|
||||
uint64 m_data[2*sc_numVars]; // unhashed data, for partial messages
|
||||
uint64 m_state[sc_numVars]; // internal state of the hash
|
||||
size_t m_length; // total length of the input so far
|
||||
uint8 m_remainder; // length of unhashed data stashed in m_data
|
||||
};
|
||||
|
||||
#endif // BEAST_SPOOKYV2_H_INCLUDED
|
||||
934
src/ripple/beast/hash/impl/xxhash.c
Normal file
934
src/ripple/beast/hash/impl/xxhash.c
Normal file
@@ -0,0 +1,934 @@
|
||||
/*
|
||||
xxHash - Fast Hash algorithm
|
||||
Copyright (C) 2012-2014, Yann Collet.
|
||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
You can contact the author at :
|
||||
- xxHash source repository : http://code.google.com/p/xxhash/
|
||||
- public discussion board : https://groups.google.com/forum/#!forum/lz4c
|
||||
*/
|
||||
|
||||
#include <ripple/beast/hash/impl/xxhash.h>
|
||||
|
||||
//**************************************
|
||||
// Tuning parameters
|
||||
//**************************************
|
||||
// Unaligned memory access is automatically enabled for "common" CPU, such as x86.
|
||||
// For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected.
|
||||
// If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance.
|
||||
// You can also enable this parameter if you know your input data will always be aligned (boundaries of 4, for U32).
|
||||
#if defined(__ARM_FEATURE_UNALIGNED) || defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
|
||||
# define XXH_USE_UNALIGNED_ACCESS 1
|
||||
#endif
|
||||
|
||||
// XXH_ACCEPT_NULL_INPUT_POINTER :
|
||||
// If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer.
|
||||
// When this option is enabled, xxHash output for null input pointers will be the same as a null-length input.
|
||||
// This option has a very small performance cost (only measurable on small inputs).
|
||||
// By default, this option is disabled. To enable it, uncomment below define :
|
||||
// #define XXH_ACCEPT_NULL_INPUT_POINTER 1
|
||||
|
||||
// XXH_FORCE_NATIVE_FORMAT :
|
||||
// By default, xxHash library provides endian-independant Hash values, based on little-endian convention.
|
||||
// Results are therefore identical for little-endian and big-endian CPU.
|
||||
// This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format.
|
||||
// Should endian-independance be of no importance for your application, you may set the #define below to 1.
|
||||
// It will improve speed for Big-endian CPU.
|
||||
// This option has no impact on Little_Endian CPU.
|
||||
#define XXH_FORCE_NATIVE_FORMAT 0
|
||||
|
||||
//**************************************
|
||||
// Compiler Specific Options
|
||||
//**************************************
|
||||
// Disable some Visual warning messages
|
||||
#ifdef _MSC_VER // Visual Studio
|
||||
# pragma warning(disable : 4127) // disable: C4127: conditional expression is constant
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER // Visual Studio
|
||||
# define FORCE_INLINE static __forceinline
|
||||
#else
|
||||
# ifdef __GNUC__
|
||||
# define FORCE_INLINE static inline __attribute__((always_inline))
|
||||
# else
|
||||
# define FORCE_INLINE static inline
|
||||
# endif
|
||||
#endif
|
||||
|
||||
//**************************************
|
||||
// Includes & Memory related functions
|
||||
//**************************************
|
||||
//#include "xxhash.h"
|
||||
// Modify the local functions below should you wish to use some other memory routines
|
||||
// for malloc(), free()
|
||||
#include <stdlib.h>
|
||||
static void* XXH_malloc(size_t s) { return malloc(s); }
|
||||
static void XXH_free (void* p) { free(p); }
|
||||
// for memcpy()
|
||||
#include <string.h>
|
||||
static void* XXH_memcpy(void* dest, const void* src, size_t size)
|
||||
{
|
||||
return memcpy(dest,src,size);
|
||||
}
|
||||
|
||||
|
||||
//**************************************
|
||||
// Basic Types
|
||||
//**************************************
|
||||
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L // C99
|
||||
# include <stdint.h>
|
||||
typedef uint8_t BYTE;
|
||||
typedef uint16_t U16;
|
||||
typedef uint32_t U32;
|
||||
typedef int32_t S32;
|
||||
typedef uint64_t U64;
|
||||
#else
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned short U16;
|
||||
typedef unsigned int U32;
|
||||
typedef signed int S32;
|
||||
typedef unsigned long long U64;
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && !defined(XXH_USE_UNALIGNED_ACCESS)
|
||||
# define _PACKED __attribute__ ((packed))
|
||||
#else
|
||||
# define _PACKED
|
||||
#endif
|
||||
|
||||
#if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__)
|
||||
# ifdef __IBMC__
|
||||
# pragma pack(1)
|
||||
# else
|
||||
# pragma pack(push, 1)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
typedef struct _U32_S
|
||||
{
|
||||
U32 v;
|
||||
} _PACKED U32_S;
|
||||
typedef struct _U64_S
|
||||
{
|
||||
U64 v;
|
||||
} _PACKED U64_S;
|
||||
|
||||
#if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__)
|
||||
# pragma pack(pop)
|
||||
#endif
|
||||
|
||||
#define A32(x) (((U32_S *)(x))->v)
|
||||
#define A64(x) (((U64_S *)(x))->v)
|
||||
|
||||
|
||||
//***************************************
|
||||
// Compiler-specific Functions and Macros
|
||||
//***************************************
|
||||
#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
||||
|
||||
// Note : although _rotl exists for minGW (GCC under windows), performance seems poor
|
||||
#if defined(_MSC_VER)
|
||||
# define XXH_rotl32(x,r) _rotl(x,r)
|
||||
# define XXH_rotl64(x,r) _rotl64(x,r)
|
||||
#else
|
||||
# define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r)))
|
||||
# define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r)))
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) // Visual Studio
|
||||
# define XXH_swap32 _byteswap_ulong
|
||||
# define XXH_swap64 _byteswap_uint64
|
||||
#elif GCC_VERSION >= 403
|
||||
# define XXH_swap32 __builtin_bswap32
|
||||
# define XXH_swap64 __builtin_bswap64
|
||||
#else
|
||||
static inline U32 XXH_swap32 (U32 x)
|
||||
{
|
||||
return ((x << 24) & 0xff000000 ) |
|
||||
((x << 8) & 0x00ff0000 ) |
|
||||
((x >> 8) & 0x0000ff00 ) |
|
||||
((x >> 24) & 0x000000ff );
|
||||
}
|
||||
static inline U64 XXH_swap64 (U64 x)
|
||||
{
|
||||
return ((x << 56) & 0xff00000000000000ULL) |
|
||||
((x << 40) & 0x00ff000000000000ULL) |
|
||||
((x << 24) & 0x0000ff0000000000ULL) |
|
||||
((x << 8) & 0x000000ff00000000ULL) |
|
||||
((x >> 8) & 0x00000000ff000000ULL) |
|
||||
((x >> 24) & 0x0000000000ff0000ULL) |
|
||||
((x >> 40) & 0x000000000000ff00ULL) |
|
||||
((x >> 56) & 0x00000000000000ffULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//**************************************
|
||||
// Constants
|
||||
//**************************************
|
||||
#define PRIME32_1 2654435761U
|
||||
#define PRIME32_2 2246822519U
|
||||
#define PRIME32_3 3266489917U
|
||||
#define PRIME32_4 668265263U
|
||||
#define PRIME32_5 374761393U
|
||||
|
||||
#define PRIME64_1 11400714785074694791ULL
|
||||
#define PRIME64_2 14029467366897019727ULL
|
||||
#define PRIME64_3 1609587929392839161ULL
|
||||
#define PRIME64_4 9650029242287828579ULL
|
||||
#define PRIME64_5 2870177450012600261ULL
|
||||
|
||||
//**************************************
|
||||
// Architecture Macros
|
||||
//**************************************
|
||||
typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;
|
||||
#ifndef XXH_CPU_LITTLE_ENDIAN // It is possible to define XXH_CPU_LITTLE_ENDIAN externally, for example using a compiler switch
|
||||
static const int one = 1;
|
||||
# define XXH_CPU_LITTLE_ENDIAN (*(char*)(&one))
|
||||
#endif
|
||||
|
||||
|
||||
//**************************************
|
||||
// Macros
|
||||
//**************************************
|
||||
#define XXH_STATIC_ASSERT(c) { enum { XXH_static_assert = 1/(!!(c)) }; } // use only *after* variable declarations
|
||||
|
||||
|
||||
//****************************
|
||||
// Memory reads
|
||||
//****************************
|
||||
typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment;
|
||||
|
||||
FORCE_INLINE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
|
||||
{
|
||||
if (align==XXH_unaligned)
|
||||
return endian==XXH_littleEndian ? A32(ptr) : XXH_swap32(A32(ptr));
|
||||
else
|
||||
return endian==XXH_littleEndian ? *(U32*)ptr : XXH_swap32(*(U32*)ptr);
|
||||
}
|
||||
|
||||
FORCE_INLINE U32 XXH_readLE32(const void* ptr, XXH_endianess endian)
|
||||
{
|
||||
return XXH_readLE32_align(ptr, endian, XXH_unaligned);
|
||||
}
|
||||
|
||||
FORCE_INLINE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
|
||||
{
|
||||
if (align==XXH_unaligned)
|
||||
return endian==XXH_littleEndian ? A64(ptr) : XXH_swap64(A64(ptr));
|
||||
else
|
||||
return endian==XXH_littleEndian ? *(U64*)ptr : XXH_swap64(*(U64*)ptr);
|
||||
}
|
||||
|
||||
FORCE_INLINE U64 XXH_readLE64(const void* ptr, XXH_endianess endian)
|
||||
{
|
||||
return XXH_readLE64_align(ptr, endian, XXH_unaligned);
|
||||
}
|
||||
|
||||
|
||||
//****************************
|
||||
// Simple Hash Functions
|
||||
//****************************
|
||||
FORCE_INLINE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align)
|
||||
{
|
||||
const BYTE* p = (const BYTE*)input;
|
||||
const BYTE* bEnd = p + len;
|
||||
U32 h32;
|
||||
#define XXH_get32bits(p) XXH_readLE32_align(p, endian, align)
|
||||
|
||||
#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
|
||||
if (p==NULL)
|
||||
{
|
||||
len=0;
|
||||
bEnd=p=(const BYTE*)(size_t)16;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (len>=16)
|
||||
{
|
||||
const BYTE* const limit = bEnd - 16;
|
||||
U32 v1 = seed + PRIME32_1 + PRIME32_2;
|
||||
U32 v2 = seed + PRIME32_2;
|
||||
U32 v3 = seed + 0;
|
||||
U32 v4 = seed - PRIME32_1;
|
||||
|
||||
do
|
||||
{
|
||||
v1 += XXH_get32bits(p) * PRIME32_2;
|
||||
v1 = XXH_rotl32(v1, 13);
|
||||
v1 *= PRIME32_1;
|
||||
p+=4;
|
||||
v2 += XXH_get32bits(p) * PRIME32_2;
|
||||
v2 = XXH_rotl32(v2, 13);
|
||||
v2 *= PRIME32_1;
|
||||
p+=4;
|
||||
v3 += XXH_get32bits(p) * PRIME32_2;
|
||||
v3 = XXH_rotl32(v3, 13);
|
||||
v3 *= PRIME32_1;
|
||||
p+=4;
|
||||
v4 += XXH_get32bits(p) * PRIME32_2;
|
||||
v4 = XXH_rotl32(v4, 13);
|
||||
v4 *= PRIME32_1;
|
||||
p+=4;
|
||||
}
|
||||
while (p<=limit);
|
||||
|
||||
h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);
|
||||
}
|
||||
else
|
||||
{
|
||||
h32 = seed + PRIME32_5;
|
||||
}
|
||||
|
||||
h32 += (U32) len;
|
||||
|
||||
while (p+4<=bEnd)
|
||||
{
|
||||
h32 += XXH_get32bits(p) * PRIME32_3;
|
||||
h32 = XXH_rotl32(h32, 17) * PRIME32_4 ;
|
||||
p+=4;
|
||||
}
|
||||
|
||||
while (p<bEnd)
|
||||
{
|
||||
h32 += (*p) * PRIME32_5;
|
||||
h32 = XXH_rotl32(h32, 11) * PRIME32_1 ;
|
||||
p++;
|
||||
}
|
||||
|
||||
h32 ^= h32 >> 15;
|
||||
h32 *= PRIME32_2;
|
||||
h32 ^= h32 >> 13;
|
||||
h32 *= PRIME32_3;
|
||||
h32 ^= h32 >> 16;
|
||||
|
||||
return h32;
|
||||
}
|
||||
|
||||
|
||||
unsigned int XXH32 (const void* input, size_t len, unsigned seed)
|
||||
{
|
||||
#if 0
|
||||
// Simple version, good for code maintenance, but unfortunately slow for small inputs
|
||||
XXH32_state_t state;
|
||||
XXH32_reset(&state, seed);
|
||||
XXH32_update(&state, input, len);
|
||||
return XXH32_digest(&state);
|
||||
#else
|
||||
XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
|
||||
|
||||
# if !defined(XXH_USE_UNALIGNED_ACCESS)
|
||||
if ((((size_t)input) & 3) == 0) // Input is aligned, let's leverage the speed advantage
|
||||
{
|
||||
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
|
||||
return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
|
||||
else
|
||||
return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
|
||||
}
|
||||
# endif
|
||||
|
||||
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
|
||||
return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
|
||||
else
|
||||
return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);
|
||||
#endif
|
||||
}
|
||||
|
||||
FORCE_INLINE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align)
|
||||
{
|
||||
const BYTE* p = (const BYTE*)input;
|
||||
const BYTE* bEnd = p + len;
|
||||
U64 h64;
|
||||
#define XXH_get64bits(p) XXH_readLE64_align(p, endian, align)
|
||||
|
||||
#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
|
||||
if (p==NULL)
|
||||
{
|
||||
len=0;
|
||||
bEnd=p=(const BYTE*)(size_t)32;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (len>=32)
|
||||
{
|
||||
const BYTE* const limit = bEnd - 32;
|
||||
U64 v1 = seed + PRIME64_1 + PRIME64_2;
|
||||
U64 v2 = seed + PRIME64_2;
|
||||
U64 v3 = seed + 0;
|
||||
U64 v4 = seed - PRIME64_1;
|
||||
|
||||
do
|
||||
{
|
||||
v1 += XXH_get64bits(p) * PRIME64_2;
|
||||
p+=8;
|
||||
v1 = XXH_rotl64(v1, 31);
|
||||
v1 *= PRIME64_1;
|
||||
v2 += XXH_get64bits(p) * PRIME64_2;
|
||||
p+=8;
|
||||
v2 = XXH_rotl64(v2, 31);
|
||||
v2 *= PRIME64_1;
|
||||
v3 += XXH_get64bits(p) * PRIME64_2;
|
||||
p+=8;
|
||||
v3 = XXH_rotl64(v3, 31);
|
||||
v3 *= PRIME64_1;
|
||||
v4 += XXH_get64bits(p) * PRIME64_2;
|
||||
p+=8;
|
||||
v4 = XXH_rotl64(v4, 31);
|
||||
v4 *= PRIME64_1;
|
||||
}
|
||||
while (p<=limit);
|
||||
|
||||
h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
|
||||
|
||||
v1 *= PRIME64_2;
|
||||
v1 = XXH_rotl64(v1, 31);
|
||||
v1 *= PRIME64_1;
|
||||
h64 ^= v1;
|
||||
h64 = h64 * PRIME64_1 + PRIME64_4;
|
||||
|
||||
v2 *= PRIME64_2;
|
||||
v2 = XXH_rotl64(v2, 31);
|
||||
v2 *= PRIME64_1;
|
||||
h64 ^= v2;
|
||||
h64 = h64 * PRIME64_1 + PRIME64_4;
|
||||
|
||||
v3 *= PRIME64_2;
|
||||
v3 = XXH_rotl64(v3, 31);
|
||||
v3 *= PRIME64_1;
|
||||
h64 ^= v3;
|
||||
h64 = h64 * PRIME64_1 + PRIME64_4;
|
||||
|
||||
v4 *= PRIME64_2;
|
||||
v4 = XXH_rotl64(v4, 31);
|
||||
v4 *= PRIME64_1;
|
||||
h64 ^= v4;
|
||||
h64 = h64 * PRIME64_1 + PRIME64_4;
|
||||
}
|
||||
else
|
||||
{
|
||||
h64 = seed + PRIME64_5;
|
||||
}
|
||||
|
||||
h64 += (U64) len;
|
||||
|
||||
while (p+8<=bEnd)
|
||||
{
|
||||
U64 k1 = XXH_get64bits(p);
|
||||
k1 *= PRIME64_2;
|
||||
k1 = XXH_rotl64(k1,31);
|
||||
k1 *= PRIME64_1;
|
||||
h64 ^= k1;
|
||||
h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4;
|
||||
p+=8;
|
||||
}
|
||||
|
||||
if (p+4<=bEnd)
|
||||
{
|
||||
h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1;
|
||||
h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
|
||||
p+=4;
|
||||
}
|
||||
|
||||
while (p<bEnd)
|
||||
{
|
||||
h64 ^= (*p) * PRIME64_5;
|
||||
h64 = XXH_rotl64(h64, 11) * PRIME64_1;
|
||||
p++;
|
||||
}
|
||||
|
||||
h64 ^= h64 >> 33;
|
||||
h64 *= PRIME64_2;
|
||||
h64 ^= h64 >> 29;
|
||||
h64 *= PRIME64_3;
|
||||
h64 ^= h64 >> 32;
|
||||
|
||||
return h64;
|
||||
}
|
||||
|
||||
|
||||
unsigned long long XXH64 (const void* input, size_t len, unsigned long long seed)
|
||||
{
|
||||
#if 0
|
||||
// Simple version, good for code maintenance, but unfortunately slow for small inputs
|
||||
XXH64_state_t state;
|
||||
XXH64_reset(&state, seed);
|
||||
XXH64_update(&state, input, len);
|
||||
return XXH64_digest(&state);
|
||||
#else
|
||||
XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
|
||||
|
||||
# if !defined(XXH_USE_UNALIGNED_ACCESS)
|
||||
if ((((size_t)input) & 7)==0) // Input is aligned, let's leverage the speed advantage
|
||||
{
|
||||
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
|
||||
return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
|
||||
else
|
||||
return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
|
||||
}
|
||||
# endif
|
||||
|
||||
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
|
||||
return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
|
||||
else
|
||||
return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************
|
||||
* Advanced Hash Functions
|
||||
****************************************************/
|
||||
|
||||
/*** Allocation ***/
|
||||
typedef struct
|
||||
{
|
||||
U64 total_len;
|
||||
U32 seed;
|
||||
U32 v1;
|
||||
U32 v2;
|
||||
U32 v3;
|
||||
U32 v4;
|
||||
U32 mem32[4]; /* defined as U32 for alignment */
|
||||
U32 memsize;
|
||||
} XXH_istate32_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U64 total_len;
|
||||
U64 seed;
|
||||
U64 v1;
|
||||
U64 v2;
|
||||
U64 v3;
|
||||
U64 v4;
|
||||
U64 mem64[4]; /* defined as U64 for alignment */
|
||||
U32 memsize;
|
||||
} XXH_istate64_t;
|
||||
|
||||
|
||||
XXH32_state_t* XXH32_createState(void)
|
||||
{
|
||||
static_assert(sizeof(XXH32_state_t) >= sizeof(XXH_istate32_t), ""); // A compilation error here means XXH32_state_t is not large enough
|
||||
return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t));
|
||||
}
|
||||
XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr)
|
||||
{
|
||||
XXH_free(statePtr);
|
||||
return XXH_OK;
|
||||
};
|
||||
|
||||
XXH64_state_t* XXH64_createState(void)
|
||||
{
|
||||
static_assert(sizeof(XXH64_state_t) >= sizeof(XXH_istate64_t), ""); // A compilation error here means XXH64_state_t is not large enough
|
||||
return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t));
|
||||
}
|
||||
XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr)
|
||||
{
|
||||
XXH_free(statePtr);
|
||||
return XXH_OK;
|
||||
};
|
||||
|
||||
|
||||
/*** Hash feed ***/
|
||||
|
||||
XXH_errorcode XXH32_reset(XXH32_state_t* state_in, U32 seed)
|
||||
{
|
||||
XXH_istate32_t* state = (XXH_istate32_t*) state_in;
|
||||
state->seed = seed;
|
||||
state->v1 = seed + PRIME32_1 + PRIME32_2;
|
||||
state->v2 = seed + PRIME32_2;
|
||||
state->v3 = seed + 0;
|
||||
state->v4 = seed - PRIME32_1;
|
||||
state->total_len = 0;
|
||||
state->memsize = 0;
|
||||
return XXH_OK;
|
||||
}
|
||||
|
||||
XXH_errorcode XXH64_reset(XXH64_state_t* state_in, unsigned long long seed)
|
||||
{
|
||||
XXH_istate64_t* state = (XXH_istate64_t*) state_in;
|
||||
state->seed = seed;
|
||||
state->v1 = seed + PRIME64_1 + PRIME64_2;
|
||||
state->v2 = seed + PRIME64_2;
|
||||
state->v3 = seed + 0;
|
||||
state->v4 = seed - PRIME64_1;
|
||||
state->total_len = 0;
|
||||
state->memsize = 0;
|
||||
return XXH_OK;
|
||||
}
|
||||
|
||||
|
||||
FORCE_INLINE XXH_errorcode XXH32_update_endian (XXH32_state_t* state_in, const void* input, size_t len, XXH_endianess endian)
|
||||
{
|
||||
XXH_istate32_t* state = (XXH_istate32_t *) state_in;
|
||||
const BYTE* p = (const BYTE*)input;
|
||||
const BYTE* const bEnd = p + len;
|
||||
|
||||
#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
|
||||
if (input==NULL) return XXH_ERROR;
|
||||
#endif
|
||||
|
||||
state->total_len += len;
|
||||
|
||||
if (state->memsize + len < 16) // fill in tmp buffer
|
||||
{
|
||||
XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len);
|
||||
state->memsize += (U32)len;
|
||||
return XXH_OK;
|
||||
}
|
||||
|
||||
if (state->memsize) // some data left from previous update
|
||||
{
|
||||
XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize);
|
||||
{
|
||||
const U32* p32 = state->mem32;
|
||||
state->v1 += XXH_readLE32(p32, endian) * PRIME32_2;
|
||||
state->v1 = XXH_rotl32(state->v1, 13);
|
||||
state->v1 *= PRIME32_1;
|
||||
p32++;
|
||||
state->v2 += XXH_readLE32(p32, endian) * PRIME32_2;
|
||||
state->v2 = XXH_rotl32(state->v2, 13);
|
||||
state->v2 *= PRIME32_1;
|
||||
p32++;
|
||||
state->v3 += XXH_readLE32(p32, endian) * PRIME32_2;
|
||||
state->v3 = XXH_rotl32(state->v3, 13);
|
||||
state->v3 *= PRIME32_1;
|
||||
p32++;
|
||||
state->v4 += XXH_readLE32(p32, endian) * PRIME32_2;
|
||||
state->v4 = XXH_rotl32(state->v4, 13);
|
||||
state->v4 *= PRIME32_1;
|
||||
p32++;
|
||||
}
|
||||
p += 16-state->memsize;
|
||||
state->memsize = 0;
|
||||
}
|
||||
|
||||
if (p <= bEnd-16)
|
||||
{
|
||||
const BYTE* const limit = bEnd - 16;
|
||||
U32 v1 = state->v1;
|
||||
U32 v2 = state->v2;
|
||||
U32 v3 = state->v3;
|
||||
U32 v4 = state->v4;
|
||||
|
||||
do
|
||||
{
|
||||
v1 += XXH_readLE32(p, endian) * PRIME32_2;
|
||||
v1 = XXH_rotl32(v1, 13);
|
||||
v1 *= PRIME32_1;
|
||||
p+=4;
|
||||
v2 += XXH_readLE32(p, endian) * PRIME32_2;
|
||||
v2 = XXH_rotl32(v2, 13);
|
||||
v2 *= PRIME32_1;
|
||||
p+=4;
|
||||
v3 += XXH_readLE32(p, endian) * PRIME32_2;
|
||||
v3 = XXH_rotl32(v3, 13);
|
||||
v3 *= PRIME32_1;
|
||||
p+=4;
|
||||
v4 += XXH_readLE32(p, endian) * PRIME32_2;
|
||||
v4 = XXH_rotl32(v4, 13);
|
||||
v4 *= PRIME32_1;
|
||||
p+=4;
|
||||
}
|
||||
while (p<=limit);
|
||||
|
||||
state->v1 = v1;
|
||||
state->v2 = v2;
|
||||
state->v3 = v3;
|
||||
state->v4 = v4;
|
||||
}
|
||||
|
||||
if (p < bEnd)
|
||||
{
|
||||
XXH_memcpy(state->mem32, p, bEnd-p);
|
||||
state->memsize = (int)(bEnd-p);
|
||||
}
|
||||
|
||||
return XXH_OK;
|
||||
}
|
||||
|
||||
XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void* input, size_t len)
|
||||
{
|
||||
XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
|
||||
|
||||
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
|
||||
return XXH32_update_endian(state_in, input, len, XXH_littleEndian);
|
||||
else
|
||||
return XXH32_update_endian(state_in, input, len, XXH_bigEndian);
|
||||
}
|
||||
|
||||
|
||||
|
||||
FORCE_INLINE U32 XXH32_digest_endian (const XXH32_state_t* state_in, XXH_endianess endian)
|
||||
{
|
||||
XXH_istate32_t* state = (XXH_istate32_t*) state_in;
|
||||
const BYTE * p = (const BYTE*)state->mem32;
|
||||
BYTE* bEnd = (BYTE*)(state->mem32) + state->memsize;
|
||||
U32 h32;
|
||||
|
||||
if (state->total_len >= 16)
|
||||
{
|
||||
h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18);
|
||||
}
|
||||
else
|
||||
{
|
||||
h32 = state->seed + PRIME32_5;
|
||||
}
|
||||
|
||||
h32 += (U32) state->total_len;
|
||||
|
||||
while (p+4<=bEnd)
|
||||
{
|
||||
h32 += XXH_readLE32(p, endian) * PRIME32_3;
|
||||
h32 = XXH_rotl32(h32, 17) * PRIME32_4;
|
||||
p+=4;
|
||||
}
|
||||
|
||||
while (p<bEnd)
|
||||
{
|
||||
h32 += (*p) * PRIME32_5;
|
||||
h32 = XXH_rotl32(h32, 11) * PRIME32_1;
|
||||
p++;
|
||||
}
|
||||
|
||||
h32 ^= h32 >> 15;
|
||||
h32 *= PRIME32_2;
|
||||
h32 ^= h32 >> 13;
|
||||
h32 *= PRIME32_3;
|
||||
h32 ^= h32 >> 16;
|
||||
|
||||
return h32;
|
||||
}
|
||||
|
||||
|
||||
U32 XXH32_digest (const XXH32_state_t* state_in)
|
||||
{
|
||||
XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
|
||||
|
||||
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
|
||||
return XXH32_digest_endian(state_in, XXH_littleEndian);
|
||||
else
|
||||
return XXH32_digest_endian(state_in, XXH_bigEndian);
|
||||
}
|
||||
|
||||
|
||||
FORCE_INLINE XXH_errorcode XXH64_update_endian (XXH64_state_t* state_in, const void* input, size_t len, XXH_endianess endian)
|
||||
{
|
||||
XXH_istate64_t * state = (XXH_istate64_t *) state_in;
|
||||
const BYTE* p = (const BYTE*)input;
|
||||
const BYTE* const bEnd = p + len;
|
||||
|
||||
#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
|
||||
if (input==NULL) return XXH_ERROR;
|
||||
#endif
|
||||
|
||||
state->total_len += len;
|
||||
|
||||
if (state->memsize + len < 32) // fill in tmp buffer
|
||||
{
|
||||
XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len);
|
||||
state->memsize += (U32)len;
|
||||
return XXH_OK;
|
||||
}
|
||||
|
||||
if (state->memsize) // some data left from previous update
|
||||
{
|
||||
XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, 32-state->memsize);
|
||||
{
|
||||
const U64* p64 = state->mem64;
|
||||
state->v1 += XXH_readLE64(p64, endian) * PRIME64_2;
|
||||
state->v1 = XXH_rotl64(state->v1, 31);
|
||||
state->v1 *= PRIME64_1;
|
||||
p64++;
|
||||
state->v2 += XXH_readLE64(p64, endian) * PRIME64_2;
|
||||
state->v2 = XXH_rotl64(state->v2, 31);
|
||||
state->v2 *= PRIME64_1;
|
||||
p64++;
|
||||
state->v3 += XXH_readLE64(p64, endian) * PRIME64_2;
|
||||
state->v3 = XXH_rotl64(state->v3, 31);
|
||||
state->v3 *= PRIME64_1;
|
||||
p64++;
|
||||
state->v4 += XXH_readLE64(p64, endian) * PRIME64_2;
|
||||
state->v4 = XXH_rotl64(state->v4, 31);
|
||||
state->v4 *= PRIME64_1;
|
||||
p64++;
|
||||
}
|
||||
p += 32-state->memsize;
|
||||
state->memsize = 0;
|
||||
}
|
||||
|
||||
if (p+32 <= bEnd)
|
||||
{
|
||||
const BYTE* const limit = bEnd - 32;
|
||||
U64 v1 = state->v1;
|
||||
U64 v2 = state->v2;
|
||||
U64 v3 = state->v3;
|
||||
U64 v4 = state->v4;
|
||||
|
||||
do
|
||||
{
|
||||
v1 += XXH_readLE64(p, endian) * PRIME64_2;
|
||||
v1 = XXH_rotl64(v1, 31);
|
||||
v1 *= PRIME64_1;
|
||||
p+=8;
|
||||
v2 += XXH_readLE64(p, endian) * PRIME64_2;
|
||||
v2 = XXH_rotl64(v2, 31);
|
||||
v2 *= PRIME64_1;
|
||||
p+=8;
|
||||
v3 += XXH_readLE64(p, endian) * PRIME64_2;
|
||||
v3 = XXH_rotl64(v3, 31);
|
||||
v3 *= PRIME64_1;
|
||||
p+=8;
|
||||
v4 += XXH_readLE64(p, endian) * PRIME64_2;
|
||||
v4 = XXH_rotl64(v4, 31);
|
||||
v4 *= PRIME64_1;
|
||||
p+=8;
|
||||
}
|
||||
while (p<=limit);
|
||||
|
||||
state->v1 = v1;
|
||||
state->v2 = v2;
|
||||
state->v3 = v3;
|
||||
state->v4 = v4;
|
||||
}
|
||||
|
||||
if (p < bEnd)
|
||||
{
|
||||
XXH_memcpy(state->mem64, p, bEnd-p);
|
||||
state->memsize = (int)(bEnd-p);
|
||||
}
|
||||
|
||||
return XXH_OK;
|
||||
}
|
||||
|
||||
XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void* input, size_t len)
|
||||
{
|
||||
XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
|
||||
|
||||
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
|
||||
return XXH64_update_endian(state_in, input, len, XXH_littleEndian);
|
||||
else
|
||||
return XXH64_update_endian(state_in, input, len, XXH_bigEndian);
|
||||
}
|
||||
|
||||
|
||||
|
||||
FORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state_in, XXH_endianess endian)
|
||||
{
|
||||
XXH_istate64_t * state = (XXH_istate64_t *) state_in;
|
||||
const BYTE * p = (const BYTE*)state->mem64;
|
||||
BYTE* bEnd = (BYTE*)state->mem64 + state->memsize;
|
||||
U64 h64;
|
||||
|
||||
if (state->total_len >= 32)
|
||||
{
|
||||
U64 v1 = state->v1;
|
||||
U64 v2 = state->v2;
|
||||
U64 v3 = state->v3;
|
||||
U64 v4 = state->v4;
|
||||
|
||||
h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
|
||||
|
||||
v1 *= PRIME64_2;
|
||||
v1 = XXH_rotl64(v1, 31);
|
||||
v1 *= PRIME64_1;
|
||||
h64 ^= v1;
|
||||
h64 = h64*PRIME64_1 + PRIME64_4;
|
||||
|
||||
v2 *= PRIME64_2;
|
||||
v2 = XXH_rotl64(v2, 31);
|
||||
v2 *= PRIME64_1;
|
||||
h64 ^= v2;
|
||||
h64 = h64*PRIME64_1 + PRIME64_4;
|
||||
|
||||
v3 *= PRIME64_2;
|
||||
v3 = XXH_rotl64(v3, 31);
|
||||
v3 *= PRIME64_1;
|
||||
h64 ^= v3;
|
||||
h64 = h64*PRIME64_1 + PRIME64_4;
|
||||
|
||||
v4 *= PRIME64_2;
|
||||
v4 = XXH_rotl64(v4, 31);
|
||||
v4 *= PRIME64_1;
|
||||
h64 ^= v4;
|
||||
h64 = h64*PRIME64_1 + PRIME64_4;
|
||||
}
|
||||
else
|
||||
{
|
||||
h64 = state->seed + PRIME64_5;
|
||||
}
|
||||
|
||||
h64 += (U64) state->total_len;
|
||||
|
||||
while (p+8<=bEnd)
|
||||
{
|
||||
U64 k1 = XXH_readLE64(p, endian);
|
||||
k1 *= PRIME64_2;
|
||||
k1 = XXH_rotl64(k1,31);
|
||||
k1 *= PRIME64_1;
|
||||
h64 ^= k1;
|
||||
h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4;
|
||||
p+=8;
|
||||
}
|
||||
|
||||
if (p+4<=bEnd)
|
||||
{
|
||||
h64 ^= (U64)(XXH_readLE32(p, endian)) * PRIME64_1;
|
||||
h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
|
||||
p+=4;
|
||||
}
|
||||
|
||||
while (p<bEnd)
|
||||
{
|
||||
h64 ^= (*p) * PRIME64_5;
|
||||
h64 = XXH_rotl64(h64, 11) * PRIME64_1;
|
||||
p++;
|
||||
}
|
||||
|
||||
h64 ^= h64 >> 33;
|
||||
h64 *= PRIME64_2;
|
||||
h64 ^= h64 >> 29;
|
||||
h64 *= PRIME64_3;
|
||||
h64 ^= h64 >> 32;
|
||||
|
||||
return h64;
|
||||
}
|
||||
|
||||
|
||||
unsigned long long XXH64_digest (const XXH64_state_t* state_in)
|
||||
{
|
||||
XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
|
||||
|
||||
if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
|
||||
return XXH64_digest_endian(state_in, XXH_littleEndian);
|
||||
else
|
||||
return XXH64_digest_endian(state_in, XXH_bigEndian);
|
||||
}
|
||||
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
154
src/ripple/beast/hash/impl/xxhash.h
Normal file
154
src/ripple/beast/hash/impl/xxhash.h
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
xxHash - Extremely Fast Hash algorithm
|
||||
Header File
|
||||
Copyright (C) 2012-2014, Yann Collet.
|
||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
You can contact the author at :
|
||||
- xxHash source repository : http://code.google.com/p/xxhash/
|
||||
*/
|
||||
|
||||
/* Notice extracted from xxHash homepage :
|
||||
|
||||
xxHash is an extremely fast Hash algorithm, running at RAM speed limits.
|
||||
It also successfully passes all tests from the SMHasher suite.
|
||||
|
||||
Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz)
|
||||
|
||||
Name Speed Q.Score Author
|
||||
xxHash 5.4 GB/s 10
|
||||
CrapWow 3.2 GB/s 2 Andrew
|
||||
MumurHash 3a 2.7 GB/s 10 Austin Appleby
|
||||
SpookyHash 2.0 GB/s 10 Bob Jenkins
|
||||
SBox 1.4 GB/s 9 Bret Mulvey
|
||||
Lookup3 1.2 GB/s 9 Bob Jenkins
|
||||
SuperFastHash 1.2 GB/s 1 Paul Hsieh
|
||||
CityHash64 1.05 GB/s 10 Pike & Alakuijala
|
||||
FNV 0.55 GB/s 5 Fowler, Noll, Vo
|
||||
CRC32 0.43 GB/s 9
|
||||
MD5-32 0.33 GB/s 10 Ronald L. Rivest
|
||||
SHA1-32 0.28 GB/s 10
|
||||
|
||||
Q.Score is a measure of quality of the hash function.
|
||||
It depends on successfully passing SMHasher test set.
|
||||
10 is a perfect score.
|
||||
*/
|
||||
|
||||
#ifndef BEAST_HASH_XXHASH_H_INCLUDED
|
||||
#define BEAST_HASH_XXHASH_H_INCLUDED
|
||||
|
||||
/*****************************
|
||||
Includes
|
||||
*****************************/
|
||||
#include <stddef.h> /* size_t */
|
||||
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
/*****************************
|
||||
Type
|
||||
*****************************/
|
||||
typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;
|
||||
|
||||
|
||||
|
||||
/*****************************
|
||||
Simple Hash Functions
|
||||
*****************************/
|
||||
|
||||
unsigned int XXH32 (const void* input, size_t length, unsigned seed);
|
||||
unsigned long long XXH64 (const void* input, size_t length, unsigned long long seed);
|
||||
|
||||
/*
|
||||
XXH32() :
|
||||
Calculate the 32-bits hash of sequence "length" bytes stored at memory address "input".
|
||||
The memory between input & input+length must be valid (allocated and read-accessible).
|
||||
"seed" can be used to alter the result predictably.
|
||||
This function successfully passes all SMHasher tests.
|
||||
Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s
|
||||
XXH64() :
|
||||
Calculate the 64-bits hash of sequence of length "len" stored at memory address "input".
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*****************************
|
||||
Advanced Hash Functions
|
||||
*****************************/
|
||||
typedef struct { long long ll[ 6]; } XXH32_state_t;
|
||||
typedef struct { long long ll[11]; } XXH64_state_t;
|
||||
|
||||
/*
|
||||
These structures allow static allocation of XXH states.
|
||||
States must then be initialized using XXHnn_reset() before first use.
|
||||
|
||||
If you prefer dynamic allocation, please refer to functions below.
|
||||
*/
|
||||
|
||||
XXH32_state_t* XXH32_createState(void);
|
||||
XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr);
|
||||
|
||||
XXH64_state_t* XXH64_createState(void);
|
||||
XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr);
|
||||
|
||||
/*
|
||||
These functions create and release memory for XXH state.
|
||||
States must then be initialized using XXHnn_reset() before first use.
|
||||
*/
|
||||
|
||||
|
||||
XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, unsigned seed);
|
||||
XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length);
|
||||
unsigned int XXH32_digest (const XXH32_state_t* statePtr);
|
||||
|
||||
XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned long long seed);
|
||||
XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length);
|
||||
unsigned long long XXH64_digest (const XXH64_state_t* statePtr);
|
||||
|
||||
/*
|
||||
These functions calculate the xxHash of an input provided in multiple smaller packets,
|
||||
as opposed to an input provided as a single block.
|
||||
|
||||
XXH state space must first be allocated, using either static or dynamic method provided above.
|
||||
|
||||
Start a new hash by initializing state with a seed, using XXHnn_reset().
|
||||
|
||||
Then, feed the hash state by calling XXHnn_update() as many times as necessary.
|
||||
Obviously, input must be valid, meaning allocated and read accessible.
|
||||
The function returns an error code, with 0 meaning OK, and any other value meaning there is an error.
|
||||
|
||||
Finally, you can produce a hash anytime, by using XXHnn_digest().
|
||||
This function returns the final nn-bits hash.
|
||||
You can nonetheless continue feeding the hash state with more input,
|
||||
and therefore get some new hashes, by calling again XXHnn_digest().
|
||||
|
||||
When you are done, don't forget to free XXH state space, using typically XXHnn_freeState().
|
||||
*/
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
140
src/ripple/beast/hash/meta.h
Normal file
140
src/ripple/beast/hash/meta.h
Normal file
@@ -0,0 +1,140 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2014, Howard Hinnant <howard.hinnant@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_HASH_META_H_INCLUDED
|
||||
#define BEAST_HASH_META_H_INCLUDED
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace beast {
|
||||
|
||||
template <bool ...> struct static_and;
|
||||
|
||||
template <bool b0, bool ... bN>
|
||||
struct static_and <b0, bN...>
|
||||
: public std::integral_constant <
|
||||
bool, b0 && static_and<bN...>::value>
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct static_and<>
|
||||
: public std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
static_assert( static_and<true, true, true>::value, "");
|
||||
static_assert(!static_and<true, false, true>::value, "");
|
||||
|
||||
template <std::size_t ...>
|
||||
struct static_sum;
|
||||
|
||||
template <std::size_t s0, std::size_t ...sN>
|
||||
struct static_sum <s0, sN...>
|
||||
: public std::integral_constant <
|
||||
std::size_t, s0 + static_sum<sN...>::value>
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct static_sum<>
|
||||
: public std::integral_constant<std::size_t, 0>
|
||||
{
|
||||
};
|
||||
|
||||
static_assert(static_sum<5, 2, 17, 0>::value == 24, "");
|
||||
|
||||
template <class T, class U>
|
||||
struct enable_if_lvalue
|
||||
: public std::enable_if
|
||||
<
|
||||
std::is_same<std::decay_t<T>, U>::value &&
|
||||
std::is_lvalue_reference<T>::value
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
/** Ensure const reference function parameters are valid lvalues.
|
||||
|
||||
Some functions, especially class constructors, accept const references and
|
||||
store them for later use. If any of those parameters are rvalue objects,
|
||||
the object will be freed as soon as the function returns. This could
|
||||
potentially lead to a variety of "use after free" errors.
|
||||
|
||||
If the function is rewritten as a template using this type and the
|
||||
parameters references as rvalue references (eg. TX&&), a compiler
|
||||
error will be generated if an rvalue is provided in the caller.
|
||||
|
||||
@code
|
||||
// Example:
|
||||
struct X
|
||||
{
|
||||
};
|
||||
struct Y
|
||||
{
|
||||
};
|
||||
|
||||
struct Unsafe
|
||||
{
|
||||
Unsafe (X const& x, Y const& y)
|
||||
: x_ (x)
|
||||
, y_ (y)
|
||||
{
|
||||
}
|
||||
|
||||
X const& x_;
|
||||
Y const& y_;
|
||||
};
|
||||
|
||||
struct Safe
|
||||
{
|
||||
template <class TX, class TY,
|
||||
class = beast::enable_if_lvalue_t<TX, X>,
|
||||
class = beast::enable_if_lvalue_t < TY, Y >>
|
||||
Safe (TX&& x, TY&& y)
|
||||
: x_ (x)
|
||||
, y_ (y)
|
||||
{
|
||||
}
|
||||
|
||||
X const& x_;
|
||||
Y const& y_;
|
||||
};
|
||||
|
||||
struct demo
|
||||
{
|
||||
void
|
||||
createObjects ()
|
||||
{
|
||||
X x {};
|
||||
Y const y {};
|
||||
Unsafe u1 (x, y); // ok
|
||||
Unsafe u2 (X (), y); // compiles, but u2.x_ becomes invalid at the end of the line.
|
||||
Safe s1 (x, y); // ok
|
||||
// Safe s2 (X (), y); // compile-time error
|
||||
}
|
||||
};
|
||||
@endcode
|
||||
*/
|
||||
template <class T, class U>
|
||||
using enable_if_lvalue_t = typename enable_if_lvalue<T, U>::type;
|
||||
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_UTILITY_META_H_INCLUDED
|
||||
60
src/ripple/beast/hash/siphash.h
Normal file
60
src/ripple/beast/hash/siphash.h
Normal file
@@ -0,0 +1,60 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2014, Howard Hinnant <howard.hinnant@gmail.com>,
|
||||
Vinnie Falco <vinnie.falco@gmail.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_HASH_SIPHASH_H_INCLUDED
|
||||
#define BEAST_HASH_SIPHASH_H_INCLUDED
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
namespace beast {
|
||||
|
||||
// See https://131002.net/siphash/
|
||||
class siphash
|
||||
{
|
||||
private:
|
||||
std::uint64_t v0_ = 0x736f6d6570736575ULL;
|
||||
std::uint64_t v1_ = 0x646f72616e646f6dULL;
|
||||
std::uint64_t v2_ = 0x6c7967656e657261ULL;
|
||||
std::uint64_t v3_ = 0x7465646279746573ULL;
|
||||
unsigned char buf_[8];
|
||||
unsigned bufsize_ = 0;
|
||||
unsigned total_length_ = 0;
|
||||
|
||||
public:
|
||||
using result_type = std::size_t;
|
||||
|
||||
static beast::endian const endian = beast::endian::native;
|
||||
|
||||
siphash() = default;
|
||||
|
||||
explicit
|
||||
siphash (std::uint64_t k0, std::uint64_t k1 = 0) noexcept;
|
||||
|
||||
void
|
||||
operator() (void const* key, std::size_t len) noexcept;
|
||||
|
||||
explicit
|
||||
operator std::size_t() noexcept;
|
||||
};
|
||||
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
61
src/ripple/beast/hash/spooky.h
Normal file
61
src/ripple/beast/hash/spooky.h
Normal file
@@ -0,0 +1,61 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2014, Howard Hinnant <howard.hinnant@gmail.com>,
|
||||
Vinnie Falco <vinnie.falco@gmail.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_HASH_SPOOKY_H_INCLUDED
|
||||
#define BEAST_HASH_SPOOKY_H_INCLUDED
|
||||
|
||||
#include <ripple/beast/hash/endian.h>
|
||||
#include <ripple/beast/hash/impl/spookyv2.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
// See http://burtleburtle.net/bob/hash/spooky.html
|
||||
class spooky
|
||||
{
|
||||
private:
|
||||
SpookyHash state_;
|
||||
|
||||
public:
|
||||
using result_type = std::size_t;
|
||||
static beast::endian const endian = beast::endian::native;
|
||||
|
||||
spooky (std::size_t seed1 = 1, std::size_t seed2 = 2) noexcept
|
||||
{
|
||||
state_.Init (seed1, seed2);
|
||||
}
|
||||
|
||||
void
|
||||
operator() (void const* key, std::size_t len) noexcept
|
||||
{
|
||||
state_.Update (key, len);
|
||||
}
|
||||
|
||||
explicit
|
||||
operator std::size_t() noexcept
|
||||
{
|
||||
std::uint64_t h1, h2;
|
||||
state_.Final (&h1, &h2);
|
||||
return static_cast <std::size_t> (h1);
|
||||
}
|
||||
};
|
||||
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
490
src/ripple/beast/hash/tests/hash_append_test.cpp
Normal file
490
src/ripple/beast/hash/tests/hash_append_test.cpp
Normal file
@@ -0,0 +1,490 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#if BEAST_INCLUDE_BEASTCONFIG
|
||||
#include <BeastConfig.h>
|
||||
#endif
|
||||
|
||||
#include <ripple/beast/hash/endian.h>
|
||||
#include <ripple/beast/hash/tests/hash_metrics.h>
|
||||
#include <ripple/beast/hash/hash_append.h>
|
||||
#include <ripple/beast/xor_shift_engine.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <ripple/beast/type_name.h>
|
||||
#include <array>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <random>
|
||||
|
||||
namespace beast {
|
||||
|
||||
template <class Block, class Derived>
|
||||
class block_stream
|
||||
{
|
||||
private:
|
||||
Block m_block;
|
||||
std::size_t m_size;
|
||||
|
||||
std::size_t
|
||||
needed() const noexcept
|
||||
{
|
||||
return sizeof(Block) - m_size;
|
||||
}
|
||||
|
||||
void*
|
||||
tail() noexcept
|
||||
{
|
||||
return ((char *)&m_block) + m_size;
|
||||
}
|
||||
|
||||
protected:
|
||||
void
|
||||
finish()
|
||||
{
|
||||
if (m_size > 0)
|
||||
{
|
||||
// zero-pad
|
||||
memset (tail(), 0, needed());
|
||||
static_cast <Derived*> (this)->process_block (m_block);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
block_stream ()
|
||||
: m_size(0)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
operator() (void const* data, std::size_t bytes) noexcept
|
||||
{
|
||||
// handle leftovers
|
||||
if (m_size > 0)
|
||||
{
|
||||
std::size_t const n (std::min (needed(), bytes));
|
||||
std::memcpy (tail(), data, n);
|
||||
data = ((char const*)data) + n;
|
||||
bytes -= n;
|
||||
m_size += n;
|
||||
|
||||
if (m_size < sizeof(Block))
|
||||
return;
|
||||
|
||||
static_cast <Derived*> (this)->process_block (m_block);
|
||||
}
|
||||
|
||||
// loop over complete blocks
|
||||
while (bytes >= sizeof(Block))
|
||||
{
|
||||
m_block = *((Block const*)data);
|
||||
static_cast <Derived*> (this)->process_block (m_block);
|
||||
data = ((char const*)data) + sizeof(m_block);
|
||||
bytes -= sizeof(m_block);
|
||||
}
|
||||
|
||||
// save leftovers
|
||||
if (bytes > 0)
|
||||
{
|
||||
memcpy (tail(), data, bytes);
|
||||
m_size += bytes;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace hash_append_tests {
|
||||
|
||||
template <std::size_t> class fnv1a_imp;
|
||||
|
||||
template <>
|
||||
class fnv1a_imp<64>
|
||||
{
|
||||
private:
|
||||
std::uint64_t state_ = 14695981039346656037u;
|
||||
|
||||
public:
|
||||
static beast::endian const endian = beast::endian::native;
|
||||
|
||||
void
|
||||
operator() (void const* key, std::size_t len) noexcept
|
||||
{
|
||||
unsigned char const* p = static_cast<unsigned char const*>(key);
|
||||
unsigned char const* const e = p + len;
|
||||
for (; p < e; ++p)
|
||||
state_ = (state_ ^ *p) * 1099511628211u;
|
||||
}
|
||||
|
||||
explicit
|
||||
operator std::size_t() noexcept
|
||||
{
|
||||
return state_;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class fnv1a_imp<32>
|
||||
{
|
||||
private:
|
||||
std::uint32_t state_ = 2166136261;
|
||||
|
||||
public:
|
||||
static beast::endian const endian = beast::endian::native;
|
||||
|
||||
void
|
||||
operator() (void const* key, std::size_t len) noexcept
|
||||
{
|
||||
unsigned char const* p = static_cast<unsigned char const*>(key);
|
||||
unsigned char const* const e = p + len;
|
||||
for (; p < e; ++p)
|
||||
state_ = (state_ ^ *p) * 16777619;
|
||||
}
|
||||
|
||||
explicit
|
||||
operator std::size_t() noexcept
|
||||
{
|
||||
return state_;
|
||||
}
|
||||
};
|
||||
|
||||
class fnv1a
|
||||
: public fnv1a_imp<CHAR_BIT*sizeof(std::size_t)>
|
||||
{
|
||||
public:
|
||||
};
|
||||
|
||||
class jenkins1
|
||||
{
|
||||
private:
|
||||
std::size_t state_ = 0;
|
||||
|
||||
public:
|
||||
static beast::endian const endian = beast::endian::native;
|
||||
|
||||
void
|
||||
operator() (void const* key, std::size_t len) noexcept
|
||||
{
|
||||
unsigned char const* p = static_cast <unsigned char const*>(key);
|
||||
unsigned char const* const e = p + len;
|
||||
for (; p < e; ++p)
|
||||
{
|
||||
state_ += *p;
|
||||
state_ += state_ << 10;
|
||||
state_ ^= state_ >> 6;
|
||||
}
|
||||
}
|
||||
|
||||
explicit
|
||||
operator std::size_t() noexcept
|
||||
{
|
||||
state_ += state_ << 3;
|
||||
state_ ^= state_ >> 11;
|
||||
state_ += state_ << 15;
|
||||
return state_;
|
||||
}
|
||||
};
|
||||
|
||||
class spooky
|
||||
{
|
||||
private:
|
||||
SpookyHash state_;
|
||||
|
||||
public:
|
||||
static beast::endian const endian = beast::endian::native;
|
||||
|
||||
spooky(std::size_t seed1 = 1, std::size_t seed2 = 2) noexcept
|
||||
{
|
||||
state_.Init(seed1, seed2);
|
||||
}
|
||||
|
||||
void
|
||||
operator()(void const* key, std::size_t len) noexcept
|
||||
{
|
||||
state_.Update(key, len);
|
||||
}
|
||||
|
||||
explicit
|
||||
operator std::size_t() noexcept
|
||||
{
|
||||
std::uint64_t h1, h2;
|
||||
state_.Final(&h1, &h2);
|
||||
return h1;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <
|
||||
class PRNG = std::conditional_t <
|
||||
sizeof(std::size_t)==sizeof(std::uint64_t),
|
||||
std::mt19937_64,
|
||||
std::mt19937
|
||||
>
|
||||
>
|
||||
class prng_hasher
|
||||
: public block_stream <std::size_t, prng_hasher <PRNG>>
|
||||
{
|
||||
private:
|
||||
std::size_t m_seed;
|
||||
PRNG m_prng;
|
||||
|
||||
using base = block_stream <std::size_t, prng_hasher <PRNG>>;
|
||||
friend base;
|
||||
|
||||
// compress
|
||||
void
|
||||
process_block (std::size_t block)
|
||||
{
|
||||
m_prng.seed (m_seed + block);
|
||||
m_seed = m_prng();
|
||||
}
|
||||
|
||||
public:
|
||||
prng_hasher (std::size_t seed = 0)
|
||||
: m_seed (seed)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
operator() (void const* data, std::size_t bytes) noexcept
|
||||
{
|
||||
base::operator() (data, bytes);
|
||||
}
|
||||
|
||||
explicit
|
||||
operator std::size_t() noexcept
|
||||
{
|
||||
base::finish();
|
||||
return m_seed;
|
||||
}
|
||||
};
|
||||
|
||||
class SlowKey
|
||||
{
|
||||
private:
|
||||
std::tuple <short, unsigned char, unsigned char> date_;
|
||||
std::vector <std::pair <int, int>> data_;
|
||||
|
||||
public:
|
||||
SlowKey()
|
||||
{
|
||||
static beast::xor_shift_engine eng;
|
||||
std::uniform_int_distribution<short> yeardata(1900, 2014);
|
||||
std::uniform_int_distribution<unsigned> monthdata(1, 12);
|
||||
std::uniform_int_distribution<unsigned> daydata(1, 28);
|
||||
std::uniform_int_distribution<std::size_t> veclen(0, 100);
|
||||
std::uniform_int_distribution<int> int1data(1, 10);
|
||||
std::uniform_int_distribution<int> int2data(-3, 5000);
|
||||
std::get<0>(date_) = yeardata(eng);
|
||||
std::get<1>(date_) = (unsigned char)monthdata(eng);
|
||||
std::get<2>(date_) = (unsigned char)daydata(eng);
|
||||
data_.resize(veclen(eng));
|
||||
for (auto& p : data_)
|
||||
{
|
||||
p.first = int1data(eng);
|
||||
p.second = int2data(eng);
|
||||
}
|
||||
}
|
||||
|
||||
// Hook into the system like this
|
||||
template <class Hasher>
|
||||
friend
|
||||
void
|
||||
hash_append (Hasher& h, SlowKey const& x) noexcept
|
||||
{
|
||||
using beast::hash_append;
|
||||
hash_append (h, x.date_, x.data_);
|
||||
}
|
||||
|
||||
friend
|
||||
bool operator< (SlowKey const& x, SlowKey const& y) noexcept
|
||||
{
|
||||
return std::tie(x.date_, x.data_) < std::tie(y.date_, y.data_);
|
||||
}
|
||||
|
||||
// Hook into the std::system like this
|
||||
friend struct std::hash<SlowKey>;
|
||||
friend struct X_fnv1a;
|
||||
};
|
||||
|
||||
struct FastKey
|
||||
{
|
||||
private:
|
||||
std::array <std::size_t, 4> m_values;
|
||||
|
||||
public:
|
||||
FastKey()
|
||||
{
|
||||
static beast::xor_shift_engine eng;
|
||||
for (auto& v : m_values)
|
||||
v = eng();
|
||||
}
|
||||
|
||||
friend
|
||||
bool
|
||||
operator< (FastKey const& x, FastKey const& y) noexcept
|
||||
{
|
||||
return x.m_values < y.m_values;
|
||||
}
|
||||
};
|
||||
|
||||
} // hash_append_tests
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class HashAlgorithm>
|
||||
struct is_contiguously_hashable <hash_append_tests::FastKey, HashAlgorithm>
|
||||
: std::integral_constant<bool, is_contiguously_hashable<std::array <std::size_t, 4>,
|
||||
HashAlgorithm>::value>
|
||||
{
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class hash_append_test : public unit_test::suite
|
||||
{
|
||||
public:
|
||||
using SlowKey = hash_append_tests::SlowKey;
|
||||
using FastKey = hash_append_tests::FastKey;
|
||||
|
||||
struct results_t
|
||||
{
|
||||
results_t()
|
||||
: collision_factor (0)
|
||||
, distribution_factor (0)
|
||||
, elapsed (0)
|
||||
{
|
||||
}
|
||||
|
||||
float collision_factor;
|
||||
float distribution_factor;
|
||||
float windowed_score;
|
||||
std::chrono::milliseconds elapsed;
|
||||
};
|
||||
|
||||
// Generate a set of keys
|
||||
template <class Key>
|
||||
std::set <Key>
|
||||
make_keys (std::size_t count)
|
||||
{
|
||||
std::set <Key> keys;
|
||||
while (count--)
|
||||
keys.emplace();
|
||||
return keys;
|
||||
}
|
||||
|
||||
// Generate a set of hashes from a container
|
||||
template <class Hasher, class Keys>
|
||||
std::vector <std::size_t>
|
||||
make_hashes (Keys const& keys)
|
||||
{
|
||||
std::vector <std::size_t> hashes;
|
||||
hashes.reserve (keys.size());
|
||||
for (auto const& key : keys)
|
||||
{
|
||||
Hasher h;
|
||||
hash_append (h, key);
|
||||
hashes.push_back (static_cast <std::size_t> (h));
|
||||
}
|
||||
return hashes;
|
||||
}
|
||||
|
||||
template <class Hasher, class Hashes>
|
||||
void
|
||||
measure_hashes (results_t& results, Hashes const& hashes)
|
||||
{
|
||||
results.collision_factor =
|
||||
hash_metrics::collision_factor (
|
||||
hashes.begin(), hashes.end());
|
||||
|
||||
results.distribution_factor =
|
||||
hash_metrics::distribution_factor (
|
||||
hashes.begin(), hashes.end());
|
||||
|
||||
results.windowed_score =
|
||||
hash_metrics::windowed_score (
|
||||
hashes.begin(), hashes.end());
|
||||
}
|
||||
|
||||
template <class Hasher, class Keys>
|
||||
void
|
||||
measure_keys (results_t& results, Keys const& keys)
|
||||
{
|
||||
auto const start (
|
||||
std::chrono::high_resolution_clock::now());
|
||||
|
||||
auto const hashes (make_hashes <Hasher> (keys));
|
||||
|
||||
results.elapsed = std::chrono::duration_cast <std::chrono::milliseconds> (
|
||||
std::chrono::high_resolution_clock::now() - start);
|
||||
|
||||
measure_hashes <Hasher> (results, hashes);
|
||||
}
|
||||
|
||||
template <class Hasher, class Key>
|
||||
void
|
||||
test_hasher (std::string const& name, std::size_t n)
|
||||
{
|
||||
results_t results;
|
||||
auto const keys (make_keys <Key> (n));
|
||||
measure_keys <Hasher> (results, keys);
|
||||
report (name, results);
|
||||
}
|
||||
|
||||
void
|
||||
report (std::string const& name, results_t const& results)
|
||||
{
|
||||
log <<
|
||||
std::left <<
|
||||
std::setw (39) << name << " | " <<
|
||||
std::right <<
|
||||
std::setw (13) << std::setprecision (5) <<
|
||||
results.collision_factor << " | " <<
|
||||
std::setw (13) << std::setprecision (5) <<
|
||||
results.distribution_factor << " | " <<
|
||||
std::setw (13) << std::setprecision (5) <<
|
||||
results.windowed_score << " | " <<
|
||||
std::left <<
|
||||
results.elapsed.count();
|
||||
pass ();
|
||||
}
|
||||
|
||||
void
|
||||
run()
|
||||
{
|
||||
log <<
|
||||
"name | collision | distribution | windowed | time (milliseconds)" << std::endl <<
|
||||
"----------------------------------------+---------------+---------------+---------------+--------------------";
|
||||
|
||||
//test_hasher <hash_append_tests::prng_hasher<>, SlowKey> ("prng_hasher <SlowKey>", 10000);
|
||||
//test_hasher <hash_append_tests::prng_hasher<>, FastKey> ("prng_hasher <FastKey>", 100000);
|
||||
|
||||
test_hasher <hash_append_tests::jenkins1, SlowKey> ("jenkins1 <SlowKey>", 1000000);
|
||||
test_hasher <hash_append_tests::spooky, SlowKey> ("spooky <SlowKey>", 1000000);
|
||||
test_hasher <hash_append_tests::fnv1a, SlowKey> ("fnv1a <SlowKey>", 1000000);
|
||||
|
||||
test_hasher <hash_append_tests::jenkins1, FastKey> ("jenkins1 <FastKey>", 1000000);
|
||||
test_hasher <hash_append_tests::spooky, FastKey> ("spooky <FastKey>", 1000000);
|
||||
test_hasher <hash_append_tests::fnv1a, FastKey> ("fnv1a <FastKey>", 1000000);
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE_MANUAL(hash_append,container,beast);
|
||||
|
||||
}
|
||||
200
src/ripple/beast/hash/tests/hash_metrics.h
Normal file
200
src/ripple/beast/hash/tests/hash_metrics.h
Normal file
@@ -0,0 +1,200 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2014, Howard Hinnant <howard.hinnant@gmail.com>,
|
||||
Vinnie Falco <vinnie.falco@gmail.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_HASH_HASH_METRICS_H_INCLUDED
|
||||
#define BEAST_HASH_HASH_METRICS_H_INCLUDED
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <climits>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace beast {
|
||||
namespace hash_metrics {
|
||||
|
||||
// Metrics for measuring the quality of container hash functions
|
||||
|
||||
/** Returns the fraction of duplicate items in the sequence. */
|
||||
template <class FwdIter>
|
||||
float
|
||||
collision_factor (FwdIter first, FwdIter last)
|
||||
{
|
||||
std::set <typename FwdIter::value_type> s (first, last);
|
||||
return 1 - static_cast <float>(s.size()) / std::distance (first, last);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Returns the deviation of the sequence from the ideal distribution. */
|
||||
template <class FwdIter>
|
||||
float
|
||||
distribution_factor (FwdIter first, FwdIter last)
|
||||
{
|
||||
using value_type = typename FwdIter::value_type;
|
||||
static_assert (std::is_unsigned <value_type>::value, "");
|
||||
|
||||
const unsigned nbits = CHAR_BIT * sizeof(std::size_t);
|
||||
const unsigned rows = nbits / 4;
|
||||
unsigned counts[rows][16] = {};
|
||||
std::for_each (first, last, [&](typename FwdIter::value_type h)
|
||||
{
|
||||
std::size_t mask = 0xF;
|
||||
for (unsigned i = 0; i < rows; ++i, mask <<= 4)
|
||||
counts[i][(h & mask) >> 4*i] += 1;
|
||||
});
|
||||
float mean_rows[rows] = {0};
|
||||
float mean_cols[16] = {0};
|
||||
for (unsigned i = 0; i < rows; ++i)
|
||||
{
|
||||
for (unsigned j = 0; j < 16; ++j)
|
||||
{
|
||||
mean_rows[i] += counts[i][j];
|
||||
mean_cols[j] += counts[i][j];
|
||||
}
|
||||
}
|
||||
for (unsigned i = 0; i < rows; ++i)
|
||||
mean_rows[i] /= 16;
|
||||
for (unsigned j = 0; j < 16; ++j)
|
||||
mean_cols[j] /= rows;
|
||||
std::pair<float, float> dev[rows][16];
|
||||
for (unsigned i = 0; i < rows; ++i)
|
||||
{
|
||||
for (unsigned j = 0; j < 16; ++j)
|
||||
{
|
||||
dev[i][j].first = std::abs(counts[i][j] - mean_rows[i]) / mean_rows[i];
|
||||
dev[i][j].second = std::abs(counts[i][j] - mean_cols[j]) / mean_cols[j];
|
||||
}
|
||||
}
|
||||
float max_err = 0;
|
||||
for (unsigned i = 0; i < rows; ++i)
|
||||
{
|
||||
for (unsigned j = 0; j < 16; ++j)
|
||||
{
|
||||
if (max_err < dev[i][j].first)
|
||||
max_err = dev[i][j].first;
|
||||
if (max_err < dev[i][j].second)
|
||||
max_err = dev[i][j].second;
|
||||
}
|
||||
}
|
||||
return max_err;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class T>
|
||||
inline
|
||||
T
|
||||
sqr(T t)
|
||||
{
|
||||
return t*t;
|
||||
}
|
||||
|
||||
double
|
||||
score (int const* bins, std::size_t const bincount, double const k)
|
||||
{
|
||||
double const n = bincount;
|
||||
// compute rms^2 value
|
||||
double rms_sq = 0;
|
||||
for(std::size_t i = 0; i < bincount; ++i)
|
||||
rms_sq += sqr(bins[i]);;
|
||||
rms_sq /= n;
|
||||
// compute fill factor
|
||||
double const f = (sqr(k) - 1) / (n*rms_sq - k);
|
||||
// rescale to (0,1) with 0 = good, 1 = bad
|
||||
return 1 - (f / n);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
std::uint32_t
|
||||
window (T* blob, int start, int count )
|
||||
{
|
||||
std::size_t const len = sizeof(T);
|
||||
static_assert((len & 3) == 0, "");
|
||||
if(count == 0)
|
||||
return 0;
|
||||
int const nbits = len * CHAR_BIT;
|
||||
start %= nbits;
|
||||
int ndwords = len / 4;
|
||||
std::uint32_t const* k = static_cast <
|
||||
std::uint32_t const*>(static_cast<void const*>(blob));
|
||||
int c = start & (32-1);
|
||||
int d = start / 32;
|
||||
if(c == 0)
|
||||
return (k[d] & ((1 << count) - 1));
|
||||
int ia = (d + 1) % ndwords;
|
||||
int ib = (d + 0) % ndwords;
|
||||
std::uint32_t a = k[ia];
|
||||
std::uint32_t b = k[ib];
|
||||
std::uint32_t t = (a << (32-c)) | (b >> c);
|
||||
t &= ((1 << count)-1);
|
||||
return t;
|
||||
}
|
||||
|
||||
} // detail
|
||||
|
||||
/** Calculated a windowed metric using bins.
|
||||
TODO Need reference (SMHasher?)
|
||||
*/
|
||||
template <class FwdIter>
|
||||
double
|
||||
windowed_score (FwdIter first, FwdIter last)
|
||||
{
|
||||
auto const size (std::distance (first, last));
|
||||
int maxwidth = 20;
|
||||
// We need at least 5 keys per bin to reliably test distribution biases
|
||||
// down to 1%, so don't bother to test sparser distributions than that
|
||||
while (static_cast<double>(size) / (1ull << maxwidth) < 5.0)
|
||||
maxwidth--;
|
||||
double worst = 0;
|
||||
std::vector <int> bins (1ull << maxwidth);
|
||||
int const hashbits = sizeof(std::size_t) * CHAR_BIT;
|
||||
for (int start = 0; start < hashbits; ++start)
|
||||
{
|
||||
int width = maxwidth;
|
||||
bins.assign (1ull << width, 0);
|
||||
for (auto iter (first); iter != last; ++iter)
|
||||
++bins[detail::window(&*iter, start, width)];
|
||||
// Test the distribution, then fold the bins in half,
|
||||
// repeat until we're down to 256 bins
|
||||
while (bins.size() >= 256)
|
||||
{
|
||||
double score (detail::score (
|
||||
bins.data(), bins.size(), size));
|
||||
worst = std::max(score, worst);
|
||||
if (--width < 8)
|
||||
break;
|
||||
for (std::size_t i = 0, j = bins.size() / 2; j < bins.size(); ++i, ++j)
|
||||
bins[i] += bins[j];
|
||||
bins.resize(bins.size() / 2);
|
||||
}
|
||||
}
|
||||
return worst;
|
||||
}
|
||||
|
||||
} // hash_metrics
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
119
src/ripple/beast/hash/tests/hash_speed_test.cpp
Normal file
119
src/ripple/beast/hash/tests/hash_speed_test.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/beast/hash/fnv1a.h>
|
||||
#include <ripple/beast/hash/siphash.h>
|
||||
#include <ripple/beast/hash/xxhasher.h>
|
||||
#include <ripple/beast/xor_shift_engine.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <random>
|
||||
|
||||
namespace beast {
|
||||
|
||||
class hash_speed_test : public beast::unit_test::suite
|
||||
{
|
||||
public:
|
||||
template <class Generator>
|
||||
static
|
||||
void
|
||||
rngfill (void* buffer, std::size_t bytes,
|
||||
Generator& g)
|
||||
{
|
||||
using result_type =
|
||||
typename Generator::result_type;
|
||||
while (bytes >= sizeof(result_type))
|
||||
{
|
||||
auto const v = g();
|
||||
std::memcpy(buffer, &v, sizeof(v));
|
||||
buffer = reinterpret_cast<
|
||||
std::uint8_t*>(buffer) + sizeof(v);
|
||||
bytes -= sizeof(v);
|
||||
}
|
||||
if (bytes > 0)
|
||||
{
|
||||
auto const v = g();
|
||||
std::memcpy(buffer, &v, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Generator, std::size_t N,
|
||||
class = std::enable_if_t<
|
||||
N % sizeof(typename Generator::result_type) == 0>>
|
||||
static
|
||||
void
|
||||
rngfill (std::array<std::uint8_t, N>& a, Generator& g)
|
||||
{
|
||||
using result_type =
|
||||
typename Generator::result_type;
|
||||
auto i = N / sizeof(result_type);
|
||||
result_type* p =
|
||||
reinterpret_cast<result_type*>(a.data());
|
||||
while (i--)
|
||||
*p++ = g();
|
||||
}
|
||||
using clock_type =
|
||||
std::chrono::high_resolution_clock;
|
||||
template <class Hasher, std::size_t KeySize>
|
||||
void
|
||||
test (std::string const& what, std::size_t n)
|
||||
{
|
||||
using namespace std;
|
||||
using namespace std::chrono;
|
||||
xor_shift_engine g(1);
|
||||
array<std::uint8_t, KeySize> key;
|
||||
auto const start = clock_type::now();
|
||||
while(n--)
|
||||
{
|
||||
rngfill (key, g);
|
||||
Hasher h;
|
||||
h(key.data(), KeySize);
|
||||
volatile size_t temp =
|
||||
static_cast<std::size_t>(h);
|
||||
(void)temp;
|
||||
}
|
||||
auto const elapsed = clock_type::now() - start;
|
||||
log << setw(12) << what << " " <<
|
||||
duration<double>(elapsed).count() << "s";
|
||||
}
|
||||
|
||||
void
|
||||
run()
|
||||
{
|
||||
enum
|
||||
{
|
||||
N = 100000000
|
||||
};
|
||||
|
||||
#if ! BEAST_NO_XXHASH
|
||||
test<xxhasher,32> ("xxhash", N);
|
||||
#endif
|
||||
test<fnv1a,32> ("fnv1a", N);
|
||||
test<siphash,32> ("siphash", N);
|
||||
pass();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE_MANUAL(hash_speed,container,beast);
|
||||
|
||||
} // beast
|
||||
47
src/ripple/beast/hash/uhash.h
Normal file
47
src/ripple/beast/hash/uhash.h
Normal file
@@ -0,0 +1,47 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2014, Howard Hinnant <howard.hinnant@gmail.com>,
|
||||
Vinnie Falco <vinnie.falco@gmail.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_HASH_UHASH_H_INCLUDED
|
||||
#define BEAST_HASH_UHASH_H_INCLUDED
|
||||
|
||||
#include <ripple/beast/hash/hash_append.h>
|
||||
#include <ripple/beast/hash/spooky.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
// Universal hash function
|
||||
template <class Hasher = spooky>
|
||||
struct uhash
|
||||
{
|
||||
using result_type = typename Hasher::result_type;
|
||||
|
||||
template <class T>
|
||||
result_type
|
||||
operator()(T const& t) const noexcept
|
||||
{
|
||||
Hasher h;
|
||||
hash_append (h, t);
|
||||
return static_cast<result_type>(h);
|
||||
}
|
||||
};
|
||||
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
88
src/ripple/beast/hash/xxhasher.h
Normal file
88
src/ripple/beast/hash/xxhasher.h
Normal file
@@ -0,0 +1,88 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2014, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_HASH_XXHASHER_H_INCLUDED
|
||||
#define BEAST_HASH_XXHASHER_H_INCLUDED
|
||||
|
||||
#ifndef BEAST_NO_XXHASH
|
||||
#define BEAST_NO_XXHASH 0
|
||||
#endif
|
||||
|
||||
#if ! BEAST_NO_XXHASH
|
||||
|
||||
#include <ripple/beast/hash/endian.h>
|
||||
#include <ripple/beast/hash/impl/xxhash.h>
|
||||
#include <type_traits>
|
||||
#include <cstddef>
|
||||
|
||||
namespace beast {
|
||||
|
||||
class xxhasher
|
||||
{
|
||||
private:
|
||||
// requires 64-bit std::size_t
|
||||
static_assert(sizeof(std::size_t)==8, "");
|
||||
|
||||
detail::XXH64_state_t state_;
|
||||
|
||||
public:
|
||||
using result_type = std::size_t;
|
||||
|
||||
static beast::endian const endian = beast::endian::native;
|
||||
|
||||
xxhasher() noexcept
|
||||
{
|
||||
detail::XXH64_reset (&state_, 1);
|
||||
}
|
||||
|
||||
template <class Seed,
|
||||
std::enable_if_t<
|
||||
std::is_unsigned<Seed>::value>* = nullptr>
|
||||
explicit
|
||||
xxhasher (Seed seed)
|
||||
{
|
||||
detail::XXH64_reset (&state_, seed);
|
||||
}
|
||||
|
||||
template <class Seed,
|
||||
std::enable_if_t<
|
||||
std::is_unsigned<Seed>::value>* = nullptr>
|
||||
xxhasher (Seed seed, Seed)
|
||||
{
|
||||
detail::XXH64_reset (&state_, seed);
|
||||
}
|
||||
|
||||
void
|
||||
operator()(void const* key, std::size_t len) noexcept
|
||||
{
|
||||
detail::XXH64_update (&state_, key, len);
|
||||
}
|
||||
|
||||
explicit
|
||||
operator std::size_t() noexcept
|
||||
{
|
||||
return detail::XXH64_digest(&state_);
|
||||
}
|
||||
};
|
||||
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <ripple/beast/insight/Base.h>
|
||||
#include <ripple/beast/insight/EventImpl.h>
|
||||
|
||||
#include <beast/clock/chrono_util.h>
|
||||
#include <ripple/beast/clock/chrono_util.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include <ripple/beast/insight/Group.h>
|
||||
#include <ripple/beast/insight/Groups.h>
|
||||
#include <beast/hash/uhash.h>
|
||||
#include <ripple/beast/hash/uhash.h>
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <ripple/beast/insight/GaugeImpl.h>
|
||||
#include <ripple/beast/insight/MeterImpl.h>
|
||||
#include <ripple/beast/insight/StatsDCollector.h>
|
||||
#include <beast/asio/placeholders.h>
|
||||
#include <beast/placeholders.hpp>
|
||||
#include <ripple/beast/core/List.h>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
|
||||
#include <ripple/beast/net/IPAddressV4.h>
|
||||
#include <ripple/beast/net/IPAddressV6.h>
|
||||
#include <beast/hash/hash_append.h>
|
||||
#include <beast/hash/uhash.h>
|
||||
#include <ripple/beast/hash/hash_append.h>
|
||||
#include <ripple/beast/hash/uhash.h>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#ifndef BEAST_NET_IPADDRESSV4_H_INCLUDED
|
||||
#define BEAST_NET_IPADDRESSV4_H_INCLUDED
|
||||
|
||||
#include <beast/hash/hash_append.h>
|
||||
#include <ripple/beast/hash/hash_append.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
#define BEAST_NET_IPENDPOINT_H_INCLUDED
|
||||
|
||||
#include <ripple/beast/net/IPAddress.h>
|
||||
#include <beast/hash/hash_append.h>
|
||||
#include <beast/hash/uhash.h>
|
||||
#include <ripple/beast/hash/hash_append.h>
|
||||
#include <ripple/beast/hash/uhash.h>
|
||||
#include <cstdint>
|
||||
#include <ios>
|
||||
#include <string>
|
||||
|
||||
@@ -1,195 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_HTTP_URL_H_INCLUDED
|
||||
#define BEAST_HTTP_URL_H_INCLUDED
|
||||
|
||||
#include <ios>
|
||||
#include <utility>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** A URL.
|
||||
The accompanying robust parser is hardened against all forms of attack.
|
||||
*/
|
||||
class URL
|
||||
{
|
||||
public:
|
||||
/** Construct a URL from it's components. */
|
||||
URL (
|
||||
std::string schema_,
|
||||
std::string host_,
|
||||
std::uint16_t port_,
|
||||
std::string port_string_,
|
||||
std::string path_,
|
||||
std::string query_ = "",
|
||||
std::string fragment_ = "",
|
||||
std::string userinfo_ = "");
|
||||
|
||||
/** Construct an empty URL. */
|
||||
explicit URL () = default;
|
||||
|
||||
/** Copy construct a URL. */
|
||||
URL (URL const& other) = default;
|
||||
|
||||
/** Copy assign a URL. */
|
||||
URL& operator= (URL const& other) = default;
|
||||
|
||||
/** Move construct a URL. */
|
||||
URL (URL&& other) = default;
|
||||
|
||||
/** Returns `true` if this is an empty URL. */
|
||||
bool
|
||||
empty () const;
|
||||
|
||||
/** Returns the scheme of the URL.
|
||||
If no scheme was specified, the string will be empty.
|
||||
*/
|
||||
std::string const&
|
||||
scheme () const;
|
||||
|
||||
/** Returns the host of the URL.
|
||||
If no host was specified, the string will be empty.
|
||||
*/
|
||||
std::string const&
|
||||
host () const;
|
||||
|
||||
/** Returns the port number as an integer.
|
||||
If no port was specified, the value will be zero.
|
||||
*/
|
||||
std::uint16_t
|
||||
port () const;
|
||||
|
||||
/** Returns the port number as a string.
|
||||
If no port was specified, the string will be empty.
|
||||
*/
|
||||
std::string const&
|
||||
port_string () const;
|
||||
|
||||
/** Returns the path of the URL.
|
||||
If no path was specified, the string will be empty.
|
||||
*/
|
||||
std::string const&
|
||||
path () const;
|
||||
|
||||
/** Returns the query parameters portion of the URL.
|
||||
If no query parameters were present, the string will be empty.
|
||||
*/
|
||||
std::string const&
|
||||
query () const;
|
||||
|
||||
/** Returns the URL fragment, if any. */
|
||||
std::string const&
|
||||
fragment () const;
|
||||
|
||||
/** Returns the user information, if any. */
|
||||
std::string const&
|
||||
userinfo () const;
|
||||
|
||||
private:
|
||||
std::string m_scheme;
|
||||
std::string m_host;
|
||||
std::uint16_t m_port = 0;
|
||||
std::string m_port_string;
|
||||
std::string m_path;
|
||||
std::string m_query;
|
||||
std::string m_fragment;
|
||||
std::string m_userinfo;
|
||||
};
|
||||
|
||||
/** Attempt to parse a string into a URL */
|
||||
std::pair<bool, URL>
|
||||
parse_URL(std::string const&);
|
||||
|
||||
/** Retrieve the full URL as a single string. */
|
||||
std::string
|
||||
to_string(URL const& url);
|
||||
|
||||
/** Output stream conversion. */
|
||||
std::ostream&
|
||||
operator<< (std::ostream& os, URL const& url);
|
||||
|
||||
/** URL comparisons. */
|
||||
/** @{ */
|
||||
inline bool
|
||||
operator== (URL const& lhs, URL const& rhs)
|
||||
{
|
||||
return to_string (lhs) == to_string (rhs);
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!= (URL const& lhs, URL const& rhs)
|
||||
{
|
||||
return to_string (lhs) != to_string (rhs);
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator< (URL const& lhs, URL const& rhs)
|
||||
{
|
||||
return to_string (lhs) < to_string (rhs);
|
||||
}
|
||||
|
||||
inline bool operator> (URL const& lhs, URL const& rhs)
|
||||
{
|
||||
return to_string (rhs) < to_string (lhs);
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator<= (URL const& lhs, URL const& rhs)
|
||||
{
|
||||
return ! (to_string (rhs) < to_string (lhs));
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator>= (URL const& lhs, URL const& rhs)
|
||||
{
|
||||
return ! (to_string (lhs) < to_string (rhs));
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/** boost::hash support */
|
||||
template <class Hasher>
|
||||
inline
|
||||
void
|
||||
hash_append (Hasher& h, URL const& url)
|
||||
{
|
||||
using beast::hash_append;
|
||||
hash_append (h, to_string (url));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace std {
|
||||
|
||||
template <>
|
||||
struct hash <beast::URL>
|
||||
{
|
||||
std::size_t operator() (beast::URL const& url) const
|
||||
{
|
||||
return std::hash<std::string>{} (to_string (url));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#endif
|
||||
@@ -1,231 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/beast/net/URL.h>
|
||||
#include <beast/http/src/nodejs_parser.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
URL::URL (
|
||||
std::string scheme_,
|
||||
std::string host_,
|
||||
std::uint16_t port_,
|
||||
std::string port_string_,
|
||||
std::string path_,
|
||||
std::string query_,
|
||||
std::string fragment_,
|
||||
std::string userinfo_)
|
||||
: m_scheme (scheme_)
|
||||
, m_host (host_)
|
||||
, m_port (port_)
|
||||
, m_port_string (port_string_)
|
||||
, m_path (path_)
|
||||
, m_query (query_)
|
||||
, m_fragment (fragment_)
|
||||
, m_userinfo (userinfo_)
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool
|
||||
URL::empty () const
|
||||
{
|
||||
return m_scheme.empty ();
|
||||
}
|
||||
|
||||
std::string
|
||||
const& URL::scheme () const
|
||||
{
|
||||
return m_scheme;
|
||||
}
|
||||
|
||||
std::string
|
||||
const& URL::host () const
|
||||
{
|
||||
return m_host;
|
||||
}
|
||||
|
||||
std::string
|
||||
const& URL::port_string () const
|
||||
{
|
||||
return m_port_string;
|
||||
}
|
||||
|
||||
std::uint16_t
|
||||
URL::port () const
|
||||
{
|
||||
return m_port;
|
||||
}
|
||||
|
||||
std::string
|
||||
const& URL::path () const
|
||||
{
|
||||
return m_path;
|
||||
}
|
||||
|
||||
std::string
|
||||
const& URL::query () const
|
||||
{
|
||||
return m_query;
|
||||
}
|
||||
|
||||
std::string
|
||||
const& URL::fragment () const
|
||||
{
|
||||
return m_fragment;
|
||||
}
|
||||
|
||||
std::string
|
||||
const& URL::userinfo () const
|
||||
{
|
||||
return m_userinfo;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
std::pair<bool, URL>
|
||||
parse_URL(std::string const& url)
|
||||
{
|
||||
std::size_t const buflen (url.size ());
|
||||
char const* const buf (url.c_str ());
|
||||
|
||||
http_parser_url parser;
|
||||
|
||||
if (http_parser_parse_url (buf, buflen, false, &parser) != 0)
|
||||
return std::make_pair (false, URL{});
|
||||
|
||||
std::string scheme;
|
||||
std::string host;
|
||||
std::uint16_t port (0);
|
||||
std::string port_string;
|
||||
std::string path;
|
||||
std::string query;
|
||||
std::string fragment;
|
||||
std::string userinfo;
|
||||
|
||||
if ((parser.field_set & (1<<UF_SCHEMA)) != 0)
|
||||
{
|
||||
scheme = std::string (
|
||||
buf + parser.field_data [UF_SCHEMA].off,
|
||||
parser.field_data [UF_SCHEMA].len);
|
||||
}
|
||||
|
||||
if ((parser.field_set & (1<<UF_HOST)) != 0)
|
||||
{
|
||||
host = std::string (
|
||||
buf + parser.field_data [UF_HOST].off,
|
||||
parser.field_data [UF_HOST].len);
|
||||
}
|
||||
|
||||
if ((parser.field_set & (1<<UF_PORT)) != 0)
|
||||
{
|
||||
port = parser.port;
|
||||
port_string = std::string (
|
||||
buf + parser.field_data [UF_PORT].off,
|
||||
parser.field_data [UF_PORT].len);
|
||||
}
|
||||
|
||||
if ((parser.field_set & (1<<UF_PATH)) != 0)
|
||||
{
|
||||
path = std::string (
|
||||
buf + parser.field_data [UF_PATH].off,
|
||||
parser.field_data [UF_PATH].len);
|
||||
}
|
||||
|
||||
if ((parser.field_set & (1<<UF_QUERY)) != 0)
|
||||
{
|
||||
query = std::string (
|
||||
buf + parser.field_data [UF_QUERY].off,
|
||||
parser.field_data [UF_QUERY].len);
|
||||
}
|
||||
|
||||
if ((parser.field_set & (1<<UF_FRAGMENT)) != 0)
|
||||
{
|
||||
fragment = std::string (
|
||||
buf + parser.field_data [UF_FRAGMENT].off,
|
||||
parser.field_data [UF_FRAGMENT].len);
|
||||
}
|
||||
|
||||
if ((parser.field_set & (1<<UF_USERINFO)) != 0)
|
||||
{
|
||||
userinfo = std::string (
|
||||
buf + parser.field_data [UF_USERINFO].off,
|
||||
parser.field_data [UF_USERINFO].len);
|
||||
}
|
||||
|
||||
return std::make_pair (true,
|
||||
URL {scheme, host, port, port_string, path, query, fragment, userinfo});
|
||||
}
|
||||
|
||||
std::string
|
||||
to_string (URL const& url)
|
||||
{
|
||||
std::string s;
|
||||
|
||||
if (!url.empty ())
|
||||
{
|
||||
// Pre-allocate enough for components and inter-component separators
|
||||
s.reserve (
|
||||
url.scheme ().length () + url.userinfo ().length () +
|
||||
url.host ().length () + url.port_string ().length () +
|
||||
url.query ().length () + url.fragment ().length () + 16);
|
||||
|
||||
s.append (url.scheme ());
|
||||
s.append ("://");
|
||||
|
||||
if (!url.userinfo ().empty ())
|
||||
{
|
||||
s.append (url.userinfo ());
|
||||
s.append ("@");
|
||||
}
|
||||
|
||||
s.append (url.host ());
|
||||
|
||||
if (url.port ())
|
||||
{
|
||||
s.append (":");
|
||||
s.append (url.port_string ());
|
||||
}
|
||||
|
||||
s.append (url.path ());
|
||||
|
||||
if (!url.query ().empty ())
|
||||
{
|
||||
s.append ("?");
|
||||
s.append (url.query ());
|
||||
}
|
||||
|
||||
if (!url.fragment ().empty ())
|
||||
{
|
||||
s.append ("#");
|
||||
s.append (url.fragment ());
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<< (std::ostream &os, URL const& url)
|
||||
{
|
||||
os << to_string (url);
|
||||
return os;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <ripple/beast/net/IPEndpoint.h>
|
||||
#include <ripple/beast/net/detail/Parse.h>
|
||||
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
|
||||
#include <typeinfo>
|
||||
|
||||
|
||||
43
src/ripple/beast/net/tests/beast_asio_error_test.cpp
Normal file
43
src/ripple/beast/net/tests/beast_asio_error_test.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/beast/asio/ssl_error.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <string>
|
||||
|
||||
namespace beast {
|
||||
|
||||
class error_test : public unit_test::suite
|
||||
{
|
||||
public:
|
||||
void run()
|
||||
{
|
||||
{
|
||||
boost::system::error_code ec =
|
||||
boost::system::error_code (335544539,
|
||||
boost::asio::error::get_ssl_category ());
|
||||
std::string const s = beast::error_message_with_ssl(ec);
|
||||
expect(s == " (20,0,219) error:140000DB:SSL routines:SSL routines:short read");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(error,asio,beast);
|
||||
|
||||
} // beast
|
||||
@@ -18,9 +18,9 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/beast/nudb/test/common.h>
|
||||
#include <beast/unit_test/temp_dir.h>
|
||||
#include <beast/xor_shift_engine.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <beast/detail/temp_dir.hpp>
|
||||
#include <ripple/beast/xor_shift_engine.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
@@ -98,7 +98,7 @@ public:
|
||||
|
||||
testcase (abort_on_fail);
|
||||
|
||||
beast::temp_dir tempDir;
|
||||
beast::detail::temp_dir tempDir;
|
||||
do_test (N, tempDir.path());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/beast/nudb/test/common.h>
|
||||
#include <beast/xor_shift_engine.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <beast/unit_test/temp_dir.h>
|
||||
#include <ripple/beast/xor_shift_engine.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <beast/detail/temp_dir.hpp>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
@@ -117,7 +117,7 @@ public:
|
||||
{
|
||||
testcase << count << " inserts";
|
||||
|
||||
beast::temp_dir tempDir;
|
||||
beast::detail::temp_dir tempDir;
|
||||
|
||||
auto const path = tempDir.path();
|
||||
for (std::size_t n = 1;;++n)
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/beast/nudb/test/common.h>
|
||||
#include <beast/unit_test/temp_dir.h>
|
||||
#include <beast/xor_shift_engine.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <beast/detail/temp_dir.hpp>
|
||||
#include <ripple/beast/xor_shift_engine.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <cmath>
|
||||
#include <iomanip>
|
||||
#include <memory>
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
std::size_t block_size, float load_factor)
|
||||
{
|
||||
testcase (abort_on_fail);
|
||||
beast::temp_dir tempDir;
|
||||
beast::detail::temp_dir tempDir;
|
||||
|
||||
auto const dp = tempDir.file ("nudb.dat");
|
||||
auto const kp = tempDir.file ("nudb.key");
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/beast/nudb/detail/varint.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
|
||||
#include <ripple/beast/nudb/verify.h>
|
||||
#include <ripple/beast/nudb/test/common.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <beast/clock/basic_seconds_clock.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <ripple/beast/clock/basic_seconds_clock.h>
|
||||
#include <chrono>
|
||||
#include <iomanip>
|
||||
#include <ostream>
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
#include <ripple/beast/nudb.h>
|
||||
#include <ripple/beast/nudb/identity.h>
|
||||
#include <ripple/beast/nudb/test/fail_file.h>
|
||||
#include <beast/hash/xxhasher.h>
|
||||
#include <beast/xor_shift_engine.h>
|
||||
#include <ripple/beast/hash/xxhasher.h>
|
||||
#include <ripple/beast/xor_shift_engine.h>
|
||||
#include <cstdint>
|
||||
#include <iomanip>
|
||||
#include <memory>
|
||||
|
||||
188
src/ripple/beast/site_scons/Beast.py
Normal file
188
src/ripple/beast/site_scons/Beast.py
Normal file
@@ -0,0 +1,188 @@
|
||||
# Beast.py
|
||||
# Copyright 2014 by:
|
||||
# Vinnie Falco <vinnie.falco@gmail.com>
|
||||
# Tom Ritchford <?>
|
||||
# Nik Bougalis <?>
|
||||
# This file is part of Beast: http://github.com/vinniefalco/Beast
|
||||
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
import os
|
||||
import platform
|
||||
import subprocess
|
||||
import sys
|
||||
import SCons.Node
|
||||
import SCons.Util
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
#
|
||||
# Environment
|
||||
#
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
def _execute(args, include_errors=True, **kwds):
|
||||
"""Execute a shell command and return the value. If args is a string,
|
||||
it's split on spaces - if some of your arguments contain spaces, args should
|
||||
instead be a list of arguments."""
|
||||
def single_line(line, report_errors=True, joiner='+'):
|
||||
"""Force a string to be a single line with no carriage returns, and report
|
||||
a warning if there was more than one line."""
|
||||
lines = line.strip().splitlines()
|
||||
if report_errors and len(lines) > 1:
|
||||
print('multiline result:', lines)
|
||||
return joiner.join(lines)
|
||||
def is_string(s):
|
||||
"""Is s a string? - in either Python 2.x or 3.x."""
|
||||
return isinstance(s, (str, unicode))
|
||||
if is_string(args):
|
||||
args = args.split()
|
||||
stderr = subprocess.STDOUT if include_errors else None
|
||||
return single_line(subprocess.check_output(args, stderr=stderr, **kwds))
|
||||
|
||||
class __System(object):
|
||||
"""Provides information about the host platform"""
|
||||
def __init__(self):
|
||||
self.name = platform.system()
|
||||
self.linux = self.name == 'Linux'
|
||||
self.osx = self.name == 'Darwin'
|
||||
self.windows = self.name == 'Windows'
|
||||
self.distro = None
|
||||
self.version = None
|
||||
|
||||
# True if building under the Travis CI (http://travis-ci.org)
|
||||
self.travis = (
|
||||
os.environ.get('TRAVIS', '0') == 'true') and (
|
||||
os.environ.get('CI', '0') == 'true')
|
||||
|
||||
if self.linux:
|
||||
self.distro, self.version, _ = platform.linux_distribution()
|
||||
self.__display = '%s %s (%s)' % (self.distro, self.version, self.name)
|
||||
|
||||
elif self.osx:
|
||||
parts = platform.mac_ver()[0].split('.')
|
||||
while len(parts) < 3:
|
||||
parts.append('0')
|
||||
self.__display = '%s %s' % (self.name, '.'.join(parts))
|
||||
elif self.windows:
|
||||
release, version, csd, ptype = platform.win32_ver()
|
||||
self.__display = '%s %s %s (%s)' % (self.name, release, version, ptype)
|
||||
|
||||
else:
|
||||
raise Exception('Unknown system platform "' + self.name + '"')
|
||||
|
||||
self.platform = self.distro or self.name
|
||||
|
||||
def __str__(self):
|
||||
return self.__display
|
||||
|
||||
class Git(object):
|
||||
"""Provides information about git and the repository we are called from"""
|
||||
def __init__(self, env):
|
||||
self.tags = self.branch = self.user = ''
|
||||
self.exists = env.Detect('git')
|
||||
if self.exists:
|
||||
try:
|
||||
self.tags = _execute('git describe --tags')
|
||||
self.branch = _execute('git rev-parse --abbrev-ref HEAD')
|
||||
remote = _execute('git config remote.origin.url')
|
||||
self.user = remote.split(':')[1].split('/')[0]
|
||||
except:
|
||||
self.exists = False
|
||||
|
||||
system = __System()
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
def printChildren(target):
|
||||
def doPrint(tgt, level, found):
|
||||
for item in tgt:
|
||||
if SCons.Util.is_List(item):
|
||||
doPrint(item, level, found)
|
||||
else:
|
||||
if item.abspath in found:
|
||||
continue
|
||||
found[item.abspath] = False
|
||||
print('\t'*level + item.path)
|
||||
#DoPrint(item.children(scan=1), level+1, found)
|
||||
item.scan()
|
||||
doPrint(item.all_children(), level+1, found)
|
||||
doPrint(target, 0, {})
|
||||
|
||||
def variantFile(path, variant_dirs):
|
||||
'''Returns the path to the corresponding dict entry in variant_dirs'''
|
||||
path = str(path)
|
||||
for dest, source in variant_dirs.iteritems():
|
||||
common = os.path.commonprefix([path, source])
|
||||
if common == source:
|
||||
return os.path.join(dest, path[len(common)+1:])
|
||||
return path
|
||||
|
||||
def variantFiles(files, variant_dirs):
|
||||
'''Returns a list of files remapped to their variant directories'''
|
||||
result = []
|
||||
for path in files:
|
||||
result.append(variantFile(path, variant_dirs))
|
||||
return result
|
||||
|
||||
def printEnv(env, keys):
|
||||
if type(keys) != list:
|
||||
keys = list(keys)
|
||||
s = ''
|
||||
for key in keys:
|
||||
if key in env:
|
||||
value = env[key]
|
||||
else:
|
||||
value = ''
|
||||
s+=('%s=%s, ' % (key, value))
|
||||
print('[' + s + ']')
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
#
|
||||
# Output
|
||||
#
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# See https://stackoverflow.com/questions/7445658/how-to-detect-if-the-console-does-support-ansi-escape-codes-in-python
|
||||
CAN_CHANGE_COLOR = (
|
||||
hasattr(sys.stderr, "isatty")
|
||||
and sys.stderr.isatty()
|
||||
and not system.windows
|
||||
and not os.environ.get('INSIDE_EMACS')
|
||||
)
|
||||
|
||||
# See https://en.wikipedia.org/wiki/ANSI_escape_code
|
||||
BLUE = 94
|
||||
GREEN = 92
|
||||
RED = 91
|
||||
YELLOW = 93
|
||||
|
||||
def add_mode(text, *modes):
|
||||
if CAN_CHANGE_COLOR:
|
||||
modes = ';'.join(str(m) for m in modes)
|
||||
return '\033[%sm%s\033[0m' % (modes, text)
|
||||
else:
|
||||
return text
|
||||
|
||||
def blue(text):
|
||||
return add_mode(text, BLUE)
|
||||
|
||||
def green(text):
|
||||
return add_mode(text, GREEN)
|
||||
|
||||
def red(text):
|
||||
return add_mode(text, RED)
|
||||
|
||||
def yellow(text):
|
||||
return add_mode(text, YELLOW)
|
||||
|
||||
def warn(text, print=print):
|
||||
print('%s %s' % (red('WARNING:'), text))
|
||||
|
||||
# Prints command lines using environment substitutions
|
||||
def print_coms(coms, env):
|
||||
if type(coms) is str:
|
||||
coms=list(coms)
|
||||
for key in coms:
|
||||
cmdline = env.subst(env[key], 0,
|
||||
env.File('<target>'), env.File('<sources>'))
|
||||
print (green(cmdline))
|
||||
97
src/ripple/beast/site_scons/site_tools/Protoc.py
Normal file
97
src/ripple/beast/site_scons/site_tools/Protoc.py
Normal file
@@ -0,0 +1,97 @@
|
||||
#
|
||||
# Copyright (c) 2009 Scott Stafford
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
# Author : Scott Stafford
|
||||
# Date : 2009-12-09 20:36:14
|
||||
#
|
||||
# Changes : Vinnie Falco <vinnie.falco@gmail.com>
|
||||
# Date : 2014--4-25
|
||||
|
||||
"""
|
||||
Protoc.py: Protoc Builder for SCons
|
||||
|
||||
This Builder invokes protoc to generate C++ and Python from a .proto file.
|
||||
|
||||
NOTE: Java is not currently supported.
|
||||
"""
|
||||
|
||||
__author__ = "Scott Stafford"
|
||||
|
||||
import SCons.Action
|
||||
import SCons.Builder
|
||||
import SCons.Defaults
|
||||
import SCons.Node.FS
|
||||
import SCons.Util
|
||||
|
||||
from SCons.Script import File, Dir
|
||||
|
||||
import os.path
|
||||
|
||||
protocs = 'protoc'
|
||||
|
||||
ProtocAction = SCons.Action.Action('$PROTOCCOM', '$PROTOCCOMSTR')
|
||||
|
||||
def ProtocEmitter(target, source, env):
|
||||
PROTOCOUTDIR = env['PROTOCOUTDIR']
|
||||
PROTOCPYTHONOUTDIR = env['PROTOCPYTHONOUTDIR']
|
||||
for source_path in [str(x) for x in source]:
|
||||
base = os.path.splitext(os.path.basename(source_path))[0]
|
||||
if PROTOCOUTDIR:
|
||||
target.extend([os.path.join(PROTOCOUTDIR, base + '.pb.cc'),
|
||||
os.path.join(PROTOCOUTDIR, base + '.pb.h')])
|
||||
if PROTOCPYTHONOUTDIR:
|
||||
target.append(os.path.join(PROTOCPYTHONOUTDIR, base + '_pb2.py'))
|
||||
|
||||
try:
|
||||
target.append(env['PROTOCFDSOUT'])
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
#print "PROTOC SOURCE:", [str(s) for s in source]
|
||||
#print "PROTOC TARGET:", [str(s) for s in target]
|
||||
|
||||
return target, source
|
||||
|
||||
ProtocBuilder = SCons.Builder.Builder(
|
||||
action = ProtocAction,
|
||||
emitter = ProtocEmitter,
|
||||
srcsuffix = '$PROTOCSRCSUFFIX')
|
||||
|
||||
def generate(env):
|
||||
"""Add Builders and construction variables for protoc to an Environment."""
|
||||
try:
|
||||
bld = env['BUILDERS']['Protoc']
|
||||
except KeyError:
|
||||
bld = ProtocBuilder
|
||||
env['BUILDERS']['Protoc'] = bld
|
||||
|
||||
env['PROTOC'] = env.Detect(protocs) or 'protoc'
|
||||
env['PROTOCFLAGS'] = SCons.Util.CLVar('')
|
||||
env['PROTOCPROTOPATH'] = SCons.Util.CLVar('')
|
||||
env['PROTOCCOM'] = '$PROTOC ${["-I%s"%x for x in PROTOCPROTOPATH]} $PROTOCFLAGS --cpp_out=$PROTOCCPPOUTFLAGS$PROTOCOUTDIR ${PROTOCPYTHONOUTDIR and ("--python_out="+PROTOCPYTHONOUTDIR) or ""} ${PROTOCFDSOUT and ("-o"+PROTOCFDSOUT) or ""} ${SOURCES}'
|
||||
env['PROTOCOUTDIR'] = '${SOURCE.dir}'
|
||||
env['PROTOCPYTHONOUTDIR'] = "python"
|
||||
env['PROTOCSRCSUFFIX'] = '.proto'
|
||||
|
||||
def exists(env):
|
||||
return env.Detect(protocs)
|
||||
894
src/ripple/beast/site_scons/site_tools/VSProject.py
Normal file
894
src/ripple/beast/site_scons/site_tools/VSProject.py
Normal file
@@ -0,0 +1,894 @@
|
||||
# Copyright 2014 Vinnie Falco (vinnie.falco@gmail.com)
|
||||
# Portions Copyright The SCons Foundation
|
||||
# Portions Copyright Google, Inc.
|
||||
# This file is part of beast
|
||||
|
||||
"""
|
||||
A SCons tool to provide a family of scons builders that
|
||||
generate Visual Studio project files
|
||||
"""
|
||||
|
||||
import collections
|
||||
import hashlib
|
||||
import io
|
||||
import itertools
|
||||
import ntpath
|
||||
import os
|
||||
import pprint
|
||||
import random
|
||||
import re
|
||||
|
||||
import SCons.Builder
|
||||
import SCons.Node.FS
|
||||
import SCons.Node
|
||||
import SCons.Script.Main
|
||||
import SCons.Util
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# Adapted from msvs.py
|
||||
|
||||
UnicodeByteMarker = '\xEF\xBB\xBF'
|
||||
|
||||
V14DSPHeader = """\
|
||||
<?xml version="1.0" encoding="%(encoding)s"?>\r
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
|
||||
"""
|
||||
|
||||
V14DSPProjectConfiguration = """\
|
||||
<ProjectConfiguration Include="%(variant)s|%(platform)s">\r
|
||||
<Configuration>%(variant)s</Configuration>\r
|
||||
<Platform>%(platform)s</Platform>\r
|
||||
</ProjectConfiguration>\r
|
||||
"""
|
||||
|
||||
V14DSPGlobals = """\
|
||||
<PropertyGroup Label="Globals">\r
|
||||
<ProjectGuid>%(project_guid)s</ProjectGuid>\r
|
||||
<Keyword>Win32Proj</Keyword>\r
|
||||
<RootNamespace>%(name)s</RootNamespace>\r
|
||||
<IgnoreWarnCompileDuplicatedFilename>true</IgnoreWarnCompileDuplicatedFilename>\r
|
||||
</PropertyGroup>\r
|
||||
"""
|
||||
|
||||
V14DSPPropertyGroup = """\
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='%(variant)s|%(platform)s'" Label="Configuration">\r
|
||||
<CharacterSet>MultiByte</CharacterSet>\r
|
||||
<ConfigurationType>Application</ConfigurationType>\r
|
||||
<PlatformToolset>v140</PlatformToolset>\r
|
||||
<LinkIncremental>False</LinkIncremental>\r
|
||||
<UseDebugLibraries>%(use_debug_libs)s</UseDebugLibraries>\r
|
||||
<UseOfMfc>False</UseOfMfc>\r
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>\r
|
||||
<IntDir>%(int_dir)s</IntDir>\r
|
||||
<OutDir>%(out_dir)s</OutDir>\r
|
||||
</PropertyGroup>\r
|
||||
"""
|
||||
|
||||
V14DSPImportGroup= """\
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='%(variant)s|%(platform)s'" Label="PropertySheets">\r
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
|
||||
</ImportGroup>\r
|
||||
"""
|
||||
|
||||
V14DSPItemDefinitionGroup= """\
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='%(variant)s|%(platform)s'">\r
|
||||
"""
|
||||
|
||||
V14CustomBuildProtoc= """\
|
||||
<FileType>Document</FileType>\r
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='%(name)s'">protoc --cpp_out=%(cpp_out)s --proto_path=%%(RelativeDir) %%(Identity)</Command>\r
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='%(name)s'">%(base_out)s.pb.h;%(base_out)s.pb.cc</Outputs>\r
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='%(name)s'">protoc --cpp_out=%(cpp_out)s --proto_path=%%(RelativeDir) %%(Identity)</Message>\r
|
||||
<LinkObjects Condition="'$(Configuration)|$(Platform)'=='%(name)s'">false</LinkObjects>\r
|
||||
"""
|
||||
|
||||
V14DSPFiltersHeader = (
|
||||
'''<?xml version="1.0" encoding="utf-8"?>\r
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
|
||||
''')
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
def is_subdir(child, parent):
|
||||
'''Determine if child is a subdirectory of parent'''
|
||||
return os.path.commonprefix([parent, child]) == parent
|
||||
|
||||
def _key(item):
|
||||
if isinstance(item, (str, unicode)):
|
||||
return ('s', item.upper(), item)
|
||||
elif isinstance(item, (int, long, float)):
|
||||
return ('n', item)
|
||||
elif isinstance(item, (list, tuple)):
|
||||
return ('l', map(_key, item))
|
||||
elif isinstance(item, dict):
|
||||
return ('d', xsorted(item.keys()), xsorted(item.values()))
|
||||
elif isinstance(item, Configuration):
|
||||
return ('c', _key(item.name), _key(item.target), _key(item.variant), _key(item.platform))
|
||||
elif isinstance(item, Item):
|
||||
return ('i', _key(winpath(item.path())), _key(item.is_compiled()), _key(item.builder()), _key(item.tag()), _key(item.is_excluded()))
|
||||
elif isinstance(item, SCons.Node.FS.File):
|
||||
return ('f', _key(item.name), _key(item.suffix))
|
||||
else:
|
||||
return ('x', item)
|
||||
|
||||
def xsorted(tosort, **kwargs):
|
||||
'''Performs sorted in a deterministic manner.'''
|
||||
if 'key' in kwargs:
|
||||
map(kwargs['key'], tosort)
|
||||
kwargs['key'] = _key
|
||||
return sorted(tosort, **kwargs)
|
||||
|
||||
def itemList(items, sep):
|
||||
if type(items) == str: # Won't work in Python 3.
|
||||
return items
|
||||
def gen():
|
||||
for item in xsorted(items):
|
||||
if isinstance(item, dict):
|
||||
for k, v in xsorted(item.items()):
|
||||
yield k + '=' + v
|
||||
elif isinstance(item, (tuple, list)):
|
||||
assert len(item) == 2, "Item shoud have exactly two elements: " + str(item)
|
||||
yield '%s=%s' % tuple(item)
|
||||
else:
|
||||
yield item
|
||||
yield sep
|
||||
return ''.join(gen())
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
class SwitchConverter(object):
|
||||
'''Converts command line switches to MSBuild XML, using tables'''
|
||||
|
||||
def __init__(self, table, booltable, retable=None):
|
||||
self.table = {}
|
||||
for key in table:
|
||||
self.table[key] = table[key]
|
||||
for key in booltable:
|
||||
value = booltable[key]
|
||||
self.table[key] = [value[0], 'True']
|
||||
self.table[key + '-'] = [value[0], 'False']
|
||||
if retable != None:
|
||||
self.retable = retable
|
||||
else:
|
||||
self.retable = []
|
||||
|
||||
def getXml(self, switches, prefix = ''):
|
||||
switches = list(set(switches)) # Filter dupes because on windows platforms, /nologo is added automatically to the environment.
|
||||
xml = []
|
||||
for regex, tag in self.retable:
|
||||
matches = []
|
||||
for switch in switches[:]:
|
||||
match = regex.match(switch)
|
||||
if None != match:
|
||||
matches.append(match.group(1))
|
||||
switches.remove(switch)
|
||||
if len(matches) > 0:
|
||||
xml.append (
|
||||
'%s<%s>%s</%s>\r\n' % (
|
||||
prefix, tag, ';'.join(matches), tag))
|
||||
unknown = []
|
||||
for switch in switches:
|
||||
try:
|
||||
value = self.table[switch]
|
||||
xml.append (
|
||||
'%s<%s>%s</%s>\r\n' % (
|
||||
prefix, value[0], value[1], value[0]))
|
||||
except:
|
||||
unknown.append(switch)
|
||||
if unknown:
|
||||
s = itemList(unknown, ' ')
|
||||
tag = 'AdditionalOptions'
|
||||
xml.append('%(prefix)s<%(tag)s>%(s)s%%(%(tag)s)</%(tag)s>\r\n' % locals())
|
||||
if xml:
|
||||
return ''.join(xml)
|
||||
return ''
|
||||
|
||||
class ClSwitchConverter(SwitchConverter):
|
||||
def __init__(self):
|
||||
booltable = {
|
||||
'/C' : ['KeepComments'],
|
||||
'/doc' : ['GenerateXMLDocumentationFiles'],
|
||||
'/FAu' : ['UseUnicodeForAssemblerListing'],
|
||||
'/FC' : ['UseFullPaths'],
|
||||
'/FR' : ['BrowseInformation'],
|
||||
'/Fr' : ['BrowseInformation'],
|
||||
'/Fx' : ['ExpandAttributedSource'],
|
||||
'/GF' : ['StringPooling'],
|
||||
'/GL' : ['WholeProgramOptimization'],
|
||||
'/Gm' : ['MinimalRebuild'],
|
||||
'/GR' : ['RuntimeTypeInfo'],
|
||||
'/GS' : ['BufferSecurityCheck'],
|
||||
'/GT' : ['EnableFiberSafeOptimizations'],
|
||||
'/Gy' : ['FunctionLevelLinking'],
|
||||
'/MP' : ['MultiProcessorCompilation'],
|
||||
'/Oi' : ['IntrinsicFunctions'],
|
||||
'/Oy' : ['OmitFramePointers'],
|
||||
'/RTCc' : ['SmallerTypeCheck'],
|
||||
'/u' : ['UndefineAllPreprocessorDefinitions'],
|
||||
'/X' : ['IgnoreStandardIncludePath'],
|
||||
'/WX' : ['TreatWarningAsError'],
|
||||
'/Za' : ['DisableLanguageExtensions'],
|
||||
'/Zl' : ['OmitDefaultLibName'],
|
||||
'/fp:except' : ['FloatingPointExceptions'],
|
||||
'/hotpatch' : ['CreateHotpatchableImage'],
|
||||
'/nologo' : ['SuppressStartupBanner'],
|
||||
'/openmp' : ['OpenMPSupport'],
|
||||
'/showIncludes' : ['ShowIncludes'],
|
||||
'/Zc:forScope' : ['ForceConformanceInForLoopScope'],
|
||||
'/Zc:wchar_t' : ['TreatWChar_tAsBuiltInType'],
|
||||
}
|
||||
table = {
|
||||
'/EHsc' : ['ExceptionHandling', 'Sync'],
|
||||
'/EHa' : ['ExceptionHandling', 'Async'],
|
||||
'/EHs' : ['ExceptionHandling', 'SyncCThrow'],
|
||||
'/FA' : ['AssemblerOutput', 'AssemblyCode'],
|
||||
'/FAcs' : ['AssemblerOutput', 'All'],
|
||||
'/FAc' : ['AssemblerOutput', 'AssemblyAndMachineCode'],
|
||||
'/FAs' : ['AssemblerOutput', 'AssemblyAndSourceCode'],
|
||||
'/Gd' : ['CallingConvention', 'Cdecl'],
|
||||
'/Gr' : ['CallingConvention', 'FastCall'],
|
||||
'/Gz' : ['CallingConvention', 'StdCall'],
|
||||
'/MT' : ['RuntimeLibrary', 'MultiThreaded'],
|
||||
'/MTd' : ['RuntimeLibrary', 'MultiThreadedDebug'],
|
||||
'/MD' : ['RuntimeLibrary', 'MultiThreadedDLL'],
|
||||
'/MDd' : ['RuntimeLibrary', 'MultiThreadedDebugDLL'],
|
||||
'/Od' : ['Optimization', 'Disabled'],
|
||||
'/O1' : ['Optimization', 'MinSpace'],
|
||||
'/O2' : ['Optimization', 'MaxSpeed'],
|
||||
'/Ox' : ['Optimization', 'Full'],
|
||||
'/Ob1' : ['InlineFunctionExpansion', 'OnlyExplicitInline'],
|
||||
'/Ob2' : ['InlineFunctionExpansion', 'AnySuitable'],
|
||||
'/Ot' : ['FavorSizeOrSpeed', 'Speed'],
|
||||
'/Os' : ['FavorSizeOrSpeed', 'Size'],
|
||||
'/RTCs' : ['BasicRuntimeChecks', 'StackFrameRuntimeCheck'],
|
||||
'/RTCu' : ['BasicRuntimeChecks', 'UninitializedLocalUsageCheck'],
|
||||
'/RTC1' : ['BasicRuntimeChecks', 'EnableFastChecks'],
|
||||
'/TC' : ['CompileAs', 'CompileAsC'],
|
||||
'/TP' : ['CompileAs', 'CompileAsCpp'],
|
||||
'/W0' : [ 'WarningLevel', 'TurnOffAllWarnings'],
|
||||
'/W1' : [ 'WarningLevel', 'Level1'],
|
||||
'/W2' : [ 'WarningLevel', 'Level2'],
|
||||
'/W3' : [ 'WarningLevel', 'Level3'],
|
||||
'/W4' : [ 'WarningLevel', 'Level4'],
|
||||
'/Wall' : [ 'WarningLevel', 'EnableAllWarnings'],
|
||||
'/Yc' : ['PrecompiledHeader', 'Create'],
|
||||
'/Yu' : ['PrecompiledHeader', 'Use'],
|
||||
'/Z7' : ['DebugInformationFormat', 'OldStyle'],
|
||||
'/Zi' : ['DebugInformationFormat', 'ProgramDatabase'],
|
||||
'/ZI' : ['DebugInformationFormat', 'EditAndContinue'],
|
||||
'/Zp1' : ['StructMemberAlignment', '1Byte'],
|
||||
'/Zp2' : ['StructMemberAlignment', '2Bytes'],
|
||||
'/Zp4' : ['StructMemberAlignment', '4Bytes'],
|
||||
'/Zp8' : ['StructMemberAlignment', '8Bytes'],
|
||||
'/Zp16' : ['StructMemberAlignment', '16Bytes'],
|
||||
'/arch:IA32' : ['EnableEnhancedInstructionSet', 'NoExtensions'],
|
||||
'/arch:SSE' : ['EnableEnhancedInstructionSet', 'StreamingSIMDExtensions'],
|
||||
'/arch:SSE2' : ['EnableEnhancedInstructionSet', 'StreamingSIMDExtensions2'],
|
||||
'/arch:AVX' : ['EnableEnhancedInstructionSet', 'AdvancedVectorExtensions'],
|
||||
'/clr' : ['CompileAsManaged', 'True'],
|
||||
'/clr:pure' : ['CompileAsManaged', 'Pure'],
|
||||
'/clr:safe' : ['CompileAsManaged', 'Safe'],
|
||||
'/clr:oldSyntax' : ['CompileAsManaged', 'OldSyntax'],
|
||||
'/fp:fast' : ['FloatingPointModel', 'Fast'],
|
||||
'/fp:precise' : ['FloatingPointModel', 'Precise'],
|
||||
'/fp:strict' : ['FloatingPointModel', 'Strict'],
|
||||
'/errorReport:none' : ['ErrorReporting', 'None'],
|
||||
'/errorReport:prompt' : ['ErrorReporting', 'Prompt'],
|
||||
'/errorReport:queue' : ['ErrorReporting', 'Queue'],
|
||||
'/errorReport:send' : ['ErrorReporting', 'Send'],
|
||||
}
|
||||
retable = [
|
||||
(re.compile(r'/wd\"(\d+)\"'), 'DisableSpecificWarnings'),
|
||||
]
|
||||
# Ideas from Google's Generate Your Project
|
||||
'''
|
||||
_Same(_compile, 'AdditionalIncludeDirectories', _folder_list) # /I
|
||||
|
||||
_Same(_compile, 'PreprocessorDefinitions', _string_list) # /D
|
||||
_Same(_compile, 'ProgramDataBaseFileName', _file_name) # /Fd
|
||||
|
||||
_Same(_compile, 'AdditionalOptions', _string_list)
|
||||
_Same(_compile, 'AdditionalUsingDirectories', _folder_list) # /AI
|
||||
_Same(_compile, 'AssemblerListingLocation', _file_name) # /Fa
|
||||
_Same(_compile, 'BrowseInformationFile', _file_name)
|
||||
_Same(_compile, 'ForcedIncludeFiles', _file_list) # /FI
|
||||
_Same(_compile, 'ForcedUsingFiles', _file_list) # /FU
|
||||
_Same(_compile, 'UndefinePreprocessorDefinitions', _string_list) # /U
|
||||
_Same(_compile, 'XMLDocumentationFileName', _file_name)
|
||||
'' : ['EnablePREfast', _boolean) # /analyze Visible='false'
|
||||
_Renamed(_compile, 'ObjectFile', 'ObjectFileName', _file_name) # /Fo
|
||||
_Renamed(_compile, 'PrecompiledHeaderThrough', 'PrecompiledHeaderFile',
|
||||
_file_name) # Used with /Yc and /Yu
|
||||
_Renamed(_compile, 'PrecompiledHeaderFile', 'PrecompiledHeaderOutputFile',
|
||||
_file_name) # /Fp
|
||||
_ConvertedToAdditionalOption(_compile, 'DefaultCharIsUnsigned', '/J')
|
||||
_MSBuildOnly(_compile, 'ProcessorNumber', _integer) # the number of processors
|
||||
_MSBuildOnly(_compile, 'TrackerLogDirectory', _folder_name)
|
||||
_MSBuildOnly(_compile, 'TreatSpecificWarningsAsErrors', _string_list) # /we
|
||||
_MSBuildOnly(_compile, 'PreprocessOutputPath', _string) # /Fi
|
||||
'''
|
||||
SwitchConverter.__init__(self, table, booltable, retable)
|
||||
|
||||
class LinkSwitchConverter(SwitchConverter):
|
||||
def __init__(self):
|
||||
# Based on code in Generate Your Project
|
||||
booltable = {
|
||||
'/DEBUG' : ['GenerateDebugInformation'],
|
||||
'/DYNAMICBASE' : ['RandomizedBaseAddress'],
|
||||
'/NOLOGO' : ['SuppressStartupBanner'],
|
||||
'/nologo' : ['SuppressStartupBanner'],
|
||||
}
|
||||
table = {
|
||||
'/ERRORREPORT:NONE' : ['ErrorReporting', 'NoErrorReport'],
|
||||
'/ERRORREPORT:PROMPT' : ['ErrorReporting', 'PromptImmediately'],
|
||||
'/ERRORREPORT:QUEUE' : ['ErrorReporting', 'QueueForNextLogin'],
|
||||
'/ERRORREPORT:SEND' : ['ErrorReporting', 'SendErrorReport'],
|
||||
'/MACHINE:X86' : ['TargetMachine', 'MachineX86'],
|
||||
'/MACHINE:ARM' : ['TargetMachine', 'MachineARM'],
|
||||
'/MACHINE:EBC' : ['TargetMachine', 'MachineEBC'],
|
||||
'/MACHINE:IA64' : ['TargetMachine', 'MachineIA64'],
|
||||
'/MACHINE:MIPS' : ['TargetMachine', 'MachineMIPS'],
|
||||
'/MACHINE:MIPS16' : ['TargetMachine', 'MachineMIPS16'],
|
||||
'/MACHINE:MIPSFPU' : ['TargetMachine', 'MachineMIPSFPU'],
|
||||
'/MACHINE:MIPSFPU16' : ['TargetMachine', 'MachineMIPSFPU16'],
|
||||
'/MACHINE:SH4' : ['TargetMachine', 'MachineSH4'],
|
||||
'/MACHINE:THUMB' : ['TargetMachine', 'MachineTHUMB'],
|
||||
'/MACHINE:X64' : ['TargetMachine', 'MachineX64'],
|
||||
'/NXCOMPAT' : ['DataExecutionPrevention', 'true'],
|
||||
'/NXCOMPAT:NO' : ['DataExecutionPrevention', 'false'],
|
||||
'/SUBSYSTEM:CONSOLE' : ['SubSystem', 'Console'],
|
||||
'/SUBSYSTEM:WINDOWS' : ['SubSystem', 'Windows'],
|
||||
'/SUBSYSTEM:NATIVE' : ['SubSystem', 'Native'],
|
||||
'/SUBSYSTEM:EFI_APPLICATION' : ['SubSystem', 'EFI Application'],
|
||||
'/SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER' : ['SubSystem', 'EFI Boot Service Driver'],
|
||||
'/SUBSYSTEM:EFI_ROM' : ['SubSystem', 'EFI ROM'],
|
||||
'/SUBSYSTEM:EFI_RUNTIME_DRIVER' : ['SubSystem', 'EFI Runtime'],
|
||||
'/SUBSYSTEM:WINDOWSCE' : ['SubSystem', 'WindowsCE'],
|
||||
'/SUBSYSTEM:POSIX' : ['SubSystem', 'POSIX'],
|
||||
}
|
||||
'''
|
||||
/TLBID:1 /MANIFEST /MANIFESTUAC:level='asInvoker' uiAccess='false'
|
||||
|
||||
_Same(_link, 'AllowIsolation', _boolean) # /ALLOWISOLATION
|
||||
_Same(_link, 'CLRUnmanagedCodeCheck', _boolean) # /CLRUNMANAGEDCODECHECK
|
||||
_Same(_link, 'DelaySign', _boolean) # /DELAYSIGN
|
||||
_Same(_link, 'EnableUAC', _boolean) # /MANIFESTUAC
|
||||
_Same(_link, 'GenerateMapFile', _boolean) # /MAP
|
||||
_Same(_link, 'IgnoreAllDefaultLibraries', _boolean) # /NODEFAULTLIB
|
||||
_Same(_link, 'IgnoreEmbeddedIDL', _boolean) # /IGNOREIDL
|
||||
_Same(_link, 'MapExports', _boolean) # /MAPINFO:EXPORTS
|
||||
_Same(_link, 'StripPrivateSymbols', _file_name) # /PDBSTRIPPED
|
||||
_Same(_link, 'PerUserRedirection', _boolean)
|
||||
_Same(_link, 'Profile', _boolean) # /PROFILE
|
||||
_Same(_link, 'RegisterOutput', _boolean)
|
||||
_Same(_link, 'SetChecksum', _boolean) # /RELEASE
|
||||
_Same(_link, 'SupportUnloadOfDelayLoadedDLL', _boolean) # /DELAY:UNLOAD
|
||||
|
||||
_Same(_link, 'SwapRunFromCD', _boolean) # /SWAPRUN:CD
|
||||
_Same(_link, 'TurnOffAssemblyGeneration', _boolean) # /NOASSEMBLY
|
||||
_Same(_link, 'UACUIAccess', _boolean) # /uiAccess='true'
|
||||
_Same(_link, 'EnableCOMDATFolding', _newly_boolean) # /OPT:ICF
|
||||
_Same(_link, 'FixedBaseAddress', _newly_boolean) # /FIXED
|
||||
_Same(_link, 'LargeAddressAware', _newly_boolean) # /LARGEADDRESSAWARE
|
||||
_Same(_link, 'OptimizeReferences', _newly_boolean) # /OPT:REF
|
||||
_Same(_link, 'TerminalServerAware', _newly_boolean) # /TSAWARE
|
||||
|
||||
_Same(_link, 'AdditionalDependencies', _file_list)
|
||||
_Same(_link, 'AdditionalLibraryDirectories', _folder_list) # /LIBPATH
|
||||
_Same(_link, 'AdditionalManifestDependencies', _file_list) # /MANIFESTDEPENDENCY:
|
||||
_Same(_link, 'AdditionalOptions', _string_list)
|
||||
_Same(_link, 'AddModuleNamesToAssembly', _file_list) # /ASSEMBLYMODULE
|
||||
_Same(_link, 'AssemblyLinkResource', _file_list) # /ASSEMBLYLINKRESOURCE
|
||||
_Same(_link, 'BaseAddress', _string) # /BASE
|
||||
_Same(_link, 'DelayLoadDLLs', _file_list) # /DELAYLOAD
|
||||
_Same(_link, 'EmbedManagedResourceFile', _file_list) # /ASSEMBLYRESOURCE
|
||||
_Same(_link, 'EntryPointSymbol', _string) # /ENTRY
|
||||
_Same(_link, 'ForceSymbolReferences', _file_list) # /INCLUDE
|
||||
_Same(_link, 'FunctionOrder', _file_name) # /ORDER
|
||||
_Same(_link, 'HeapCommitSize', _string)
|
||||
_Same(_link, 'HeapReserveSize', _string) # /HEAP
|
||||
_Same(_link, 'ImportLibrary', _file_name) # /IMPLIB
|
||||
_Same(_link, 'KeyContainer', _file_name) # /KEYCONTAINER
|
||||
_Same(_link, 'KeyFile', _file_name) # /KEYFILE
|
||||
_Same(_link, 'ManifestFile', _file_name) # /ManifestFile
|
||||
_Same(_link, 'MapFileName', _file_name)
|
||||
_Same(_link, 'MergedIDLBaseFileName', _file_name) # /IDLOUT
|
||||
_Same(_link, 'MergeSections', _string) # /MERGE
|
||||
_Same(_link, 'MidlCommandFile', _file_name) # /MIDL
|
||||
_Same(_link, 'ModuleDefinitionFile', _file_name) # /DEF
|
||||
_Same(_link, 'OutputFile', _file_name) # /OUT
|
||||
_Same(_link, 'ProfileGuidedDatabase', _file_name) # /PGD
|
||||
_Same(_link, 'ProgramDatabaseFile', _file_name) # /PDB
|
||||
_Same(_link, 'StackCommitSize', _string)
|
||||
_Same(_link, 'StackReserveSize', _string) # /STACK
|
||||
_Same(_link, 'TypeLibraryFile', _file_name) # /TLBOUT
|
||||
_Same(_link, 'TypeLibraryResourceID', _integer) # /TLBID
|
||||
_Same(_link, 'Version', _string) # /VERSION
|
||||
|
||||
|
||||
_Same(_link, 'AssemblyDebug',
|
||||
_Enumeration(['',
|
||||
'true', # /ASSEMBLYDEBUG
|
||||
'false'])) # /ASSEMBLYDEBUG:DISABLE
|
||||
_Same(_link, 'CLRImageType',
|
||||
_Enumeration(['Default',
|
||||
'ForceIJWImage', # /CLRIMAGETYPE:IJW
|
||||
'ForcePureILImage', # /Switch="CLRIMAGETYPE:PURE
|
||||
'ForceSafeILImage'])) # /Switch="CLRIMAGETYPE:SAFE
|
||||
_Same(_link, 'CLRThreadAttribute',
|
||||
_Enumeration(['DefaultThreadingAttribute', # /CLRTHREADATTRIBUTE:NONE
|
||||
'MTAThreadingAttribute', # /CLRTHREADATTRIBUTE:MTA
|
||||
'STAThreadingAttribute'])) # /CLRTHREADATTRIBUTE:STA
|
||||
_Same(_link, 'Driver',
|
||||
_Enumeration(['NotSet',
|
||||
'Driver', # /Driver
|
||||
'UpOnly', # /DRIVER:UPONLY
|
||||
'WDM'])) # /DRIVER:WDM
|
||||
_Same(_link, 'LinkTimeCodeGeneration',
|
||||
_Enumeration(['Default',
|
||||
'UseLinkTimeCodeGeneration', # /LTCG
|
||||
'PGInstrument', # /LTCG:PGInstrument
|
||||
'PGOptimization', # /LTCG:PGOptimize
|
||||
'PGUpdate'])) # /LTCG:PGUpdate
|
||||
_Same(_link, 'ShowProgress',
|
||||
_Enumeration(['NotSet',
|
||||
'LinkVerbose', # /VERBOSE
|
||||
'LinkVerboseLib'], # /VERBOSE:Lib
|
||||
new=['LinkVerboseICF', # /VERBOSE:ICF
|
||||
'LinkVerboseREF', # /VERBOSE:REF
|
||||
'LinkVerboseSAFESEH', # /VERBOSE:SAFESEH
|
||||
'LinkVerboseCLR'])) # /VERBOSE:CLR
|
||||
_Same(_link, 'UACExecutionLevel',
|
||||
_Enumeration(['AsInvoker', # /level='asInvoker'
|
||||
'HighestAvailable', # /level='highestAvailable'
|
||||
'RequireAdministrator'])) # /level='requireAdministrator'
|
||||
_Same(_link, 'MinimumRequiredVersion', _string)
|
||||
_Same(_link, 'TreatLinkerWarningAsErrors', _boolean) # /WX
|
||||
|
||||
|
||||
# Options found in MSVS that have been renamed in MSBuild.
|
||||
_Renamed(_link, 'IgnoreDefaultLibraryNames', 'IgnoreSpecificDefaultLibraries',
|
||||
_file_list) # /NODEFAULTLIB
|
||||
_Renamed(_link, 'ResourceOnlyDLL', 'NoEntryPoint', _boolean) # /NOENTRY
|
||||
_Renamed(_link, 'SwapRunFromNet', 'SwapRunFromNET', _boolean) # /SWAPRUN:NET
|
||||
|
||||
_Moved(_link, 'GenerateManifest', '', _boolean)
|
||||
_Moved(_link, 'IgnoreImportLibrary', '', _boolean)
|
||||
_Moved(_link, 'LinkIncremental', '', _newly_boolean)
|
||||
_Moved(_link, 'LinkLibraryDependencies', 'ProjectReference', _boolean)
|
||||
_Moved(_link, 'UseLibraryDependencyInputs', 'ProjectReference', _boolean)
|
||||
|
||||
# MSVS options not found in MSBuild.
|
||||
_MSVSOnly(_link, 'OptimizeForWindows98', _newly_boolean)
|
||||
_MSVSOnly(_link, 'UseUnicodeResponseFiles', _boolean)
|
||||
|
||||
# MSBuild options not found in MSVS.
|
||||
_MSBuildOnly(_link, 'BuildingInIDE', _boolean)
|
||||
_MSBuildOnly(_link, 'ImageHasSafeExceptionHandlers', _boolean) # /SAFESEH
|
||||
_MSBuildOnly(_link, 'LinkDLL', _boolean) # /DLL Visible='false'
|
||||
_MSBuildOnly(_link, 'LinkStatus', _boolean) # /LTCG:STATUS
|
||||
_MSBuildOnly(_link, 'PreventDllBinding', _boolean) # /ALLOWBIND
|
||||
_MSBuildOnly(_link, 'SupportNobindOfDelayLoadedDLL', _boolean) # /DELAY:NOBIND
|
||||
_MSBuildOnly(_link, 'TrackerLogDirectory', _folder_name)
|
||||
_MSBuildOnly(_link, 'MSDOSStubFileName', _file_name) # /STUB Visible='false'
|
||||
_MSBuildOnly(_link, 'SectionAlignment', _integer) # /ALIGN
|
||||
_MSBuildOnly(_link, 'SpecifySectionAttributes', _string) # /SECTION
|
||||
_MSBuildOnly(_link, 'ForceFileOutput',
|
||||
_Enumeration([], new=['Enabled', # /FORCE
|
||||
# /FORCE:MULTIPLE
|
||||
'MultiplyDefinedSymbolOnly',
|
||||
'UndefinedSymbolOnly'])) # /FORCE:UNRESOLVED
|
||||
_MSBuildOnly(_link, 'CreateHotPatchableImage',
|
||||
_Enumeration([], new=['Enabled', # /FUNCTIONPADMIN
|
||||
'X86Image', # /FUNCTIONPADMIN:5
|
||||
'X64Image', # /FUNCTIONPADMIN:6
|
||||
'ItaniumImage'])) # /FUNCTIONPADMIN:16
|
||||
_MSBuildOnly(_link, 'CLRSupportLastError',
|
||||
_Enumeration([], new=['Enabled', # /CLRSupportLastError
|
||||
'Disabled', # /CLRSupportLastError:NO
|
||||
# /CLRSupportLastError:SYSTEMDLL
|
||||
'SystemDlls']))
|
||||
|
||||
'''
|
||||
SwitchConverter.__init__(self, table, booltable)
|
||||
|
||||
CLSWITCHES = ClSwitchConverter()
|
||||
LINKSWITCHES = LinkSwitchConverter()
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# Return a Windows path from a native path
|
||||
def winpath(path):
|
||||
drive, rest = ntpath.splitdrive(path)
|
||||
result = []
|
||||
while rest and rest != ntpath.sep:
|
||||
rest, part = ntpath.split(rest)
|
||||
result.insert(0, part)
|
||||
if rest:
|
||||
result.insert(0, rest)
|
||||
return ntpath.join(drive.upper(), *result)
|
||||
|
||||
def makeList(x):
|
||||
if not x:
|
||||
return []
|
||||
if type(x) is not list:
|
||||
return [x]
|
||||
return x
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
class Configuration(object):
|
||||
def __init__(self, variant, platform, target, env):
|
||||
self.name = '%s|%s' % (variant, platform)
|
||||
self.variant = variant
|
||||
self.platform = platform
|
||||
self.target = target
|
||||
self.env = env
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
class Item(object):
|
||||
'''Represents a file item in the Solution Explorer'''
|
||||
def __init__(self, path, builder):
|
||||
self._path = path
|
||||
self._builder = builder
|
||||
self.node = dict()
|
||||
|
||||
if builder == 'Object':
|
||||
self._tag = 'ClCompile'
|
||||
self._excluded = False
|
||||
elif builder == 'Protoc':
|
||||
self._tag = 'CustomBuild'
|
||||
self._excluded = False
|
||||
else:
|
||||
ext = os.path.splitext(self._path)[1]
|
||||
if ext in ['.c', '.cc', '.cpp']:
|
||||
self._tag = 'ClCompile'
|
||||
self._excluded = True
|
||||
else:
|
||||
if ext in ['.h', '.hpp', '.hxx', '.inl', '.inc']:
|
||||
self._tag = 'ClInclude'
|
||||
else:
|
||||
self._tag = 'None'
|
||||
self._excluded = False;
|
||||
|
||||
def __repr__(self):
|
||||
return '<VSProject.Item "%s" %s>' % (
|
||||
self.path, self.tag, str(self.node))
|
||||
|
||||
def path(self):
|
||||
return self._path
|
||||
|
||||
def tag(self):
|
||||
return self._tag
|
||||
|
||||
def builder(self):
|
||||
return self._builder
|
||||
|
||||
def is_compiled(self):
|
||||
return self._builder == 'Object'
|
||||
|
||||
def is_excluded(self):
|
||||
return self._excluded
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
def _guid(seed, name = None):
|
||||
m = hashlib.md5()
|
||||
m.update(seed)
|
||||
if name:
|
||||
m.update(name)
|
||||
d = m.hexdigest().upper()
|
||||
guid = "{%s-%s-%s-%s-%s}" % (d[:8], d[8:12], d[12:16], d[16:20], d[20:32])
|
||||
return guid
|
||||
|
||||
class _ProjectGenerator(object):
|
||||
'''Generates a project file for Visual Studio 2013'''
|
||||
|
||||
def __init__(self, project_node, filters_node, env):
|
||||
try:
|
||||
self.configs = xsorted(env['VSPROJECT_CONFIGS'])
|
||||
except KeyError:
|
||||
raise ValueError ('Missing VSPROJECT_CONFIGS')
|
||||
self.root_dir = os.getcwd()
|
||||
self.root_dirs = [os.path.abspath(x) for x in makeList(env['VSPROJECT_ROOT_DIRS'])]
|
||||
self.project_dir = os.path.dirname(os.path.abspath(str(project_node)))
|
||||
self.project_node = project_node
|
||||
self.project_file = None
|
||||
self.filters_node = filters_node
|
||||
self.filters_file = None
|
||||
self.guid = _guid(os.path.basename(str(self.project_node)))
|
||||
self.buildItemList(env)
|
||||
|
||||
def buildItemList(self, env):
|
||||
'''Build the Item set associated with the configurations'''
|
||||
items = {}
|
||||
def _walk(target, items, prefix=''):
|
||||
if os.path.isabs(str(target)):
|
||||
return
|
||||
if target.has_builder():
|
||||
builder = target.get_builder().get_name(env)
|
||||
bsources = target.get_binfo().bsources
|
||||
if builder == 'Program':
|
||||
for child in bsources:
|
||||
_walk(child, items, prefix+' ')
|
||||
else:
|
||||
for child in bsources:
|
||||
item = items.setdefault(str(child), Item(str(child), builder=builder))
|
||||
item.node[config] = target
|
||||
_walk(child, items, prefix+' ')
|
||||
for child in target.children(scan=1):
|
||||
if not os.path.isabs(str(child)):
|
||||
item = items.setdefault(str(child), Item(str(child), builder=None))
|
||||
_walk(child, items, prefix+' ')
|
||||
for config in self.configs:
|
||||
targets = config.target
|
||||
for target in targets:
|
||||
_walk(target, items)
|
||||
self.items = xsorted(items.values())
|
||||
|
||||
def makeListTag(self, items, prefix, tag, attrs, inherit=True):
|
||||
'''Builds an XML tag string from a list of items. If items is
|
||||
empty, then the returned string is empty.'''
|
||||
if not items:
|
||||
return ''
|
||||
s = '%(prefix)s<%(tag)s%(attrs)s>' % locals()
|
||||
s += ';'.join(items)
|
||||
if inherit:
|
||||
s += ';%%(%(tag)s)' % locals()
|
||||
s += '</%(tag)s>\r\n' % locals()
|
||||
return s
|
||||
|
||||
def relPaths(self, paths):
|
||||
items = []
|
||||
for path in paths:
|
||||
if not os.path.isabs(path):
|
||||
items.append(winpath(os.path.relpath(path, self.project_dir)))
|
||||
return items
|
||||
|
||||
def extraRelPaths(self, paths, base):
|
||||
extras = []
|
||||
for path in paths:
|
||||
if not path in base:
|
||||
extras.append(path)
|
||||
return self.relPaths(extras)
|
||||
|
||||
def writeHeader(self):
|
||||
global clSwitches
|
||||
|
||||
encoding = 'utf-8'
|
||||
project_guid = self.guid
|
||||
name = os.path.splitext(os.path.basename(str(self.project_node)))[0]
|
||||
|
||||
f = self.project_file
|
||||
f.write(UnicodeByteMarker)
|
||||
f.write(V14DSPHeader % locals())
|
||||
f.write(V14DSPGlobals % locals())
|
||||
f.write(' <ItemGroup Label="ProjectConfigurations">\r\n')
|
||||
for config in self.configs:
|
||||
variant = config.variant
|
||||
platform = config.platform
|
||||
f.write(V14DSPProjectConfiguration % locals())
|
||||
f.write(' </ItemGroup>\r\n')
|
||||
|
||||
f.write(' <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r\n')
|
||||
for config in self.configs:
|
||||
variant = config.variant
|
||||
platform = config.platform
|
||||
use_debug_libs = variant == 'Debug'
|
||||
variant_dir = os.path.relpath(os.path.dirname(
|
||||
config.target[0].get_abspath()), self.project_dir)
|
||||
out_dir = winpath(variant_dir) + ntpath.sep
|
||||
int_dir = winpath(ntpath.join(variant_dir, 'src')) + ntpath.sep
|
||||
f.write(V14DSPPropertyGroup % locals())
|
||||
|
||||
f.write(' <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r\n')
|
||||
f.write(' <ImportGroup Label="ExtensionSettings" />\r\n')
|
||||
for config in self.configs:
|
||||
variant = config.variant
|
||||
platform = config.platform
|
||||
f.write(V14DSPImportGroup % locals())
|
||||
|
||||
f.write(' <PropertyGroup Label="UserMacros" />\r\n')
|
||||
for config in self.configs:
|
||||
variant = config.variant
|
||||
platform = config.platform
|
||||
f.write(V14DSPItemDefinitionGroup % locals())
|
||||
# Cl options
|
||||
f.write(' <ClCompile>\r\n')
|
||||
f.write(
|
||||
' <PreprocessorDefinitions>%s%%(PreprocessorDefinitions)</PreprocessorDefinitions>\r\n' % (
|
||||
itemList(config.env['CPPDEFINES'], ';')))
|
||||
props = ''
|
||||
props += self.makeListTag(self.relPaths(xsorted(config.env['CPPPATH'])),
|
||||
' ', 'AdditionalIncludeDirectories', '', True)
|
||||
f.write(props)
|
||||
f.write(CLSWITCHES.getXml(xsorted(config.env['CCFLAGS']), ' '))
|
||||
f.write(' </ClCompile>\r\n')
|
||||
|
||||
f.write(' <Link>\r\n')
|
||||
props = ''
|
||||
props += self.makeListTag(xsorted(config.env['LIBS']),
|
||||
' ', 'AdditionalDependencies', '', True)
|
||||
try:
|
||||
props += self.makeListTag(self.relPaths(xsorted(config.env['LIBPATH'])),
|
||||
' ', 'AdditionalLibraryDirectories', '', True)
|
||||
except:
|
||||
pass
|
||||
f.write(props)
|
||||
f.write(LINKSWITCHES.getXml(xsorted(config.env['LINKFLAGS']), ' '))
|
||||
f.write(' </Link>\r\n')
|
||||
|
||||
f.write(' </ItemDefinitionGroup>\r\n')
|
||||
|
||||
def writeProject(self):
|
||||
self.writeHeader()
|
||||
|
||||
f = self.project_file
|
||||
self.project_file.write(' <ItemGroup>\r\n')
|
||||
for item in self.items:
|
||||
path = winpath(os.path.relpath(item.path(), self.project_dir))
|
||||
tag = item.tag()
|
||||
props = ''
|
||||
if item.builder() == 'Object':
|
||||
props = ''
|
||||
for config in self.configs:
|
||||
name = config.name
|
||||
variant = config.variant
|
||||
platform = config.platform
|
||||
if not config in item.node:
|
||||
props += \
|
||||
''' <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='%(variant)s|%(platform)s'">True</ExcludedFromBuild>\r\n''' % locals()
|
||||
for config, output in xsorted(item.node.items()):
|
||||
name = config.name
|
||||
env = output.get_build_env()
|
||||
variant = config.variant
|
||||
platform = config.platform
|
||||
props += self.makeListTag(self.extraRelPaths(xsorted(env['CPPPATH']), config.env['CPPPATH']),
|
||||
' ', 'AdditionalIncludeDirectories',
|
||||
''' Condition="'$(Configuration)|$(Platform)'=='%(variant)s|%(platform)s'"''' % locals(),
|
||||
True)
|
||||
elif item.is_excluded():
|
||||
props = ' <ExcludedFromBuild>True</ExcludedFromBuild>\r\n'
|
||||
elif item.builder() == 'Protoc':
|
||||
for config, output in xsorted(item.node.items()):
|
||||
name = config.name
|
||||
out_dir = os.path.relpath(os.path.dirname(str(output)), self.project_dir)
|
||||
cpp_out = winpath(out_dir)
|
||||
out_parts = out_dir.split(os.sep)
|
||||
out_parts.append(os.path.splitext(os.path.basename(item.path()))[0])
|
||||
base_out = ntpath.join(*out_parts)
|
||||
props += V14CustomBuildProtoc % locals()
|
||||
|
||||
f.write(' <%(tag)s Include="%(path)s">\r\n' % locals())
|
||||
f.write(props)
|
||||
f.write(' </%(tag)s>\r\n' % locals())
|
||||
f.write(' </ItemGroup>\r\n')
|
||||
|
||||
f.write(
|
||||
' <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r\n'
|
||||
' <ImportGroup Label="ExtensionTargets">\r\n'
|
||||
' </ImportGroup>\r\n'
|
||||
'</Project>\r\n')
|
||||
|
||||
def writeFilters(self):
|
||||
def getGroup(abspath):
|
||||
abspath = os.path.dirname(abspath)
|
||||
for d in self.root_dirs:
|
||||
common = os.path.commonprefix([abspath, d])
|
||||
if common == d:
|
||||
return winpath(os.path.relpath(abspath, common))
|
||||
return winpath(os.path.split(abspath)[1])
|
||||
|
||||
f = self.filters_file
|
||||
f.write(UnicodeByteMarker)
|
||||
f.write(V14DSPFiltersHeader)
|
||||
|
||||
f.write(' <ItemGroup>\r\n')
|
||||
groups = set()
|
||||
for item in self.items:
|
||||
group = getGroup(os.path.abspath(item.path()))
|
||||
while group != '':
|
||||
groups.add(group)
|
||||
group = ntpath.split(group)[0]
|
||||
for group in xsorted(groups):
|
||||
guid = _guid(self.guid, group)
|
||||
f.write(
|
||||
' <Filter Include="%(group)s">\r\n'
|
||||
' <UniqueIdentifier>%(guid)s</UniqueIdentifier>\r\n'
|
||||
' </Filter>\r\n' % locals())
|
||||
f.write(' </ItemGroup>\r\n')
|
||||
|
||||
f.write(' <ItemGroup>\r\n')
|
||||
for item in self.items:
|
||||
path = os.path.abspath(item.path())
|
||||
group = getGroup(path)
|
||||
path = winpath(os.path.relpath(path, self.project_dir))
|
||||
tag = item.tag()
|
||||
f.write (
|
||||
' <%(tag)s Include="%(path)s">\r\n'
|
||||
' <Filter>%(group)s</Filter>\r\n'
|
||||
' </%(tag)s>\r\n' % locals())
|
||||
f.write(' </ItemGroup>\r\n')
|
||||
f.write('</Project>\r\n')
|
||||
|
||||
def build(self):
|
||||
try:
|
||||
self.project_file = open(str(self.project_node), 'wb')
|
||||
except IOError, detail:
|
||||
raise SCons.Errors.InternalError('Unable to open "' +
|
||||
str(self.project_node) + '" for writing:' + str(detail))
|
||||
try:
|
||||
self.filters_file = open(str(self.filters_node), 'wb')
|
||||
except IOError, detail:
|
||||
raise SCons.Errors.InternalError('Unable to open "' +
|
||||
str(self.filters_node) + '" for writing:' + str(detail))
|
||||
self.writeProject()
|
||||
self.writeFilters()
|
||||
self.project_file.close()
|
||||
self.filters_file.close()
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
class _SolutionGenerator(object):
|
||||
def __init__(self, slnfile, projfile, env):
|
||||
pass
|
||||
|
||||
def build(self):
|
||||
pass
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# Generate the VS2013 project
|
||||
def buildProject(target, source, env):
|
||||
if env.get('auto_build_solution', 1):
|
||||
if len(target) != 3:
|
||||
raise ValueError ("Unexpected len(target) != 3")
|
||||
if not env.get('auto_build_solution', 1):
|
||||
if len(target) != 2:
|
||||
raise ValueError ("Unexpected len(target) != 2")
|
||||
|
||||
g = _ProjectGenerator (target[0], target[1], env)
|
||||
g.build()
|
||||
|
||||
if env.get('auto_build_solution', 1):
|
||||
g = _SolutionGenerator (target[2], target[0], env)
|
||||
g.build()
|
||||
|
||||
def projectEmitter(target, source, env):
|
||||
if len(target) != 1:
|
||||
raise ValueError ("Exactly one target must be specified")
|
||||
|
||||
# If source is unspecified this condition will be true
|
||||
if not source or source[0] == target[0]:
|
||||
source = []
|
||||
|
||||
outputs = []
|
||||
for node in list(target):
|
||||
path = env.GetBuildPath(node)
|
||||
outputs.extend([
|
||||
path + '.vcxproj',
|
||||
path + '.vcxproj.filters'])
|
||||
if env.get('auto_build_solution', 1):
|
||||
outputs.append(path + '.sln')
|
||||
return outputs, source
|
||||
|
||||
projectBuilder = SCons.Builder.Builder(
|
||||
action = SCons.Action.Action(buildProject, "Building ${TARGET}"),
|
||||
emitter = projectEmitter)
|
||||
|
||||
def createConfig(self, variant, platform, target, env):
|
||||
return Configuration(variant, platform, target, env)
|
||||
|
||||
def generate(env):
|
||||
'''Add Builders and construction variables for Microsoft Visual
|
||||
Studio project files to an Environment.'''
|
||||
try:
|
||||
env['BUILDERS']['VSProject']
|
||||
except KeyError:
|
||||
env['BUILDERS']['VSProject'] = projectBuilder
|
||||
env.AddMethod(createConfig, 'VSProjectConfig')
|
||||
|
||||
def exists(env):
|
||||
return True
|
||||
73
src/ripple/beast/type_name.h
Normal file
73
src/ripple/beast/type_name.h
Normal file
@@ -0,0 +1,73 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2014, Howard Hinnant <howard.hinnant@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_TYPE_NAME_H_INCLUDED
|
||||
#define BEAST_TYPE_NAME_H_INCLUDED
|
||||
|
||||
#include <type_traits>
|
||||
#include <typeinfo>
|
||||
#include <iostream>
|
||||
#ifndef _MSC_VER
|
||||
#include <cxxabi.h>
|
||||
#endif
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
|
||||
namespace beast {
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
std::string
|
||||
type_name()
|
||||
{
|
||||
using TR = typename std::remove_reference<T>::type;
|
||||
std::unique_ptr<char, void(*)(void*)> own (
|
||||
#ifndef _MSC_VER
|
||||
abi::__cxa_demangle (typeid(TR).name(), nullptr,
|
||||
nullptr, nullptr),
|
||||
#else
|
||||
nullptr,
|
||||
#endif
|
||||
std::free
|
||||
);
|
||||
std::string r = own != nullptr ? own.get() : typeid(TR).name();
|
||||
if (std::is_const<TR>::value)
|
||||
r += " const";
|
||||
if (std::is_volatile<TR>::value)
|
||||
r += " volatile";
|
||||
if (std::is_lvalue_reference<T>::value)
|
||||
r += "&";
|
||||
else if (std::is_rvalue_reference<T>::value)
|
||||
r += "&&";
|
||||
return r;
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
41
src/ripple/beast/unit_test.h
Normal file
41
src/ripple/beast/unit_test.h
Normal file
@@ -0,0 +1,41 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_UNIT_TEST_H_INCLUDED
|
||||
#define BEAST_UNIT_TEST_H_INCLUDED
|
||||
|
||||
#include <beast/detail/unit_test/amount.hpp>
|
||||
#include <beast/detail/unit_test/print.hpp>
|
||||
#include <beast/detail/unit_test/global_suites.hpp>
|
||||
#include <beast/detail/unit_test/match.hpp>
|
||||
#include <beast/detail/unit_test/recorder.hpp>
|
||||
#include <beast/detail/unit_test/reporter.hpp>
|
||||
#include <beast/detail/unit_test/results.hpp>
|
||||
#include <beast/detail/unit_test/runner.hpp>
|
||||
#include <beast/detail/unit_test/suite.hpp>
|
||||
#include <beast/detail/unit_test/suite_info.hpp>
|
||||
#include <beast/detail/unit_test/suite_list.hpp>
|
||||
|
||||
namespace beast {
|
||||
namespace unit_test {
|
||||
using namespace beast::detail::unit_test;
|
||||
} // unit_test
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
21
src/ripple/beast/unity/beast_clock_unity.cpp
Normal file
21
src/ripple/beast/unity/beast_clock_unity.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/beast/clock/tests/beast_abstract_clock_test.cpp>
|
||||
#include <ripple/beast/clock/tests/beast_basic_seconds_clock_test.cpp>
|
||||
29
src/ripple/beast/unity/beast_hash_unity.cpp
Normal file
29
src/ripple/beast/unity/beast_hash_unity.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/beast/hash/xxhasher.h>
|
||||
#include <ripple/beast/hash/impl/spookyv2.cpp>
|
||||
|
||||
#if ! BEAST_NO_XXHASH
|
||||
#include <ripple/beast/hash/impl/xxhash.c>
|
||||
#endif
|
||||
#include <ripple/beast/hash/impl/siphash.cpp>
|
||||
|
||||
#include <ripple/beast/hash/tests/hash_append_test.cpp>
|
||||
#include <ripple/beast/hash/tests/hash_speed_test.cpp>
|
||||
@@ -21,7 +21,5 @@
|
||||
#include <ripple/beast/net/impl/IPAddressV6.cpp>
|
||||
#include <ripple/beast/net/impl/IPEndpoint.cpp>
|
||||
#include <ripple/beast/net/impl/IPAddressConversion.cpp>
|
||||
#include <ripple/beast/net/impl/URL.cpp>
|
||||
|
||||
#include <ripple/beast/net/tests/beast_http_URL_test.cpp>
|
||||
#include <ripple/beast/net/tests/IPEndpoint.test.cpp>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user