00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef datagram_h
00023 #define datagram_h
00024
00025 #ifndef _REENTRANT
00026 #define _REENTRANT
00027 #endif
00028
00029 #include "config.h"
00030 #include <netinet/in.h>
00031 #include <iostream>
00032 #include "queue.h"
00033 #include "util.h"
00034 #include <stdexcept>
00035
00036 using std::exception;
00037 using std::ostream;
00038
00039 namespace karoo {
00040
00044 enum datagram_status_enum {
00045 DATAGRAM_OK = 0,
00046 DATAGRAM_RECEIVE_FAILED,
00047 DATAGRAM_SEND_FAILED,
00048 DATAGRAM_UNINITIALISED,
00049 DATAGRAM_CREATE_FAILED,
00050 DATAGRAM_BIND_FAILED
00051 };
00052
00053 class bad_address : public exception {
00054 char* str;
00055 public:
00056 bad_address() throw()
00057 : exception()
00058 {
00059 str = NULL;
00060 }
00061 bad_address(const text& s) throw()
00062 : exception()
00063 {
00064 try {
00065 this->str = s.new_clone();
00066 }
00067 catch (...) {
00068 str = NULL;
00069 }
00070 }
00071 bad_address(const bad_address& ref) throw()
00072 : exception()
00073 {
00074 try {
00075 if (ref.str) {
00076 size_t len = strlen(ref.str)+1;
00077 this->str = new char[len];
00078 memcpy(this->str, ref.str, len);
00079 return;
00080 }
00081 }
00082 catch (...) {}
00083 str = NULL;
00084 }
00085 bad_address& operator=(const bad_address& ref) throw()
00086 {
00087 try {
00088 if (str) {
00089 delete [] str;
00090 str = NULL;
00091 }
00092 if (ref.str) {
00093 size_t len = strlen(ref.str)+1;
00094 this->str = new char[len];
00095 memcpy(this->str, ref.str, len);
00096 }
00097 else {
00098 str = NULL;
00099 }
00100 }
00101 catch (...) {
00102 str = NULL;
00103 }
00104 return *this;
00105 }
00106 virtual ~bad_address() throw()
00107 {
00108 try {
00109 if (str)
00110 delete [] str;
00111 }
00112 catch (...) {}
00113 }
00114 virtual const char* what() const throw()
00115 {
00116 if (str) {
00117 return str;
00118 }
00119 else {
00120 return "";
00121 }
00122 }
00123 };
00124
00128 class datagram_status
00129 {
00130 private:
00131 mutable karoo_mutex sem;
00132 enum datagram_status_enum status;
00133 public:
00137 datagram_status();
00142 datagram_status(const enum datagram_status_enum ref);
00147 datagram_status(const datagram_status& ref);
00148
00149 virtual ~datagram_status();
00150
00155 enum datagram_status_enum operator=(const datagram_status& ref);
00160 enum datagram_status_enum operator=(enum datagram_status_enum ref);
00161
00166 operator bool() const;
00170 operator enum datagram_status_enum() const;
00172 operator text() const;
00173 };
00174
00178 extern ostream& operator << (ostream& os, const datagram_status& s);
00179 extern logstream& operator << (logstream& os, const datagram_status& s);
00180
00185 class datagram_message : public pebble
00186 {
00187 protected:
00189 size_t addrlen;
00191 struct sockaddr* addr;
00193 size_t size;
00195 size_t alloc_size;
00197 uint8_t* data;
00198 friend class datagram_server;
00199 friend class datagram_client;
00200 public:
00204 datagram_message(size_t alloc_size);
00213 datagram_message(size_t alloc_size, const text& ip, int port);
00223 datagram_message(const void* data, size_t size, const text& ip, int port);
00224 virtual ~datagram_message();
00225
00235 virtual datagram_message* clone(size_t alloc_size = 0) const = 0;
00246 virtual datagram_message* clone(int port, size_t alloc_size = 0) const = 0;
00247
00248
00252 void init(const text& ip, int port);
00253
00255 size_t getSize() const { return size; }
00256
00258 uint8_t* getDataPtr() { return data; }
00259 };
00260
00270 class datagram_message_factory
00271 {
00272 private:
00273 protected:
00274 public:
00275 datagram_message_factory() {}
00276 virtual ~datagram_message_factory() {}
00277
00278 virtual datagram_message* create_datagram_message(size_t alloc_size) = 0;
00279 };
00280
00286 class datagram_server : public pebble
00287 {
00288 private:
00289 protected:
00291 int port;
00296 struct sockaddr_in addr;
00298 int sock;
00302 datagram_status status;
00304 size_t message_size;
00314 exeque* output_queue;
00323 exeque* run_queue;
00328 datagram_message_factory* factory;
00330 mutable karoo_mutex running_sem;
00332 bool running;
00333
00335 unsigned fail_count;
00336
00340 log logger;
00341
00346 void close();
00347
00354 datagram_status read(datagram_message* message);
00355
00356 public:
00357 datagram_server(int port, size_t message_size, exeque* output_queue, exeque* run_queue, datagram_message_factory* factory);
00358 virtual ~datagram_server();
00359
00364 void setLogger(const log& logger);
00365
00373 datagram_status create();
00385 void run();
00386
00390 void start();
00394 void stop();
00395
00399 datagram_status getStatus() const { return status; }
00400 };
00401
00406 class datagram_client
00407 {
00408 private:
00409 protected:
00411 karoo_mutex sem;
00413 int sock;
00415 datagram_status status;
00417 log logger;
00418
00420 void close();
00421 public:
00422 datagram_client();
00423 virtual ~datagram_client();
00424
00429 void setLogger(const log& logger) { this->logger = logger; }
00430
00432 datagram_status create();
00439 datagram_status write(datagram_message* message);
00441 datagram_status getStatus() const { return status; }
00442 };
00443
00444 }
00445
00446 #endif