mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-11 09:34:34 +00:00
Separated ana.hpp & detail.hpp into several single-purpose files...
...and updated error_code creation to comply with boost 1.35.
This commit is contained in:
parent
8a310769d7
commit
83f105b6b3
@ -51,13 +51,10 @@
|
|||||||
*
|
*
|
||||||
* @section requirements requirements
|
* @section requirements requirements
|
||||||
* To compile ana, you need:
|
* To compile ana, you need:
|
||||||
* - Boost, version 1.37 or older
|
* - Boost, version 1.35 or older
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ANA_HPP
|
|
||||||
#define ANA_HPP
|
|
||||||
|
|
||||||
#include <boost/cstdint.hpp>
|
#include <boost/cstdint.hpp>
|
||||||
#include <boost/noncopyable.hpp>
|
#include <boost/noncopyable.hpp>
|
||||||
#include <boost/system/error_code.hpp>
|
#include <boost/system/error_code.hpp>
|
||||||
@ -68,184 +65,22 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
#ifndef ANA_HPP
|
||||||
|
#define ANA_HPP
|
||||||
|
|
||||||
|
#define ANA_DETAIL_INTERNAL_HPP
|
||||||
|
#include "common.hpp" //Main definitions
|
||||||
|
#include "timers.hpp" //Timer related
|
||||||
|
#include "predicates.hpp" //Client predicates, used for conditional sending
|
||||||
|
#include "binary_streams.hpp" //For serialization
|
||||||
|
#undef ANA_DETAIL_INTERNAL_HPP
|
||||||
|
|
||||||
/** @namespace ana
|
/** @namespace ana
|
||||||
*
|
*
|
||||||
* Namespace for project ana, the entire API is under this namespce.
|
* Namespace for project ana, the entire API is under this namespce.
|
||||||
*/
|
*/
|
||||||
namespace ana
|
namespace ana
|
||||||
{
|
{
|
||||||
/** @name Type and constant definitions
|
|
||||||
*
|
|
||||||
* Definitions of main types and relevant constants.
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
typedef uint32_t ana_uint32 /** Standard unsigned int, with fixed size to 32 bits. */ ;
|
|
||||||
typedef int32_t ana_int32 /** Standard int, with fixed size to 32 bits. */ ;
|
|
||||||
|
|
||||||
typedef ana_uint32 client_id /** Type of IDs of connected components, unique. */ ;
|
|
||||||
typedef ana_uint32 message_size /** Message size type. */ ;
|
|
||||||
|
|
||||||
typedef std::string port /** Port type, a std::string (instead of a short.) */ ;
|
|
||||||
typedef std::string address /** Address type, a string. Either IP of hostname. */ ;
|
|
||||||
|
|
||||||
typedef bool send_type /** Send operation type, true to copy the buffer. */ ;
|
|
||||||
|
|
||||||
typedef boost::system::error_code error_code /** Standard error code, can evaluate to bool. */ ;
|
|
||||||
|
|
||||||
const send_type ZeroCopy = false /** Don't copy the buffer. */ ;
|
|
||||||
const send_type CopyBuffer = true /** Copy the buffer. */ ;
|
|
||||||
|
|
||||||
const message_size HeaderLength = sizeof(ana_uint32) /** Length of message header. */ ;
|
|
||||||
|
|
||||||
const client_id ServerID = 0 /** The ID of the server application. */ ;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Timeout policies for send operations.
|
|
||||||
*
|
|
||||||
* \sa timer
|
|
||||||
*/
|
|
||||||
enum timeout_policy
|
|
||||||
{
|
|
||||||
NoTimeouts /** Don't use timers in any operation. */,
|
|
||||||
FixedTime /** Use timers with a fixed time for every operation. */,
|
|
||||||
TimePerKilobyte /** Use timers, calculating the necessary time from
|
|
||||||
the size of the buffer that is to be sent. */
|
|
||||||
};
|
|
||||||
//@}
|
|
||||||
|
|
||||||
/** @name Predicates over client ids.
|
|
||||||
*
|
|
||||||
* Declaration of types used in conditional send operations, e.g. send_if.
|
|
||||||
* \sa send_if
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
/** A boolean predicate of client IDs. Used for conditional send operations. */
|
|
||||||
struct client_predicate
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Decides if a given condition applies to a client.
|
|
||||||
*
|
|
||||||
* @param client ID of the queried client.
|
|
||||||
* @returns true if the condition holds for this client.
|
|
||||||
*/
|
|
||||||
virtual bool selects(client_id) const = 0;
|
|
||||||
};
|
|
||||||
//@}
|
|
||||||
|
|
||||||
/** @name Timers
|
|
||||||
*
|
|
||||||
* Definitions of timer related types.
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* General purpose asynchronous timer.
|
|
||||||
*/
|
|
||||||
class timer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/** Standard constructor. */
|
|
||||||
timer() :
|
|
||||||
io_service_(),
|
|
||||||
timer_(io_service_)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wait in background a given amount of milliseconds.
|
|
||||||
*
|
|
||||||
* The method shouldn't be called with a size_t constant
|
|
||||||
* directly. Instead, the user should use the functions in
|
|
||||||
* the ana::time namespace.
|
|
||||||
*
|
|
||||||
* @param milliseconds : Amount of milliseconds to wait.
|
|
||||||
* @param handler : Handler object to handle the timeout event.
|
|
||||||
*
|
|
||||||
* Examples:
|
|
||||||
* - wait( ana::time::seconds(5),
|
|
||||||
* boost::bind( &ChatServer::handle_timeout, this,
|
|
||||||
* boost::asio::placeholders::error);
|
|
||||||
*
|
|
||||||
* \sa ana::time
|
|
||||||
*/
|
|
||||||
template<class Handler>
|
|
||||||
void wait(size_t milliseconds, Handler handler)
|
|
||||||
{
|
|
||||||
timer_.expires_from_now(milliseconds / 1000);
|
|
||||||
timer_.async_wait(handler);
|
|
||||||
boost::thread t( boost::bind( &boost::asio::io_service::run_one, &io_service_ ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Cancel the timer if running. */
|
|
||||||
void cancel()
|
|
||||||
{
|
|
||||||
timer_.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Standard destructor, cancels pending operations and stops the I/O service. */
|
|
||||||
~timer()
|
|
||||||
{
|
|
||||||
timer_.cancel();
|
|
||||||
io_service_.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
/** Private class providing traits for the timer type. */
|
|
||||||
struct time_t_traits
|
|
||||||
{
|
|
||||||
// The time type.
|
|
||||||
typedef std::time_t time_type;
|
|
||||||
|
|
||||||
// The duration type.
|
|
||||||
struct duration_type
|
|
||||||
{
|
|
||||||
duration_type() : value(0) {}
|
|
||||||
duration_type(std::time_t v) : value(v) {}
|
|
||||||
std::time_t value;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get the current time.
|
|
||||||
static time_type now()
|
|
||||||
{
|
|
||||||
return std::time(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a duration to a time.
|
|
||||||
static time_type add(const time_type& t, const duration_type& d)
|
|
||||||
{
|
|
||||||
return t + d.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subtract one time from another.
|
|
||||||
static duration_type subtract(const time_type& t1, const time_type& t2)
|
|
||||||
{
|
|
||||||
return duration_type(t1 - t2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test whether one time is less than another.
|
|
||||||
static bool less_than(const time_type& t1, const time_type& t2)
|
|
||||||
{
|
|
||||||
return t1 < t2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert to POSIX duration type.
|
|
||||||
static boost::posix_time::time_duration to_posix_duration(const duration_type& d)
|
|
||||||
{
|
|
||||||
return boost::posix_time::seconds(d.value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
boost::asio::io_service io_service_;
|
|
||||||
|
|
||||||
boost::asio::basic_deadline_timer<std::time_t,time_t_traits> timer_;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define DETAIL_INTERNAL_HPP
|
|
||||||
#include "detail.hpp"
|
|
||||||
#undef DETAIL_INTERNAL_HPP
|
|
||||||
|
|
||||||
#include "binary_streams.hpp"
|
|
||||||
|
|
||||||
/** @name Handler Interfaces
|
/** @name Handler Interfaces
|
||||||
*
|
*
|
||||||
* Interfaces to handle network events.
|
* Interfaces to handle network events.
|
||||||
@ -286,6 +121,42 @@ namespace ana
|
|||||||
virtual void handle_disconnect(error_code, client_id) = 0;
|
virtual void handle_disconnect(error_code, client_id) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Used for implementation purposes. */
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Base class for any network entity that handles incoming messages.
|
||||||
|
*/
|
||||||
|
class listener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Sets the handler for incoming messages.
|
||||||
|
*
|
||||||
|
* @param listener : Pointer to the listener_handler object that will
|
||||||
|
* handle following incoming message events.
|
||||||
|
*
|
||||||
|
* \sa listener_handler
|
||||||
|
*/
|
||||||
|
virtual void set_listener_handler( listener_handler* listener ) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the client_id of this listener.
|
||||||
|
*
|
||||||
|
* @returns : ServerID for the server application, or a comparable client_id
|
||||||
|
* unique to this listener.
|
||||||
|
*
|
||||||
|
* \sa ServerID
|
||||||
|
* \sa client_id
|
||||||
|
*/
|
||||||
|
virtual client_id id() const = 0;
|
||||||
|
|
||||||
|
protected: // should be so?
|
||||||
|
/** Start listening for incoming messages. */
|
||||||
|
virtual void run_listener() = 0;
|
||||||
|
};
|
||||||
|
} //namespace details
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class that should be implemented to handle new connection events.
|
* Class that should be implemented to handle new connection events.
|
||||||
*/
|
*/
|
||||||
@ -325,61 +196,6 @@ namespace ana
|
|||||||
};
|
};
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Base class for any network entity that handles incoming messages.
|
|
||||||
*/
|
|
||||||
class listener
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Sets the handler for incoming messages.
|
|
||||||
*
|
|
||||||
* @param listener : Pointer to the listener_handler object that will
|
|
||||||
* handle following incoming message events.
|
|
||||||
*
|
|
||||||
* \sa listener_handler
|
|
||||||
*/
|
|
||||||
virtual void set_listener_handler( listener_handler* listener ) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the client_id of this listener.
|
|
||||||
*
|
|
||||||
* @returns : ServerID for the server application, or a comparable client_id
|
|
||||||
* unique to this listener.
|
|
||||||
*
|
|
||||||
* \sa ServerID
|
|
||||||
* \sa client_id
|
|
||||||
*/
|
|
||||||
virtual client_id id() const = 0;
|
|
||||||
|
|
||||||
protected: // should be so?
|
|
||||||
/** Start listening for incoming messages. */
|
|
||||||
virtual void run_listener() = 0;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a client predicate to be used in send operations.
|
|
||||||
*
|
|
||||||
* This function can be used to create predicate objects from the standard library's
|
|
||||||
* bind1st objects and from boost::bind too.
|
|
||||||
*
|
|
||||||
* Examples:
|
|
||||||
* - server_->send_if(boost::asio::buffer( str ), this, create_predicate(
|
|
||||||
* boost::bind( std::not_equal_to<client_id>(), client, _1) ) );
|
|
||||||
*
|
|
||||||
* @param pred Predicate of the queried client.
|
|
||||||
* @returns Predicate for client selection.
|
|
||||||
*/
|
|
||||||
template<class predicate>
|
|
||||||
detail::_generic_client_predicate<predicate> create_predicate(const predicate& pred)
|
|
||||||
{
|
|
||||||
return detail::_generic_client_predicate<predicate>(pred);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @name Time duration functions. */
|
/** @name Time duration functions. */
|
||||||
//@{
|
//@{
|
||||||
/** @namespace time
|
/** @namespace time
|
||||||
@ -654,150 +470,6 @@ namespace ana
|
|||||||
virtual ~client() {}
|
virtual ~client() {}
|
||||||
};
|
};
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/** @name Buffer creation methods
|
|
||||||
*
|
|
||||||
* @defgroup buffer
|
|
||||||
*
|
|
||||||
* API user should create buffers with one of these methods.
|
|
||||||
*
|
|
||||||
* Paraphrasing boost asio's documentation on the buffer function:
|
|
||||||
* The ana::buffer function is used to create a buffer object to represent raw memory,
|
|
||||||
* an array of POD elements, a vector of POD elements, or a std::string.
|
|
||||||
*
|
|
||||||
* Check <http://think-async.com/Asio/boost_asio_1_3_1/doc/html/boost_asio/reference/buffer.html>
|
|
||||||
*/
|
|
||||||
//@{
|
|
||||||
|
|
||||||
inline boost::asio::mutable_buffers_1 buffer(const boost::asio::mutable_buffer & b)
|
|
||||||
{
|
|
||||||
return boost::asio::buffer(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline boost::asio::mutable_buffers_1 buffer(const boost::asio::mutable_buffer & b, std::size_t max_size_in_bytes)
|
|
||||||
{
|
|
||||||
return boost::asio::buffer(b, max_size_in_bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline boost::asio::const_buffers_1 buffer(const boost::asio::const_buffer & b)
|
|
||||||
{
|
|
||||||
return boost::asio::buffer(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline boost::asio::const_buffers_1 buffer(const boost::asio::const_buffer & b, std::size_t max_size_in_bytes)
|
|
||||||
{
|
|
||||||
return boost::asio::buffer(b, max_size_in_bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline boost::asio::mutable_buffers_1 buffer(void * data, std::size_t size_in_bytes)
|
|
||||||
{
|
|
||||||
return boost::asio::buffer(data, size_in_bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline boost::asio::const_buffers_1 buffer(const void * data, std::size_t size_in_bytes)
|
|
||||||
{
|
|
||||||
return boost::asio::buffer(data, size_in_bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename PodType, std::size_t N>
|
|
||||||
inline boost::asio::mutable_buffers_1 buffer(PodType & data)
|
|
||||||
{
|
|
||||||
return boost::asio::buffer(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename PodType, std::size_t N>
|
|
||||||
inline boost::asio::mutable_buffers_1 buffer(PodType & data, std::size_t max_size_in_bytes)
|
|
||||||
{
|
|
||||||
return boost::asio::buffer(data, max_size_in_bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename PodType, std::size_t N>
|
|
||||||
inline boost::asio::const_buffers_1 buffer(const PodType & data)
|
|
||||||
{
|
|
||||||
return boost::asio::buffer(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename PodType, std::size_t N>
|
|
||||||
inline boost::asio::const_buffers_1 buffer(const PodType & data, std::size_t max_size_in_bytes)
|
|
||||||
{
|
|
||||||
return boost::asio::buffer(data, max_size_in_bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename PodType, std::size_t N>
|
|
||||||
inline boost::asio::mutable_buffers_1 buffer(boost::array< PodType, N > & data)
|
|
||||||
{
|
|
||||||
return boost::asio::buffer(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename PodType, std::size_t N>
|
|
||||||
inline boost::asio::mutable_buffers_1 buffer(boost::array< PodType, N > & data,
|
|
||||||
std::size_t max_size_in_bytes)
|
|
||||||
{
|
|
||||||
return boost::asio::buffer(data, max_size_in_bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename PodType, std::size_t N>
|
|
||||||
inline boost::asio::const_buffers_1 buffer(boost::array< const PodType, N > & data)
|
|
||||||
{
|
|
||||||
return boost::asio::buffer(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename PodType, std::size_t N>
|
|
||||||
inline boost::asio::const_buffers_1 buffer(boost::array< const PodType, N > & data,
|
|
||||||
std::size_t max_size_in_bytes)
|
|
||||||
{
|
|
||||||
return boost::asio::buffer(data, max_size_in_bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename PodType, std::size_t N>
|
|
||||||
inline boost::asio::const_buffers_1 buffer(const boost::array< PodType, N > & data)
|
|
||||||
{
|
|
||||||
return boost::asio::buffer(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename PodType, std::size_t N>
|
|
||||||
inline boost::asio::const_buffers_1 buffer(const boost::array< PodType, N > & data,
|
|
||||||
std::size_t max_size_in_bytes)
|
|
||||||
{
|
|
||||||
return boost::asio::buffer(data, max_size_in_bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename PodType, typename Allocator>
|
|
||||||
inline boost::asio::mutable_buffers_1 buffer(std::vector< PodType, Allocator > & data)
|
|
||||||
{
|
|
||||||
return boost::asio::buffer(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename PodType, typename Allocator>
|
|
||||||
inline boost::asio::mutable_buffers_1 buffer(std::vector< PodType, Allocator > & data,
|
|
||||||
std::size_t max_size_in_bytes)
|
|
||||||
{
|
|
||||||
return boost::asio::buffer(data, max_size_in_bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename PodType, typename Allocator>
|
|
||||||
inline boost::asio::const_buffers_1 buffer(const std::vector< PodType, Allocator > & data)
|
|
||||||
{
|
|
||||||
return boost::asio::buffer(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename PodType, typename Allocator>
|
|
||||||
inline boost::asio::const_buffers_1 buffer(const std::vector< PodType, Allocator > & data,
|
|
||||||
std::size_t max_size_in_bytes)
|
|
||||||
{
|
|
||||||
return boost::asio::buffer(data, max_size_in_bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline boost::asio::const_buffers_1 buffer(const std::string & data)
|
|
||||||
{
|
|
||||||
return boost::asio::buffer(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline boost::asio::const_buffers_1 buffer(const std::string & data, std::size_t max_size_in_bytes)
|
|
||||||
{
|
|
||||||
return boost::asio::buffer(data, max_size_in_bytes);
|
|
||||||
}
|
|
||||||
//@}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -40,123 +40,127 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
namespace serializer
|
namespace ana
|
||||||
{
|
{
|
||||||
class bostream
|
namespace serializer
|
||||||
{
|
{
|
||||||
public:
|
class bostream
|
||||||
bostream() :
|
{
|
||||||
_s()
|
public:
|
||||||
{
|
bostream() :
|
||||||
}
|
_s()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
bostream& operator<< (T x)
|
bostream& operator<< (T x)
|
||||||
{
|
{
|
||||||
_s.append(reinterpret_cast<char*>(&x), sizeof(T));
|
_s.append(reinterpret_cast<char*>(&x), sizeof(T));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Inserting a string inserts its size first. */
|
/* Inserting a string inserts its size first. */
|
||||||
bostream& operator<< (const std::string& s)
|
bostream& operator<< (const std::string& s)
|
||||||
{
|
{
|
||||||
(*this) << uint32_t( s.size() );
|
(*this) << uint32_t( s.size() );
|
||||||
_s += s;
|
_s += s;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Other>
|
template <class Other>
|
||||||
bostream& operator<< (const std::vector<Other>& vec)
|
bostream& operator<< (const std::vector<Other>& vec)
|
||||||
{
|
{
|
||||||
const uint32_t size(vec.size());
|
const uint32_t size(vec.size());
|
||||||
(*this) << size;
|
(*this) << size;
|
||||||
for (size_t i(0); i < size; ++i)
|
for (size_t i(0); i < size; ++i)
|
||||||
(*this) << vec[i];
|
(*this) << vec[i];
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bostream& operator<< (const char* cs)
|
bostream& operator<< (const char* cs)
|
||||||
{
|
{
|
||||||
const std::string s(cs);
|
const std::string s(cs);
|
||||||
return operator<< (s);
|
return operator<< (s);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& str() const
|
const std::string& str() const
|
||||||
{
|
{
|
||||||
return _s;
|
return _s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
_s.clear();
|
_s.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string _s;
|
std::string _s;
|
||||||
};
|
};
|
||||||
|
|
||||||
class bistream
|
class bistream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bistream(const std::string& str) :
|
bistream(const std::string& str) :
|
||||||
_s(str),
|
_s(str),
|
||||||
_pos(0)
|
_pos(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bistream() :
|
bistream() :
|
||||||
_s(),
|
_s(),
|
||||||
_pos(0)
|
_pos(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void str(const std::string& str)
|
void str(const std::string& str)
|
||||||
{
|
{
|
||||||
_pos = 0;
|
_pos = 0;
|
||||||
_s = str;
|
_s = str;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
bistream& operator >> (T& x)
|
bistream& operator >> (T& x)
|
||||||
{
|
{
|
||||||
assert(_s.size() >= _pos + sizeof(x));
|
assert(_s.size() >= _pos + sizeof(x));
|
||||||
_pos += _s.copy(reinterpret_cast<char*>(&x), sizeof(x),_pos);
|
_pos += _s.copy(reinterpret_cast<char*>(&x), sizeof(x),_pos);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bistream& operator >> (std::string& str)
|
bistream& operator >> (std::string& str)
|
||||||
{
|
{
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
(*this) >> size;
|
(*this) >> size;
|
||||||
assert(_s.size() >= size+_pos);
|
assert(_s.size() >= size+_pos);
|
||||||
str = _s.substr(_pos,size);
|
str = _s.substr(_pos,size);
|
||||||
_pos += size;
|
_pos += size;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Other>
|
template <class Other>
|
||||||
bistream& operator>> (std::vector<Other>& vec)
|
bistream& operator>> (std::vector<Other>& vec)
|
||||||
{
|
{
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
(*this) >> size;
|
(*this) >> size;
|
||||||
assert(_s.size() >= (size * sizeof(Other)) + _pos);
|
assert(_s.size() >= (size * sizeof(Other)) + _pos);
|
||||||
vec.resize(size);
|
vec.resize(size);
|
||||||
for (size_t i(0); i < size; i++)
|
for (size_t i(0); i < size; i++)
|
||||||
(*this) >> vec[i];
|
(*this) >> vec[i];
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
_s.clear();
|
_s.clear();
|
||||||
_pos = 0;
|
_pos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string _s;
|
||||||
|
std::size_t _pos;
|
||||||
|
};
|
||||||
|
} //serializer namespace
|
||||||
|
} //ana namespace
|
||||||
|
|
||||||
private:
|
|
||||||
std::string _s;
|
|
||||||
std::size_t _pos;
|
|
||||||
};
|
|
||||||
} //serializer namespace
|
|
||||||
#endif
|
#endif
|
||||||
|
296
src/ana/api/buffers.hpp
Normal file
296
src/ana/api/buffers.hpp
Normal file
@ -0,0 +1,296 @@
|
|||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file buffers.hpp
|
||||||
|
* @brief Implementation details for the ana project dealing with buffers.
|
||||||
|
*
|
||||||
|
* ana: Asynchronous Network API.
|
||||||
|
* Copyright (C) 2010 Guillermo Biset.
|
||||||
|
*
|
||||||
|
* This file is part of the ana project.
|
||||||
|
*
|
||||||
|
* System: ana
|
||||||
|
* Language: C++
|
||||||
|
*
|
||||||
|
* Author: Guillermo Biset
|
||||||
|
* E-Mail: billybiset AT gmail DOT com
|
||||||
|
*
|
||||||
|
* ana is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* ana is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with ana. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ANA_BUFFERS_HPP
|
||||||
|
#define ANA_BUFFERS_HPP
|
||||||
|
|
||||||
|
#ifndef ANA_DETAIL_INTERNAL_HPP
|
||||||
|
#error "Private file, do not include directly."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace ana
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* A simple buffer to read things on, supports conversion to string.
|
||||||
|
*/
|
||||||
|
class read_buffer_implementation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a new buffer in heap.
|
||||||
|
*
|
||||||
|
* @param size : The size of the buffer.
|
||||||
|
*/
|
||||||
|
read_buffer_implementation( size_t size ) :
|
||||||
|
base_( new char[ size ] ),
|
||||||
|
size_( size )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Deletes the buffer from heap. */
|
||||||
|
~read_buffer_implementation()
|
||||||
|
{
|
||||||
|
delete[] base_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the base address.
|
||||||
|
*
|
||||||
|
* @returns A char* to the base address of the buffer.
|
||||||
|
*/
|
||||||
|
char* base_char() const
|
||||||
|
{
|
||||||
|
return base_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the base address.
|
||||||
|
*
|
||||||
|
* @returns A void* to the base address of the buffer.
|
||||||
|
*/
|
||||||
|
void* base() const
|
||||||
|
{
|
||||||
|
return static_cast<void*>(base_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get the size of the buffer. */
|
||||||
|
size_t size() const
|
||||||
|
{
|
||||||
|
return size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Create a string from the buffer. */
|
||||||
|
std::string string()
|
||||||
|
{
|
||||||
|
return std::string( base_, size_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
char* base_;
|
||||||
|
size_t size_;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** A shared pointer to a read_buffer, self destructs when no one is left referencing it. */
|
||||||
|
typedef boost::shared_ptr<read_buffer_implementation> read_buffer;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A buffer to be constructed from different buffers that can duplicate the other
|
||||||
|
* and hold a local copy that will destruct with the object itself.
|
||||||
|
*/
|
||||||
|
class copying_buffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
copying_buffer( boost::asio::const_buffer buffer, ana::send_type copy_buffer) :
|
||||||
|
size_(boost::asio::detail::buffer_size_helper(buffer) ),
|
||||||
|
base_( NULL ),
|
||||||
|
copy_( copy_buffer )
|
||||||
|
{
|
||||||
|
if (copy_buffer)
|
||||||
|
{
|
||||||
|
base_ = std::malloc( size_ );
|
||||||
|
std::memcpy(base_, boost::asio::detail::buffer_cast_helper(buffer), size_);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
base_ = const_cast<void*>(boost::asio::detail::buffer_cast_helper(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t size() const { return size_; }
|
||||||
|
|
||||||
|
inline void* base() const { return base_; }
|
||||||
|
|
||||||
|
~copying_buffer()
|
||||||
|
{
|
||||||
|
if (copy_)
|
||||||
|
std::free( base_ );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const size_t size_;
|
||||||
|
void* base_;
|
||||||
|
const bool copy_;
|
||||||
|
};
|
||||||
|
/** A buffer that can be shared by many users. */
|
||||||
|
typedef boost::shared_ptr<detail::copying_buffer> shared_buffer;
|
||||||
|
|
||||||
|
} //namespace detail
|
||||||
|
|
||||||
|
|
||||||
|
/** @name Buffer creation methods
|
||||||
|
*
|
||||||
|
* @defgroup buffer
|
||||||
|
*
|
||||||
|
* API user should create buffers with one of these methods.
|
||||||
|
*
|
||||||
|
* Paraphrasing boost asio's documentation on the buffer function:
|
||||||
|
* The ana::buffer function is used to create a buffer object to represent raw memory,
|
||||||
|
* an array of POD elements, a vector of POD elements, or a std::string.
|
||||||
|
*
|
||||||
|
* Check <http://think-async.com/Asio/boost_asio_1_3_1/doc/html/boost_asio/reference/buffer.html>
|
||||||
|
*/
|
||||||
|
//@{
|
||||||
|
|
||||||
|
inline boost::asio::mutable_buffers_1 buffer(const boost::asio::mutable_buffer & b)
|
||||||
|
{
|
||||||
|
return boost::asio::buffer(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline boost::asio::mutable_buffers_1 buffer(const boost::asio::mutable_buffer & b, std::size_t max_size_in_bytes)
|
||||||
|
{
|
||||||
|
return boost::asio::buffer(b, max_size_in_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline boost::asio::const_buffers_1 buffer(const boost::asio::const_buffer & b)
|
||||||
|
{
|
||||||
|
return boost::asio::buffer(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline boost::asio::const_buffers_1 buffer(const boost::asio::const_buffer & b, std::size_t max_size_in_bytes)
|
||||||
|
{
|
||||||
|
return boost::asio::buffer(b, max_size_in_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline boost::asio::mutable_buffers_1 buffer(void * data, std::size_t size_in_bytes)
|
||||||
|
{
|
||||||
|
return boost::asio::buffer(data, size_in_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline boost::asio::const_buffers_1 buffer(const void * data, std::size_t size_in_bytes)
|
||||||
|
{
|
||||||
|
return boost::asio::buffer(data, size_in_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename PodType, std::size_t N>
|
||||||
|
inline boost::asio::mutable_buffers_1 buffer(PodType & data)
|
||||||
|
{
|
||||||
|
return boost::asio::buffer(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename PodType, std::size_t N>
|
||||||
|
inline boost::asio::mutable_buffers_1 buffer(PodType & data, std::size_t max_size_in_bytes)
|
||||||
|
{
|
||||||
|
return boost::asio::buffer(data, max_size_in_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename PodType, std::size_t N>
|
||||||
|
inline boost::asio::const_buffers_1 buffer(const PodType & data)
|
||||||
|
{
|
||||||
|
return boost::asio::buffer(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename PodType, std::size_t N>
|
||||||
|
inline boost::asio::const_buffers_1 buffer(const PodType & data, std::size_t max_size_in_bytes)
|
||||||
|
{
|
||||||
|
return boost::asio::buffer(data, max_size_in_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename PodType, std::size_t N>
|
||||||
|
inline boost::asio::mutable_buffers_1 buffer(boost::array< PodType, N > & data)
|
||||||
|
{
|
||||||
|
return boost::asio::buffer(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename PodType, std::size_t N>
|
||||||
|
inline boost::asio::mutable_buffers_1 buffer(boost::array< PodType, N > & data,
|
||||||
|
std::size_t max_size_in_bytes)
|
||||||
|
{
|
||||||
|
return boost::asio::buffer(data, max_size_in_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename PodType, std::size_t N>
|
||||||
|
inline boost::asio::const_buffers_1 buffer(boost::array< const PodType, N > & data)
|
||||||
|
{
|
||||||
|
return boost::asio::buffer(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename PodType, std::size_t N>
|
||||||
|
inline boost::asio::const_buffers_1 buffer(boost::array< const PodType, N > & data,
|
||||||
|
std::size_t max_size_in_bytes)
|
||||||
|
{
|
||||||
|
return boost::asio::buffer(data, max_size_in_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename PodType, std::size_t N>
|
||||||
|
inline boost::asio::const_buffers_1 buffer(const boost::array< PodType, N > & data)
|
||||||
|
{
|
||||||
|
return boost::asio::buffer(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename PodType, std::size_t N>
|
||||||
|
inline boost::asio::const_buffers_1 buffer(const boost::array< PodType, N > & data,
|
||||||
|
std::size_t max_size_in_bytes)
|
||||||
|
{
|
||||||
|
return boost::asio::buffer(data, max_size_in_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename PodType, typename Allocator>
|
||||||
|
inline boost::asio::mutable_buffers_1 buffer(std::vector< PodType, Allocator > & data)
|
||||||
|
{
|
||||||
|
return boost::asio::buffer(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename PodType, typename Allocator>
|
||||||
|
inline boost::asio::mutable_buffers_1 buffer(std::vector< PodType, Allocator > & data,
|
||||||
|
std::size_t max_size_in_bytes)
|
||||||
|
{
|
||||||
|
return boost::asio::buffer(data, max_size_in_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename PodType, typename Allocator>
|
||||||
|
inline boost::asio::const_buffers_1 buffer(const std::vector< PodType, Allocator > & data)
|
||||||
|
{
|
||||||
|
return boost::asio::buffer(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename PodType, typename Allocator>
|
||||||
|
inline boost::asio::const_buffers_1 buffer(const std::vector< PodType, Allocator > & data,
|
||||||
|
std::size_t max_size_in_bytes)
|
||||||
|
{
|
||||||
|
return boost::asio::buffer(data, max_size_in_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline boost::asio::const_buffers_1 buffer(const std::string & data)
|
||||||
|
{
|
||||||
|
return boost::asio::buffer(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline boost::asio::const_buffers_1 buffer(const std::string & data, std::size_t max_size_in_bytes)
|
||||||
|
{
|
||||||
|
return boost::asio::buffer(data, max_size_in_bytes);
|
||||||
|
}
|
||||||
|
//@}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
69
src/ana/api/common.hpp
Normal file
69
src/ana/api/common.hpp
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file common.hpp
|
||||||
|
* @brief Main definitions for project ana.
|
||||||
|
*
|
||||||
|
* ana: Asynchronous Network API.
|
||||||
|
* Copyright (C) 2010 Guillermo Biset.
|
||||||
|
*
|
||||||
|
* This file is part of the ana project.
|
||||||
|
*
|
||||||
|
* System: ana
|
||||||
|
* Language: C++
|
||||||
|
*
|
||||||
|
* Author: Guillermo Biset
|
||||||
|
* E-Mail: billybiset AT gmail DOT com
|
||||||
|
*
|
||||||
|
* ana is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* ana is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with ana. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ANA_COMMON_HPP
|
||||||
|
#define ANA_COMMON_HPP
|
||||||
|
|
||||||
|
#ifndef ANA_DETAIL_INTERNAL_HPP
|
||||||
|
#error "Private file, do not include directly."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace ana
|
||||||
|
{
|
||||||
|
/** @name Type and constant definitions
|
||||||
|
*
|
||||||
|
* Definitions of main types and relevant constants.
|
||||||
|
*/
|
||||||
|
//@{
|
||||||
|
typedef boost::uint32_t ana_uint32 /** Standard unsigned int, with fixed size to 32 bits. */ ;
|
||||||
|
typedef boost::int32_t ana_int32 /** Standard int, with fixed size to 32 bits. */ ;
|
||||||
|
|
||||||
|
typedef ana_uint32 client_id /** Type of IDs of connected components, unique. */ ;
|
||||||
|
typedef ana_uint32 message_size /** Message size type. */ ;
|
||||||
|
|
||||||
|
typedef std::string port /** Port type, a std::string (instead of a short.) */ ;
|
||||||
|
typedef std::string address /** Address type, a string. Either IP of hostname. */ ;
|
||||||
|
|
||||||
|
typedef bool send_type /** Send operation type, true to copy the buffer. */ ;
|
||||||
|
|
||||||
|
typedef boost::system::error_code error_code /** Standard error code, can evaluate to bool. */ ;
|
||||||
|
|
||||||
|
const send_type ZeroCopy = false /** Don't copy the buffer. */ ;
|
||||||
|
const send_type CopyBuffer = true /** Copy the buffer. */ ;
|
||||||
|
|
||||||
|
const message_size HeaderLength = sizeof(ana_uint32) /** Length of message header. */ ;
|
||||||
|
|
||||||
|
const client_id ServerID = 0 /** The ID of the server application. */ ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -1,247 +0,0 @@
|
|||||||
/* $Id$ */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file detail.hpp
|
|
||||||
* @brief Implementation details for the ana project. Private file, do not include directly.
|
|
||||||
*
|
|
||||||
* ana: Asynchronous Network API.
|
|
||||||
* Copyright (C) 2010 Guillermo Biset.
|
|
||||||
*
|
|
||||||
* This file is part of the ana project.
|
|
||||||
*
|
|
||||||
* System: ana
|
|
||||||
* Language: C++
|
|
||||||
*
|
|
||||||
* Author: Guillermo Biset
|
|
||||||
* E-Mail: billybiset AT gmail DOT com
|
|
||||||
*
|
|
||||||
* ana is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* ana is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with ana. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DETAIL_INTERNAL_HPP
|
|
||||||
#error "Private file, do not include directly."
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Used for implementation purposes. */
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Intended for private use, should be created with create_predicate.
|
|
||||||
*
|
|
||||||
* \sa create_predicate
|
|
||||||
*/
|
|
||||||
template<class predicate>
|
|
||||||
class _generic_client_predicate : public client_predicate
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/** Construct via a generic object with overloaded operator(). */
|
|
||||||
_generic_client_predicate(const predicate& pred)
|
|
||||||
: pred(pred)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Copy constructor. */
|
|
||||||
_generic_client_predicate(const _generic_client_predicate<predicate>& other )
|
|
||||||
: pred(other.pred)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
const predicate pred /** The predicate object. */ ;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of the selection method using operator() from the
|
|
||||||
* predicate object.
|
|
||||||
*
|
|
||||||
* \sa client_predicate
|
|
||||||
*/
|
|
||||||
virtual bool selects(client_id cid) const
|
|
||||||
{
|
|
||||||
return pred(cid);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A simple buffer to read things on, supports conversion to string.
|
|
||||||
*/
|
|
||||||
class read_buffer_implementation
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Creates a new buffer in heap.
|
|
||||||
*
|
|
||||||
* @param size : The size of the buffer.
|
|
||||||
*/
|
|
||||||
read_buffer_implementation( size_t size ) :
|
|
||||||
base_( new char[ size ] ),
|
|
||||||
size_( size )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Deletes the buffer from heap. */
|
|
||||||
~read_buffer_implementation()
|
|
||||||
{
|
|
||||||
delete[] base_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the base address.
|
|
||||||
*
|
|
||||||
* @returns A char* to the base address of the buffer.
|
|
||||||
*/
|
|
||||||
char* base_char() const
|
|
||||||
{
|
|
||||||
return base_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the base address.
|
|
||||||
*
|
|
||||||
* @returns A void* to the base address of the buffer.
|
|
||||||
*/
|
|
||||||
void* base() const
|
|
||||||
{
|
|
||||||
return static_cast<void*>(base_);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get the size of the buffer. */
|
|
||||||
size_t size() const
|
|
||||||
{
|
|
||||||
return size_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create a string from the buffer. */
|
|
||||||
std::string string()
|
|
||||||
{
|
|
||||||
return std::string( base_, size_ );
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
char* base_;
|
|
||||||
size_t size_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** A shared pointer to a read_buffer, self destructs when no one is left referencing it. */
|
|
||||||
typedef boost::shared_ptr<read_buffer_implementation> read_buffer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A buffer to be constructed from different buffers that can duplicate the other
|
|
||||||
* and hold a local copy that will destruct with the object itself.
|
|
||||||
*/
|
|
||||||
class copying_buffer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
copying_buffer( boost::asio::const_buffer buffer, ana::send_type copy_buffer) :
|
|
||||||
size_(boost::asio::detail::buffer_size_helper(buffer) ),
|
|
||||||
base_( NULL ),
|
|
||||||
copy_( copy_buffer )
|
|
||||||
{
|
|
||||||
if (copy_buffer)
|
|
||||||
{
|
|
||||||
base_ = std::malloc( size_ );
|
|
||||||
std::memcpy(base_, boost::asio::detail::buffer_cast_helper(buffer), size_);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
base_ = const_cast<void*>(boost::asio::detail::buffer_cast_helper(buffer));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t size() const { return size_; }
|
|
||||||
|
|
||||||
inline void* base() const { return base_; }
|
|
||||||
|
|
||||||
~copying_buffer()
|
|
||||||
{
|
|
||||||
if (copy_)
|
|
||||||
std::free( base_ );
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const size_t size_;
|
|
||||||
void* base_;
|
|
||||||
const bool copy_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** A buffer that can be shared by many users. */
|
|
||||||
typedef boost::shared_ptr<detail::copying_buffer> shared_buffer;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A network sender component that can be configured to issue timeout events.
|
|
||||||
*/
|
|
||||||
class timed_sender
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Set the policy for timed operations (such as send.)
|
|
||||||
*
|
|
||||||
* @param type : Type of timeout policy.
|
|
||||||
* @param ms : Milliseconds related to the given policy, 0 means no timeouts.
|
|
||||||
*
|
|
||||||
* Examples:
|
|
||||||
* - set_timeouts( ana::NoTimeouts );
|
|
||||||
* - set_timeouts( ana::FixedTime, ana::time::minutes( 1 ) );
|
|
||||||
*
|
|
||||||
* \sa timeout_policy
|
|
||||||
* \sa ana::time
|
|
||||||
*/
|
|
||||||
void set_timeouts(timeout_policy type, size_t ms = 0)
|
|
||||||
{
|
|
||||||
timeout_milliseconds_ = ms;
|
|
||||||
if (ms > 0)
|
|
||||||
timeout_type_ = type;
|
|
||||||
else
|
|
||||||
timeout_type_ = NoTimeouts;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start a timer given the current configuration.
|
|
||||||
*
|
|
||||||
* @param buffer : The buffer used in the send operation.
|
|
||||||
* @param handler : The handler of the timeout/abort event.
|
|
||||||
*
|
|
||||||
* @returns : A pointer to a newly created timer object.
|
|
||||||
*/
|
|
||||||
template<class Handler>
|
|
||||||
timer* start_timer( shared_buffer buffer, Handler handler ) const
|
|
||||||
{
|
|
||||||
if ( (timeout_milliseconds_ == 0) || (timeout_type_ == NoTimeouts) )
|
|
||||||
return NULL;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
timer* t = new timer();
|
|
||||||
switch ( timeout_type_ ) //this should be more OO looking
|
|
||||||
{
|
|
||||||
case TimePerKilobyte :
|
|
||||||
t->wait( (buffer->size() / 1024.0) * timeout_milliseconds_, handler);
|
|
||||||
break;
|
|
||||||
default :
|
|
||||||
t->wait( timeout_milliseconds_, handler);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/** Standard constructor. */
|
|
||||||
timed_sender() :
|
|
||||||
timeout_type_( NoTimeouts ),
|
|
||||||
timeout_milliseconds_( 0 )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
timeout_policy timeout_type_ /** Type of timer policy. */ ;
|
|
||||||
size_t timeout_milliseconds_ /** Amount of ms relevant to this policy. */ ;
|
|
||||||
};
|
|
||||||
} //namespace details
|
|
116
src/ana/api/predicates.hpp
Normal file
116
src/ana/api/predicates.hpp
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file predicates.hpp
|
||||||
|
* @brief Implementation details for the ana project dealing with client predicates.
|
||||||
|
*
|
||||||
|
* ana: Asynchronous Network API.
|
||||||
|
* Copyright (C) 2010 Guillermo Biset.
|
||||||
|
*
|
||||||
|
* This file is part of the ana project.
|
||||||
|
*
|
||||||
|
* System: ana
|
||||||
|
* Language: C++
|
||||||
|
*
|
||||||
|
* Author: Guillermo Biset
|
||||||
|
* E-Mail: billybiset AT gmail DOT com
|
||||||
|
*
|
||||||
|
* ana is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* ana is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with ana. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ANA_PREDICATES_HPP
|
||||||
|
#define ANA_PREDICATES_HPP
|
||||||
|
|
||||||
|
#ifndef ANA_DETAIL_INTERNAL_HPP
|
||||||
|
#error "Private file, do not include directly."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace ana
|
||||||
|
{
|
||||||
|
/** @name Predicates over client ids.
|
||||||
|
*
|
||||||
|
* Declaration of types used in conditional send operations, e.g. send_if.
|
||||||
|
* \sa send_if
|
||||||
|
*/
|
||||||
|
//@{
|
||||||
|
/** A boolean predicate of client IDs. Used for conditional send operations. */
|
||||||
|
struct client_predicate
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Decides if a given condition applies to a client.
|
||||||
|
*
|
||||||
|
* @param client ID of the queried client.
|
||||||
|
* @returns true if the condition holds for this client.
|
||||||
|
*/
|
||||||
|
virtual bool selects(client_id) const = 0;
|
||||||
|
};
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intended for private use, should be created with create_predicate.
|
||||||
|
*
|
||||||
|
* \sa create_predicate
|
||||||
|
*/
|
||||||
|
template<class predicate>
|
||||||
|
class _generic_client_predicate : public client_predicate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** Construct via a generic object with overloaded operator(). */
|
||||||
|
_generic_client_predicate(const predicate& pred)
|
||||||
|
: pred(pred)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Copy constructor. */
|
||||||
|
_generic_client_predicate(const _generic_client_predicate<predicate>& other )
|
||||||
|
: pred(other.pred)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
const predicate pred /** The predicate object. */ ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of the selection method using operator() from the
|
||||||
|
* predicate object.
|
||||||
|
*
|
||||||
|
* \sa client_predicate
|
||||||
|
*/
|
||||||
|
virtual bool selects(client_id cid) const
|
||||||
|
{
|
||||||
|
return pred(cid);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a client predicate to be used in send operations.
|
||||||
|
*
|
||||||
|
* This function can be used to create predicate objects from the standard library's
|
||||||
|
* bind1st objects and from boost::bind too.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
* - server_->send_if(boost::asio::buffer( str ), this, create_predicate(
|
||||||
|
* boost::bind( std::not_equal_to<client_id>(), client, _1) ) );
|
||||||
|
*
|
||||||
|
* @param pred Predicate of the queried client.
|
||||||
|
* @returns Predicate for client selection.
|
||||||
|
*/
|
||||||
|
template<class predicate>
|
||||||
|
_generic_client_predicate<predicate> create_predicate(const predicate& pred)
|
||||||
|
{
|
||||||
|
return _generic_client_predicate<predicate>(pred);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
238
src/ana/api/timers.hpp
Normal file
238
src/ana/api/timers.hpp
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file timers.hpp
|
||||||
|
* @brief Implementation details for the ana project dealing with timers.
|
||||||
|
*
|
||||||
|
* ana: Asynchronous Network API.
|
||||||
|
* Copyright (C) 2010 Guillermo Biset.
|
||||||
|
*
|
||||||
|
* This file is part of the ana project.
|
||||||
|
*
|
||||||
|
* System: ana
|
||||||
|
* Language: C++
|
||||||
|
*
|
||||||
|
* Author: Guillermo Biset
|
||||||
|
* E-Mail: billybiset AT gmail DOT com
|
||||||
|
*
|
||||||
|
* ana is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* ana is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with ana. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "buffers.hpp"
|
||||||
|
|
||||||
|
#ifndef ANA_TIMERS_HPP
|
||||||
|
#define ANA_TIMERS_HPP
|
||||||
|
|
||||||
|
#ifndef ANA_DETAIL_INTERNAL_HPP
|
||||||
|
#error "Private file, do not include directly."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace ana
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Timeout policies for send operations.
|
||||||
|
*
|
||||||
|
* \sa timer
|
||||||
|
*/
|
||||||
|
enum timeout_policy
|
||||||
|
{
|
||||||
|
NoTimeouts /** Don't use timers in any operation. */,
|
||||||
|
FixedTime /** Use timers with a fixed time for every operation. */,
|
||||||
|
TimePerKilobyte /** Use timers, calculating the necessary time from
|
||||||
|
the size of the buffer that is to be sent. */
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @name Timers
|
||||||
|
*
|
||||||
|
* Definitions of timer related types.
|
||||||
|
*/
|
||||||
|
//@{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* General purpose asynchronous timer.
|
||||||
|
*/
|
||||||
|
class timer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** Standard constructor. */
|
||||||
|
timer() :
|
||||||
|
io_service_(),
|
||||||
|
timer_(io_service_)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait in background a given amount of milliseconds.
|
||||||
|
*
|
||||||
|
* The method shouldn't be called with a size_t constant
|
||||||
|
* directly. Instead, the user should use the functions in
|
||||||
|
* the ana::time namespace.
|
||||||
|
*
|
||||||
|
* @param milliseconds : Amount of milliseconds to wait.
|
||||||
|
* @param handler : Handler object to handle the timeout event.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
* - wait( ana::time::seconds(5),
|
||||||
|
* boost::bind( &ChatServer::handle_timeout, this,
|
||||||
|
* boost::asio::placeholders::error);
|
||||||
|
*
|
||||||
|
* \sa ana::time
|
||||||
|
*/
|
||||||
|
template<class Handler>
|
||||||
|
void wait(size_t milliseconds, Handler handler)
|
||||||
|
{
|
||||||
|
timer_.expires_from_now(milliseconds / 1000);
|
||||||
|
timer_.async_wait(handler);
|
||||||
|
boost::thread t( boost::bind( &boost::asio::io_service::run_one, &io_service_ ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Cancel the timer if running. */
|
||||||
|
void cancel()
|
||||||
|
{
|
||||||
|
timer_.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Standard destructor, cancels pending operations and stops the I/O service. */
|
||||||
|
~timer()
|
||||||
|
{
|
||||||
|
timer_.cancel();
|
||||||
|
io_service_.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/** Private class providing traits for the timer type. */
|
||||||
|
struct time_t_traits
|
||||||
|
{
|
||||||
|
// The time type.
|
||||||
|
typedef std::time_t time_type;
|
||||||
|
|
||||||
|
// The duration type.
|
||||||
|
struct duration_type
|
||||||
|
{
|
||||||
|
duration_type() : value(0) {}
|
||||||
|
duration_type(std::time_t v) : value(v) {}
|
||||||
|
std::time_t value;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get the current time.
|
||||||
|
static time_type now()
|
||||||
|
{
|
||||||
|
return std::time(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a duration to a time.
|
||||||
|
static time_type add(const time_type& t, const duration_type& d)
|
||||||
|
{
|
||||||
|
return t + d.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subtract one time from another.
|
||||||
|
static duration_type subtract(const time_type& t1, const time_type& t2)
|
||||||
|
{
|
||||||
|
return duration_type(t1 - t2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test whether one time is less than another.
|
||||||
|
static bool less_than(const time_type& t1, const time_type& t2)
|
||||||
|
{
|
||||||
|
return t1 < t2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to POSIX duration type.
|
||||||
|
static boost::posix_time::time_duration to_posix_duration(const duration_type& d)
|
||||||
|
{
|
||||||
|
return boost::posix_time::seconds(d.value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
boost::asio::io_service io_service_;
|
||||||
|
|
||||||
|
boost::asio::basic_deadline_timer<std::time_t,time_t_traits> timer_;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* A network sender component that can be configured to issue timeout events.
|
||||||
|
*/
|
||||||
|
class timed_sender
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Set the policy for timed operations (such as send.)
|
||||||
|
*
|
||||||
|
* @param type : Type of timeout policy.
|
||||||
|
* @param ms : Milliseconds related to the given policy, 0 means no timeouts.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
* - set_timeouts( ana::NoTimeouts );
|
||||||
|
* - set_timeouts( ana::FixedTime, ana::time::minutes( 1 ) );
|
||||||
|
*
|
||||||
|
* \sa timeout_policy
|
||||||
|
* \sa ana::time
|
||||||
|
*/
|
||||||
|
void set_timeouts(timeout_policy type, size_t ms = 0)
|
||||||
|
{
|
||||||
|
timeout_milliseconds_ = ms;
|
||||||
|
if (ms > 0)
|
||||||
|
timeout_type_ = type;
|
||||||
|
else
|
||||||
|
timeout_type_ = NoTimeouts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start a timer given the current configuration.
|
||||||
|
*
|
||||||
|
* @param buffer : The buffer used in the send operation.
|
||||||
|
* @param handler : The handler of the timeout/abort event.
|
||||||
|
*
|
||||||
|
* @returns : A pointer to a newly created timer object.
|
||||||
|
*/
|
||||||
|
template<class Handler>
|
||||||
|
timer* start_timer( shared_buffer buffer, Handler handler ) const
|
||||||
|
{
|
||||||
|
if ( (timeout_milliseconds_ == 0) || (timeout_type_ == NoTimeouts) )
|
||||||
|
return NULL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
timer* t = new timer();
|
||||||
|
switch ( timeout_type_ ) //this should be more OO looking
|
||||||
|
{
|
||||||
|
case TimePerKilobyte :
|
||||||
|
t->wait( (buffer->size() / 1024.0) * timeout_milliseconds_, handler);
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
t->wait( timeout_milliseconds_, handler);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** Standard constructor. */
|
||||||
|
timed_sender() :
|
||||||
|
timeout_type_( NoTimeouts ),
|
||||||
|
timeout_milliseconds_( 0 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
timeout_policy timeout_type_ /** Type of timer policy. */ ;
|
||||||
|
size_t timeout_milliseconds_ /** Amount of ms relevant to this policy. */ ;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -1,6 +1,6 @@
|
|||||||
include_directories( ../api )
|
include_directories( ../api )
|
||||||
|
|
||||||
find_package( Boost 1.37 REQUIRED COMPONENTS thread system)
|
find_package( Boost 1.35 REQUIRED COMPONENTS thread system)
|
||||||
|
|
||||||
set ( server_srcs asio_server.cpp asio_listener.cpp )
|
set ( server_srcs asio_server.cpp asio_listener.cpp )
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ void asio_client::connect( ana::connection_handler* handler )
|
|||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
handler->handle_connect( boost::system::error_code(1,boost::system::get_generic_category() ), 0 );
|
handler->handle_connect( boost::system::error_code(1,boost::system::system_category ), 0 );
|
||||||
std::cerr << "Client: An error ocurred, " << e.what() << std::endl;
|
std::cerr << "Client: An error ocurred, " << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,6 +126,6 @@ void asio_listener::listen_one_message()
|
|||||||
}
|
}
|
||||||
catch(const std::exception& e)
|
catch(const std::exception& e)
|
||||||
{
|
{
|
||||||
disconnect(listener_, boost::system::error_code(1,boost::system::get_generic_category() ));
|
disconnect(listener_, boost::system::error_code(1,boost::system::system_category) );
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -146,13 +146,13 @@ void proxy_connection::handle_response(boost::asio::streambuf* buf,
|
|||||||
}
|
}
|
||||||
else //TODO: digest authentication support here
|
else //TODO: digest authentication support here
|
||||||
manager_->handle_proxy_connection(
|
manager_->handle_proxy_connection(
|
||||||
boost::system::error_code(1,boost::system::get_generic_category() ),
|
boost::system::error_code(1,boost::system::system_category ),
|
||||||
conn_handler_);
|
conn_handler_);
|
||||||
|
|
||||||
}
|
}
|
||||||
else //Couldn't connect, wrong password or wasn't offered the possibility to authenticate
|
else //Couldn't connect, wrong password or wasn't offered the possibility to authenticate
|
||||||
manager_->handle_proxy_connection(
|
manager_->handle_proxy_connection(
|
||||||
boost::system::error_code(1,boost::system::get_generic_category() ),
|
boost::system::error_code(1,boost::system::system_category ),
|
||||||
conn_handler_);
|
conn_handler_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -222,7 +222,7 @@ void proxy_connection::do_connect()
|
|||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
manager_->handle_proxy_connection(
|
manager_->handle_proxy_connection(
|
||||||
boost::system::error_code(1,boost::system::get_generic_category() ),
|
boost::system::error_code(1,boost::system::system_category),
|
||||||
conn_handler_ );
|
conn_handler_ );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user