Compare commits

..

425 Commits

Author SHA1 Message Date
Nik Bougalis
f999839e59 Set version to 0.27.3-sp2 2015-03-12 13:37:47 -07:00
JoelKatz
f1bc662a24 Add noripple_check RPC command
To help gateways make the changes needed to adjust to the
"default ripple" flag, we've added the "noripple_check"
RPC command. This command tells gateways what they need
to do to set this flag and fix any trust lines created
before they set the flag.

Once your server is running and synchronized, you can run
the tool from the command line with a command like:
  rippled json noripple_check '
  {
    "account" : "<gateway_trusted_address_here>",
    "role" : "gateway",
    "transactions" : "true"
  }'

The server will respond with a list of "problems" that it
sees with the configuration of the account and its trust
lines. It will also return a "transactions" array suggesting
the transactions needed to fix the problems it found.
2015-03-12 13:37:06 -07:00
Nik Bougalis
232693419a Set version to 0.27.3-sp1 2015-03-11 10:26:39 -07:00
Nicholas Dudfield
ed66b951c6 Fix testutils.create_accounts
* Don't call ledger_wait inside parallel async loop
2015-03-11 10:25:27 -07:00
Nik Bougalis
70c2854f7c Set version to 0.27.3 2015-03-10 14:06:33 -07:00
David Schwartz
e9381ddeb2 Add "Default Ripple" account flag and associated logic:
AccountSet set/clear, asfDefaultRipple = 8

AccountRoot flag, lsfDefaultRipple = 0x00800000

In trustCreate, set no ripple flag if appropriate.

If an account does not have the default ripple flag set,
new ripple lines created as a result of its offers being
taken or people creating trust lines to it have no ripple
set by that account's side automatically

Trust lines can be deleted if the no ripple flag matches
its default setting based on the account's default ripple
setting.

Fix default no-rippling in integration tests.
2015-03-10 14:05:18 -07:00
Nik Bougalis
9cc8eec773 Set version to 0.27.2 2015-03-01 14:56:44 -08:00
Nik Bougalis
0b45535061 Calculate deep offer quality 2015-02-28 13:28:54 -08:00
Vinnie Falco
95973ba3e8 Set version to 0.27.1 2015-02-24 13:31:13 -08:00
Vinnie Falco
ac64731d55 Set version to 0.27.1-rc3 2015-02-12 12:59:48 -08:00
Vinnie Falco
5dc064e971 Revert "Disable Overlay socket handoffs"
This reverts commit 8eb05d0950.
2015-02-12 12:59:48 -08:00
Vinnie Falco
c24732ed4e Fix streambuf bug:
The buffers_type::iterator could hold a pointer to a buffers_type that
was destroyed. This changes buffers_type::iterator to point to the
original streambuf instead, which always outlives the iterator.
2015-02-12 12:59:35 -08:00
Vinnie Falco
ba710bee86 Reject invalid requests on peer port sooner. 2015-02-12 12:43:42 -08:00
Vinnie Falco
c20392ca80 Set version to 0.27.1-rc2 2015-02-11 20:53:27 -08:00
Vinnie Falco
8eb05d0950 Disable Overlay socket handoffs 2015-02-11 20:53:27 -08:00
Vinnie Falco
0f94e2c0c3 Set version to 0.27.1-rc1 2015-02-10 16:22:14 -08:00
Vinnie Falco
a25508b98d Add RocksDB to nudb import tool (RIPD-781,785):
This custom tool is specifically designed for very fast import of
RocksDB nodestore databases into NuDB.
2015-02-10 16:22:14 -08:00
Vinnie Falco
e825433a38 NuDB: Use nodeobject codec in Backend (RIPD-793):
This adds codecs for snappy and lz4, and a new nodeobject codec. The
nodeobject codec provides a highly efficient custom compression scheme
for inner nodes, which make up the majority of nodestore databases.
Non inner node objects are compressed using lz4.

The NuDB backend is modified to use the nodeobject codec. This change
is not backward compatible - older NuDB databases cannot be opened or
imported.
2015-02-10 16:22:13 -08:00
Vinnie Falco
d1c08889fe Remove obsolete NodeObject fields:
Legacy fields of NodeObject are removed, as they are no longer
used and there is a space savings from omitting them:

* Remove LedgerIndex
2015-02-10 16:22:13 -08:00
Vinnie Falco
0b82b5a0d6 NuDB: Performance improvements (RIPD-793,796):
This introduces changes in nudb to improve speed, reduce database size,
and enhance correctness. The most significant change is to store hashes
rather than entire keys in the key file. The output of the hash function
is reduced to 48 bits, and stored directly in buckets.

The API is also modified to introduce a Codec parameter allowing for
compression and decompression to be supported in the implementation
itself rather than callers.

THe data file no longer contains a salt, as the salt is applicable
only to the key and log files. This allows a data file to have multiple
key files with different salt values. To distinguish physical files
belonging to the same logical database, a new field UID is introduced.
The UID is a 64-bit random value generated once on creation and stored
in all three files.

Buckets are zero filled to the end of each block, this is a security
measure to prevent unintended contents of memory getting stored to
disk. NuDB offers the varint integer type, this is identical to
the varint described by Google.

* Add varint
* Add Codec template argument
* Add "api" convenience traits
* Store hash in buckets
* istream can throw short read errors
* Support std::uint8_t format in streams
* Make file classes part of the public interface
* Remove buffers pessimization, replace with buffer
* Consolidate creation utility functions to the same header
* Zero fill unused areas of buckets on disk
* More coverage and improvements to the recover test
* Fix file read/write to loop until all bytes processed
* Add verify_fast, faster verify for large databases

The database version number is incremented to 2; older databases can
no longer be opened and should be deleted.
2015-02-10 16:22:13 -08:00
Vinnie Falco
a33d0d4fb6 Add general delimiter split() to rfc2616 2015-02-08 19:43:37 -08:00
Vinnie Falco
ba42334d36 Add lz4
Conflicts:
	Builds/VisualStudio2013/RippleD.vcxproj
	Builds/VisualStudio2013/RippleD.vcxproj.filters
2015-02-08 19:43:26 -08:00
Vinnie Falco
2e62641aa4 Merge commit 'dad460dcfc8466a8e1c59529d490829fcfaeee73' as 'src/lz4' 2015-02-08 19:43:04 -08:00
Vinnie Falco
dad460dcfc Squashed 'src/lz4/' content from commit e25b51d
git-subtree-dir: src/lz4
git-subtree-split: e25b51de7b51101e04ceea194dd557fcc23c03ca
2015-02-08 19:43:04 -08:00
Vinnie Falco
3ae23b6a54 Remove spurious call to fetch in NuDBBackend 2015-02-08 19:42:07 -08:00
Vinnie Falco
97126f18b1 Add /crawl cgi request feature to peer protocol (RIPD-729):
This adds support for a cgi /crawl request, issued over HTTPS to the configured
peer protocol port. The response to the request is a JSON object containing
the node public key, type, and IP address of each directly connected neighbor.
The IP address is suppressed unless the neighbor has requested its address
to be revealed by adding "Crawl: public" to its HTTP headers. This field is
currently set by the peer_private option in the rippled.cfg file.
2015-02-08 19:42:01 -08:00
Vinnie Falco
3838d222c2 NuDB: limit size of mempool (RIPD-787):
Insert now blocks when the size of the memory pool exceeds a predefined
threshold. This solves the problem where sustained insertions cause the
memory pool to grow without bound.
2015-02-08 19:41:54 -08:00
Vinnie Falco
96c3292210 Add missing include 2015-02-08 19:41:48 -08:00
Vinnie Falco
b0fd92cb3f Fix unsafe iterator dereference in PeerFinder 2015-02-08 19:41:43 -08:00
Vinnie Falco
6276c55cc9 Set version to 0.27.0-sp1 2015-02-03 14:58:02 -08:00
Vinnie Falco
afa6ff7c4b Revert RocksDB backend settings:
This reverts the change that makes RocksDBQuick the default settings for
node_db "type=rocksdb". The quick settings can be obtained by setting
"type=rocksdbquick".

RocksDBQuick settings are implicated in memory over-utilization problems
seen recently.
2015-02-03 14:57:54 -08:00
Vinnie Falco
c6c8e5d70c Set version to 0.27.0 2015-01-26 10:56:11 -08:00
Nik Bougalis
fa354ec8d9 Set version to 0.27.0-b11 2015-01-23 17:37:18 -08:00
Nik Bougalis
d0375f697d Invoke correct deleter 2015-01-23 17:34:30 -08:00
Vinnie Falco
33c8257d25 Set version to 0.27.0-b10 2015-01-21 15:25:11 -08:00
Scott Determan
f389bc33c3 VSProject: Handle tuples in CPPDEFINES:
The VSProject generator now handles tuples in addition to strings and
dicts when converting environment variables such as CPPDEFINES.
2015-01-21 15:20:06 -08:00
Vinnie Falco
4d5dca71ce Squelch Peerfinder fixed connection attempts 2015-01-21 14:59:47 -08:00
Vinnie Falco
a9c44a1b9c Set version to 0.27.0-b9 2015-01-21 14:23:50 -08:00
Vinnie Falco
4144f800a1 Fix PeerImp concurrent access of socket:
The PeerImp::run launch function is now dispatched on the strand to prevent
undefined behavior resulting from concurrent access to the ssl::stream object.
2015-01-21 14:21:43 -08:00
Vinnie Falco
6ef9a81017 Set version to 0.27.0-b8 2015-01-21 14:21:43 -08:00
Vinnie Falco
8c6722f3c5 Remove use of date and time from rocksdb unity build 2015-01-21 14:21:43 -08:00
Vinnie Falco
40e138627b Fixes to Overlay:
* Make ~Peer virtual
* Call close in ConnectAttempt::stop
* Handle nullptr return in new_outbound_slot
* Check gracefulClose_ in read loop
2015-01-21 10:48:32 -08:00
Vinnie Falco
a470dda4e6 Fix Journal::Stream::active to return the correct value 2015-01-21 10:48:32 -08:00
Edward Hennis
b725410623 Option to specify rippled path on command line.
* --rippled=<absolute or relative path>
* Works for "npm test" and "mocha"
* Remove "rippled_path" from config.js to require CLI path.
2015-01-21 10:48:31 -08:00
Miguel Portilla
a9dfb33126 Log abnormal close time offsets (RIPD-572) 2015-01-21 10:48:31 -08:00
Miguel Portilla
8b848770dc Add config "ledger_history_index" functionality (RIPD-559) 2015-01-21 10:48:31 -08:00
Vinnie Falco
94629edb9b Add NuDB backend:
The NuDB database backend is a high performance key/value store presented
as an alternative to RocksDB on Mac and Linux deployments, and the preferred
backend option for Windows deployments. The LevelDB backend is deprecated for
all platforms.

This includes these changes:

* Add Backend::verify API for doing consistency checks
* Add Database::close so caller can catch exceptions
* Improved Timing test for NodeStore creates a simulated workload
2015-01-21 10:48:30 -08:00
Vinnie Falco
2a3f2ca28d Add NuDB: A Key/Value Store For Decentralized Systems
NuDB is a high performance key/value database optimized for insert-only
workloads, with these features:

* Low memory footprint
* Values are immutable
* Value sizes from 1 2^48 bytes (281TB)
* All keys are the same size
* Performance independent of growth
* Optimized for concurrent fetch
* Key file can be rebuilt if needed
* Inserts are atomic and consistent
* Data file may be iterated, index rebuilt.
* Key and data files may be on different volumes
* Hardened against algorithmic complexity attacks
* Header-only, nothing to build or link
2015-01-21 10:48:30 -08:00
Edward Hennis
8ab1e7d432 Integration test to subscribe to offer books. 2015-01-20 16:45:04 -08:00
Miguel Portilla
b2ba6a0c85 Fix RPC subscribe with multiple books 2015-01-20 16:45:04 -08:00
Tom Ritchford
cca5421aed Fix Subscribe RPC to correctly distinguish bids and asks. 2015-01-20 16:45:04 -08:00
Nik Bougalis
799d9a73e6 Ensure that hash_append will never throw
Conflicts:
	src/beast/beast/net/IPAddress.h
2015-01-20 16:45:03 -08:00
Scott Determan
b0781622b2 Handle nullptr return values to InboundLedgers::findCreate
In normal operation, InboundLedgers::findCreate never returns null, but
during system shutdown, it will return null.

Since this only happens in system shutdown, when findCreate returns null
the calling function stops what it was doing and returns.

During testing, an issue where destroying the application object
and creating a new one caused problems with a static PathTable. This table
is now cleared when re-initialized.
2015-01-20 16:45:03 -08:00
Tom Ritchford
0d0eec6345 Clean up test documentation and a log message. 2015-01-20 16:45:03 -08:00
Nik Bougalis
1af79f7960 Properly validate the configured online delete interval 2015-01-20 16:45:03 -08:00
Vinnie Falco
15b570bbdd Add profile targets for gcc and clang 2015-01-20 16:45:02 -08:00
Tom Ritchford
7aa5599cc2 Remove unused parameter in two lambdas. 2015-01-20 16:45:02 -08:00
JoelKatz
676293ec42 Ensure account_tx queries over and returns correct range 2015-01-20 16:45:02 -08:00
Nik Bougalis
abc4fb81b1 Improve RippleLineCache hashing 2015-01-20 16:45:01 -08:00
Vinnie Falco
53a16f354f Add hardened_hash to basics/:
xxhasher is the default hash function for hardened_hash.
2015-01-20 16:45:01 -08:00
Vinnie Falco
6ab1ecd836 Tidy up container hash functions:
* Add xxhasher
* Move fnv1a, siphash, spookyto hash/
* Move hash_append, uhash to hash/
* Move hash_speed_test to hash/
* Move hash classes to individual header files
* Remove hardened_hash
2015-01-20 16:45:01 -08:00
Vinnie Falco
e7b16e7b47 Add rngfill 2015-01-20 16:45:01 -08:00
Vinnie Falco
14804f81a8 Optimize calls to unit_test::suite::expect:
This changes expect and unexpected to receive the reason text as a
template argument, allowing the std::string conversion of char const*
parameters to take place only if the condition evaluates to false. This
cuts all calls to malloc and free on tests that pass.
2015-01-20 16:45:00 -08:00
Vinnie Falco
9a61b8d77d Declare base_uints with using statements 2015-01-20 16:45:00 -08:00
Vinnie Falco
f42c2763d5 Improve streambuf unit test 2015-01-20 16:45:00 -08:00
Vinnie Falco
98d4e0e1b5 Fix ZeroCopyOutputStream:
Added a destructor that commits the last block of data
if there was no final call to BackUp.
2015-01-20 16:45:00 -08:00
Tom Ritchford
9156633baf Set version to 0.27.0-b7 2015-01-20 17:59:55 -05:00
Tom Ritchford
bcf4f836b4 Use websocketpp_02 namespace. 2015-01-20 17:08:15 -05:00
Vinnie Falco
dbc1d70f99 Set version to 0.27.0-b6 2015-01-20 09:41:27 -08:00
Vinnie Falco
78bc190a85 Merge commit '02855d7fed46d3c1aa1f2cefbcf4a42720575c3f' as 'src/websocketpp' 2015-01-20 09:35:00 -08:00
Vinnie Falco
02855d7fed Squashed 'src/websocketpp/' content from commit 875d420
git-subtree-dir: src/websocketpp
git-subtree-split: 875d420952
2015-01-20 09:35:00 -08:00
Vinnie Falco
6fdd5d32be Rename websocket/ to websocketpp_02 2015-01-20 09:34:54 -08:00
Vinnie Falco
d7f32b105b Set version to 0.27.0-b5 2015-01-13 11:50:58 -08:00
Vinnie Falco
0ac480a0bd Fix extra increment in GenerateRootDeterministicKey 2015-01-13 11:49:59 -08:00
Tom Ritchford
417996de02 Set version to 0.27.0-b4 2015-01-13 11:30:23 -05:00
Tom Ritchford
6c2d60cec2 Prevent RPC handlers from returning non-objects. 2015-01-13 11:30:23 -05:00
Tom Ritchford
743bd6c917 Fix RPC command logrotate to return a Json object. 2015-01-13 11:30:14 -05:00
Edward Hennis
ab61aa41d9 Set version to 0.27.0-b3 2015-01-12 18:00:55 -05:00
Edward Hennis
36396ae29e rippled.cfg [db_node] options for RocksDB
* open_files and compression.
2015-01-12 18:00:54 -05:00
Vinnie Falco
749e083e6e NodeStore improvements:
* Add Backend::verify API for doing consistency checks
* Add Database::close so caller can catch exceptions
* Improved Timing test for NodeStore creates a simulated workload
2015-01-12 18:00:52 -05:00
Vinnie Falco
67b9cf9e82 Improved support for exceptions in threads spawned by unit tests:
Unit tests that wish to spawn threads for testing concurrency may now do so
by using unit_test::thread as a replacement for std::thread. These threads
propagate unhandled exceptions to the unit test, and work with the abort on
failure feature.
2015-01-12 17:17:09 -05:00
Vinnie Falco
27fb20f3ab Add xor_shift_engine 2015-01-12 17:17:07 -05:00
Josh Juran
1c71b274f0 SConstruct: Add ed25519.c
Conflicts:
	Builds/VisualStudio2013/RippleD.vcxproj
	Builds/VisualStudio2013/RippleD.vcxproj.filters
	SConstruct
2015-01-12 12:16:26 -08:00
Vinnie Falco
fcd20b63fe Merge commit '8ec344ac1b6c66d936fa0f7005490e126a434a70' as 'src/ed25519-donna' 2015-01-12 11:27:15 -08:00
Vinnie Falco
8ec344ac1b Squashed 'src/ed25519-donna/' content from commit 04223b0
git-subtree-dir: src/ed25519-donna
git-subtree-split: 04223b04e22f5eff32c6c27e25194d4d984c6f41
2015-01-12 11:27:15 -08:00
Vinnie Falco
df966a9ac6 Set version to 0.27.0-b2 2015-01-05 18:49:18 -08:00
Vinnie Falco
f634666dc6 Make rocksdbquick settings default:
This removes the old default configuration for the "rocksdb" backend and
replaces it with the configuration that was formerly available using
the experimental backend "rocksdbquick".

The new configuration setting improves the performance of the key/value
database by changing the compaction style and tuning the size parameters for
the typical rippled workload. Testing shows a decrease in I/O spikes for both
reading and writing.
2015-01-05 18:49:17 -08:00
Tom Ritchford
e2f9f5d7e5 Fix compilation warnings. 2015-01-05 18:49:17 -08:00
Tom Ritchford
d078b0d143 Extract the git ID into a separate compilation unit. 2015-01-05 18:49:15 -08:00
Nik Bougalis
0ccdea3cd8 Disable Ticket transactions and tests 2015-01-05 14:18:27 -08:00
Vinnie Falco
df54b47cd0 Tidy up includes and add modules to the classic build:
An alternative to the unity build, the classic build compiles each
translation unit individually. This adds more modules to the classic build:

* Remove unity header app.h
* Add missing includes as needed
* Remove obsolete NodeStore backend code
* Add app/, core/, crypto/, json/, net/, overlay/, peerfinder/ to classic build
2015-01-05 13:35:57 -08:00
Vinnie Falco
2e595830b3 Levelize SHAMap:
The SHAMap class is refactored into a separate module where each translation
unit compiles separate without errors. Dependencies on higher level business
logic are removed. SHAMap now depends only on basics, crypto, nodestore,
and protocol:

* Inject NodeStore::Database& to SHAMap
* Move sync filter instances to app/ledger/
* Move shamap to its own module
* Move FullBelowCache to shamap/
* Move private code to shamap/impl/
* Refactor SHAMap treatment of missing node handler
* Inject and use Journal for logging in SHAMap
2015-01-05 11:46:11 -08:00
Vinnie Falco
96fbcc9a5a Refactor NodeStore:
Manager is changed to be a Meyer's singleton, with factories automatically
registering upon construction.
2015-01-05 11:46:11 -08:00
Vinnie Falco
6283801981 Add non-unity build targets:
The SConstruct is modified to provide a new family of targets, ending with
the suffix ".nounity", which compile individual translation units instead of
some of the unity translation units ("classic" builds). Two modules updated
for this treatment are ripple/basics/ and ripple/protocol/, with plans to
update more in the future. A consequence is longer build times in some cases.
A benefit of classic builds is that missing includes can be identified
through compiler errors.
2015-01-05 11:46:11 -08:00
Vinnie Falco
9a3214d46e Normalize files containing unit test code:
Source files are split to place all unit test code into translation
units ending in .test.cpp with no other business logic in the same file,
and in directories named "test".

A new target is added to the SConstruct, invoked by:
    scons count
This prints the total number of source code lines occupied by unit tests,
in rippled specific code and excluding library subtrees.
2015-01-05 11:46:07 -08:00
Vinnie Falco
9eb7c8344f Don't leak track StringPairArray 2015-01-05 11:44:15 -08:00
Vinnie Falco
4140bbb1f7 Set version to 0.27.0-b1 2015-01-05 11:37:01 -08:00
Vinnie Falco
ea44497136 Fix msvc ICE on initializer-list 2015-01-05 11:37:00 -08:00
Nik Bougalis
07737c6e5b Add 'delivered_amount' to Transaction JSON (RIPD-643):
The synthetic field 'delivered_amount' can be used to determine the exact
amount delivered by a Payment without having to check the DeliveredAmount
field, if present, or the Amount field otherwise.

The field is only returned when metadata is available and the data is not
returned in binary format.
2014-12-31 01:55:10 -08:00
JoelKatz
98d5eefc86 Pathfinding bugfixes (RIPD-735):
* Fix specifying paths and search level for ripple_path_find
* Don't modify the pathfinder, it has issuer-neutral paths.
* Handle previous paths correctly
* Compare paths correctly
2014-12-31 01:55:10 -08:00
JoelKatz
4f2d93bb65 Avoid processing transactions if we need a network ledger
Not processing tranasctions without a network ledger makes
initial network synchronization faster.
2014-12-31 01:55:10 -08:00
Edward Hennis
a5df3f1747 Support a "no_server" flag in test config.
* Will use a running instance of rippled (possibly in a debugger).
* Modify all tests to respect the server_default value.
* Fail test if new account already exists and has a balance.
* README.md with instructions for advanced test debugging, particularly using no_server.
2014-12-31 01:55:10 -08:00
Howard Hinnant
7f5f73887d Fix undefined behavior 2014-12-31 01:55:10 -08:00
Nik Bougalis
91ce7807b9 Remove legacy LoadTypes (RIPD-365) 2014-12-31 01:55:10 -08:00
Nik Bougalis
d26fae9875 Reduce Beast dependencies by leveraging C++11 features:
* Remove beast::Atomic (RIPD-728):
  * Use std-provided alternatives
  * Eliminate atomic variables where possible

* Cleanup beast::Thread interface:
  * Use std::string instead of beast::String
  * Remove unused functions and parameters

* Remove unused code:
  * beast::ThreadLocalValue
  * beast::ServiceQueue
2014-12-31 01:55:10 -08:00
Nik Bougalis
60bdc79ec4 Remove unused sitefiles module 2014-12-30 12:33:41 -08:00
Tom Ritchford
253ddf2998 Split off CheckLibraryVersions.test.cpp. 2014-12-30 12:33:41 -08:00
Nik Bougalis
9fa15b390a Always initialize LedgerHandler options field 2014-12-29 11:21:19 -08:00
Josh Juran
e7d6fe6c8b Cull duplicate/unused code in RippleAddress:
Deduplicate a call to GeneratePublicDeterministicKey().
Remove unused member functions.
2014-12-29 11:21:19 -08:00
Tom Ritchford
9650b1aa70 New ripple::TestSuite with method expectEquals(). 2014-12-29 11:21:19 -08:00
Howard Hinnant
eafa6f960f API for improved Unit Testing (RIPD-432):
* Added new test APIs allowing easy ways to create ledgers, apply
  transactions to them, close and advance them.

* Moved Ledger tests from Ledger.cpp to Ledger.test.cpp.

* Changed several TransactionEngine log priorities from lsINFO to lsDEBUG to
  reduce unnecessary verbosity in the log messages while running these tests.

* Moved LedgerConsensus:applyTransactions from a private member function to a
  free function so that it could be accessed externally, and without having to
  reference a LedgerConsensus object.  This was done to facilitate the new
  testing API.
2014-12-29 11:21:19 -08:00
Yana
c62ccf4870 Update README.md (RIPD-601) 2014-12-29 11:21:19 -08:00
Vinnie Falco
ef34439a79 Set version to 0.26.5-rc1 2014-12-22 15:20:03 -08:00
Nik Bougalis
b328ec2462 Prevent passing of non-POD types to POD-only interfaces:
This tidies up the code that produces random numbers to conform
to programming best practices and reduce dependencies.

* Use std::random_device instead of platform-specific code
* Remove RandomNumbers class and use free functions instead
2014-12-22 15:19:48 -08:00
Vinnie Falco
60f27178b8 Levelization, improve structure of source files:
Source files are moved between modules, includes changed and added,
and some code rewritten, with the goal of reducing cross-module dependencies
and eliminating cycles in the dependency graph of classes.

* Remove RippleAddress dependency in CKey_test
* ByteOrder.h, Blob.h, and strHex.h are moved to basics/. This makes
  the basics/ module fully independent of other ripple sources.
* types/ is merged into protocol/. The protocol module now contains
  all primitive types specific to the Ripple protocol.
* Move ErrorCodes to protocol/
* Move base_uint to basics/
* Move Base58 to crypto/
* Remove dependence on Serializer in GenerateDeterministicKey
* Eliminate unity header json.h
* Remove obsolete unity headers
* Remove unnecessary includes
2014-12-22 10:23:49 -08:00
Vinnie Falco
e3fbb83ad0 Tidy up usage of std::begin, std::end 2014-12-19 11:55:43 -08:00
Nik Bougalis
28b70a7b9a Remove 'Proof of Work' code 2014-12-19 11:00:29 -08:00
Nicholas Dudfield
dcdc341d0f Add appveyor 2014-12-19 11:00:29 -08:00
Tom Ritchford
fce77c9372 Configuration for yielding RPC server. 2014-12-19 11:00:28 -08:00
Tom Ritchford
a360c481c2 Refactor out a version of lookupLedger returning Status. 2014-12-19 11:00:28 -08:00
Tom Ritchford
c72db5fa5f Refactor away RPCHandler::doRpcCommand 2014-12-19 11:00:28 -08:00
Tom Ritchford
fc9a23d6d4 Send output incrementally in ServerHandlerImp. 2014-12-19 11:00:27 -08:00
Tom Ritchford
167f4666e2 New generic Ledger RPC handler. 2014-12-19 11:00:27 -08:00
Tom Ritchford
1cbcc7be21 Allow the Ledger to generically output to both Json models. 2014-12-19 11:00:27 -08:00
Tom Ritchford
8053598069 Better interoperation between Json::Value and JsonObject.
* Generic functions to add entries to both object models.
* Add Json::Value into JsonObjects.
* Write Json::Value to string incrementally.
* Get rid of ripple::RPC::New namespace
2014-12-19 11:00:26 -08:00
Tom Ritchford
7cfac1a91a Wrap Output in a coroutine that periodically yields. 2014-12-19 11:00:26 -08:00
Tom Ritchford
192cdd028e Change Output to be a generic std::function. 2014-12-19 11:00:26 -08:00
Tom Ritchford
029c143922 Add a comment to ledger/Ledger.h. 2014-12-19 11:00:26 -08:00
Tom Ritchford
00298cc68c Simplify LedgerData.cpp. 2014-12-19 11:00:25 -08:00
Tom Ritchford
d9c7db51af Make three ErrorCode functions generic. 2014-12-19 11:00:25 -08:00
Vinnie Falco
f12b15d22b Fix logic in HTTP/S server:
These bugs do not affect production code since callers do not invoke
`write` multiple times, but these would become a problem in the future.

* Access to Peer::write_queue_ is synchronized correctly.
* Remove unsafe access to deleted container element.
2014-12-19 11:00:25 -08:00
Vinnie Falco
409b8bac00 Remove unused and obsolete Ripple identifiers and tidy up:
These identifiers were part of a failed set of classes to replace
the functionality combined into RippleAddress. They are not used
and therefore can be removed.

* Remove RippleAccountPrivateKey
* Remove RippleAccountPublicKey
* Remove RippleAccountID
* Remove RipplePrivateKey
* Remove RipplePublicKeyHash
* Remove RippleLedgerHash
* Remove unused withCheck argument
* Remove CryptoIdentifier
* Remove IdentifierStorage
* Remove IdentifierType
* Remove SimpleIdentifier
* Add missing include
2014-12-19 11:00:24 -08:00
Vinnie Falco
28b09bde4b Simplify RipplePublicKey:
This implements the bare minimum necessary to store a 33 byte public
key and use it in ordered containers. It is an efficient and well
defined alternative to RippleAddress when the caller only needs
a node public key.
2014-12-19 11:00:24 -08:00
Vinnie Falco
2f6af906f4 Validators work (RIPD-703):
This replaces the experimental validators module with foundational
code to implement a new system for tracking validators, validations and
the UNL. The code is turned off by default, in BeastConfig.h

* Remove obsolete public Manager interfaces
* Remove obsolete database methods
* Remove obsolete ChosenList concept
* Remove obsolete code
* Add missing includes
* Tidy up STValidation.h
* Move factory function to Validators::make_Manager
* Add Connection object for tracking STValidations
2014-12-19 11:00:23 -08:00
Vinnie Falco
628e3ac1eb Add waitable_executor 2014-12-18 10:26:55 -08:00
Josh Juran
fbf5785e35 Combine STTx::checkSign overloads:
Callers don't need to specify the signing key -- they're just retrieving
the key from the SerializedTransaction and then passing it back.

This simplifies Ed25519 implementation.
2014-12-12 20:14:02 -08:00
Nicholas Dudfield
eeea2b1ff8 Use ppa:afrank/boost 1.57 for Travis 2014-12-12 20:14:02 -08:00
Vinnie Falco
32062e439f Split peer connect logic to another class (RIPD-711):
All of the logic for establishing an outbound peer connection including
the initial HTTP handshake exchange is moved into a separate class. This
allows PeerImp to have a strong invariant: All PeerImp objects that exist
represent active peer connections that have already gone through the
handshake process.
2014-12-12 20:14:02 -08:00
Vinnie Falco
930a0beaf1 Add ZeroCopyOutputStream and tidy up 2014-12-12 20:14:02 -08:00
Nik Bougalis
4a49fefdd9 Various cleanups:
* Replace SYSTEM_NAME and other macros with C++ constructs
* Remove RIPPLE_ARRAYSIZE and use std::extent or ranged for loops
* Remove old-style, unused offer crossing unit test
* Make STAmount::saFromRate free and remove default argument
2014-12-12 20:14:02 -08:00
Nik Bougalis
8e792855e0 Do not use path if path expansion fails 2014-12-10 16:55:06 -08:00
Tom Ritchford
69f5c6987a Whitespace: clean WebSockets to 80 columns. 2014-12-10 16:55:06 -08:00
Nik Bougalis
85fc9e4ecf Revert e4c9822d78 "Enable processor-specific optimizations when available:" 2014-12-08 14:54:03 -08:00
Mark Travis
d5c3f0c9cf Stability bugfixes for online delete SHAMapStore:
The correct ledger age is necessary for checking health
status, and the previous behavior caused the online deletion process to
abort if the process took too long.

The tuning parameter added and the parameter whose default was modified both
minimize impact of SQL DELETE operations by decreasing the default batch size
for deletes and for increasing the backoff period between deletion batches.
These parameters decrease contention for the SQLite and I/O with the trade-off
of longer processing time for online delete. Online-delete is not a
time-critical function, so a little slowness in wall-clock time is not harmful.
2014-12-08 14:54:03 -08:00
JoelKatz
a48120e675 Fix incorrect source issuer for XRP source 2014-12-08 14:54:03 -08:00
Nik Bougalis
36f8e4f2ad Improve hex conversion & parsing routines 2014-12-08 14:54:03 -08:00
David Schwartz
1084a39a45 Improve the humanAccountID cache (RIPD-693)
Profiling indicated some performance issues coming from the
cache of 160-bit account IDs to base58 format. This replaces
the single cache with two caches and rotates out old
entries.
2014-12-08 14:54:03 -08:00
Tom Ritchford
86df482842 Make sure that handlers always return Json::objectValue. 2014-12-01 17:16:24 -05:00
Tom Ritchford
b0d47ebcc6 Use better base64 handling in ServerHandlerImp. 2014-12-01 17:15:23 -05:00
Tom Ritchford
fffdf1dfba Make beast::detail::chunk_encoded_buffers::to_hex() static 2014-12-01 11:12:59 -05:00
Tom Ritchford
3273ed2616 Remove unused BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES. 2014-12-01 10:56:03 -05:00
Vinnie Falco
aa7b0a31b0 Refactor protocol message parsing:
This replaces the stateful class parser with a stateless free function.
The protocol buffer message is parsed using a ZeroCopyInputStream.

* Invoke method is now a free function.
* Protocol handler doesn't need to derive from an abstract interface
* Only up to one message is processed at a time by the invoker.
* Remove error_code return from the handler's message processing functions.
* Add ZeroCopyInputStream implementation that wraps a BufferSequence.
* Free function parses up to one protocol message and calls the handler.
* Message type and size can be calculated from an iterator
  range or a buffer sequence.
2014-11-26 12:23:21 -08:00
Vinnie Falco
fb0d44d403 Use cluster state in Slot instead of PeerImp 2014-11-26 12:23:10 -08:00
Vinnie Falco
cd8ec89cbb Use injections from OverlayImpl in PeerImp 2014-11-26 12:23:02 -08:00
Vinnie Falco
252f271dc5 Fixes to beast::asio::streambuf:
* Fix to_string conversion
* Fix assert on debug invariant checks
* Fix the treatment of the output position when the entire output is committed.
* Add unit test
2014-11-26 12:22:55 -08:00
Vinnie Falco
62d400c3a9 Move the call to cancel_timer to the right place 2014-11-26 12:22:46 -08:00
Scott Schurr
f9aa3e0da5 Add more unit tests to rpc/impl/TransactionSign (RIPD-480):
By adding a mock it is possible to test the transactionSign
function without interacting with the ledger.  This is the
smallest change I could come up with that allows transactionSign
to be unit tested.

The unit tests are white boxed.  Each test case is a result
of examining the code and identifying behavior associated with
different JSON fields.  That means the tests are not based on
requirements, they are based on observed behavior.
2014-11-26 12:07:44 -08:00
Vinnie Falco
685fe5b0fb Don't call std::exit on clean exit 2014-11-25 19:19:56 -08:00
Vinnie Falco
5180e71a0d Remove unused chrono::time_point stream conversions 2014-11-25 19:19:56 -08:00
Vinnie Falco
55637f7508 Template abstract_clock on Clock:
The abstract_clock is now templated on a type meeting the requirements of
the Clock concept. It inherits the nested types of the Clock on which it
is based. This resolves a problem with the original design which broke the
type-safety of time_point from different abstract clocks.
2014-11-25 19:19:56 -08:00
Nicholas Dudfield
7d72dfe0be Updated freeze tests:
* Always run freeze tests (and  enforcement tests)
* book_offers filtering tests are broken
2014-11-25 11:46:34 -08:00
Mark Travis
02529a0fc2 SHAMapStore Online Delete (RIPD-415):
Makes rippled configurable to support deletion of all data in its key-value
store (nodestore) and ledger and transaction SQLite databases based on
validated ledger sequence numbers. All records from a specified ledger
and forward shall remain available in the key-value store and SQLite, and
all data prior to that specific ledger may be deleted.

Additionally, the administrator may require that an RPC command be
executed to enable deletion. This is to align data deletion with local
policy.
2014-11-25 11:44:02 -08:00
JoelKatz
b44974677e Cleanup some stray formatting left in logs 2014-11-21 17:13:13 -08:00
Vinnie Falco
d4fd5e4fce HTTP Handshaking for Peers on Universal Port (RIPD-446):
This introduces a considerable change in the way that peers handshake. Instead
of sending the TMHello protocol message, the peer making the connection (client
role) sends an HTTP Upgrade request along with some special headers. The peer
acting in the server role sends an HTTP response completing the upgrade and
transition to RTXP (Ripple Transaction Protocol, a.k.a. peer protocol). If the
server has no available slots, then it sends a 503 Service Unavailable HTTP
response with a JSON content-body containing IP addresses of other servers to
try. The information that was previously contained in the TMHello message is
now communicated in the HTTP request and HTTP response including the secure
cookie to prevent man in the middle attacks. This information is documented
in the overlay README.md file.

To prevent disruption on the network, the handshake feature is rolled out in
two parts. This is part 1, where new servents acting in the client role will
send the old style TMHello handshake, and new servents acting in the server
role can automatically detect and accept both the old style TMHello handshake,
or the HTTP request accordingly. This detection happens in the Server module,
which supports the universal port. An experimental .cfg setting allows clients
to instead send HTTP handshakes when establishing peer connections. When this
code has reached a significant fraction of the network, these clients will be
able to establish a connection to the Ripple network using HTTP handshakes.

These changes clean up the handling of the socket for peers. It fixes a long
standing bug in the graceful close sequence, where remaining data such as the
IP addresses of other servers to try, did not get sent. Redundant state
variables for the peer are removed and the treatment of completion handlers is
streamlined. The treatment of SSL short reads and secure shutdown is also fixed.

Logging for the peers in the overlay module are divided into two partitions:
"Peer" and "Protocol". The Peer partition records activity taking place on the
socket while the Protocol partition informs about RTXP specific actions such as
transaction relay, fetch packs, and consensus rounds. The severity on the log
partitions may be adjusted independently to diagnose problems. Every log
message for peers is prefixed with a small, unique integer id in brackets,
to accurately associate log messages with peers.

HTTP handshaking is the first step in implementing the Hub and Spoke feature,
which transforms the network from a homogeneous network where all peers are
the same, into a structured network where peers with above average capabilities
in their ability to process ledgers and transactions self-assemble to form a
backbone of high powered machines which in turn serve a much larger number of
'leaves' with lower capacities with a goal to improve the number of
transactions that may be retired over time.
2014-11-21 16:47:12 -08:00
Vinnie Falco
30123eaa4a Add WrappedSink:
This class puts a configured string prefix in front of
each line of Journal output.
2014-11-21 16:46:57 -08:00
Nik Bougalis
454ec97d51 Replace custom exceptions with std::runtime_error 2014-11-21 13:15:41 -08:00
Vinnie Falco
c2ac331e78 Fix unit_test suite matching with full names 2014-11-21 12:59:32 -08:00
Nik Bougalis
be4a35af11 Clarify SetAccount logic and clean up existing code 2014-11-21 12:59:32 -08:00
Tom Ritchford
445b29ad0d Fix RPC handlers to use the results of lookupLedger. 2014-11-21 12:59:32 -08:00
Vinnie Falco
64d0f7fffd Fix DecayingSample treatment of the window 2014-11-21 12:59:32 -08:00
Nik Bougalis
baf0d09455 Simplify the Beast fatal error reporting framework:
* Reduce interface to a single function which reports error details
* Remove unused functions
2014-11-21 12:59:32 -08:00
Vinnie Falco
08a81a0ab9 Tidy up the structure of sources in protocol/:
Split out and rename STValidation
Split out and rename STBlob
Split out and rename STAccount
Split out STPathSet
Split STVector256 and move UintTypes to protocol/
Rename to STBase
Rename to STLedgerEntry
Rename to SOTemplate
Rename to STTx
Remove obsolete AgedHistory
Remove types.h and add missing includes
Remove unnecessary includes in app.h
Remove unnecessary includes in app.h
Remove include app.h from app1.cpp
2014-11-20 20:15:29 -08:00
Nik Bougalis
31110c7fd9 Cleanup ripple::Ledger:
* Convert static member functions to free functions
* Adopt consistent naming convention
* De-inline code
2014-11-20 20:15:29 -08:00
Vinnie Falco
0e1dd92d9b Fix case where slot==nullptr in Overlay:
This changes the Overlay to correctly handle the case when nullptr is
returned by PeerFinder new_inbound_slot on a detected self-connection.
2014-11-20 20:15:29 -08:00
Vinnie Falco
a3204a4df7 Add http::chunk_encode:
This transforms a ConstBufferSequence into a new ConstBufferSequence whose
data is encoded according to the Content transfer encoding rules of RFC2616.
The implementation does not copy any memory.
2014-11-20 20:15:29 -08:00
Donovan Hide
2288ab48b9 Use asio signal handling in Application (RIPD-140):
* Use signal_set as cross platform way of handling SIGINT
* Remove polling on main thread for shutdown.
* Add extra logging for received signal.
* Clean up exit handling on error in setup routines.
* Reuse isStopped() from Stoppable for status (could be isStopping() instead).
* Ctrl-C should now work for standalone mode as well on Windows.

Also small fixes to Resolver:
* Add Resolver prefix to logging.
* Fix AsyncObject::removeReference() logic.
* Fix work remaining logic.
2014-11-20 20:15:29 -08:00
mDuo13
670401884c Improve the human-readable description of the tesSUCCESS code:
Transactions that return tesSUCCESS have only been accepted and
propagated on the Ripple network and should not be considered
final until they have been included in a validated ledger.
2014-11-20 20:14:04 -08:00
Yana
37181c341e Changed doc/rippled-example.cfg to specify default for ssl_verify 2014-11-14 11:19:42 -08:00
wltsmrz
be7e677448 Update integration tests for changes to ripple-lib account request API:
Account requests expect an object as first argument
2014-11-14 11:10:12 -08:00
Josh Juran
b2eeb49a45 Clean up CKey and RippleAddress (RIPD-672)
* Remove CKey dependency on RippleAddress
* Create RAII ec_key wrapper that hides EC_KEY and other OpenSSL details
* Move CKey member logic into free functions
* Delete CKey class
* Rename units that are no longer CKey-related
* Delete code that was unused
2014-11-14 11:10:12 -08:00
Vinnie Falco
9aa040d917 Accept generic arguments in ci_equal 2014-11-14 11:10:11 -08:00
Vinnie Falco
c2043a223b Tidy up split_commas function and use it in Server
Conflicts:
	src/ripple/server/impl/ServerHandlerImp.cpp
2014-11-14 11:10:11 -08:00
Vinnie Falco
f24e859f17 Construct Server after Overlay and WSDoors:
When the ServerHandler is constructed before the Overlay, an incoming
connection received after the server's listening ports have been opened
but before the Overlay object has been created causes a crash.
2014-11-14 11:10:11 -08:00
Vinnie Falco
737b33f9d1 Merge branch 'release' into develop 2014-11-14 10:56:45 -08:00
David Schwartz
00791d2151 Set version to 0.26.4-sp3 2014-11-11 16:33:52 -08:00
David Schwartz
b141598f9b Fix bugs in pathfinding with XRP as the source currency 2014-11-11 16:27:39 -08:00
Tom Ritchford
d1618d79b0 Fix pathfinding with multiple issuers for one currency (RIPD-618).
* Allow pathfinding requests where the starting currency may have
  multiple issuers.

* Cache paths over all issuers to avoid repeating work.

* Clear the ledger checkpoint in one retry case.

* Add an additional node at the front of paths when the starting issuer
  is not the source account.
2014-11-11 16:27:03 -08:00
Tom Ritchford
00c84dfe5c Clean up Pathfinder.
* Restrict to 80-columns and other style cleanups.
* Make pathfinding a free function and hide the class Pathfinder.
* Split off unrelated utility functions into separate files.
2014-11-11 16:26:38 -08:00
Vinnie Falco
95f31b98a8 Set version to 0.26.4-sp2 2014-11-11 14:22:37 -08:00
Miguel Portilla
10d74ed100 Fix account_lines, account_offers and book_offers result (RIPD-682):
The RPC account_lines and account_offers commands respond with the correct ledger info. account_offers, account_lines and book_offers allow admins unlimited size on the limit param. Specifying a negative value on limit clamps to the minimum value allowed. Incorrect types for limit are correctly reported in the result.
2014-11-11 14:21:49 -08:00
Vinnie Falco
8a7f612d5b Revert pathfinding changes:
* 5e7c527 Revert "Fix account_lines, account_offers and book_offers result (RIPD-682):"
* b3417ca Revert "Fix pathfinding with multiple issuers for one currency (RIPD-618)."
* 00db7f5 Revert "Clean up Pathfinder."
2014-11-11 14:21:40 -08:00
Tom Ritchford
0829ee9234 Add missing header needed for boost 1.57 compatibility. 2014-11-10 23:23:53 -05:00
Nik Bougalis
b22e33444b Make Stoppable unit tests manual 2014-11-10 23:23:53 -05:00
David Schwartz
d115a12cbe Remove dead TxQueue code 2014-11-10 23:23:53 -05:00
Nik Bougalis
b7b744de94 Remove sole use of beast::MurmurHash 2014-11-10 15:00:20 -08:00
Nik Bougalis
68e46e406a Remove MurmurHash from Beast 2014-11-10 14:00:54 -08:00
Miguel Portilla
a46ae4efec Set version to 0.26.4-sp1 2014-11-10 16:25:45 -05:00
Miguel Portilla
62777a794e Fix account_lines, account_offers and book_offers result (RIPD-682):
The RPC account_lines and account_offers commands respond with the correct ledger info. account_offers, account_lines and book_offers allow admins unlimited size on the limit param. Specifying a negative value on limit clamps to the minimum value allowed. Incorrect types for limit are correctly reported in the result.
2014-11-10 16:25:14 -05:00
Tom Ritchford
329a969761 Remove unused RPCServer. 2014-11-10 12:53:21 -08:00
Vinnie Falco
30170bc394 Add short_read manual unit test:
This manual unit test explores the outcomes of shutting down
SSL stream connections at various point during a session.
2014-11-10 12:52:57 -08:00
Vinnie Falco
f193302e15 Add WrappedSink 2014-11-10 12:52:57 -08:00
Vinnie Falco
7c4870d641 Add operator<< for basic_streambuf 2014-11-10 12:52:43 -08:00
Vinnie Falco
8b84a76d5d Make ci_equal a function 2014-11-10 12:52:42 -08:00
Vinnie Falco
a4cd761372 Add rfc2616::parse_csv 2014-11-10 12:52:42 -08:00
Miguel Portilla
63d2cfd6ba Fix account_lines, account_offers and book_offers result (RIPD-682):
The RPC account_lines and account_offers commands respond with the correct
ledger info. account_offers, account_lines and book_offers allow admins
unlimited size on the limit param. Specifying a negative value on limit clamps
to the minimum value allowed. Incorrect types for limit are correctly reported
in the result.
2014-11-10 12:46:36 -08:00
Tom Ritchford
bb44bdd047 Fix pathfinding with multiple issuers for one currency (RIPD-618).
* Allow pathfinding requests where the starting currency may have
  multiple issuers.

* Cache paths over all issuers to avoid repeating work.

* Clear the ledger checkpoint in one retry case.

* Add an additional node at the front of paths when the starting issuer
  is not the source account.
2014-11-10 12:07:57 -05:00
Tom Ritchford
6904e66384 Clean up Pathfinder.
* Restrict to 80-columns and other style cleanups.
* Make pathfinding a free function and hide the class Pathfinder.
* Split off unrelated utility functions into separate files.
2014-11-10 12:06:49 -05:00
Vinnie Falco
fbffe2367e Fix weak_fn unit test. 2014-11-09 20:27:05 -08:00
Vinnie Falco
e442a2846d Overlay improvements and bug fixes:
PeerImp::detach had a default argument graceful=true which did not
correctly close the socket and cause the Overlay to often hang on exit.
The logging for Overlay and Peers has been reworked. All the socket activity
is logged to Peers while protocol activity goes to Protocol. Every log line
is prefixed by a small integer ID unique to the connection.
* Removed graceful PeerImp::detach option
* Peer and Protocol log message handle respective types of logging
* Log messages prefixed with peer unique integer
* Prevent call to timer ancel from throwing an exception
2014-11-08 14:39:46 -08:00
Vinnie Falco
f6985586ea Better logging when opening Server ports. 2014-11-08 14:36:45 -08:00
Vinnie Falco
2bae5b0959 Throw if rippled.cfg is missing a [server] section 2014-11-08 14:36:45 -08:00
Vinnie Falco
1e58809fcc Remove obsolete get_pointer 2014-11-08 14:36:44 -08:00
Vinnie Falco
6b1d213cc2 Add weak_fn 2014-11-08 14:36:44 -08:00
David Schwartz
42bec13a83 Add missing include needed for std::bad_cast in LexicalCast.h 2014-11-07 15:23:43 -08:00
Vinnie Falco
4415a179b3 Update freeze test for moved TxFlags.h 2014-11-07 14:12:43 -08:00
Vinnie Falco
5d42604efd Refactor the structure of source files:
* New src/ripple/crypto and src/ripple/protocol directories
* Merged src/ripple/common into src/ripple/basics
* Move resource/api files up a level
* Add headers for "include what you use"
* Normalized include guards
* Renamed to JsonFields.h
* Remove obsolete files
* Remove net.h unity header
* Remove resource.h unity header
* Removed some deprecated unity includes
2014-11-07 13:40:43 -08:00
Vinnie Falco
b134b7d3f6 Add missing includes. 2014-11-07 12:24:02 -08:00
Vinnie Falco
788219fe05 Adjust SSL context generation for Server:
The creation of self-signed certificates slows down the command
line client when launched repeatedly during unit test.
* Contexts are no longer generated for the command line client
* A port with no secure protocols generates an empty context
2014-11-07 06:13:56 -08:00
Tom Ritchford
9a7f66cfe9 Fix compilation errors in RPC/RipplePathFind.cpp 2014-11-06 21:58:13 -05:00
Tom Ritchford
daa4d16e61 Remove unused isXRP(Issue) function. 2014-11-06 20:17:13 -05:00
Tom Ritchford
cf05f87795 Fix pathfinding with multiple issuers for one currency (RIPD-618).
* Allow pathfinding requests where the starting currency may have
  multiple issuers.

* Cache paths over all issuers to avoid repeating work.

* Clear the ledger checkpoint in one retry case.

* Add an additional node at the front of paths when the starting issuer
  is not the source account.
2014-11-06 20:14:01 -05:00
Tom Ritchford
c2f2f83b7c Clean up Pathfinder.
* Restrict to 80-columns and other style cleanups.
* Make pathfinding a free function and hide the class Pathfinder.
* Split off unrelated utility functions into separate files.

Conflicts:
	src/ripple/rpc/handlers/RipplePathFind.cpp
2014-11-06 16:58:10 -08:00
Tom Ritchford
b30b2a523f Fix public member names of RPC::Context.
Conflicts:
	src/ripple/rpc/handlers/AccountTx.cpp
	src/ripple/rpc/handlers/AccountTxOld.cpp
	src/ripple/rpc/handlers/Ledger.cpp
	src/ripple/rpc/handlers/LedgerData.cpp
	src/ripple/rpc/handlers/RipplePathFind.cpp
	src/ripple/rpc/handlers/ServerInfo.cpp
	src/ripple/rpc/handlers/ServerState.cpp
	src/ripple/rpc/handlers/Submit.cpp
	src/ripple/rpc/handlers/Subscribe.cpp
	src/ripple/rpc/handlers/TxHistory.cpp
	src/ripple/rpc/handlers/Unsubscribe.cpp
	src/ripple/rpc/impl/Context.h
2014-11-06 16:55:20 -08:00
Nicholas Dudfield
150a3810a8 Update npm test rippled.cfg to use [server]:
The test now generates a configuration file with the new
configuration sections define by the Universal Port feature.
2014-11-06 16:10:00 -08:00
Vinnie Falco
ac0eaa912b Universal Port (RIPD-160):
This changes the behavior and configuration specification of the listening
ports that rippled uses to accept incoming connections for the supported
protocols: peer (Peer Protocol), http (JSON-RPC over HTTP), https (JSON-RPC)
over HTTPS, ws (Websockets Clients), and wss (Secure Websockets Clients).
Each listening port is now capable of handshaking in multiple protocols
specified in the configuration file (subject to some restrictions). Each
port can be configured to provide its own SSL certificate, or to use a
self-signed certificate. Ports can be configured to share settings, this
allows multiple ports to use the same certificate or values. The list of
ports is dynamic, administrators can open as few or as many ports as they
like. Authentication settings such as user/password or admin user/admin
password (for administrative commands on RPC or Websockets interfaces) can
also be specified per-port.

As the configuration file has changed significantly, administrators will
need to update their ripple.cfg files and carefully review the documentation
and new settings.

Changes:

* rippled-example.cfg updated with documentation and new example settings:
  All obsolete websocket, rpc, and peer configuration sections have been
  removed, the documentation updated, and a new documented set of example
  settings added.

* HTTP::Writer abstraction for sending HTTP server requests and responses
* HTTP::Handler handler improvements to support Universal Port
* HTTP::Handler handler supports legacy Peer protocol handshakes
* HTTP::Port uses shared_ptr<boost::asio::ssl::context>
* HTTP::PeerImp and Overlay use ssl_bundle to support Universal Port
* New JsonWriter to stream message and body through HTTP server
* ServerHandler refactored to support Universal Port and legacy peers
* ServerHandler Setup struct updated for Universal Port
* Refactor some PeerFinder members
* WSDoor and Websocket code stores and uses the HTTP::Port configuration
* Websocket autotls class receives the current secure/plain SSL setting
* Remove PeerDoor and obsolete Overlay peer accept code
* Remove obsolete RPCDoor and synchronous RPC handling code
* Remove other obsolete classes, types, and files
* Command line tool uses ServerHandler Setup for port and authorization info
* Fix handling of admin_user, admin_password in administrative commands
* Fix adminRole to check credentials for Universal Port
* Updated Overlay README.md

* Overlay sends IP:port redirects on HTTP Upgrade peer connection requests:
  Incoming peers who handshake using the HTTP Upgrade mechanism don't get
  a slot, and always get HTTP Status 503 redirect containing a JSON
  content-body with a set of alternate IP and port addresses to try, learned
  from PeerFinder. A future commit related to the Hub and Spoke feature will
  change the response to grant the peer a slot when there are peer slots
  available.

* HTTP responses to outgoing Peer connect requests parse redirect IP:ports:
  When the [overlay] configuration section (which is experimental) has
  http_handshake = 1, HTTP redirect responses will have the JSON content-body
  parsed to obtain the redirect IP:port addresses.

* Use a single io_service for HTTP::Server and Overlay:
  This is necessary to allow HTTP::Server to pass sockets to and from Overlay
  and eventually Websockets. Unfortunately Websockets is not so easily changed
  to use an externally provided io_service. This will be addressed in a future
  commit, and is one step necessary ease the restriction on ports configured
  to offer Websocket protocols in the .cfg file.
2014-11-06 16:10:00 -08:00
Vinnie Falco
05a04aa801 Set version to 0.26.4 2014-11-03 16:53:37 -08:00
Vinnie Falco
e37d4043f6 Add missing includes to make headers compile separately 2014-11-03 16:40:57 -08:00
Vinnie Falco
d073425b44 Improved beast::http::message:
* Add headers::erase
* Set http::message version with std::pair
* Use std::pair for headers::value_type
2014-11-03 16:40:57 -08:00
Nicholas Dudfield
825b18cf71 Add bin/stop-test.js shutdown testing script:
This script launches rippled repeatedly and then issues a stop command
after a variable amount of time. This is to test the shutdown of the
application and catch errors.
2014-11-03 16:31:21 -08:00
Vinnie Falco
549ad3204f Fix race conditions closing HTTP I/O objects:
This fixes a case where stop can sometimes skip calling close on some
I/O objects or crash in a rare circumstance where a connection is in the
process of being torn down at the exact time the server is stopped. When
the acceptor receives errors, it logs the error and continues listening
instead of stopping.
2014-11-03 14:11:06 -08:00
Vinnie Falco
35f9499b67 Fix Overlay stop on exit:
The stop sequence for Overlay had a race condition where autoconnect could
be called after close_all, resulting in a hang on exit. This resolves the
problem by putting the close and timer operations on a strand:
* Rename some Overlay members
* Put close on strand and tidy up members
* Use completion handler instead of coroutine for timer
* Use App io_service in PeerFinder
2014-11-03 14:11:05 -08:00
Vinnie Falco
db82c35c17 Remove spurious assert in ResolverAsioImpl 2014-11-03 14:11:05 -08:00
Vinnie Falco
73c74f753c Change to the Application io_service:
* Simplified the implementation and removed class IoServicePool
* The io_service outlives the components of the Application
2014-11-03 14:11:05 -08:00
JoelKatz
a38fb2a5dc Clear the acquiring ledger when shutting down NetworkOPs:
This solves a circular destruction problem on exit.
2014-11-03 14:11:04 -08:00
Donovan Hide
38e99e01f9 Improve nodestore benchmarking:
* Use more succinct while loops on NodeFactory.
* Better formatting of multiple test results.
* Updated benchmarks.
* Use simpler and faster RNG to generate test data.
2014-11-02 07:16:08 -08:00
Donovan Hide
a1f46e84b8 Add new RocksDBQuickFactory for benchmarking:
This new factory is intended for benchmarking against the existing RocksDBFactory and has the following differences.
* Does not use BatchWriter
* Disables WAL for writes to memtable
* Uses a hash index in blocks
* Uses RocksDB OptimizeFor… functions
See Benchmarks.md for further discussion of some of the issues raised by investigation of RocksDB performance.
2014-11-01 07:12:09 -07:00
Donovan Hide
6540804571 Add repeatable NodeStore timing benchmark:
The timing test is changed to overcome possible file buffer cache effects by creating different read access patterns. The unittest-arg command line arguments allow running the benchmarks against any of the available backends and altering the parameters passed in the same format as rippled.cfg. The num_objects parameter permits variation of the number of key/values inserted. The data is random but matches reasonably well the values that rippled might generate.
2014-11-01 07:12:08 -07:00
Howard Hinnant
ffe6707595 Refactor Stoppable:
The Stoppable interface aids in the enforcement of invariants needed to
successful start and stop a multi-threaded application composed of classes
that depend on each other in complex ways.
* Test written to confirm the current behavior.
* Comments updated to reflect the current behavior.
* Public API reduced to what is currently in use.
* Protected data members made private.
* volatile bool members changed to std::atomic<bool>.
* std::atomic<int> members changed to std::atomic<bool>.
* Name storage uses std::string
2014-10-31 21:29:16 -07:00
Tom Ritchford
9b21740c9f Delete temporary directories at the end of tests (RIPD-460). 2014-10-31 21:21:54 -07:00
Tom Ritchford
bd12e2ab95 New class TempDirectory in UnitTestUtilities. 2014-10-31 21:21:54 -07:00
Donovan Hide
bffb5ef8b4 Avoid zero initialization of Blob:
This seemed to improve the performance of the copy, although there did seem to be some byte by byte copying still present. Further investigation recommended.
2014-10-31 20:12:39 -07:00
Donovan Hide
e4c9822d78 Enable processor-specific optimizations when available:
The SConstruct is modified to enable processor specific optimizations on clang and gcc toolchains. This improves the performance of RocksDB's CRC function. It might also enable other used libraries that are in the codebase now or in the future to apply cpu-specific optimisations. The mtune option ensures that a binary compiled on one machine will function on another,
2014-10-31 20:12:39 -07:00
Vinnie Falco
73187d8832 Remove obsolete multitls and proxy websocket features 2014-10-31 15:15:40 -07:00
Vinnie Falco
8101154d5e Remove obsolete websocket PROXY port 2014-10-31 15:15:40 -07:00
Vinnie Falco
c02937fd6f Remove obsolete sections from rippled-example.cfg:
* peer_port_proxy is obsolete since the MultiSocket was removed.
* peer_ssl_cipher_list has no effect, SSL ciphers are hard coded for security.
2014-10-31 15:15:40 -07:00
Vinnie Falco
3430be4075 Add PeerFinder onRedirects function 2014-10-31 13:27:55 -07:00
Vinnie Falco
3f2b6f771f Add streambuf to_string function 2014-10-31 13:27:38 -07:00
Vinnie Falco
6e39b49cc2 Add Json::stream to write Value to a Streambuf 2014-10-31 13:27:33 -07:00
Vinnie Falco
71c34ed4e0 Remove unused ErrorReply function 2014-10-31 13:25:54 -07:00
Vinnie Falco
477178675c Fix parseIniFile for duplicate sections 2014-10-31 13:25:30 -07:00
Vinnie Falco
dbdf68b248 Refactor HTTP::Server to support Universal Port:
These changes are necessary to support the Universal port feature. Synopsis:

* Persist HTTP peer io_service::work lifetime:
This simplification eliminates any potential for bugs caused by incorrect
lifetime management of the io_service::work object.

* Restructure Door to prevent data races, and handle clean exit:
The Server, Door, Door::detector, and Peer objects work together to
correctly implement graceful stop and destructors that block until
all child objects have been destroyed.

Cleanups:
* De-pimpl HTTP::Server
* Rename ServerImpl data members
* Tidy up HTTP::Port interface
2014-10-30 16:02:19 -07:00
Vinnie Falco
2fd139b307 Refactor Overlay and add [overlay] config section (experimental):
These changes prepare Overlay for the Universal Port and Hub and Spoke
features.

* Add [overlay configuration section:
The [overlay] section uses the new BasicConfig interface that
supports key-value pairs in the section. Some exposition is added to the
example cfg file. The new settings for overlay are related to the Hub and
Spoke feature which is currently in development. Production servers should
not set these configuration options, they are clearly marked experimental
in the example cfg file.

Other changes:
* Use _MSC_VER to detect Visual Studio
* Use ssl_bundle in Overlay::Peer
* Use shared_ptr to SSL context in Overlay:
* Removed undocumented PEER_SSL_CIPHER_LIST configuration setting
* Add Section::name: The Section object now stores its name for better diagnostic messages.
2014-10-30 13:55:01 -07:00
Vinnie Falco
a6c2657062 Add shared_ptr<boost::asio::ssl::context> to ssl_bundle:
This gives the ssl_bundle shared ownership of the underlying ssl context
so that ownership of the bundle may be transferred to other classes without
introduce lifetime issues.
2014-10-30 13:55:00 -07:00
Vinnie Falco
78a0bc0e2c Make streambuf buffers_type iterators default constructible 2014-10-30 13:55:00 -07:00
Edward Hennis
d7116d6867 Enable std::array overloads for boost::asio on clang:
* Remove Boost config option from beast config.
* Define from compiler, or let Boost figure out itself.
2014-10-30 13:55:00 -07:00
Josh Juran
edc15b9fa2 Use a self-signed certificate for peers (RIPD-108):
Generate a new RSA key pair and a self-signed X.509v3 certificate to use
with SSL connections to rippled peers.  New credentials are created each
startup.
2014-10-30 13:54:49 -07:00
Josh Juran
93d4b73b2f RippleSSLContext: Add openssl wrappers 2014-10-30 10:52:37 -07:00
Vinnie Falco
8e3849e591 Create Ripple SSL contexts using std::make_shared. 2014-10-30 10:52:36 -07:00
Vinnie Falco
acaa1098f7 Separate beast::http::body from beast::http::message (RIPD-660):
This changes the http::message object to no longer contain a body. It modifies
the parser to store the body in a separate object, or to pass the body data
to a functor. This allows the body to be stored in more flexible ways. For
example, in HTTP responses the body can be generated procedurally instead
of being required to exist entirely in memory at once.
2014-10-29 19:23:53 -07:00
Vinnie Falco
c1a5e88752 Use beast::asio::streambuf in Overlay 2014-10-29 19:23:53 -07:00
Vinnie Falco
74b99014d2 Add beast::asio::basic_streambuf (RIPD-661):
This is class whose interface is identical to the boost::asio::basic_streambuf,
and uses an implementation that stores the data in multiple discontiguous
linear buffers, expanding and shrinking as needed.
2014-10-29 19:23:53 -07:00
Tom Ritchford
9cba944d21 Add Json::to_string:
This allows the declaration for FastWriter to be hidden and makes
conversion of Json::Value objects to strings a little less clunky.
2014-10-29 19:23:52 -07:00
Tom Ritchford
8c1c2f5d05 Eliminate a copy of the string returned by FastWriter 2014-10-29 19:22:44 -07:00
Tom Ritchford
bf0fa8c562 Add 'sample' npm test:
test/sample-test.js is the smallest possible npm test.
2014-10-28 10:59:59 -07:00
Donovan Hide
3e1fc9ba6c Update unit testing command line parser parameters:
A string passed by the '--unittest-arg' command line parameter is passed to
suites when unit tests run and can be used to customize test behavior.
* Add '--unittest-arg' command line argument
* Remove obsolete '--unittest-format' command line argument
2014-10-28 10:55:44 -07:00
Vinnie Falco
4ceba603e4 Improvements to beast::unit_test framework:
* Some runner member functions are now thread-safe.
* De-inline and tidy up declarations and definitions.
* arg() interface allows command lines to be passed to suites.
2014-10-28 10:41:10 -07:00
Vinnie Falco
6591c21ace Set version to 0.26.4-rc4 2014-10-27 11:49:39 -07:00
Vinnie Falco
e8d03c7b9b Update rocksdb unity file 2014-10-27 11:48:21 -07:00
Vinnie Falco
6fbce4c2f7 Update src/rocksdb2 to rocksdb-3.5.1:
Merge commit 'c168d54495d7d7b84639514f6443ad99b89ce996' into develop
2014-10-27 11:37:01 -07:00
Vinnie Falco
c168d54495 Squashed 'src/rocksdb2/' changes from 25888ae..1fdd726
1fdd726 Hotfix RocksDB 3.5
d67500a Add `make install` to Makefile in 3.5.fb.
4cb631a update HISTORY.md
cfd0946 comments about the BlockBasedTableOptions migration in Options
REVERT: 25888ae Merge pull request #329 from fyrz/master
REVERT: 89833e5 Fixed signed-unsigned comparison warning in db_test.cc
REVERT: fcac705 Fixed compile warning on Mac caused by unused variables.
REVERT: b3343fd resolution for java build problem introduced by 5ec53f3edf62bec1b690ce12fb21a6c52203f3c8
REVERT: 187b299 ForwardIterator: update prev_key_ only if prefix hasn't changed
REVERT: 5ec53f3 make compaction related options changeable
REVERT: d122e7b Update INSTALL.md
REVERT: 986dad0 Merge pull request #324 from dalgaaf/wip-da-SCA-20140930
REVERT: 8ee75dc db/memtable.cc: remove unused variable merge_result
REVERT: 0fd8bbc db/db_impl.cc: reduce scope of prefix_initialized
REVERT: 676ff7b compaction_picker.cc: remove check for >=0 for unsigned
REVERT: e55aea5 document_db.cc: fix assert
REVERT: d517c83 in_table_factory.cc: use correct format specifier
REVERT: b140375 ttl/ttl_test.cc: prefer prefix ++operator for non-primitive types
REVERT: 43c789c spatialdb/spatial_db.cc: use !empty() instead of 'size() > 0'
REVERT: 0de452e document_db.cc: pass const parameter by reference
REVERT: 4cc8643 util/ldb_cmd.cc: prefer prefix ++operator for non-primitive types
REVERT: af8c2b2 util/signal_test.cc: suppress intentional null pointer deref
REVERT: 33580fa db/db_impl.cc: fix object handling, remove double lines
REVERT: 873f135 db_ttl_impl.h: pass func parameter by reference
REVERT: 8558457 ldb_cmd_execute_result.h: perform init in initialization list
REVERT: 063471b table/table_test.cc: pass func parameter by reference
REVERT: 93548ce table/cuckoo_table_reader.cc: pass func parameter by ref
REVERT: b8b7117 db/version_set.cc: use !empty() instead of 'size() > 0'
REVERT: 8ce050b table/bloom_block.*: pass func parameter by reference
REVERT: 53910dd db_test.cc: pass parameter by reference
REVERT: 68ca534 corruption_test.cc: pass parameter by reference
REVERT: 7506198 cuckoo_table_db_test.cc: add flush after delete
REVERT: 1f96330 Print MB per second compaction throughput separately for reads and writes
REVERT: ffe3d49 Add an instruction about SSE in INSTALL.md
REVERT: ee1f3cc Package generation for Ubuntu and CentOS
REVERT: f0f7955 Fixing comile errors on OS X
REVERT: 99fb613 remove 2 space linter
REVERT: b2d64a4 Fix linters, second try
REVERT: 747523d Print per column family metrics in db_bench
REVERT: 56ebd40 Fix arc lint (should fix #238)
REVERT: 637f891 Merge pull request #321 from eonnen/master
REVERT: 827e31c Make test use a compatible type in the size checks.
REVERT: fd5d80d CompactedDB: log using the correct info_log
REVERT: 2faf49d use GetContext to replace callback function pointer
REVERT: 983d2de Add AUTHORS file. Fix #203
REVERT: abd70c5 Merge pull request #316 from fyrz/ReverseBytewiseComparator
REVERT: 2dc6f62 handle kDelete type in cuckoo builder
REVERT: 8b8011a Changed name of ReverseBytewiseComparator based on review comment
REVERT: 389edb6 universal compaction picker: use double for potential overflow
REVERT: 5340484 Built-in comparator(s) in RocksJava
REVERT: d439451 delay initialization of cuckoo table iterator
REVERT: 94997ea reduce memory usage of cuckoo table builder
REVERT: c627595 improve memory efficiency of cuckoo reader
REVERT: 581442d option to choose module when calculating CuckooTable hash
REVERT: fbd2daf CompactedDBImpl::MultiGet() for better CuckooTable performance
REVERT: 3c68006 CompactedDBImpl
REVERT: f7375f3 Fix double deletes
REVERT: 21ddcf6 Remove allow_thread_local
REVERT: fb4a492 Merge pull request #311 from ankgup87/master
REVERT: 611e286 Merge branch 'master' of https://github.com/facebook/rocksdb
REVERT: 0103b44 Merge branch 'master' of ssh://github.com/ankgup87/rocksdb
REVERT: 1dfb7bb Add block based table config options
REVERT: cdaf44f Enlarge log size cap when printing file summary
REVERT: 7cc1ed7 Merge pull request #309 from naveenatceg/staticbuild
REVERT: ba6d660 Resolving merge conflict
REVERT: 51eeaf6 Addressing review comments
REVERT: fd7d3fe Addressing review comments (adding a env variable to override temp directory)
REVERT: cf7ace8 Addressing review comments
REVERT: 0a29ce5 re-enable BlockBasedTable::SetupForCompaction()
REVERT: 55af370 Remove TODO for checking index checksums
REVERT: 3d74f09 Fix compile
REVERT: 53b0039 Fix release compile
REVERT: d0de413 WriteBatchWithIndex to allow different Comparators for different column families
REVERT: 57a32f1 change target_file_size_base to uint64_t
REVERT: 5e6aee4 dont create backup_input if compaction filter v2 is not used
REVERT: 49b5f94 Merge pull request #306 from Liuchang0812/fix_cast
REVERT: 787cb4d remove cast, replace %llu with % PRIu64
REVERT: a7574d4 Update logging.cc
REVERT: 7e0dcb9 Update logging.cc
REVERT: 57fa3cc Merge pull request #304 from Liuchang0812/fix-check
REVERT: cd44522 Merge pull request #305 from Liuchang0812/fix-logging
REVERT: 6a031b6 remove unused variable
REVERT: 4436f17 fixed #303: replace %ld with % PRId64
REVERT: 7a1bd05 Merge pull request #302 from ankgup87/master
REVERT: 423e52c Merge branch 'master' of https://github.com/facebook/rocksdb
REVERT: bfeef94 Add rate limiter
REVERT: 32f2532 Print compression_size_percent as a signed int
REVERT: 976caca Skip AllocateTest if fallocate() is not supported in the file system
REVERT: 3b897cd Enable no-fbcode RocksDB build
REVERT: f445947 RocksDB: Format uint64 using PRIu64 in db_impl.cc
REVERT: e17bc65 Merge pull request #299 from ankgup87/master
REVERT: b93797a Fix build
REVERT: adae3ca [Java] Fix JNI link error caused by the removal of options.db_stats_log_interval
REVERT: 90b8c07 Fix unit tests errors
REVERT: 51af7c3 CuckooTable: add one option to allow identity function for the first hash function
REVERT: 0350435 Fixed a signed-unsigned comparison in spatial_db.cc -- issue #293
REVERT: 2fb1fea Fix syncronization issues
REVERT: ff76895 Remove some unnecessary constructors
REVERT: feadb9d fix cuckoo table builder test
REVERT: 3c232e1 Fix mac compile
REVERT: 54cada9 Run make format on PR #249
REVERT: 27b22f1 Merge pull request #249 from tdfischer/decompression-refactoring
REVERT: fb6456b Replace naked calls to operator new and delete (Fixes #222)
REVERT: 5600c8f cuckoo table: return estimated size - 1
REVERT: a062e1f SetOptions() for memtable related options
REVERT: e4eca6a Options conversion function for convenience
REVERT: a7c2094 Merge pull request #292 from saghmrossi/master
REVERT: 4d05234 Merge branch 'master' of github.com:saghmrossi/rocksdb
REVERT: 60a4aa1 Test use_mmap_reads
REVERT: 94e43a1 [Java] Fixed 32-bit overflowing issue when converting jlong to size_t
REVERT: f9eaaa6 added include for inttypes.h to fix nonworking printf statements
REVERT: f090575 Replaced "built on on earlier work" by "built on earlier work" in README.md
REVERT: faad439 Fix #284
REVERT: 49aacd8 Fix make install
REVERT: acb9348 [Java] Include WriteBatch into RocksDBSample.java, fix how DbBenchmark.java handles WriteBatch.
REVERT: 4a27a2f Don't sync manifest when disableDataSync = true
REVERT: 9b8480d Merge pull request #287 from yinqiwen/rate-limiter-crash-fix
REVERT: 28be16b fix rate limiter crash #286
REVERT: 04ce1b2 Fix #284
REVERT: add22e3 standardize scripts to run RocksDB benchmarks
REVERT: dee91c2 WriteThread
REVERT: 540a257 Fix WAL synced
REVERT: 24f034b Merge pull request #282 from Chilledheart/develop
REVERT: 49fe329 Fix build issue under macosx
REVERT: ebb5c65 Add make install
REVERT: 0352a9f add_wrapped_bloom_test
REVERT: 9c0e66c Don't run background jobs (flush, compactions) when bg_error_ is set
REVERT: a9639bd Fix valgrind test
REVERT: d1f24dc Relax FlushSchedule test
REVERT: 3d9e6f7 Push model for flushing memtables
REVERT: 059e584 [unit test] CompactRange should fail if we don't have space
REVERT: dd641b2 fix RocksDB java build
REVERT: 53404d9 add_qps_info_in cache bench
REVERT: a52cecb Fix Mac compile
REVERT: 092f97e Fix comments and typos
REVERT: 6cc1286 Added a few statistics for BackupableDB
REVERT: 0a42295 Fix SimpleWriteTimeoutTest
REVERT: 06d9862 Always pass MergeContext as pointer, not reference
REVERT: d343c3f Improve db recovery
REVERT: 6bb7e3e Merger test
REVERT: 88841bd Explicitly cast char to signed char in Hash()
REVERT: 5231146 MemTableOptions
REVERT: 1d284db Addressing review comments
REVERT: 55114e7 Some updates for SpatialDB
REVERT: 171d4ff remove TailingIterator reference in db_impl.h
REVERT: 9b0f7ff rename version_set options_ to db_options_ to avoid confusion
REVERT: 2d57828 Check stop level trigger-0 before slowdown level-0 trigger
REVERT: 659d2d5 move compaction_filter to immutable_options
REVERT: 048560a reduce references to cfd->options() in DBImpl
REVERT: 011241b DB::Flush() Do not wait for background threads when there is nothing in mem table
REVERT: a2bb7c3 Push- instead of pull-model for managing Write stalls
REVERT: 0af157f Implement full filter for block based table.
REVERT: 9360cc6 Fix valgrind issue
REVERT: 02d5bff Merge pull request #277 from wankai/master
REVERT: 88a2f44 fix comments
REVERT: 7c16e39 Merge pull request #276 from wankai/master
REVERT: 8237738 replace hard-coded number with named variable
REVERT: db8ca52 Merge pull request #273 from nbougalis/static-analysis
REVERT: b7b031f Merge pull request #274 from wankai/master
REVERT: 4c2b1f0 Merge remote-tracking branch 'upstream/master'
REVERT: a5d2863 typo improvement
REVERT: 9f8aa09 Don't leak data returned by opendir
REVERT: d1cfb71 Remove unused member(s)
REVERT: bfee319 sizeof(int*) where sizeof(int) was intended
REVERT: d40c1f7 Add missing break statement
REVERT: 2e97c38 Avoid off-by-one error when using readlink
REVERT: 40ddc3d add cache bench
REVERT: 9f1c80b Drop column family from write thread
REVERT: 8de151b Add db_bench with lots of column families to regression tests
REVERT: c9e419c rename options_ to db_options_ in DBImpl to avoid confusion
REVERT: 5cd0576 Fix compaction bug in Cuckoo Table Builder. Use kvs_.size() instead of num_entries in FileSize() method.
REVERT: 0fbb3fa fixed memory leak in unit test DBIteratorBoundTest
REVERT: adcd253 fix asan check
REVERT: 4092b7a Merge pull request #272 from project-zerus/patch-1
REVERT: bb6ae0f fix more compile warnings
REVERT: 6d31441 Merge pull request #271 from nbougalis/cleanups
REVERT: 0cd0ec4 Plug memory leak during index creation
REVERT: 4329d74 Fix swapped variable names to accurately reflect usage
REVERT: 45a5e3e Remove path with arena==nullptr from NewInternalIterator
REVERT: 5665e5e introduce ImmutableOptions
REVERT: e0b99d4 created a new ReadOptions parameter 'iterate_upper_bound'
REVERT: 51ea889 Fix travis builds
REVERT: a481626 Relax backupable rate limiting test
REVERT: f7f973d Merge pull request #269 from huahang/patch-2
REVERT: ef5b384 fix a few compile warnings
REVERT: 2fd3806 Merge pull request #263 from wankai/master
REVERT: 1785114 delete unused Comparator
REVERT: 1b1d961 update HISTORY.md
REVERT: 703c3ea comments about the BlockBasedTableOptions migration in Options
REVERT: 4b5ad88 Merge pull request #260 from wankai/master
REVERT: 19cc588 change to filter_block std::unique_ptr support RAII
REVERT: 9b976e3 Merge pull request #259 from wankai/master
REVERT: 5d25a46 Merge remote-tracking branch 'upstream/master'
REVERT: dff2b1a typo improvement
REVERT: 343e98a Reverting import change
REVERT: ddb8039 RocksDB static build Make file changes to download and build the dependencies .Load the shared library when RocksDB is initialized

git-subtree-dir: src/rocksdb2
git-subtree-split: 1fdd726a8254c13d0c66d8db8130ad17c13d7bcc
2014-10-27 11:36:32 -07:00
Vinnie Falco
2cce22052b Update SQLite to 3.8.7:
sha1: 3e23079f062fc06705eead4db108ee429878b532
2014-10-27 11:04:46 -07:00
Tom Ritchford
4e19d5f625 Adjust paths and costs in Pathfinder. 2014-10-27 11:03:19 -07:00
Tom Ritchford
5b667da526 Squelch some warnings in rippled and third-party code. 2014-10-27 10:00:03 -07:00
Nik Bougalis
f9fc9a3518 Reduce RippleD dependencies on Beast:
* Use static_assert where appropriate
* Use std::min and std::max where appropriate
* Simplify RippleD error reporting
* Remove use of beast::RandomAccessFile
2014-10-27 09:55:58 -07:00
Nik Bougalis
e005cfd70e Reduce Beast public interface and eliminate unused code:
Beast includes a lot of code for encapsulating cross-platform differences
which are not used or needed by rippled. Additionally, a lot of that code
implements functionality that is available from the standard library.

This moves away from custom implementations of features that the standard
library provides and reduces the number of platform-specific interfaces
andfeatures that Beast makes available.

Highlights include:
* Use std:: instead of beast implementations when possible
* Reduce the use of beast::String in public interfaces
* Remove Windows-specific COM and Registry code
* Reduce the public interface of beast::File
* Reduce the public interface of beast::SystemStats
* Remove unused sysctl/getsysinfo functions
* Remove beast::Logger
2014-10-27 09:55:43 -07:00
Vinnie Falco
feb997481c Refactor the structure of ServerHandler:
This is a cleanup to the structure of the sources.
* Rename to ServerHandler
* Move private implementation declaration to separate header
* De-inline function definitions in the class declaration.
2014-10-27 09:50:03 -07:00
Vinnie Falco
2c8e90c9d8 Remove obsolete RPCServerHandler:
This removes the legacy RPCServerHandler, which has been replaced by the
asynchronous RPC-HTTP/S server and corresponding RPCHTTPHandler.
2014-10-27 09:50:03 -07:00
Vinnie Falco
ec96d5afa0 Remove unused and obsolete classes and tidy up:
Many classes required to support type-erasure of handlers and boost::asio
types are now obsolete, so these classes and files are removed:
HTTPClientType, FixedInputBuffer, PeerRole, socket_wrapper,
client_session, basic_url, abstract_socket, buffer_sequence, memory_buffer,
enable_wait_for_async, shared_handler, wrap_handler, streambuf,
ContentBodyBuffer, SSLContext, completion-handler based handshake detectors.
These structural changes are made:
* Some missing includes added to headers
* asio module directory flattened
2014-10-26 08:40:52 -07:00
Vinnie Falco
8be8853c33 Remove obsolete classes, disable unused code, and tidy up:
* Removed MultiSocket. Code that previously used the MultiSocket now uses
  a combination of boost::asio coroutines and CRTP.
* Sitefiles headers rolled up and directory flattened.
* Disabled Sitefiles use of deprecated HTTPClient.
* Validators headers tidied up.
* Disabled Validators use of deprecated HTTPClient.
2014-10-26 08:38:37 -07:00
Vinnie Falco
c228f5a244 Set version to 0.26.4-rc3 2014-10-25 08:07:40 -07:00
Vinnie Falco
d4c8b4e3ac Merge branch 'release' into develop 2014-10-25 08:07:30 -07:00
Vinnie Falco
6564f6c164 Fix incorrect socket closure in Overlay peers:
On Application exit, Overlay was calling PeerImp::close for each peer.
The implementation of PeerImp::close only canceled all pending I/O and did not
call functions necessary for proper transition of Peer state during socket
closure. The correct transition is ensured by calling PeerImp::detach. This
changes PeerImp::close to call PeerImp::detach instead, ensuring that Overlay
invariants are maintained. Specifically, that reference counts for pending I/O
on peers will be correctly unwound by canceling operations and that the Peer
object will be destroyed, thus allowing the Overlay to stop correctly.
2014-10-25 08:01:57 -07:00
Vinnie Falco
1e37a5509c Add missing includes 2014-10-24 08:13:55 -07:00
Vinnie Falco
1e9503deaa Set version to 0.26.2-rc2 2014-10-23 13:49:22 -07:00
Vinnie Falco
ab1f36c565 Revert "Add [overlay] configuration section (experimental):"
This reverts commit 856fd9d69f.
2014-10-23 13:48:52 -07:00
Vinnie Falco
5a212cd626 Set version to 0.26.4-rc1 2014-10-23 13:01:12 -07:00
Vinnie Falco
856fd9d69f Add [overlay] configuration section (experimental):
This configuration section uses the new BasicConfig interface that supports
key-value pairs in the section. Some exposition is added to the example cfg
file. The new settings for overlay are related to the Hub and Spoke feature
which is currently in development. Production servers should not set
these configuration options, they are clearly marked experimental in the
example cfg file.

Conflicts:
	src/ripple/overlay/impl/OverlayImpl.cpp
	src/ripple/overlay/impl/OverlayImpl.h
	src/ripple/overlay/impl/PeerImp.cpp
	src/ripple/overlay/impl/PeerImp.h
2014-10-23 12:56:16 -07:00
Vinnie Falco
4606d99951 Don't use MultiSocket in Overlay:
The MultiSocket is obsolete technology which is superceded by a more
straightforward, template based implementation that is compatible with
boost::asio::coroutines. This removes support for the unused PROXY handshake
feature. After this change a large number of classes and source files may be
removed.
2014-10-23 12:56:16 -07:00
Tom Ritchford
dbd75169e5 New JsonWriter for improved client performance (RIPD-439):
When JSON-RPC and Websocket responses are calculated, the result is stored
in intermediate Json::Value objects and later composed in a single linear
memory buffer before being sent to the socket.  These classes support a
new model for building responses that supports incremental construction
of JSON replies in constant time and removes the requirement that all
data returned be located in continuguous memory.
* New JsonWriter incrementally writes JSON with O(1) granularity and memory.
* Array, Object are RAII wrappers for the O(1) JsonWriter.
2014-10-23 07:04:47 -07:00
Vinnie Falco
f5b39ee911 Remove HTTP::ScopedStream:
This class was used to allow stream style operator<< to write to the
HTTP::Session. This is being superceded by a more robust object-based model
that supports coroutines.
2014-10-22 19:36:28 -07:00
Vinnie Falco
db5d52b4b2 Keep a list of section config values that are not key/value pairs:
This change to BasicConfig stores all appended lines which are not key/value
pairs in a separate values vector which can be retrieved later. This is to
support sections containing both key/value pairs and a list of values.
2014-10-22 19:36:28 -07:00
Vinnie Falco
dfeb9967b8 Return error_code from beast::http::basic_parser:
This changes the HTTP parser interface to return an error_code instead
of a bool. This eliminates the need for the error() member function and
simplifies calling code.
2014-10-22 19:36:28 -07:00
Vinnie Falco
673e860c18 Add beast::asio::ssl_bundle workaround:
This works around the limitation that 1.56 boost::asio::ssl::stream objects
do not support r-value move or construction. It is required when the stream
does not own the socket.
2014-10-22 19:36:28 -07:00
Vinnie Falco
9deae34b20 Workaround for MSVC stdlib and coroutine interaction:
If beast::Time::currentTimeMillis is first called from a coroutine launched
using boost::asio::spawn, Win32 throws an exception. This workaround calls
getCurrentTime once in main to prevent the exception.
Reference:
    https://svn.boost.org/trac/boost/ticket/10657
2014-10-22 19:36:27 -07:00
Vinnie Falco
ec92344fb4 Use autotls instead of multitls in websocket:
The MultiSocket class implements a socket that handshakes in multiple
protocols including SSL and PROXY. Unfortunately the way it type-erases the
handlers and buffers is incompatible with boost::asio coroutines. To pave the
way for coroutines this is part of a larger set of changes that roll back the
usage of MultiSocket to older code, and some custom implementations that use
templates. The custom implementations are more simple since they use
coroutines. Removing MultiSocket will make many other classes and source files
unused, a big win for trimming down the codebase size.
2014-10-22 19:34:48 -07:00
Donovan Hide
44c68d6174 Change NodeStore::Backend tests to reflect observed patterns:
Empirical evidence shows a database access pattern with few hits
and many misses (objects that don't exist). This changes the timing
tests so they more accurately reflect rippled's actual usage:
* Add read missing keys test
* Increase numObjectsToTest to 1,000,000
* Alter PredictableObjectFactory to seed RNG once only
* Make NodeStoreTiming a manual test
2014-10-22 19:29:29 -07:00
Howard Hinnant
5b7f172d03 Fix OS X version parsing/error related to OS X 10.10 update. 2014-10-22 19:29:28 -07:00
JoelKatz
65125eac87 Add "deferred" flag to transaction relay message
If we receive a deferred transaction from a server in our
cluster, treat it as if it wasn't received from a server
in our cluster.

This currently has no effect but is needed for server to
interoperate with future code that will relay deferred
transactions.
2014-10-22 19:29:28 -07:00
Scott Schurr
761902864a Refactor STParsedJSON to parse an object or array [RIPD-480]
The implementation of multi-sign has a SigningAccounts array as a
member of the outermost object.  This array could not be parsed
by the previous implementation of STParsedJSON, which only knew
how to parse objects.  This refactor supports the required parsing.

The refactor divides the parsing into three separate functions:

 o parseNoRecurse() which parses most rippled data types.
 o parseObject() which parses object types that may contain
   arbitrary other types.
 o parseArray() which parses object types that may contain
   arbitrary other types.

The change is required by the multi-sign implementation, but is
independent.  So the parsing change is going in as a separate
commit.

The parsing is still far from perfect.  But this was as much as
needs doing to accomplish the ends and mitigate risk of breaking
the parser.
2014-10-22 19:29:28 -07:00
Vinnie Falco
af24d541d1 Workaround for MSVC move special members. 2014-10-18 08:16:12 -07:00
Donovan Hide
3ad68a617e Fix dependency on boost::thread on OS/X. 2014-10-16 21:44:36 -04:00
Nik Bougalis
9e1a6589d4 Return descriptive error message from memo validation (RIPD-591). 2014-10-16 21:44:36 -04:00
Josh Juran
da8ceed07e RippleSSLContext.cpp cleanup.
* These cleanups precede work on RIPD-108.
2014-10-16 21:44:36 -04:00
Nik Bougalis
35935adc98 Fix URL compositing in Beast (RIPD-636). 2014-10-16 21:44:36 -04:00
Howard Hinnant
5b4a501f68 Detab beast 2014-10-15 19:39:30 -04:00
Tom Ritchford
5425a90f16 Fix tabs and trailing whitespace. 2014-10-15 19:39:30 -04:00
Donovan Hide
7eaca149c1 Remove boost_thread dependency (RIPD-216).
Fixes RIPD-216
2014-10-15 19:37:25 -04:00
Mark Travis
4b5fd95657 Disable SSLv3 2014-10-15 19:37:25 -04:00
Nik Bougalis
96dedf553e Refactor SerializedTransaction:
* Use boost:tribool instead of two intertwined bool variables
* Trim down public interface, reduce member variables
2014-10-15 19:37:25 -04:00
sublimator
23219f2662 Disable transaction submission tests under Travis. 2014-10-15 19:37:25 -04:00
Vinnie Falco
af78ed608e Call Stoppable::stopped in PeerFinder onStop. 2014-10-15 19:37:25 -04:00
Vinnie Falco
51dc59e019 Fix outgoing bytes calculation in HTTP server. 2014-10-15 19:37:25 -04:00
Tom Ritchford
afc102e90a New class RPC::Status enforces JSON-RPC 2.0 error format.
* Relevant issues:
  * RIPD-92
  * RIPD-97
  * RIPD-98
  * RIPD-439
2014-10-15 19:37:25 -04:00
David Schwartz
fc560179e0 SHAMap performance improvements (RIPD-434)
This reworks the way SHAMaps are stored, flushed, backed, and
traversed. Rather than storing the linkages in the SHAMap itself,
that information is now stored in the nodes. This makes
snapshotting much cheaper and also allows traverse work done on
behalf of one SHAMap to be used by other SHAMaps that share inner
nodes with that SHAMap.

When a SHAMap is modified, nodes are modified all the way up to the
root. This means that the modified nodes in a SHAMap can easily be
traversed for flushing. So they don't need to be separately tracked.

Summary
* Remove mTNByID
* Remove mDirtyNodes
* Much faster traverses
* Much Faster snapshots
* New algorithm for flushing
* New vistNodes/visitLeaves
* Avoid I/O if a map is unbacked
2014-10-14 13:32:17 -04:00
sublimator
d26241de0e Remove Og from debug mode
Last time I used gdb, iterating over a directory's `Indexes`, each uint256 printed as `<optimized out>`.

Debug mode is for debugging ...
2014-10-14 12:57:41 -04:00
Howard Hinnant
00310f4f10 Silence clang warnings 2014-10-14 12:35:17 -04:00
Howard Hinnant
8caae219cf Gracefully cast from std:🧵:hardware_concurrency 2014-10-14 12:35:17 -04:00
Howard Hinnant
2264ae9247 Guarantee C locale
*  Remove all calls to setlocale to ensure that the global
   locale is always C.

*  Also replace beast::SystemStats::getNumCpus() with
   std:🧵:hardware_concurrency()
2014-10-14 12:35:17 -04:00
Nicholas Dudfield
29225bbe75 Attempt to fix spurious travis failures 2014-10-14 12:35:17 -04:00
Vinnie Falco
4b5625fd59 Load PeerFinder database in Stoppable::onPrepare:
OverlayImpl::onStart calls into PeerFinder before PeerFinder::Manager::onStart,
causing tests to sometimes fail and the application to intermittently not start.
The order of calls to Stoppable::onStart is implementation defined and not
predictable.

This changes PeerFinder to load the database in Stoppable::onPrepare, before
threads are launched. In general, creation and initialization of resources that
are shared between classes should happen in onPrepare rather than onStart,
to solve this problem.
2014-10-10 19:38:52 -07:00
Vinnie Falco
7c0c2419f7 Refactor PeerFinder:
Previously, the PeerFinder manager constructed with a Callback object
provided by the owner which was used to perform operations like connecting,
disconnecting, and sending messages. This made it difficult to change the
overlay code because a single call into the PeerFinder could cause both
OverlayImpl and PeerImp to be re-entered one or more times, sometimes while
holding a recursive mutex. This change eliminates the callback by changing
PeerFinder functions to return values indicating the action the caller should
take.

As a result of this change the PeerFinder no longer needs its own dedicated
thread. OverlayImpl is changed to call into PeerFinder on a timer to perform
periodic activities. Furthermore the Checker class used to perform connectivity
checks has been refactored. It no longer uses an abstract base class, in order
to not type-erase the handler passed to async_connect (ensuring compatibility
with coroutines). To allow unit tests that don't need a network, the Logic
class is now templated on the Checker type. Currently the Manager provides its
own io_service. However, this can easily be changed so that the io_service is
provided upon construction.

Summary
* Remove unused SiteFiles dependency injection
* Remove Callback and update signatures for public APIs
* Remove obsolete functions
* Move timer to overlay
* Steps toward a shared io_service
* Templated, simplified Checker
* Tidy up Checker declaration
2014-10-10 15:04:37 -07:00
Vinnie Falco
5f59282ba1 Clean up Overlay and PeerFinder sources:
* Tidy up identifiers and declarations
* Merge PeerFinder headers into one file
* Merge handout classes and functions into one file
2014-10-10 15:04:36 -07:00
Vinnie Falco
db03ce939c Add pending_handlers 2014-10-10 13:26:08 -07:00
Vinnie Falco
68bcbbb701 Add missing include in beast header 2014-10-10 13:26:08 -07:00
David Schwartz
8bdf7b3983 Remove unused file 2014-10-10 10:27:47 -07:00
Vinnie Falco
4ab427d315 Cleanup: Combine Section and BasicConfig, move to basics 2014-10-09 14:49:10 -07:00
Vinnie Falco
9a0a434dd8 Fix incorrect address in connectivity check report:
The remoteAddress is the address as seen on the socket, which for
incoming connections has a random port chosen by the remote implementation
that is different from the port number used to accept connections by the
remote listening socket. The checkedAddress is the remote address as seen
on the socket, combined with the port advertised in the TMEndpoints message.
This fixes the reporting and metadata associated with addresses tested
for connectivity.

The README has been updated to reflect that uptime is no longer part of
the metadata associated with IP addresses saved for bootstrapping.
2014-10-09 14:48:54 -07:00
Nik Bougalis
33d1dda954 Handle BIGNUM conversion failure 2014-10-06 11:24:42 -07:00
Howard Hinnant
8e9efb4ceb Remove unused transaction code. 2014-10-06 11:18:15 -07:00
Nik Bougalis
8835af11d5 Cleanups and surface reduction:
* Don't use friendship unless needed
* Trim down interfaces
* Make classes feel more like std containers
2014-10-06 11:18:15 -07:00
Nik Bougalis
cfb6b678f1 Remove HashMaps 2014-10-02 14:58:14 -07:00
miguelportilla
365500da98 Create orderbook integration test (RIPD-483) 2014-10-02 14:58:14 -07:00
Miguel Portilla
f14d75e798 Optimize account_lines and account_offers (RIPD-587)
Conflicts:
	src/ripple/app/ledger/Ledger.h
2014-10-02 14:58:14 -07:00
Tom Ritchford
0f71b4a378 Fix most compilation warnings for gcc, clang, release, debug. 2014-10-02 14:58:14 -07:00
JoelKatz
b651e0146d Fix some fee logic: (RIPD-614)
* fee_default sets cost in drops of reference transaction
* Offline signing uses fee_default
* Signing multiplier maximum works correctly
* Fix bugs in load fee track
* Remove dead code, add comments
2014-10-02 14:58:14 -07:00
Tom Ritchford
a0dbbb2d84 Update and sort ErrorCode descriptions 2014-10-02 14:57:31 -07:00
Torrie Fischer
a85fbf69e0 Update rocksdb 2014-10-02 14:57:31 -07:00
Torrie Fischer
92b8c7961b Squashed 'src/rocksdb2/' changes from 37c6740..25888ae
25888ae Merge pull request #329 from fyrz/master
89833e5 Fixed signed-unsigned comparison warning in db_test.cc
fcac705 Fixed compile warning on Mac caused by unused variables.
b3343fd resolution for java build problem introduced by 5ec53f3edf62bec1b690ce12fb21a6c52203f3c8
187b299 ForwardIterator: update prev_key_ only if prefix hasn't changed
5ec53f3 make compaction related options changeable
d122e7b Update INSTALL.md
986dad0 Merge pull request #324 from dalgaaf/wip-da-SCA-20140930
8ee75dc db/memtable.cc: remove unused variable merge_result
0fd8bbc db/db_impl.cc: reduce scope of prefix_initialized
676ff7b compaction_picker.cc: remove check for >=0 for unsigned
e55aea5 document_db.cc: fix assert
d517c83 in_table_factory.cc: use correct format specifier
b140375 ttl/ttl_test.cc: prefer prefix ++operator for non-primitive types
43c789c spatialdb/spatial_db.cc: use !empty() instead of 'size() > 0'
0de452e document_db.cc: pass const parameter by reference
4cc8643 util/ldb_cmd.cc: prefer prefix ++operator for non-primitive types
af8c2b2 util/signal_test.cc: suppress intentional null pointer deref
33580fa db/db_impl.cc: fix object handling, remove double lines
873f135 db_ttl_impl.h: pass func parameter by reference
8558457 ldb_cmd_execute_result.h: perform init in initialization list
063471b table/table_test.cc: pass func parameter by reference
93548ce table/cuckoo_table_reader.cc: pass func parameter by ref
b8b7117 db/version_set.cc: use !empty() instead of 'size() > 0'
8ce050b table/bloom_block.*: pass func parameter by reference
53910dd db_test.cc: pass parameter by reference
68ca534 corruption_test.cc: pass parameter by reference
7506198 cuckoo_table_db_test.cc: add flush after delete
1f96330 Print MB per second compaction throughput separately for reads and writes
ffe3d49 Add an instruction about SSE in INSTALL.md
ee1f3cc Package generation for Ubuntu and CentOS
f0f7955 Fixing comile errors on OS X
99fb613 remove 2 space linter
b2d64a4 Fix linters, second try
747523d Print per column family metrics in db_bench
56ebd40 Fix arc lint (should fix #238)
637f891 Merge pull request #321 from eonnen/master
827e31c Make test use a compatible type in the size checks.
fd5d80d CompactedDB: log using the correct info_log
2faf49d use GetContext to replace callback function pointer
983d2de Add AUTHORS file. Fix #203
abd70c5 Merge pull request #316 from fyrz/ReverseBytewiseComparator
2dc6f62 handle kDelete type in cuckoo builder
8b8011a Changed name of ReverseBytewiseComparator based on review comment
389edb6 universal compaction picker: use double for potential overflow
5340484 Built-in comparator(s) in RocksJava
d439451 delay initialization of cuckoo table iterator
94997ea reduce memory usage of cuckoo table builder
c627595 improve memory efficiency of cuckoo reader
581442d option to choose module when calculating CuckooTable hash
fbd2daf CompactedDBImpl::MultiGet() for better CuckooTable performance
3c68006 CompactedDBImpl
f7375f3 Fix double deletes
21ddcf6 Remove allow_thread_local
fb4a492 Merge pull request #311 from ankgup87/master
611e286 Merge branch 'master' of https://github.com/facebook/rocksdb
0103b44 Merge branch 'master' of ssh://github.com/ankgup87/rocksdb
1dfb7bb Add block based table config options
cdaf44f Enlarge log size cap when printing file summary
7cc1ed7 Merge pull request #309 from naveenatceg/staticbuild
ba6d660 Resolving merge conflict
51eeaf6 Addressing review comments
fd7d3fe Addressing review comments (adding a env variable to override temp directory)
cf7ace8 Addressing review comments
0a29ce5 re-enable BlockBasedTable::SetupForCompaction()
55af370 Remove TODO for checking index checksums
3d74f09 Fix compile
53b0039 Fix release compile
d0de413 WriteBatchWithIndex to allow different Comparators for different column families
57a32f1 change target_file_size_base to uint64_t
5e6aee4 dont create backup_input if compaction filter v2 is not used
49b5f94 Merge pull request #306 from Liuchang0812/fix_cast
787cb4d remove cast, replace %llu with % PRIu64
a7574d4 Update logging.cc
7e0dcb9 Update logging.cc
57fa3cc Merge pull request #304 from Liuchang0812/fix-check
cd44522 Merge pull request #305 from Liuchang0812/fix-logging
6a031b6 remove unused variable
4436f17 fixed #303: replace %ld with % PRId64
7a1bd05 Merge pull request #302 from ankgup87/master
423e52c Merge branch 'master' of https://github.com/facebook/rocksdb
bfeef94 Add rate limiter
32f2532 Print compression_size_percent as a signed int
976caca Skip AllocateTest if fallocate() is not supported in the file system
3b897cd Enable no-fbcode RocksDB build
f445947 RocksDB: Format uint64 using PRIu64 in db_impl.cc
e17bc65 Merge pull request #299 from ankgup87/master
b93797a Fix build
adae3ca [Java] Fix JNI link error caused by the removal of options.db_stats_log_interval
90b8c07 Fix unit tests errors
51af7c3 CuckooTable: add one option to allow identity function for the first hash function
0350435 Fixed a signed-unsigned comparison in spatial_db.cc -- issue #293
2fb1fea Fix syncronization issues
ff76895 Remove some unnecessary constructors
feadb9d fix cuckoo table builder test
3c232e1 Fix mac compile
54cada9 Run make format on PR #249
27b22f1 Merge pull request #249 from tdfischer/decompression-refactoring
fb6456b Replace naked calls to operator new and delete (Fixes #222)
5600c8f cuckoo table: return estimated size - 1
a062e1f SetOptions() for memtable related options
e4eca6a Options conversion function for convenience
a7c2094 Merge pull request #292 from saghmrossi/master
4d05234 Merge branch 'master' of github.com:saghmrossi/rocksdb
60a4aa1 Test use_mmap_reads
94e43a1 [Java] Fixed 32-bit overflowing issue when converting jlong to size_t
f9eaaa6 added include for inttypes.h to fix nonworking printf statements
f090575 Replaced "built on on earlier work" by "built on earlier work" in README.md
faad439 Fix #284
49aacd8 Fix make install
acb9348 [Java] Include WriteBatch into RocksDBSample.java, fix how DbBenchmark.java handles WriteBatch.
4a27a2f Don't sync manifest when disableDataSync = true
9b8480d Merge pull request #287 from yinqiwen/rate-limiter-crash-fix
28be16b fix rate limiter crash #286
04ce1b2 Fix #284
add22e3 standardize scripts to run RocksDB benchmarks
dee91c2 WriteThread
540a257 Fix WAL synced
24f034b Merge pull request #282 from Chilledheart/develop
49fe329 Fix build issue under macosx
ebb5c65 Add make install
0352a9f add_wrapped_bloom_test
9c0e66c Don't run background jobs (flush, compactions) when bg_error_ is set
a9639bd Fix valgrind test
d1f24dc Relax FlushSchedule test
3d9e6f7 Push model for flushing memtables
059e584 [unit test] CompactRange should fail if we don't have space
dd641b2 fix RocksDB java build
53404d9 add_qps_info_in cache bench
a52cecb Fix Mac compile
092f97e Fix comments and typos
6cc1286 Added a few statistics for BackupableDB
0a42295 Fix SimpleWriteTimeoutTest
06d9862 Always pass MergeContext as pointer, not reference
d343c3f Improve db recovery
6bb7e3e Merger test
88841bd Explicitly cast char to signed char in Hash()
5231146 MemTableOptions
1d284db Addressing review comments
55114e7 Some updates for SpatialDB
171d4ff remove TailingIterator reference in db_impl.h
9b0f7ff rename version_set options_ to db_options_ to avoid confusion
2d57828 Check stop level trigger-0 before slowdown level-0 trigger
659d2d5 move compaction_filter to immutable_options
048560a reduce references to cfd->options() in DBImpl
011241b DB::Flush() Do not wait for background threads when there is nothing in mem table
a2bb7c3 Push- instead of pull-model for managing Write stalls
0af157f Implement full filter for block based table.
9360cc6 Fix valgrind issue
02d5bff Merge pull request #277 from wankai/master
88a2f44 fix comments
7c16e39 Merge pull request #276 from wankai/master
8237738 replace hard-coded number with named variable
db8ca52 Merge pull request #273 from nbougalis/static-analysis
b7b031f Merge pull request #274 from wankai/master
4c2b1f0 Merge remote-tracking branch 'upstream/master'
a5d2863 typo improvement
9f8aa09 Don't leak data returned by opendir
d1cfb71 Remove unused member(s)
bfee319 sizeof(int*) where sizeof(int) was intended
d40c1f7 Add missing break statement
2e97c38 Avoid off-by-one error when using readlink
40ddc3d add cache bench
9f1c80b Drop column family from write thread
8de151b Add db_bench with lots of column families to regression tests
c9e419c rename options_ to db_options_ in DBImpl to avoid confusion
5cd0576 Fix compaction bug in Cuckoo Table Builder. Use kvs_.size() instead of num_entries in FileSize() method.
0fbb3fa fixed memory leak in unit test DBIteratorBoundTest
adcd253 fix asan check
4092b7a Merge pull request #272 from project-zerus/patch-1
bb6ae0f fix more compile warnings
6d31441 Merge pull request #271 from nbougalis/cleanups
0cd0ec4 Plug memory leak during index creation
4329d74 Fix swapped variable names to accurately reflect usage
45a5e3e Remove path with arena==nullptr from NewInternalIterator
5665e5e introduce ImmutableOptions
e0b99d4 created a new ReadOptions parameter 'iterate_upper_bound'
51ea889 Fix travis builds
a481626 Relax backupable rate limiting test
f7f973d Merge pull request #269 from huahang/patch-2
ef5b384 fix a few compile warnings
2fd3806 Merge pull request #263 from wankai/master
1785114 delete unused Comparator
1b1d961 update HISTORY.md
703c3ea comments about the BlockBasedTableOptions migration in Options
4b5ad88 Merge pull request #260 from wankai/master
19cc588 change to filter_block std::unique_ptr support RAII
9b976e3 Merge pull request #259 from wankai/master
5d25a46 Merge remote-tracking branch 'upstream/master'
9b58c73 call SanitizeDBOptionsByCFOptions() in the right place
a84234a Ignore missing column families
8ed70fc add assert to db Put in db_stress test
7f19bb9 Merge pull request #242 from tdfischer/perf-timer-destructors
8438a19 fix dropping column family bug
6614a48 Refactor PerfStepTimer to stop on destruct
076bd01 Fix compile
990df99 Fix ios compile
7dcadb1 Don't let flush preempt compaction in certain cases
dff2b1a typo improvement
985a31c Merge pull request #251 from nbougalis/master
f09329c Fix candidate file comparison when using path ids
7e9f28c limit max bytes that can be read/written per pread/write syscall
d20b8cf Improve Cuckoo Table Reader performance. Inlined hash function and number of buckets a power of two.
0f9c43e ForwardIterator: reset incomplete iterators on Seek()
722d80c reduce recordTick overhead in compaction loop
22a0a60 Merge pull request #250 from wankai/master
be25ee4 delete unused struct Options
0c26e76 Merge pull request #237 from tdfischer/tdfischer/faster-timeout-test
1d23b5c remove_internal_filter_policy
2a8faf7 Compact SpatialDB as we go, not at the end
7f71448 Implementing a cache friendly version of Cuckoo Hash
d977e55 Don't let other compactions run when manual compaction runs
d5bd6c7 Fix ios compile
6b46f78 Merge pull request #248 from wankai/master
528a11c Update block_builder.h
536e997 Remove assert in vector rep
4142a3e Adding a user comparator for comparing Uint64 slices.
1913ce2 more concurrent flushes in SpatialDB
808e809 Adjust SpatialDB column family options
0c39f54 Use Vector memtable when bulk loading SpatialDB
b6fd781 Don't do memtable lookup in db_impl_readonly if memtables are empty while opening db.
9dcb75b Add is-file-deletions-enabled property
1755581 improve OptimizeForPointLookup()
d9c0785 Fix assertion in PosixRandomAccessFile
bda6f33 fix valgrind error in c_test caused by BlockBasedTableOptions
0db6b02 Update timeout to 50ms instead of 3.
ff6ec0e Optimize SpatialDB
2386185 ReadOptions.total_order_seek to allow total order seek for block-based table when hash index is enabled
a98badf print table options
66f62e5 JNI changes corresponding to BlockBasedTableOptions migration
3844001 move block based table related options BlockBasedTableOptions
17b54ae Merge pull request #243 from andybons/patch-1
0508691 Add missing include to use std::unique_ptr
42ea795 Fix concurrency issue in CompactionPicker
bb530c0 Merge pull request #240 from ShaoYuZhang/master
f76eda7 Fix compilation issue on OSX
08be7f5 Implement Prepare method in CuckooTableReader
47b452c Fix the error of c_test.c
562b7a1 Add missing implementaiton of SanitizeDBOptions in simple_table_db_test.cc
63a2215 Improve Options sanitization and add MmapReadRequired() to TableFactory
e173bf9 Eliminate VersionSet memory leak
10720a5 Revert the unintended change that DestroyDB() doesn't clean up info logs.
01cbdd2 Optimize storage parameters for spatialDB
045575a Add CuckooHash table format to table_reader_bench
7c5173d test: db: fix test to have a smaller timeout for when it runs on faster hardware
6929b08 Remove BitStream* tests
50b790c Removing BitStream* functions
162b815 Adding Column Family support in db_bench.
28b5c76 WriteBatchWithIndex: a wrapper of WriteBatch, with a searchable index
5585e00 Update release note of 3.4
343e98a Reverting import change
ddb8039 RocksDB static build Make file changes to download and build the dependencies .Load the shared library when RocksDB is initialized
68eed8c Bump up version
36e759d Adding Cuckoo Table SST option to db_bench
a6fd14c Fix valgrind error in c_test
c703715 attempt to fix auto_roll_logger_test
c8ecfae Merge pull request #230 from cockroachdb/spencerkimball/send-user-keys-to-v2-filter
570ba5a Avoid retrying to read property block from a table when it does not exist.
625b9ef Merge pull request #234 from bbiao/master
59a2763 Fix typo huage => huge
f611935 Fix autovector iterator increment/decrement comments
58b0f9d Support purging logs from separate log directory
2da53b1 [Java] Add purgeOldBackups API
6c4c159 fix_sst_dump_for_old_sst_format
8dfe2fd fix compile error under Mac OS X
58c4946 Allow env_posix to lower background thread IO priority
6a2be31 fix_valgrind_error_caused_in_db_info_dummper
e91ebf1 print compaction_filter name in Options.Dump
5a5953b Add histogram for DB_SEEK
5e64240 log db path info before open
0c9dc9f Remove malloc from FormatFileNumber
bcefede Update HISTORY.md
4808177 Revert "Include candidate files under options.db_log_dir in FindObsoleteFiles()"
0138b8e Fixed compile errors (signed / unsigned comparison) in cuckoo_table_db_test on Mac
1562653 Fixed a signed-unsigned comparison error in db_test
218857b remove tailing_iter.h/cc
5d0074c set bytes_per_sync to 1MB if rate limiter is enabled
3fcf7b2 Pass parsed user key to prefix extractor in V2 compaction
2fa6434 Add scope guard
06a52bd Flush only one column family
9674c11 Integrating Cuckoo Hash SST Table format into RocksDB

git-subtree-dir: src/rocksdb2
git-subtree-split: 25888ae0068c9b8e3d9421ea8c78a7be339298d8
2014-10-02 10:47:26 -07:00
Torrie Fischer
225f8ac12f Merge commit '92b8c7961b433d12d9d77da5d61c26a920bbd370' into updated-rocksdb 2014-10-02 10:47:26 -07:00
Howard Hinnant
1161511207 Fix two Wunused-private-field warnings. 2014-10-01 08:47:56 -07:00
Nicholas Dudfield
ca8eda412e Make travis build and use debug variants for tests 2014-10-01 08:47:56 -07:00
Mark Travis
ec4ec48fb8 Add counters to track nodestore read and write activities. 2014-10-01 08:47:56 -07:00
Nik Bougalis
c0b69e8ef7 Remove the use of beast::String from rippled (RIPD-443) 2014-10-01 08:47:55 -07:00
Tom Ritchford
4241dbb600 Clean and harden Transaction.
* Replace boolean parameter with enumerated type.
* Get rid of std::ref.
* 80-column cleanups.
* Replace an std::bin with a lambda.
2014-10-01 08:47:55 -07:00
Tom Ritchford
f54280aaad New DatabaseReader reads ledger numbers from database. 2014-10-01 08:47:55 -07:00
Tom Ritchford
6069400538 Fix compiler warnings under gcc. 2014-10-01 08:47:55 -07:00
Howard Hinnant
616be1d76c Miscellaneous cleanups:
* Limit HashPrefix construction and disallow assignment

* Give KnownFormats deleted copy members so that derived
  classes will give the right answers if queried with the
  std::is_copy_constructible/assignable traits.

* Replace SharedSingleton with a local static in
  LedgerFormats::getInstance() to be consistent with
  similar code in other places.  This also allows the
  LedgerFormats default constructor to be marked private
  so that the compiler enforces the design that
  LedgerFormats is a singleton type.

* Change return types of LedgerFormats::getInstance() and
  TxFormats::getInstance() from pointer to non-const to
  reference to const so as follow more established design
  guidelines for singletons.  This prevents pointers being
  mistaken for heap-allocated objects, and the const
  ensures the singleton isn't mutable.

* Change RippleAddress to inherit privately from
  CBase58Data instead of publicly.  This lets the compiler
  enforce that there are no unintended conversions from
  RippleAddress to CBase58Data.  This change allows us
  to remove a comment warning about unwanted conversions.
2014-10-01 08:47:54 -07:00
Nik Bougalis
8e91ce67c5 Allow beast::lexicalCast to parse 'true' & 'false' into a bool 2014-10-01 08:47:54 -07:00
JoelKatz
c1ecd661c3 Fix broken assert in built/validated ledger mismatch handler 2014-10-01 08:47:54 -07:00
JoelKatz
b27e2aad07 Improve transaction security
* Check signatures of every transaction on every validator
* Remove obsolete code
* Check transaction status in submit/sign RPC handler
2014-10-01 08:47:54 -07:00
MarkusTeufelberger
5ce508e09d Change output range names of ledger_cleaner
The input parameters are called "min_ledger" and "max_ledger", they are also called "minRange" and "maxRange" in the code BUT "ledger_min" and ledger_max" if printed. This is inconsistent and should be changed, as it might lead to confusion on how to call this module via RPC.
2014-10-01 08:47:53 -07:00
Nik Bougalis
3cfa5a41b1 Improve BuildInfo interface:
* Remove unnecessary beast::String dependency
* Explicitly cast to result type while packing a version
* Add unit tests for version formatting
2014-10-01 08:47:53 -07:00
Vinnie Falco
6c072f37ef Remove unused testoverlay module 2014-10-01 08:47:53 -07:00
Nik Bougalis
dbd993ed2b Use namespaces instead of static-only classes 2014-10-01 08:47:52 -07:00
Nik Bougalis
45b5c4ba7a Use deleted members to prevent copying in Beast (RIPD-268) 2014-10-01 08:47:52 -07:00
Nik Bougalis
7933e5d1f9 Use deleted members to prevent copying in rippled (RIPD-268) 2014-10-01 06:28:32 -07:00
Vinnie Falco
01e52e6f9f Use trusted validators median fee
Conflicts:
	src/ripple/app/misc/Validations.cpp
2014-10-01 06:28:32 -07:00
Vinnie Falco
40a955e192 Consume handshake data in HTTP/S server 2014-10-01 06:28:12 -07:00
Vinnie Falco
a8296f7301 Set version to 0.26.3-sp4 2014-09-30 18:04:59 -07:00
Vinnie Falco
590c3b876b Use trusted validators median fee 2014-09-30 18:03:53 -07:00
Vinnie Falco
6dfc805eaa Rewrite HTTP/S server to use coroutines:
* Fix bug with more than one complete request in a read buffer
* Use stackful coroutines for simplified control flow
* Door refactored to detect handshakes
* Remove dependency on MultiSocket
* Remove dependency on handshake detect logic framework
2014-09-30 13:29:32 -07:00
Vinnie Falco
5ce6068df5 Remove obsolete SharedArg 2014-09-29 07:18:51 -07:00
Nik Bougalis
bf9b8f4d1b Use secure RPC connections when configured 2014-09-28 04:39:49 -07:00
Vinnie Falco
d618581060 Config improvements:
* More fine-grained Section mutators
* Add remap for mapping legacy single sections to key value pairs
* Add output stream operators for BasicConfig and Section
* Allow section values to be overwritten from command line
* Update rpc key/value configs from command line
* Add RPC::Setup with defaults and remap legacy rpc sections
2014-09-28 04:39:49 -07:00
David Schwartz
2936bbfae8 Make path filtering smarter (RIPD-561)
* Break path liquidity checking into its own function
* Measure initial quality over minimum destination amount
* Test for available liquidity
2014-09-24 11:54:12 -07:00
Nik Bougalis
47b08bfc02 Add --quorum command line argument (RIPD-563) 2014-09-24 11:19:39 -07:00
Nik Bougalis
da4f77ca1f Return correct error message for invalid fields 2014-09-24 11:19:38 -07:00
David Schwartz
1c0a75d467 Distinguish Byzantine failure from tx bug (RIPD-523) 2014-09-24 11:19:38 -07:00
Nik Bougalis
659cf0c221 Decouple LedgerMaster from configuration 2014-09-24 11:19:38 -07:00
Howard Hinnant
430229fd84 Mark several Ledger member functions as const. 2014-09-24 11:19:37 -07:00
Howard Hinnant
81699a0971 Add +DEBUG to the raw version string for DEBUG builds.
This will show up in the rpc server_info command.
There is no impact on the version string for release builds.
2014-09-24 11:19:37 -07:00
MarkusTeufelberger
c54aff74b3 Build gcc.debug using -Og flag
Since gcc 4.8 is required anyways, it might be nice to use its features.

Intro to feature (second bullet point):
https://gcc.gnu.org/gcc-4.8/changes.html

-g (line 328) is still needed:
http://stackoverflow.com/questions/12970596/gcc-4-8-does-og-imply-g
2014-09-24 11:19:37 -07:00
Mark Travis
7f43ab9097 Improvements to SConstruct:
* Default target is release instead of debug (scons with no arguments).
* All targets now include debug symbols, including release.
Rationale: "out of the box" builds of rippled using plain "scons" or "scons -j4" will produce
a debug instead of a release build, which could underperform.
2014-09-24 11:19:36 -07:00
Miguel Portilla
d78f740250 Add account_offers paging (RIPD-344) 2014-09-19 16:38:10 -07:00
Miguel Portilla
cd1bd18a49 Add account_lines paging (RIPD-343) 2014-09-19 16:18:50 -07:00
sublimator
f81b084448 Set page sizes for ledger_data correctly (RIPD-249) 2014-09-19 16:16:49 -07:00
Vinnie Falco
02d9c77402 Set version to 0.26.3-sp2 2014-09-19 11:57:22 -07:00
Howard Hinnant
a0c903c68c Add needed #include <istream>
This is needed for the combination of boost 1.56 and libc++
2014-09-19 10:29:14 -07:00
JoelKatz
6aa325d3da On missing node in consensus, bow out (RIPD-567) 2014-09-18 15:12:45 -07:00
JoelKatz
041f874d4c Improve transaction security
* Check signatures of every transaction on every validator
* Remove obsolete code
* Check transaction status in submit/sign RPC handler
2014-09-18 14:25:09 -07:00
Nik Bougalis
526ecd6a81 Detect invalid inputs during STAmount conversion (RIPD-570):
* More robust validation of input
* XRP may not be specified using fractions
* Prevent creating native amounts larger than max possible value
* Add unit tests to verify correct parsing
2014-09-18 12:46:21 -07:00
Nik Bougalis
d373054fc4 Templetize and improve beast string-to-integer conversions:
* Properly handle numbers at the edge of precision
* Improve and expand unit test coverage
2014-09-18 12:46:16 -07:00
Vinnie Falco
b6d9f1d4b2 Add fee voting configuration and docs (RIPD-564) 2014-09-17 12:22:51 -07:00
Vinnie Falco
3fef916972 Move some constants to core/SystemParameters.h 2014-09-17 12:22:49 -07:00
Vinnie Falco
89a51e5b91 Split Section to its own header and add convenience accessors 2014-09-17 12:22:49 -07:00
miguelportilla
f87a6ccc7a Fix missing includes for boost 1.56.0 2014-09-16 15:22:00 -07:00
Nik Bougalis
f65cea66ef Remove unused macros, config variables, and file 2014-09-16 14:15:13 -07:00
Vinnie Falco
4239880acb Clean up and restructure sources 2014-09-16 14:15:12 -07:00
Vinnie Falco
1dcd06a1c1 Add missing includes and tidy up 2014-09-16 14:03:50 -07:00
Vinnie Falco
0f30191d10 Refactor STAmount:
* Remove unused functions
* Remove unused constructor
* Use delegating constructors
* Mark some observers deprecated
* Clean up declaration parameter names
* Add checked and unchecked constructors
* De-inline unnecessary inlined functions
* Reorder and regroup members into sections
* Move globals from the unity file to the .cpp
* Change some member functions to be free functions
* Put implementation in one .cpp and the test in another .cpp

Remove unused STAmount constructor and delegate two others No change in functionality.
2014-09-16 07:39:50 -07:00
Vinnie Falco
8fb9d5daaa Set version to 0.26.4-alpha 2014-09-15 18:20:47 -07:00
Nik Bougalis
ed3c942ff1 Inject JobQueue in NetworkOPs 2014-09-15 16:05:01 -07:00
Nik Bougalis
80436d4a8b Cleanups:
* Remove obsolete string formatting function
* Remove unused ADDRESS macro
* Re-scope functions
2014-09-15 16:04:48 -07:00
Howard Hinnant
cfc702c766 Fix beast::http::headers move members 2014-09-15 16:03:36 -07:00
Vinnie Falco
88ae15ea8e Add base64 conversions and tests 2014-09-15 14:52:42 -07:00
Vinnie Falco
6bafca7386 Use transform_iterator in http::headers 2014-09-15 14:52:42 -07:00
Vinnie Falco
379e842080 Add BasicConfig simplified config interface 2014-09-15 12:46:04 -07:00
Vinnie Falco
c41ce469d0 Cleanup:
* Move QUALITY_ONE to Quality.h
* Move functional files up one level
* Remove core.h
* Merge routines into Config.cpp
* Rename Section to IniFileSections
* Rename IniFileSections routines
2014-09-15 12:21:36 -07:00
Vinnie Falco
a1ca68473d Merge branch 'release' into develop 2014-09-14 15:39:09 -07:00
Nik Bougalis
3345d03433 Avoid conversions whenever possible during RippleState lookups 2014-09-13 11:06:38 -07:00
Nik Bougalis
81a426608a Make log partitions case-insensitive 2014-09-13 11:06:19 -07:00
Vinnie Falco
0215a7400d Fix handling of HTTP/S keep-alives (RIPD-556):
* Proper shutdown for ssl and non-ssl connections
* Report session id in history
* Report histogram of requests per session
* Change print name to 'http'
* Split logging into "HTTP" and "HTTP-RPC" partitions
* More logging and refinement of logging severities
* Log the request count when a session is destroyed
2014-09-12 14:20:30 -07:00
Vinnie Falco
79db0ca7a6 Add is_short_read() 2014-09-12 14:10:33 -07:00
JoelKatz
1a7eafb699 Add ledger cleaner documentation (RIPD-555) 2014-09-09 22:33:42 -07:00
Nik Bougalis
81a06ea6cd Cleanups:
* Remove obsolete config variables
* Reduce coupling
* Use C++11 ownership containers
* Use auto when it makes sense
* Detect edge-case in unit tests
* Reduce the number of LedgerEntrySet public members
2014-09-09 22:33:42 -07:00
Nik Bougalis
de4be649ab Refactor string-to-integer conversions 2014-09-09 21:38:09 -07:00
sublimator
d90ec5f06c Normalize sort paths in Visual Studio project generator 2014-09-08 11:17:40 -07:00
Vinnie Falco
32065ced6e Add peer count to HTTP server properties 2014-09-08 11:17:39 -07:00
Scott Schurr
b5224a2227 Improve regularity of STObject and STArray (RIPD-448, RIPD-544):
* reduce duplicated code using templates
* replace BOOST_FOREACH with C++11 for loops
* remove most direct calls to new
* limit line length to 80 characters
* clearly identify virtual and overridden methods
* split STObject and STArray into their own files
* name files after the class they contain
2014-09-05 13:02:07 -07:00
Nik Bougalis
c55777738f Refactor LedgerEntrySet:
* Split adjustOwnerCount to increment and decrement paths.
* Move pathfinding-specific functions out of LedgerEntrySet
* Convert members to free functions
2014-09-05 11:50:17 -07:00
JoelKatz
c72dff5a24 Make more RocksDB tunables
Add support for universal compaction
2014-09-05 11:50:17 -07:00
JoelKatz
6b09e49c08 Increase the size of the tree cache:
This change will not significantly increase memory consumption
because most entries are pinned anyway.
2014-09-05 11:48:00 -07:00
Nik Bougalis
413218c4c4 Create the directory for the debug_logfile (RIPD-551) 2014-09-04 16:51:31 -07:00
Miguel Portilla
16c04b50ee Add date to tx command (RIPD-542) 2014-09-04 16:51:31 -07:00
Nik Bougalis
56c18f7768 Cleanups and fixes (RIPD-532):
* Properly handle sfWalletLocator field
* Plug a tiny memory leak
* Avoid naked pointers
* Remove unused variables
* Other small cleanups
2014-09-04 16:51:31 -07:00
Tom Ritchford
22ca13bc78 Cleanups to RPC code 2014-09-04 16:51:31 -07:00
Nicholas Dudfield
4c7fd18230 Ticket integration tests 2014-09-04 16:51:31 -07:00
Nik Bougalis
39730fc13e Ticket issuing (RIPD-368):
* New CreateTicket transactor to create tickets
* New CancelTicket transactor to cancel tickets
* Ledger entries for tickets & associated functions
* First draft of M-of-N documentation
2014-09-04 16:11:44 -07:00
Nik Bougalis
889c0a0d0f Transactor refactor:
* Allocate transactors on the stack instead of the heap.
* Remove header files and reduce transactor public interface.
2014-09-04 16:11:44 -07:00
Nik Bougalis
624a803955 Handle whitespace separating an 'ip port' correctly (RIPD-552) 2014-09-04 12:26:27 -07:00
Nik Bougalis
a3fe089367 Fix missing return value error check 2014-09-02 08:45:19 -07:00
Vinnie Falco
61006e626d Also report mismatched built ledger 2014-08-28 18:03:50 -07:00
Nik Bougalis
15aad1cb24 Optimize pathfinding operations (RIPD-537):
* Calculate and cache Account hashes without holding locks.
* Fast hash-based path element comparison.
* Use emplace instead of find/insert
2014-08-28 15:57:29 -07:00
Tom Ritchford
95c1c5f54e Stream generated JSON. 2014-08-28 12:38:21 -07:00
Vinnie Falco
c65fb91878 Fix special members for http classes 2014-08-28 12:38:03 -07:00
1916 changed files with 150744 additions and 84819 deletions

View File

@@ -6,20 +6,10 @@ before_install:
- sudo apt-get update -qq
- sudo apt-get install -qq python-software-properties
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
- sudo add-apt-repository -y ppa:boost-latest/ppa
- sudo add-apt-repository -y ppa:afrank/boost
- sudo apt-get update -qq
- sudo apt-get install -qq g++-4.8
- sudo apt-get install -qq libboost1.55-all-dev
# We want debug symbols for boost as we install gdb later
- sudo apt-get install -qq libboost1.55-dbg
- | # Setup the BOOST_ROOT
export BOOST_ROOT=$HOME/boost_root
mkdir -p $BOOST_ROOT/stage
ln -s /usr/lib/x86_64-linux-gnu $BOOST_ROOT/stage/lib
ln -s /usr/include/boost $BOOST_ROOT/boost
- | # Try to patch boost
sudo patch /usr/include/boost/bimap/detail/debug/static_error.hpp Builds/travis/static_error.boost.patch
sudo patch /usr/include/boost/config/compiler/clang.hpp Builds/travis/clang.boost.patch
- sudo apt-get install -qq libboost1.57-all-dev
- sudo apt-get install -qq mlocate
- sudo updatedb
- sudo locate libboost | grep /lib | grep -e ".a$"
@@ -35,23 +25,35 @@ before_install:
# What versions are we ACTUALLY running?
- g++ -v
- clang -v
# Avoid `spurious errors` caused by ~/.npm permission issues
# Does it already exist? Who owns? What permissions?
- ls -lah ~/.npm || mkdir ~/.npm
# Make sure we own it
- sudo chown -R $USER ~/.npm
script:
# Set so any failing command will abort the build
- set -e
# If only we could do -j12 ;)
- scons
# $CC will be either `clang` or `gcc` (If only we could do -j12 ;)
- scons $CC.debug
# We can be sure we're using the build/$CC.debug variant (-f so never err)
- rm -f build/rippled
- export RIPPLED_PATH="$PWD/build/$CC.debug/rippled"
# See what we've actually built
- ldd ./build/rippled
- ldd $RIPPLED_PATH
# Run unittests (under gdb)
- | # create gdb script
echo "set env MALLOC_CHECK_=3" > script.gdb
echo "run" >> script.gdb
echo "backtrace full" >> script.gdb
# gdb --help
- cat script.gdb | gdb --ex 'set print thread-events off' --return-child-result --args ./build/rippled --unittest
# Run integration tests
- cat script.gdb | gdb --ex 'set print thread-events off' --return-child-result --args $RIPPLED_PATH --unittest
- npm install
# Use build/(gcc|clang).debug/rippled
- |
echo "exports.default_server_config = {\"rippled_path\" : \"$RIPPLED_PATH\"};" > test/config.js
# Run integration tests
- npm test
notifications:
email:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Express 2013 for Windows Desktop
VisualStudioVersion = 12.0.30110.0
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RippleD", "RippleD.vcxproj", "{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}"
EndProject
@@ -14,9 +14,11 @@ Global
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.Debug|Win32.ActiveCfg = debug|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.Debug|Win32.Build.0 = debug|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.Debug|x64.ActiveCfg = debug|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.Debug|x64.Build.0 = debug|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.Release|Win32.ActiveCfg = release|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.Release|Win32.Build.0 = release|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.Release|x64.ActiveCfg = release|x64
{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}.Release|x64.Build.0 = release|x64
EndGlobalSection

View File

@@ -1,5 +1,5 @@
Name: rippled
Version: 0.26.3-sp1
Version: 0.27.3-sp2
Release: 1%{?dist}
Summary: Ripple peer-to-peer network daemon
@@ -50,4 +50,3 @@ rm -rf %{buildroot}
/usr/bin/rippled
/usr/share/rippled/LICENSE
/etc/rippled/rippled-example.cfg

View File

@@ -1,3 +1,77 @@
![Ripple](/images/ripple.png)
#The Worlds Fastest and Most Secure Payment System
**What is Ripple?**
Ripple is the open-source, distributed payment protocol that enables instant
payments with low fees, no chargebacks, and currency flexibility (for example
dollars, yen, euros, bitcoins, or even loyalty points). Businesses of any size
can easily build payment solutions such as banking or remittance apps, and
accelerate the movement of money. Ripple enables the world to move value the
way it moves information on the Internet.
![Ripple Network](images/network.png)
**What is a Gateway?**
Ripple works with gateways: independent businesses which hold customer
deposits in various currencies such as U.S. dollars (USD) or Euros (EUR),
in exchange for providing cryptographically-signed issuances that users can
send and trade with one another in seconds on the Ripple network. Within the
protocol, exchanges between multiple currencies can occur atomically without
any central authority to monitor them. Later, customers can withdraw their
Ripple balances from the gateways that created those issuances.
**How do Ripple payments work?**
A sender specifies the amount and currency the recipient should receive and
Ripple automatically converts the senders available currencies using the
distributed order books integrated into the Ripple protocol. Independent third
parties acting as market makers provide liquidity in these order books.
Ripple uses a pathfinding algorithm that considers currency pairs when
converting from the source to the destination currency. This algorithm searches
for a series of currency swaps that gives the user the lowest cost. Since
anyone can participate as a market maker, market forces drive fees to the
lowest practical level.
**What can you do with Ripple?**
The protocol is entirely open-source and the networks shared ledger is public
information, so no central authority prevents anyone from participating.Anyone
can become a market maker, create a wallet or a gateway, or monitor network
behavior. Competition drives down spreads and fees, making the network useful
to everyone.
###Key Protocol Features
1. XRP is Ripples native [cryptocurrency]
(http://en.wikipedia.org/wiki/Cryptocurrency) with a fixed supply that
decreases slowly over time, with no mining. XRP acts as a bridge currency, and
pays for transaction fees that protect the network against spam
![XRP as a bridge currency](/images/vehicle_currency.png)
2. Pathfinding discovers cheap and efficient payment paths through multiple
[order books](https://www.ripplecharts.com) allowing anyone to [trade](https://www.rippletrade.com) anything. When two accounts arent linked by relationships of trust, the Ripple pathfinding engine considers intermediate links and order books to produce a set of possible paths the transaction can take. When the payment is processed, the liquidity along these paths is iteratively consumed in best-first order.
![Pathfinding from Euro to Japanese Yen](/images/pathfinding.png)
3. [Consensus](https://www.youtube.com/watch?v=pj1QVb1vlC0) confirms
transactions in an atomic fashion, without mining, ensuring efficient use of
resources.
[transact]: https://ripple.com/files/ripple-FIs.pdf
[build]: https://ripple.com/build/
[transact.png]: /images/transact.png
[build.png]: /images/build.png
[contribute.png]: /images/contribute.png
###Join The Ripple Community
|![Transact][transact.png]|![Build][build.png]|![Contribute][contribute.png]|
|:-----------------------:|:-----------------:|:---------------------------:|
|[Transact on the fastest payment infrastructure][transact]|[Build Imaginative Apps][build]|Contribute to the Ripple Protocol Implementation|
#rippled - Ripple P2P server
##[![Build Status](https://travis-ci.org/ripple/rippled.png?branch=develop)](https://travis-ci.org/ripple/rippled)
@@ -37,5 +111,9 @@ Ripple is open source and permissively licensed under the ISC license. See the
LICENSE file for more details.
###For more information:
* https://ripple.com
* https://ripple.com/wiki
* Ripple Wiki - https://ripple.com/wiki/
* Ripple Primer - https://ripple.com/ripple_primer.pdf
* Ripple Primer (Market Making) - https://ripple.com/ripple-mm.pdf
* Ripple Gateway Primer - https://ripple.com/ripple-gateways.pdf
* Consensus - https://wiki.ripple.com/Consensus

View File

@@ -11,14 +11,17 @@
all All available variants
debug All available debug variants
release All available release variants
profile All available profile variants
clang All clang variants
clang.debug clang debug variant
clang.release clang release variant
clang.profile clang profile variant
gcc All gcc variants
gcc.debug gcc debug variant
gcc.release gcc release variant
gcc.profile gcc profile variant
msvc All msvc variants
msvc.debug MSVC debug variant
@@ -26,6 +29,13 @@
vcxproj Generate Visual Studio 2013 project file
count Show line count metrics
Any individual target can also have ".nounity" appended for a classic,
non unity build. Example:
scons gcc.debug.nounity
If the clang toolchain is detected, then the default target will use it, else
the gcc toolchain will be used. On Windows environments, the MSVC toolchain is
also detected.
@@ -67,6 +77,7 @@ CHECK_LINE = 'built on: '
BUILD_TIME = 'Mon Apr 7 20:33:19 UTC 2014'
OPENSSL_ERROR = ('Your openSSL was built on %s; '
'rippled needs a version built on or after %s.')
UNITY_BUILD_DIRECTORY = 'src/ripple/unity/'
def check_openssl():
if Beast.system.platform in CHECK_PLATFORMS:
@@ -198,7 +209,10 @@ def config_base(env):
)
check_openssl()
env.Append(CPPDEFINES=['OPENSSL_NO_SSL2'])
env.Append(CPPDEFINES=[
'OPENSSL_NO_SSL2'
,'DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER'
])
try:
BOOST_ROOT = os.path.normpath(os.environ['BOOST_ROOT'])
@@ -244,7 +258,7 @@ def config_env(toolchain, variant, env):
if variant == 'debug':
env.Append(CPPDEFINES=['DEBUG', '_DEBUG'])
elif variant == 'release':
elif variant == 'release' or variant == 'profile':
env.Append(CPPDEFINES=['NDEBUG'])
if toolchain in Split('clang gcc'):
@@ -259,16 +273,35 @@ def config_env(toolchain, variant, env):
'-Wno-sign-compare',
'-Wno-char-subscripts',
'-Wno-format',
'-g' # generate debug symbols
])
env.Append(LINKFLAGS=[
'-rdynamic',
'-g',
])
if variant == 'profile':
env.Append(CCFLAGS=[
'-p',
'-pg',
])
env.Append(LINKFLAGS=[
'-p',
'-pg',
])
if toolchain == 'clang':
env.Append(CCFLAGS=['-Wno-redeclared-class-member'])
env.Append(CPPDEFINES=['BOOST_ASIO_HAS_STD_ARRAY'])
env.Append(CXXFLAGS=[
'-frtti',
'-std=c++11',
'-Wno-invalid-offsetof'])
env.Append(CPPDEFINES=['_FILE_OFFSET_BITS=64'])
if Beast.system.osx:
env.Append(CPPDEFINES={
'BEAST_COMPILE_OBJECTIVE_CPP': 1,
@@ -289,6 +322,8 @@ def config_env(toolchain, variant, env):
])
boost_libs = [
'boost_coroutine',
'boost_context',
'boost_date_time',
'boost_filesystem',
'boost_program_options',
@@ -319,26 +354,12 @@ def config_env(toolchain, variant, env):
else:
env.Append(LIBS=['rt'])
env.Append(LINKFLAGS=[
'-rdynamic'
])
if variant == 'debug':
env.Append(CCFLAGS=[
'-g'
])
elif variant == 'release':
if variant == 'release':
env.Append(CCFLAGS=[
'-O3',
'-fno-strict-aliasing'
])
if toolchain != 'msvc':
git = Beast.Git(env)
if git.exists:
id = '%s+%s.%s' % (git.tags, git.user, git.branch)
env.Append(CPPDEFINES={'GIT_COMMIT_ID' : '\'"%s"\'' % id })
if toolchain == 'clang':
if Beast.system.osx:
env.Replace(CC='clang', CXX='clang++', LINK='clang++')
@@ -370,6 +391,9 @@ def config_env(toolchain, variant, env):
env.Append(CPPDEFINES={
'_FORTIFY_SOURCE': 2
})
env.Append(CCFLAGS=[
'-O0'
])
elif toolchain == 'msvc':
env.Append (CPPPATH=[
@@ -459,14 +483,6 @@ def config_env(toolchain, variant, env):
#-------------------------------------------------------------------------------
def addSource(path, env, variant_dirs, CPPPATH=[]):
if CPPPATH:
env = env.Clone()
env.Prepend(CPPPATH=CPPPATH)
return env.Object(Beast.variantFile(path, variant_dirs))
#-------------------------------------------------------------------------------
# Configure the base construction environment
root_dir = Dir('#').srcnode().get_abspath() # Path to this SConstruct file
build_dir = os.path.join('build')
@@ -484,7 +500,7 @@ base.Append(CPPPATH=[
])
# Configure the toolchains, variants, default toolchain, and default target
variants = ['debug', 'release']
variants = ['debug', 'release', 'profile']
all_toolchains = ['clang', 'gcc', 'msvc']
if Beast.system.osx:
toolchains = ['clang']
@@ -505,7 +521,9 @@ else:
default_toolchain = 'clang'
else:
raise ValueError("Don't understand toolchains in " + str(toolchains))
default_variant = 'debug'
default_tu_style = 'unity'
default_variant = 'release'
default_target = None
for source in [
@@ -517,111 +535,230 @@ for source in [
PROTOCOUTDIR=os.path.join(build_dir, 'proto'),
PROTOCPYTHONOUTDIR=None)
#-------------------------------------------------------------------------------
class ObjectBuilder(object):
def __init__(self, env, variant_dirs):
self.env = env
self.variant_dirs = variant_dirs
self.objects = []
def add_source_files(self, *filenames, **kwds):
for filename in filenames:
env = self.env
if kwds:
env = env.Clone()
env.Prepend(**kwds)
o = env.Object(Beast.variantFile(filename, self.variant_dirs))
self.objects.append(o)
def list_sources(base, suffixes):
def _iter(base):
for parent, dirs, files in os.walk(base):
files = [f for f in files if not f[0] == '.']
dirs[:] = [d for d in dirs if not d[0] == '.']
for path in files:
path = os.path.join(parent, path)
r = os.path.splitext(path)
if r[1] and r[1] in suffixes:
yield os.path.normpath(path)
return list(_iter(base))
# Declare the targets
aliases = collections.defaultdict(list)
msvc_configs = []
for toolchain in all_toolchains:
for variant in variants:
# Configure this variant's construction environment
env = base.Clone()
config_env(toolchain, variant, env)
variant_name = '%s.%s' % (toolchain, variant)
variant_dir = os.path.join(build_dir, variant_name)
variant_dirs = {
os.path.join(variant_dir, 'src') :
'src',
os.path.join(variant_dir, 'proto') :
os.path.join (build_dir, 'proto'),
}
for dest, source in variant_dirs.iteritems():
env.VariantDir(dest, source, duplicate=0)
objects = []
objects.append(addSource('src/ripple/unity/app.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/app1.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/app2.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/app3.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/app4.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/app5.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/app6.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/app7.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/app8.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/app9.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/basics.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/beast.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/beastc.c', env, variant_dirs))
objects.append(addSource('src/ripple/unity/common.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/core.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/data.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/http.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/json.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/net.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/overlay.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/peerfinder.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/protobuf.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/ripple.proto.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/radmap.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/resource.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/rpcx.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/sitefiles.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/sslutil.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/testoverlay.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/types.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/validators.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/websocket.cpp', env, variant_dirs))
objects.append(addSource('src/ripple/unity/nodestore.cpp', env, variant_dirs, [
'src/leveldb/include',
#'src/hyperleveldb/include', # hyper
'src/rocksdb2/include',
]))
for tu_style in ['classic', 'unity']:
for toolchain in all_toolchains:
for variant in variants:
if variant == 'profile' and toolchain == 'msvc':
continue
# Configure this variant's construction environment
env = base.Clone()
config_env(toolchain, variant, env)
variant_name = '%s.%s' % (toolchain, variant)
if tu_style == 'classic':
variant_name += '.nounity'
variant_dir = os.path.join(build_dir, variant_name)
variant_dirs = {
os.path.join(variant_dir, 'src') :
'src',
os.path.join(variant_dir, 'proto') :
os.path.join (build_dir, 'proto'),
}
for dest, source in variant_dirs.iteritems():
env.VariantDir(dest, source, duplicate=0)
objects.append(addSource('src/ripple/unity/leveldb.cpp', env, variant_dirs, [
'src/leveldb/',
'src/leveldb/include',
'src/snappy/snappy',
'src/snappy/config',
]))
object_builder = ObjectBuilder(env, variant_dirs)
objects.append(addSource('src/ripple/unity/hyperleveldb.cpp', env, variant_dirs, [
'src/hyperleveldb',
'src/snappy/snappy',
'src/snappy/config',
]))
if tu_style == 'classic':
object_builder.add_source_files(
*list_sources('src/ripple/app', '.cpp'))
object_builder.add_source_files(
*list_sources('src/ripple/basics', '.cpp'))
object_builder.add_source_files(
*list_sources('src/ripple/core', '.cpp'))
object_builder.add_source_files(
*list_sources('src/ripple/crypto', '.cpp'))
object_builder.add_source_files(
*list_sources('src/ripple/json', '.cpp'))
object_builder.add_source_files(
*list_sources('src/ripple/net', '.cpp'))
object_builder.add_source_files(
*list_sources('src/ripple/overlay', '.cpp'))
object_builder.add_source_files(
*list_sources('src/ripple/peerfinder', '.cpp'))
object_builder.add_source_files(
*list_sources('src/ripple/protocol', '.cpp'))
object_builder.add_source_files(
*list_sources('src/ripple/shamap', '.cpp'))
object_builder.add_source_files(
*list_sources('src/ripple/nodestore', '.cpp'),
CPPPATH=[
'src/leveldb/include',
'src/rocksdb2/include',
'src/snappy/snappy',
'src/snappy/config',
])
else:
object_builder.add_source_files(
'src/ripple/unity/app.cpp',
'src/ripple/unity/app1.cpp',
'src/ripple/unity/app2.cpp',
'src/ripple/unity/app3.cpp',
'src/ripple/unity/app4.cpp',
'src/ripple/unity/app5.cpp',
'src/ripple/unity/app6.cpp',
'src/ripple/unity/app7.cpp',
'src/ripple/unity/app8.cpp',
'src/ripple/unity/app9.cpp',
'src/ripple/unity/core.cpp',
'src/ripple/unity/basics.cpp',
'src/ripple/unity/crypto.cpp',
'src/ripple/unity/net.cpp',
'src/ripple/unity/overlay.cpp',
'src/ripple/unity/peerfinder.cpp',
'src/ripple/unity/json.cpp',
'src/ripple/unity/protocol.cpp',
'src/ripple/unity/shamap.cpp',
)
objects.append(addSource('src/ripple/unity/rocksdb.cpp', env, variant_dirs, [
'src/rocksdb2',
'src/rocksdb2/include',
'src/snappy/snappy',
'src/snappy/config',
]))
object_builder.add_source_files(
'src/ripple/unity/nodestore.cpp',
CPPPATH=[
'src/leveldb/include',
'src/rocksdb2/include',
'src/snappy/snappy',
'src/snappy/config',
])
objects.append(addSource('src/ripple/unity/snappy.cpp', env, variant_dirs, [
'src/snappy/snappy',
'src/snappy/config',
]))
git_commit_tag = {}
if toolchain != 'msvc':
git = Beast.Git(env)
if git.exists:
id = '%s+%s.%s' % (git.tags, git.user, git.branch)
git_commit_tag = {'CPPDEFINES':
{'GIT_COMMIT_ID' : '\'"%s"\'' % id }}
if toolchain == "clang" and Beast.system.osx:
objects.append(addSource('src/ripple/unity/beastobjc.mm', env, variant_dirs))
object_builder.add_source_files(
'src/ripple/unity/git_id.cpp',
**git_commit_tag)
target = env.Program(
target = os.path.join(variant_dir, 'rippled'),
source = objects
object_builder.add_source_files(
'src/beast/beast/unity/hash_unity.cpp',
'src/ripple/unity/beast.cpp',
'src/ripple/unity/lz4.c',
'src/ripple/unity/protobuf.cpp',
'src/ripple/unity/ripple.proto.cpp',
'src/ripple/unity/resource.cpp',
'src/ripple/unity/rpcx.cpp',
'src/ripple/unity/server.cpp',
'src/ripple/unity/validators.cpp',
'src/ripple/unity/websocket.cpp'
)
if toolchain == default_toolchain and variant == default_variant:
default_target = target
install_target = env.Install (build_dir, source = default_target)
env.Alias ('install', install_target)
env.Default (install_target)
aliases['all'].extend(install_target)
if toolchain == 'msvc':
config = env.VSProjectConfig(variant, 'x64', target, env)
msvc_configs.append(config)
if toolchain in toolchains:
aliases['all'].extend(target)
aliases[variant].extend(target)
aliases[toolchain].extend(target)
env.Alias(variant_name, target)
object_builder.add_source_files(
'src/ripple/unity/beastc.c',
CCFLAGS = ([] if toolchain == 'msvc' else ['-Wno-array-bounds']))
if 'gcc' in toolchain:
no_uninitialized_warning = {'CCFLAGS': ['-Wno-maybe-uninitialized']}
else:
no_uninitialized_warning = {}
object_builder.add_source_files(
'src/ripple/unity/ed25519.c',
CPPPATH=[
'src/ed25519-donna',
]
)
object_builder.add_source_files(
'src/ripple/unity/leveldb.cpp',
CPPPATH=[
'src/leveldb/',
'src/leveldb/include',
'src/snappy/snappy',
'src/snappy/config',
],
**no_uninitialized_warning
)
object_builder.add_source_files(
'src/ripple/unity/hyperleveldb.cpp',
CPPPATH=[
'src/hyperleveldb',
'src/snappy/snappy',
'src/snappy/config',
],
**no_uninitialized_warning
)
object_builder.add_source_files(
'src/ripple/unity/rocksdb.cpp',
CPPPATH=[
'src/rocksdb2',
'src/rocksdb2/include',
'src/snappy/snappy',
'src/snappy/config',
],
**no_uninitialized_warning
)
object_builder.add_source_files(
'src/ripple/unity/snappy.cpp',
CCFLAGS=([] if toolchain == 'msvc' else ['-Wno-unused-function']),
CPPPATH=[
'src/snappy/snappy',
'src/snappy/config',
]
)
if toolchain == "clang" and Beast.system.osx:
object_builder.add_source_files('src/ripple/unity/beastobjc.mm')
target = env.Program(
target=os.path.join(variant_dir, 'rippled'),
source=object_builder.objects
)
if tu_style == default_tu_style:
if toolchain == default_toolchain and (
variant == default_variant):
default_target = target
install_target = env.Install (build_dir, source=default_target)
env.Alias ('install', install_target)
env.Default (install_target)
aliases['all'].extend(install_target)
if toolchain == 'msvc':
config = env.VSProjectConfig(variant, 'x64', target, env)
msvc_configs.append(config)
if toolchain in toolchains:
aliases['all'].extend(target)
aliases[toolchain].extend(target)
if toolchain in toolchains:
aliases[variant].extend(target)
env.Alias(variant_name, target)
for key, value in aliases.iteritems():
env.Alias(key, value)
@@ -632,3 +769,32 @@ vcxproj = base.VSProject(
VSPROJECT_ROOT_DIRS = ['src/beast', 'src', '.'],
VSPROJECT_CONFIGS = msvc_configs)
base.Alias('vcxproj', vcxproj)
#-------------------------------------------------------------------------------
# Adds a phony target to the environment that always builds
# See: http://www.scons.org/wiki/PhonyTargets
def PhonyTargets(env = None, **kw):
if not env: env = DefaultEnvironment()
for target, action in kw.items():
env.AlwaysBuild(env.Alias(target, [], action))
# Build the list of rippled source files that hold unit tests
def do_count(target, source, env):
def list_testfiles(base, suffixes):
def _iter(base):
for parent, _, files in os.walk(base):
for path in files:
path = os.path.join(parent, path)
r = os.path.splitext(path)
if r[1] in suffixes:
if r[0].endswith('.test'):
yield os.path.normpath(path)
return list(_iter(base))
testfiles = list_testfiles(os.path.join('src', 'ripple'), env.get('CPPSUFFIXES'))
lines = 0
for f in testfiles:
lines = lines + sum(1 for line in open(f))
print "Total unit test lines: %d" % lines
PhonyTargets(env, count = do_count)

77
appveyor.yml Normal file
View File

@@ -0,0 +1,77 @@
# Set environment variables.
environment:
PYTHON: C:/Python27-x64
# We bundle up protoc.exe and only the parts of boost and openssl we need so
# that it's a small download. We also use appveyor's free cache, avoiding fees
# downloading from S3 each time.
# TODO: script to create this package.
RIPPLED_DEPS_URL: https://s3-ap-northeast-1.amazonaws.com/history-replay/rippled_deps.zip
# Other dependencies we just download each time.
PIP_URL: https://bootstrap.pypa.io/get-pip.py
PYWIN32_URL: https://downloads.sourceforge.net/project/pywin32/pywin32/Build%20219/pywin32-219.win-amd64-py2.7.exe
# Scons honours these environment variables, setting the include/lib paths.
BOOST_ROOT: C:/rippled_deps/boost
OPENSSL_ROOT: C:/rippled_deps/openssl
# At the end of each successful build we cache this directory. It must be less
# than 100MB total compressed.
cache:
- 'C:\\rippled_deps'
# This means we'll download a zip of the branch we want, rather than the full
# history.
shallow_clone: true
install:
# We want easy_install, python and protoc.exe on PATH.
- SET PATH=%PYTHON%;%PYTHON%/Scripts;C:/rippled_deps;%PATH%
# `ps` prefix means the command is executed by powershell.
- ps: Start-FileDownload $env:PIP_URL
- ps: Start-FileDownload $env:PYWIN32_URL
# Installing pip will install setuptools/easy_install.
- python get-pip.py
# Pip has some problems installing scons on windows so we use easy install.
- easy_install scons
# Scons has problems with parallel builds on windows without pywin32.
- easy_install pywin32-219.win-amd64-py2.7.exe
# (easy_install can do headless installs of .exe wizards)
# Download dependencies if appveyor didn't restore them from the cache.
# Use 7zip to unzip.
- ps: |
if (-not(Test-Path 'C:/rippled_deps')) {
Start-FileDownload "$env:RIPPLED_DEPS_URL"
7z x rippled_deps.zip -oC:\ -y > $null
}
# TODO: This is giving me grief
# artifacts:
# # Save rippled.exe in the cloud after each build.
# - path: "build\\rippled.exe"
build_script:
# We set the environment variables needed to put compilers on the PATH.
- '"%VS120COMNTOOLS%../../VC/vcvarsall.bat" x86_amd64'
# Show which version of the compiler we are using.
- cl
- scons msvc.debug -j%NUMBER_OF_PROCESSORS%
after_build:
# Put our executable in a place where npm test can find it.
- ps: cp build/msvc.debug/rippled.exe build
- ps: ls build
test_script:
# Run the unit tests
- build\\rippled --unittest
# Run the integration tests
- npm install
- npm test

View File

@@ -7,11 +7,13 @@ import os
from ripple.ledger import LedgerNumber
from ripple.util import File
from ripple.util import Log
from ripple.util import PrettyPrint
from ripple.util import Range
from ripple.util.Function import Function
NAME = 'LedgerTool'
VERSION = '0.1'
NONE = '(none)'
_parser = argparse.ArgumentParser(
prog=NAME,
@@ -56,7 +58,14 @@ _parser.add_argument(
)
_parser.add_argument(
'--display', '-d',
'--database', '-d',
nargs='*',
default=NONE,
help='Specify a database.',
)
_parser.add_argument(
'--display',
help='Specify a function to display ledgers.',
)
@@ -102,6 +111,12 @@ _parser.add_argument(
help='If true, display times in UTC rather than local time.',
)
_parser.add_argument(
'--validations',
default=3,
help='The number of validations needed before considering a ledger valid.',
)
_parser.add_argument(
'--version',
action='version',
@@ -130,6 +145,7 @@ _parser.add_argument(
# Read the arguments from the command line.
ARGS = _parser.parse_args()
ARGS.NONE = NONE
Log.VERBOSE = ARGS.verbose
@@ -159,10 +175,13 @@ if ARGS.window < 0:
raise ValueError('Window cannot be negative: --window=%d' %
ARGS.window)
_loaders = bool(ARGS.server) + bool(ARGS.rippled)
PrettyPrint.INDENT = (ARGS.indent * ' ')
_loaders = (ARGS.database != NONE) + bool(ARGS.rippled) + bool(ARGS.server)
if not _loaders:
ARGS.rippled = 'rippled'
elif _loaders > 1:
raise ValueError('At most one of --rippled and --server must be specified')
raise ValueError('At most one of --database, --rippled and --server '
'may be specified')

View File

@@ -0,0 +1,78 @@
from __future__ import absolute_import, division, print_function, unicode_literals
import json
import os
import subprocess
from ripple.ledger.Args import ARGS
from ripple.util import ConfigFile
from ripple.util import Database
from ripple.util import File
from ripple.util import Log
from ripple.util import Range
LEDGER_QUERY = """
SELECT
L.*, count(1) validations
FROM
(select LedgerHash, LedgerSeq from Ledgers ORDER BY LedgerSeq DESC) L
JOIN Validations V
ON (V.LedgerHash = L.LedgerHash)
GROUP BY L.LedgerHash
HAVING validations >= {validation_quorum}
ORDER BY 2;
"""
COMPLETE_QUERY = """
SELECT
L.LedgerSeq, count(*) validations
FROM
(select LedgerHash, LedgerSeq from Ledgers ORDER BY LedgerSeq) L
JOIN Validations V
ON (V.LedgerHash = L.LedgerHash)
GROUP BY L.LedgerHash
HAVING validations >= :validation_quorum
ORDER BY 2;
"""
_DATABASE_NAME = 'ledger.db'
USE_PLACEHOLDERS = False
class DatabaseReader(object):
def __init__(self, config):
assert ARGS.database != ARGS.NONE
database = ARGS.database or config['database_path']
if not database.endswith(_DATABASE_NAME):
database = os.path.join(database, _DATABASE_NAME)
if USE_PLACEHOLDERS:
cursor = Database.fetchall(
database, COMPLETE_QUERY, config)
else:
cursor = Database.fetchall(
database, LEDGER_QUERY.format(**config), {})
self.complete = [c[1] for c in cursor]
def name_to_ledger_index(self, ledger_name, is_full=False):
if not self.complete:
return None
if ledger_name == 'closed':
return self.complete[-1]
if ledger_name == 'current':
return None
if ledger_name == 'validated':
return self.complete[-1]
def get_ledger(self, name, is_full=False):
cmd = ['ledger', str(name)]
if is_full:
cmd.append('full')
response = self._command(*cmd)
result = response.get('ledger')
if result:
return result
error = response['error']
etext = _ERROR_TEXT.get(error)
if etext:
error = '%s (%s)' % (etext, error)
Log.fatal(_ERROR_TEXT.get(error, error))

View File

@@ -1,21 +0,0 @@
from __future__ import absolute_import, division, print_function, unicode_literals
from ripple.ledger.Args import ARGS
from functools import wraps
import json
def pretty_print(item):
return json.dumps(item,
sort_keys=True,
indent=ARGS.indent,
separators=(',', ': '))
def pretty(f):
""""A decorator on a function that makes its results pretty """
@wraps(f)
def wrapper(*args, **kwds):
result = list(f(*args, **kwds))
return pretty_print(result)
return wrapper

View File

@@ -22,13 +22,13 @@ _ERROR_TEXT = {
_DEFAULT_ERROR_ = "Couldn't connect to server."
class RippledReader(object):
def __init__(self):
def __init__(self, config):
fname = File.normalize(ARGS.rippled)
if not os.path.exists(fname):
raise Exception('No rippled found at %s.' % fname)
self.cmd = [fname]
if ARGS.config:
self.cmd.extend(['--conf', _normalize(ARGS.config)])
self.cmd.extend(['--conf', File.normalize(ARGS.config)])
self.info = self._command('server_info')['info']
c = self.info.get('complete_ledgers')
if c == 'empty':

View File

@@ -3,17 +3,21 @@ from __future__ import absolute_import, division, print_function, unicode_litera
import json
import os
from ripple.ledger import RippledReader, ServerReader
from ripple.ledger import DatabaseReader, RippledReader
from ripple.ledger.Args import ARGS
from ripple.util.FileCache import FileCache
from ripple.util import ConfigFile
from ripple.util import File
from ripple.util import Range
class Server(object):
def __init__(self):
if ARGS.rippled:
reader = RippledReader.RippledReader()
cfg_file = File.normalize(ARGS.config or 'rippled.cfg')
self.config = ConfigFile.read(open(cfg_file))
if ARGS.database != ARGS.NONE:
reader = DatabaseReader.DatabaseReader(self.config)
else:
reader = ServerReader.ServerReader()
reader = RippledReader.RippledReader(self.config)
self.reader = reader
self.complete = reader.complete
@@ -23,8 +27,7 @@ class Server(object):
'current': reader.name_to_ledger_index('current'),
'validated': reader.name_to_ledger_index('validated'),
'first': self.complete[0] if self.complete else None,
'last': self.complete[-1] if self.complete else None
,
'last': self.complete[-1] if self.complete else None,
}
self.__dict__.update(names)
self.ledgers = sorted(Range.join_ranges(*ARGS.ledgers, **names))

View File

@@ -1,5 +1,5 @@
from __future__ import absolute_import, division, print_function, unicode_literals
class ServerReader(object):
def __init__(self, server):
def __init__(self, config):
raise ValueError('Direct server connections are not yet implemented.')

View File

@@ -1,9 +1,9 @@
from __future__ import absolute_import, division, print_function, unicode_literals
from ripple.ledger.Args import ARGS
from ripple.ledger.PrettyPrint import pretty_print
from ripple.util import Log
from ripple.util import Range
from ripple.util.PrettyPrint import pretty_print
SAFE = True

View File

@@ -1,17 +1,17 @@
from __future__ import absolute_import, division, print_function, unicode_literals
from ripple.ledger.Args import ARGS
from ripple.ledger.PrettyPrint import pretty_print
from ripple.util import Log
from ripple.util import Range
from ripple.util.PrettyPrint import pretty_print
SAFE = True
HELP = 'info - return server_info'
def info(server):
Log.out('first = ', server.first)
Log.out('last = ', server.last)
Log.out('first =', server.first)
Log.out('last =', server.last)
Log.out('closed =', server.closed)
Log.out('current =', server.current)
Log.out('validated =', server.validated)

View File

@@ -12,5 +12,4 @@ HELP = """print
Print the ledgers to stdout. The default command."""
def run_print(server):
for x in ARGS.display(server, SearchLedgers.search(server)):
print(x)
ARGS.display(print, server, SearchLedgers.search(server))

View File

@@ -5,11 +5,11 @@ from functools import wraps
import jsonpath_rw
from ripple.ledger.Args import ARGS
from ripple.ledger.PrettyPrint import pretty_print
from ripple.util import Dict
from ripple.util import Log
from ripple.util import Range
from ripple.util.Decimal import Decimal
from ripple.util.PrettyPrint import pretty_print, Streamer
TRANSACT_FIELDS = (
'accepted',
@@ -33,33 +33,30 @@ LEDGER_FIELDS = (
def _dict_filter(d, keys):
return dict((k, v) for (k, v) in d.items() if k in keys)
def ledger_number(server, numbers):
yield Range.to_string(numbers)
def ledger_number(print, server, numbers):
print(Range.to_string(numbers))
def display(f):
"""A decorator for displays that just print JSON"""
@wraps(f)
def wrapper(server, numbers, *args, **kwds):
def wrapper(printer, server, numbers, *args):
streamer = Streamer(printer=printer)
for number in numbers:
ledger = server.get_ledger(number, ARGS.full)
if ledger:
yield pretty_print(f(ledger, *args, **kwds))
streamer.add(number, f(ledger, *args))
streamer.finish()
return wrapper
def json(f):
"""A decorator for displays that print JSON, extracted by a path"""
def extractor(f):
@wraps(f)
def wrapper(server, numbers, path, *args, **kwds):
def wrapper(printer, server, numbers, *paths):
try:
path_expr = jsonpath_rw.parse(path)
find = jsonpath_rw.parse('|'.join(paths)).find
except:
raise ValueError("Can't understand jsonpath '%s'." % path)
for number in numbers:
ledger = server.get_ledger(number, ARGS.full)
if ledger:
finds = path_expr.find(ledger)
yield pretty_print(f(finds, *args, **kwds))
def fn(ledger, *args):
return f(find(ledger), *args)
display(fn)(printer, server, numbers)
return wrapper
@display
@@ -67,6 +64,7 @@ def ledger(ledger, full=False):
if ARGS.full:
if full:
return ledger
ledger = Dict.prune(ledger, 1, False)
return _dict_filter(ledger, LEDGER_FIELDS)
@@ -79,11 +77,11 @@ def prune(ledger, level=1):
def transact(ledger):
return _dict_filter(ledger, TRANSACT_FIELDS)
@json
@extractor
def extract(finds):
return dict((str(f.full_path), str(f.value)) for f in finds)
@json
@extractor
def sum(finds):
d = Decimal()
for f in finds:

View File

@@ -0,0 +1,54 @@
from __future__ import absolute_import, division, print_function, unicode_literals
import json
"""Ripple has a proprietary format for their .cfg files, so we need a reader for
them."""
def read(lines):
sections = []
section = []
for line in lines:
line = line.strip()
if (not line) or line[0] == '#':
continue
if line.startswith('['):
if section:
sections.append(section)
section = []
section.append(line)
if section:
sections.append(section)
result = {}
for section in sections:
option = section.pop(0)
assert section, ('No value for option "%s".' % option)
assert option.startswith('[') and option.endswith(']'), (
'No option name in block "%s"' % p[0])
option = option[1:-1]
assert option not in result, 'Duplicate option "%s".' % option
subdict = {}
items = []
for part in section:
if '=' in part:
assert not items, 'Dictionary mixed with list.'
k, v = part.split('=', 1)
assert k not in subdict, 'Repeated dictionary entry ' + k
subdict[k] = v
else:
assert not subdict, 'List mixed with dictionary.'
if part.startswith('{'):
items.append(json.loads(part))
else:
words = part.split()
if len(words) > 1:
items.append(words)
else:
items.append(part)
if len(items) == 1:
result[option] = items[0]
else:
result[option] = items or subdict
return result

View File

@@ -0,0 +1,12 @@
from __future__ import absolute_import, division, print_function, unicode_literals
import sqlite3
def fetchall(database, query, kwds):
conn = sqlite3.connect(database)
try:
cursor = conn.execute(query, kwds)
return cursor.fetchall()
finally:
conn.close()

View File

@@ -20,7 +20,10 @@ REMAPPINGS = {
}
def eval_arguments(args):
tokens = tokenize.generate_tokens(StringIO(args or '()').readline)
args = args.strip()
if not args or (args == '()'):
return ()
tokens = list(tokenize.generate_tokens(StringIO(args).readline))
def remap():
for type, name, _, _, _ in tokens:
if type == tokenize.NAME and name not in REMAPPINGS:
@@ -30,7 +33,11 @@ def eval_arguments(args):
untok = tokenize.untokenize(remap())
if untok[1:-1].strip():
untok = untok[:-1] + ',)' # Force a tuple.
return eval(untok, REMAPPINGS)
try:
return eval(untok, REMAPPINGS)
except Exception as e:
raise ValueError('Couldn\'t evaluate expression "%s" (became "%s"), '
'error "%s"' % (args, untok, str(e)))
class Function(object):
def __init__(self, desc='', default_path=''):
@@ -52,10 +59,10 @@ class Function(object):
default_path += '.'
self.function = default_path + self.function
p, m = self.function.rsplit('.', 1)
try:
mod = importlib.import_module(p)
except:
raise ValueError('Can\'t find Python module "%s"' % p)
mod = importlib.import_module(p)
# Errors in modules are swallowed here.
# except:
# raise ValueError('Can\'t find Python module "%s"' % p)
try:
self.function = getattr(mod, m)

View File

@@ -0,0 +1,42 @@
from __future__ import absolute_import, division, print_function, unicode_literals
from functools import wraps
import json
SEPARATORS = ',', ': '
INDENT = ' '
def pretty_print(item):
return json.dumps(item,
sort_keys=True,
indent=len(INDENT),
separators=SEPARATORS)
class Streamer(object):
def __init__(self, printer=print):
# No automatic spacing or carriage returns.
self.printer = lambda *args: printer(*args, end='', sep='')
self.first_key = True
def add(self, key, value):
if self.first_key:
self.first_key = False
self.printer('{')
else:
self.printer(',')
self.printer('\n', INDENT, '"', str(key), '": ')
pp = pretty_print(value).splitlines()
if len(pp) > 1:
for i, line in enumerate(pp):
if i > 0:
self.printer('\n', INDENT)
self.printer(line)
else:
self.printer(pp[0])
def finish(self):
if not self.first_key:
self.first_key = True
self.printer('\n}')

View File

@@ -0,0 +1,163 @@
from __future__ import absolute_import, division, print_function, unicode_literals
from ripple.util import ConfigFile
from unittest import TestCase
class test_ConfigFile(TestCase):
def test_trivial(self):
self.assertEquals(ConfigFile.read(''), {})
def test_full(self):
self.assertEquals(ConfigFile.read(FULL.splitlines()), RESULT)
RESULT = {
'websocket_port': '6206',
'database_path': '/development/alpha/db',
'sntp_servers':
['time.windows.com', 'time.apple.com', 'time.nist.gov', 'pool.ntp.org'],
'validation_seed': 'sh1T8T9yGuV7Jb6DPhqSzdU2s5LcV',
'node_size': 'medium',
'rpc_startup': {
'command': 'log_level',
'severity': 'debug'},
'ips': ['r.ripple.com', '51235'],
'node_db': {
'file_size_mult': '2',
'file_size_mb': '8',
'cache_mb': '256',
'path': '/development/alpha/db/rocksdb',
'open_files': '2000',
'type': 'RocksDB',
'filter_bits': '12'},
'peer_port': '53235',
'ledger_history': 'full',
'rpc_ip': '127.0.0.1',
'websocket_public_ip': '0.0.0.0',
'rpc_allow_remote': '0',
'validators':
[['n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7', 'RL1'],
['n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj', 'RL2'],
['n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C', 'RL3'],
['n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS', 'RL4'],
['n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA', 'RL5']],
'debug_logfile': '/development/alpha/debug.log',
'websocket_public_port': '5206',
'peer_ip': '0.0.0.0',
'rpc_port': '5205',
'validation_quorum': '3',
'websocket_ip': '127.0.0.1'}
FULL = """
[ledger_history]
full
# Allow other peers to connect to this server.
#
[peer_ip]
0.0.0.0
[peer_port]
53235
# Allow untrusted clients to connect to this server.
#
[websocket_public_ip]
0.0.0.0
[websocket_public_port]
5206
# Provide trusted websocket ADMIN access to the localhost.
#
[websocket_ip]
127.0.0.1
[websocket_port]
6206
# Provide trusted json-rpc ADMIN access to the localhost.
#
[rpc_ip]
127.0.0.1
[rpc_port]
5205
[rpc_allow_remote]
0
[node_size]
medium
# This is primary persistent datastore for rippled. This includes transaction
# metadata, account states, and ledger headers. Helpful information can be
# found here: https://ripple.com/wiki/NodeBackEnd
[node_db]
type=RocksDB
path=/development/alpha/db/rocksdb
open_files=2000
filter_bits=12
cache_mb=256
file_size_mb=8
file_size_mult=2
[database_path]
/development/alpha/db
# This needs to be an absolute directory reference, not a relative one.
# Modify this value as required.
[debug_logfile]
/development/alpha/debug.log
[sntp_servers]
time.windows.com
time.apple.com
time.nist.gov
pool.ntp.org
# Where to find some other servers speaking the Ripple protocol.
#
[ips]
r.ripple.com 51235
# The latest validators can be obtained from
# https://ripple.com/ripple.txt
#
[validators]
n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7 RL1
n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj RL2
n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C RL3
n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS RL4
n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA RL5
# Ditto.
[validation_quorum]
3
[validation_seed]
sh1T8T9yGuV7Jb6DPhqSzdU2s5LcV
# Turn down default logging to save disk space in the long run.
# Valid values here are trace, debug, info, warning, error, and fatal
[rpc_startup]
{ "command": "log_level", "severity": "debug" }
# Configure SSL for WebSockets. Not enabled by default because not everybody
# has an SSL cert on their server, but if you uncomment the following lines and
# set the path to the SSL certificate and private key the WebSockets protocol
# will be protected by SSL/TLS.
#[websocket_secure]
#1
#[websocket_ssl_cert]
#/etc/ssl/certs/server.crt
#[websocket_ssl_key]
#/etc/ssl/private/server.key
# Defaults to 0 ("no") so that you can use self-signed SSL certificates for
# development, or internally.
#[ssl_verify]
#0
""".strip()

View File

@@ -0,0 +1,56 @@
from __future__ import absolute_import, division, print_function, unicode_literals
from ripple.util import PrettyPrint
from unittest import TestCase
class test_PrettyPrint(TestCase):
def setUp(self):
self._results = []
self.printer = PrettyPrint.Streamer(printer=self.printer)
def printer(self, *args, **kwds):
self._results.extend(args)
def run_test(self, expected, *args):
for i in range(0, len(args), 2):
self.printer.add(args[i], args[i + 1])
self.printer.finish()
self.assertEquals(''.join(self._results), expected)
def test_simple_printer(self):
self.run_test(
'{\n "foo": "bar"\n}',
'foo', 'bar')
def test_multiple_lines(self):
self.run_test(
'{\n "foo": "bar",\n "baz": 5\n}',
'foo', 'bar', 'baz', 5)
def test_multiple_lines(self):
self.run_test(
"""
{
"foo": {
"bar": 1,
"baz": true
},
"bang": "bing"
}
""".strip(), 'foo', {'bar': 1, 'baz': True}, 'bang', 'bing')
def test_multiple_lines_with_list(self):
self.run_test(
"""
{
"foo": [
"bar",
1
],
"baz": [
23,
42
]
}
""".strip(), 'foo', ['bar', 1], 'baz', [23, 42])

133
bin/stop-test.js Normal file
View File

@@ -0,0 +1,133 @@
/* -------------------------------- REQUIRES -------------------------------- */
var child = require("child_process");
var assert = require("assert");
/* --------------------------------- CONFIG --------------------------------- */
if (process.argv[2] == null) {
[
'Usage: ',
'',
' `node bin/stop-test.js i,j [rippled_path] [rippled_conf]`',
'',
' Launch rippled and stop it after n seconds for all n in [i, j}',
' For all even values of n launch rippled with `--fg`',
' For values of n where n % 3 == 0 launch rippled with `--fg`\n',
'Examples: ',
'',
' $ node bin/stop-test.js 5,10',
(' $ node bin/stop-test.js 1,4 ' +
'build/clang.debug/rippled $HOME/.confs/rippled.cfg')
]
.forEach(function(l){console.log(l)});
process.exit();
} else {
var testRange = process.argv[2].split(',').map(Number);
var rippledPath = process.argv[3] || 'build/rippled'
var rippledConf = process.argv[4] || 'rippled.cfg'
}
var options = {
env: process.env,
stdio: 'ignore' // we could dump the child io when it fails abnormally
};
// default args
var conf_args = ['--conf='+rippledConf];
var start_args = conf_args.concat([/*'--net'*/])
var stop_args = conf_args.concat(['stop']);
/* --------------------------------- HELPERS -------------------------------- */
function start(args) {
return child.spawn(rippledPath, args, options);
}
function stop(rippled) { child.execFile(rippledPath, stop_args, options)}
function secs_l8r(ms, f) {setTimeout(f, ms * 1000); }
function show_results_and_exit(results) {
console.log(JSON.stringify(results, undefined, 2));
process.exit();
}
var timeTakes = function (range) {
function sumRange(n) {return (n+1) * n /2}
var ret = sumRange(range[1]);
if (range[0] > 1) {
ret = ret - sumRange(range[0] - 1)
}
var stopping = (range[1] - range[0]) * 0.5;
return ret + stopping;
}
/* ---------------------------------- TEST ---------------------------------- */
console.log("Test will take ~%s seconds", timeTakes(testRange));
(function oneTest(n /* seconds */, results) {
if (n >= testRange[1]) {
// show_results_and_exit(results);
console.log(JSON.stringify(results, undefined, 2));
oneTest(testRange[0], []);
return;
}
var args = start_args;
if (n % 2 == 0) {args = args.concat(['--fg'])}
if (n % 3 == 0) {args = args.concat(['--net'])}
var result = {args: args, alive_for: n};
results.push(result);
console.log("\nLaunching `%s` with `%s` for %d seconds",
rippledPath, JSON.stringify(args), n);
rippled = start(args);
console.log("Rippled pid: %d", rippled.pid);
// defaults
var b4StopSent = false;
var stopSent = false;
var stop_took = null;
rippled.once('exit', function(){
if (!stopSent && !b4StopSent) {
console.warn('\nRippled exited itself b4 stop issued');
process.exit();
};
// The io handles close AFTER exit, may have implications for
// `stdio:'inherit'` option to `child.spawn`.
rippled.once('close', function() {
result.stop_took = (+new Date() - stop_took) / 1000; // seconds
console.log("Stopping after %d seconds took %s seconds",
n, result.stop_took);
oneTest(n+1, results);
});
});
secs_l8r(n, function(){
console.log("Stopping rippled after %d seconds", n);
// possible race here ?
// seems highly unlikely, but I was having issues at one point
b4StopSent=true;
stop_took = (+new Date());
// when does `exit` actually get sent?
stop();
stopSent=true;
// Sometimes we want to attach with a debugger.
if (process.env.ABORT_TESTS_ON_STALL != null) {
// We wait 30 seconds, and if it hasn't stopped, we abort the process
secs_l8r(30, function() {
if (result.stop_took == null) {
console.log("rippled has stalled");
process.exit();
};
});
}
})
}(testRange[0], []));

View File

@@ -6,21 +6,23 @@
#
# Contents
#
# 1. Peer Networking
# 1. Server
#
# 2. Websocket Networking
# 2. Peer Protocol
#
# 3. RPC Networking
# 3. SMS Gateway
#
# 4. SMS Gateway
# 4. Ripple Protocol
#
# 5. Ripple Protcol
# 5. HTTPS Client
#
# 6. HTTPS Client
# 6. Database
#
# 7. Database
# 7. Diagnostics
#
# 8. Diagnostics
# 8. Voting
#
# 9. Example Settings
#
#-------------------------------------------------------------------------------
#
@@ -42,19 +44,235 @@
# or Mac style end of lines. Blank lines and lines beginning with '#' are
# ignored. Undefined sections are reserved. No escapes are currently defined.
#
# Notation
#
# In this document a simple BNF notation is used. Angle brackets denote
# required elements, square brackets denote optional elements, and single
# quotes indicate string literals. A vertical bar separating 1 or more
# elements is a logical "or"; Any one of the elements may be chosen.
# Parenthesis are notational only, and used to group elements, they are not
# part of the syntax unless they appear in quotes. White space may always
# appear between elements, it has no effect on values.
#
# <key> A required identifier
# '=' The equals sign character
# | Logical "or"
# ( ) Used for grouping
#
#
# An identifier is a string of upper or lower case letters, digits, or
# underscores subject to the requirement that the first character of an
# identifier must be a letter. Identifiers are not case sensitive (but
# values may be).
#
# Some configuration sections contain key/value pairs. A line containing
# a key/value pair has this syntax:
#
# <identifier> '=' <value>
#
# Depending on the section and key, different value types are possible:
#
# <integer> A signed integer
# <unsigned> An unsigned integer
# <flag> A boolean. 1 = true/yes/on, 0 = false/no/off.
#
# Consult the documentation on the key in question to determine the possible
# value types.
#
#
#
#-------------------------------------------------------------------------------
#
# 1. Peer Networking
# 1. Server
#
#-------------------
#----------
#
#
#
# rippled offers various server protocols to clients making inbound
# connections. The listening ports rippled uses are "universal" ports
# which may be configured to handshake in one or more of the available
# supported protocols. These universal ports simplify administration:
# A single open port can be used for multiple protocols.
#
# NOTE At least one server port must be defined in order
# to accept incoming network connections.
#
#
# [server]
#
# A list of port names and key/value pairs. A port name must start with a
# letter and contain only letters and numbers. The name is not case-sensitive.
# For each name in this list, rippled will look for a configuration file
# section with the same name and use it to create a listening port. The
# name is informational only; the choice of name does not affect the function
# of the listening port.
#
# Key/value pairs specified in this section are optional, and apply to all
# listening ports unless the port overrides the value in its section. They
# may be considered default values.
#
# Suggestion:
#
# To avoid a conflict with port names and future configuration sections,
# we recommend prepending "port_" to the port name. This prefix is not
# required, but suggested.
#
# This example defines two ports with different port numbers and settings:
#
# [server]
# port_public
# port_private
# port = 80
#
# [port_public]
# ip=0.0.0.0
# port = 443
# protocol=peer,https
#
# [port_private]
# ip=127.0.0.1
# protocol=http
#
# When rippled is used as a command line client (for example, issuing a
# server stop command), the first port advertising the http or https
# protocol will be used to make the connection.
#
#
#
# [<name>]
#
# A series of key/value pairs that define the settings for the port with
# the corresponding name. These keys are possible:
#
# ip = <IP-address>
#
# Required. Determines the IP address of the network interface to bind
# to. To bind to all available interfaces, uses 0.0.0.0
#
# port = <number>
#
# Required. Sets the port number to use for this port.
#
# protocol = [ http, https, peer ]
#
# Required. A comma-separated list of protocols to support:
#
# http JSON-RPC over HTTP
# https JSON-RPC over HTTPS
# ws Websockets
# wss Secure Websockets
# peer Peer Protocol
#
# Restrictions:
#
# Only one port may be configured to support the peer protocol.
# A port cannot have websocket and non websocket protocols at the
# same time. It is possible have both Websockets and Secure Websockets
# together in one port.
#
# NOTE If no ports support the peer protocol, rippled cannot
# receive incoming peer connections or become a superpeer.
#
# user = <text>
# password = <text>
#
# When set, these credentials will be required on HTTP/S requests.
# The credentials must be provided using HTTP's Basic Authentication
# headers. If either or both fields are empty, then no credentials are
# required. IP address restrictions, if any, will be checked in addition
# to the credentials specified here.
#
# When acting in the client role, rippled will supply these credentials
# using HTTP's Basic Authentication headers when making outbound HTTP/S
# requests.
#
# admin = no | allow
#
# Controls whether or not administrative commands are allowed. These
# commands may be issued over http, https, ws, or wss if configured
# on the port. If unspecified, the default is to not allow
# administrative commands.
#
# admin_user = <text>
# admin_password = <text>
#
# When set, clients must provide these credentials in the submitted
# JSON for any administrative command requests submitted to the HTTP/S,
# WS, or WSS protocol interfaces. If administrative commands are
# disabled for a port, these credentials have no effect.
#
# When acting in the client role, rippled will supply these credentials
# in the submitted JSON for any administrative command requests when
# invoking JSON-RPC commands on remote servers.
#
# ssl_key = <filename>
# ssl_cert = <filename>
# ssl_chain = <filename>
#
# Use the specified files when configuring SSL on the port.
#
# NOTE If no files are specified and secure protocols are selected,
# rippled will generate an internal self-signed certificate.
#
# The files have these meanings:
#
# ssl_key
#
# Specifies the filename holding the SSL key in PEM format.
#
# ssl_cert
#
# Specifies the path to the SSL certificate file in PEM format.
# This is not needed if the chain includes it.
#
# ssl_chain
#
# If you need a certificate chain, specify the path to the
# certificate chain here. The chain may include the end certificate.
#
#
#
# [rpc_admin_allow]
#
# Specify a list of IP addresses allowed to have admin access. One per line.
# If you want to test the output of non-admin commands add this section and
# just put an ip address not under your control.
# Defaults to 127.0.0.1.
#
#
#
# [rpc_startup]
#
# Specify a list of RPC commands to run at startup.
#
# Examples:
# { "command" : "server_info" }
# { "command" : "log_level", "partition" : "ripplecalc", "severity" : "trace" }
#
#
#
# [websocket_ping_frequency]
#
# <number>
#
# The amount of time to wait in seconds, before sending a websocket 'ping'
# message. Ping messages are used to determine if the remote end of the
# connection is no longer available.
#
#
#
#-------------------------------------------------------------------------------
#
# 2. Peer Protocol
#
#-----------------
#
# These settings control security and access attributes of the Peer to Peer
# server section of the rippled process. Peer Networking implements the
# server section of the rippled process. Peer Protocol implements the
# Ripple Payment protocol. It is over peer connections that transactions
# and validations are passed from to machine to machine, to make up the
# components of closed ledgers.
# and validations are passed from to machine to machine, to determine the
# contents of validated ledgers.
#
#
#
@@ -93,40 +311,6 @@
#
#
#
# [peer_ip]
#
# IP address or domain to bind to allow external connections from peers.
# Defaults to not binding, which disallows external connections from peers.
#
# Examples: 0.0.0.0 - Bind on all interfaces.
#
#
#
# [peer_port]
#
# If peer_ip is supplied, corresponding port to bind to for peer connections.
#
#
#
# [peer_port_proxy]
#
# An optional, additional listening port number for peers. Incoming
# connections on this port will be required to provide a PROXY Protocol
# handshake, described in this document (external link):
#
# http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt
#
# The PROXY Protocol is a popular method used by elastic load balancing
# service providers such as Amazon, to identify the true IP address and
# port number of external incoming connections.
#
# In addition to enabling this setting, it will also be required to
# use your provider-specific control panel or administrative web page
# to configure your server instance to receive PROXY Protocol handshakes,
# and also to restrict access to your instance to the Elastic Load Balancer.
#
#
#
# [peer_private]
#
# 0 or 1.
@@ -145,19 +329,6 @@
#
#
#
# [peer_ssl_cipher_list]
#
# A colon delimited string with the allowed SSL cipher modes for peer. The
# choices for for ciphers are defined by the OpenSSL API function
# SSL_CTX_set_cipher_list, documented here (external link):
#
# http://pic.dhe.ibm.com/infocenter/tpfhelp/current/index.jsp?topic=%2Fcom.ibm.ztpf-ztpfdf.doc_put.cur%2Fgtpc2%2Fcpp_ssl_ctx_set_cipher_list.html
#
# The default setting is "ALL:!LOW:!EXP:!MD5:@STRENGTH", which allows
# non-authenticated peer connections (they are, however, secure).
#
#
#
# [node_seed]
#
# This is used for clustering. To force a particular node seed or key, the
@@ -191,245 +362,49 @@
#
#
#
#-------------------------------------------------------------------------------
# [overlay] EXPERIMENTAL
#
# 2. Websocket Networking
# This section is EXPERIMENTAL, and should not be
# present for production configuration settings.
#
#------------------------
# A set of key/value pair parameters to configure the overlay.
#
# These settings control security and access attributes of the Websocket
# server section of the rippled process, primarily used to service
# client requests and backend applications.
# auto_connect = 0 | 1
#
# When set, activates the autoconnect feature. This maintains outgoing
# connections using PeerFinder's "Outgoing Connection Strategy."
#
# http_handshake = 0 | 1
#
# [websocket_public_ip]
# When set, outgoing peer connections will handshaking using a HTTP
# request instead of the legacy TMHello protocol buffers message.
# Incoming peer connections have their handshakes detected automatically.
#
# IP address or domain to bind to allow untrusted connections from clients.
# In the future, this option will go away and the peer_ip will accept
# websocket client connections.
# become_superpeer = 'never' | 'always' | 'auto'
#
# Examples: 0.0.0.0 - Bind on all interfaces.
# 127.0.0.1 - Bind on localhost interface. Only local programs may connect.
# Controls the selection of peer roles:
#
# 'never' Always handshake in the leaf role.
# 'always' Always handshake in the superpeer role.
# 'auto' Start as a leaf, promote to superpeer after
# passing capability check (default).
#
# In the leaf role, a peer does not advertise its IP and port for
# the purpose of receiving incoming connections. The peer also does
# not forward transactions and validations received from other peers.
#
# [websocket_public_port]
#
# Port to bind to allow untrusted connections from clients. In the future,
# this option will go away and the peer_ip will accept websocket client
# connections.
#
#
#
# [websocket_public_secure]
#
# 0, 1 or 2.
# 0: Provide ws service for websocket_public_ip/websocket_public_port.
# 1: Provide both ws and wss service for websocket_public_ip/websocket_public_port. [default]
# 2: Provide wss service only for websocket_public_ip/websocket_public_port.
#
# Browser pages like the Ripple client will not be able to connect to a secure
# websocket connection if a self-signed certificate is used. As the Ripple
# reference client currently shares secrets with its server, this should be
# enabled.
#
#
#
# [websocket_ping_frequency]
#
# <number>
#
# The amount of time to wait in seconds, before sending a websocket 'ping'
# message. Ping messages are used to determine if the remote end of the
# connection is no longer available.
#
#
#
# [websocket_ip]
#
# IP address or domain to bind to allow trusted ADMIN connections from backend
# applications.
#
# Examples: 0.0.0.0 - Bind on all interfaces.
# 127.0.0.1 - Bind on localhost interface. Only local programs may connect.
#
#
#
# [websocket_port]
#
# Port to bind to allow trusted ADMIN connections from backend applications.
#
#
#
# [websocket_secure]
#
# 0, 1, or 2.
# 0: Provide ws service only for websocket_ip/websocket_port. [default]
# 1: Provide ws and wss service for websocket_ip/websocket_port
# 2: Provide wss service for websocket_ip/websocket_port.
#
#
#
# [websocket_ssl_cert]
#
# Specify the path to the SSL certificate file in PEM format.
# This is not needed if the chain includes it.
#
#
#
# [websocket_ssl_chain]
#
# If you need a certificate chain, specify the path to the certificate chain
# here. The chain may include the end certificate.
#
#
#
# [websocket_ssl_key]
#
# Specify the filename holding the SSL key in PEM format.
# In the superpeer role, a peer advertises its IP and port for
# receiving incoming connections after passing an incoming connection
# test. Superpeers forward transactions and protocol messages to all
# other peers. Superpeers do not forward validations to other superpeers.
# Instead, a validation received by a superpeer from a leaf is forwarded
# only to other leaf connections.
#
#
#
#-------------------------------------------------------------------------------
#
# 3. RPC Networking
#
#------------------
#
# This group of settings configures security and access attributes of the
# RPC server section of the rippled process, used to service both local
# and optional remote clients.
#
#
#
# [rpc_allow_remote]
#
# 0 or 1.
#
# 0: Allow RPC connections only from 127.0.0.1. [default]
# 1: Allow RPC connections from any IP.
#
#
#
# [rpc_admin_allow]
#
# Specify a list of IP addresses allowed to have admin access. One per line.
# If you want to test the output of non-admin commands add this section and
# just put an ip address not under your control.
# Defaults to 127.0.0.1.
#
#
#
# [rpc_admin_user]
#
# As a server, require this as the admin user to be specified. Also, require
# rpc_admin_user and rpc_admin_password to be checked for RPC admin functions.
# The request must specify these as the admin_user and admin_password in the
# request object.
#
# As a client, supply this to the server in the request object.
#
#
#
# [rpc_admin_password]
#
# As a server, require this as the admin password to be specified. Also,
# require rpc_admin_user and rpc_admin_password to be checked for RPC admin
# functions. The request must specify these as the admin_user and
# admin_password in the request object.
#
# As a client, supply this to the server in the request object.
#
#
#
# [rpc_ip]
#
# IP address or domain to bind to allow insecure RPC connections.
# Defaults to not binding, which disallows RPC connections.
#
#
#
# [rpc_port]
#
# If rpc_ip is supplied, corresponding port to bind to for peer connections.
#
#
#
# [rpc_user]
#
# As a server, require this user to be specified and require rpc_password to
# be checked for RPC access via the rpc_ip and rpc_port. The user and password
# must be specified via HTTP's basic authentication method.
# As a client, supply this to the server via HTTP's basic authentication
# method.
#
#
#
# [rpc_password]
#
# As a server, require this password to be specified and require rpc_user to
# be checked for RPC access via the rpc_ip and rpc_port. The user and password
# must be specified via HTTP's basic authentication method.
# As a client, supply this to the server via HTTP's basic authentication
# method.
#
#
#
# [rpc_startup]
#
# Specify a list of RPC commands to run at startup.
#
# Examples:
# { "command" : "server_info" }
# { "command" : "log_level", "partition" : "ripplecalc", "severity" : "trace" }
#
#
#
# [rpc_secure]
#
# 0 or 1.
#
# 0: Server certificates are not provided for RPC clients using SSL [default]
# 1: Client RPC connections wil be provided with SSL certificates.
#
# Note that if rpc_secure is enabled, it will also be necessary to configure
# the certificate file settings located in rpc_ssl_cert, rpc_ssl_chain, and
# rpc_ssl_key
#
#
#
# [rpc_ssl_cert]
#
# <pathname>
#
# A file system path leading to the SSL certificate file to use for secure
# RPC. The file is in PEM format. The file is not needed if the chain
# includes it.
#
#
#
# [rpc_ssl_chain]
#
# <pathname>
#
# A file system path leading to the file with the certificate chain.
# The chain may include the end certificate.
#
#
#
# [rpc_ssl_key]
#
# <pathname>
#
# A file system path leading to the file with the SSL key.
# The file is in PEM format.
#
#
#
#-------------------------------------------------------------------------------
#
# 4. SMS Gateway
# 3. SMS Gateway
#
#---------------
#
@@ -465,9 +440,9 @@
#
#-------------------------------------------------------------------------------
#
# 5. Ripple Protocol
# 4. Ripple Protocol
#
#------------------
#-------------------
#
# These settings affect the behavior of the server instance with respect
# to Ripple payment protocol level activities such as validating and
@@ -506,6 +481,13 @@
#
#
#
# [ledger_history_index]
#
# If set to greater than 0, the index number of the earliest ledger to
# acquire.
#
#
#
# [fetch_depth]
#
# The number of past ledgers to serve to other peers that request historical
@@ -600,9 +582,16 @@
#
#
#
# [fee_default]
#
# Sets the base cost of a transaction in drops. Used when the server has
# no other source of fee information, such as signing transactions offline.
#
#
#
#-------------------------------------------------------------------------------
#
# 6. HTTPS Client
# 5. HTTPS Client
#
#----------------
#
@@ -616,7 +605,9 @@
# 0 or 1.
#
# 0. HTTPS client connections will not verify certificates.
# 1. Certificates will be checked for HTTPS client connections .
# 1. Certificates will be checked for HTTPS client connections.
#
# If not specified, this parameter defaults to 1.
#
#
#
@@ -642,7 +633,7 @@
#
#-------------------------------------------------------------------------------
#
# 7. Database
# 6. Database
#
#------------
#
@@ -681,16 +672,24 @@
#
# Choices for 'type' (not case-sensitive)
# RocksDB Use Facebook's RocksDB database (preferred)
# HyperLevelDB Use an improved version of LevelDB
# SQLite Use SQLite
# LevelDB Use Google's LevelDB database (deprecated)
# none Use no backend
# NuDB Use Ripple Labs' NuDB (Windows preferred)
# HyperLevelDB (Deprecated)
# SQLite (Deprecated)
# LevelDB (Deprecated)
# none (No backend)
#
# Required keys:
# path Location to store the database (all types)
#
# Optional keys:
# compression 0 for none, 1 for Snappy compression
# online_delete Minimum value of 256. Enable automatic purging
# of older ledger information. Maintain at least this
# number of ledger records online. Must be greater
# than or equal to ledger_history.
# advisory_delete 0 for disabled, 1 for enabled. If set, then
# require administrative RPC call "can_delete"
# to enable online deletion of ledger records.
#
# Notes:
# The 'node_db' entry configures the primary, persistent storage.
@@ -715,7 +714,7 @@
#
#-------------------------------------------------------------------------------
#
# 8. Diagnostics
# 7. Diagnostics
#
#---------------
#
@@ -770,41 +769,135 @@
# prefix=my_validator
#
#-------------------------------------------------------------------------------
# Allow other peers to connect to this server.
#
[peer_ip]
0.0.0.0
[peer_port]
51235
# Allow untrusted clients to connect to this server.
# 8. Voting
#
[websocket_public_ip]
0.0.0.0
[websocket_public_port]
5006
# Provide trusted websocket ADMIN access to the localhost.
#----------
#
[websocket_ip]
127.0.0.1
[websocket_port]
6006
# Provide trusted json-rpc ADMIN access to the localhost.
# The vote settings configure settings for the entire Ripple network.
# While a single instance of rippled cannot unilaterally enforce network-wide
# settings, these choices become part of the instance's vote during the
# consensus process for each voting ledger.
#
[rpc_ip]
127.0.0.1
# [voting]
#
# A set of key/value pair parameters used during voting ledgers.
#
# reference_fee = <drops>
#
# The cost of the reference transaction fee, specified in drops.
# The reference transaction is the simplest form of transaction.
# It represents an XRP payment between two parties.
#
# If this parameter is unspecified, rippled will use an internal
# default. Don't change this without understanding the consequences.
#
# Example:
# reference_fee = 10 # 10 drops
#
# account_reserve = <drops>
#
# The account reserve requirement specified in drops. The portion of an
# account's XRP balance that is at or below the reserve may only be
# spent on transaction fees, and not transferred out of the account.
#
# If this parameter is unspecified, rippled will use an internal
# default. Don't change this without understanding the consequences.
#
# Example:
# account_reserve = 20000000 # 20 XRP
#
# owner_reserve = <drops>
#
# The owner reserve is the amount of XRP reserved in the account for
# each ledger item owned by the account. Ledger items an account may
# own include trust lines, open orders, and tickets.
#
# If this parameter is unspecified, rippled will use an internal
# default. Don't change this without understanding the consequences.
#
# Example:
# owner_reserve = 5000000 # 5 XRP
#
#-------------------------------------------------------------------------------
#
# 9. Example Settings
#
#--------------------
#
# Administrators can use these values as a starting poing for configuring
# their instance of rippled, but each value should be checked to make sure
# it meets the business requirements for the organization.
#
# Server
#
# These example configuration settings create these ports:
#
# "peer"
#
# Peer protocol open to everyone. This is required to accept
# incoming rippled connections. This does not affect automatic
# or manual outgoing Peer protocol connections.
#
# "rpc"
#
# Administrative RPC commands over HTTPS, when originating from
# the same machine (via the loopback adapter at 127.0.0.1).
#
# "wss_admin"
#
# Admin level API commands over Secure Websockets, when originating
# from the same machine (via the loopback adapter at 127.0.0.1).
#
# This port is commented out but can be enabled by removing
# the '#' from each corresponding line including the entry under [server]
#
# "wss_public"
#
# Guest level API commands over Secure Websockets, open to everyone.
#
# For HTTPS and Secure Websockets ports, if no certificate and key file
# are specified then a self-signed certificate will be generated on startup.
# If you have a certificate and key file, uncomment the corresponding lines
# and ensure the paths to the files are correct.
#
# NOTE
#
# To accept connections on well known ports such as 80 (HTTP) or
# 443 (HTTPS), most operating systems will require rippled to
# run with administrator privileges, or else rippled will not start.
[rpc_port]
5005
[server]
port_rpc
port_peer
port_wss_admin
#port_ws_public
#ssl_key = /etc/ssl/private/server.key
#ssl_cert = /etc/ssl/certs/server.crt
[rpc_allow_remote]
0
[port_rpc]
port = 5005
ip = 127.0.0.1
admin = allow
protocol = https
[port_peer]
port = 51235
ip = 0.0.0.0
protocol = peer
[port_wss_admin]
port = 6006
ip = 127.0.0.1
admin = allow
protocol = wss
#[port_ws_public]
#port = 5005
#ip = 127.0.0.1
#protocol = wss
#-------------------------------------------------------------------------------
[node_size]
medium
@@ -812,6 +905,8 @@ medium
# This is primary persistent datastore for rippled. This includes transaction
# metadata, account states, and ledger headers. Helpful information can be
# found here: https://ripple.com/wiki/NodeBackEnd
# delete old ledgers while maintaining at least 2000. Do not require an
# external administrative command to initiate deletion.
[node_db]
type=RocksDB
path=/var/lib/rippled/db/rocksdb
@@ -820,6 +915,8 @@ filter_bits=12
cache_mb=256
file_size_mb=8
file_size_mult=2
online_delete=2000
advisory_delete=0
[database_path]
/var/lib/rippled/db
@@ -844,11 +941,11 @@ r.ripple.com 51235
# https://ripple.com/ripple.txt
#
[validators]
n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7 RL1
n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj RL2
n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C RL3
n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS RL4
n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA RL5
n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7 RL1
n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj RL2
n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C RL3
n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS RL4
n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA RL5
# Ditto.
[validation_quorum]
@@ -859,22 +956,7 @@ n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA RL5
[rpc_startup]
{ "command": "log_level", "severity": "warning" }
# Configure SSL for WebSockets. Not enabled by default because not everybody
# has an SSL cert on their server, but if you uncomment the following lines and
# set the path to the SSL certificate and private key the WebSockets protocol
# will be protected by SSL/TLS.
#[websocket_secure]
#1
#[websocket_ssl_cert]
#/etc/ssl/certs/server.crt
#[websocket_ssl_key]
#/etc/ssl/private/server.key
# Defaults to 0 ("no") so that you can use self-signed SSL certificates for
# development, or internally.
# Defaults to 1 ("yes") so that certificates will be validated. To allow the use
# of self-signed certificates for development or internal use, set to 0 ("no").
#[ssl_verify]
#0

BIN
images/build.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
images/contribute.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
images/network.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
images/pathfinding.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

BIN
images/ripple.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
images/transact.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
images/vehicle_currency.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@@ -2,33 +2,28 @@
"name": "rippled",
"version": "0.0.1",
"description": "Rippled Server",
"private": true,
"directories": {
"test": "test"
},
"dependencies": {
"ripple-lib": "0.7.37",
"ripple-lib": "0.8.2",
"async": "~0.2.9",
"extend": "~1.2.0",
"simple-jsonrpc": "~0.0.2",
"deep-equal": "0.0.0"
},
"devDependencies": {
"assert-diff": "^1.0.1",
"coffee-script": "~1.6.3",
"mocha": "~1.13.0"
},
"scripts": {
"test": "mocha test/websocket-test.js test/server-test.js test/*-test.{js,coffee}"
},
"repository": {
"type": "git",
"url": "git://github.com/ripple/rippled.git"
},
"readmeFilename": "README.md"
}

View File

@@ -57,18 +57,6 @@
//#define BEAST_FORCE_DEBUG 1
#endif
/** Config: BEAST_LOG_ASSERTIONS
If this flag is enabled, the the bassert and bassertfalse macros will always
use Logger::writeToLog() to write a message when an assertion happens.
Enabling it will also leave this turned on in release builds. When it's
disabled, however, the bassert and bassertfalse macros will not be compiled
in a release build.
@see bassert, bassertfalse, Logger
*/
#ifndef BEAST_LOG_ASSERTIONS
//#define BEAST_LOG_ASSERTIONS 1
#endif
/** Config: BEAST_CHECK_MEMORY_LEAKS
Enables a memory-leak check for certain objects when the app terminates.
See the LeakChecked class for more details about enabling leak checking for
@@ -78,17 +66,6 @@
//#define BEAST_CHECK_MEMORY_LEAKS 0
#endif
/** Config: BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
Setting this option makes Socket-derived classes generate compile errors
if they forget any of the virtual overrides As some Socket-derived classes
intentionally omit member functions that are not applicable, this macro
should only be enabled temporarily when writing your own Socket-derived
class, to make sure that the function signatures match as expected.
*/
#ifndef BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
//#define BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES 1
#endif
//------------------------------------------------------------------------------
//
// Libraries
@@ -220,23 +197,18 @@
#define RIPPLE_SINGLE_IO_SERVICE_THREAD 0
#endif
/** Config: RIPPLE_STRUCTURED_OVERLAY_CLIENT
RIPPLE_STRUCTURED_OVERLAY_SERVER
Enables Structured Overlay support for the client or server roles.
This feature is currently in development:
https://ripplelabs.atlassian.net/browse/RIPD-157
/** Config: RIPPLE_HOOK_VALIDATORS
Activates code for handling validations and validators (work in progress).
*/
#ifndef RIPPLE_STRUCTURED_OVERLAY_CLIENT
#define RIPPLE_STRUCTURED_OVERLAY_CLIENT 0
#endif
#ifndef RIPPLE_STRUCTURED_OVERLAY_SERVER
#define RIPPLE_STRUCTURED_OVERLAY_SERVER 1
#ifndef RIPPLE_HOOK_VALIDATORS
#define RIPPLE_HOOK_VALIDATORS 0
#endif
/** Config: RIPPLE_ASYNC_RPC_HANDLER
/** Config: RIPPLE_ENABLE_TICKETS
Enables processing of ticket transactions
*/
#ifndef RIPPLE_ASYNC_RPC_HANDLER
#define RIPPLE_ASYNC_RPC_HANDLER 1
#ifndef RIPPLE_ENABLE_TICKETS
#define RIPPLE_ENABLE_TICKETS 0
#endif
#endif

View File

@@ -55,18 +55,6 @@
//#define BEAST_FORCE_DEBUG 1
#endif
/** Config: BEAST_LOG_ASSERTIONS
If this flag is enabled, the the bassert and bassertfalse macros will always
use Logger::writeToLog() to write a message when an assertion happens.
Enabling it will also leave this turned on in release builds. When it's
disabled, however, the bassert and bassertfalse macros will not be compiled
in a release build.
@see bassert, bassertfalse, Logger
*/
#ifndef BEAST_LOG_ASSERTIONS
//#define BEAST_LOG_ASSERTIONS 1
#endif
/** Config: BEAST_CHECK_MEMORY_LEAKS
Enables a memory-leak check for certain objects when the app terminates.
See the LeakChecked class for more details about enabling leak checking for
@@ -76,17 +64,6 @@
//#define BEAST_CHECK_MEMORY_LEAKS 0
#endif
/** Config: BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
Setting this option makes Socket-derived classes generate compile errors
if they forget any of the virtual overrides As some Socket-derived classes
intentionally omit member functions that are not applicable, this macro
should only be enabled temporarily when writing your own Socket-derived
class, to make sure that the function signatures match as expected.
*/
#ifndef BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
//#define BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES 1
#endif
//------------------------------------------------------------------------------
//
// Libraries

View File

@@ -34,101 +34,6 @@
namespace beast {
// Some indispensible min/max functions
/** Returns the larger of two values. */
template <typename Type>
inline Type bmax (const Type a, const Type b)
{ return (a < b) ? b : a; }
/** Returns the larger of three values. */
template <typename Type>
inline Type bmax (const Type a, const Type b, const Type c)
{ return (a < b) ? ((b < c) ? c : b) : ((a < c) ? c : a); }
/** Returns the larger of four values. */
template <typename Type>
inline Type bmax (const Type a, const Type b, const Type c, const Type d)
{ return bmax (a, bmax (b, c, d)); }
/** Returns the smaller of two values. */
template <typename Type>
inline Type bmin (const Type a, const Type b)
{ return (b < a) ? b : a; }
/** Returns the smaller of three values. */
template <typename Type>
inline Type bmin (const Type a, const Type b, const Type c)
{ return (b < a) ? ((c < b) ? c : b) : ((c < a) ? c : a); }
/** Returns the smaller of four values. */
template <typename Type>
inline Type bmin (const Type a, const Type b, const Type c, const Type d)
{ return bmin (a, bmin (b, c, d)); }
/** Scans an array of values, returning the minimum value that it contains. */
template <typename Type>
const Type findMinimum (const Type* data, int numValues)
{
if (numValues <= 0)
return Type();
Type result (*data++);
while (--numValues > 0) // (> 0 rather than >= 0 because we've already taken the first sample)
{
const Type& v = *data++;
if (v < result) result = v;
}
return result;
}
/** Scans an array of values, returning the maximum value that it contains. */
template <typename Type>
const Type findMaximum (const Type* values, int numValues)
{
if (numValues <= 0)
return Type();
Type result (*values++);
while (--numValues > 0) // (> 0 rather than >= 0 because we've already taken the first sample)
{
const Type& v = *values++;
if (result < v) result = v;
}
return result;
}
/** Scans an array of values, returning the minimum and maximum values that it contains. */
template <typename Type>
void findMinAndMax (const Type* values, int numValues, Type& lowest, Type& highest)
{
if (numValues <= 0)
{
lowest = Type();
highest = Type();
}
else
{
Type mn (*values++);
Type mx (mn);
while (--numValues > 0) // (> 0 rather than >= 0 because we've already taken the first sample)
{
const Type& v = *values++;
if (mx < v) mx = v;
if (v < mn) mn = v;
}
lowest = mn;
highest = mx;
}
}
//==============================================================================
/** Constrains a value to keep it within a given range.
@@ -151,7 +56,8 @@ inline Type blimit (const Type lowerLimit,
const Type upperLimit,
const Type valueToConstrain) noexcept
{
bassert (lowerLimit <= upperLimit); // if these are in the wrong order, results are unpredictable..
// if these are in the wrong order, results are unpredictable.
bassert (lowerLimit <= upperLimit);
return (valueToConstrain < lowerLimit) ? lowerLimit
: ((upperLimit < valueToConstrain) ? upperLimit
@@ -177,24 +83,6 @@ inline bool isPositiveAndBelow (const int valueToTest, const int upperLimit) noe
return static_cast <unsigned int> (valueToTest) < static_cast <unsigned int> (upperLimit);
}
/** Returns true if a value is at least zero, and also less than or equal to a specified upper limit.
This is basically a quicker way to write:
@code valueToTest >= 0 && valueToTest <= upperLimit
@endcode
*/
template <typename Type>
inline bool isPositiveAndNotGreaterThan (Type valueToTest, Type upperLimit) noexcept
{
bassert (Type() <= upperLimit); // makes no sense to call this if the upper limit is itself below zero..
return Type() <= valueToTest && valueToTest <= upperLimit;
}
template <>
inline bool isPositiveAndNotGreaterThan (const int valueToTest, const int upperLimit) noexcept
{
bassert (upperLimit >= 0); // makes no sense to call this if the upper limit is itself below zero..
return static_cast <unsigned int> (valueToTest) <= static_cast <unsigned int> (upperLimit);
}
//==============================================================================
@@ -214,55 +102,6 @@ int numElementsInArray (Type (&array)[N])
return N;
}
/** 64-bit abs function. */
inline std::int64_t abs64 (const std::int64_t n) noexcept
{
return (n >= 0) ? n : -n;
}
//==============================================================================
#if BEAST_MSVC
#pragma optimize ("t", off)
#ifndef __INTEL_COMPILER
#pragma float_control (precise, on, push)
#endif
#endif
/** Fast floating-point-to-integer conversion.
This is faster than using the normal c++ cast to convert a float to an int, and
it will round the value to the nearest integer, rather than rounding it down
like the normal cast does.
Note that this routine gets its speed at the expense of some accuracy, and when
rounding values whose floating point component is exactly 0.5, odd numbers and
even numbers will be rounded up or down differently.
*/
template <typename FloatType>
inline int roundToInt (const FloatType value) noexcept
{
#ifdef __INTEL_COMPILER
#pragma float_control (precise, on, push)
#endif
union { int asInt[2]; double asDouble; } n;
n.asDouble = ((double) value) + 6755399441055744.0;
#if BEAST_BIG_ENDIAN
return n.asInt [1];
#else
return n.asInt [0];
#endif
}
#if BEAST_MSVC
#ifndef __INTEL_COMPILER
#pragma float_control (pop)
#endif
#pragma optimize ("", on) // resets optimisations to the project defaults
#endif
}
#endif

View File

@@ -1,428 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.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_ATOMIC_H_INCLUDED
#define BEAST_ATOMIC_H_INCLUDED
#include <beast/Config.h>
#include <beast/StaticAssert.h>
#include <beast/utility/noexcept.h>
#include <cstdint>
namespace beast {
//==============================================================================
/**
Simple class to hold a primitive value and perform atomic operations on it.
The type used must be a 32 or 64 bit primitive, like an int, pointer, etc.
There are methods to perform most of the basic atomic operations.
*/
template <typename Type>
class Atomic
{
public:
/** Creates a new value, initialised to zero. */
inline Atomic() noexcept
: value (0)
{
}
/** Creates a new value, with a given initial value. */
inline Atomic (const Type initialValue) noexcept
: value (initialValue)
{
}
/** Copies another value (atomically). */
inline Atomic (const Atomic& other) noexcept
: value (other.get())
{
}
/** Destructor. */
inline ~Atomic() noexcept
{
// This class can only be used for types which are 32 or 64 bits in size.
static_bassert (sizeof (Type) == 4 || sizeof (Type) == 8);
}
/** Atomically reads and returns the current value. */
Type get() const noexcept;
/** Copies another value onto this one (atomically). */
Atomic& operator= (const Atomic& other) noexcept
{ exchange (other.get()); return *this; }
/** Copies another value onto this one (atomically). */
Atomic& operator= (const Type newValue) noexcept
{ exchange (newValue); return *this; }
/** Atomically sets the current value. */
void set (Type newValue) noexcept
{ exchange (newValue); }
/** Atomically sets the current value, returning the value that was replaced. */
Type exchange (Type value) noexcept;
/** Atomically adds a number to this value, returning the new value. */
Type operator+= (Type amountToAdd) noexcept;
/** Atomically subtracts a number from this value, returning the new value. */
Type operator-= (Type amountToSubtract) noexcept;
/** Atomically increments this value, returning the new value. */
Type operator++() noexcept;
/** Atomically decrements this value, returning the new value. */
Type operator--() noexcept;
/** Atomically compares this value with a target value, and if it is equal, sets
this to be equal to a new value.
This operation is the atomic equivalent of doing this:
@code
bool compareAndSetBool (Type newValue, Type valueToCompare)
{
if (get() == valueToCompare)
{
set (newValue);
return true;
}
return false;
}
@endcode
@returns true if the comparison was true and the value was replaced; false if
the comparison failed and the value was left unchanged.
@see compareAndSetValue
*/
bool compareAndSetBool (Type newValue, Type valueToCompare) noexcept;
/** Atomically compares this value with a target value, and if it is equal, sets
this to be equal to a new value.
This operation is the atomic equivalent of doing this:
@code
Type compareAndSetValue (Type newValue, Type valueToCompare)
{
Type oldValue = get();
if (oldValue == valueToCompare)
set (newValue);
return oldValue;
}
@endcode
@returns the old value before it was changed.
@see compareAndSetBool
*/
Type compareAndSetValue (Type newValue, Type valueToCompare) noexcept;
//==============================================================================
#if BEAST_64BIT
BEAST_ALIGN (8)
#else
BEAST_ALIGN (4)
#endif
/** The raw value that this class operates on.
This is exposed publically in case you need to manipulate it directly
for performance reasons.
*/
volatile Type value;
private:
template <typename Dest, typename Source>
static inline Dest castTo (Source value) noexcept { union { Dest d; Source s; } u; u.s = value; return u.d; }
static inline Type castFrom32Bit (std::int32_t value) noexcept { return castTo <Type, std::int32_t> (value); }
static inline Type castFrom64Bit (std::int64_t value) noexcept { return castTo <Type, std::int64_t> (value); }
static inline std::int32_t castTo32Bit (Type value) noexcept { return castTo <std::int32_t, Type> (value); }
static inline std::int64_t castTo64Bit (Type value) noexcept { return castTo <std::int64_t, Type> (value); }
Type operator++ (int); // better to just use pre-increment with atomics..
Type operator-- (int);
/** This templated negate function will negate pointers as well as integers */
template <typename ValueType>
inline ValueType negateValue (ValueType n) noexcept
{
return sizeof (ValueType) == 1 ? (ValueType) -(signed char) n
: (sizeof (ValueType) == 2 ? (ValueType) -(short) n
: (sizeof (ValueType) == 4 ? (ValueType) -(int) n
: ((ValueType) -(std::int64_t) n)));
}
/** This templated negate function will negate pointers as well as integers */
template <typename PointerType>
inline PointerType* negateValue (PointerType* n) noexcept
{
return reinterpret_cast <PointerType*> (-reinterpret_cast <std::intptr_t> (n));
}
};
//==============================================================================
/*
The following code is in the header so that the atomics can be inlined where possible...
*/
#if BEAST_IOS || (BEAST_MAC && (BEAST_PPC || BEAST_CLANG || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2)))
#define BEAST_ATOMICS_MAC 1 // Older OSX builds using gcc4.1 or earlier
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
#define BEAST_MAC_ATOMICS_VOLATILE
#else
#define BEAST_MAC_ATOMICS_VOLATILE volatile
#endif
#if BEAST_PPC || BEAST_IOS
// None of these atomics are available for PPC or for iOS 3.1 or earlier!!
template <typename Type> static Type OSAtomicAdd64Barrier (Type b, BEAST_MAC_ATOMICS_VOLATILE Type* a) noexcept { bassertfalse; return *a += b; }
template <typename Type> static Type OSAtomicIncrement64Barrier (BEAST_MAC_ATOMICS_VOLATILE Type* a) noexcept { bassertfalse; return ++*a; }
template <typename Type> static Type OSAtomicDecrement64Barrier (BEAST_MAC_ATOMICS_VOLATILE Type* a) noexcept { bassertfalse; return --*a; }
template <typename Type> static bool OSAtomicCompareAndSwap64Barrier (Type old, Type newValue, BEAST_MAC_ATOMICS_VOLATILE Type* value) noexcept
{ bassertfalse; if (old == *value) { *value = newValue; return true; } return false; }
#define BEAST_64BIT_ATOMICS_UNAVAILABLE 1
#endif
#elif BEAST_CLANG && BEAST_LINUX
#define BEAST_ATOMICS_GCC 1
//==============================================================================
#elif BEAST_GCC
#define BEAST_ATOMICS_GCC 1 // GCC with intrinsics
#if BEAST_IOS || BEAST_ANDROID // (64-bit ops will compile but not link on these mobile OSes)
#define BEAST_64BIT_ATOMICS_UNAVAILABLE 1
#endif
//==============================================================================
#else
#define BEAST_ATOMICS_WINDOWS 1 // Windows with intrinsics
#if BEAST_USE_INTRINSICS
#ifndef __INTEL_COMPILER
#pragma intrinsic (_InterlockedExchange, _InterlockedIncrement, _InterlockedDecrement, _InterlockedCompareExchange, \
_InterlockedCompareExchange64, _InterlockedExchangeAdd, _ReadWriteBarrier)
#endif
#define beast_InterlockedExchange(a, b) _InterlockedExchange(a, b)
#define beast_InterlockedIncrement(a) _InterlockedIncrement(a)
#define beast_InterlockedDecrement(a) _InterlockedDecrement(a)
#define beast_InterlockedExchangeAdd(a, b) _InterlockedExchangeAdd(a, b)
#define beast_InterlockedCompareExchange(a, b, c) _InterlockedCompareExchange(a, b, c)
#define beast_InterlockedCompareExchange64(a, b, c) _InterlockedCompareExchange64(a, b, c)
#define beast_MemoryBarrier _ReadWriteBarrier
#else
long beast_InterlockedExchange (volatile long* a, long b) noexcept;
long beast_InterlockedIncrement (volatile long* a) noexcept;
long beast_InterlockedDecrement (volatile long* a) noexcept;
long beast_InterlockedExchangeAdd (volatile long* a, long b) noexcept;
long beast_InterlockedCompareExchange (volatile long* a, long b, long c) noexcept;
__int64 beast_InterlockedCompareExchange64 (volatile __int64* a, __int64 b, __int64 c) noexcept;
inline void beast_MemoryBarrier() noexcept { long x = 0; beast_InterlockedIncrement (&x); }
#endif
#if BEAST_64BIT
#ifndef __INTEL_COMPILER
#pragma intrinsic (_InterlockedExchangeAdd64, _InterlockedExchange64, _InterlockedIncrement64, _InterlockedDecrement64)
#endif
#define beast_InterlockedExchangeAdd64(a, b) _InterlockedExchangeAdd64(a, b)
#define beast_InterlockedExchange64(a, b) _InterlockedExchange64(a, b)
#define beast_InterlockedIncrement64(a) _InterlockedIncrement64(a)
#define beast_InterlockedDecrement64(a) _InterlockedDecrement64(a)
#else
// None of these atomics are available in a 32-bit Windows build!!
template <typename Type> static Type beast_InterlockedExchangeAdd64 (volatile Type* a, Type b) noexcept { bassertfalse; Type old = *a; *a += b; return old; }
template <typename Type> static Type beast_InterlockedExchange64 (volatile Type* a, Type b) noexcept { bassertfalse; Type old = *a; *a = b; return old; }
template <typename Type> static Type beast_InterlockedIncrement64 (volatile Type* a) noexcept { bassertfalse; return ++*a; }
template <typename Type> static Type beast_InterlockedDecrement64 (volatile Type* a) noexcept { bassertfalse; return --*a; }
#define BEAST_64BIT_ATOMICS_UNAVAILABLE 1
#endif
#endif
#if BEAST_MSVC
#pragma warning (push)
#pragma warning (disable: 4311) // (truncation warning)
#endif
//==============================================================================
template <typename Type>
inline Type Atomic<Type>::get() const noexcept
{
#if BEAST_ATOMICS_MAC
return sizeof (Type) == 4 ? castFrom32Bit ((std::int32_t) OSAtomicAdd32Barrier ((int32_t) 0, (BEAST_MAC_ATOMICS_VOLATILE int32_t*) &value))
: castFrom64Bit ((std::int64_t) OSAtomicAdd64Barrier ((int64_t) 0, (BEAST_MAC_ATOMICS_VOLATILE int64_t*) &value));
#elif BEAST_ATOMICS_WINDOWS
return sizeof (Type) == 4 ? castFrom32Bit ((std::int32_t) beast_InterlockedExchangeAdd ((volatile long*) &value, (long) 0))
: castFrom64Bit ((std::int64_t) beast_InterlockedExchangeAdd64 ((volatile __int64*) &value, (__int64) 0));
#elif BEAST_ATOMICS_GCC
return sizeof (Type) == 4 ? castFrom32Bit ((std::int32_t) __sync_add_and_fetch ((volatile std::int32_t*) &value, 0))
: castFrom64Bit ((std::int64_t) __sync_add_and_fetch ((volatile std::int64_t*) &value, 0));
#endif
}
template <typename Type>
inline Type Atomic<Type>::exchange (const Type newValue) noexcept
{
#if BEAST_ATOMICS_MAC || BEAST_ATOMICS_GCC
Type currentVal = value;
while (! compareAndSetBool (newValue, currentVal)) { currentVal = value; }
return currentVal;
#elif BEAST_ATOMICS_WINDOWS
return sizeof (Type) == 4 ? castFrom32Bit ((std::int32_t) beast_InterlockedExchange ((volatile long*) &value, (long) castTo32Bit (newValue)))
: castFrom64Bit ((std::int64_t) beast_InterlockedExchange64 ((volatile __int64*) &value, (__int64) castTo64Bit (newValue)));
#endif
}
template <typename Type>
inline Type Atomic<Type>::operator+= (const Type amountToAdd) noexcept
{
#if BEAST_ATOMICS_MAC
# ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wint-to-void-pointer-cast"
# pragma clang diagnostic ignored "-Wint-to-pointer-cast"
# endif
return sizeof (Type) == 4 ? (Type) OSAtomicAdd32Barrier ((int32_t) castTo32Bit (amountToAdd), (BEAST_MAC_ATOMICS_VOLATILE int32_t*) &value)
: (Type) OSAtomicAdd64Barrier ((int64_t) amountToAdd, (BEAST_MAC_ATOMICS_VOLATILE int64_t*) &value);
# ifdef __clang__
# pragma clang diagnostic pop
# endif
#elif BEAST_ATOMICS_WINDOWS
return sizeof (Type) == 4 ? (Type) (beast_InterlockedExchangeAdd ((volatile long*) &value, (long) amountToAdd) + (long) amountToAdd)
: (Type) (beast_InterlockedExchangeAdd64 ((volatile __int64*) &value, (__int64) amountToAdd) + (__int64) amountToAdd);
#elif BEAST_ATOMICS_GCC
return (Type) __sync_add_and_fetch (&value, amountToAdd);
#endif
}
template <typename Type>
inline Type Atomic<Type>::operator-= (const Type amountToSubtract) noexcept
{
return operator+= (negateValue (amountToSubtract));
}
template <typename Type>
inline Type Atomic<Type>::operator++() noexcept
{
#if BEAST_ATOMICS_MAC
# ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wint-to-void-pointer-cast"
# pragma clang diagnostic ignored "-Wint-to-pointer-cast"
# endif
return sizeof (Type) == 4 ? (Type) OSAtomicIncrement32Barrier ((BEAST_MAC_ATOMICS_VOLATILE int32_t*) &value)
: (Type) OSAtomicIncrement64Barrier ((BEAST_MAC_ATOMICS_VOLATILE int64_t*) &value);
# ifdef __clang__
# pragma clang diagnostic pop
# endif
#elif BEAST_ATOMICS_WINDOWS
return sizeof (Type) == 4 ? (Type) beast_InterlockedIncrement ((volatile long*) &value)
: (Type) beast_InterlockedIncrement64 ((volatile __int64*) &value);
#elif BEAST_ATOMICS_GCC
return (Type) __sync_add_and_fetch (&value, (Type) 1);
#endif
}
template <typename Type>
inline Type Atomic<Type>::operator--() noexcept
{
#if BEAST_ATOMICS_MAC
# ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wint-to-void-pointer-cast"
# pragma clang diagnostic ignored "-Wint-to-pointer-cast"
# endif
return sizeof (Type) == 4 ? (Type) OSAtomicDecrement32Barrier ((BEAST_MAC_ATOMICS_VOLATILE int32_t*) &value)
: (Type) OSAtomicDecrement64Barrier ((BEAST_MAC_ATOMICS_VOLATILE int64_t*) &value);
# ifdef __clang__
# pragma clang diagnostic pop
# endif
#elif BEAST_ATOMICS_WINDOWS
return sizeof (Type) == 4 ? (Type) beast_InterlockedDecrement ((volatile long*) &value)
: (Type) beast_InterlockedDecrement64 ((volatile __int64*) &value);
#elif BEAST_ATOMICS_GCC
return (Type) __sync_add_and_fetch (&value, (Type) -1);
#endif
}
template <typename Type>
inline bool Atomic<Type>::compareAndSetBool (const Type newValue, const Type valueToCompare) noexcept
{
#if BEAST_ATOMICS_MAC
return sizeof (Type) == 4 ? OSAtomicCompareAndSwap32Barrier ((int32_t) castTo32Bit (valueToCompare), (int32_t) castTo32Bit (newValue), (BEAST_MAC_ATOMICS_VOLATILE int32_t*) &value)
: OSAtomicCompareAndSwap64Barrier ((int64_t) castTo64Bit (valueToCompare), (int64_t) castTo64Bit (newValue), (BEAST_MAC_ATOMICS_VOLATILE int64_t*) &value);
#elif BEAST_ATOMICS_WINDOWS
return compareAndSetValue (newValue, valueToCompare) == valueToCompare;
#elif BEAST_ATOMICS_GCC
return sizeof (Type) == 4 ? __sync_bool_compare_and_swap ((volatile std::int32_t*) &value, castTo32Bit (valueToCompare), castTo32Bit (newValue))
: __sync_bool_compare_and_swap ((volatile std::int64_t*) &value, castTo64Bit (valueToCompare), castTo64Bit (newValue));
#endif
}
template <typename Type>
inline Type Atomic<Type>::compareAndSetValue (const Type newValue, const Type valueToCompare) noexcept
{
#if BEAST_ATOMICS_MAC
for (;;) // Annoying workaround for only having a bool CAS operation..
{
if (compareAndSetBool (newValue, valueToCompare))
return valueToCompare;
const Type result = value;
if (result != valueToCompare)
return result;
}
#elif BEAST_ATOMICS_WINDOWS
return sizeof (Type) == 4 ? castFrom32Bit ((std::int32_t) beast_InterlockedCompareExchange ((volatile long*) &value, (long) castTo32Bit (newValue), (long) castTo32Bit (valueToCompare)))
: castFrom64Bit ((std::int64_t) beast_InterlockedCompareExchange64 ((volatile __int64*) &value, (__int64) castTo64Bit (newValue), (__int64) castTo64Bit (valueToCompare)));
#elif BEAST_ATOMICS_GCC
return sizeof (Type) == 4 ? castFrom32Bit ((std::int32_t) __sync_val_compare_and_swap ((volatile std::int32_t*) &value, castTo32Bit (valueToCompare), castTo32Bit (newValue)))
: castFrom64Bit ((std::int64_t) __sync_val_compare_and_swap ((volatile std::int64_t*) &value, castTo64Bit (valueToCompare), castTo64Bit (newValue)));
#endif
}
inline void memoryBarrier() noexcept
{
#if BEAST_ATOMICS_MAC
OSMemoryBarrier();
#elif BEAST_ATOMICS_GCC
__sync_synchronize();
#elif BEAST_ATOMICS_WINDOWS
beast_MemoryBarrier();
#endif
}
#if BEAST_MSVC
#pragma warning (pop)
#endif
}
#endif

View File

@@ -25,7 +25,6 @@
#define BEAST_BYTEORDER_H_INCLUDED
#include <beast/Config.h>
#include <beast/Uncopyable.h>
#include <cstdint>
@@ -35,7 +34,7 @@ namespace beast {
/** Contains static methods for converting the byte order between different
endiannesses.
*/
class ByteOrder : public Uncopyable
class ByteOrder
{
public:
//==============================================================================
@@ -105,6 +104,8 @@ public:
private:
ByteOrder();
ByteOrder(ByteOrder const&) = delete;
ByteOrder& operator= (ByteOrder const&) = delete;
};
//==============================================================================

View File

@@ -26,9 +26,6 @@
// VFALCO NOTE this is analogous to <boost/config.hpp>
// Assert to boost that we always have std::array support
#define BOOST_ASIO_HAS_STD_ARRAY 1
#if !defined(BEAST_COMPILER_CONFIG) && !defined(BEAST_NO_COMPILER_CONFIG) && !defined(BEAST_NO_CONFIG)
#include <beast/config/SelectCompilerConfig.h>
#endif

View File

@@ -20,11 +20,7 @@
#ifndef BEAST_CRYPTO_H_INCLUDED
#define BEAST_CRYPTO_H_INCLUDED
#include <beast/crypto/BinaryEncoding.h>
#include <beast/crypto/MurmurHash.h>
#include <beast/crypto/Sha256.h>
#include <beast/crypto/UnsignedInteger.h>
#include <beast/crypto/UnsignedIntegerCalc.h>
#endif

View File

@@ -29,7 +29,6 @@
#include <stdexcept>
#include <beast/Memory.h>
#include <beast/Uncopyable.h>
// If the MSVC debug heap headers were included, disable
// the macros during the juce include since they conflict.
@@ -122,7 +121,7 @@ namespace HeapBlockHelper
@see Array, MemoryBlock
*/
template <class ElementType, bool throwOnFailure = false>
class HeapBlock : public Uncopyable
class HeapBlock
{
public:
//==============================================================================
@@ -136,12 +135,6 @@ public:
{
}
HeapBlock (HeapBlock& other)
{
data = other.data;
other.data = nullptr;
}
/** Creates a HeapBlock containing a number of elements.
The contents of the block are undefined, as it will have been created by a
@@ -169,6 +162,10 @@ public:
throwOnAllocationFailure();
}
HeapBlock(HeapBlock const&) = delete;
HeapBlock& operator= (HeapBlock const&) = delete;
/** Destructor.
This will free the data, if any has been allocated.
*/

View File

@@ -27,7 +27,6 @@
#include <cstring>
#include <beast/Config.h>
#include <beast/Uncopyable.h>
namespace beast {
@@ -78,12 +77,16 @@ Type* createCopyIfNotNull (const Type* pointer)
/** A handy C++ wrapper that creates and deletes an NSAutoreleasePool object using RAII.
You should use the BEAST_AUTORELEASEPOOL macro to create a local auto-release pool on the stack.
*/
class ScopedAutoReleasePool : public Uncopyable
class ScopedAutoReleasePool
{
public:
ScopedAutoReleasePool();
~ScopedAutoReleasePool();
ScopedAutoReleasePool(ScopedAutoReleasePool const&) = delete;
ScopedAutoReleasePool& operator= (ScopedAutoReleasePool const&) = delete;
private:
void* pool;
};

View File

@@ -1,45 +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_STATICASSERT_H_INCLUDED
#define BEAST_STATICASSERT_H_INCLUDED
#ifndef DOXYGEN
namespace beast
{
template <bool b>
struct BeastStaticAssert;
template <>
struct BeastStaticAssert <true>
{
static void dummy() {}
};
}
#endif
/** A compile-time assertion macro.
If the expression parameter is false, the macro will cause a compile error.
(The actual error message that the compiler generates may be completely
bizarre and seem to have no relation to the place where you put the
static_assert though!)
*/
#define static_bassert(expression) beast::BeastStaticAssert<expression>::dummy();
#endif

View File

@@ -25,11 +25,9 @@
#include <beast/threads/SharedLockGuard.h>
#include <beast/threads/SharedMutexAdapter.h>
#include <beast/threads/SharedData.h>
#include <beast/threads/ServiceQueue.h>
#include <beast/threads/SpinLock.h>
#include <beast/threads/Stoppable.h>
#include <beast/threads/Thread.h>
#include <beast/threads/ThreadLocalValue.h>
#include <beast/threads/WaitableEvent.h>
#include <beast/threads/ScopedWrapperContext.h>

View File

@@ -1,77 +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_UNCOPYABLE_H_INCLUDED
#define BEAST_UNCOPYABLE_H_INCLUDED
namespace beast
{
// Ideas from boost
/** Prevent copy construction and assignment.
This is used to suppress warnings and prevent unsafe operations on
objects which cannot be passed by value. Ideas based on Boost.
For example, instead of
@code
class MyClass
{
public:
//...
private:
MyClass (const MyClass&);
MyClass& operator= (const MyClass&);
};
@endcode
..you can just write:
@code
class MyClass : public Uncopyable
{
public:
//...
};
@endcode
@note The derivation should be public or else child classes which
also derive from Uncopyable may not compile.
*/
class Uncopyable
{
protected:
Uncopyable () { }
~Uncopyable () { }
private:
Uncopyable (Uncopyable const&);
Uncopyable const& operator= (Uncopyable const&);
};
}
#endif

View File

@@ -22,11 +22,6 @@
#endif
#include <beast/asio/impl/IPAddressConversion.cpp>
#include <beast/asio/tests/wrap_handler.test.cpp>
#include <beast/asio/tests/bind_handler.test.cpp>
#include <beast/asio/tests/enable_wait_for_async.test.cpp>
#include <beast/asio/tests/shared_handler.test.cpp>
#include <beast/asio/abstract_socket.cpp> // TEMPORARY!
#include <beast/asio/tests/streambuf.test.cpp>

View File

@@ -1,217 +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 <beast/asio/abstract_socket.h>
#include <beast/asio/bind_handler.h>
namespace beast {
namespace asio {
#if ! BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
//------------------------------------------------------------------------------
//
// Socket
//
//------------------------------------------------------------------------------
void* abstract_socket::this_layer_ptr (char const*) const
{
pure_virtual_called ();
return nullptr;
}
//------------------------------------------------------------------------------
//
// native_handle
//
//------------------------------------------------------------------------------
bool abstract_socket::native_handle (char const*, void*)
{
pure_virtual_called ();
return false;
}
//------------------------------------------------------------------------------
//
// basic_io_object
//
//------------------------------------------------------------------------------
boost::asio::io_service& abstract_socket::get_io_service ()
{
pure_virtual_called ();
return *static_cast <boost::asio::io_service*>(nullptr);
}
//------------------------------------------------------------------------------
//
// basic_socket
//
//------------------------------------------------------------------------------
void*
abstract_socket::lowest_layer_ptr (char const*) const
{
pure_virtual_called ();
return nullptr;
}
auto
abstract_socket::cancel (boost::system::error_code& ec) -> error_code
{
return pure_virtual_error (ec);
}
auto
abstract_socket::shutdown (shutdown_type, boost::system::error_code& ec) -> error_code
{
return pure_virtual_error (ec);
}
auto
abstract_socket::close (boost::system::error_code& ec) -> error_code
{
return pure_virtual_error (ec);
}
//------------------------------------------------------------------------------
//
// basic_socket_acceptor
//
//------------------------------------------------------------------------------
auto
abstract_socket::accept (abstract_socket&, error_code& ec) -> error_code
{
return pure_virtual_error (ec);
}
void
abstract_socket::async_accept (abstract_socket&, error_handler handler)
{
get_io_service ().post (bind_handler (
handler, pure_virtual_error()));
}
//------------------------------------------------------------------------------
//
// basic_stream_socket
//
//------------------------------------------------------------------------------
std::size_t
abstract_socket::read_some (mutable_buffers, error_code& ec)
{
ec = pure_virtual_error ();
return 0;
}
std::size_t
abstract_socket::write_some (const_buffers, error_code& ec)
{
ec = pure_virtual_error ();
return 0;
}
void
abstract_socket::async_read_some (mutable_buffers, transfer_handler handler)
{
get_io_service ().post (bind_handler (
handler, pure_virtual_error(), 0));
}
void
abstract_socket::async_write_some (const_buffers, transfer_handler handler)
{
get_io_service ().post (bind_handler (
handler, pure_virtual_error(), 0));
}
//------------------------------------------------------------------------------
//
// ssl::stream
//
//------------------------------------------------------------------------------
void*
abstract_socket::next_layer_ptr (char const*) const
{
pure_virtual_called ();
return nullptr;
}
bool
abstract_socket::needs_handshake ()
{
return false;
}
void
abstract_socket::set_verify_mode (int)
{
pure_virtual_called ();
}
auto
abstract_socket::handshake (handshake_type, error_code& ec) -> error_code
{
return pure_virtual_error (ec);
}
void
abstract_socket::async_handshake (handshake_type, error_handler handler)
{
get_io_service ().post (bind_handler (
handler, pure_virtual_error()));
}
auto
abstract_socket::handshake (handshake_type, const_buffers, error_code& ec) ->
error_code
{
return pure_virtual_error (ec);
}
void
abstract_socket::async_handshake (handshake_type, const_buffers,
transfer_handler handler)
{
get_io_service ().post (bind_handler (
handler, pure_virtual_error(), 0));
}
auto
abstract_socket::shutdown (error_code& ec) -> error_code
{
return pure_virtual_error (ec);
}
void
abstract_socket::async_shutdown (error_handler handler)
{
get_io_service ().post (bind_handler (
handler, pure_virtual_error()));
}
#endif
}
}

View File

@@ -1,404 +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_ASIO_ABSTRACT_SOCKET_H_INCLUDED
#define BEAST_ASIO_ABSTRACT_SOCKET_H_INCLUDED
#include <beast/asio/buffer_sequence.h>
#include <beast/asio/shared_handler.h>
#include <boost/asio/io_service.hpp>
#include <boost/asio/socket_base.hpp>
#include <boost/asio/ssl/stream_base.hpp>
// Checking overrides replaces unimplemented stubs with pure virtuals
#ifndef BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
# define BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES 1
#endif
#if BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
# define BEAST_SOCKET_VIRTUAL = 0
#else
# define BEAST_SOCKET_VIRTUAL
#endif
namespace beast {
namespace asio {
/** A high level socket abstraction.
This combines the capabilities of multiple socket interfaces such
as listening, connecting, streaming, and handshaking. It brings
everything together into a single abstract interface.
When member functions are called and the underlying implementation does
not support the operation, a fatal error is generated.
*/
class abstract_socket
: public boost::asio::ssl::stream_base
, public boost::asio::socket_base
{
protected:
typedef boost::system::error_code error_code;
typedef asio::shared_handler <void (void)> post_handler;
typedef asio::shared_handler <void (error_code)> error_handler;
typedef asio::shared_handler <
void (error_code, std::size_t)> transfer_handler;
static
void
pure_virtual_called()
{
throw std::runtime_error ("pure virtual called");
}
static
error_code
pure_virtual_error ()
{
pure_virtual_called();
return boost::system::errc::make_error_code (
boost::system::errc::function_not_supported);
}
static
error_code
pure_virtual_error (error_code& ec)
{
return ec = pure_virtual_error();
}
static
void
throw_if (error_code const& ec)
{
if (ec)
throw boost::system::system_error (ec);
}
public:
virtual ~abstract_socket ()
{
}
//--------------------------------------------------------------------------
//
// abstract_socket
//
//--------------------------------------------------------------------------
/** Retrieve the underlying object.
@note If the type doesn't match, nullptr is returned or an
exception is thrown if trying to acquire a reference.
*/
/** @{ */
template <class Object>
Object& this_layer ()
{
Object* object (this->this_layer_ptr <Object> ());
if (object == nullptr)
throw std::bad_cast ();
return *object;
}
template <class Object>
Object const& this_layer () const
{
Object const* object (this->this_layer_ptr <Object> ());
if (object == nullptr)
throw std::bad_cast ();
return *object;
}
template <class Object>
Object* this_layer_ptr ()
{
return static_cast <Object*> (
this->this_layer_ptr (typeid (Object).name ()));
}
template <class Object>
Object const* this_layer_ptr () const
{
return static_cast <Object const*> (
this->this_layer_ptr (typeid (Object).name ()));
}
/** @} */
virtual void* this_layer_ptr (char const* type_name) const
BEAST_SOCKET_VIRTUAL;
//--------------------------------------------------------------------------
//
// native_handle
//
//--------------------------------------------------------------------------
/** Retrieve the native representation of the object.
Since we dont know the return type, and because almost every
asio implementation passes the result by value, you need to provide
a pointer to a default-constructed object of the matching type.
@note If the type doesn't match, an exception is thrown.
*/
template <typename Handle>
void native_handle (Handle* dest)
{
if (! native_handle (typeid (Handle).name (), dest))
throw std::bad_cast ();
}
virtual bool native_handle (char const* type_name, void* dest)
BEAST_SOCKET_VIRTUAL;
//--------------------------------------------------------------------------
//
// basic_io_object
//
//--------------------------------------------------------------------------
virtual boost::asio::io_service& get_io_service ()
BEAST_SOCKET_VIRTUAL;
//--------------------------------------------------------------------------
//
// basic_socket
//
//--------------------------------------------------------------------------
/** Retrieve the lowest layer object.
@note If the type doesn't match, nullptr is returned or an
exception is thrown if trying to acquire a reference.
*/
/** @{ */
template <class Object>
Object& lowest_layer ()
{
Object* object (this->lowest_layer_ptr <Object> ());
if (object == nullptr)
throw std::bad_cast ();
return *object;
}
template <class Object>
Object const& lowest_layer () const
{
Object const* object (this->lowest_layer_ptr <Object> ());
if (object == nullptr)
throw std::bad_cast ();
return *object;
}
template <class Object>
Object* lowest_layer_ptr ()
{
return static_cast <Object*> (
this->lowest_layer_ptr (typeid (Object).name ()));
}
template <class Object>
Object const* lowest_layer_ptr () const
{
return static_cast <Object const*> (
this->lowest_layer_ptr (typeid (Object).name ()));
}
/** @} */
virtual void* lowest_layer_ptr (char const* type_name) const
BEAST_SOCKET_VIRTUAL;
//--------------------------------------------------------------------------
void cancel ()
{
error_code ec;
cancel (ec);
throw_if (ec);
}
virtual error_code cancel (error_code& ec)
BEAST_SOCKET_VIRTUAL;
void shutdown (shutdown_type what)
{
error_code ec;
shutdown (what, ec);
throw_if (ec);
}
virtual error_code shutdown (shutdown_type what,
error_code& ec)
BEAST_SOCKET_VIRTUAL;
void close ()
{
error_code ec;
close (ec);
throw_if (ec);
}
virtual error_code close (error_code& ec)
BEAST_SOCKET_VIRTUAL;
//--------------------------------------------------------------------------
//
// basic_socket_acceptor
//
//--------------------------------------------------------------------------
virtual error_code accept (abstract_socket& peer, error_code& ec)
BEAST_SOCKET_VIRTUAL;
virtual void async_accept (abstract_socket& peer, error_handler handler)
BEAST_SOCKET_VIRTUAL;
//--------------------------------------------------------------------------
//
// basic_stream_socket
//
//--------------------------------------------------------------------------
virtual std::size_t read_some (mutable_buffers buffers, error_code& ec)
BEAST_SOCKET_VIRTUAL;
virtual std::size_t write_some (const_buffers buffers, error_code& ec)
BEAST_SOCKET_VIRTUAL;
virtual void async_read_some (mutable_buffers buffers,
transfer_handler handler)
BEAST_SOCKET_VIRTUAL;
virtual void async_write_some (const_buffers buffers,
transfer_handler handler)
BEAST_SOCKET_VIRTUAL;
//--------------------------------------------------------------------------
//
// ssl::stream
//
//--------------------------------------------------------------------------
/** Retrieve the next layer object.
@note If the type doesn't match, nullptr is returned or an
exception is thrown if trying to acquire a reference.
*/
/** @{ */
template <class Object>
Object& next_layer ()
{
Object* object (this->next_layer_ptr <Object> ());
if (object == nullptr)
throw std::bad_cast ();
return *object;
}
template <class Object>
Object const& next_layer () const
{
Object const* object (this->next_layer_ptr <Object> ());
if (object == nullptr)
throw std::bad_cast ();
return *object;
}
template <class Object>
Object* next_layer_ptr ()
{
return static_cast <Object*> (
this->next_layer_ptr (typeid (Object).name ()));
}
template <class Object>
Object const* next_layer_ptr () const
{
return static_cast <Object const*> (
this->next_layer_ptr (typeid (Object).name ()));
}
/** @} */
virtual void* next_layer_ptr (char const* type_name) const
BEAST_SOCKET_VIRTUAL;
/** Determines if the underlying stream requires a handshake.
If needs_handshake is true, it will be necessary to call handshake or
async_handshake after the connection is established. Furthermore it
will be necessary to call the shutdown member from the
HandshakeInterface to close the connection. Do not close the underlying
socket or else the closure will not be graceful. Only one side should
initiate the handshaking shutdon. The other side should observe it.
Which side does what is up to the user.
The default version returns false.
*/
virtual bool needs_handshake ()
BEAST_SOCKET_VIRTUAL;
virtual void set_verify_mode (int verify_mode)
BEAST_SOCKET_VIRTUAL;
void handshake (handshake_type type)
{
error_code ec;
handshake (type, ec);
throw_if (ec);
}
virtual error_code handshake (handshake_type type, error_code& ec)
BEAST_SOCKET_VIRTUAL;
virtual void async_handshake (handshake_type type, error_handler handler)
BEAST_SOCKET_VIRTUAL;
//--------------------------------------------------------------------------
virtual error_code handshake (handshake_type type,
const_buffers buffers, error_code& ec)
BEAST_SOCKET_VIRTUAL;
virtual void async_handshake (handshake_type type,
const_buffers buffers, transfer_handler handler)
BEAST_SOCKET_VIRTUAL;
//--------------------------------------------------------------------------
void shutdown ()
{
error_code ec;
shutdown (ec);
throw_if (ec);
}
virtual error_code shutdown (error_code& ec)
BEAST_SOCKET_VIRTUAL;
virtual void async_shutdown (error_handler handler)
BEAST_SOCKET_VIRTUAL;
};
}
}
#endif

View File

@@ -1,126 +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_ASIO_BUFFER_SEQUENCE_H_INCLUDED
#define BEAST_ASIO_BUFFER_SEQUENCE_H_INCLUDED
#include <boost/asio/buffer.hpp>
#include <beast/utility/noexcept.h>
#include <algorithm>
#include <iterator>
#include <beast/cxx14/type_traits.h> // <type_traits>
#include <vector>
namespace beast {
namespace asio {
template <class Buffer>
class buffer_sequence
{
private:
typedef std::vector <Buffer> sequence_type;
public:
typedef Buffer value_type;
typedef typename sequence_type::const_iterator const_iterator;
private:
sequence_type m_buffers;
template <class FwdIter>
void assign (FwdIter first, FwdIter last)
{
m_buffers.clear();
m_buffers.reserve (std::distance (first, last));
for (;first != last; ++first)
m_buffers.push_back (*first);
}
public:
buffer_sequence ()
{
}
template <
class BufferSequence,
class = std::enable_if_t <std::is_constructible <
Buffer, typename BufferSequence::value_type>::value>
>
buffer_sequence (BufferSequence const& s)
{
assign (std::begin (s), std::end (s));
}
template <
class FwdIter,
class = std::enable_if_t <std::is_constructible <
Buffer, typename std::iterator_traits <
FwdIter>::value_type>::value>
>
buffer_sequence (FwdIter first, FwdIter last)
{
assign (first, last);
}
template <class BufferSequence>
std::enable_if_t <std::is_constructible <
Buffer, typename BufferSequence::value_type>::value,
buffer_sequence&
>
operator= (BufferSequence const& s)
{
return assign (s);
}
const_iterator
begin () const noexcept
{
return m_buffers.begin ();
}
const_iterator
end () const noexcept
{
return m_buffers.end ();
}
#if 0
template <class ConstBufferSequence>
void
assign (ConstBufferSequence const& buffers)
{
auto const n (std::distance (
std::begin (buffers), std::end (buffers)));
for (int i = 0, auto iter (std::begin (buffers));
iter != std::end (buffers); ++iter, ++i)
m_buffers[i] = Buffer (boost::asio::buffer_cast <void*> (
*iter), boost::asio::buffer_size (*iter));
}
#endif
};
typedef buffer_sequence <boost::asio::const_buffer> const_buffers;
typedef buffer_sequence <boost::asio::mutable_buffer> mutable_buffers;
}
}
#endif

View File

@@ -1,265 +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_ASIO_ENABLE_WAIT_FOR_ASYNC_H_INCLUDED
#define BEAST_ASIO_ENABLE_WAIT_FOR_ASYNC_H_INCLUDED
#include <beast/asio/wrap_handler.h>
#include <beast/utility/is_call_possible.h>
#include <boost/asio/detail/handler_alloc_helpers.hpp>
#include <boost/asio/detail/handler_cont_helpers.hpp>
#include <boost/asio/detail/handler_invoke_helpers.hpp>
#include <atomic>
#include <condition_variable>
#include <mutex>
#include <beast/cxx14/type_traits.h> // <type_traits>
namespace beast {
namespace asio {
namespace detail {
template <class Owner, class Handler>
class ref_counted_wrapped_handler
{
private:
static_assert (std::is_same <std::decay_t <Owner>, Owner>::value,
"Owner cannot be a const or reference type");
Handler m_handler;
std::reference_wrapper <Owner> m_owner;
bool m_continuation;
public:
ref_counted_wrapped_handler (Owner& owner,
Handler&& handler, bool continuation)
: m_handler (std::move (handler))
, m_owner (owner)
, m_continuation (continuation ? true :
boost_asio_handler_cont_helpers::is_continuation (m_handler))
{
m_owner.get().increment();
}
ref_counted_wrapped_handler (Owner& owner,
Handler const& handler, bool continuation)
: m_handler (handler)
, m_owner (owner)
, m_continuation (continuation ? true :
boost_asio_handler_cont_helpers::is_continuation (m_handler))
{
m_owner.get().increment();
}
~ref_counted_wrapped_handler ()
{
m_owner.get().decrement();
}
ref_counted_wrapped_handler (ref_counted_wrapped_handler const& other)
: m_handler (other.m_handler)
, m_owner (other.m_owner)
, m_continuation (other.m_continuation)
{
m_owner.get().increment();
}
ref_counted_wrapped_handler (ref_counted_wrapped_handler&& other)
: m_handler (std::move (other.m_handler))
, m_owner (other.m_owner)
, m_continuation (other.m_continuation)
{
m_owner.get().increment();
}
ref_counted_wrapped_handler& operator= (
ref_counted_wrapped_handler const&) = delete;
template <class... Args>
void
operator() (Args&&... args)
{
m_handler (std::forward <Args> (args)...);
}
template <class... Args>
void
operator() (Args&&... args) const
{
m_handler (std::forward <Args> (args)...);
}
template <class Function>
friend
void
asio_handler_invoke (Function& f,
ref_counted_wrapped_handler* h)
{
boost_asio_handler_invoke_helpers::
invoke (f, h->m_handler);
}
template <class Function>
friend
void
asio_handler_invoke (Function const& f,
ref_counted_wrapped_handler* h)
{
boost_asio_handler_invoke_helpers::
invoke (f, h->m_handler);
}
friend
void*
asio_handler_allocate (std::size_t size,
ref_counted_wrapped_handler* h)
{
return boost_asio_handler_alloc_helpers::
allocate (size, h->m_handler);
}
friend
void
asio_handler_deallocate (void* p, std::size_t size,
ref_counted_wrapped_handler* h)
{
boost_asio_handler_alloc_helpers::
deallocate (p, size, h->m_handler);
}
friend
bool
asio_handler_is_continuation (ref_counted_wrapped_handler* h)
{
return h->m_continuation;
}
};
}
//------------------------------------------------------------------------------
/** Facilitates blocking until no completion handlers are remaining.
If Derived has this member function:
@code
void on_wait_for_async (void)
@endcode
Then it will be called every time the number of pending completion
handlers transitions to zero from a non-zero value. The call is made
while holding the internal mutex.
*/
template <class Derived>
class enable_wait_for_async
{
private:
BEAST_DEFINE_IS_CALL_POSSIBLE(
has_on_wait_for_async,on_wait_for_async);
void increment()
{
std::lock_guard <decltype(m_mutex)> lock (m_mutex);
++m_count;
}
void notify (std::true_type)
{
static_cast <Derived*> (this)->on_wait_for_async();
}
void notify (std::false_type)
{
}
void decrement()
{
std::lock_guard <decltype(m_mutex)> lock (m_mutex);
--m_count;
if (m_count == 0)
{
m_cond.notify_all();
notify (std::integral_constant <bool,
has_on_wait_for_async<Derived, void(void)>::value>());
}
}
template <class Owner, class Handler>
friend class detail::ref_counted_wrapped_handler;
std::mutex m_mutex;
std::condition_variable m_cond;
std::size_t m_count;
public:
/** Blocks if there are any pending completion handlers. */
void
wait_for_async()
{
std::unique_lock <decltype (m_mutex)> lock (m_mutex);
while (m_count != 0)
m_cond.wait (lock);
}
protected:
enable_wait_for_async()
: m_count (0)
{
}
~enable_wait_for_async()
{
assert (m_count == 0);
}
/** Wraps the specified handler so it can be counted. */
/** @{ */
template <class Handler>
detail::ref_counted_wrapped_handler <
enable_wait_for_async,
std::remove_reference_t <Handler>
>
wrap_with_counter (Handler&& handler, bool continuation = false)
{
return detail::ref_counted_wrapped_handler <enable_wait_for_async,
std::remove_reference_t <Handler>> (*this,
std::forward <Handler> (handler), continuation);
}
template <class Handler>
detail::ref_counted_wrapped_handler <
enable_wait_for_async,
std::remove_reference_t <Handler>
>
wrap_with_counter (continuation_t, Handler&& handler)
{
return detail::ref_counted_wrapped_handler <enable_wait_for_async,
std::remove_reference_t <Handler>> (*this,
std::forward <Handler> (handler), true);
}
/** @} */
};
}
}
#endif

View File

@@ -1,426 +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_ASIO_MEMORY_BUFFER_H_INCLUDED
#define BEAST_ASIO_MEMORY_BUFFER_H_INCLUDED
#include <beast/utility/empty_base_optimization.h>
#include <boost/asio/buffer.hpp>
#include <beast/utility/noexcept.h>
#include <cstddef>
#include <memory>
#include <type_traits>
namespace beast {
namespace asio {
template <
class T,
class Alloc = std::allocator <T>
>
class memory_buffer
: private empty_base_optimization <Alloc>
{
private:
static_assert (std::is_same <char, T>::value ||
std::is_same <unsigned char, T>::value,
"memory_buffer only works with char and unsigned char");
typedef empty_base_optimization <Alloc> Base;
using AllocTraits = std::allocator_traits <Alloc>;
T* m_base;
std::size_t m_size;
public:
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef T& reference;
typedef T const& const_reference;
typedef T* pointer;
typedef T const* const_pointer;
typedef Alloc allocator_type;
typedef T* iterator;
typedef T const* const_iterator;
typedef std::reverse_iterator <iterator> reverse_iterator;
typedef std::reverse_iterator <const_iterator> const_reverse_iterator;
memory_buffer ()
: m_base (nullptr)
, m_size (0)
{
}
memory_buffer (memory_buffer&& other)
: Base (std::move (other))
, m_base (other.m_base)
, m_size (other.m_size)
{
other.m_base = nullptr;
other.m_size = 0;
}
explicit memory_buffer (size_type n)
: m_base (AllocTraits::allocate (Base::member(), n))
, m_size (n)
{
}
explicit memory_buffer (Alloc const& alloc)
: Base (alloc)
, m_base (nullptr)
, m_size (0)
{
}
memory_buffer (size_type n, Alloc const& alloc)
: Base (alloc)
, m_base (AllocTraits::allocate (Base::member(), n))
, m_size (n)
{
}
~memory_buffer()
{
if (m_base != nullptr)
AllocTraits::deallocate (Base::member(), m_base, m_size);
}
memory_buffer& operator= (memory_buffer const&) = delete;
allocator_type
get_allocator() const
{
return Base::member;
}
//
// asio support
//
boost::asio::mutable_buffer
buffer()
{
return boost::asio::mutable_buffer (
data(), bytes());
}
boost::asio::const_buffer
buffer() const
{
return boost::asio::const_buffer (
data(), bytes());
}
boost::asio::mutable_buffers_1
buffers()
{
return boost::asio::mutable_buffers_1 (
data(), bytes());
}
boost::asio::const_buffers_1
buffers() const
{
return boost::asio::const_buffers_1 (
data(), bytes());
}
operator boost::asio::mutable_buffer()
{
return buffer();
}
operator boost::asio::const_buffer() const
{
return buffer();
}
operator boost::asio::mutable_buffers_1()
{
return buffers();
}
operator boost::asio::const_buffers_1() const
{
return buffers();
}
//
// Element access
//
reference
at (size_type pos)
{
if (! (pos < size()))
throw std::out_of_range ("bad array index");
return m_base [pos];
}
const_reference
at (size_type pos) const
{
if (! (pos < size()))
throw std::out_of_range ("bad array index");
return m_base [pos];
}
reference
operator[] (size_type pos) noexcept
{
return m_base [pos];
}
const_reference
operator[] (size_type pos) const noexcept
{
return m_base [pos];
}
reference
back() noexcept
{
return m_base [m_size - 1];
}
const_reference
back() const noexcept
{
return m_base [m_size - 1];
}
reference
front() noexcept
{
return *m_base;
}
const_reference
front() const noexcept
{
return *m_base;
}
pointer
data() noexcept
{
return m_base;
}
const_pointer
data() const noexcept
{
return m_base;
}
//
// Iterators
//
iterator
begin() noexcept
{
return m_base;
}
const_iterator
begin() const noexcept
{
return m_base;
}
const_iterator
cbegin() const noexcept
{
return m_base;
}
iterator
end() noexcept
{
return m_base + m_size;
}
const_iterator
end() const noexcept
{
return m_base + m_size;
}
const_iterator
cend() const noexcept
{
return m_base + m_size;
}
reverse_iterator
rbegin() noexcept
{
return reverse_iterator (end());
}
const_reverse_iterator
rbegin() const noexcept
{
return const_reverse_iterator (cend());
}
const_reverse_iterator
crbegin() const noexcept
{
return const_reverse_iterator (cend());
}
reverse_iterator
rend() noexcept
{
return reverse_iterator (begin());
}
const_reverse_iterator
rend() const noexcept
{
return const_reverse_iterator (cbegin());
}
const_reverse_iterator
crend() const noexcept
{
return const_reverse_iterator (cbegin());
}
//
// Capacity
//
bool
empty() const noexcept
{
return m_size == 0;
}
size_type
size() const noexcept
{
return m_size;
}
size_type
max_size() const noexcept
{
return size();
}
size_type
capacity() const noexcept
{
return size();
}
size_type bytes() const
{
return m_size * sizeof(T);
}
//
// Modifiers
//
template <class U, class A>
friend
void
swap (memory_buffer <U, A>& lhs,
memory_buffer <U, A>& rhs) noexcept;
};
//------------------------------------------------------------------------------
template <class T, class Alloc>
void
swap (memory_buffer <T, Alloc>& lhs,
memory_buffer <T, Alloc>& rhs) noexcept
{
std::swap (lhs.m_base, rhs.m_base);
std::swap (lhs.m_size, rhs.m_size);
}
template <class T, class A1, class A2>
inline
bool
operator== (memory_buffer <T, A1> const& lhs,
memory_buffer <T, A2> const& rhs)
{
return std::equal (lhs.cbegin(), lhs.cend(),
rhs.cbegin(), rhs.cend());
}
template <class T, class A1, class A2>
inline
bool
operator!= (memory_buffer <T, A1> const& lhs,
memory_buffer <T, A2> const& rhs)
{
return ! (lhs == rhs);
}
template <class T, class A1, class A2>
inline
bool
operator< (memory_buffer <T, A1> const& lhs,
memory_buffer <T, A2> const& rhs)
{
return std::lexicographical_compare (
lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend());
}
template <class T, class A1, class A2>
inline
bool
operator>= (memory_buffer <T, A1> const& lhs,
memory_buffer <T, A2> const& rhs)
{
return ! (lhs < rhs);
}
template <class T, class A1, class A2>
inline
bool
operator> (memory_buffer <T, A1> const& lhs,
memory_buffer <T, A2> const& rhs)
{
return rhs < lhs;
}
template <class T, class A1, class A2>
inline
bool
operator<= (memory_buffer <T, A1> const& lhs,
memory_buffer <T, A2> const& rhs)
{
return ! (rhs < lhs);
}
}
}
#endif

View File

@@ -1,475 +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_ASIO_SHARED_HANDLER_H_INCLUDED
#define BEAST_ASIO_SHARED_HANDLER_H_INCLUDED
#include <beast/Config.h>
#include <beast/utility/is_call_possible.h>
#include <boost/utility/base_from_member.hpp>
#include <boost/asio/detail/handler_alloc_helpers.hpp>
#include <boost/asio/detail/handler_cont_helpers.hpp>
#include <boost/asio/detail/handler_invoke_helpers.hpp>
#include <beast/utility/noexcept.h>
#include <functional>
#include <memory>
#include <beast/cxx14/type_traits.h> // <type_traits>
#ifndef BEAST_ASIO_NO_ALLOCATE_SHARED
#define BEAST_ASIO_NO_ALLOCATE_SHARED 0
#endif
#ifndef BEAST_ASIO_NO_HANDLER_RESULT_OF
#define BEAST_ASIO_NO_HANDLER_RESULT_OF 1
#endif
namespace beast {
namespace asio {
class shared_handler_wrapper_base
{
public:
virtual ~shared_handler_wrapper_base()
{
}
virtual void invoke (std::function <void (void)> f) = 0;
virtual void* allocate (std::size_t size) = 0;
virtual void deallocate (void* p, std::size_t size) = 0;
virtual bool is_continuation () = 0;
};
//------------------------------------------------------------------------------
template <class Signature>
class shared_handler_wrapper_func
: public shared_handler_wrapper_base
{
private:
std::function <Signature> m_func;
public:
template <class Handler>
explicit shared_handler_wrapper_func (Handler&& handler)
: m_func (std::ref (std::forward <Handler> (handler)))
{
}
template <class... Args>
#if BEAST_ASIO_NO_HANDLER_RESULT_OF
void
#else
std::result_of_t <std::function <Signature> (Args...)>
#endif
operator() (Args&&... args) const
{
return m_func (std::forward <Args> (args)...);
}
};
//------------------------------------------------------------------------------
namespace detail {
#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable: 4512) // assignment operator could not be generated
#endif
template <class Signature, class Handler>
class shared_handler_wrapper
: private boost::base_from_member <Handler>
, public shared_handler_wrapper_func <Signature>
{
private:
typedef boost::base_from_member <Handler> Base;
BEAST_DEFINE_IS_CALL_POSSIBLE(has_is_continuation, is_continuation);
public:
shared_handler_wrapper (Handler&& handler)
: boost::base_from_member <Handler> (std::move (handler))
, shared_handler_wrapper_func <Signature> (Base::member)
{
}
shared_handler_wrapper (Handler const& handler)
: boost::base_from_member <Handler> (handler)
, shared_handler_wrapper_func <Signature> (Base::member)
{
}
private:
void
invoke (std::function <void (void)> f) override
{
return boost_asio_handler_invoke_helpers::
invoke (f, Base::member);
}
void*
allocate (std::size_t size) override
{
return boost_asio_handler_alloc_helpers::
allocate (size, Base::member);
}
void
deallocate (void* p, std::size_t size) override
{
boost_asio_handler_alloc_helpers::
deallocate (p, size, Base::member);
}
bool
is_continuation () override
{
return is_continuation (std::integral_constant <bool,
has_is_continuation <Handler, bool(void)>::value>());
}
bool
is_continuation (std::true_type)
{
return Base::member.is_continuation();
}
bool
is_continuation (std::false_type)
{
return boost_asio_handler_cont_helpers::
is_continuation (Base::member);
}
};
#ifdef _MSC_VER
#pragma warning (pop)
#endif
template <class T>
struct is_shared_handler : public std::false_type
{
};
//------------------------------------------------------------------------------
template <class T, class Handler>
class handler_allocator
{
private:
// We want a partial template specialization as a friend
// but that isn't allowed so we friend all versions. This
// should produce a compile error if Handler is not constructible
// from H.
//
template <class U, class H>
friend class handler_allocator;
Handler m_handler;
public:
typedef T value_type;
typedef T* pointer;
template <class U>
struct rebind
{
public:
typedef handler_allocator <U, Handler> other;
};
handler_allocator() = delete;
handler_allocator (Handler const& handler)
: m_handler (handler)
{
}
template <class U>
handler_allocator (
handler_allocator <U, Handler> const& other)
: m_handler (other.m_handler)
{
}
handler_allocator&
operator= (handler_allocator const&) = delete;
pointer
allocate (std::ptrdiff_t n)
{
auto const size (n * sizeof (T));
return static_cast <pointer> (
boost_asio_handler_alloc_helpers::allocate (
size, m_handler));
}
void
deallocate (pointer p, std::ptrdiff_t n)
{
auto const size (n * sizeof (T));
boost_asio_handler_alloc_helpers::deallocate (
p, size, m_handler);
}
// Work-around for MSVC not using allocator_traits
// in the implementation of shared_ptr
//
#ifdef _MSC_VER
void
destroy (T* t)
{
t->~T();
}
#endif
friend
bool
operator== (handler_allocator const& lhs, handler_allocator const& rhs)
{
return true;
}
friend
bool
operator!= (handler_allocator const& lhs, handler_allocator const& rhs)
{
return ! (lhs == rhs);
}
};
}
//------------------------------------------------------------------------------
/** Handler shared reference that provides io_service execution guarantees. */
template <class Signature>
class shared_handler
{
private:
template <class T>
friend class shared_handler_allocator;
typedef shared_handler_wrapper_func <
Signature> wrapper_type;
typedef std::shared_ptr <wrapper_type> ptr_type;
ptr_type m_ptr;
public:
shared_handler()
{
}
template <
class DeducedHandler,
class = std::enable_if_t <
! detail::is_shared_handler <
std::decay_t <DeducedHandler>>::value &&
std::is_constructible <std::function <Signature>,
std::decay_t <DeducedHandler>>::value
>
>
shared_handler (DeducedHandler&& handler)
{
typedef std::remove_reference_t <DeducedHandler> Handler;
#if BEAST_ASIO_NO_ALLOCATE_SHARED
m_ptr = std::make_shared <detail::shared_handler_wrapper <
Signature, Handler>> (std::forward <DeducedHandler> (handler));
#else
m_ptr = std::allocate_shared <detail::shared_handler_wrapper <
Signature, Handler>> (detail::handler_allocator <char, Handler> (
handler), std::forward <DeducedHandler> (handler));
#endif
}
shared_handler (shared_handler&& other)
: m_ptr (std::move (other.m_ptr))
{
}
shared_handler (shared_handler const& other)
: m_ptr (other.m_ptr)
{
}
shared_handler&
operator= (std::nullptr_t)
{
m_ptr = nullptr;
return *this;
}
shared_handler&
operator= (shared_handler const& rhs)
{
m_ptr = rhs.m_ptr;
return *this;
}
shared_handler&
operator= (shared_handler&& rhs)
{
m_ptr = std::move (rhs.m_ptr);
return *this;
}
explicit
operator bool() const noexcept
{
return m_ptr.operator bool();
}
void
reset()
{
m_ptr.reset();
}
template <class... Args>
#if BEAST_ASIO_NO_HANDLER_RESULT_OF
void
#else
std::result_of_t <std::function <Signature> (Args...)>
#endif
operator() (Args&&... args) const
{
return (*m_ptr)(std::forward <Args> (args)...);
}
template <class Function>
friend
void
asio_handler_invoke (Function&& f, shared_handler* h)
{
return h->m_ptr->invoke (f);
}
friend
void*
asio_handler_allocate (
std::size_t size, shared_handler* h)
{
return h->m_ptr->allocate (size);
}
friend
void
asio_handler_deallocate (
void* p, std::size_t size, shared_handler* h)
{
return h->m_ptr->deallocate (p, size);
}
friend
bool
asio_handler_is_continuation (
shared_handler* h)
{
return h->m_ptr->is_continuation ();
}
};
//------------------------------------------------------------------------------
namespace detail {
template <
class Signature
>
struct is_shared_handler <
shared_handler <Signature>
> : public std::true_type
{
};
}
//------------------------------------------------------------------------------
template <class T>
class shared_handler_allocator
{
private:
template <class U>
friend class shared_handler_allocator;
std::shared_ptr <shared_handler_wrapper_base> m_ptr;
public:
typedef T value_type;
typedef T* pointer;
shared_handler_allocator() = delete;
template <class Signature>
shared_handler_allocator (
shared_handler <Signature> const& handler)
: m_ptr (handler.m_ptr)
{
}
template <class U>
shared_handler_allocator (
shared_handler_allocator <U> const& other)
: m_ptr (other.m_ptr)
{
}
pointer
allocate (std::ptrdiff_t n)
{
auto const size (n * sizeof (T));
return static_cast <pointer> (
m_ptr->allocate (size));
}
void
deallocate (pointer p, std::ptrdiff_t n)
{
auto const size (n * sizeof (T));
m_ptr->deallocate (p, size);
}
friend
bool
operator== (shared_handler_allocator const& lhs,
shared_handler_allocator const& rhs)
{
return lhs.m_ptr == rhs.m_ptr;
}
friend
bool
operator!= (shared_handler_allocator const& lhs,
shared_handler_allocator const& rhs)
{
return ! (lhs == rhs);
}
};
}
}
#endif

View File

@@ -1,826 +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_ASIO_SOCKET_WRAPPER_H_INCLUDED
#define BEAST_ASIO_SOCKET_WRAPPER_H_INCLUDED
#include <beast/asio/abstract_socket.h>
#include <beast/asio/bind_handler.h>
#include <beast/utility/noexcept.h>
namespace beast {
namespace asio {
/** Wraps a reference to any object and exports all availble interfaces.
If the object does not support an interface, calling those
member functions will behave as if a pure virtual was called.
Note that only a reference to the underlying is stored. Management
of the lifetime of the object is controlled by the caller.
Examples of the type of Object:
asio::ip::tcp::socket
asio::ip::tcp::socket&
asio::ssl::stream <asio::ip::tcp::socket>
asio::ssl::stream <asio::ip::tcp::socket&>
explain arg must be an io_context
explain socket_wrapper will create and take ownership of the tcp::socket
explain this_layer_type will be tcp::socket
explain next_layer () returns a asio::ip::tcp::socket&
explain lowest_layer () returns a asio::ip::tcp::socket&
asio::ssl::stream <asio::buffered_stream <asio::ip::tcp::socket> > >
This makes my head explode
*/
template <typename Object>
class socket_wrapper : public abstract_socket
{
private:
Object m_object;
public:
template <class... Args>
explicit socket_wrapper (Args&&... args)
: m_object (std::forward <Args> (args)...)
{
}
socket_wrapper (socket_wrapper const&) = delete;
socket_wrapper& operator= (socket_wrapper const&) = delete;
//--------------------------------------------------------------------------
//
// socket_wrapper
//
//--------------------------------------------------------------------------
/** The type of the object being wrapped. */
typedef typename boost::remove_reference <Object>::type this_layer_type;
/** Get a reference to this layer. */
this_layer_type& this_layer () noexcept
{
return m_object;
}
/** Get a const reference to this layer. */
this_layer_type const& this_layer () const noexcept
{
return m_object;
}
//--------------------------------------------------------------------------
//
// abstract_socket
//
//--------------------------------------------------------------------------
void* this_layer_ptr (char const* type_name) const override
{
char const* const name (typeid (this_layer_type).name ());
if (strcmp (name, type_name) == 0)
return const_cast <void*> (static_cast <void const*> (&m_object));
return nullptr;
}
private:
BEAST_DEFINE_IS_CALL_POSSIBLE(has_get_io_service, get_io_service);
BEAST_DEFINE_IS_CALL_POSSIBLE(has_lowest_layer, lowest_layer);
BEAST_DEFINE_IS_CALL_POSSIBLE(has_cancel, cancel);
BEAST_DEFINE_IS_CALL_POSSIBLE(has_shutdown, shutdown);
BEAST_DEFINE_IS_CALL_POSSIBLE(has_close, close);
BEAST_DEFINE_IS_CALL_POSSIBLE(has_accept, accept);
BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_accept, async_accept);
BEAST_DEFINE_IS_CALL_POSSIBLE(has_read_some, read_some);
BEAST_DEFINE_IS_CALL_POSSIBLE(has_write_some, write_some);
BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_read_some, async_read_some);
BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_write_some, async_write_some);
BEAST_DEFINE_IS_CALL_POSSIBLE(has_set_verify_mode, set_verify_mode);
BEAST_DEFINE_IS_CALL_POSSIBLE(has_handshake, handshake);
BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_handshake, async_handshake);
BEAST_DEFINE_IS_CALL_POSSIBLE(has_async_shutdown, async_shutdown);
//--------------------------------------------------------------------------
//
// Implementation
//
//--------------------------------------------------------------------------
template <class Cond>
struct Enabled : public std::integral_constant <bool, Cond::value>
{
};
//--------------------------------------------------------------------------
//
// native_handle
//
//--------------------------------------------------------------------------
#if 0
// This is a potential work-around for the problem with
// the has_type_native_handle_type template, but requires
// Boost 1.54 or later.
//
// This include will be needed:
//
// boost/tti/has_type.hpp
//
//
BOOST_TTI_HAS_TYPE(native_handle_type)
#else
template <class T>
struct has_type_native_handle_type
{
typedef char yes;
typedef struct {char dummy[2];} no;
template <class C> static yes f(typename C::native_handle_type*);
template <class C> static no f(...);
#ifdef _MSC_VER
static bool const value = sizeof(f<T>(0)) == 1;
#else
// This line fails to compile under Visual Studio 2012
static bool const value = sizeof(
has_type_native_handle_type<T>::f<T>(0)) == 1;
#endif
};
#endif
template <typename T,
bool Exists = has_type_native_handle_type <T>::value
>
struct extract_native_handle_type
{
typedef typename T::native_handle_type type;
};
template <typename T>
struct extract_native_handle_type <T, false>
{
typedef void type;
};
// This will be void if native_handle_type doesn't exist in Object
typedef typename extract_native_handle_type <
this_layer_type>::type native_handle_type;
//--------------------------------------------------------------------------
bool native_handle (char const* type_name, void* dest) override
{
return native_handle (type_name, dest,
Enabled <has_type_native_handle_type <this_layer_type> > ());
}
bool native_handle (char const* type_name, void* dest,
std::true_type)
{
char const* const name (typeid (
typename this_layer_type::native_handle_type).name ());
if (strcmp (name, type_name) == 0)
{
native_handle_type* const p (reinterpret_cast <
native_handle_type*> (dest));
*p = m_object.native_handle ();
return true;
}
return false;
}
bool native_handle (char const*, void*,
std::false_type)
{
pure_virtual_called();
return false;
}
//--------------------------------------------------------------------------
//
// basic_io_object
//
//--------------------------------------------------------------------------
boost::asio::io_service& get_io_service () override
{
return get_io_service (
Enabled <has_get_io_service <this_layer_type,
boost::asio::io_service&()> > ());
}
boost::asio::io_service& get_io_service (
std::true_type)
{
return m_object.get_io_service ();
}
boost::asio::io_service& get_io_service (
std::false_type)
{
pure_virtual_called();
return *static_cast <boost::asio::io_service*>(nullptr);
}
//--------------------------------------------------------------------------
//
// basic_socket
//
//--------------------------------------------------------------------------
/*
To forward the lowest_layer_type type, we need to make sure it
exists in Object. This is a little more tricky than just figuring
out if Object has a particular member function.
The problem is boost::asio::basic_socket_acceptor, which doesn't
have lowest_layer () or lowest_layer_type ().
*/
template <class T>
struct has_type_lowest_layer_type
{
typedef char yes;
typedef struct {char dummy[2];} no;
template <class C> static yes f(typename C::lowest_layer_type*);
template <class C> static no f(...);
#ifdef _MSC_VER
static bool const value = sizeof(f<T>(0)) == 1;
#else
// This line fails to compile under Visual Studio 2012
static bool const value = sizeof(has_type_lowest_layer_type<T>::f<T>(0)) == 1;
#endif
};
template <typename T, bool Exists = has_type_lowest_layer_type <T>::value >
struct extract_lowest_layer_type
{
typedef typename T::lowest_layer_type type;
};
template <typename T>
struct extract_lowest_layer_type <T, false>
{
typedef void type;
};
// This will be void if lowest_layer_type doesn't exist in Object
typedef typename extract_lowest_layer_type <this_layer_type>::type lowest_layer_type;
//--------------------------------------------------------------------------
void* lowest_layer_ptr (char const* type_name) const override
{
return lowest_layer_ptr (type_name,
Enabled <has_type_lowest_layer_type <this_layer_type> > ());
}
void* lowest_layer_ptr (char const* type_name,
std::true_type) const
{
char const* const name (typeid (typename this_layer_type::lowest_layer_type).name ());
if (strcmp (name, type_name) == 0)
return const_cast <void*> (static_cast <void const*> (&m_object.lowest_layer ()));
return nullptr;
}
void* lowest_layer_ptr (char const*,
std::false_type) const
{
pure_virtual_called();
return nullptr;
}
//--------------------------------------------------------------------------
error_code cancel (error_code& ec) override
{
return cancel (ec,
Enabled <has_cancel <this_layer_type,
error_code (error_code&)> > ());
}
error_code cancel (error_code& ec,
std::true_type)
{
return m_object.cancel (ec);
}
error_code cancel (error_code& ec,
std::false_type)
{
return pure_virtual_error (ec);
}
//--------------------------------------------------------------------------
error_code shutdown (shutdown_type what, error_code& ec) override
{
return shutdown (what, ec,
Enabled <has_shutdown <this_layer_type,
error_code (shutdown_type, error_code&)> > ());
}
error_code shutdown (shutdown_type what, error_code& ec,
std::true_type)
{
return m_object.shutdown (what, ec);
}
error_code shutdown (shutdown_type, error_code& ec,
std::false_type)
{
return pure_virtual_error (ec);
}
//--------------------------------------------------------------------------
error_code close (error_code& ec) override
{
return close (ec,
Enabled <has_close <this_layer_type,
error_code (error_code&)> > ());
}
error_code close (error_code& ec,
std::true_type)
{
return m_object.close (ec);
}
error_code close (error_code& ec,
std::false_type)
{
return pure_virtual_error (ec);
}
//--------------------------------------------------------------------------
//
// basic_socket_acceptor
//
//--------------------------------------------------------------------------
// Extracts the underlying socket type from the protocol of another asio object
template <typename T, typename Enable = void>
struct native_socket
{
typedef void* socket_type;
inline native_socket (abstract_socket&)
: m_socket (nullptr)
{
abstract_socket::pure_virtual_called();
}
inline socket_type& get ()
{
abstract_socket::pure_virtual_called();
return m_socket;
}
inline socket_type& operator-> ()
{
return get ();
}
private:
socket_type m_socket;
};
// Enabled if T::protocol_type::socket exists as a type
template <typename T>
struct native_socket <T, typename boost::enable_if <boost::is_class <
typename T::protocol_type::socket> >::type>
{
typedef typename T::protocol_type::socket socket_type;
inline native_socket (abstract_socket& peer)
: m_socket_ptr (&peer.this_layer <socket_type> ())
{
}
inline socket_type& get () noexcept
{
return *m_socket_ptr;
}
inline socket_type& operator-> () noexcept
{
return get ();
}
private:
socket_type* m_socket_ptr;
};
//--------------------------------------------------------------------------
error_code accept (abstract_socket& peer, error_code& ec) override
{
typedef typename native_socket <this_layer_type>::socket_type socket_type;
return accept (peer, ec,
Enabled <has_accept <this_layer_type,
error_code (socket_type&, error_code&)> > ());
}
error_code accept (abstract_socket& peer, error_code& ec,
std::true_type)
{
return m_object.accept (
native_socket <this_layer_type> (peer).get (), ec);
}
error_code accept (abstract_socket&, error_code& ec,
std::false_type)
{
return pure_virtual_error (ec);
}
//--------------------------------------------------------------------------
void async_accept (abstract_socket& peer, error_handler handler) override
{
typedef typename native_socket <this_layer_type>::socket_type socket_type;
async_accept (peer, handler,
Enabled <has_async_accept <this_layer_type,
void (socket_type&, error_handler)> > ());
}
void async_accept (abstract_socket& peer, error_handler const& handler,
std::true_type)
{
m_object.async_accept (
native_socket <this_layer_type> (peer).get (), handler);
}
void async_accept (abstract_socket&, error_handler const& handler,
std::false_type)
{
get_io_service ().post (bind_handler (
handler, pure_virtual_error()));
}
//--------------------------------------------------------------------------
//
// basic_stream_socket
//
//--------------------------------------------------------------------------
std::size_t
read_some (mutable_buffers buffers, error_code& ec) override
{
return read_some (buffers, ec,
Enabled <has_read_some <this_layer_type,
std::size_t (mutable_buffers const&, error_code&)> > ());
}
std::size_t
read_some (mutable_buffers const& buffers, error_code& ec,
std::true_type)
{
return m_object.read_some (buffers, ec);
}
std::size_t read_some (mutable_buffers const&, error_code& ec,
std::false_type)
{
ec = pure_virtual_error ();
return 0;
}
//--------------------------------------------------------------------------
std::size_t
write_some (const_buffers buffers, error_code& ec) override
{
return write_some (buffers, ec,
Enabled <has_write_some <this_layer_type,
std::size_t (const_buffers const&, error_code&)> > ());
}
std::size_t
write_some (const_buffers const& buffers, error_code& ec,
std::true_type)
{
return m_object.write_some (buffers, ec);
}
std::size_t
write_some (const_buffers const&, error_code& ec,
std::false_type)
{
ec = pure_virtual_error ();
return 0;
}
//--------------------------------------------------------------------------
void async_read_some (mutable_buffers buffers,
transfer_handler handler) override
{
async_read_some (buffers, handler,
Enabled <has_async_read_some <this_layer_type,
void (mutable_buffers const&, transfer_handler const&)> > ());
}
void
async_read_some (mutable_buffers const& buffers,
transfer_handler const& handler,
std::true_type)
{
m_object.async_read_some (buffers, handler);
}
void
async_read_some (mutable_buffers const&,
transfer_handler const& handler,
std::false_type)
{
get_io_service ().post (bind_handler (
handler, pure_virtual_error(), 0));
}
//--------------------------------------------------------------------------
void
async_write_some (const_buffers buffers,
transfer_handler handler) override
{
async_write_some (buffers, handler,
Enabled <has_async_write_some <this_layer_type,
void (const_buffers const&, transfer_handler const&)> > ());
}
void
async_write_some (const_buffers const& buffers,
transfer_handler const& handler,
std::true_type)
{
m_object.async_write_some (buffers, handler);
}
void
async_write_some (const_buffers const&,
transfer_handler const& handler,
std::false_type)
{
get_io_service ().post (bind_handler (
handler, pure_virtual_error(), 0));
}
//--------------------------------------------------------------------------
//
// ssl::stream
//
//--------------------------------------------------------------------------
template <class T>
struct has_type_next_layer_type
{
typedef char yes;
typedef struct {char dummy[2];} no;
template <class C> static yes f(typename C::next_layer_type*);
template <class C> static no f(...);
#ifdef _MSC_VER
static bool const value = sizeof(f<T>(0)) == 1;
#else
// This line fails to compile under Visual Studio 2012
static bool const value = sizeof(has_type_next_layer_type<T>::f<T>(0)) == 1;
#endif
};
template <typename T, bool Exists = has_type_next_layer_type <T>::value >
struct extract_next_layer_type
{
typedef typename T::next_layer_type type;
};
template <typename T>
struct extract_next_layer_type <T, false>
{
typedef void type;
};
// This will be void if next_layer_type doesn't exist in Object
typedef typename extract_next_layer_type <this_layer_type>::type next_layer_type;
//--------------------------------------------------------------------------
void* next_layer_ptr (char const* type_name) const override
{
return next_layer_ptr (type_name,
Enabled <has_type_next_layer_type <this_layer_type> > ());
}
void* next_layer_ptr (char const* type_name,
std::true_type) const
{
char const* const name (typeid (typename this_layer_type::next_layer_type).name ());
if (strcmp (name, type_name) == 0)
return const_cast <void*> (static_cast <void const*> (&m_object.next_layer ()));
return nullptr;
}
void* next_layer_ptr (char const*,
std::false_type) const
{
pure_virtual_called();
return nullptr;
}
//--------------------------------------------------------------------------
bool needs_handshake () override
{
return
has_handshake <this_layer_type,
error_code (handshake_type, error_code&)>::value ||
has_async_handshake <this_layer_type,
void (handshake_type, error_handler)>::value;
}
//--------------------------------------------------------------------------
void set_verify_mode (int verify_mode) override
{
set_verify_mode (verify_mode,
Enabled <has_set_verify_mode <this_layer_type,
void (int)> > ());
}
void set_verify_mode (int verify_mode,
std::true_type)
{
m_object.set_verify_mode (verify_mode);
}
void set_verify_mode (int,
std::false_type)
{
pure_virtual_called();
}
//--------------------------------------------------------------------------
error_code
handshake (handshake_type type, error_code& ec) override
{
return handshake (type, ec,
Enabled <has_handshake <this_layer_type,
error_code (handshake_type, error_code&)> > ());
}
error_code
handshake (handshake_type type, error_code& ec,
std::true_type)
{
return m_object.handshake (type, ec);
}
error_code
handshake (handshake_type, error_code& ec,
std::false_type)
{
return pure_virtual_error (ec);
}
//--------------------------------------------------------------------------
void async_handshake (handshake_type type, error_handler handler) override
{
async_handshake (type, handler,
Enabled <has_async_handshake <this_layer_type,
void (handshake_type, error_handler)> > ());
}
void async_handshake (handshake_type type, error_handler const& handler,
std::true_type)
{
m_object.async_handshake (type, handler);
}
void async_handshake (handshake_type, error_handler const& handler,
std::false_type)
{
get_io_service ().post (bind_handler (
handler, pure_virtual_error()));
}
//--------------------------------------------------------------------------
error_code
handshake (handshake_type type, const_buffers buffers,
error_code& ec) override
{
return handshake (type, buffers, ec,
Enabled <has_handshake <this_layer_type,
error_code (handshake_type, const_buffers const&, error_code&)> > ());
}
error_code
handshake (handshake_type type, const_buffers const& buffers,
error_code& ec,
std::true_type)
{
return m_object.handshake (type, buffers, ec);
}
error_code
handshake (handshake_type, const_buffers const&,
error_code& ec,
std::false_type)
{
return pure_virtual_error (ec);
}
//--------------------------------------------------------------------------
void async_handshake (handshake_type type,
const_buffers buffers, transfer_handler handler) override
{
async_handshake (type, buffers, handler,
Enabled <has_async_handshake <this_layer_type,
void (handshake_type, const_buffers const&,
transfer_handler)> > ());
}
void async_handshake (handshake_type type, const_buffers const& buffers,
transfer_handler const& handler,
std::true_type)
{
m_object.async_handshake (type, buffers, handler);
}
void async_handshake (handshake_type, const_buffers const&,
transfer_handler const& handler,
std::false_type)
{
get_io_service ().post (bind_handler (
handler, pure_virtual_error(), 0));
}
//--------------------------------------------------------------------------
error_code shutdown (error_code& ec) override
{
return shutdown (ec,
Enabled <has_shutdown <this_layer_type,
error_code (error_code&)> > ());
}
error_code shutdown (error_code& ec,
std::true_type)
{
return m_object.shutdown (ec);
}
error_code shutdown (error_code& ec,
std::false_type)
{
return pure_virtual_error (ec);
}
//--------------------------------------------------------------------------
void async_shutdown (error_handler handler) override
{
async_shutdown (handler,
Enabled <has_async_shutdown <this_layer_type,
void (error_handler)> > ());
}
void async_shutdown (error_handler const& handler,
std::true_type)
{
m_object.async_shutdown (handler);
}
void async_shutdown (error_handler const& handler,
std::false_type)
{
get_io_service ().post (bind_handler (
handler, pure_virtual_error()));
}
};
}
}
#endif

View 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

View File

@@ -17,33 +17,663 @@
*/
//==============================================================================
#ifndef BEAST_ASIO_BASIC_STREAMBUF_H_INCLUDED
#define BEAST_ASIO_BASIC_STREAMBUF_H_INCLUDED
#ifndef BEAST_ASIO_STREAMBUF_H_INCLUDED
#define BEAST_ASIO_STREAMBUF_H_INCLUDED
#include <beast/utility/empty_base_optimization.h>
#include <boost/asio/buffer.hpp>
#include <boost/intrusive/list.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <algorithm>
#include <cassert>
#include <memory>
#include <vector>
#include <exception>
#include <beast/cxx14/type_traits.h> // <type_traits>
#include <string>
#include <utility>
namespace beast {
namespace asio {
template <class Alloc = std::allocator <char>>
class basic_streambuf : private Alloc
/** Implements asio::streambuf interface using multiple buffers. */
template <class Allocator>
class basic_streambuf
: private empty_base_optimization<Allocator>
{
public:
using size_type = typename std::allocator_traits<Allocator>::size_type;
using const_buffer = boost::asio::const_buffer;
using mutable_buffer = boost::asio::mutable_buffer;
private:
typedef std::allocator_traits <Alloc> alloc_traits;
std::vector <boost::asio::mutable_buffer> bufs_;
class element;
using alloc_traits = std::allocator_traits<Allocator>;
using list_type = typename boost::intrusive::make_list <element,
boost::intrusive::constant_time_size <true>>::type;
using iterator = typename list_type::iterator;
using const_iterator = typename list_type::const_iterator;
/* These diagrams illustrate the layout and state variables.
Input and output contained entirely in one element:
0 out_
|<-------------+------------------------------------------->|
in_pos_ out_pos_ out_end_
Output contained in first and second elements:
out_
|<------+----------+------->| |<----------+-------------->|
in_pos_ out_pos_ out_end_
Output contained in the second element:
out_
|<------------+------------>| |<----+-------------------->|
in_pos_ out_pos_ out_end_
Output contained in second and third elements:
out_
|<-----+-------->| |<-------+------>| |<--------------->|
in_pos_ out_pos_ out_end_
Input sequence is empty:
out_
|<------+------------------>| |<-----------+------------->|
out_pos_ out_end_
in_pos_
Output sequence is empty:
out_
|<------+------------------>| |<------+------------------>|
in_pos_ out_pos_
out_end_
The end of output can point to the end of an element.
But out_pos_ should never point to the end:
out_
|<------+------------------>| |<------+------------------>|
in_pos_ out_pos_ out_end_
When the input sequence entirely fills the last element and
the output sequence is empty, out_ will point to the end of
the list of buffers, and out_pos_ and out_end_ will be 0:
|<------+------------------>| out_ == list_.end()
in_pos_ out_pos_ == 0
out_end_ == 0
*/
list_type list_;
size_type block_size_;
size_type block_size_next_;
size_type in_size_ = 0; // size of the input sequence
iterator out_; // element that contains out_pos_
size_type in_pos_ = 0; // input offset in list_.front()
size_type out_pos_ = 0; // output offset in *out_
size_type out_end_ = 0; // output end offset in list_.back()
public:
~basic_streambuf()
class const_buffers_type;
class mutable_buffers_type;
basic_streambuf (basic_streambuf const& other) = delete;
basic_streambuf& operator= (basic_streambuf const& other) = delete;
basic_streambuf& operator= (basic_streambuf&& other) = delete;
~basic_streambuf();
explicit
basic_streambuf(std::size_t block_size = 16*1024,
Allocator const& alloc = Allocator{});
basic_streambuf (basic_streambuf&& other);
/** Get the maximum size of the basic_streambuf. */
size_type
max_size() const
{
for (auto const& buf : bufs_)
alloc_traits::deallocate (
boost::asio::buffer_cast<char const*>(buf));
return std::numeric_limits<std::size_t>::max();
}
/** Get the size of the input sequence. */
size_type
size() const
{
return in_size_;
}
/** Get a list of buffers that represents the output sequence, with the given size. */
mutable_buffers_type
prepare (size_type n);
/** Move bytes from the output sequence to the input sequence. */
void
commit (size_type n);
/** Get a list of buffers that represents the input sequence. */
const_buffers_type
data() const;
/** Remove bytes from the input sequence. */
void
consume (size_type n);
private:
void
debug_check() const;
};
//------------------------------------------------------------------------------
template <class Allocator>
class basic_streambuf<Allocator>::element
: public boost::intrusive::list_base_hook <
boost::intrusive::link_mode <boost::intrusive::normal_link>>
{
private:
size_type const size_; // size of the allocation minus sizeof(element)
public:
element (element const&) = delete;
element& operator= (element const&) = delete;
explicit
element (size_type block_size)
: size_(block_size)
{ }
size_type
size() const
{
return size_;
}
size_type
alloc_size() const
{
return size_ + sizeof(*this);
}
char*
data() const
{
return const_cast<char*>(
reinterpret_cast<char const*>(this+1));
}
};
//------------------------------------------------------------------------------
template <class Allocator>
class basic_streambuf<Allocator>::const_buffers_type
{
public:
using value_type = const_buffer;
private:
struct transform
{
using argument_type = element;
using result_type = value_type;
basic_streambuf const* streambuf_ = nullptr;
transform() = default;
explicit
transform (basic_streambuf const& streambuf)
: streambuf_ (&streambuf)
{
}
value_type const
operator() (element const& e) const;
};
basic_streambuf const* streambuf_ = nullptr;
public:
using const_iterator = boost::transform_iterator<
transform, typename list_type::const_iterator,
value_type, value_type>;
const_buffers_type() = default;
const_buffers_type (const_buffers_type const&) = default;
const_buffers_type& operator= (const_buffers_type const&) = default;
const_iterator
begin() const
{
return const_iterator (streambuf_->list_.begin(),
transform(*streambuf_));
}
const_iterator
end() const
{
return const_iterator (streambuf_->out_ ==
streambuf_->list_.end() ? streambuf_->list_.end() :
std::next(streambuf_->out_), transform(*streambuf_));
}
private:
friend class basic_streambuf;
explicit
const_buffers_type (basic_streambuf const& streambuf);
};
template <class Allocator>
basic_streambuf<Allocator>::const_buffers_type::const_buffers_type (
basic_streambuf const& streambuf)
: streambuf_ (&streambuf)
{
}
template <class Allocator>
auto
basic_streambuf<Allocator>::const_buffers_type::
transform::operator() (element const& e) const ->
value_type const
{
return value_type (e.data(),
(streambuf_->out_ == streambuf_->list_.end() ||
&e != &*streambuf_->out_) ? e.size() : streambuf_->out_pos_) +
(&e == &*streambuf_->list_.begin() ?
streambuf_->in_pos_ : 0);
}
//------------------------------------------------------------------------------
template <class Allocator>
class basic_streambuf<Allocator>::mutable_buffers_type
{
public:
using value_type = mutable_buffer;
private:
struct transform
{
using argument_type = element;
using result_type = value_type;
basic_streambuf const* streambuf_ = nullptr;
transform() = default;
explicit
transform (basic_streambuf const& streambuf)
: streambuf_ (&streambuf)
{
}
value_type const
operator() (element const& e) const;
};
basic_streambuf const* streambuf_;
public:
using const_iterator = boost::transform_iterator<
transform, typename list_type::const_iterator,
value_type, value_type>;
mutable_buffers_type() = default;
mutable_buffers_type (mutable_buffers_type const&) = default;
mutable_buffers_type& operator= (mutable_buffers_type const&) = default;
const_iterator
begin() const
{
return const_iterator (streambuf_->out_,
transform(*streambuf_));
}
const_iterator
end() const
{
return const_iterator (streambuf_->list_.end(),
transform(*streambuf_));
}
private:
friend class basic_streambuf;
mutable_buffers_type (basic_streambuf const& streambuf);
};
template <class Allocator>
basic_streambuf<Allocator>::mutable_buffers_type::mutable_buffers_type (
basic_streambuf const& streambuf)
: streambuf_ (&streambuf)
{
}
template <class Allocator>
auto
basic_streambuf<Allocator>::mutable_buffers_type::
transform::operator() (element const& e) const ->
value_type const
{
return value_type (e.data(), &e == &*std::prev(streambuf_->list_.end()) ?
streambuf_->out_end_ : e.size()) + (&e == &*streambuf_->out_ ?
streambuf_->out_pos_ : 0);
}
//------------------------------------------------------------------------------
template <class Allocator>
basic_streambuf<Allocator>::~basic_streambuf()
{
for(auto iter = list_.begin(); iter != list_.end();)
{
auto& e = *iter++;
size_type const n = e.alloc_size();
alloc_traits::destroy(this->member(), &e);
alloc_traits::deallocate(this->member(),
reinterpret_cast<char*>(&e), n);
}
}
} // asio
} // beast
template <class Allocator>
basic_streambuf<Allocator>::basic_streambuf(std::size_t block_size,
Allocator const& alloc)
: empty_base_optimization<Allocator>(alloc)
, block_size_ (block_size)
, block_size_next_ (block_size)
, out_ (list_.end())
{
if (! (block_size > 0))
throw std::invalid_argument(
"basic_streambuf: invalid block_size");
}
template <class Allocator>
basic_streambuf<Allocator>::basic_streambuf (basic_streambuf&& other)
: empty_base_optimization<Allocator>(other.member())
, list_ (std::move(other.list_))
, block_size_ (other.block_size_)
, block_size_next_ (other.block_size_next_)
, in_size_ (other.in_size_)
, out_ (other.out_)
, in_pos_ (other.in_pos_)
, out_pos_ (other.out_pos_)
, out_end_ (other.out_end_)
{
other.in_size_ = 0;
other.out_ = other.list_.end();
other.in_pos_ = 0;
other.out_pos_ = 0;
other.out_end_ = 0;
}
template <class Allocator>
auto
basic_streambuf<Allocator>::prepare (size_type n) ->
mutable_buffers_type
{
iterator pos = out_;
if (pos != list_.end())
{
auto const avail = pos->size() - out_pos_;
if (n > avail)
{
n -= avail;
while (++pos != list_.end())
{
if (n < pos->size())
{
out_end_ = n;
n = 0;
++pos;
break;
}
n -= pos->size();
}
}
else
{
++pos;
out_end_ = out_pos_ + n;
n = 0;
}
debug_check();
}
if (n > 0)
{
assert(pos == list_.end());
for(;;)
{
auto const avail = block_size_next_;
auto& e = *reinterpret_cast<element*>(alloc_traits::allocate(
this->member(), avail + sizeof(element)));
alloc_traits::construct(this->member(), &e, avail);
list_.push_back(e);
if (out_ == list_.end())
{
out_ = list_.iterator_to(e);
debug_check();
}
if (n <= avail)
{
out_end_ = n;
debug_check();
break;
}
n -= avail;
}
}
else
{
while (pos != list_.end())
{
auto& e = *pos++;
list_.erase(list_.iterator_to(e));
auto const len = e.alloc_size();
alloc_traits::destroy(this->member(), &e);
alloc_traits::deallocate(this->member(),
reinterpret_cast<char*>(&e), len);
}
debug_check();
}
return mutable_buffers_type (*this);
}
template <class Allocator>
void
basic_streambuf<Allocator>::commit (size_type n)
{
if (list_.empty())
return;
if (out_ == list_.end())
return;
auto const last = std::prev(list_.end());
while (out_ != last)
{
auto const avail =
out_->size() - out_pos_;
if (n < avail)
{
out_pos_ += n;
in_size_ += n;
debug_check();
return;
}
++out_;
n -= avail;
out_pos_ = 0;
in_size_ += avail;
debug_check();
}
n = std::min (n, out_end_ - out_pos_);
out_pos_ += n;
in_size_ += n;
if (out_pos_ == out_->size())
{
++out_;
out_pos_ = 0;
out_end_ = 0;
}
debug_check();
}
template <class Allocator>
auto
basic_streambuf<Allocator>::data() const ->
const_buffers_type
{
return const_buffers_type(*this);
}
template <class Allocator>
void
basic_streambuf<Allocator>::consume (size_type n)
{
if (list_.empty())
return;
auto pos = list_.begin();
for(;;)
{
if (pos != out_)
{
auto const avail = pos->size() - in_pos_;
if (n < avail)
{
in_size_ -= n;
in_pos_ += n;
debug_check();
break;
}
n -= avail;
in_size_ -= avail;
in_pos_ = 0;
debug_check();
element& e = *pos++;
list_.erase(list_.iterator_to(e));
size_type const len = e.alloc_size();
alloc_traits::destroy(this->member(), &e);
alloc_traits::deallocate(this->member(),
reinterpret_cast<char*>(&e), len);
}
else
{
auto const avail = out_pos_ - in_pos_;
if (n < avail)
{
in_size_ -= n;
in_pos_ += n;
}
else
{
in_size_ -= avail;
if (out_pos_ != out_end_||
out_ != list_.iterator_to(list_.back()))
{
in_pos_ = out_pos_;
}
else
{
// Use the whole buffer now.
// Alternatively we could deallocate it.
in_pos_ = 0;
out_pos_ = 0;
out_end_ = 0;
}
}
debug_check();
break;
}
}
}
template <class Allocator>
void
basic_streambuf<Allocator>::debug_check() const
{
#ifndef NDEBUG
if (list_.empty())
{
assert(in_pos_ == 0);
assert(in_size_ == 0);
assert(out_pos_ == 0);
assert(out_end_ == 0);
assert(out_ == list_.end());
return;
}
auto const& front = list_.front();
assert(in_pos_ < front.size());
if (out_ == list_.end())
{
assert(out_pos_ == 0);
assert(out_end_ == 0);
}
else
{
auto const& out = *out_;
auto const& back = list_.back();
assert(out_end_ <= back.size());
assert(out_pos_ < out.size());
assert(&out != &front || out_pos_ >= in_pos_);
assert(&out != &front || out_pos_ - in_pos_ == in_size_);
assert(&out != &back || out_pos_ <= out_end_);
}
#endif
}
template <class Alloc, class T>
basic_streambuf<Alloc>&
operator<< (basic_streambuf<Alloc>& buf, T const& t)
{
std::stringstream ss;
ss << t;
auto const& s = ss.str();
buf.commit(boost::asio::buffer_copy(
buf.prepare(s.size()), boost::asio::buffer(s)));
return buf;
}
//------------------------------------------------------------------------------
using streambuf = basic_streambuf<std::allocator<char>>;
/** Convert the entire basic_streambuf to a string.
@note It is more efficient to deal directly in the streambuf instead.
*/
template <class Allocator>
std::string
to_string (basic_streambuf<Allocator> const& buf)
{
std::string s;
s.resize(buf.size());
boost::asio::buffer_copy(boost::asio::buffer(
&s[0], s.size()), buf.data());
return s;
}
}
}
#endif

View File

@@ -1,105 +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.
*/
//==============================================================================
#if BEAST_INCLUDE_BEASTCONFIG
#include <BeastConfig.h>
#endif
#include <beast/unit_test/suite.h>
#include <beast/asio/bind_handler.h>
#include <beast/asio/enable_wait_for_async.h>
#include <boost/asio/io_service.hpp>
namespace beast {
class enable_wait_for_async_test : public unit_test::suite
{
public:
typedef boost::system::error_code error_code;
void test()
{
struct handler
{
void operator()(error_code)
{
}
};
struct owner : asio::enable_wait_for_async <owner>
{
bool notified;
owner()
: notified (false)
{
}
void operator()()
{
{
boost::asio::io_service ios;
ios.post (asio::bind_handler (handler(),
error_code()));
ios.run();
ios.reset();
wait_for_async();
}
{
boost::asio::io_service ios;
ios.post (wrap_with_counter (asio::bind_handler (
handler(), error_code())));
ios.run();
wait_for_async();
}
{
boost::asio::io_service ios;
handler h;
ios.post (wrap_with_counter (std::bind (
&handler::operator(), &h,
error_code())));
ios.run();
wait_for_async();
}
}
void on_wait_for_async()
{
notified = true;
}
};
owner o;
o();
expect (o.notified);
}
void run()
{
test();
}
};
BEAST_DEFINE_TESTSUITE(enable_wait_for_async,asio,beast);
}

View File

@@ -1,235 +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.
*/
//==============================================================================
#if BEAST_INCLUDE_BEASTCONFIG
#include <BeastConfig.h>
#endif
#include <beast/unit_test/suite.h>
#include <beast/asio/shared_handler.h>
// Disables is_constructible tests for std::function
// Visual Studio std::function fails the is_constructible tests
#ifndef BEAST_NO_STD_FUNCTION_CONSTRUCTIBLE
# ifdef _MSC_VER
# define BEAST_NO_STD_FUNCTION_CONSTRUCTIBLE 1
# else
# define BEAST_NO_STD_FUNCTION_CONSTRUCTIBLE 0
# endif
#endif
namespace beast {
class shared_handler_test : public unit_test::suite
{
public:
struct test_results
{
bool call;
bool invoke;
bool alloc;
bool dealloc;
bool cont;
test_results ()
: call (false)
, invoke (false)
, alloc (false)
, dealloc (false)
, cont (false)
{
}
};
struct test_handler
{
std::reference_wrapper <test_results> results;
explicit test_handler (test_results& results_)
: results (results_)
{
}
void operator() ()
{
results.get().call = true;
}
template <class Function>
friend void asio_handler_invoke (
Function& f, test_handler* h)
{
h->results.get().invoke = true;
f();
}
template <class Function>
friend void asio_handler_invoke (
Function const& f, test_handler* h)
{
h->results.get().invoke = true;
f();
}
friend void* asio_handler_allocate (
std::size_t size, test_handler* h)
{
h->results.get().alloc = true;
return boost::asio::asio_handler_allocate (size);
}
friend void asio_handler_deallocate (
void* p, std::size_t size, test_handler* h)
{
h->results.get().dealloc = true;
boost::asio::asio_handler_deallocate (p, size);
}
friend bool asio_handler_is_continuation (
test_handler* h)
{
h->results.get().cont = true;
return true;
}
};
struct test_invokable
{
bool call;
test_invokable ()
: call (false)
{
}
void operator() ()
{
call = true;
}
};
template <class Handler>
bool async_op (Handler&& handler)
{
void* const p (boost_asio_handler_alloc_helpers::allocate (32, handler));
handler();
boost_asio_handler_alloc_helpers::deallocate (p, 32, handler);
return boost_asio_handler_cont_helpers::is_continuation (handler);
}
void virtual_async_op (asio::shared_handler <void(void)> handler)
{
async_op (handler);
}
void run()
{
#if ! BEAST_NO_STD_FUNCTION_CONSTRUCTIBLE
static_assert (! std::is_constructible <
std::function <void(void)>, int&&>::value,
"Cannot construct std::function from int&&");
static_assert (! std::is_constructible <
std::function <void(void)>, int>::value,
"Cannot construct std::function from int");
static_assert (! std::is_constructible <
asio::shared_handler <void(void)>, int>::value,
"Cannot construct shared_handler from int");
#endif
static_assert (std::is_constructible <
asio::shared_handler <void(int)>,
asio::shared_handler <void(int)>>::value,
"Should construct <void(int)> from <void(int)>");
static_assert (! std::is_constructible <
asio::shared_handler <void(int)>,
asio::shared_handler <void(void)>>::value,
"Can't construct <void(int)> from <void(void)>");
// Hooks called when using the raw handler
{
test_results r;
test_handler h (r);
async_op (h);
expect (r.call);
expect (r.alloc);
expect (r.dealloc);
expect (r.cont);
test_invokable f;
boost_asio_handler_invoke_helpers::invoke (std::ref (f), h);
expect (r.invoke);
expect (f.call);
}
// Use of std::function shows the hooks not getting called
{
test_results r;
std::function <void(void)> fh ((test_handler) (r));
async_op (fh);
expect (r.call);
unexpected (r.alloc);
unexpected (r.dealloc);
unexpected (r.cont);
test_invokable f;
boost_asio_handler_invoke_helpers::invoke (std::ref (f), fh);
unexpected (r.invoke);
expect (f.call);
}
// Make sure shared_handler calls the hooks
{
test_results r;
asio::shared_handler <void(void)> sh ((test_handler)(r));
async_op (sh);
expect (r.call);
expect (r.alloc);
expect (r.dealloc);
expect (r.cont);
test_invokable f;
boost_asio_handler_invoke_helpers::invoke (std::ref (f), sh);
expect (r.invoke);
expect (f.call);
}
// Make sure shared_handler via implicit conversion calls hooks
{
test_results r;
test_handler h (r);
virtual_async_op ((test_handler) (r));
expect (r.call);
expect (r.alloc);
expect (r.dealloc);
expect (r.cont);
}
}
};
BEAST_DEFINE_TESTSUITE(shared_handler,asio,beast);
}

View File

@@ -0,0 +1,158 @@
//------------------------------------------------------------------------------
/*
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 <beast/asio/streambuf.h>
#include <beast/unit_test/suite.h>
namespace beast {
namespace asio {
class streambuf_test : public unit_test::suite
{
public:
// Convert a buffer sequence to a string
template <class Buffers>
static
std::string
to_str (Buffers const& b)
{
std::string s;
auto const n = boost::asio::buffer_size(b);
s.resize(n);
boost::asio::buffer_copy(
boost::asio::buffer(&s[0], n), b);
return s;
}
// Fill a buffer sequence with predictable data
template <class Buffers>
static
void
fill (Buffers const& b)
{
char c = 0;
auto first = boost::asio::buffers_begin(b);
auto last = boost::asio::buffers_end(b);
while (first != last)
*first++ = c++;
}
// Check that a buffer sequence has predictable data
template <class Buffers>
void
check (Buffers const& b, char c = 0)
{
auto first = boost::asio::buffers_begin(b);
auto last = boost::asio::buffers_end(b);
while (first != last)
expect (*first++ == c++);
}
void
test_prepare()
{
testcase << "prepare";
beast::asio::streambuf b(11);
for (std::size_t n = 0; n < 97; ++n)
{
fill(b.prepare(n));
b.commit(n);
check(b.data());
b.consume(n);
}
}
void
test_commit()
{
testcase << "commit";
beast::asio::streambuf b(11);
for (std::size_t n = 0; n < 97; ++n)
{
fill(b.prepare(n));
char c = 0;
for (int i = 1;; ++i)
{
b.commit(i);
check(b.data(), c);
b.consume(i);
if (b.size() < 1)
break;
c += i;
}
}
}
void
test_consume()
{
testcase << "consume";
beast::asio::streambuf b(11);
for (std::size_t n = 0; n < 97; ++n)
{
fill(b.prepare(n));
b.commit(n);
char c = 0;
for (int i = 1; b.size() > 0; ++i)
{
check(b.data(), c);
b.consume(i);
c += i;
}
}
}
void run()
{
{
beast::asio::streambuf b(10);
std::string const s = "1234567890";
b << s;
expect (to_str(b.data()) == s);
b.prepare(5);
}
{
beast::asio::streambuf b(10);
b.prepare(10);
b.commit(10);
b.consume(10);
}
{
beast::asio::streambuf b(5);
boost::asio::buffer_copy(b.prepare(14),
boost::asio::buffer(std::string("1234567890ABCD")));
b.commit(4);
expect(to_str(b.data()) == "1234");
b.consume(4);
b.commit(10);
expect(to_str(b.data()) == "567890ABCD");
}
test_prepare();
test_commit();
test_consume();
}
};
BEAST_DEFINE_TESTSUITE(streambuf,asio,beast);
}
}

View File

@@ -1,280 +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.
*/
//==============================================================================
#if BEAST_INCLUDE_BEASTCONFIG
#include <BeastConfig.h>
#endif
#include <beast/unit_test/suite.h>
#include <beast/asio/wrap_handler.h>
#include <boost/version.hpp>
#include <boost/bind.hpp>
#include <functional>
#include <memory>
namespace beast {
namespace asio {
//------------------------------------------------------------------------------
// Displays the order of destruction of parameters in the bind wrapper
//
class boost_bind_test : public unit_test::suite
{
public:
struct Result
{
std::string text;
void push_back (std::string const& s)
{
if (! text.empty())
text += ", ";
text += s;
}
};
struct Payload
{
std::reference_wrapper <Result> m_result;
std::string m_name;
explicit Payload (Result& result, std::string const& name)
: m_result (result)
, m_name (name)
{
}
~Payload ()
{
m_result.get().push_back (m_name);
}
};
struct Arg
{
std::shared_ptr <Payload> m_payload;
Arg (Result& result, std::string const& name)
: m_payload (std::make_shared <Payload> (result, name))
{
}
};
static void foo (Arg const&, Arg const&, Arg const&)
{
}
void run()
{
{
Result r;
{
boost::bind (&foo,
Arg (r, "one"),
Arg (r, "two"),
Arg (r, "three"));
}
log <<
std::string ("boost::bind (") + r.text + ")";
}
{
Result r;
{
std::bind (&foo,
Arg (r, "one"),
Arg (r, "two"),
Arg (r, "three"));
}
log <<
std::string ("std::bind (") + r.text + ")";
}
pass();
}
};
BEAST_DEFINE_TESTSUITE(boost_bind,asio,beast);
//------------------------------------------------------------------------------
class wrap_handler_test : public unit_test::suite
{
public:
struct test_results
{
bool call;
bool invoke;
bool alloc;
bool dealloc;
bool cont;
test_results ()
: call (false)
, invoke (false)
, alloc (false)
, dealloc (false)
, cont (false)
{
}
};
struct test_handler
{
std::reference_wrapper <test_results> results;
explicit test_handler (test_results& results_)
: results (results_)
{
}
void operator() ()
{
results.get().call = true;
}
template <class Function>
friend void asio_handler_invoke (
Function& f, test_handler* h)
{
h->results.get().invoke = true;
f();
}
template <class Function>
friend void asio_handler_invoke (
Function const& f, test_handler* h)
{
h->results.get().invoke = true;
f();
}
friend void* asio_handler_allocate (
std::size_t, test_handler* h)
{
h->results.get().alloc = true;
return nullptr;
}
friend void asio_handler_deallocate (
void*, std::size_t, test_handler* h)
{
h->results.get().dealloc = true;
}
friend bool asio_handler_is_continuation (
test_handler* h)
{
h->results.get().cont = true;
return true;
}
};
struct test_invokable
{
bool call;
test_invokable ()
: call (false)
{
}
void operator() ()
{
call = true;
}
};
template <class Handler>
bool async_op (Handler&& handler)
{
void* const p (boost_asio_handler_alloc_helpers::allocate (32, handler));
(handler)();
boost_asio_handler_alloc_helpers::deallocate (p, 32, handler);
return boost_asio_handler_cont_helpers::is_continuation (handler);
}
void run()
{
// Hooks called when using the raw handler
{
test_results r;
test_handler h (r);
async_op (h);
expect (r.call);
expect (r.alloc);
expect (r.dealloc);
expect (r.cont);
test_invokable f;
boost_asio_handler_invoke_helpers::invoke (std::ref (f), h);
expect (r.invoke);
expect (f.call);
}
// Use of boost::bind shows the hooks not getting called
{
test_results r;
test_handler h (r);
auto b (std::bind (&test_handler::operator(), &h));
async_op (b);
expect (r.call);
unexpected (r.alloc);
unexpected (r.dealloc);
unexpected (r.cont);
test_invokable f;
boost_asio_handler_invoke_helpers::invoke (std::ref (f), b);
unexpected (r.invoke);
expect (f.call);
}
// Make sure the wrapped handler calls the hooks
{
test_results r;
test_handler h (r);
auto w (wrap_handler (
std::bind (&test_handler::operator(), test_handler(r)), h));
async_op (w);
expect (r.call);
expect (r.alloc);
expect (r.dealloc);
expect (r.cont);
test_invokable f;
boost_asio_handler_invoke_helpers::invoke (std::ref (f), w);
expect (r.invoke);
expect (f.call);
}
}
};
BEAST_DEFINE_TESTSUITE(wrap_handler,asio,beast);
}
}

View File

@@ -0,0 +1,315 @@
//------------------------------------------------------------------------------
/*
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_WAITABLE_EXECUTOR_H_INCLUDED
#define BEAST_ASIO_WAITABLE_EXECUTOR_H_INCLUDED
#include <boost/asio/handler_alloc_hook.hpp>
#include <boost/asio/handler_continuation_hook.hpp>
#include <boost/asio/handler_invoke_hook.hpp>
#include <condition_variable>
#include <functional>
#include <memory>
#include <mutex>
#include <beast/cxx14/type_traits.h> // <type_traits>
#include <utility>
#include <vector>
namespace beast {
namespace asio {
namespace detail {
template <class Owner, class Handler>
class waitable_executor_wrapped_handler
{
private:
static_assert (std::is_same <std::decay_t <Owner>, Owner>::value,
"Owner cannot be a const or reference type");
Handler handler_;
std::reference_wrapper <Owner> owner_;
bool cont_;
public:
waitable_executor_wrapped_handler (Owner& owner,
Handler&& handler, bool continuation = false)
: handler_ (std::move(handler))
, owner_ (owner)
{
using boost::asio::asio_handler_is_continuation;
cont_ = continuation ? true :
asio_handler_is_continuation(
std::addressof(handler_));
owner_.get().increment();
}
waitable_executor_wrapped_handler (Owner& owner,
Handler const& handler, bool continuation = false)
: handler_ (handler)
, owner_ (owner)
{
using boost::asio::asio_handler_is_continuation;
cont_ = continuation ? true :
asio_handler_is_continuation(
std::addressof(handler_));
owner_.get().increment();
}
~waitable_executor_wrapped_handler()
{
owner_.get().decrement();
}
waitable_executor_wrapped_handler (
waitable_executor_wrapped_handler const& other)
: handler_ (other.handler_)
, owner_ (other.owner_)
, cont_ (other.cont_)
{
owner_.get().increment();
}
waitable_executor_wrapped_handler (
waitable_executor_wrapped_handler&& other)
: handler_ (std::move(other.handler_))
, owner_ (other.owner_)
, cont_ (other.cont_)
{
owner_.get().increment();
}
waitable_executor_wrapped_handler& operator=(
waitable_executor_wrapped_handler const&) = delete;
template <class... Args>
void
operator()(Args&&... args)
{
handler_(std::forward<Args>(args)...);
}
template <class... Args>
void
operator()(Args&&... args) const
{
handler_(std::forward<Args>(args)...);
}
template <class Function>
friend
void
asio_handler_invoke (Function& f,
waitable_executor_wrapped_handler* h)
{
using boost::asio::asio_handler_invoke;
asio_handler_invoke(f,
std::addressof(h->handler_));
}
template <class Function>
friend
void
asio_handler_invoke (Function const& f,
waitable_executor_wrapped_handler* h)
{
using boost::asio::asio_handler_invoke;
asio_handler_invoke(f,
std::addressof(h->handler_));
}
friend
void*
asio_handler_allocate (std::size_t size,
waitable_executor_wrapped_handler* h)
{
using boost::asio::asio_handler_allocate;
return asio_handler_allocate(
size, std::addressof(h->handler_));
}
friend
void
asio_handler_deallocate (void* p, std::size_t size,
waitable_executor_wrapped_handler* h)
{
using boost::asio::asio_handler_deallocate;
asio_handler_deallocate(
p, size, std::addressof(h->handler_));
}
friend
bool
asio_handler_is_continuation (
waitable_executor_wrapped_handler* h)
{
return h->cont_;
}
};
} // detail
//------------------------------------------------------------------------------
/** Executor which provides blocking until all handlers are called. */
class waitable_executor
{
private:
template <class, class>
friend class detail::waitable_executor_wrapped_handler;
std::mutex mutex_;
std::condition_variable cond_;
std::size_t count_ = 0;
std::vector<std::function<void(void)>> notify_;
public:
/** Block until all handlers are called. */
template <class = void>
void
wait();
/** Blocks until all handlers are called or time elapses.
@return `true` if all handlers are done or `false` if the time elapses.
*/
template <class Rep, class Period>
bool
wait_for (std::chrono::duration<
Rep, Period> const& elapsed_time);
/** Blocks until all handlers are called or a time is reached.
@return `true` if all handlers are done or `false` on timeout.
*/
template <class Clock, class Duration>
bool
wait_until (std::chrono::time_point<
Clock, Duration> const& timeout_time);
/** Call a function asynchronously after all handlers are called.
The function may be called on the callers thread.
*/
template <class = void>
void
async_wait(std::function<void(void)> f);
/** Create a new handler that dispatches the wrapped handler on the Context. */
template <class Handler>
detail::waitable_executor_wrapped_handler<waitable_executor,
std::remove_reference_t<Handler>>
wrap (Handler&& handler);
private:
template <class = void>
void
increment();
template <class = void>
void
decrement();
};
template <class>
void
waitable_executor::wait()
{
std::unique_lock<std::mutex> lock(mutex_);
cond_.wait(lock,
[this]() { return count_ == 0; });
}
template <class Rep, class Period>
bool
waitable_executor::wait_for (std::chrono::duration<
Rep, Period> const& elapsed_time)
{
std::unique_lock<std::mutex> lock(mutex_);
return cond_.wait_for(lock, elapsed_time,
[this]() { return count_ == 0; }) ==
std::cv_status::no_timeout;
}
template <class Clock, class Duration>
bool
waitable_executor::wait_until (std::chrono::time_point<
Clock, Duration> const& timeout_time)
{
std::unique_lock<std::mutex> lock(mutex_);
return cond_.wait_until(lock, timeout_time,
[this]() { return count_ == 0; }) ==
std::cv_status::no_timeout;
return true;
}
template <class>
void
waitable_executor::async_wait(std::function<void(void)> f)
{
bool busy;
{
std::lock_guard<std::mutex> _(mutex_);
busy = count_ > 0;
if (busy)
notify_.emplace_back(std::move(f));
}
if (! busy)
f();
}
template <class Handler>
detail::waitable_executor_wrapped_handler<waitable_executor,
std::remove_reference_t<Handler>>
waitable_executor::wrap (Handler&& handler)
{
return detail::waitable_executor_wrapped_handler<
waitable_executor, std::remove_reference_t<Handler>>(
*this, std::forward<Handler>(handler));
}
template <class>
void
waitable_executor::increment()
{
std::lock_guard<std::mutex> _(mutex_);
++count_;
}
template <class>
void
waitable_executor::decrement()
{
bool notify;
std::vector<std::function<void(void)>> list;
{
std::lock_guard<std::mutex> _(mutex_);
notify = --count_ == 0;
if (notify)
std::swap(list, notify_);
}
if (notify)
{
cond_.notify_all();
for(auto& _ : list)
_();
}
}
} // asio
} // beast
#endif

View File

@@ -1,176 +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_ASIO_WRAP_HANDLER_H_INCLUDED
#define BEAST_ASIO_WRAP_HANDLER_H_INCLUDED
#include <boost/asio/detail/handler_alloc_helpers.hpp>
#include <boost/asio/detail/handler_cont_helpers.hpp>
#include <boost/asio/detail/handler_invoke_helpers.hpp>
#include <beast/cxx14/type_traits.h> // <type_traits>
#include <utility>
namespace beast {
namespace asio {
#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable: 4512) // assignment operator could not be generated
#endif
namespace detail {
/** A handler which wraps another handler using a specfic context.
The handler is invoked with the same io_service execution guarantees
as the provided context.
@note A copy of Context is made.
*/
template <class Handler, class Context>
class wrapped_handler
{
private:
Handler m_handler;
Context m_context;
bool m_continuation;
// If this goes off, consider carefully what the intent is.
static_assert (! std::is_reference <Handler>::value,
"Handler should not be a reference type");
public:
wrapped_handler (bool continuation, Handler&& handler, Context context)
: m_handler (std::move (handler))
, m_context (context)
, m_continuation (continuation ? true :
boost_asio_handler_cont_helpers::is_continuation (context))
{
}
wrapped_handler (bool continuation, Handler const& handler, Context context)
: m_handler (handler)
, m_context (context)
, m_continuation (continuation ? true :
boost_asio_handler_cont_helpers::is_continuation (context))
{
}
template <class... Args>
void
operator() (Args&&... args)
{
m_handler (std::forward <Args> (args)...);
}
template <class... Args>
void
operator() (Args&&... args) const
{
m_handler (std::forward <Args> (args)...);
}
template <class Function>
friend
void
asio_handler_invoke (Function& f, wrapped_handler* h)
{
boost_asio_handler_invoke_helpers::
invoke (f, h->m_context);
}
template <class Function>
friend
void
asio_handler_invoke (Function const& f, wrapped_handler* h)
{
boost_asio_handler_invoke_helpers::
invoke (f, h->m_context);
}
friend
void*
asio_handler_allocate (std::size_t size, wrapped_handler* h)
{
return boost_asio_handler_alloc_helpers::
allocate (size, h->m_context);
}
friend
void
asio_handler_deallocate (void* p, std::size_t size, wrapped_handler* h)
{
boost_asio_handler_alloc_helpers::
deallocate (p, size, h->m_context);
}
friend
bool
asio_handler_is_continuation (wrapped_handler* h)
{
return h->m_continuation;
}
};
}
//------------------------------------------------------------------------------
// Tag for dispatching wrap_handler with is_continuation == true
enum continuation_t
{
continuation
};
/** Returns a wrapped handler so it executes within another context.
The handler is invoked with the same io_service execution guarantees
as the provided context. The handler will be copied if necessary.
@note A copy of Context is made.
*/
/** @{ */
template <class DeducedHandler, class Context>
detail::wrapped_handler <
std::remove_reference_t <DeducedHandler>,
Context
>
wrap_handler (DeducedHandler&& handler, Context const& context,
bool continuation = false)
{
typedef std::remove_reference_t <DeducedHandler> Handler;
return detail::wrapped_handler <Handler, Context> (continuation,
std::forward <DeducedHandler> (handler), context);
}
template <class DeducedHandler, class Context>
detail::wrapped_handler <
std::remove_reference_t <DeducedHandler>,
Context
>
wrap_handler (continuation_t, DeducedHandler&& handler,
Context const& context)
{
typedef std::remove_reference_t <DeducedHandler> Handler;
return detail::wrapped_handler <Handler, Context> (true,
std::forward <DeducedHandler> (handler), context);
}
/** @} */
}
}
#endif

View File

@@ -1,46 +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_BOOST_GET_POINTER_H_INCLUDED
#define BEAST_BOOST_GET_POINTER_H_INCLUDED
#include <boost/get_pointer.hpp>
// Boost 1.55 incorrectly defines BOOST_NO_CXX11_SMART_PTR
// when building with clang 3.4 and earlier. This workaround
// gives beast its own overloads.
#ifdef BOOST_NO_CXX11_SMART_PTR
#include <memory>
namespace beast {
template <class T>
T* get_pointer (std::unique_ptr<T> const& p)
{
return p.get();
}
template <class T>
T* get_pointer (std::shared_ptr<T> const& p)
{
return p.get();
}
}
#endif
#endif

View File

@@ -27,12 +27,12 @@ namespace beast {
/** Abstract interface to a clock.
The abstract clock interface allows a dependency injection to take
place so that the choice of implementation can be made at run-time
instead of compile time. The trade-off is that the Duration used to
represent the clock must be chosen at compile time and cannot be
changed. This includes both the choice of representation (integers
for example) and the period in ticks corresponding to one second.
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:
@@ -40,56 +40,37 @@ namespace beast {
struct Implementation
{
abstract_clock <std::chrono::seconds>& m_clock;
// Dependency injection
//
explicit Implementation (
abstract_clock <std::chrono::seconds>& clock)
: m_clock (clock)
using clock_type = abstract_clock <std::chrono::steady_clock>;
clock_type& clock_;
explicit Implementation (clock_type& clock)
: clock_(clock)
{
}
};
@endcode
@tparam The length of time, in seconds, corresponding to one tick.
@tparam Clock A type meeting these requirements:
http://en.cppreference.com/w/cpp/concept/Clock
*/
template <class Duration>
template <class Clock>
class abstract_clock
{
public:
typedef typename Duration::rep rep;
typedef typename Duration::period period;
typedef Duration duration;
typedef std::chrono::time_point <
abstract_clock, duration> time_point;
using rep = typename Clock::rep;
using period = typename Clock::period;
using duration = typename Clock::duration;
using time_point = typename Clock::time_point;
virtual ~abstract_clock () { }
static bool const is_steady = Clock::is_steady;
/** Returns `true` if this is a steady clock. */
virtual bool is_steady () const = 0;
virtual ~abstract_clock() = default;
/** Returns the current time. */
virtual time_point now () const = 0;
#if 0
/** Convert the specified time point to a string. */
/** @{ */
//virtual std::string to_string (time_point const& tp) const = 0;
template <class Duration2>
std::string to_string (
std::chrono::time_point <abstract_clock, Duration2> const& tp) const
{
return to_string (
std::chrono::time_point_cast <Duration> (tp));
}
/** @} */
#endif
virtual time_point now() const = 0;
/** Returning elapsed ticks since the epoch. */
rep elapsed () const
rep elapsed()
{
return now().time_since_epoch().count();
}
@@ -99,68 +80,34 @@ public:
namespace detail {
template <class TrivialClock, class Duration>
struct basic_abstract_clock_wrapper : public abstract_clock <Duration>
{
using typename abstract_clock <Duration>::duration;
using typename abstract_clock <Duration>::time_point;
bool is_steady () const
{
return TrivialClock::is_steady;
}
time_point now () const
{
return time_point (duration (
std::chrono::duration_cast <duration> (
TrivialClock::now().time_since_epoch ()).count ()));
}
};
template <class TrivialClock, class Duration>
template <class Facade, class Clock>
struct abstract_clock_wrapper
: public basic_abstract_clock_wrapper <TrivialClock, Duration>
: public abstract_clock<Facade>
{
// generic conversion displays the duration
/*
std::string to_string (typename basic_abstract_clock_wrapper <
TrivialClock, Duration>::time_point const& tp) const
{
std::stringstream ss;
ss << tp.time_since_epoch();
return ss.str ();
}
*/
};
using typename abstract_clock<Facade>::duration;
using typename abstract_clock<Facade>::time_point;
/*
template <class Duration>
struct abstract_clock_wrapper <std::chrono::system_clock, Duration>
: public basic_abstract_clock_wrapper <std::chrono::system_clock, Duration>
{
typedef std::chrono::system_clock clock_type;
std::string to_string (time_point const& tp)
time_point
now() const override
{
std::stringstream ss;
ss << clock_type::time_point (tp.time_since_epoch ());
return ss.str ();
return Clock::now();
}
};
*/
}
//------------------------------------------------------------------------------
/** Retrieve a discrete clock for a type implementing the Clock concept.
The interface is created as an object with static storage duration.
/** 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 TrivialClock, class Duration>
abstract_clock <Duration>& get_abstract_clock ()
template<class Facade, class Clock = Facade>
abstract_clock<Facade>&
get_abstract_clock()
{
static detail::abstract_clock_wrapper <
TrivialClock, Duration> clock;
static detail::abstract_clock_wrapper<Facade, Clock> clock;
return clock;
}

View File

@@ -1,37 +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_CHRONO_ABSTRACT_CLOCK_IO_H_INCLUDED
#define BEAST_CHRONO_ABSTRACT_CLOCK_IO_H_INCLUDED
#include <beast/chrono/chrono_io.h>
namespace beast {
template <class CharT, class Traits, class Duration, class Resolution>
std::basic_ostream <CharT, Traits>&
operator<< (std::basic_ostream <CharT, Traits>& os,
std::chrono::time_point <abstract_clock <Resolution>, Duration> const& tp)
{
return os << tp.time_since_epoch() << " since epoch";
}
}
#endif

View File

@@ -45,25 +45,25 @@ public:
class seconds_clock_thread
{
public:
typedef std::mutex mutex;
typedef std::condition_variable cond_var;
typedef std::lock_guard <mutex> lock_guard;
typedef std::unique_lock <mutex> unique_lock;
typedef std::chrono::steady_clock clock_type;
typedef std::chrono::seconds seconds;
typedef std::thread thread;
typedef std::vector <seconds_clock_worker*> workers;
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 m_stop;
mutex m_mutex;
cond_var m_cond;
workers m_workers;
thread m_thread;
bool stop_;
mutex mutex_;
cond_var cond_;
workers workers_;
thread thread_;
seconds_clock_thread ()
: m_stop (false)
: stop_ (false)
{
m_thread = thread (std::bind(
thread_ = thread (std::bind(
&seconds_clock_thread::run, this));
}
@@ -74,37 +74,37 @@ public:
void add (seconds_clock_worker& w)
{
lock_guard lock (m_mutex);
m_workers.push_back (&w);
lock_guard lock (mutex_);
workers_.push_back (&w);
}
void remove (seconds_clock_worker& w)
{
lock_guard lock (m_mutex);
m_workers.erase (std::find (
m_workers.begin (), m_workers.end(), &w));
lock_guard lock (mutex_);
workers_.erase (std::find (
workers_.begin (), workers_.end(), &w));
}
void stop()
{
if (m_thread.joinable())
if (thread_.joinable())
{
{
lock_guard lock (m_mutex);
m_stop = true;
lock_guard lock (mutex_);
stop_ = true;
}
m_cond.notify_all();
m_thread.join();
cond_.notify_all();
thread_.join();
}
}
void run()
{
unique_lock lock (m_mutex);;
unique_lock lock (mutex_);;
for (;;)
{
for (auto iter : m_workers)
for (auto iter : workers_)
iter->sample();
clock_type::time_point const when (
@@ -112,7 +112,7 @@ public:
clock_type::now().time_since_epoch()) +
seconds (1));
if (m_cond.wait_until (lock, when, [this]{ return m_stop; }))
if (cond_.wait_until (lock, when, [this]{ return stop_; }))
return;
}
}
@@ -143,24 +143,26 @@ basic_seconds_clock_main_hook()
}
/** 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 TrivialClock The clock to sample.
@tparam Clock A type meeting these requirements:
http://en.cppreference.com/w/cpp/concept/Clock
*/
template <class TrivialClock>
template <class Clock>
class basic_seconds_clock
{
public:
typedef std::chrono::seconds resolution;
typedef typename resolution::rep rep;
typedef typename resolution::period period;
typedef std::chrono::duration <rep, period> duration;
typedef std::chrono::time_point <basic_seconds_clock> time_point;
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 = TrivialClock::is_steady;
static bool const is_steady = Clock::is_steady;
static time_point now ()
static time_point now()
{
// Make sure the thread is constructed before the
// worker otherwise we will crash during destruction
@@ -176,45 +178,36 @@ public:
struct worker : detail::seconds_clock_worker
{
typedef std::mutex mutex;
typedef std::lock_guard <mutex> lock_guard;
time_point m_now;
mutex m_mutex;
std::mutex mutex_;
static time_point get_now ()
worker()
: m_now(Clock::now())
{
return time_point (floor <resolution> (
TrivialClock::now().time_since_epoch()));
detail::seconds_clock_thread::instance().add(*this);
}
worker ()
: m_now (get_now ())
~worker()
{
detail::seconds_clock_thread::instance().add (*this);
}
~worker ()
{
detail::seconds_clock_thread::instance().remove (*this);
detail::seconds_clock_thread::instance().remove(*this);
}
time_point now()
{
lock_guard lock (m_mutex);
std::lock_guard<std::mutex> lock (mutex_);
return m_now;
}
void sample ()
void sample()
{
lock_guard lock (m_mutex);
m_now = get_now ();
std::lock_guard<std::mutex> lock (mutex_);
m_now = Clock::now();
}
};
static worker w;
return w.now ();
return w.now();
}
};

View File

@@ -32,8 +32,6 @@
#include <beast/utility/noexcept.h>
#include <ctime>
#include <locale>
#define BEAST_CHRONO_NO_TIMEPOINT_IO 1
/*
@@ -798,292 +796,8 @@ time_fmt(timezone f)
return __time_man(f);
}
#if ! BEAST_CHRONO_NO_TIMEPOINT_IO
} // chrono
template <class _CharT, class _Traits, class _Duration>
basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is,
time_point<steady_clock, _Duration>& __tp)
{
_Duration __d;
__is >> __d;
if (__is.good())
{
const _CharT __u[] = {' ', 's', 'i', 'n', 'c', 'e', ' ', 'b', 'o', 'o', 't'};
const basic_string<_CharT> __units(__u, __u + sizeof(__u)/sizeof(__u[0]));
ios_base::iostate __err = ios_base::goodbit;
typedef istreambuf_iterator<_CharT, _Traits> _I;
_I __i(__is);
_I __e;
ptrdiff_t __k = __scan_keyword(__i, __e,
&__units, &__units + 1,
use_facet<ctype<_CharT> >(__is.getloc()),
__err) - &__units;
if (__k == 1)
{
// failed to read epoch string
__is.setstate(__err);
return __is;
}
__tp = time_point<steady_clock, _Duration>(__d);
}
else
__is.setstate(__is.failbit);
return __is;
}
template <class _CharT, class _Traits, class _Duration>
basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os,
const time_point<system_clock, _Duration>& __tp)
{
typename basic_ostream<_CharT, _Traits>::sentry ok(__os);
if (ok)
{
bool failed = false;
try
{
const _CharT* pb = nullptr;
const _CharT* pe = pb;
timezone tz = utc;
typedef timepunct<_CharT> F;
locale loc = __os.getloc();
if (has_facet<F>(loc))
{
const F& f = use_facet<F>(loc);
pb = f.fmt().data();
pe = pb + f.fmt().size();
tz = f.get_timezone();
}
time_t __t = system_clock::to_time_t(__tp);
tm __tm;
if (tz == local)
{
if (localtime_r(&__t, &__tm) == 0)
failed = true;
}
else
{
if (gmtime_r(&__t, &__tm) == 0)
failed = true;
}
if (!failed)
{
const time_put<_CharT>& tp = use_facet<time_put<_CharT> >(loc);
if (pb == pe)
{
_CharT pattern[] = {'%', 'F', 'T', '%', 'H', ':', '%', 'M', ':'};
pb = pattern;
pe = pb + sizeof(pattern) / sizeof(_CharT);
failed = tp.put(__os, __os, __os.fill(), &__tm, pb, pe).failed();
if (!failed)
{
duration<double> __d = __tp - system_clock::from_time_t(__t) +
seconds(__tm.tm_sec);
if (__d.count() < 10)
__os << _CharT('0');
ios::fmtflags __flgs = __os.flags();
__os.setf(ios::fixed, ios::floatfield);
__os << __d.count();
__os.flags(__flgs);
if (tz == local)
{
_CharT sub_pattern[] = {' ', '%', 'z'};
pb = sub_pattern;
pe = pb + + sizeof(sub_pattern) / sizeof(_CharT);
failed = tp.put(__os, __os, __os.fill(), &__tm, pb, pe).failed();
}
else
{
_CharT sub_pattern[] = {' ', '+', '0', '0', '0', '0', 0};
__os << sub_pattern;
}
}
}
else
failed = tp.put(__os, __os, __os.fill(), &__tm, pb, pe).failed();
}
}
catch (...)
{
failed = true;
}
if (failed)
__os.setstate(ios_base::failbit | ios_base::badbit);
}
return __os;
}
template <class _CharT, class _InputIterator>
minutes
__extract_z(_InputIterator& __b, _InputIterator __e,
ios_base::iostate& __err, const ctype<_CharT>& __ct)
{
int __minn = 0;
if (__b != __e)
{
char __cn = __ct.narrow(*__b, 0);
if (__cn != '+' && __cn != '-')
{
__err |= ios_base::failbit;
return minutes(0);
}
int __sn = __cn == '-' ? -1 : 1;
int __hr = 0;
for (int i = 0; i < 2; ++i)
{
if (++__b == __e)
{
__err |= ios_base::eofbit | ios_base::failbit;
return minutes(0);
}
__cn = __ct.narrow(*__b, 0);
if (!('0' <= __cn && __cn <= '9'))
{
__err |= ios_base::failbit;
return minutes(0);
}
__hr = __hr * 10 + __cn - '0';
}
for (int i = 0; i < 2; ++i)
{
if (++__b == __e)
{
__err |= ios_base::eofbit | ios_base::failbit;
return minutes(0);
}
__cn = __ct.narrow(*__b, 0);
if (!('0' <= __cn && __cn <= '9'))
{
__err |= ios_base::failbit;
return minutes(0);
}
__minn = __minn * 10 + __cn - '0';
}
if (++__b == __e)
__err |= ios_base::eofbit;
__minn += __hr * 60;
__minn *= __sn;
}
else
__err |= ios_base::eofbit | ios_base::failbit;
return minutes(__minn);
}
template <class _CharT, class _Traits, class _Duration>
basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is,
time_point<system_clock, _Duration>& __tp)
{
typename basic_istream<_CharT,_Traits>::sentry ok(__is);
if (ok)
{
ios_base::iostate err = ios_base::goodbit;
try
{
const _CharT* pb = nullptr;
const _CharT* pe = pb;
typedef timepunct<_CharT> F;
locale loc = __is.getloc();
timezone tz = utc;
if (has_facet<F>(loc))
{
const F& f = use_facet<F>(loc);
pb = f.fmt().data();
pe = pb + f.fmt().size();
tz = f.get_timezone();
}
const time_get<_CharT>& tg = use_facet<time_get<_CharT> >(loc);
const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(loc);
tm __tm = {0};
typedef istreambuf_iterator<_CharT, _Traits> _I;
if (pb == pe)
{
_CharT pattern[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd',
'T', '%', 'H', ':', '%', 'M', ':'};
pb = pattern;
pe = pb + sizeof(pattern) / sizeof(_CharT);
tg.get(__is, 0, __is, err, &__tm, pb, pe);
if (err & ios_base::failbit)
goto __exit;
double __sec;
_CharT __c = _CharT();
__is >> __sec;
if (__is.fail())
{
err |= ios_base::failbit;
goto __exit;
}
_I __i(__is);
_I __eof;
__c = *__i;
if (++__i == __eof || __c != ' ')
{
err |= ios_base::failbit;
goto __exit;
}
minutes __minn = __extract_z(__i, __eof, err, __ct);
if (err & ios_base::failbit)
goto __exit;
time_t __t;
__t = timegm(&__tm);
__tp = system_clock::from_time_t(__t) - __minn
+ round<microseconds>(duration<double>(__sec));
}
else
{
const _CharT __z[2] = {'%', 'z'};
const _CharT* __fz = std::search(pb, pe, __z, __z+2);
tg.get(__is, 0, __is, err, &__tm, pb, __fz);
minutes __minn(0);
if (__fz != pe)
{
if (err != ios_base::goodbit)
{
err |= ios_base::failbit;
goto __exit;
}
_I __i(__is);
_I __eof;
__minn = __extract_z(__i, __eof, err, __ct);
if (err & ios_base::failbit)
goto __exit;
if (__fz+2 != pe)
{
if (err != ios_base::goodbit)
{
err |= ios_base::failbit;
goto __exit;
}
tg.get(__is, 0, __is, err, &__tm, __fz+2, pe);
if (err & ios_base::failbit)
goto __exit;
}
}
__tm.tm_isdst = -1;
time_t __t;
if (tz == utc || __fz != pe)
__t = timegm(&__tm);
else
__t = mktime(&__tm);
__tp = system_clock::from_time_t(__t) - __minn;
}
}
catch (...)
{
err |= ios_base::badbit | ios_base::failbit;
}
__exit:
__is.setstate(err);
}
return __is;
}
#endif
} // chrono
//_LIBCPP_END_NAMESPACE_STD
}
#endif

View File

@@ -256,7 +256,7 @@ std::string RelativeTime::to_string () const
}
}
#if BEAST_WINDOWS
#include <windows.h>
@@ -266,12 +266,12 @@ namespace detail {
static double monotonicCurrentTimeInSeconds()
{
return GetTickCount64() / 1000.0;
return GetTickCount64() / 1000.0;
}
}
}
#elif BEAST_MAC || BEAST_IOS
#include <mach/mach_time.h>
@@ -279,39 +279,39 @@ static double monotonicCurrentTimeInSeconds()
namespace beast {
namespace detail {
static double monotonicCurrentTimeInSeconds()
{
struct StaticInitializer
{
StaticInitializer ()
{
double numerator;
double denominator;
struct StaticInitializer
{
StaticInitializer ()
{
double numerator;
double denominator;
mach_timebase_info_data_t timebase;
(void) mach_timebase_info (&timebase);
if (timebase.numer % 1000000 == 0)
{
numerator = timebase.numer / 1000000.0;
denominator = timebase.denom * 1000.0;
}
else
{
numerator = timebase.numer;
mach_timebase_info_data_t timebase;
(void) mach_timebase_info (&timebase);
if (timebase.numer % 1000000 == 0)
{
numerator = timebase.numer / 1000000.0;
denominator = timebase.denom * 1000.0;
}
else
{
numerator = timebase.numer;
// VFALCO NOTE I don't understand this code
//denominator = timebase.denom * (std::uint64_t) 1000000 * 1000.0;
//denominator = timebase.denom * (std::uint64_t) 1000000 * 1000.0;
denominator = timebase.denom * 1000000000.0;
}
ratio = numerator / denominator;
}
}
ratio = numerator / denominator;
}
double ratio;
};
static StaticInitializer const data;
double ratio;
};
static StaticInitializer const data;
return mach_absolute_time() * data.ratio;
}
@@ -319,7 +319,7 @@ static double monotonicCurrentTimeInSeconds()
}
#else
#include <time.h>
namespace beast {
@@ -327,14 +327,14 @@ namespace detail {
static double monotonicCurrentTimeInSeconds()
{
timespec t;
clock_gettime (CLOCK_MONOTONIC, &t);
return t.tv_sec + t.tv_nsec / 1000000000.0;
timespec t;
clock_gettime (CLOCK_MONOTONIC, &t);
return t.tv_sec + t.tv_nsec / 1000000000.0;
}
}
}
#endif
namespace beast {
@@ -343,37 +343,37 @@ namespace detail {
// Records and returns the time from process startup
static double getStartupTime()
{
struct StaticInitializer
{
StaticInitializer ()
{
struct StaticInitializer
{
StaticInitializer ()
{
when = detail::monotonicCurrentTimeInSeconds();
}
double when;
};
};
static StaticInitializer const data;
static StaticInitializer const data;
return data.when;
return data.when;
}
// Used to call getStartupTime as early as possible
struct StartupTimeStaticInitializer
{
StartupTimeStaticInitializer ()
{
StartupTimeStaticInitializer ()
{
getStartupTime();
}
};
static StartupTimeStaticInitializer startupTimeStaticInitializer;
}
RelativeTime RelativeTime::fromStartup ()
{
return RelativeTime (
return RelativeTime (
detail::monotonicCurrentTimeInSeconds() - detail::getStartupTime());
}

View File

@@ -25,68 +25,73 @@
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 The length of time, in seconds, corresponding to one tick.
@tparam Clock A type meeting these requirements:
http://en.cppreference.com/w/cpp/concept/Clock
*/
template <class Duration, bool IsSteady = true>
class manual_clock : public abstract_clock <Duration>
template <class Clock>
class manual_clock
: public abstract_clock<Clock>
{
public:
using typename abstract_clock <Duration>::rep;
using typename abstract_clock <Duration>::duration;
using typename abstract_clock <Duration>::time_point;
explicit manual_clock (time_point const& t = time_point (Duration (0)))
: m_now (t)
{
}
bool is_steady () const
{
return IsSteady;
}
time_point now () const
{
return m_now;
}
#if 0
std::string to_string (time_point const& tp) const
{
std::stringstream ss;
ss << tp.time_since_epoch() << " from start";
return ss.str ();
}
#endif
/** Set the current time of the manual clock.
Precondition:
! IsSteady || t > now()
*/
void set (time_point const& t)
{
//if (IsSteady)
m_now = t;
}
/** Convenience for setting the time using a duration in @ref rep units. */
void set (rep v)
{
set (time_point (duration (v)));
}
/** Convenience for advancing the clock by one. */
manual_clock& operator++ ()
{
m_now += duration (1);
return *this;
}
using typename abstract_clock<Clock>::rep;
using typename abstract_clock<Clock>::duration;
using typename abstract_clock<Clock>::time_point;
private:
time_point m_now;
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;
}
};
}

View File

@@ -20,11 +20,8 @@
// MODULES: ../impl/chrono_io.cpp
#include <beast/chrono/abstract_clock.h>
#include <beast/chrono/abstract_clock_io.h>
#include <beast/chrono/manual_clock.h>
#include <beast/unit_test/suite.h>
#include <sstream>
#include <string>
#include <thread>
@@ -34,7 +31,8 @@ namespace beast {
class abstract_clock_test : public unit_test::suite
{
public:
void test (abstract_clock <std::chrono::seconds>& c)
template <class Clock>
void test (abstract_clock<Clock>& c)
{
{
auto const t1 (c.now ());
@@ -53,18 +51,18 @@ public:
void test_manual ()
{
typedef manual_clock <std::chrono::seconds> clock_type;
using clock_type = manual_clock<std::chrono::steady_clock>;
clock_type c;
std::stringstream ss;
ss << "now() = " << c.now () << std::endl;
ss << "now() = " << c.now().time_since_epoch() << std::endl;
c.set (clock_type::time_point (std::chrono::seconds (1)));
ss << "now() = " << c.now () << std::endl;
c.set (clock_type::time_point (std::chrono::seconds(1)));
ss << "now() = " << c.now().time_since_epoch() << std::endl;
c.set (clock_type::time_point (std::chrono::seconds (2)));
ss << "now() = " << c.now () << std::endl;
c.set (clock_type::time_point (std::chrono::seconds(2)));
ss << "now() = " << c.now().time_since_epoch() << std::endl;
log << ss.str();
}
@@ -72,16 +70,16 @@ public:
void run ()
{
log << "steady_clock";
test (get_abstract_clock <std::chrono::steady_clock,
std::chrono::seconds> ());
test (get_abstract_clock<
std::chrono::steady_clock>());
log << "system_clock";
test (get_abstract_clock <std::chrono::system_clock,
std::chrono::seconds> ());
test (get_abstract_clock<
std::chrono::system_clock>());
log << "high_resolution_clock";
test (get_abstract_clock <std::chrono::high_resolution_clock,
std::chrono::seconds> ());
test (get_abstract_clock<
std::chrono::high_resolution_clock>());
log << "manual_clock";
test_manual ();

View File

@@ -109,9 +109,12 @@ extern void beast_reportFatalError (char const* message, char const* fileName, i
/** Writes a string to the standard error stream.
This is only compiled in a debug build.
@see Logger::outputDebugString
*/
#define BDBG(dbgtext) { beast::String tempDbgBuf; tempDbgBuf << dbgtext; beast::Logger::outputDebugString (tempDbgBuf); }
#define BDBG(dbgtext) { \
beast::String tempDbgBuf; \
tempDbgBuf << dbgtext; \
beast::outputDebugString (tempDbgBuf.toStdString ()); \
}
#if 0
/** This will always cause an assertion failure.

View File

@@ -44,10 +44,6 @@
#define BEAST_DISABLE_CONTRACT_CHECKS 0
#endif
#ifndef BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
#define BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES 0
#endif
//------------------------------------------------------------------------------
#ifndef BEAST_DONT_AUTOLINK_TO_WIN32_LIBRARIES

View File

@@ -21,10 +21,5 @@
#include <BeastConfig.h>
#endif
#include <beast/container/impl/spookyv2.cpp>
#include <beast/container/impl/siphash.cpp>
#include <beast/container/tests/aged_associative_container.test.cpp>
#include <beast/container/tests/buffer_view.test.cpp>
#include <beast/container/tests/hardened_hash.test.cpp>
#include <beast/container/tests/hash_append.test.cpp>

View File

@@ -31,12 +31,12 @@ namespace beast {
template <
class Key,
class T,
class Duration = std::chrono::seconds,
class Clock = std::chrono::steady_clock,
class Compare = std::less <Key>,
class Allocator = std::allocator <std::pair <Key const, T>>
>
using aged_map = detail::aged_ordered_container <
false, true, Key, T, Duration, Compare, Allocator>;
false, true, Key, T, Clock, Compare, Allocator>;
}

View File

@@ -31,12 +31,12 @@ namespace beast {
template <
class Key,
class T,
class Duration = std::chrono::seconds,
class Clock = std::chrono::steady_clock,
class Compare = std::less <Key>,
class Allocator = std::allocator <std::pair <Key const, T>>
>
using aged_multimap = detail::aged_ordered_container <
true, true, Key, T, Duration, Compare, Allocator>;
true, true, Key, T, Clock, Compare, Allocator>;
}

View File

@@ -30,12 +30,12 @@ namespace beast {
template <
class Key,
class Duration = std::chrono::seconds,
class Clock = std::chrono::steady_clock,
class Compare = std::less <Key>,
class Allocator = std::allocator <Key>
>
using aged_multiset = detail::aged_ordered_container <
true, false, Key, void, Duration, Compare, Allocator>;
true, false, Key, void, Clock, Compare, Allocator>;
}

View File

@@ -30,12 +30,12 @@ namespace beast {
template <
class Key,
class Duration = std::chrono::seconds,
class Clock = std::chrono::steady_clock,
class Compare = std::less <Key>,
class Allocator = std::allocator <Key>
>
using aged_set = detail::aged_ordered_container <
false, false, Key, void, Duration, Compare, Allocator>;
false, false, Key, void, Clock, Compare, Allocator>;
}

View File

@@ -31,13 +31,13 @@ namespace beast {
template <
class Key,
class T,
class Duration = std::chrono::seconds,
class Clock = std::chrono::steady_clock,
class Hash = std::hash <Key>,
class KeyEqual = std::equal_to <Key>,
class Allocator = std::allocator <std::pair <Key const, T>>
>
using aged_unordered_map = detail::aged_unordered_container <
false, true, Key, T, Duration, Hash, KeyEqual, Allocator>;
false, true, Key, T, Clock, Hash, KeyEqual, Allocator>;
}

View File

@@ -31,13 +31,13 @@ namespace beast {
template <
class Key,
class T,
class Duration = std::chrono::seconds,
class Clock = std::chrono::steady_clock,
class Hash = std::hash <Key>,
class KeyEqual = std::equal_to <Key>,
class Allocator = std::allocator <std::pair <Key const, T>>
>
using aged_unordered_multimap = detail::aged_unordered_container <
true, true, Key, T, Duration, Hash, KeyEqual, Allocator>;
true, true, Key, T, Clock, Hash, KeyEqual, Allocator>;
}

View File

@@ -30,13 +30,13 @@ namespace beast {
template <
class Key,
class Duration = std::chrono::seconds,
class Clock = std::chrono::steady_clock,
class Hash = std::hash <Key>,
class KeyEqual = std::equal_to <Key>,
class Allocator = std::allocator <Key>
>
using aged_unordered_multiset = detail::aged_unordered_container <
true, false, Key, void, Duration, Hash, KeyEqual, Allocator>;
true, false, Key, void, Clock, Hash, KeyEqual, Allocator>;
}

View File

@@ -30,13 +30,13 @@ namespace beast {
template <
class Key,
class Duration = std::chrono::seconds,
class Clock = std::chrono::steady_clock,
class Hash = std::hash <Key>,
class KeyEqual = std::equal_to <Key>,
class Allocator = std::allocator <Key>
>
using aged_unordered_set = detail::aged_unordered_container <
false, false, Key, void, Duration, Hash, KeyEqual, Allocator>;
false, false, Key, void, Clock, Hash, KeyEqual, Allocator>;
}

View File

@@ -141,154 +141,154 @@ Here is a short example demonstrating its use.
\snippet cyclic_iterator.cpp cyclic_iterator
*/
template<
typename ContainerIterator
typename ContainerIterator
>
class cyclic_iterator
:
public detail::cyclic_iterator_base<
ContainerIterator
>::type
public detail::cyclic_iterator_base<
ContainerIterator
>::type
{
public:
/**
\brief The base type which is a <code>boost::iterator_facade</code>
*/
typedef typename detail::cyclic_iterator_base<
ContainerIterator
>::type base_type;
/**
\brief The base type which is a <code>boost::iterator_facade</code>
*/
typedef typename detail::cyclic_iterator_base<
ContainerIterator
>::type base_type;
/**
\brief The underlying iterator type
*/
typedef ContainerIterator container_iterator_type;
/**
\brief The underlying iterator type
*/
typedef ContainerIterator container_iterator_type;
/**
\brief The value type adapted from \a ContainerIterator
*/
typedef typename base_type::value_type value_type;
/**
\brief The value type adapted from \a ContainerIterator
*/
typedef typename base_type::value_type value_type;
/**
\brief The reference type adapted from \a ContainerIterator
*/
typedef typename base_type::reference reference;
/**
\brief The reference type adapted from \a ContainerIterator
*/
typedef typename base_type::reference reference;
/**
\brief The pointer type adapted from \a ContainerIterator
*/
typedef typename base_type::pointer pointer;
/**
\brief The pointer type adapted from \a ContainerIterator
*/
typedef typename base_type::pointer pointer;
/**
\brief The difference type adapted from \a ContainerIterator
*/
typedef typename base_type::difference_type difference_type;
/**
\brief The difference type adapted from \a ContainerIterator
*/
typedef typename base_type::difference_type difference_type;
/**
\brief The iterator category, either Forward or Bidirectional
*/
typedef typename base_type::iterator_category iterator_category;
/**
\brief The iterator category, either Forward or Bidirectional
*/
typedef typename base_type::iterator_category iterator_category;
/**
\brief Creates a singular iterator
*/
cyclic_iterator();
/**
\brief Creates a singular iterator
*/
cyclic_iterator();
/**
\brief Copy constructs from another cyclic iterator
/**
\brief Copy constructs from another cyclic iterator
Copy constructs from another cyclic iterator \a other. This only works
if the underlying iterators are convertible.
Copy constructs from another cyclic iterator \a other. This only works
if the underlying iterators are convertible.
\param other The iterator to copy construct from
*/
template<
typename OtherIterator
>
explicit
cyclic_iterator(
cyclic_iterator<OtherIterator> const &other
);
\param other The iterator to copy construct from
*/
template<
typename OtherIterator
>
explicit
cyclic_iterator(
cyclic_iterator<OtherIterator> const &other
);
/**
\brief Constructs a new cyclic iterator
/**
\brief Constructs a new cyclic iterator
Constructs a new cyclic iterator, starting at \a it, inside
a range from \a begin to \a end.
Constructs a new cyclic iterator, starting at \a it, inside
a range from \a begin to \a end.
\param pos The start of the iterator
\param begin The beginning of the range
\param end The end of the range
\param pos The start of the iterator
\param begin The beginning of the range
\param end The end of the range
\warning The behaviour is undefined if \a pos isn't between \a begin
and \a end. Also, the behaviour is undefined, if \a begin and \a end
don't form a valid range.
*/
cyclic_iterator(
container_iterator_type const &pos,
container_iterator_type const &begin,
container_iterator_type const &end
);
\warning The behaviour is undefined if \a pos isn't between \a begin
and \a end. Also, the behaviour is undefined, if \a begin and \a end
don't form a valid range.
*/
cyclic_iterator(
container_iterator_type const &pos,
container_iterator_type const &begin,
container_iterator_type const &end
);
/**
\brief Assigns from another cyclic iterator
/**
\brief Assigns from another cyclic iterator
Assigns from another cyclic iterator \a other. This only works if the
underlying iterators are convertible.
Assigns from another cyclic iterator \a other. This only works if the
underlying iterators are convertible.
\param other The iterator to assign from
\param other The iterator to assign from
\return <code>*this</code>
*/
template<
typename OtherIterator
>
cyclic_iterator<ContainerIterator> &
operator=(
cyclic_iterator<OtherIterator> const &other
);
\return <code>*this</code>
*/
template<
typename OtherIterator
>
cyclic_iterator<ContainerIterator> &
operator=(
cyclic_iterator<OtherIterator> const &other
);
/**
\brief Returns the beginning of the range
*/
container_iterator_type
begin() const;
/**
\brief Returns the beginning of the range
*/
container_iterator_type
begin() const;
/**
\brief Returns the end of the range
*/
container_iterator_type
end() const;
/**
\brief Returns the end of the range
*/
container_iterator_type
end() const;
/**
\brief Returns the underlying iterator
*/
container_iterator_type
get() const;
/**
\brief Returns the underlying iterator
*/
container_iterator_type
get() const;
private:
friend class boost::iterator_core_access;
friend class boost::iterator_core_access;
void
increment();
void
increment();
void
decrement();
void
decrement();
bool
equal(
cyclic_iterator const &
) const;
bool
equal(
cyclic_iterator const &
) const;
reference
dereference() const;
reference
dereference() const;
difference_type
distance_to(
cyclic_iterator const &
) const;
difference_type
distance_to(
cyclic_iterator const &
) const;
private:
container_iterator_type
it_,
begin_,
end_;
container_iterator_type
it_,
begin_,
end_;
};
//

View File

@@ -22,15 +22,11 @@
#include <beast/container/detail/aged_container_iterator.h>
#include <beast/container/detail/aged_associative_container.h>
#include <beast/container/aged_container.h>
#include <beast/chrono/abstract_clock.h>
#include <beast/utility/empty_base_optimization.h>
#include <boost/intrusive/list.hpp>
#include <boost/intrusive/set.hpp>
#include <beast/cxx14/algorithm.h> // <algorithm>
#include <functional>
#include <initializer_list>
@@ -75,7 +71,7 @@ template <
bool IsMap,
class Key,
class T,
class Duration = std::chrono::seconds,
class Clock = std::chrono::steady_clock,
class Compare = std::less <Key>,
class Allocator = std::allocator <
typename std::conditional <IsMap,
@@ -85,25 +81,20 @@ template <
class aged_ordered_container
{
public:
typedef abstract_clock <Duration> clock_type;
typedef typename clock_type::time_point time_point;
typedef typename clock_type::duration duration;
typedef Key key_type;
typedef T mapped_type;
typedef typename std::conditional <
IsMap,
std::pair <Key const, T>,
Key>::type value_type;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
using clock_type = abstract_clock<Clock>;
using time_point = typename clock_type::time_point;
using duration = typename clock_type::duration;
using key_type = Key;
using mapped_type = T;
using value_type = typename std::conditional <
IsMap, std::pair <Key const, T>, Key>::type;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
// Introspection (for unit tests)
typedef std::false_type is_unordered;
typedef std::integral_constant <bool, IsMulti> is_multi;
typedef std::integral_constant <bool, IsMap> is_map;
// VFALCO TODO How can we reorder the declarations to keep
// all the public things together contiguously?
using is_unordered = std::false_type;
using is_multi = std::integral_constant <bool, IsMulti>;
using is_map = std::integral_constant <bool, IsMap>;
private:
static Key const& extract (value_type const& value)
@@ -1237,8 +1228,8 @@ private:
//------------------------------------------------------------------------------
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
class Clock, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (
clock_type& clock)
: m_config (clock)
@@ -1246,8 +1237,8 @@ aged_ordered_container (
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
class Clock, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (
clock_type& clock,
Compare const& comp)
@@ -1256,8 +1247,8 @@ aged_ordered_container (
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
class Clock, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (
clock_type& clock,
Allocator const& alloc)
@@ -1266,8 +1257,8 @@ aged_ordered_container (
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
class Clock, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (
clock_type& clock,
Compare const& comp,
@@ -1277,9 +1268,9 @@ aged_ordered_container (
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <class InputIt>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (InputIt first, InputIt last,
clock_type& clock)
: m_config (clock)
@@ -1288,9 +1279,9 @@ aged_ordered_container (InputIt first, InputIt last,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <class InputIt>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (InputIt first, InputIt last,
clock_type& clock,
Compare const& comp)
@@ -1300,9 +1291,9 @@ aged_ordered_container (InputIt first, InputIt last,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <class InputIt>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (InputIt first, InputIt last,
clock_type& clock,
Allocator const& alloc)
@@ -1312,9 +1303,9 @@ aged_ordered_container (InputIt first, InputIt last,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <class InputIt>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (InputIt first, InputIt last,
clock_type& clock,
Compare const& comp,
@@ -1325,8 +1316,8 @@ aged_ordered_container (InputIt first, InputIt last,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
class Clock, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (aged_ordered_container const& other)
: m_config (other.m_config)
{
@@ -1334,8 +1325,8 @@ aged_ordered_container (aged_ordered_container const& other)
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
class Clock, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (aged_ordered_container const& other,
Allocator const& alloc)
: m_config (other.m_config, alloc)
@@ -1344,8 +1335,8 @@ aged_ordered_container (aged_ordered_container const& other,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
class Clock, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (aged_ordered_container&& other)
: m_config (std::move (other.m_config))
, m_cont (std::move (other.m_cont))
@@ -1354,8 +1345,8 @@ aged_ordered_container (aged_ordered_container&& other)
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
class Clock, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (aged_ordered_container&& other,
Allocator const& alloc)
: m_config (std::move (other.m_config), alloc)
@@ -1365,8 +1356,8 @@ aged_ordered_container (aged_ordered_container&& other,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
class Clock, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (std::initializer_list <value_type> init,
clock_type& clock)
: m_config (clock)
@@ -1375,8 +1366,8 @@ aged_ordered_container (std::initializer_list <value_type> init,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
class Clock, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (std::initializer_list <value_type> init,
clock_type& clock,
Compare const& comp)
@@ -1386,8 +1377,8 @@ aged_ordered_container (std::initializer_list <value_type> init,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
class Clock, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (std::initializer_list <value_type> init,
clock_type& clock,
Allocator const& alloc)
@@ -1397,8 +1388,8 @@ aged_ordered_container (std::initializer_list <value_type> init,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
class Clock, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
aged_ordered_container (std::initializer_list <value_type> init,
clock_type& clock,
Compare const& comp,
@@ -1409,17 +1400,17 @@ aged_ordered_container (std::initializer_list <value_type> init,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
class Clock, class Compare, class Allocator>
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
~aged_ordered_container()
{
clear();
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
operator= (aged_ordered_container const& other) ->
aged_ordered_container&
{
@@ -1433,9 +1424,9 @@ operator= (aged_ordered_container const& other) ->
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
operator= (aged_ordered_container&& other) ->
aged_ordered_container&
{
@@ -1447,9 +1438,9 @@ operator= (aged_ordered_container&& other) ->
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
operator= (std::initializer_list <value_type> init) ->
aged_ordered_container&
{
@@ -1461,10 +1452,10 @@ operator= (std::initializer_list <value_type> init) ->
//------------------------------------------------------------------------------
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <class K, bool maybe_multi, bool maybe_map, class>
typename std::conditional <IsMap, T, void*>::type&
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
at (K const& k)
{
auto const iter (m_cont.find (k,
@@ -1475,10 +1466,10 @@ at (K const& k)
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <class K, bool maybe_multi, bool maybe_map, class>
typename std::conditional <IsMap, T, void*>::type const&
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
at (K const& k) const
{
auto const iter (m_cont.find (k,
@@ -1489,10 +1480,10 @@ at (K const& k) const
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool maybe_multi, bool maybe_map, class>
typename std::conditional <IsMap, T, void*>::type&
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
operator[] (Key const& key)
{
typename cont_type::insert_commit_data d;
@@ -1511,10 +1502,10 @@ operator[] (Key const& key)
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool maybe_multi, bool maybe_map, class>
typename std::conditional <IsMap, T, void*>::type&
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
operator[] (Key&& key)
{
typename cont_type::insert_commit_data d;
@@ -1536,9 +1527,9 @@ operator[] (Key&& key)
//------------------------------------------------------------------------------
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
void
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
clear()
{
for (auto iter (chronological.list.begin());
@@ -1550,10 +1541,10 @@ clear()
// map, set
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool maybe_multi>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
insert (value_type const& value) ->
typename std::enable_if <! maybe_multi,
std::pair <iterator, bool>>::type
@@ -1573,10 +1564,10 @@ insert (value_type const& value) ->
// multimap, multiset
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool maybe_multi>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
insert (value_type const& value) ->
typename std::enable_if <maybe_multi,
iterator>::type
@@ -1591,10 +1582,10 @@ insert (value_type const& value) ->
// set
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool maybe_multi, bool maybe_map>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
insert (value_type&& value) ->
typename std::enable_if <! maybe_multi && ! maybe_map,
std::pair <iterator, bool>>::type
@@ -1614,10 +1605,10 @@ insert (value_type&& value) ->
// multiset
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool maybe_multi, bool maybe_map>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
insert (value_type&& value) ->
typename std::enable_if <maybe_multi && ! maybe_map,
iterator>::type
@@ -1634,10 +1625,10 @@ insert (value_type&& value) ->
// map, set
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool maybe_multi>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
insert (const_iterator hint, value_type const& value) ->
typename std::enable_if <! maybe_multi,
iterator>::type
@@ -1657,10 +1648,10 @@ insert (const_iterator hint, value_type const& value) ->
// map, set
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool maybe_multi>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
insert (const_iterator hint, value_type&& value) ->
typename std::enable_if <! maybe_multi,
iterator>::type
@@ -1680,10 +1671,10 @@ insert (const_iterator hint, value_type&& value) ->
// map, set
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool maybe_multi, class... Args>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
emplace (Args&&... args) ->
typename std::enable_if <! maybe_multi,
std::pair <iterator, bool>>::type
@@ -1707,10 +1698,10 @@ emplace (Args&&... args) ->
// multiset, multimap
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool maybe_multi, class... Args>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
emplace (Args&&... args) ->
typename std::enable_if <maybe_multi,
iterator>::type
@@ -1726,10 +1717,10 @@ emplace (Args&&... args) ->
// map, set
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool maybe_multi, class... Args>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
emplace_hint (const_iterator hint, Args&&... args) ->
typename std::enable_if <! maybe_multi,
std::pair <iterator, bool>>::type
@@ -1752,10 +1743,10 @@ emplace_hint (const_iterator hint, Args&&... args) ->
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool is_const, class Iterator, class Base, class>
detail::aged_container_iterator <false, Iterator, Base>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
erase (detail::aged_container_iterator <is_const, Iterator, Base> pos)
{
unlink_and_delete_element(&*((pos++).iterator()));
@@ -1764,10 +1755,10 @@ erase (detail::aged_container_iterator <is_const, Iterator, Base> pos)
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool is_const, class Iterator, class Base, class>
detail::aged_container_iterator <false, Iterator, Base>
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
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)
{
@@ -1779,10 +1770,10 @@ erase (detail::aged_container_iterator <is_const, Iterator, Base> first,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <class K>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
erase (K const& k) ->
size_type
{
@@ -1805,9 +1796,9 @@ erase (K const& k) ->
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
void
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
swap (aged_ordered_container& other) noexcept
{
swap_data (other);
@@ -1818,10 +1809,10 @@ swap (aged_ordered_container& other) noexcept
//------------------------------------------------------------------------------
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <class K>
auto
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
touch (K const& k) ->
size_type
{
@@ -1839,11 +1830,11 @@ touch (K const& k) ->
//------------------------------------------------------------------------------
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool OtherIsMulti, bool OtherIsMap,
class OtherT, class OtherDuration, class OtherAllocator>
bool
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
operator== (
aged_ordered_container <OtherIsMulti, OtherIsMap,
Key, OtherT, OtherDuration, Compare,
@@ -1866,10 +1857,10 @@ operator== (
//------------------------------------------------------------------------------
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool is_const, class Iterator, class Base, class>
void
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
touch (detail::aged_container_iterator <
is_const, Iterator, Base> pos,
typename clock_type::time_point const& now)
@@ -1881,10 +1872,10 @@ touch (detail::aged_container_iterator <
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool maybe_propagate>
typename std::enable_if <maybe_propagate>::type
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
swap_data (aged_ordered_container& other) noexcept
{
std::swap (m_config.key_compare(), other.m_config.key_compare());
@@ -1893,10 +1884,10 @@ swap_data (aged_ordered_container& other) noexcept
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
template <bool maybe_propagate>
typename std::enable_if <! maybe_propagate>::type
aged_ordered_container <IsMulti, IsMap, Key, T, Duration, Compare, Allocator>::
aged_ordered_container <IsMulti, IsMap, Key, T, Clock, Compare, Allocator>::
swap_data (aged_ordered_container& other) noexcept
{
std::swap (m_config.key_compare(), other.m_config.key_compare());
@@ -1908,9 +1899,9 @@ swap_data (aged_ordered_container& other) noexcept
//------------------------------------------------------------------------------
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
struct is_aged_container <detail::aged_ordered_container <
IsMulti, IsMap, Key, T, Duration, Compare, Allocator>>
IsMulti, IsMap, Key, T, Clock, Compare, Allocator>>
: std::true_type
{
};
@@ -1918,22 +1909,22 @@ struct is_aged_container <detail::aged_ordered_container <
// Free functions
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator>
class Clock, class Compare, class Allocator>
void swap (
detail::aged_ordered_container <IsMulti, IsMap,
Key, T, Duration, Compare, Allocator>& lhs,
Key, T, Clock, Compare, Allocator>& lhs,
detail::aged_ordered_container <IsMulti, IsMap,
Key, T, Duration, Compare, Allocator>& rhs) noexcept
Key, T, Clock, Compare, Allocator>& rhs) noexcept
{
lhs.swap (rhs);
}
/** Expire aged container items past the specified age. */
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Compare, class Allocator,
class Clock, class Compare, class Allocator,
class Rep, class Period>
std::size_t expire (detail::aged_ordered_container <
IsMulti, IsMap, Key, T, Duration, Compare, Allocator>& c,
IsMulti, IsMap, Key, T, Clock, Compare, Allocator>& c,
std::chrono::duration <Rep, Period> const& age)
{
std::size_t n (0);

View File

@@ -22,15 +22,11 @@
#include <beast/container/detail/aged_container_iterator.h>
#include <beast/container/detail/aged_associative_container.h>
#include <beast/container/aged_container.h>
#include <beast/chrono/abstract_clock.h>
#include <beast/utility/empty_base_optimization.h>
#include <boost/intrusive/list.hpp>
#include <boost/intrusive/unordered_set.hpp>
#include <beast/cxx14/algorithm.h> // <algorithm>
#include <functional>
#include <initializer_list>
@@ -80,7 +76,7 @@ template <
bool IsMap,
class Key,
class T,
class Duration = std::chrono::seconds,
class Clock = std::chrono::steady_clock,
class Hash = std::hash <Key>,
class KeyEqual = std::equal_to <Key>,
class Allocator = std::allocator <
@@ -91,24 +87,20 @@ template <
class aged_unordered_container
{
public:
typedef abstract_clock <Duration> clock_type;
typedef typename clock_type::time_point time_point;
typedef typename clock_type::duration duration;
typedef Key key_type;
typedef T mapped_type;
typedef typename std::conditional <IsMap,
std::pair <Key const, T>,
Key>::type value_type;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
using clock_type = abstract_clock<Clock>;
using time_point = typename clock_type::time_point;
using duration = typename clock_type::duration;
using key_type = Key;
using mapped_type = T;
using value_type = typename std::conditional <IsMap,
std::pair <Key const, T>, Key>::type;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
// Introspection (for unit tests)
typedef std::true_type is_unordered;
typedef std::integral_constant <bool, IsMulti> is_multi;
typedef std::integral_constant <bool, IsMap> is_map;
// VFALCO TODO How can we reorder the declarations to keep
// all the public things together contiguously?
using is_unordered = std::true_type;
using is_multi = std::integral_constant <bool, IsMulti>;
using is_map = std::integral_constant <bool, IsMap>;
private:
static Key const& extract (value_type const& value)
@@ -1504,8 +1496,8 @@ private:
//------------------------------------------------------------------------------
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (
clock_type& clock)
@@ -1517,8 +1509,8 @@ aged_unordered_container (
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (
clock_type& clock,
@@ -1531,8 +1523,8 @@ aged_unordered_container (
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (
clock_type& clock,
@@ -1545,8 +1537,8 @@ aged_unordered_container (
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (
clock_type& clock,
@@ -1560,8 +1552,8 @@ aged_unordered_container (
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (
clock_type& clock,
@@ -1575,8 +1567,8 @@ aged_unordered_container (
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (
clock_type& clock,
@@ -1591,8 +1583,8 @@ aged_unordered_container (
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (
clock_type& clock,
@@ -1607,8 +1599,8 @@ aged_unordered_container (
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (
clock_type& clock,
@@ -1624,9 +1616,9 @@ aged_unordered_container (
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <class InputIt>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (InputIt first, InputIt last,
clock_type& clock)
@@ -1639,9 +1631,9 @@ aged_unordered_container (InputIt first, InputIt last,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <class InputIt>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (InputIt first, InputIt last,
clock_type& clock,
@@ -1655,9 +1647,9 @@ aged_unordered_container (InputIt first, InputIt last,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <class InputIt>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (InputIt first, InputIt last,
clock_type& clock,
@@ -1671,9 +1663,9 @@ aged_unordered_container (InputIt first, InputIt last,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <class InputIt>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (InputIt first, InputIt last,
clock_type& clock,
@@ -1688,9 +1680,9 @@ aged_unordered_container (InputIt first, InputIt last,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <class InputIt>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (InputIt first, InputIt last,
clock_type& clock,
@@ -1705,9 +1697,9 @@ aged_unordered_container (InputIt first, InputIt last,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <class InputIt>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (InputIt first, InputIt last,
clock_type& clock,
@@ -1723,9 +1715,9 @@ aged_unordered_container (InputIt first, InputIt last,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <class InputIt>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (InputIt first, InputIt last,
clock_type& clock,
@@ -1741,9 +1733,9 @@ aged_unordered_container (InputIt first, InputIt last,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <class InputIt>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (InputIt first, InputIt last,
clock_type& clock,
@@ -1760,8 +1752,8 @@ aged_unordered_container (InputIt first, InputIt last,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (aged_unordered_container const& other)
: m_config (other.m_config)
@@ -1774,8 +1766,8 @@ aged_unordered_container (aged_unordered_container const& other)
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (aged_unordered_container const& other,
Allocator const& alloc)
@@ -1789,8 +1781,8 @@ aged_unordered_container (aged_unordered_container const& other,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (aged_unordered_container&& other)
: m_config (std::move (other.m_config))
@@ -1801,8 +1793,8 @@ aged_unordered_container (aged_unordered_container&& other)
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (aged_unordered_container&& other,
Allocator const& alloc)
@@ -1817,8 +1809,8 @@ aged_unordered_container (aged_unordered_container&& other,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (std::initializer_list <value_type> init,
clock_type& clock)
@@ -1831,8 +1823,8 @@ aged_unordered_container (std::initializer_list <value_type> init,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (std::initializer_list <value_type> init,
clock_type& clock,
@@ -1846,8 +1838,8 @@ aged_unordered_container (std::initializer_list <value_type> init,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (std::initializer_list <value_type> init,
clock_type& clock,
@@ -1861,8 +1853,8 @@ aged_unordered_container (std::initializer_list <value_type> init,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (std::initializer_list <value_type> init,
clock_type& clock,
@@ -1877,8 +1869,8 @@ aged_unordered_container (std::initializer_list <value_type> init,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (std::initializer_list <value_type> init,
clock_type& clock,
@@ -1893,8 +1885,8 @@ aged_unordered_container (std::initializer_list <value_type> init,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (std::initializer_list <value_type> init,
clock_type& clock,
@@ -1910,8 +1902,8 @@ aged_unordered_container (std::initializer_list <value_type> init,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (std::initializer_list <value_type> init,
clock_type& clock,
@@ -1927,8 +1919,8 @@ aged_unordered_container (std::initializer_list <value_type> init,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
aged_unordered_container (std::initializer_list <value_type> init,
clock_type& clock,
@@ -1945,8 +1937,8 @@ aged_unordered_container (std::initializer_list <value_type> init,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
class Clock, class Hash, class KeyEqual, class Allocator>
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
~aged_unordered_container()
{
@@ -1954,9 +1946,9 @@ aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
operator= (aged_unordered_container const& other)
-> aged_unordered_container&
@@ -1974,9 +1966,9 @@ operator= (aged_unordered_container const& other)
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
operator= (aged_unordered_container&& other) ->
aged_unordered_container&
@@ -1992,9 +1984,9 @@ operator= (aged_unordered_container&& other) ->
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
operator= (std::initializer_list <value_type> init) ->
aged_unordered_container&
@@ -2007,10 +1999,10 @@ operator= (std::initializer_list <value_type> init) ->
//------------------------------------------------------------------------------
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <class K, bool maybe_multi, bool maybe_map, class>
typename std::conditional <IsMap, T, void*>::type&
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
at (K const& k)
{
@@ -2023,10 +2015,10 @@ at (K const& k)
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <class K, bool maybe_multi, bool maybe_map, class>
typename std::conditional <IsMap, T, void*>::type const&
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
at (K const& k) const
{
@@ -2039,10 +2031,10 @@ at (K const& k) const
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool maybe_multi, bool maybe_map, class>
typename std::conditional <IsMap, T, void*>::type&
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
operator[] (Key const& key)
{
@@ -2065,10 +2057,10 @@ operator[] (Key const& key)
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool maybe_multi, bool maybe_map, class>
typename std::conditional <IsMap, T, void*>::type&
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
operator[] (Key&& key)
{
@@ -2093,9 +2085,9 @@ operator[] (Key&& key)
//------------------------------------------------------------------------------
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
void
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
clear()
{
@@ -2109,10 +2101,10 @@ clear()
// map, set
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool maybe_multi>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
insert (value_type const& value) ->
typename std::enable_if <! maybe_multi,
@@ -2135,10 +2127,10 @@ insert (value_type const& value) ->
// multimap, multiset
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool maybe_multi>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
insert (value_type const& value) ->
typename std::enable_if <maybe_multi,
@@ -2153,10 +2145,10 @@ insert (value_type const& value) ->
// map, set
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool maybe_multi, bool maybe_map>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
insert (value_type&& value) ->
typename std::enable_if <! maybe_multi && ! maybe_map,
@@ -2179,10 +2171,10 @@ insert (value_type&& value) ->
// multimap, multiset
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool maybe_multi, bool maybe_map>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
insert (value_type&& value) ->
typename std::enable_if <maybe_multi && ! maybe_map,
@@ -2198,10 +2190,10 @@ insert (value_type&& value) ->
#if 1 // Use insert() instead of insert_check() insert_commit()
// set, map
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool maybe_multi, class... Args>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
emplace (Args&&... args) ->
typename std::enable_if <! maybe_multi,
@@ -2223,10 +2215,10 @@ emplace (Args&&... args) ->
#else // As original, use insert_check() / insert_commit () pair.
// set, map
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool maybe_multi, class... Args>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
emplace (Args&&... args) ->
typename std::enable_if <! maybe_multi,
@@ -2254,10 +2246,10 @@ emplace (Args&&... args) ->
// multiset, multimap
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool maybe_multi, class... Args>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
emplace (Args&&... args) ->
typename std::enable_if <maybe_multi,
@@ -2273,10 +2265,10 @@ emplace (Args&&... args) ->
// set, map
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool maybe_multi, class... Args>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
emplace_hint (const_iterator /*hint*/, Args&&... args) ->
typename std::enable_if <! maybe_multi,
@@ -2302,10 +2294,10 @@ emplace_hint (const_iterator /*hint*/, Args&&... args) ->
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool is_const, class Iterator, class Base>
detail::aged_container_iterator <false, Iterator, Base>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
erase (detail::aged_container_iterator <
is_const, Iterator, Base> pos)
@@ -2316,10 +2308,10 @@ erase (detail::aged_container_iterator <
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool is_const, class Iterator, class Base>
detail::aged_container_iterator <false, Iterator, Base>
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
erase (detail::aged_container_iterator <
is_const, Iterator, Base> first,
@@ -2334,10 +2326,10 @@ erase (detail::aged_container_iterator <
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <class K>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
erase (K const& k) ->
size_type
@@ -2361,9 +2353,9 @@ erase (K const& k) ->
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
void
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
swap (aged_unordered_container& other) noexcept
{
@@ -2373,10 +2365,10 @@ swap (aged_unordered_container& other) noexcept
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <class K>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
touch (K const& k) ->
size_type
@@ -2393,7 +2385,7 @@ touch (K const& k) ->
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <
bool OtherIsMap,
class OtherKey,
@@ -2405,7 +2397,7 @@ template <
>
typename std::enable_if <! maybe_multi, bool>::type
aged_unordered_container <
IsMulti, IsMap, Key, T, Duration, Hash, KeyEqual, Allocator>::
IsMulti, IsMap, Key, T, Clock, Hash, KeyEqual, Allocator>::
operator== (
aged_unordered_container <false, OtherIsMap,
OtherKey, OtherT, OtherDuration, OtherHash, KeyEqual,
@@ -2424,7 +2416,7 @@ operator== (
}
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <
bool OtherIsMap,
class OtherKey,
@@ -2436,7 +2428,7 @@ template <
>
typename std::enable_if <maybe_multi, bool>::type
aged_unordered_container <
IsMulti, IsMap, Key, T, Duration, Hash, KeyEqual, Allocator>::
IsMulti, IsMap, Key, T, Clock, Hash, KeyEqual, Allocator>::
operator== (
aged_unordered_container <true, OtherIsMap,
OtherKey, OtherT, OtherDuration, OtherHash, KeyEqual,
@@ -2469,10 +2461,10 @@ operator== (
// map, set
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool maybe_multi>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
insert_unchecked (value_type const& value) ->
typename std::enable_if <! maybe_multi,
@@ -2494,10 +2486,10 @@ insert_unchecked (value_type const& value) ->
// multimap, multiset
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
template <bool maybe_multi>
auto
aged_unordered_container <IsMulti, IsMap, Key, T, Duration,
aged_unordered_container <IsMulti, IsMap, Key, T, Clock,
Hash, KeyEqual, Allocator>::
insert_unchecked (value_type const& value) ->
typename std::enable_if <maybe_multi,
@@ -2516,32 +2508,32 @@ insert_unchecked (value_type const& value) ->
//------------------------------------------------------------------------------
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator>
class Clock, class Hash, class KeyEqual, class Allocator>
struct is_aged_container <detail::aged_unordered_container <
IsMulti, IsMap, Key, T, Duration, Hash, KeyEqual, Allocator>>
IsMulti, IsMap, Key, T, Clock, Hash, KeyEqual, Allocator>>
: std::true_type
{
};
// Free functions
template <bool IsMulti, bool IsMap, class Key, class T, class Duration,
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,
Key, T, Duration, Hash, KeyEqual, Allocator>& lhs,
Key, T, Clock, Hash, KeyEqual, Allocator>& lhs,
detail::aged_unordered_container <IsMulti, IsMap,
Key, T, Duration, Hash, KeyEqual, Allocator>& rhs) noexcept
Key, T, Clock, Hash, KeyEqual, Allocator>& rhs) noexcept
{
lhs.swap (rhs);
}
/** Expire aged container items past the specified age. */
template <bool IsMulti, bool IsMap, class Key, class T,
class Duration, class Hash, class KeyEqual, class Allocator,
class Clock, class Hash, class KeyEqual, class Allocator,
class Rep, class Period>
std::size_t expire (detail::aged_unordered_container <
IsMulti, IsMap, Key, T, Duration, Hash, KeyEqual, Allocator>& c,
IsMulti, IsMap, Key, T, Clock, Hash, KeyEqual, Allocator>& c,
std::chrono::duration <Rep, Period> const& age) noexcept
{
std::size_t n (0);

View File

@@ -302,7 +302,7 @@ public:
>
using Cont = detail::aged_ordered_container <
Base::is_multi::value, Base::is_map::value, typename Base::Key,
typename Base::T, typename Base::Dur, Compare, Allocator>;
typename Base::T, typename Base::Clock, Compare, Allocator>;
};
// unordered
@@ -318,7 +318,7 @@ public:
>
using Cont = detail::aged_unordered_container <
Base::is_multi::value, Base::is_map::value,
typename Base::Key, typename Base::T, typename Base::Dur,
typename Base::Key, typename Base::T, typename Base::Clock,
Hash, KeyEqual, Allocator>;
};
@@ -327,8 +327,8 @@ public:
struct TestTraitsBase
{
typedef std::string Key;
typedef std::chrono::seconds Dur;
typedef manual_clock <Dur> Clock;
typedef std::chrono::steady_clock Clock;
typedef manual_clock<Clock> ManualClock;
};
template <bool IsUnordered, bool IsMulti, bool IsMap>
@@ -744,12 +744,12 @@ testConstructEmpty ()
typedef typename Traits::Value Value;
typedef typename Traits::Key Key;
typedef typename Traits::T T;
typedef typename Traits::Dur Dur;
typedef typename Traits::Clock Clock;
typedef typename Traits::Comp Comp;
typedef typename Traits::Alloc Alloc;
typedef typename Traits::MyComp MyComp;
typedef typename Traits::MyAlloc MyAlloc;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
//testcase (Traits::name() + " empty");
testcase ("empty");
@@ -789,14 +789,14 @@ testConstructEmpty ()
typedef typename Traits::Value Value;
typedef typename Traits::Key Key;
typedef typename Traits::T T;
typedef typename Traits::Dur Dur;
typedef typename Traits::Clock Clock;
typedef typename Traits::Hash Hash;
typedef typename Traits::Equal Equal;
typedef typename Traits::Alloc Alloc;
typedef typename Traits::MyHash MyHash;
typedef typename Traits::MyEqual MyEqual;
typedef typename Traits::MyAlloc MyAlloc;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
//testcase (Traits::name() + " empty");
testcase ("empty");
@@ -859,12 +859,12 @@ testConstructRange ()
typedef typename Traits::Value Value;
typedef typename Traits::Key Key;
typedef typename Traits::T T;
typedef typename Traits::Dur Dur;
typedef typename Traits::Clock Clock;
typedef typename Traits::Comp Comp;
typedef typename Traits::Alloc Alloc;
typedef typename Traits::MyComp MyComp;
typedef typename Traits::MyAlloc MyAlloc;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
auto const v (Traits::values());
//testcase (Traits::name() + " range");
@@ -922,14 +922,14 @@ testConstructRange ()
typedef typename Traits::Value Value;
typedef typename Traits::Key Key;
typedef typename Traits::T T;
typedef typename Traits::Dur Dur;
typedef typename Traits::Clock Clock;
typedef typename Traits::Hash Hash;
typedef typename Traits::Equal Equal;
typedef typename Traits::Alloc Alloc;
typedef typename Traits::MyHash MyHash;
typedef typename Traits::MyEqual MyEqual;
typedef typename Traits::MyAlloc MyAlloc;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
auto const v (Traits::values());
//testcase (Traits::name() + " range");
@@ -1002,12 +1002,12 @@ testConstructInitList ()
typedef typename Traits::Value Value;
typedef typename Traits::Key Key;
typedef typename Traits::T T;
typedef typename Traits::Dur Dur;
typedef typename Traits::Clock Clock;
typedef typename Traits::Comp Comp;
typedef typename Traits::Alloc Alloc;
typedef typename Traits::MyComp MyComp;
typedef typename Traits::MyAlloc MyAlloc;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
//testcase (Traits::name() + " init-list");
testcase ("init-list");
@@ -1027,14 +1027,14 @@ testConstructInitList ()
typedef typename Traits::Value Value;
typedef typename Traits::Key Key;
typedef typename Traits::T T;
typedef typename Traits::Dur Dur;
typedef typename Traits::Clock Clock;
typedef typename Traits::Hash Hash;
typedef typename Traits::Equal Equal;
typedef typename Traits::Alloc Alloc;
typedef typename Traits::MyHash MyHash;
typedef typename Traits::MyEqual MyEqual;
typedef typename Traits::MyAlloc MyAlloc;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
//testcase (Traits::name() + " init-list");
testcase ("init-list");
@@ -1057,7 +1057,7 @@ testCopyMove ()
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
typedef typename Traits::Value Value;
typedef typename Traits::Alloc Alloc;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
auto const v (Traits::values());
//testcase (Traits::name() + " copy/move");
@@ -1139,7 +1139,7 @@ testIterator()
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
typedef typename Traits::Value Value;
typedef typename Traits::Alloc Alloc;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
auto const v (Traits::values());
//testcase (Traits::name() + " iterators");
@@ -1202,7 +1202,7 @@ testReverseIterator()
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
typedef typename Traits::Value Value;
typedef typename Traits::Alloc Alloc;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
auto const v (Traits::values());
//testcase (Traits::name() + " reverse_iterators");
@@ -1357,7 +1357,7 @@ aged_associative_container_test_base::
testModifiers()
{
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
auto const v (Traits::values());
auto const l (make_list (v));
@@ -1418,7 +1418,7 @@ testChronological ()
{
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
typedef typename Traits::Value Value;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
auto const v (Traits::values());
//testcase (Traits::name() + " chronological");
@@ -1484,7 +1484,7 @@ aged_associative_container_test_base::
testArrayCreate()
{
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
auto v (Traits::values());
//testcase (Traits::name() + " array create");
@@ -1522,8 +1522,9 @@ reverseFillAgedContainer (Container& c, Values const& values)
c.clear();
// c.clock() returns an abstract_clock, so dynamic_cast to manual_clock.
typedef TestTraitsBase::Clock Clock;
Clock& clk (dynamic_cast <Clock&> (c.clock ()));
// VFALCO NOTE This is sketchy
typedef TestTraitsBase::ManualClock ManualClock;
ManualClock& clk (dynamic_cast <ManualClock&> (c.clock()));
clk.set (0);
Values rev (values);
@@ -1626,8 +1627,8 @@ testElementErase ()
testcase ("element erase");
// Make and fill the container
typename Traits::Clock ck;
typename Traits::template Cont <> c {ck};
typename Traits::ManualClock clock;
typename Traits::template Cont <> c {clock};
reverseFillAgedContainer (c, Traits::values());
{
@@ -1756,8 +1757,8 @@ testRangeErase ()
testcase ("range erase");
// Make and fill the container
typename Traits::Clock ck;
typename Traits::template Cont <> c {ck};
typename Traits::ManualClock clock;
typename Traits::template Cont <> c {clock};
reverseFillAgedContainer (c, Traits::values());
// Not bothering to test range erase with reverse iterators.
@@ -1785,7 +1786,7 @@ testCompare ()
{
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
typedef typename Traits::Value Value;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
auto const v (Traits::values());
//testcase (Traits::name() + " array create");
@@ -1819,7 +1820,7 @@ aged_associative_container_test_base::
testObservers()
{
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
//testcase (Traits::name() + " observers");
testcase ("observers");
@@ -1838,7 +1839,7 @@ aged_associative_container_test_base::
testObservers()
{
typedef TestTraits <IsUnordered, IsMulti, IsMap> Traits;
typename Traits::Clock clock;
typename Traits::ManualClock clock;
//testcase (Traits::name() + " observers");
testcase ("observers");

View File

@@ -21,10 +21,6 @@
#include <BeastConfig.h>
#endif
#include <beast/crypto/impl/MurmurHash.cpp>
#include <beast/crypto/impl/Sha256.cpp>
#include <beast/crypto/impl/UnsignedInteger.cpp>
#include <beast/crypto/tests/BinaryEncoding.cpp>
#include <beast/crypto/tests/UnsignedInteger.test.cpp>
#include <beast/crypto/tests/base64.test.cpp>

View File

@@ -1,84 +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_CRYPTO_MURMURHASH_H_INCLUDED
#define BEAST_CRYPTO_MURMURHASH_H_INCLUDED
#include <cstdint>
#include <stdexcept>
// Original source code links in .cpp file
namespace beast {
namespace Murmur {
extern void MurmurHash3_x86_32 (const void* key, int len, std::uint32_t seed, void* out);
extern void MurmurHash3_x86_128 (const void* key, int len, std::uint32_t seed, void* out);
extern void MurmurHash3_x64_128 (const void* key, int len, std::uint32_t seed, void* out);
// Uses Beast to choose an appropriate routine
// This handy template deduces which size hash is desired
template <typename HashType>
inline void Hash (const void* key, int len, std::uint32_t seed, HashType* out)
{
switch (8 * sizeof (HashType))
{
case 32:
MurmurHash3_x86_32 (key, len, seed, out);
break;
#if BEAST_64BIT
case 64:
{
HashType tmp[2];
MurmurHash3_x64_128 (key, len, seed, &tmp[0]);
*out = tmp[0];
}
break;
case 128:
MurmurHash3_x64_128 (key, len, seed, out);
break;
#else
case 64:
{
HashType tmp[2];
MurmurHash3_x86_128 (key, len, seed, &tmp[0]);
*out = tmp[0];
}
break;
case 128:
MurmurHash3_x86_128 (key, len, seed, out);
break;
#endif
default:
throw std::runtime_error ("invalid key size in MurmurHash");
break;
};
}
}
}
#endif

View File

@@ -42,9 +42,9 @@ typedef std::array <std::uint8_t, digestLength> digest_type;
namespace detail {
struct Context
{
std::uint32_t state[8];
std::uint64_t bitcount;
std::uint8_t buffer[Sha256::blockLength];
std::uint32_t state[8];
std::uint64_t bitcount;
std::uint8_t buffer[Sha256::blockLength];
};
}

View File

@@ -1,294 +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_CRYPTO_UNSIGNEDINTEGER_H_INCLUDED
#define BEAST_CRYPTO_UNSIGNEDINTEGER_H_INCLUDED
#include <beast/crypto/UnsignedIntegerCalc.h>
#include <beast/crypto/MurmurHash.h>
#include <beast/ByteOrder.h>
#include <beast/container/hardened_hash.h>
#include <beast/utility/noexcept.h>
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <memory>
namespace beast {
/** Represents a set of bits of fixed size.
The data is stored in "canonical" format which is network (big endian)
byte order, most significant byte first.
In this implementation the pointer to the beginning of the canonical format
may not be aligned.
*/
template <std::size_t Bytes>
class UnsignedInteger
{
public:
/** Constant for determining the number of bytes. */
static std::size_t const size = Bytes;
// The underlying integer type we use when converting to calculation format.
typedef std::uint32_t IntCalcType;
// The type of object resulting from a conversion to calculation format.
typedef UnsignedIntegerCalc <IntCalcType> CalcType;
// Standard container compatibility
typedef std::uint8_t value_type;
typedef value_type* iterator;
typedef value_type const* const_iterator;
/** Hardened hash function for use with hash based containers.
The seed is used to make the hash unpredictable. This prevents
attackers from exploiting crafted inputs to produce degenerate
containers.
*/
typedef hardened_hash <> hasher;
/** Determins if two UnsignedInteger objects are equal. */
class equal
{
public:
bool operator() (UnsignedInteger const& lhs, UnsignedInteger const& rhs) const
{
return lhs.compare (rhs) == 0;
}
};
//--------------------------------------------------------------------------
/** Construct the object.
The values are uninitialized.
*/
UnsignedInteger ()
{
}
/** Construct a copy. */
UnsignedInteger (UnsignedInteger const& other)
{
this->operator= (other);
}
/** Construct from a raw memory.
The area pointed to by buffer must be at least Bytes in size,
or else undefined behavior will result.
*/
/** @{ */
explicit UnsignedInteger (void const* buf)
{
m_values [0] = 0; // clear any pad bytes
std::memcpy (begin(), buf, Bytes);
}
template <typename InputIt>
UnsignedInteger (InputIt first, InputIt last)
{
m_values [0] = 0; // clear any pad bytes
assert (std::distance (first, last) == size);
std::copy (first, last, begin());
}
/** @} */
/** Assign from another UnsignedInteger. */
UnsignedInteger& operator= (UnsignedInteger const& other)
{
// Perform an aligned, all inclusive copy that includes padding.
std::copy (other.m_values, other.m_values + CalcCount, m_values);
return *this;
}
/** Create from an integer type.
@invariant IntegerType must be an unsigned integer type.
*/
template <class UnsignedIntegralType>
static UnsignedInteger createFromInteger (UnsignedIntegralType value)
{
static_assert (Bytes >= sizeof (UnsignedIntegralType),
"Bytes is too small.");
UnsignedInteger <Bytes> result;
value = toNetworkByteOrder <UnsignedIntegralType> (value);
result.clear ();
std::memcpy (result.end () - sizeof (value), &value,
std::min (Bytes, sizeof (value)));
return result;
}
/** Construct with a filled value. */
static UnsignedInteger createFilled (value_type value)
{
UnsignedInteger result;
result.fill (value);
return result;
}
/** Fill with a particular byte value. */
void fill (value_type value)
{
IntCalcType c;
memset (&c, value, sizeof (c));
std::fill (m_values, m_values + CalcCount, c);
}
/** Clear the contents to zero. */
void clear ()
{
std::fill (m_values, m_values + CalcCount, 0);
}
/** Convert to calculation format. */
CalcType toCalcType (bool convert = true)
{
return CalcType::fromCanonical (m_values, Bytes, convert);
}
/** Determine if all bits are zero. */
bool isZero () const
{
for (int i = 0; i < CalcCount; ++i)
{
if (m_values [i] != 0)
return false;
}
return true;
}
/** Determine if any bit is non-zero. */
bool isNotZero () const
{
return ! isZero ();
}
/** Support conversion to `bool`.
@return `true` if any bit is non-zero.
*/
explicit
operator bool() const
{
return isNotZero ();
}
/** Get an iterator to the beginning. */
iterator begin ()
{
return get();
}
/** Get an iterator to past-the-end. */
iterator end ()
{
return get()+Bytes;
}
/** Get a const iterator to the beginning. */
const_iterator begin () const
{
return get();
}
/** Get a const iterator to past-the-end. */
const_iterator end () const
{
return get()+Bytes;
}
/** Get a const iterator to the beginning. */
const_iterator cbegin () const
{
return get();
}
/** Get a const iterator to past-the-end. */
const_iterator cend () const
{
return get()+Bytes;
}
/** Compare two objects of equal size.
The comparison is performed using a numeric lexicographical comparison.
*/
int compare (UnsignedInteger const& other) const
{
return memcmp (cbegin (), other.cbegin (), Bytes);
}
/** Determine equality. */
bool operator== (UnsignedInteger const& other) const
{
return compare (other) == 0;
}
/** Determine inequality. */
bool operator!= (UnsignedInteger const& other) const
{
return compare (other) != 0;
}
/** Ordered comparison. */
bool operator< (UnsignedInteger const& other) const
{
return compare (other) < 0;
}
/** Ordered comparison. */
bool operator<= (UnsignedInteger const& other) const
{
return compare (other) <= 0;
}
/** Ordered comparison. */
bool operator> (UnsignedInteger const& other) const
{
return compare (other) > 0;
}
/** Ordered comparison. */
bool operator>= (UnsignedInteger const& other) const
{
return compare (other) >= 0;
}
private:
static std::size_t const CalcCount = (Bytes + sizeof (IntCalcType) - 1) / sizeof (IntCalcType);
value_type* get ()
{
return (reinterpret_cast <value_type*> (&m_values [0])) +
((sizeof(IntCalcType)-(Bytes&(sizeof(IntCalcType)-1)))&(sizeof(IntCalcType)-1));
}
value_type const* get () const
{
return (reinterpret_cast <value_type const*> (&m_values [0])) +
((sizeof(IntCalcType)-(Bytes&(sizeof(IntCalcType)-1)))&(sizeof(IntCalcType)-1));
}
IntCalcType m_values [CalcCount];
};
}
#endif

View File

@@ -1,442 +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_CRYPTO_UNSIGNEDINTEGERCALC_H_INCLUDED
#define BEAST_CRYPTO_UNSIGNEDINTEGERCALC_H_INCLUDED
#include <beast/ByteOrder.h>
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <cstring>
#include <utility>
namespace beast {
namespace detail {
template <typename UInt>
struct DoubleWidthUInt;
template <>
struct DoubleWidthUInt <std::uint16_t>
{
typedef std::uint32_t type;
};
template <>
struct DoubleWidthUInt <std::uint32_t>
{
typedef std::uint64_t type;
};
}
/** Multiprecision unsigned integer suitable for calculations.
The data is stored in "calculation" format, which means it can be
readily used for performing calculations, but no raw access to the
bytes are provided. To transmit a serialized unsigned integer or
perform base encodings, it must be converted back into UnsignedInteger.
The number is represented as a series of native UInt unsigned integer
types, in order of increasing significance.
This is a lightweight object, storage and ownership of the underlying
data buffer is an external responsibility. The makes the class cheap to
copy and pass by value.
A consequence of this ownership model is that arithmetics operators
which return results by value cannot be included in the interface.
*/
template <typename UInt>
class UnsignedIntegerCalc
{
public:
typedef typename detail::DoubleWidthUInt <UInt>::type UIntBig;
typedef std::size_t size_type;
static UInt const maxUInt = ((UInt)(-1));
static size_type const numBits = (sizeof(UInt)*8);
//--------------------------------------------------------------------------
/** Construct an empty integer / zero bits. */
UnsignedIntegerCalc ()
: m_size (0)
, m_values (nullptr)
{
}
/** Construct a reference to an existing buffer. */
UnsignedIntegerCalc (UnsignedIntegerCalc const& other)
: m_size (other.m_size)
, m_values (other.m_values)
{
}
/** Construct from an existing array of values.
The existing data must already be in the "calculation" format.
*/
UnsignedIntegerCalc (size_type count, UInt* values)
: m_size (count)
, m_values (values)
{
}
/** Convert to calculation format from canonical format.
This overwrites the callers memory without transferring ownership.
Canonical format is defined as a big endian byte oriented
multiprecision integer format. The buffer should point to the
beginning of the storage area and not the beginning of the canonical
data. Bytes is the desired canonical bytes.
*/
static UnsignedIntegerCalc fromCanonical (
void* buffer, size_type const bytes, bool swizzle = true)
{
UInt* const values (reinterpret_cast <UInt*> (buffer));
size_type const count ((bytes + sizeof (UInt) - 1) / sizeof (UInt));
if (swizzle)
{
// Zero fill the possibly uninitialized pad bytes
std::memset (buffer, 0,
((sizeof(UInt)-(bytes&(sizeof(UInt)-1)))&(sizeof(UInt)-1)));
// Swap and swizzle
UInt* lo (values);
UInt* hi (values + count - 1);
while (lo < hi)
{
std::swap (*lo, *hi);
*lo = fromNetworkByteOrder <UInt> (*lo);
++lo;
*hi = fromNetworkByteOrder <UInt> (*hi);
++hi;
}
if (lo == hi)
*lo = fromNetworkByteOrder <UInt> (*lo);
}
return UnsignedIntegerCalc (count, values);
}
/** Convert the buffer back into canonical format.
Since ownership was never transferred, the caller's data is
restored to its original format. Typically this will be done
as the last step of a series of operations.
*/
void toCanonical ()
{
// Swap and swizzle
UInt* lo (m_values);
UInt* hi (m_values + m_size - 1);
while (lo < hi)
{
std::swap (*lo, *hi);
*lo = toNetworkByteOrder <UInt> (*lo); ++lo;
*hi = toNetworkByteOrder <UInt> (*hi); --hi;
}
if (lo == hi)
*lo = toNetworkByteOrder <UInt> (*lo);
}
/** Assign a value from another integer.
@note This does not transfer the reference to the buffer, it
copies the values from one buffer to the other.
*/
UnsignedIntegerCalc& operator= (UnsignedIntegerCalc const& other)
{
assert (other.size() <= size());
size_type n (size());
UInt* dest (m_values + size());
for (; n-- > other.size();)
*--dest = 0;
UInt const* rhs (other.m_values + n);
for (; n--;)
*--dest = *--rhs;
return *this;
}
/** Returns `true` if this represents the number zero. */
bool isZero () const
{
for (size_type n (size()); n--;)
if (m_values [n] != 0)
return false;
return true;
}
/** Returns `true` if this represents any number other than zero. */
bool isNotZero () const
{
return ! isZero ();
}
/** Safe conversion to `bool`, `true` means a non-zero value. */
explicit
operator bool() const
{
return isNotZero ();
}
/** Returns `true` if the buffer has 0 values. */
bool empty () const
{
return m_size == 0;
}
/** Returns the size of the buffer, in values. */
size_type size () const
{
return m_size;
}
/** Safe array indexing to arbitrary positions.
If the index is out of range, zero is returned.
*/
UInt operator[] (size_type n) const
{
if (n >= 0 && n < size())
return m_values [n];
return 0;
}
/** Universal comparison.
The comparison is performed numerically.
The return values have the same meaning as memcmp().
*/
int compare (UnsignedIntegerCalc const& other) const
{
if (size() == 0)
{
if (other.size() == 0)
return 0;
return -1;
}
else if (other.size() == 0)
{
return 1;
}
for (size_type n (std::max (size(), other.size())); n--;)
{
UInt lhs ((*this)[n]);
UInt rhs (other[n]);
if (lhs < rhs)
return -1;
else if (lhs > rhs)
return 1;
}
return 0;
}
/** Determine equality. */
bool operator== (UnsignedIntegerCalc const& other) const
{
return compare (other) == 0;
}
/** Determine inequality. */
bool operator!= (UnsignedIntegerCalc const& other) const
{
return compare (other) != 0;
}
/** Ordered comparison. */
bool operator< (UnsignedIntegerCalc const& other) const
{
return compare (other) < 0;
}
/** Ordered comparison. */
bool operator<= (UnsignedIntegerCalc const& other) const
{
return compare (other) <= 0;
}
/** Ordered comparison. */
bool operator> (UnsignedIntegerCalc const& other) const
{
return compare (other) > 0;
}
/** Ordered comparison. */
bool operator>= (UnsignedIntegerCalc const& other) const
{
return compare (other) >= 0;
}
/** Assign zero. */
void clear ()
{
UInt* dest (m_values - 1);
for (size_type n (size()); n--;)
*++dest = 0;
}
/** Perform bitwise logical-not. */
/*
UnsignedIntegerCalc& not ()
{
unaryAssign (Not());
return *this;
}
*/
/** Perform bitwise logical-or. */
UnsignedIntegerCalc& operator|= (UnsignedIntegerCalc const& rhs)
{
binaryAssign (rhs, Or());
return *this;
}
/** Perform bitwise logical-and. */
UnsignedIntegerCalc& operator&= (UnsignedIntegerCalc const& rhs)
{
binaryAssign (rhs, And());
return *this;
}
/** Perform bitwise logical-xor. */
UnsignedIntegerCalc& operator^= (UnsignedIntegerCalc const& rhs)
{
binaryAssign (rhs, Xor());
return *this;
}
/** Perform addition. */
UnsignedIntegerCalc& operator+= (UnsignedIntegerCalc const& v)
{
UIntBig carry (0);
UInt* lhs (m_values);
UInt const* rhs (v.m_values - 1);
for (size_type n (0); n<size() || n<v.size(); ++n)
{
UIntBig part (carry);
carry = 0;
if (n < size())
part += *lhs;
if (n < v.size())
part += *++rhs;
if (part > maxUInt)
{
part &= maxUInt;
carry = 1;
}
*lhs++ = UInt (part);
}
assert (carry == 0); // overflow
return *this;
}
/** Perform small addition. */
UnsignedIntegerCalc& operator+= (UInt rhs)
{
UnsignedIntegerCalc const v (1, &rhs);
return operator+= (v);
}
/** Perform small multiply. */
UnsignedIntegerCalc& operator*= (UInt rhs)
{
UIntBig carry (0);
UInt* lhs (m_values - 1);
for (size_type n (size()); n--;)
{
UIntBig part (carry);
carry = 0;
part += (*++lhs) * UIntBig(rhs);
carry = part >> numBits;
*lhs = UInt (part & maxUInt);
}
assert (carry == 0); // overflow
return *this;
}
/** Small division. */
UnsignedIntegerCalc operator/= (UInt rhs)
{
UIntBig dividend (0);
UInt* lhs (m_values+size());
for (size_type n (size()); n--;)
{
dividend |= *--lhs;
*lhs = UInt (dividend / rhs);
dividend = (dividend % rhs) << numBits;
}
return *this;
}
/** Small modulus. */
UInt operator% (UInt rhs) const
{
UIntBig modsq = 1;
UIntBig result = 0;
UInt const* lhs (m_values);
for (size_type n (size()); n--; ++lhs)
{
for (int bit (0); bit < numBits; ++bit)
{
if (((*lhs) & (1 << bit)) != 0)
{
result += modsq;
if (result >= rhs)
result -= rhs;
}
modsq <<= 1;
if (modsq >= rhs)
modsq -= rhs;
}
}
return UInt (result);
}
private:
struct Not { void operator() (UInt& rv) const { rv = ~rv; } };
struct Or { void operator() (UInt& lhs, UInt rhs) const { lhs |= rhs; } };
struct And { void operator() (UInt& lhs, UInt rhs) const { lhs &= rhs; } };
struct Xor { void operator() (UInt& lhs, UInt rhs) const { lhs ^= rhs; } };
template <class Operator>
void unaryAssign (Operator op = Operator())
{
UInt* dest (m_values-1);
for (size_type n (size()); n--;)
op (*++dest);
}
template <class Operator>
void binaryAssign (UnsignedIntegerCalc const& other, Operator op = Operator ())
{
UInt* dest (m_values + size());
size_type n (size());
for (; n-- > other.size();)
*--dest = 0;
UInt const* rhs (other.m_values + n);
for (UInt const* rhs (other.m_values + n); n--;)
op (*--dest, *--rhs);
}
size_type m_size;
UInt* m_values;
};
}
#endif

View File

@@ -0,0 +1,186 @@
//------------------------------------------------------------------------------
/*
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_BASE64_H_INCLUDED
#define BEAST_CRYPTO_BASE64_H_INCLUDED
#include <cctype>
#include <string>
namespace beast {
/*
Portions from http://www.adp-gmbh.ch/cpp/common/base64.html
Copyright notice:
base64.cpp and base64.h
Copyright (C) 2004-2008 Ren<65> Nyffenegger
This source code is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this source code must not be misrepresented; you must not
claim that you wrote the original source code. If you use this source code
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original source code.
3. This notice may not be removed or altered from any source distribution.
Ren<65> Nyffenegger rene.nyffenegger@adp-gmbh.ch
*/
template <class = void>
std::string const&
base64_alphabet()
{
static std::string const alphabet =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
return alphabet;
}
inline
bool
is_base64(unsigned char c)
{
return (std::isalnum(c) || (c == '+') || (c == '/'));
}
template <class = void>
std::string
base64_encode (std::uint8_t const* data,
std::size_t in_len)
{
unsigned char c3[3], c4[4];
int i = 0;
int j = 0;
std::string ret;
ret.reserve (3 + in_len * 8 / 6);
char const* alphabet (base64_alphabet().data());
while(in_len--)
{
c3[i++] = *(data++);
if(i == 3)
{
c4[0] = (c3[0] & 0xfc) >> 2;
c4[1] = ((c3[0] & 0x03) << 4) + ((c3[1] & 0xf0) >> 4);
c4[2] = ((c3[1] & 0x0f) << 2) + ((c3[2] & 0xc0) >> 6);
c4[3] = c3[2] & 0x3f;
for(i = 0; (i < 4); i++)
ret += alphabet[c4[i]];
i = 0;
}
}
if(i)
{
for(j = i; j < 3; j++)
c3[j] = '\0';
c4[0] = (c3[0] & 0xfc) >> 2;
c4[1] = ((c3[0] & 0x03) << 4) + ((c3[1] & 0xf0) >> 4);
c4[2] = ((c3[1] & 0x0f) << 2) + ((c3[2] & 0xc0) >> 6);
c4[3] = c3[2] & 0x3f;
for(j = 0; (j < i + 1); j++)
ret += alphabet[c4[j]];
while((i++ < 3))
ret += '=';
}
return ret;
}
template <class = void>
std::string
base64_encode (std::string const& s)
{
return base64_encode (reinterpret_cast <
std::uint8_t const*> (s.data()), s.size());
}
template <class = void>
std::string
base64_decode(std::string const& data)
{
int in_len = data.size();
unsigned char c3[3], c4[4];
int i = 0;
int j = 0;
int in_ = 0;
std::string ret;
ret.reserve (in_len * 6 / 8); // ???
while(in_len-- && (data[in_] != '=') &&
is_base64(data[in_]))
{
c4[i++] = data[in_]; in_++;
if(i == 4) {
for(i = 0; i < 4; i++)
c4[i] = base64_alphabet().find(c4[i]);
c3[0] = (c4[0] << 2) + ((c4[1] & 0x30) >> 4);
c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2);
c3[2] = ((c4[2] & 0x3) << 6) + c4[3];
for(i = 0; (i < 3); i++)
ret += c3[i];
i = 0;
}
}
if(i)
{
for(j = i; j < 4; j++)
c4[j] = 0;
for(j = 0; j < 4; j++)
c4[j] = base64_alphabet().find(c4[j]);
c3[0] = (c4[0] << 2) + ((c4[1] & 0x30) >> 4);
c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2);
c3[2] = ((c4[2] & 0x3) << 6) + c4[3];
for(j = 0; (j < i - 1); j++)
ret += c3[j];
}
return ret;
}
}
#endif

View File

@@ -1,492 +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.
*/
//==============================================================================
// http://code.google.com/p/smhasher/
#include <beast/crypto/MurmurHash.h>
#include <cstdint>
namespace beast {
namespace Murmur {
//-----------------------------------------------------------------------------
// Platform-specific functions and macros
// Microsoft Visual Studio
#if BEAST_MSVC
#define ROTL32(x,y) _rotl(x,y)
#define ROTL64(x,y) _rotl64(x,y)
#define BIG_CONSTANT(x) (x)
// Other compilers
#else
static inline std::uint32_t rotl32 ( std::uint32_t x, int8_t r )
{
return (x << r) | (x >> (32 - r));
}
static inline std::uint64_t rotl64 ( std::uint64_t x, int8_t r )
{
return (x << r) | (x >> (64 - r));
}
#define ROTL32(x,y) rotl32(x,y)
#define ROTL64(x,y) rotl64(x,y)
#define BIG_CONSTANT(x) (x##LLU)
#endif
//-----------------------------------------------------------------------------
// Block read - if your platform needs to do endian-swapping or can only
// handle aligned reads, do the conversion here
static inline std::uint32_t getblock ( const std::uint32_t* p, int i )
{
return p[i];
}
static inline std::uint64_t getblock ( const std::uint64_t* p, int i )
{
return p[i];
}
//-----------------------------------------------------------------------------
// Finalization mix - force all bits of a hash block to avalanche
static inline std::uint32_t fmix ( std::uint32_t h )
{
h ^= h >> 16;
h *= 0x85ebca6b;
h ^= h >> 13;
h *= 0xc2b2ae35;
h ^= h >> 16;
return h;
}
//----------
static inline std::uint64_t fmix ( std::uint64_t k )
{
k ^= k >> 33;
k *= BIG_CONSTANT (0xff51afd7ed558ccd);
k ^= k >> 33;
k *= BIG_CONSTANT (0xc4ceb9fe1a85ec53);
k ^= k >> 33;
return k;
}
//-----------------------------------------------------------------------------
void MurmurHash3_x86_32 ( const void* key, int len,
std::uint32_t seed, void* out )
{
const uint8_t* data = (const uint8_t*)key;
const int nblocks = len / 4;
std::uint32_t h1 = seed;
std::uint32_t c1 = 0xcc9e2d51;
std::uint32_t c2 = 0x1b873593;
//----------
// body
const std::uint32_t* blocks = (const std::uint32_t*) (data + nblocks * 4);
for (int i = -nblocks; i; i++)
{
std::uint32_t k1 = getblock (blocks, i);
k1 *= c1;
k1 = ROTL32 (k1, 15);
k1 *= c2;
h1 ^= k1;
h1 = ROTL32 (h1, 13);
h1 = h1 * 5 + 0xe6546b64;
}
//----------
// tail
const uint8_t* tail = (const uint8_t*) (data + nblocks * 4);
std::uint32_t k1 = 0;
switch (len & 3)
{
case 3:
k1 ^= tail[2] << 16;
case 2:
k1 ^= tail[1] << 8;
case 1:
k1 ^= tail[0];
k1 *= c1;
k1 = ROTL32 (k1, 15);
k1 *= c2;
h1 ^= k1;
};
//----------
// finalization
h1 ^= len;
h1 = fmix (h1);
* (std::uint32_t*)out = h1;
}
//-----------------------------------------------------------------------------
void MurmurHash3_x86_128 ( const void* key, const int len,
std::uint32_t seed, void* out )
{
const uint8_t* data = (const uint8_t*)key;
const int nblocks = len / 16;
std::uint32_t h1 = seed;
std::uint32_t h2 = seed;
std::uint32_t h3 = seed;
std::uint32_t h4 = seed;
std::uint32_t c1 = 0x239b961b;
std::uint32_t c2 = 0xab0e9789;
std::uint32_t c3 = 0x38b34ae5;
std::uint32_t c4 = 0xa1e38b93;
//----------
// body
const std::uint32_t* blocks = (const std::uint32_t*) (data + nblocks * 16);
for (int i = -nblocks; i; i++)
{
std::uint32_t k1 = getblock (blocks, i * 4 + 0);
std::uint32_t k2 = getblock (blocks, i * 4 + 1);
std::uint32_t k3 = getblock (blocks, i * 4 + 2);
std::uint32_t k4 = getblock (blocks, i * 4 + 3);
k1 *= c1;
k1 = ROTL32 (k1, 15);
k1 *= c2;
h1 ^= k1;
h1 = ROTL32 (h1, 19);
h1 += h2;
h1 = h1 * 5 + 0x561ccd1b;
k2 *= c2;
k2 = ROTL32 (k2, 16);
k2 *= c3;
h2 ^= k2;
h2 = ROTL32 (h2, 17);
h2 += h3;
h2 = h2 * 5 + 0x0bcaa747;
k3 *= c3;
k3 = ROTL32 (k3, 17);
k3 *= c4;
h3 ^= k3;
h3 = ROTL32 (h3, 15);
h3 += h4;
h3 = h3 * 5 + 0x96cd1c35;
k4 *= c4;
k4 = ROTL32 (k4, 18);
k4 *= c1;
h4 ^= k4;
h4 = ROTL32 (h4, 13);
h4 += h1;
h4 = h4 * 5 + 0x32ac3b17;
}
//----------
// tail
const uint8_t* tail = (const uint8_t*) (data + nblocks * 16);
std::uint32_t k1 = 0;
std::uint32_t k2 = 0;
std::uint32_t k3 = 0;
std::uint32_t k4 = 0;
switch (len & 15)
{
case 15:
k4 ^= tail[14] << 16;
case 14:
k4 ^= tail[13] << 8;
case 13:
k4 ^= tail[12] << 0;
k4 *= c4;
k4 = ROTL32 (k4, 18);
k4 *= c1;
h4 ^= k4;
case 12:
k3 ^= tail[11] << 24;
case 11:
k3 ^= tail[10] << 16;
case 10:
k3 ^= tail[ 9] << 8;
case 9:
k3 ^= tail[ 8] << 0;
k3 *= c3;
k3 = ROTL32 (k3, 17);
k3 *= c4;
h3 ^= k3;
case 8:
k2 ^= tail[ 7] << 24;
case 7:
k2 ^= tail[ 6] << 16;
case 6:
k2 ^= tail[ 5] << 8;
case 5:
k2 ^= tail[ 4] << 0;
k2 *= c2;
k2 = ROTL32 (k2, 16);
k2 *= c3;
h2 ^= k2;
case 4:
k1 ^= tail[ 3] << 24;
case 3:
k1 ^= tail[ 2] << 16;
case 2:
k1 ^= tail[ 1] << 8;
case 1:
k1 ^= tail[ 0] << 0;
k1 *= c1;
k1 = ROTL32 (k1, 15);
k1 *= c2;
h1 ^= k1;
};
//----------
// finalization
h1 ^= len;
h2 ^= len;
h3 ^= len;
h4 ^= len;
h1 += h2;
h1 += h3;
h1 += h4;
h2 += h1;
h3 += h1;
h4 += h1;
h1 = fmix (h1);
h2 = fmix (h2);
h3 = fmix (h3);
h4 = fmix (h4);
h1 += h2;
h1 += h3;
h1 += h4;
h2 += h1;
h3 += h1;
h4 += h1;
((std::uint32_t*)out)[0] = h1;
((std::uint32_t*)out)[1] = h2;
((std::uint32_t*)out)[2] = h3;
((std::uint32_t*)out)[3] = h4;
}
//-----------------------------------------------------------------------------
void MurmurHash3_x64_128 ( const void* key, const int len,
const std::uint32_t seed, void* out )
{
const uint8_t* data = (const uint8_t*)key;
const int nblocks = len / 16;
std::uint64_t h1 = seed;
std::uint64_t h2 = seed;
std::uint64_t c1 = BIG_CONSTANT (0x87c37b91114253d5);
std::uint64_t c2 = BIG_CONSTANT (0x4cf5ad432745937f);
//----------
// body
const std::uint64_t* blocks = (const std::uint64_t*) (data);
for (int i = 0; i < nblocks; i++)
{
std::uint64_t k1 = getblock (blocks, i * 2 + 0);
std::uint64_t k2 = getblock (blocks, i * 2 + 1);
k1 *= c1;
k1 = ROTL64 (k1, 31);
k1 *= c2;
h1 ^= k1;
h1 = ROTL64 (h1, 27);
h1 += h2;
h1 = h1 * 5 + 0x52dce729;
k2 *= c2;
k2 = ROTL64 (k2, 33);
k2 *= c1;
h2 ^= k2;
h2 = ROTL64 (h2, 31);
h2 += h1;
h2 = h2 * 5 + 0x38495ab5;
}
//----------
// tail
const uint8_t* tail = (const uint8_t*) (data + nblocks * 16);
std::uint64_t k1 = 0;
std::uint64_t k2 = 0;
switch (len & 15)
{
case 15:
k2 ^= std::uint64_t (tail[14]) << 48;
case 14:
k2 ^= std::uint64_t (tail[13]) << 40;
case 13:
k2 ^= std::uint64_t (tail[12]) << 32;
case 12:
k2 ^= std::uint64_t (tail[11]) << 24;
case 11:
k2 ^= std::uint64_t (tail[10]) << 16;
case 10:
k2 ^= std::uint64_t (tail[ 9]) << 8;
case 9:
k2 ^= std::uint64_t (tail[ 8]) << 0;
k2 *= c2;
k2 = ROTL64 (k2, 33);
k2 *= c1;
h2 ^= k2;
case 8:
k1 ^= std::uint64_t (tail[ 7]) << 56;
case 7:
k1 ^= std::uint64_t (tail[ 6]) << 48;
case 6:
k1 ^= std::uint64_t (tail[ 5]) << 40;
case 5:
k1 ^= std::uint64_t (tail[ 4]) << 32;
case 4:
k1 ^= std::uint64_t (tail[ 3]) << 24;
case 3:
k1 ^= std::uint64_t (tail[ 2]) << 16;
case 2:
k1 ^= std::uint64_t (tail[ 1]) << 8;
case 1:
k1 ^= std::uint64_t (tail[ 0]) << 0;
k1 *= c1;
k1 = ROTL64 (k1, 31);
k1 *= c2;
h1 ^= k1;
};
//----------
// finalization
h1 ^= len;
h2 ^= len;
h1 += h2;
h2 += h1;
h1 = fmix (h1);
h2 = fmix (h2);
h1 += h2;
h2 += h1;
((std::uint64_t*)out)[0] = h1;
((std::uint64_t*)out)[1] = h2;
}
}
}

View File

@@ -1,346 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions are Copyright (c) 2013 the authors listed at the following URL,
and/or the authors of referenced articles or incorporated external code:
http://en.literateprograms.org/Arbitrary-precision_integer_arithmetic_(C)
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 <beast/crypto/UnsignedInteger.h>
#include <beast/unit_test/suite.h>
namespace beast {
namespace multiprecsion {
#if 0
/* Copyright (c) 2013 the authors listed at the following URL, and/or
the authors of referenced articles or incorporated external code:
http://en.literateprograms.org/Arbitrary-precision_integer_arithmetic_(C)
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.
*/
//
// Retrieved from: http://en.literateprograms.org/Arbitrary-precision_integer_arithmetic_(C)?oldid=16902
//
typedef unsigned short component_t;
typedef unsigned long double_component_t;
#define MAX_COMPONENT ((component_t)(-1))
#define COMPONENT_BITS (sizeof(component_t)*CHAR_BIT)
#define LOG_2_10 3.3219280948873623478703194294894
#define MIN(x,y) ((x)<(y) ? (x) : (y))
#define MAX(x,y) ((x)>(y) ? (x) : (y))
typedef struct {
component_t* c; /* least-significant word first */
int num_components;
} integer;
integer create_integer(int components);
void free_integer(integer i);
void set_zero_integer(integer i);
void copy_integer(integer source, integer target);
void add_integer(integer left, integer right, integer result);
void subtract_integer(integer left, integer right, integer result);
void multiply_small_integer(integer left, component_t right, integer result);
void multiply_integer(integer left, integer right, integer result);
int compare_integers(integer left, integer right);
void shift_left_one_integer(integer arg);
void shift_right_one_integer(integer arg);
component_t mod_small_integer(integer left, component_t right);
void mod_integer(integer left, integer right, integer result);
void divide_small_integer(integer left, component_t right, integer result);
integer string_to_integer(char* s);
char* integer_to_string(integer x);
int is_zero_integer(integer x);
//------------------------------------------------------------------------------
integer create_integer(int components) {
integer result;
result.num_components = components;
result.c = (component_t*)malloc(sizeof(component_t)*components);
return result;
}
void free_integer(integer i) {
free(i.c);
}
void set_zero_integer(integer i) {
memset(i.c, 0, sizeof(component_t)*i.num_components);
}
int is_zero_integer(integer x) {
int i;
for(i=0; i < x.num_components; i++) {
if (x.c[i] != 0) return 0;
}
return 1;
}
void copy_integer(integer source, integer target) {
memmove(target.c, source.c,
sizeof(component_t)*MIN(source.num_components, target.num_components));
if (target.num_components > source.num_components) {
memset(target.c + source.num_components, 0,
sizeof(component_t)*(target.num_components - source.num_components));
}
}
void add_integer(integer left, integer right, integer result) {
double_component_t carry = 0;
int i;
for(i=0; i<left.num_components || i<right.num_components || carry != 0; i++) {
double_component_t partial_sum = carry;
carry = 0;
if (i < left.num_components) partial_sum += left.c[i];
if (i < right.num_components) partial_sum += right.c[i];
if (partial_sum > MAX_COMPONENT) {
partial_sum &= MAX_COMPONENT;
carry = 1;
}
result.c[i] = (component_t)partial_sum;
}
for ( ; i < result.num_components; i++) { result.c[i] = 0; }
}
void subtract_integer(integer left, integer right, integer result) {
int borrow = 0;
int i;
for(i=0; i<left.num_components; i++) {
double_component_t lhs = left.c[i];
double_component_t rhs = (i < right.num_components) ? right.c[i] : 0;
if (borrow) {
if (lhs <= rhs) {
/* leave borrow set to 1 */
lhs += (MAX_COMPONENT + 1) - 1;
} else {
borrow = 0;
lhs--;
}
}
if (lhs < rhs) {
borrow = 1;
lhs += MAX_COMPONENT + 1;
}
result.c[i] = lhs - rhs;
}
for ( ; i < result.num_components; i++) { result.c[i] = 0; }
}
void multiply_small_integer(integer left, component_t right, integer result) {
double_component_t carry = 0;
int i;
for(i=0; i<left.num_components || carry != 0; i++) {
double_component_t partial_sum = carry;
carry = 0;
if (i < left.num_components) partial_sum += left.c[i]*right;
carry = partial_sum >> COMPONENT_BITS;
result.c[i] = (component_t)(partial_sum & MAX_COMPONENT);
}
for ( ; i < result.num_components; i++) { result.c[i] = 0; }
}
void multiply_integer(integer left, integer right, integer result) {
int i, lidx, ridx;
double_component_t carry = 0;
int max_size_no_carry;
int left_max_component = left.num_components - 1;
int right_max_component = right.num_components - 1;
while(left.c[left_max_component] == 0) left_max_component--;
while(right.c[right_max_component] == 0) right_max_component--;
max_size_no_carry = left_max_component + right_max_component;
for(i=0; i <= max_size_no_carry || carry != 0; i++) {
double_component_t partial_sum = carry;
carry = 0;
lidx = MIN(i, left_max_component);
ridx = i - lidx;
while(lidx >= 0 && ridx <= right_max_component) {
partial_sum += ((double_component_t)left.c[lidx])*right.c[ridx];
carry += partial_sum >> COMPONENT_BITS;
partial_sum &= MAX_COMPONENT;
lidx--; ridx++;
}
result.c[i] = partial_sum;
}
for ( ; i < result.num_components; i++) { result.c[i] = 0; }
}
int compare_integers(integer left, integer right) {
int i = MAX(left.num_components - 1, right.num_components - 1);
for ( ; i >= 0; i--) {
component_t left_comp =
(i < left.num_components) ? left.c[i] : 0;
component_t right_comp =
(i < right.num_components) ? right.c[i] : 0;
if (left_comp < right_comp)
return -1;
else if (left_comp > right_comp)
return 1;
}
return 0;
}
void shift_left_one_integer(integer arg) {
int i;
arg.c[arg.num_components - 1] <<= 1;
for (i = arg.num_components - 2; i >= 0; i--) {
arg.c[i + 1] |= arg.c[i] >> (COMPONENT_BITS - 1);
arg.c[i] <<= 1;
}
}
void shift_right_one_integer(integer arg) {
int i;
arg.c[0] >>= 1;
for (i = 1; i < arg.num_components; i++) {
arg.c[i - 1] |= (arg.c[i] & 1) << (COMPONENT_BITS - 1);
arg.c[i] >>= 1;
}
}
component_t mod_small_integer(integer left, component_t right) {
double_component_t mod_two_power = 1;
double_component_t result = 0;
int i, bit;
for(i=0; i<left.num_components; i++) {
for(bit=0; bit<COMPONENT_BITS; bit++) {
if ((left.c[i] & (1 << bit)) != 0) {
result += mod_two_power;
if (result >= right) {
result -= right;
}
}
mod_two_power <<= 1;
if (mod_two_power >= right) {
mod_two_power -= right;
}
}
}
return (component_t)result;
}
void mod_integer(integer left, integer right, integer result) {
integer mod_two_power = create_integer(right.num_components + 1);
int i, bit;
set_zero_integer(result);
set_zero_integer(mod_two_power);
mod_two_power.c[0] = 1;
for(i=0; i<left.num_components; i++) {
for(bit=0; bit<COMPONENT_BITS; bit++) {
if ((left.c[i] & (1 << bit)) != 0) {
add_integer(result, mod_two_power, result);
if (compare_integers(result, right) >= 0) {
subtract_integer(result, right, result);
}
}
shift_left_one_integer(mod_two_power);
if (compare_integers(mod_two_power, right) >= 0) {
subtract_integer(mod_two_power, right, mod_two_power);
}
}
}
free_integer(mod_two_power);
}
void divide_small_integer(integer left, component_t right, integer result) {
double_component_t dividend = 0;
int i;
for (i = left.num_components - 1; i >= 0; i--) {
dividend |= left.c[i];
result.c[i] = dividend/right;
dividend = (dividend % right) << COMPONENT_BITS;
}
}
integer string_to_integer(char* s) {
integer result = create_integer((int)ceil(LOG_2_10*strlen(s)/COMPONENT_BITS));
set_zero_integer(result);
integer digit = create_integer(1);
int i;
for (i = 0; s[i] != '\0'; i++) {
multiply_small_integer(result, 10, result);
digit.c[0] = s[i] - '0';
add_integer(result, digit, result);
}
free_integer(digit);
return result;
}
char* integer_to_string(integer x) {
int i, result_len;
char* result =
(char*)malloc((int)ceil(COMPONENT_BITS*x.num_components/LOG_2_10) + 2);
integer ten = create_integer(1);
ten.c[0] = 10;
if (is_zero_integer(x)) {
strcpy(result, "0");
} else {
for (i = 0; !is_zero_integer(x); i++) {
result[i] = (char)mod_small_integer(x, 10) + '0';
divide_small_integer(x, 10, x);
}
result[i] = '\0';
}
result_len = strlen(result);
for(i=0; i < result_len/2; i++) {
char temp = result[i];
result[i] = result[result_len - i - 1];
result[result_len - i - 1] = temp;
}
free_integer(ten);
return result;
}
#endif
}
}

View File

@@ -1,417 +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.
*/
//==============================================================================
// MODULES: ../../../modules/beast_core/beast_core.beast_core.unity.cpp ../../strings/Strings.cpp ../../chrono/Chrono.cpp ../../threads/Threads.cpp
#include <beast/crypto/BinaryEncoding.h>
#include <beast/crypto/UnsignedInteger.h>
#include <beast/unit_test/suite.h>
#include <beast/module/core/maths/Random.h>
#include <cstddef>
#include <string>
namespace beast {
/** Generic algorithms for base encoding and decoding. */
class BinaryEncoding
{
public:
/** Concept: Conversion
X denotes a Conversion class, a is a value of type X,
i is an integral type.
Requirements:
Expression Type Notes/Contracts
------------- ----------- ------------------
X a;
X::radix size_type constexpr
a.map (i) char maps base numeral to a char
*/
/** Encode the unsigned integer into a string using the specified conversion. */
template <typename Conversion, std::size_t Bytes>
static std::string encode (UnsignedInteger <Bytes> v, Conversion c = Conversion ())
{
// bi is destroyed in this process
typename UnsignedInteger <Bytes>::CalcType bi (v.toCalcType ());
std::size_t const radix (Conversion::radix);
std::string s;
s.reserve (bi.size() * 3); // guess
while (bi.isNotZero ())
{
std::size_t const m (bi % radix);
bi /= radix;
s.push_back (c.map (m));
}
std::reverse (s.begin(), s.end());
return s;
}
/** Decode the string into an unsigned integer.
The size must match exactly
@return `true` on success.
*/
template <typename Conversion, std::size_t Bytes>
static bool decode (UnsignedInteger <Bytes>& rv,
std::string const& s, Conversion c = Conversion ())
{
typename UnsignedInteger <Bytes>::CalcType bi (rv.toCalcType (false));
std::size_t const radix (Conversion::radix);
bi.clear ();
for (std::string::const_iterator iter (s.begin()); iter != s.end(); ++iter)
{
int const v (c.invert (*iter));
if (v == -1)
return false;
bi *= radix;
bi += v;
}
bi.toCanonical();
return true;
}
};
//------------------------------------------------------------------------------
// Some common code
template <class Conversion>
class BaseConversion
{
public:
char map (std::size_t i) const
{
return Conversion::alphabet () [i];
}
int invert (char c) const
{
return Conversion::inverse_alphabet () [c];
}
static std::vector <int> const& inverse_alphabet ()
{
static std::vector <int> t (invert (Conversion::alphabet(), Conversion::radix));
return t;
}
/** Build the inverse mapping table from characters to digits. */
static std::vector <int>
invert (std::string const& alphabet, int radix)
{
std::vector <int> table (256, -1);
for (int i (0); i < radix; ++i)
table [alphabet [i]] = i;
return table;
}
};
//------------------------------------------------------------------------------
/** Foolproof hexadecimal encoding and decoding facility.
This is to check the correctness of the more complex converters.
*/
class HexEncoding
{
public:
template <std::size_t Bytes>
static std::string encode (UnsignedInteger <Bytes> const& v)
{
std::string s;
std::uint8_t const* src (v.cbegin()-1);
char const* const tab (alphabet().c_str());
s.reserve (Bytes * 2);
for (std::size_t bytes (v.size);bytes--;)
{
std::uint8_t const v (*++src);
s.push_back (tab [v>>4]);
s.push_back (tab [v&0x0f]);
}
return s;
}
template <std::size_t Bytes>
static bool decode (UnsignedInteger <Bytes>& rv,
std::string const& s)
{
// can't have an odd size
if (s.size() & 1)
return false;
std::uint8_t* dest (rv.begin()-1);
int const* const tab (&inverse_alphabet().front());
for (std::string::const_iterator iter (s.begin()); iter != s.end();)
{
int const n1 (tab [*iter++]);
if (n1 == -1)
return false;
int const n2 (tab [*iter++]);
if (n2 == -1)
return false;
*++dest = ((std::uint8_t)((n1<<4)|n2));
}
return true;
}
static std::string const& alphabet ()
{
static std::string s ("0123456789ABCDEF");
return s;
}
static std::vector <int> const& inverse_alphabet ()
{
static std::vector <int> s (invert (alphabet(), 16));
return s;
}
/** Build the inverse mapping table from characters to digits. */
static std::vector <int>
invert (std::string const& alphabet, int radix)
{
std::vector <int> table (256, -1);
for (int i (0); i < radix; ++i)
table [alphabet [i]] = int(i);
return table;
}
};
//------------------------------------------------------------------------------
/** Base58 conversion used by Bitcoin. */
class BitcoinBase58Conversion : public BaseConversion <BitcoinBase58Conversion>
{
public:
static std::size_t const radix = 58;
char const* name () const
{
return "BitcoinBase58";
}
static std::string const& alphabet ()
{
static std::string s (
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
);
return s;
}
};
//------------------------------------------------------------------------------
/** Base58 conversion used by Ripple. */
class RippleBase58Conversion : public BaseConversion <RippleBase58Conversion>
{
public:
static std::size_t const radix = 58;
char const* name () const
{
return "RippleBase58";
}
static std::string const& alphabet ()
{
static std::string s (
"rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz"
);
return s;
}
};
//------------------------------------------------------------------------------
class Base64Conversion : public BaseConversion <Base64Conversion>
{
public:
static std::size_t const radix = 64;
char const* name () const
{
return "Base64";
}
static std::string const& alphabet ()
{
static std::string s (
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
);
return s;
}
};
//------------------------------------------------------------------------------
class Base16Conversion : public BaseConversion <Base16Conversion>
{
public:
static std::size_t const radix = 16;
char const* name () const
{
return "Hex";
}
static std::string const& alphabet ()
{
static std::string s (
"0123456789ABCDEF"
);
return s;
}
};
//------------------------------------------------------------------------------
class BinaryEncoding_test : public unit_test::suite
{
public:
// This is a baseline for the other tests
template <std::size_t Bytes>
void testBase16 ()
{
Random r;
testcase ("base16");
for (int i = 0; i < 50; ++i)
{
typedef UnsignedInteger <Bytes> UInt;
UInt v0;
r.fillBitsRandomly (v0.begin(), UInt::size);
std::string const good (HexEncoding::encode (v0));
UInt v1;
bool const success (HexEncoding::decode (v1, good));
if (expect (success))
{
expect (v0 == v1);
Base16Conversion c;
std::string const check (BinaryEncoding::encode (v0, c));
expect (good == check,
std::string ("expected ") + good + " but got " + check);
}
}
}
template <std::size_t Bytes>
void testBase64Bytes (
std::string const& vin, std::string const& vout,
Base64Conversion c = Base64Conversion ())
{
typedef UnsignedInteger <Bytes> UInt;
UInt v1 (vin.c_str());
std::string const s1 (BinaryEncoding::encode (v1, c));
log <<
vout + " to " + s1;
expect (vout == s1);
UInt v2;
bool const success (BinaryEncoding::decode (v2, vout, c));
if (expect (success))
{
std::string const s2 (BinaryEncoding::encode (v2, c));
log <<
vin + " to " + s2;
}
}
void testBase64 ()
{
testcase ("Base64");
// input (uint)
std::string const vin [] = {
"","f","fo","foo","foob","fooba","foobar"
};
// output (encoded string)
std::string const vout [] = {
"","Zg==","Zm8=","Zm9v","Zm9vYg==","Zm9vYmE=","Zm9vYmFy"
};
//testBase64Bytes <0> (vin [0], vout [0]);
testBase64Bytes <1> (vin [1], vout [1]);
testBase64Bytes <2> (vin [2], vout [2]);
testBase64Bytes <3> (vin [3], vout [3]);
testBase64Bytes <4> (vin [4], vout [4]);
testBase64Bytes <5> (vin [5], vout [5]);
testBase64Bytes <6> (vin [6], vout [6]);
}
template <typename Conversion, std::size_t Bytes>
void testEncode (Conversion c = Conversion())
{
typedef UnsignedInteger <Bytes> UInt;
#if 0
std::stringstream ss;
ss <<
c.name() << " <" << Bytes << ">";
testcase (ss.str());
#else
testcase << c.name() << " <" << Bytes << ">";
#endif
Random r;
for (int i = 0; i < 50; ++i)
{
UInt v1;
r.fillBitsRandomly (v1.begin(), UInt::size);
std::string const s1 (BinaryEncoding::encode (v1, c));
UInt v2;
bool success (BinaryEncoding::decode (v2, s1, c));
if (expect (success))
expect (v1 == v2);
}
}
void run ()
{
testBase16 <10> ();
#if 0
testEncode <Base16Conversion, 1> ();
testEncode <Base16Conversion, 2> ();
testEncode <Base16Conversion, 3> ();
testEncode <Base16Conversion, 4> ();
testEncode <Base16Conversion, 5> ();
testEncode <Base16Conversion, 6> ();
testEncode <Base16Conversion, 7> ();
testEncode <Base16Conversion, 8> ();
testEncode <Base16Conversion, 9> ();
testEncode <Base16Conversion, 10> ();
testBase64 ();
testEncode <Base64Conversion, 20> ();
testEncode <Base64Conversion, 33> ();
testEncode <RippleBase58Conversion, 20> ();
testEncode <RippleBase58Conversion, 33> ();
testEncode <BitcoinBase58Conversion, 20> ();
testEncode <BitcoinBase58Conversion, 33> ();
#endif
}
};
BEAST_DEFINE_TESTSUITE_MANUAL(BinaryEncoding,crypto,beast);
}

View File

@@ -1,81 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions are Copyright (c) 2013 the authors listed at the following URL,
and/or the authors of referenced articles or incorporated external code:
http://en.literateprograms.org/Arbitrary-precision_integer_arithmetic_(C)
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 <beast/crypto/UnsignedInteger.h>
#include <beast/unit_test/suite.h>
namespace beast {
class UnsignedInteger_test : public unit_test::suite
{
public:
template <unsigned int Bytes>
void test ()
{
typedef UnsignedInteger <Bytes> UInt;
std::stringstream ss;
ss <<
"bytes=" << Bytes;
testcase (ss.str());
UInt zero;
zero.fill (0);
expect (zero.isZero (), "should be zero");
expect (! zero.isNotZero (), "sould not be non-zero");
UInt one (UInt::createFromInteger (1U));
expect (one == UInt::createFromInteger (1U), "should be equal");
expect (! one.isZero (), "should not be zero");
expect (one.isNotZero (), "sould be non-zero");
expect (zero < one, "should be less");
expect (one > zero, "should be greater");
expect (zero >= zero, "should be less than or equal");
expect (one <= one, "should be less than or equal");
expect (zero == zero, "should be equal");
expect (zero != one, "should not be equal");
expect (zero == UInt::createFromInteger (0U), "should be zero");
expect (one == UInt::createFromInteger (1U), "should be one");
expect (one != UInt::createFromInteger (2U), "should not be two");
UInt largest = UInt::createFilled (0xff);
expect (largest > zero && largest > one, "should be greater");
}
void run()
{
test <16> ();
test <33> ();
}
private:
};
BEAST_DEFINE_TESTSUITE(UnsignedInteger,crypto,beast);
}

View File

@@ -17,35 +17,35 @@
*/
//==============================================================================
#include <beast/http/ParsedURL.h>
#include <beast/crypto/base64.h>
#include <beast/unit_test/suite.h>
#include <beast/http/impl/joyent_parser.h>
namespace beast {
class ParsedURL_test : public unit_test::suite
class base64_test : public unit_test::suite
{
public:
void checkURL (String const& url)
void
check (std::string const& in, std::string const& out)
{
ParsedURL result (url);
expect (result.error () == 0);
expect (result.url ().toString () == url);
auto const encoded = base64_encode (in);
expect (encoded == out);
expect (base64_decode (encoded) == in);
}
void testURL ()
void
run()
{
checkURL ("http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference.html");
}
void run ()
{
testURL ();
check ("", "");
check ("f", "Zg==");
check ("fo", "Zm8=");
check ("foo", "Zm9v");
check ("foob", "Zm9vYg==");
check ("fooba", "Zm9vYmE=");
check ("foobar", "Zm9vYmFy");
}
};
BEAST_DEFINE_TESTSUITE(ParsedURL,http,beast);
BEAST_DEFINE_TESTSUITE(base64,crypto,beast);
}

View File

@@ -1,7 +1,8 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
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
@@ -17,54 +18,54 @@
*/
//==============================================================================
#ifndef BEAST_ASIO_BASICS_SSLCONTEXT_H_INCLUDED
#define BEAST_ASIO_BASICS_SSLCONTEXT_H_INCLUDED
#ifndef BEAST_HASH_FNV1A_H_INCLUDED
#define BEAST_HASH_FNV1A_H_INCLUDED
#include <beast/Uncopyable.h>
#include <boost/asio/ssl/context.hpp>
#include <beast/utility/noexcept.h>
#include <cstddef>
#include <cstdint>
#include <beast/cxx14/type_traits.h> // <type_traits>
namespace beast {
namespace asio {
/** Simple base class for passing a context around.
This lets derived classes hide their implementation from the headers.
*/
class SSLContext : public Uncopyable
// See http://www.isthe.com/chongo/tech/comp/fnv/
//
class fnv1a
{
private:
std::uint64_t state_ = 14695981039346656037ULL;
public:
virtual ~SSLContext ();
using result_type = std::size_t;
// Saves typing
typedef boost::asio::ssl::context ContextType;
fnv1a() = default;
inline ContextType& get () noexcept
template <class Seed,
std::enable_if_t<
std::is_unsigned<Seed>::value>* = nullptr>
explicit
fnv1a (Seed seed)
{
return m_context;
append (&seed, sizeof(seed));
}
inline ContextType const& get () const noexcept
void
append (void const* key, std::size_t len) noexcept
{
return m_context;
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;
}
// implicit conversion
inline operator ContextType& () noexcept
explicit
operator std::size_t() noexcept
{
return get ();
return static_cast<std::size_t>(state_);
}
inline operator ContextType const& () const noexcept
{
return get ();
}
protected:
explicit SSLContext (ContextType& context);
ContextType& m_context;
};
}
}
} // beast
#endif

View File

@@ -18,18 +18,14 @@
*/
//==============================================================================
#ifndef BEAST_CONTAINER_HASH_APPEND_H_INCLUDED
#define BEAST_CONTAINER_HASH_APPEND_H_INCLUDED
#ifndef BEAST_HASH_HASH_APPEND_H_INCLUDED
#define BEAST_HASH_HASH_APPEND_H_INCLUDED
#include <beast/utility/meta.h>
#include <beast/container/impl/spookyv2.h>
#include <beast/utility/noexcept.h>
#if BEAST_USE_BOOST_FEATURES
#include <boost/shared_ptr.hpp>
#endif
#include <beast/utility/noexcept.h>
#include <array>
#include <cstdint>
#include <functional>
@@ -656,96 +652,6 @@ hash_append (Hasher& h, T0 const& t0, T1 const& t1, T const& ...t) noexcept
hash_append (h, t1, t...);
}
// See http://www.isthe.com/chongo/tech/comp/fnv/
class fnv1a
{
std::uint64_t state_ = 14695981039346656037ULL;
public:
using result_type = std::size_t;
void
append (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_);
}
};
// See http://burtleburtle.net/bob/hash/spooky.html
class spooky
{
SpookyHash state_;
public:
using result_type = std::size_t;
spooky (std::size_t seed1 = 1, std::size_t seed2 = 2) noexcept
{
state_.Init (seed1, seed2);
}
void
append (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);
}
};
// See https://131002.net/siphash/
class siphash
{
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;
siphash() = default;
explicit siphash(std::uint64_t k0, std::uint64_t k1 = 0) noexcept;
void
append (void const* key, std::size_t len) noexcept;
explicit
operator std::size_t() noexcept;
};
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

View 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/random/rngfill.h>
#include <beast/random/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

View File

@@ -24,18 +24,15 @@
//
//------------------------------------------------------------------------------
#include <beast/container/hash_append.h>
#include <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
{
namespace beast {
namespace detail {
typedef std::uint64_t u64;
typedef std::uint32_t u32;
@@ -82,7 +79,7 @@ sipround(u64& v0, u64& v1, u64& v2, u64& v3)
v2 = rotl(v2, 32);
}
} // unnamed
} // detail
siphash::siphash(std::uint64_t k0, std::uint64_t k1) noexcept
{
@@ -95,6 +92,7 @@ siphash::siphash(std::uint64_t k0, std::uint64_t k1) noexcept
void
siphash::append (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)
@@ -130,6 +128,7 @@ siphash::append (void const* key, std::size_t inlen) noexcept
siphash::operator std::size_t() noexcept
{
using namespace detail;
std::size_t b = static_cast<u64>(total_length_) << 56;
switch(bufsize_)
{
@@ -163,4 +162,4 @@ siphash::operator std::size_t() noexcept
return b;
}
} // beast
} // beast

Some files were not shown because too many files have changed in this diff Show More