diff --git a/Builds/VisualStudio2012/RippleD.vcxproj b/Builds/VisualStudio2012/RippleD.vcxproj
index d427585702..ad75918cd6 100644
--- a/Builds/VisualStudio2012/RippleD.vcxproj
+++ b/Builds/VisualStudio2012/RippleD.vcxproj
@@ -780,7 +780,18 @@
true
true
-
+
+ Level4
+ Level4
+ Level4
+ Level4
+
+
+ true
+ true
+ true
+ true
+
true
diff --git a/Builds/VisualStudio2012/RippleD.vcxproj.filters b/Builds/VisualStudio2012/RippleD.vcxproj.filters
index e1c53a83e3..f860072d13 100644
--- a/Builds/VisualStudio2012/RippleD.vcxproj.filters
+++ b/Builds/VisualStudio2012/RippleD.vcxproj.filters
@@ -160,6 +160,9 @@
{c69b07a2-44e5-4b06-99a9-81f5d137ea15}
+
+ {271e2469-a2e6-40c6-acc9-aa75cd6e59c3}
+
@@ -885,6 +888,9 @@
[1] Ripple\ripple_app\main
+
+ [1] Ripple\ripple_basio\tests
+
diff --git a/Notes/VFALCO_TODO.txt b/Notes/VFALCO_TODO.txt
index bca448c1ad..8178f2f09f 100644
--- a/Notes/VFALCO_TODO.txt
+++ b/Notes/VFALCO_TODO.txt
@@ -7,18 +7,13 @@ REMINDER: KEEP CHANGE LOG UP TO DATE
Vinnie's List: Changes day to day, descending priority
(Items marked '*' can be handled by others.)
-- Emergency implement PROXY protcol
-- Get rid of boost::filesystem
+- Unit tests for boost::asio wrappers
+- Socket implementation for PROXY protocol
+- Socket that supports multiple protcols
+- Review boost::asio wrappers and consolidation of network code in ripple_net
- Deeply create directories specified in config settings
- Finish unit tests and code for Validators
* Document the command line options for the beast unit test framework
-- Review boost::asio wrappers and consolidation of network code in ripple_net
-- Refactor Section code into ConfigFile
-- Improved Mutex to track deadlocks
-- Work on KeyvaDB
-- Allow skipped/disabled unit tests and reporting.
-- Supress useless gcc warnings
- http://stackoverflow.com/questions/3378560/how-to-disable-gcc-warnings-for-a-few-lines-of-code
David Features:
- override config items from command line
@@ -26,6 +21,21 @@ David Features:
--------------------------------------------------------------------------------
+- Refactor Section code into ConfigFile
+
+- Improved Mutex to track deadlocks
+
+- Work on KeyvaDB
+
+- Allow skipped/disabled unit tests and reporting.
+
+- Supress useless gcc warnings
+ http://stackoverflow.com/questions/3378560/how-to-disable-gcc-warnings-for-a-few-lines-of-code
+
+- Get rid of boost::filesystem
+
+- Make some fatal_assert macro that calls FatalError
+
- What the heck is up with site_scons/site_tools/protoc.py?
- Figure out the right behavior of ProtectedCall
diff --git a/modules/ripple_basio/ripple_basio.cpp b/modules/ripple_basio/ripple_basio.cpp
index 9658501654..368630d3d1 100644
--- a/modules/ripple_basio/ripple_basio.cpp
+++ b/modules/ripple_basio/ripple_basio.cpp
@@ -14,6 +14,8 @@
#include "BeastConfig.h"
+#include "beast/modules/beast_basics/beast_basics.h"
+
#include "ripple_basio.h"
#include "ripple_basio_impl.h"
@@ -24,4 +26,16 @@ namespace ripple
#include "boost/ripple_IoService.cpp"
#include "boost/ripple_SslContext.cpp"
+#ifdef _MSC_VER
+#pragma warning (push)
+#pragma warning (disable: 4100)
+#pragma warning (disable: 4127) // conditional expression is constant
+#endif
+
+#include "tests/ripple_AsioTests.cpp"
+
+#ifdef _MSC_VER
+#pragma warning (pop)
+#endif
+
}
diff --git a/modules/ripple_basio/tests/ripple_AsioTests.cpp b/modules/ripple_basio/tests/ripple_AsioTests.cpp
new file mode 100644
index 0000000000..641dc7db45
--- /dev/null
+++ b/modules/ripple_basio/tests/ripple_AsioTests.cpp
@@ -0,0 +1,3252 @@
+//------------------------------------------------------------------------------
+/*
+ Copyright (c) 2011-2013, OpenCoin, Inc.
+*/
+//==============================================================================
+
+#ifndef BOOST_ASIO_INITFN_RESULT_TYPE
+#define BOOST_ASIO_INITFN_RESULT_TYPE(expr,val) void
+#endif
+
+/** Provides abstract interface for parts of boost::asio */
+namespace Asio
+{
+
+using namespace boost;
+
+//------------------------------------------------------------------------------
+
+/** 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.
+
+ Must satisfy these requirements:
+
+ DefaultConstructible, MoveConstructible, CopyConstructible,
+ MoveAssignable, CopyAssignable, Destructible
+
+ Meets the requirements of these boost concepts:
+
+ SyncReadStream, SyncWriteStream, AsyncReadStream, AsyncWriteStream,
+
+ @see SharedObjectPtr
+*/
+class AbstractSocket
+ : public asio::ssl::stream_base
+ , public asio::socket_base
+{
+protected:
+ //--------------------------------------------------------------------------
+ //
+ // Buffers
+ //
+ //--------------------------------------------------------------------------
+
+ /** Storage for a BufferSequence.
+
+ Meets these requirements:
+ BufferSequence
+ ConstBufferSequence (when Buffer is mutable_buffer)
+ MutableBufferSequence (when Buffer is const_buffer)
+ */
+ template
+ class Buffers
+ {
+ public:
+ typedef Buffer value_type;
+ typedef typename std::vector ::const_iterator const_iterator;
+
+ Buffers ()
+ : m_size (0)
+ {
+ }
+
+ template
+ explicit Buffers (OtherBuffers const& buffers)
+ : m_size (0)
+ {
+ m_buffers.reserve (std::distance (buffers.begin (), buffers.end ()));
+ BOOST_FOREACH (typename OtherBuffers::value_type buffer, buffers)
+ {
+ m_size += asio::buffer_size (buffer);
+ m_buffers.push_back (buffer);
+ }
+ }
+
+ /** Determine the total size of all buffers.
+ This is faster than calling asio::buffer_size.
+ */
+ std::size_t size () const noexcept
+ {
+ return m_size;
+ }
+
+ const_iterator begin () const noexcept
+ {
+ return m_buffers.begin ();
+ }
+
+ const_iterator end () const noexcept
+ {
+ return m_buffers.end ();
+ }
+
+ /** Retrieve a consumed BufferSequence. */
+ Buffers consumed (std::size_t bytes) const
+ {
+ Buffers result;
+ result.m_buffers.reserve (m_buffers.size ());
+ BOOST_FOREACH (Buffer buffer, m_buffers)
+ {
+ std::size_t const have = asio::buffer_size (buffer);
+ std::size_t const reduce = std::min (bytes, have);
+ bytes -= reduce;
+
+ if (have > reduce)
+ result.m_buffers.push_back (buffer + reduce);
+ }
+ return result;
+ }
+
+ private:
+ std::size_t m_size;
+ std::vector m_buffers;
+ };
+
+ /** Meets the requirements of ConstBufferSequence */
+ typedef Buffers ConstBuffers;
+
+ /** Meets the requirements of MutableBufferSequence */
+ typedef Buffers MutableBuffers;
+
+ //--------------------------------------------------------------------------
+ //
+ // Handler abstractions
+ //
+ //--------------------------------------------------------------------------
+
+ // Meets these requirements:
+ //
+ // CompletionHandler
+ // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/CompletionHandler.html
+ //
+ class CompletionCall
+ {
+ public:
+ typedef void result_type;
+
+ template
+ CompletionCall (BOOST_ASIO_MOVE_ARG (Handler) handler)
+ : m_call (new CallType (handler))
+ {
+ }
+
+ CompletionCall (CompletionCall const& other)
+ : m_call (other.m_call)
+ {
+ }
+
+ void operator() ()
+ {
+ (*m_call) ();
+ }
+
+ private:
+ struct Call : SharedObject, LeakChecked
+ {
+ virtual void operator() () = 0;
+ };
+
+ template
+ struct CallType : Call
+ {
+ CallType (BOOST_ASIO_MOVE_ARG (Handler) handler)
+ : m_handler (handler)
+ {
+ }
+
+ void operator() ()
+ {
+ m_handler ();
+ }
+
+ Handler m_handler;
+ };
+
+ private:
+ SharedObjectPtr m_call;
+ };
+
+ // Meets these requirements:
+ //
+ // AcceptHandler
+ // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/AcceptHandler.html
+ //
+ // ConnectHandler
+ // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ConnectHandler.html
+ //
+ // ShutdownHandler
+ // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ShutdownHandler.html
+ //
+ // HandshakeHandler
+ // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/HandshakeHandler.html
+ //
+ class ErrorCall
+ {
+ public:
+ typedef void result_type;
+
+ template
+ ErrorCall (BOOST_ASIO_MOVE_ARG (Handler) handler)
+ : m_call (new CallType (handler))
+ {
+ }
+
+ ErrorCall (ErrorCall const& other)
+ : m_call (other.m_call)
+ {
+ }
+
+ void operator() (system::error_code const& ec)
+ {
+ (*m_call) (ec);
+ }
+
+ private:
+ struct Call : SharedObject, LeakChecked
+ {
+ virtual void operator() (system::error_code const&) = 0;
+ };
+
+ template
+ struct CallType : Call
+ {
+ CallType (BOOST_ASIO_MOVE_ARG (Handler) handler)
+ : m_handler (handler)
+ {
+ }
+
+ void operator() (system::error_code const& ec)
+ {
+ m_handler (ec);
+ }
+
+ Handler m_handler;
+ };
+
+ private:
+ SharedObjectPtr m_call;
+ };
+
+ // Meets these requirements
+ //
+ // ReadHandler
+ // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ReadHandler.html
+ //
+ // WriteHandler
+ // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/WriteHandler.html
+ //
+ // BUfferedHandshakeHandler
+ // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/BufferedHandshakeHandler.html
+ //
+ class TransferCall
+ {
+ public:
+ typedef void result_type;
+
+ template
+ TransferCall (BOOST_ASIO_MOVE_ARG (Handler) handler)
+ : m_call (new CallType (handler))
+ {
+ }
+
+ TransferCall (TransferCall const& other)
+ : m_call (other.m_call)
+ {
+ }
+
+ void operator() (system::error_code const& ec, std::size_t bytes_transferred)
+ {
+ (*m_call) (ec, bytes_transferred);
+ }
+
+ private:
+ struct Call : SharedObject, LeakChecked
+ {
+ virtual void operator() (system::error_code const&, std::size_t) = 0;
+ };
+
+ template
+ struct CallType : Call
+ {
+ CallType (BOOST_ASIO_MOVE_ARG (Handler) handler)
+ : m_handler (handler)
+ {
+ }
+
+ void operator() (system::error_code const& ec, std::size_t bytes_transferred)
+ {
+ m_handler (ec, bytes_transferred);
+ }
+
+ Handler m_handler;
+ };
+
+ private:
+ SharedObjectPtr m_call;
+ };
+
+public:
+ typedef SharedObjectPtr Ptr;
+
+ virtual ~AbstractSocket () { }
+
+ //--------------------------------------------------------------------------
+ //
+ // General attributes
+ //
+ //--------------------------------------------------------------------------
+
+ /** Determines if the underlying stream requires a handshake.
+
+ If is_handshaked 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.
+ */
+ virtual bool is_handshaked () = 0;
+
+ /** Retrieve the underlying object.
+ Returns nullptr if the implementation doesn't match. Usually
+ you will use this if you need to get at the underlying boost::asio
+ object. For example:
+
+ @code
+
+ void set_options (AbstractSocket& socket)
+ {
+ bost::asio::ip::tcp::socket* sock =
+ socket.native_object ();
+
+ if (sock != nullptr)
+ sock->set_option (
+ boost::asio::ip::tcp::no_delay (true));
+ }
+
+ @endcode
+ */
+ template
+ Object* native_object ()
+ {
+ void* const object = native_object_raw ();
+ if (object != nullptr)
+ return dynamic_cast