00001
#ifndef DV_NET_SNDRCV_H
00002
#define DV_NET_SNDRCV_H
00003
00004
#include <strstream>
00005
#include <string>
00006
#include <iostream>
00007
#include <stdexcept>
00008
00009
namespace Dv {
00010
namespace Net {
00011
00012
00013
00014
00015
00016
00017
00018 class SimpleMessage {
00019
public:
00020
00021
00022
00023
00024
00025
00026
00027 SimpleMessage(
const char* data = 0, size_t size = 0):
00028
data_(data),
size_(size),
owner_(false) {};
00029
00030
00031
00032 virtual ~SimpleMessage() {
00033
if (
owner_)
00034
delete data_;
00035 }
00036
00037
00038
00039 const char*
data()
const {
return data_; }
00040
00041 const size_t
size()
const {
return size_; }
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 std::ostream&
send(std::ostream& os)
const;
00055
00056
00057
00058
00059
00060
00061
00062
00063 std::istream&
receive(std::istream& is)
throw (std::runtime_error);
00064
00065
protected:
00066
00067
00068
00069
00070
00071
00072
00073
const char*
data(
const char* p, size_t size);
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
char*
data(size_t size);
00084
private:
00085 const char*
data_;
00086 size_t
size_;
00087 bool owner_;
00088 };
00089
00090
00091
00092
00093
00094
00095
00096
template<
typename T>
00097 class Message:
public SimpleMessage {
00098
public:
00099
00100 Message(
const T& t = T())
throw (std::runtime_error) {
00101
if (! (
oss_ << t) )
00102
throw std::runtime_error(
"Message<T>::Message(const T&) cannot store T object");
00103
data(
oss_.str(),
oss_.pcount());
00104 }
00105
00106 ~Message() {
00107
oss_.freeze(0);
00108 }
00109
00110 operator T() const throw (std::runtime_error) {
00111 std::istrstream iss(
data(),
size());
00112 T t;
00113
if ( ! (iss >> t) )
00114
throw std::runtime_error(
"Message<T>::operator T() cannot read T object");
00115
return t;
00116 }
00117
private:
00118 std::ostrstream
oss_;
00119 };
00120
00121
00122
00123
00124
00125
template<>
00126 class Message<std::string>:
public SimpleMessage {
00127
public:
00128
00129 Message(
const std::string& s) {
00130
data(s.data(), s.size());
00131 }
00132
00133 ~Message() {}
00134
00135 operator std::string()
const {
return std::string(
data(),
size()); }
00136 };
00137
00138
00139 }}
00140
00141
inline std::ostream&
00142 operator<<(std::ostream& os,
const Dv::Net::SimpleMessage& m) {
00143
return m.
send(os);
00144 }
00145
00146
inline std::istream&
00147 operator>>(std::istream& is,
Dv::Net::SimpleMessage& m)
throw (std::runtime_error) {
00148
return m.receive(is);
00149 }
00150
00151
#endif