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
11 changed files with 876 additions and 728 deletions
|
@ -51,13 +51,10 @@
|
|||
*
|
||||
* @section requirements requirements
|
||||
* 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/noncopyable.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
@ -68,184 +65,22 @@
|
|||
#include <cstdlib>
|
||||
#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 for project ana, the entire API is under this namespce.
|
||||
*/
|
||||
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
|
||||
*
|
||||
* Interfaces to handle network events.
|
||||
|
@ -286,6 +121,42 @@ namespace ana
|
|||
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.
|
||||
*/
|
||||
|
@ -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. */
|
||||
//@{
|
||||
/** @namespace time
|
||||
|
@ -654,150 +470,6 @@ namespace ana
|
|||
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
|
||||
|
|
|
@ -40,123 +40,127 @@
|
|||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace serializer
|
||||
namespace ana
|
||||
{
|
||||
class bostream
|
||||
namespace serializer
|
||||
{
|
||||
public:
|
||||
bostream() :
|
||||
_s()
|
||||
{
|
||||
}
|
||||
class bostream
|
||||
{
|
||||
public:
|
||||
bostream() :
|
||||
_s()
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bostream& operator<< (T x)
|
||||
{
|
||||
_s.append(reinterpret_cast<char*>(&x), sizeof(T));
|
||||
return *this;
|
||||
}
|
||||
template <class T>
|
||||
bostream& operator<< (T x)
|
||||
{
|
||||
_s.append(reinterpret_cast<char*>(&x), sizeof(T));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* Inserting a string inserts its size first. */
|
||||
bostream& operator<< (const std::string& s)
|
||||
{
|
||||
(*this) << uint32_t( s.size() );
|
||||
_s += s;
|
||||
return *this;
|
||||
}
|
||||
/* Inserting a string inserts its size first. */
|
||||
bostream& operator<< (const std::string& s)
|
||||
{
|
||||
(*this) << uint32_t( s.size() );
|
||||
_s += s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Other>
|
||||
bostream& operator<< (const std::vector<Other>& vec)
|
||||
{
|
||||
const uint32_t size(vec.size());
|
||||
(*this) << size;
|
||||
for (size_t i(0); i < size; ++i)
|
||||
(*this) << vec[i];
|
||||
template <class Other>
|
||||
bostream& operator<< (const std::vector<Other>& vec)
|
||||
{
|
||||
const uint32_t size(vec.size());
|
||||
(*this) << size;
|
||||
for (size_t i(0); i < size; ++i)
|
||||
(*this) << vec[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bostream& operator<< (const char* cs)
|
||||
{
|
||||
const std::string s(cs);
|
||||
return operator<< (s);
|
||||
}
|
||||
bostream& operator<< (const char* cs)
|
||||
{
|
||||
const std::string s(cs);
|
||||
return operator<< (s);
|
||||
}
|
||||
|
||||
const std::string& str() const
|
||||
{
|
||||
return _s;
|
||||
}
|
||||
const std::string& str() const
|
||||
{
|
||||
return _s;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
_s.clear();
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
_s.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string _s;
|
||||
};
|
||||
private:
|
||||
std::string _s;
|
||||
};
|
||||
|
||||
class bistream
|
||||
{
|
||||
public:
|
||||
bistream(const std::string& str) :
|
||||
_s(str),
|
||||
_pos(0)
|
||||
{
|
||||
}
|
||||
class bistream
|
||||
{
|
||||
public:
|
||||
bistream(const std::string& str) :
|
||||
_s(str),
|
||||
_pos(0)
|
||||
{
|
||||
}
|
||||
|
||||
bistream() :
|
||||
_s(),
|
||||
_pos(0)
|
||||
{
|
||||
}
|
||||
bistream() :
|
||||
_s(),
|
||||
_pos(0)
|
||||
{
|
||||
}
|
||||
|
||||
void str(const std::string& str)
|
||||
{
|
||||
_pos = 0;
|
||||
_s = str;
|
||||
}
|
||||
void str(const std::string& str)
|
||||
{
|
||||
_pos = 0;
|
||||
_s = str;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bistream& operator >> (T& x)
|
||||
{
|
||||
assert(_s.size() >= _pos + sizeof(x));
|
||||
_pos += _s.copy(reinterpret_cast<char*>(&x), sizeof(x),_pos);
|
||||
return *this;
|
||||
}
|
||||
template <class T>
|
||||
bistream& operator >> (T& x)
|
||||
{
|
||||
assert(_s.size() >= _pos + sizeof(x));
|
||||
_pos += _s.copy(reinterpret_cast<char*>(&x), sizeof(x),_pos);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bistream& operator >> (std::string& str)
|
||||
{
|
||||
uint32_t size;
|
||||
(*this) >> size;
|
||||
assert(_s.size() >= size+_pos);
|
||||
str = _s.substr(_pos,size);
|
||||
_pos += size;
|
||||
return *this;
|
||||
}
|
||||
bistream& operator >> (std::string& str)
|
||||
{
|
||||
uint32_t size;
|
||||
(*this) >> size;
|
||||
assert(_s.size() >= size+_pos);
|
||||
str = _s.substr(_pos,size);
|
||||
_pos += size;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Other>
|
||||
bistream& operator>> (std::vector<Other>& vec)
|
||||
{
|
||||
uint32_t size;
|
||||
(*this) >> size;
|
||||
assert(_s.size() >= (size * sizeof(Other)) + _pos);
|
||||
vec.resize(size);
|
||||
for (size_t i(0); i < size; i++)
|
||||
(*this) >> vec[i];
|
||||
template <class Other>
|
||||
bistream& operator>> (std::vector<Other>& vec)
|
||||
{
|
||||
uint32_t size;
|
||||
(*this) >> size;
|
||||
assert(_s.size() >= (size * sizeof(Other)) + _pos);
|
||||
vec.resize(size);
|
||||
for (size_t i(0); i < size; i++)
|
||||
(*this) >> vec[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
_s.clear();
|
||||
_pos = 0;
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
_s.clear();
|
||||
_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
|
||||
|
|
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 )
|
||||
|
||||
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 )
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ void asio_client::connect( ana::connection_handler* handler )
|
|||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,6 +126,6 @@ void asio_listener::listen_one_message()
|
|||
}
|
||||
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
|
||||
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_);
|
||||
|
||||
}
|
||||
else //Couldn't connect, wrong password or wasn't offered the possibility to authenticate
|
||||
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_);
|
||||
}
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ void proxy_connection::do_connect()
|
|||
catch (const std::exception& e)
|
||||
{
|
||||
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_ );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue