00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef _terimber_msg_cpp_h_
00029 #define _terimber_msg_cpp_h_
00030
00031 #include "aiomsg/msg_c.h"
00032 #include "base/memory.h"
00033 #include "base/string.h"
00034 #include "base/list.h"
00035 #include "base/number.h"
00036
00037
00038 BEGIN_TERIMBER_NAMESPACE
00039 #pragma pack(4)
00040
00043 typedef room_array< ub1_t > room_byte_t;
00044
00047 enum transport_type
00048 {
00049 unknown = 0,
00050 sock,
00051 rpc
00052 };
00053
00056 const size_t user_type_send = 0x10000001;
00058 const size_t user_type_send_async = 0x10000002;
00060 const size_t user_type_post = 0x10000003;
00062 const size_t user_type_reply = 0x10000004;
00064 const size_t user_type_reply_async = 0x10000005;
00066 const size_t user_type_mask = 0x10000007;
00068 const size_t handshake_type = 0x20000000;
00070 const size_t system_type = 0x40000000;
00071
00074 const size_t msg_id_handshake_request = 0x10000001;
00076 const size_t msg_id_handshake_reply = 0x10000002;
00078 const size_t msg_id_ping = 0x10000003;
00080 const size_t msg_id_shutdown = 0x10000004;
00082 const size_t msg_default_timeout = 10000;
00084 const size_t msg_crypt_block = 16;
00085
00087 inline
00088 bool
00089 is_request(size_t type)
00090 {
00091 return type != user_type_reply && type != user_type_reply_async;
00092 }
00093
00097 class msg_cpp : public msg_t
00098 {
00100 msg_cpp(byte_allocator* allocator_, size_t size_);
00102 virtual ~msg_cpp();
00103 public:
00105 static
00106 inline
00107 msg_cpp*
00108 construct( byte_allocator* allocator_,
00109 size_t size_
00110 )
00111 {
00112 msg_cpp* msg = 0;
00113 void* msg_space = 0;
00114
00115
00116
00117 if ((msg_space = allocator_->allocate(sizeof(msg_cpp)))
00118 && (msg = new(msg_space) msg_cpp(allocator_, size_))
00119 )
00120 return msg;
00121 else
00122 return 0;
00123 }
00125 static
00126 inline
00127 byte_allocator*
00128 destroy( msg_cpp* msg
00129 )
00130 {
00131
00132 byte_allocator* all = msg->_allocator;
00133
00134 msg->~msg_cpp();
00135
00136 return all;
00137 }
00138
00141 void
00142 pack_msg( const room_byte_t* key
00143 );
00146 void
00147 unpack_msg( const room_byte_t* key
00148 );
00151 bool
00152 resize( size_t size_
00153 );
00155 inline
00156 size_t
00157 get_size() const
00158 {
00159 return _size;
00160 }
00162 inline
00163 const ub1_t*
00164 get_body() const
00165 {
00166 return _body;
00167 }
00168
00170 inline
00171 ub1_t*
00172 get_body()
00173 {
00174 return _body;
00175 }
00177 inline
00178 const ub1_t*
00179 get_block() const
00180 {
00181 return _block;
00182 }
00184 inline
00185 ub1_t*
00186 get_block()
00187 {
00188 return _block;
00189 }
00191 static
00192 inline
00193 size_t
00194 estimate_size( size_t size_
00195 )
00196 {
00197 return sizeof(msg_cpp) + block_size(size_);
00198 }
00200 static
00201 inline
00202 size_t
00203 crypt_size( size_t size_
00204 )
00205 {
00206 return size_ ? ALIGNED_MASK_SIZEOF(size_, msg_crypt_block) : 0;
00207 }
00209 static
00210 inline
00211 size_t
00212 block_size( size_t size_
00213 )
00214 {
00215 return crypt_size(size_) + _block_body_offset();
00216 }
00217 private:
00219 static
00220 inline
00221 size_t
00222 _block_body_offset()
00223 {
00224 return sizeof(ub4_t)
00225 + sizeof(msg_cpp)
00226 - sizeof(void*)
00227 - sizeof(byte_allocator*)
00228 - sizeof(void*)
00229 - sizeof(void*);
00230 }
00231
00232 public:
00234 static
00235 inline
00236 ub4_t
00237 reverse32( ub4_t value
00238 )
00239 {
00240 value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
00241 return ((value & 0xFFFF0000) >> 8) | ((value & 0x0000FFFF) << 8);
00242 }
00244 static
00245 inline
00246 ub2_t
00247 reverse16( ub2_t value
00248 )
00249 {
00250 return ((value & 0xFF00) >> 8) | ((value & 0x00FF) << 8);
00251 }
00252
00255 static
00256 inline
00257 size_t
00258 pack32( ub1_t*& dest,
00259 ub4_t x
00260 )
00261 {
00262 size_t size = sizeof(ub4_t);
00263 *(ub4_t*)dest = htonl(x);
00264 dest += size;
00265 return size;
00266 }
00269 static
00270 inline
00271 size_t
00272 unpack32( const ub1_t*& x,
00273 ub4_t& dest
00274 )
00275 {
00276 size_t size = sizeof(ub4_t);
00277 dest = ntohl(*(ub4_t*)x);
00278 x += size;
00279 return size;
00280 }
00281
00284 static
00285 inline
00286 size_t
00287 pack16( ub1_t*& dest,
00288 ub2_t x
00289 )
00290 {
00291 size_t size = sizeof(ub2_t);
00292 *(ub2_t*)dest = htons(x);
00293 dest += size;
00294 return size;
00295 }
00296
00299 static
00300 inline
00301 size_t
00302 unpack16( const ub1_t*& x,
00303 ub2_t& dest
00304 )
00305 {
00306 size_t size = sizeof(ub2_t);
00307 dest = ntohs(*(ub2_t*)x);
00308 x += size;
00309 return size;
00310 }
00311
00314 static
00315 inline
00316 size_t
00317 packaddr( ub1_t*& dest,
00318 const guid_t& x
00319 )
00320 {
00321 size_t size = 0;
00322 size += pack32(dest, x.Data1);
00323 size += pack16(dest, x.Data2);
00324 size += pack16(dest, x.Data3);
00325 for (ub1_t index = 0; index < 8; ++index, size += sizeof(ub1_t))
00326 *dest++ = x.Data4[index];
00327
00328 return size;
00329 }
00330
00333 static
00334 inline
00335 size_t
00336 unpackaddr( const ub1_t*& x,
00337 guid_t& dest
00338 )
00339 {
00340 size_t size = 0;
00341 size += unpack32(x, (ub4_t&)dest.Data1);
00342 size += unpack16(x, (ub2_t&)dest.Data2);
00343 size += unpack16(x, (ub2_t&)dest.Data3);
00344 for (size_t index = 0; index < 8; ++index, size += sizeof(ub1_t))
00345 dest.Data4[index] = *x++;
00346
00347 return size;
00348 }
00349
00352 static
00353 inline
00354 size_t
00355 pack64( ub1_t*& dest,
00356 const ub8_t& x
00357 )
00358 {
00359 size_t size = sizeof(ub8_t);
00360 *(ub4_t*)dest = htonl((ub4_t)(x & 0x00000000ffffffff));
00361 *(ub4_t*)(dest + sizeof(ub4_t)) = htonl((ub4_t)((x >> 32) & 0x00000000ffffffff));
00362 dest += size;
00363 return size;
00364 }
00365
00368 static
00369 inline
00370 size_t
00371 unpack64( const ub1_t*& x,
00372 ub8_t& dest
00373 )
00374 {
00375 size_t size = sizeof(ub8_t);
00376 dest = (ub8_t)ntohl(*(ub4_t*)x) + ((ub8_t)ntohl(*(ub4_t*)(x + sizeof(ub4_t))) << 32);
00377 x += size;
00378 return size;
00379 }
00380
00381 public:
00382 ub4_t _type;
00383 guid_t _marker;
00384 sb8_t _timestamp;
00385 guid_t _sender;
00386 guid_t _receiver;
00387 guid_t _sessionid;
00388 private:
00389 ub4_t _size;
00390 byte_allocator* _allocator;
00391 ub1_t* _body;
00392 ub1_t* _block;
00393 };
00394
00397 class msg_pack
00398 {
00399 public:
00401 static
00402 void
00403 make_error_msg( msg_cpp* msg,
00404 const char* text
00405 );
00408 static
00409 void
00410 make_reply_msg( const msg_cpp* msg,
00411 msg_cpp* reply
00412 );
00413 };
00414
00417 class conf_peer
00418 {
00419 public:
00421 conf_peer() :
00422 _support_crypt(false),
00423 _crypt(2)
00424 {
00425 _address = null_uuid;
00426 }
00428 conf_peer(const conf_peer& x) :
00429 _crypt(x._crypt)
00430 {
00431 *this = x;
00432 }
00434 conf_peer&
00435 operator=(const conf_peer& x)
00436 {
00437 if (this != &x)
00438 {
00439 _address = x._address;
00440 _support_crypt = x._support_crypt;
00441 _crypt = x._crypt;
00442 }
00443
00444 return *this;
00445 }
00446
00447
00448 guid_t _address;
00449 bool _support_crypt;
00450 room_byte_t _crypt;
00451 };
00452
00455 typedef list< conf_peer > msg_peer_list_t;
00456
00459 class conf_listener
00460 {
00461 public:
00463 conf_listener() :
00464 _type(unknown),
00465 _connections(0),
00466 _ping((ub4_t)INFINITE),
00467 _port(0),
00468 _support_crypt(false),
00469 _crypt_accept(2)
00470 {
00471 }
00473 conf_listener(const conf_listener& x) :
00474 _crypt_accept(x._crypt_accept)
00475 {
00476 *this = x;
00477 }
00479 conf_listener&
00480 operator=(const conf_listener& x)
00481 {
00482 if (this != &x)
00483 {
00484 _type = x._type;
00485 _address = x._address;
00486 _port = x._port;
00487 _network = x._network;
00488 _info = x._info;
00489 _connections = x._connections;
00490 _ping = x._ping;
00491 _support_crypt = x._support_crypt;
00492 _crypt_accept = x._crypt_accept;
00493 _accept = x._accept;
00494 _reject = x._reject;
00495 }
00496
00497 return *this;
00498 }
00499
00500 transport_type _type;
00501 guid_t _address;
00502 ub2_t _port;
00503 string_t _network;
00504 string_t _info;
00505 ub4_t _ping;
00506 bool _support_crypt;
00507 ub4_t _connections;
00508 room_byte_t _crypt_accept;
00509 msg_peer_list_t _accept;
00510 msg_peer_list_t _reject;
00511 };
00512
00515 class conf_connection
00516 {
00517 public:
00519 conf_connection() :
00520 _type(unknown),
00521 _ping((ub4_t)INFINITE),
00522 _port(0),
00523 _support_crypt(false),
00524 _crypt_private(2),
00525 _crypt_external(2)
00526 {
00527 _address = null_uuid; _session = null_uuid;
00528 }
00530 conf_connection(const conf_connection& x) :
00531 _crypt_private(x._crypt_private),
00532 _crypt_external(x._crypt_external)
00533 {
00534 *this = x;
00535 }
00537 conf_connection& operator=(const conf_connection& x)
00538 {
00539 if (this != &x)
00540 {
00541 _type = x._type;
00542 _address = x._address;
00543 _port = x._port;
00544 _session = x._session;
00545 _info = x._info;
00546 _network = x._network;
00547 _ping = x._ping;
00548 _support_crypt = x._support_crypt;
00549 _crypt_private = x._crypt_private;
00550 _crypt_external = x._crypt_external;
00551 }
00552
00553 return *this;
00554 }
00555
00557 conf_connection& operator=(const conf_listener& x)
00558 {
00559 _type = x._type;
00560 _address = x._address;
00561 _port = x._port;
00562 _info = x._info;
00563 _network = x._network;
00564 _ping = x._ping;
00565
00566 return *this;
00567 }
00568
00569 transport_type _type;
00570 guid_t _address;
00571 ub2_t _port;
00572 string_t _network;
00573 string_t _info;
00574 ub4_t _ping;
00575 bool _support_crypt;
00576 room_byte_t _crypt_private;
00577 room_byte_t _crypt_external;
00578 guid_t _session;
00579 };
00580
00581
00584 typedef list< conf_listener > msg_listener_list_t;
00587 typedef list< conf_connection > msg_connection_list_t;
00588
00591 class conf_unit
00592 {
00593 public:
00595 conf_unit()
00596 {
00597 clear();
00598 }
00600 conf_unit(const conf_unit& x)
00601 {
00602 *this = x;
00603 }
00605 conf_unit& operator=(const conf_unit& x)
00606 {
00607 if (this != &x)
00608 {
00609 clear();
00610 _listeners = x._listeners;
00611 _connections = x._connections;
00612 }
00613
00614 return *this;
00615 }
00616
00618 void clear()
00619 {
00620 _listeners.clear();
00621 _connections.clear();
00622 }
00623
00624 msg_listener_list_t _listeners;
00625 msg_connection_list_t _connections;
00626 };
00627
00628 #pragma pack()
00629 END_TERIMBER_NAMESPACE
00630
00631 #endif // _terimber_msg_cpp_h_
00632