From b5a1af6f999820564ead4867b1e5d5574778ee56 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Mon, 31 Oct 2005 21:02:30 +0000 Subject: initial import git-svn-id: http://svn.pjsip.org/repos/pjproject/main@1 74dad513-b988-da41-8d7b-12977e46ad98 --- pjlib/src/pj++/compiletest.cpp | 44 ++++++ pjlib/src/pj++/hash.hpp | 71 +++++++++ pjlib/src/pj++/ioqueue.hpp | 172 +++++++++++++++++++++ pjlib/src/pj++/list.hpp | 182 ++++++++++++++++++++++ pjlib/src/pj++/os.hpp | 342 +++++++++++++++++++++++++++++++++++++++++ pjlib/src/pj++/pj++.cpp | 15 ++ pjlib/src/pj++/pool.hpp | 84 ++++++++++ pjlib/src/pj++/proactor.cpp | 296 +++++++++++++++++++++++++++++++++++ pjlib/src/pj++/proactor.hpp | 86 +++++++++++ pjlib/src/pj++/scanner.hpp | 171 +++++++++++++++++++++ pjlib/src/pj++/sock.hpp | 194 +++++++++++++++++++++++ pjlib/src/pj++/string.hpp | 247 +++++++++++++++++++++++++++++ pjlib/src/pj++/timer.hpp | 105 +++++++++++++ pjlib/src/pj++/tree.hpp | 107 +++++++++++++ pjlib/src/pj++/types.hpp | 59 +++++++ 15 files changed, 2175 insertions(+) create mode 100644 pjlib/src/pj++/compiletest.cpp create mode 100644 pjlib/src/pj++/hash.hpp create mode 100644 pjlib/src/pj++/ioqueue.hpp create mode 100644 pjlib/src/pj++/list.hpp create mode 100644 pjlib/src/pj++/os.hpp create mode 100644 pjlib/src/pj++/pj++.cpp create mode 100644 pjlib/src/pj++/pool.hpp create mode 100644 pjlib/src/pj++/proactor.cpp create mode 100644 pjlib/src/pj++/proactor.hpp create mode 100644 pjlib/src/pj++/scanner.hpp create mode 100644 pjlib/src/pj++/sock.hpp create mode 100644 pjlib/src/pj++/string.hpp create mode 100644 pjlib/src/pj++/timer.hpp create mode 100644 pjlib/src/pj++/tree.hpp create mode 100644 pjlib/src/pj++/types.hpp (limited to 'pjlib/src/pj++') diff --git a/pjlib/src/pj++/compiletest.cpp b/pjlib/src/pj++/compiletest.cpp new file mode 100644 index 00000000..84e80aeb --- /dev/null +++ b/pjlib/src/pj++/compiletest.cpp @@ -0,0 +1,44 @@ +/* $Header: /pjproject/pjlib/src/pj++/compiletest.cpp 4 8/24/05 10:29a Bennylp $ */ +#include + + +#if 0 +struct MyNode +{ + PJ_DECL_LIST_MEMBER(struct MyNode) + int data; +}; + +int test() +{ + typedef PJ_List MyList; + MyList list; + MyList::iterator it, end = list.end(); + + for (it=list.begin(); it!=end; ++it) { + MyNode *n = *it; + } + + return 0; +} + +int test_scan() +{ + PJ_Scanner scan; + PJ_String s; + PJ_CharSpec cs; + + scan.get(&cs, &s); + return 0; +} + +int test_scan_c() +{ + pj_scanner scan; + pj_str_t s; + pj_char_spec cs; + + pj_scan_get(&scan, cs, &s); + return 0; +} +#endif diff --git a/pjlib/src/pj++/hash.hpp b/pjlib/src/pj++/hash.hpp new file mode 100644 index 00000000..d1fd162f --- /dev/null +++ b/pjlib/src/pj++/hash.hpp @@ -0,0 +1,71 @@ +/* $Header: /pjproject/pjlib/src/pj++/hash.hpp 5 8/24/05 10:29a Bennylp $ */ +#ifndef __PJPP_HASH_H__ +#define __PJPP_HASH_H__ + +#include +#include + +class PJ_Hash_Table +{ +public: + class iterator + { + public: + iterator() {} + explicit iterator(pj_hash_table_t *h, pj_hash_iterator_t *i) : ht_(h), it_(i) {} + iterator(const iterator &rhs) : ht_(rhs.ht_), it_(rhs.it_) {} + void operator++() { it_ = pj_hash_next(ht_, it_); } + bool operator==(const iterator &rhs) { return ht_ == rhs.ht_ && it_ == rhs.it_; } + iterator & operator=(const iterator &rhs) { ht_=rhs.ht_; it_=rhs.it_; return *this; } + private: + pj_hash_table_t *ht_; + pj_hash_iterator_t it_val_; + pj_hash_iterator_t *it_; + + friend class PJ_Hash_Table; + }; + + static PJ_Hash_Table *create(PJ_Pool *pool, unsigned size) + { + return (PJ_Hash_Table*) pj_hash_create(pool->pool_(), size); + } + + static pj_uint32_t calc(pj_uint32_t initial_hval, const void *key, unsigned keylen) + { + return pj_hash_calc(initial_hval, key, keylen); + } + + pj_hash_table_t *hash_table_() + { + return (pj_hash_table_t*)this; + } + + void *get(const void *key, unsigned keylen) + { + return pj_hash_get(this->hash_table_(), key, keylen); + } + + void set(PJ_Pool *pool, const void *key, unsigned keylen, void *value) + { + pj_hash_set(pool->pool_(), this->hash_table_(), key, keylen, value); + } + + unsigned count() + { + return pj_hash_count(this->hash_table_()); + } + + iterator begin() + { + iterator it(this->hash_table_(), NULL); + it.it_ = pj_hash_first(this->hash_table_(), &it.it_val_); + return it; + } + + iterator end() + { + return iterator(this->hash_table_(), NULL); + } +}; + +#endif /* __PJPP_HASH_H__ */ diff --git a/pjlib/src/pj++/ioqueue.hpp b/pjlib/src/pj++/ioqueue.hpp new file mode 100644 index 00000000..5ecb34ce --- /dev/null +++ b/pjlib/src/pj++/ioqueue.hpp @@ -0,0 +1,172 @@ +/* $Header: /pjproject/pjlib/src/pj++/ioqueue.hpp 4 8/24/05 10:29a Bennylp $ */ +#ifndef __PJPP_IOQUEUE_H__ +#define __PJPP_IOQUEUE_H__ + +#include +#include +#include +#include + +class PJ_IOQueue; + +class PJ_IOQueue_Event_Handler +{ +public: + virtual ~PJ_IOQueue_Event_Handler() + { + } + + pj_ioqueue_key_t* get_key() const + { + return key_; + } + +protected: + // + // Override this to get notification from I/O Queue + // + virtual void on_read_complete(pj_ssize_t bytes_read) + { + } + + virtual void on_write_complete(pj_ssize_t bytes_sent) + { + } + + virtual void on_accept_complete(int status) + { + } + + virtual void on_connect_complete(int status) + { + } + +protected: + PJ_IOQueue_Event_Handler() + : ioqueue_(NULL), key_(NULL) + { + } + +private: + PJ_IOQueue *ioqueue_; + pj_ioqueue_key_t *key_; + + static void read_complete_cb(pj_ioqueue_key_t *key, pj_ssize_t bytes_read) + { + PJ_IOQueue_Event_Handler *handler = + (PJ_IOQueue_Event_Handler*)pj_ioqueue_get_user_data(key); + handler->on_read_complete(bytes_read); + } + + static void write_complete_cb(pj_ioqueue_key_t *key, pj_ssize_t bytes_sent); + static void accept_complete_cb(pj_ioqueue_key_t *key, int status); + static void connect_complete_cb(pj_ioqueue_key_t *key, int status); + + friend class PJ_IOQueue; +}; + + +class PJ_IOQueue +{ + typedef pj_ioqueue_t *B_; + +public: + typedef pj_ioqueue_key_t Key; + + enum Operation + { + OP_NONE = PJ_IOQUEUE_OP_NONE, + OP_READ = PJ_IOQUEUE_OP_READ, + OP_RECV_FROM = PJ_IOQUEUE_OP_RECV_FROM, + OP_WRITE = PJ_IOQUEUE_OP_WRITE, + OP_SEND_TO = PJ_IOQUEUE_OP_SEND_TO, +#if PJ_HAS_TCP + OP_ACCEPT = PJ_IOQUEUE_OP_ACCEPT, + OP_CONNECT = PJ_IOQUEUE_OP_CONNECT, +#endif + }; + + enum Status + { + IS_PENDING = PJ_IOQUEUE_PENDING + }; + + static PJ_IOQueue *create(PJ_Pool *pool, pj_size_t max_fd) + { + return (PJ_IOQueue*) pj_ioqueue_create(pool->pool_(), max_fd); + } + + operator B_() + { + return (pj_ioqueue_t*)(PJ_IOQueue*)this; + } + + pj_ioqueue_t *ioq_() + { + return (B_)this; + } + + void destroy() + { + pj_ioqueue_destroy(this->ioq_()); + } + + Key *register_handle(PJ_Pool *pool, pj_oshandle_t hnd, void *user_data) + { + return pj_ioqueue_register(pool->pool_(), this->ioq_(), hnd, user_data); + } + + Key *register_socket(PJ_Pool *pool, pj_sock_t hnd, void *user_data) + { + return pj_ioqueue_register(pool->pool_(), this->ioq_(), (pj_oshandle_t)hnd, user_data); + } + + pj_status_t unregister(Key *key) + { + return pj_ioqueue_unregister(this->ioq_(), key); + } + + void *get_user_data(Key *key) + { + return pj_ioqueue_get_user_data(key); + } + + int poll(Key **key, pj_ssize_t *bytes_status, Operation *op, const PJ_Time_Val *timeout) + { + return pj_ioqueue_poll(this->ioq_(), key, bytes_status, (pj_ioqueue_operation_e*)op, timeout); + } + +#if PJ_HAS_TCP + pj_status_t connect(Key *key, const pj_sockaddr_t *addr, int addrlen) + { + return pj_ioqueue_connect(this->ioq_(), key, addr, addrlen); + } + + pj_status_t accept(Key *key, PJ_Socket *sock, pj_sockaddr_t *local, pj_sockaddr_t *remote, int *addrlen) + { + return pj_ioqueue_accept(this->ioq_(), key, &sock->get_handle(), local, remote, addrlen); + } +#endif + + int read(Key *key, void *buf, pj_size_t len) + { + return pj_ioqueue_read(this->ioq_(), key, buf, len); + } + + int recvfrom(Key *key, void *buf, pj_size_t len, pj_sockaddr_t *addr, int *addrlen) + { + return pj_ioqueue_recvfrom(this->ioq_(), key, buf, len, addr, addrlen); + } + + int write(Key *key, const void *data, pj_size_t len) + { + return pj_ioqueue_write(this->ioq_(), key, data, len); + } + + int sendto(Key *key, const void *data, pj_size_t len, const pj_sockaddr_t *addr, int addrlen) + { + return pj_ioqueue_sendto(this->ioq_(), key, data, len, addr, addrlen); + } +}; + +#endif /* __PJPP_IOQUEUE_H__ */ diff --git a/pjlib/src/pj++/list.hpp b/pjlib/src/pj++/list.hpp new file mode 100644 index 00000000..76452917 --- /dev/null +++ b/pjlib/src/pj++/list.hpp @@ -0,0 +1,182 @@ +/* $Header: /pjproject/pjlib/src/pj++/list.hpp 2 2/24/05 11:23a Bennylp $ */ +#ifndef __PJPP_LIST_H__ +#define __PJPP_LIST_H__ + +#include + +template +struct PJ_List_Node +{ + PJ_DECL_LIST_MEMBER(T) +}; + + +template +class PJ_List +{ +public: + PJ_List() { pj_list_init(&root_); if (0) compiletest(); } + ~PJ_List() {} + + class const_iterator + { + public: + const_iterator() : node_(NULL) {} + const_iterator(const Node *nd) : node_((Node*)nd) {} + const Node * operator *() { return node_; } + const Node * operator -> () { return node_; } + const_iterator operator++() { return const_iterator(node_->next); } + bool operator==(const const_iterator &rhs) { return node_ == rhs.node_; } + bool operator!=(const const_iterator &rhs) { return node_ != rhs.node_; } + + protected: + Node *node_; + }; + + class iterator : public const_iterator + { + public: + iterator() {} + iterator(Node *nd) : const_iterator(nd) {} + Node * operator *() { return node_; } + Node * operator -> () { return node_; } + iterator operator++() { return iterator(node_->next); } + bool operator==(const iterator &rhs) { return node_ == rhs.node_; } + bool operator!=(const iterator &rhs) { return node_ != rhs.node_; } + }; + + bool empty() const + { + return pj_list_empty(&root_); + } + + iterator begin() + { + return iterator(root_.next); + } + + const_iterator begin() const + { + return const_iterator(root_.next); + } + + const_iterator end() const + { + return const_iterator((Node*)&root_); + } + + iterator end() + { + return iterator((Node*)&root_); + } + + void insert_before (iterator &pos, Node *node) + { + pj_list_insert_before( *pos, node ); + } + + void insert_after(iterator &pos, Node *node) + { + pj_list_insert_after(*pos, node); + } + + void merge_first(Node *list2) + { + pj_list_merge_first(&root_, list2); + } + + void merge_last(PJ_List *list) + { + pj_list_merge_last(&root_, &list->root_); + } + + void insert_nodes_before(iterator &pos, PJ_List *list2) + { + pj_list_insert_nodes_before(*pos, &list2->root_); + } + + void insert_nodes_after(iterator &pos, PJ_List *list2) + { + pj_list_insert_nodes_after(*pos, &list2->root_); + } + + void erase(iterator &it) + { + pj_list_erase(*it); + } + + Node *front() + { + return root_.next; + } + + const Node *front() const + { + return root_.next; + } + + void pop_front() + { + pj_list_erase(root_.next); + } + + Node *back() + { + return root_.prev; + } + + const Node *back() const + { + return root_.prev; + } + + void pop_back() + { + pj_list_erase(root_.prev); + } + + iterator find(Node *node) + { + Node *n = pj_list_find_node(&root_, node); + return n ? iterator(n) : end(); + } + + const_iterator find(Node *node) const + { + Node *n = pj_list_find_node(&root_, node); + return n ? const_iterator(n) : end(); + } + + void push_back(Node *node) + { + pj_list_insert_after(root_.prev, node); + } + + void push_front(Node *node) + { + pj_list_insert_before(root_.next, node); + } + + void clear() + { + root_.next = &root_; + root_.prev = &root_; + } + +private: + struct RootNode + { + PJ_DECL_LIST_MEMBER(Node) + } root_; + + void compiletest() + { + // If you see error in this line, + // it's because Node is not derived from PJ_List_Node. + Node *n = (Node*)0; + n = n->next; n = n->prev; + } +}; + + +#endif /* __PJPP_LIST_H__ */ diff --git a/pjlib/src/pj++/os.hpp b/pjlib/src/pj++/os.hpp new file mode 100644 index 00000000..c3827528 --- /dev/null +++ b/pjlib/src/pj++/os.hpp @@ -0,0 +1,342 @@ +/* $Header: /pjproject/pjlib/src/pj++/os.hpp 2 2/24/05 11:23a Bennylp $ */ +#ifndef __PJPP_OS_H__ +#define __PJPP_OS_H__ + +#include +#include +#include + +class PJ_Thread +{ +public: + enum Flags + { + FLAG_SUSPENDED = PJ_THREAD_SUSPENDED + }; + + static PJ_Thread *create( PJ_Pool *pool, const char *thread_name, + pj_thread_proc *proc, void *arg, + pj_size_t stack_size, void *stack_ptr, + unsigned flags) + { + return (PJ_Thread*) pj_thread_create( pool->pool_(), thread_name, proc, arg, stack_size, stack_ptr, flags); + } + + static PJ_Thread *register_current_thread(const char *name, pj_thread_desc desc) + { + return (PJ_Thread*) pj_thread_register(name, desc); + } + + static PJ_Thread *get_current_thread() + { + return (PJ_Thread*) pj_thread_this(); + } + + static pj_status_t sleep(unsigned msec) + { + return pj_thread_sleep(msec); + } + + static pj_status_t usleep(unsigned usec) + { + return pj_thread_usleep(usec); + } + + pj_thread_t *pj_thread_t_() + { + return (pj_thread_t*)this; + } + + const char *get_name() + { + return pj_thread_get_name( this->pj_thread_t_() ); + } + + pj_status_t resume() + { + return pj_thread_resume( this->pj_thread_t_() ); + } + + pj_status_t join() + { + return pj_thread_join( this->pj_thread_t_() ); + } + + pj_status_t destroy() + { + return pj_thread_destroy( this->pj_thread_t_() ); + } +}; + + +class PJ_Thread_Local +{ +public: + static PJ_Thread_Local *alloc() + { + long index = pj_thread_local_alloc(); + return index < 0 ? NULL : (PJ_Thread_Local*)index; + } + void free() + { + pj_thread_local_free( this->tls_() ); + } + + long tls_() const + { + return (long)this; + } + + void set(void *value) + { + pj_thread_local_set( this->tls_(), value ); + } + + void *get() + { + return pj_thread_local_get( this->tls_() ); + } +}; + + +class PJ_Atomic +{ +public: + static PJ_Atomic *create(PJ_Pool *pool, long initial) + { + return (PJ_Atomic*) pj_atomic_create(pool->pool_(), initial); + } + + pj_atomic_t *pj_atomic_t_() + { + return (pj_atomic_t*)this; + } + + pj_status_t destroy() + { + return pj_atomic_destroy( this->pj_atomic_t_() ); + } + + long set(long val) + { + return pj_atomic_set( this->pj_atomic_t_(), val); + } + + long get() + { + return pj_atomic_get( this->pj_atomic_t_() ); + } + + long inc() + { + return pj_atomic_inc( this->pj_atomic_t_() ); + } + + long dec() + { + return pj_atomic_dec( this->pj_atomic_t_() ); + } +}; + + +class PJ_Mutex +{ +public: + enum Type + { + DEFAULT = PJ_MUTEX_DEFAULT, + SIMPLE = PJ_MUTEX_SIMPLE, + RECURSE = PJ_MUTEX_RECURSE, + }; + + static PJ_Mutex *create( PJ_Pool *pool, const char *name, Type type) + { + return (PJ_Mutex*) pj_mutex_create( pool->pool_(), name, type); + } + + pj_mutex_t *pj_mutex_() + { + return (pj_mutex_t*)this; + } + + pj_status_t destroy() + { + return pj_mutex_destroy( this->pj_mutex_() ); + } + + pj_status_t lock() + { + return pj_mutex_lock( this->pj_mutex_() ); + } + + pj_status_t unlock() + { + return pj_mutex_unlock( this->pj_mutex_() ); + } + + pj_status_t trylock() + { + return pj_mutex_trylock( this->pj_mutex_() ); + } + +#if PJ_DEBUG + pj_status_t is_locked() + { + return pj_mutex_is_locked( this->pj_mutex_() ); + } +#endif +}; + + +class PJ_Semaphore +{ +public: + static PJ_Semaphore *create( PJ_Pool *pool, const char *name, unsigned initial, unsigned max) + { + return (PJ_Semaphore*) pj_sem_create( pool->pool_(), name, initial, max); + } + + pj_sem_t *pj_sem_t_() + { + return (pj_sem_t*)this; + } + + pj_status_t destroy() + { + return pj_sem_destroy(this->pj_sem_t_()); + } + + pj_status_t wait() + { + return pj_sem_wait(this->pj_sem_t_()); + } + + pj_status_t lock() + { + return wait(); + } + + pj_status_t trywait() + { + return pj_sem_trywait(this->pj_sem_t_()); + } + + pj_status_t trylock() + { + return trywait(); + } + + pj_status_t post() + { + return pj_sem_post(this->pj_sem_t_()); + } + + pj_status_t unlock() + { + return post(); + } +}; + + +class PJ_Event +{ +public: + static PJ_Event *create( PJ_Pool *pool, const char *name, bool manual_reset, bool initial) + { + return (PJ_Event*) pj_event_create(pool->pool_(), name, manual_reset, initial); + } + + pj_event_t *pj_event_t_() + { + return (pj_event_t*)this; + } + + pj_status_t destroy() + { + return pj_event_destroy(this->pj_event_t_()); + } + + pj_status_t wait() + { + return pj_event_wait(this->pj_event_t_()); + } + + pj_status_t trywait() + { + return pj_event_trywait(this->pj_event_t_()); + } + + pj_status_t set() + { + return pj_event_set(this->pj_event_t_()); + } + + pj_status_t pulse() + { + return pj_event_pulse(this->pj_event_t_()); + } + + pj_status_t reset() + { + return pj_event_reset(this->pj_event_t_()); + } +}; + +class PJ_OS +{ +public: + static pj_status_t gettimeofday( PJ_Time_Val *tv ) + { + return pj_gettimeofday(tv); + } + + static pj_status_t time_decode( const PJ_Time_Val *tv, pj_parsed_time *pt ) + { + return pj_time_decode(tv, pt); + } + + static pj_status_t time_encode(const pj_parsed_time *pt, PJ_Time_Val *tv) + { + return pj_time_encode(pt, tv); + } + + static pj_status_t time_local_to_gmt( PJ_Time_Val *tv ) + { + return pj_time_local_to_gmt( tv ); + } + + static pj_status_t time_gmt_to_local( PJ_Time_Val *tv) + { + return pj_time_gmt_to_local( tv ); + } +}; + + +inline pj_status_t PJ_Time_Val::gettimeofday() +{ + return PJ_OS::gettimeofday(this); +} + +inline pj_parsed_time PJ_Time_Val::decode() +{ + pj_parsed_time pt; + PJ_OS::time_decode(this, &pt); + return pt; +} + +inline pj_status_t PJ_Time_Val::encode(const pj_parsed_time *pt) +{ + return PJ_OS::time_encode(pt, this); +} + +inline pj_status_t PJ_Time_Val::to_gmt() +{ + return PJ_OS::time_local_to_gmt(this); +} + +inline pj_status_t PJ_Time_Val::to_local() +{ + return PJ_OS::time_gmt_to_local(this); +} + +#endif /* __PJPP_OS_H__ */ diff --git a/pjlib/src/pj++/pj++.cpp b/pjlib/src/pj++/pj++.cpp new file mode 100644 index 00000000..1a41ec32 --- /dev/null +++ b/pjlib/src/pj++/pj++.cpp @@ -0,0 +1,15 @@ +/* $Header: /pjproject/pjlib/src/pj++/pj++.cpp 4 4/17/05 11:59a Bennylp $ */ +#include +#include +#include + +void PJ_Scanner::syntax_error_handler_throw_pj(pj_scanner *) +{ + PJ_THROW( PJ_Scanner::SYNTAX_ERROR ); +} + +void PJ_Timer_Entry::timer_heap_callback(pj_timer_heap_t *, pj_timer_entry *e) +{ + PJ_Timer_Entry *entry = static_cast(e); + entry->on_timeout(); +} diff --git a/pjlib/src/pj++/pool.hpp b/pjlib/src/pj++/pool.hpp new file mode 100644 index 00000000..9ceffa7d --- /dev/null +++ b/pjlib/src/pj++/pool.hpp @@ -0,0 +1,84 @@ +/* $Header: /pjproject/pjlib/src/pj++/pool.hpp 4 8/24/05 10:29a Bennylp $ */ +#ifndef __PJPP_POOL_H__ +#define __PJPP_POOL_H__ + +#include + +class PJ_Pool +{ +public: + const char *getobjname() const + { + return pj_pool_getobjname(this->pool_()); + } + + pj_pool_t *pool_() + { + return (pj_pool_t*)this; + } + + const pj_pool_t *pool_() const + { + return (const pj_pool_t*)this; + } + + void release() + { + pj_pool_release(this->pool_()); + } + + void reset() + { + pj_pool_reset(this->pool_()); + } + + pj_size_t get_capacity() + { + pj_pool_get_capacity(this->pool_()); + } + + pj_size_t get_used_size() + { + pj_pool_get_used_size(this->pool_()); + } + + void *alloc(pj_size_t size) + { + return pj_pool_alloc(this->pool_(), size); + } + + void *calloc(pj_size_t count, pj_size_t elem) + { + return pj_pool_calloc(this->pool_(), count, elem); + } +}; + +class PJ_Caching_Pool +{ +public: + void init(pj_size_t max_capacity, + const pj_pool_factory_policy *pol=&pj_pool_factory_default_policy) + { + pj_caching_pool_init(&cp_, pol, max_capacity); + } + + void destroy() + { + pj_caching_pool_destroy(&cp_); + } + + PJ_Pool *create_pool(const char *name, pj_size_t initial_size, pj_size_t increment_size, pj_pool_callback *callback) + { + return (PJ_Pool*) (*cp_.factory.create_pool)(&cp_.factory, name, initial_size, increment_size, callback); + } + + void release_pool( PJ_Pool *pool ) + { + pj_pool_release(pool->pool_()); + } + +private: + pj_caching_pool cp_; +}; + +#endif /* __PJPP_POOL_H__ */ diff --git a/pjlib/src/pj++/proactor.cpp b/pjlib/src/pj++/proactor.cpp new file mode 100644 index 00000000..58c342e0 --- /dev/null +++ b/pjlib/src/pj++/proactor.cpp @@ -0,0 +1,296 @@ +/* $Header: /pjproject-0.3/pjlib/src/pj++/proactor.cpp 7 10/29/05 11:51a Bennylp $ */ +#include +#include // memset + +static struct pj_ioqueue_callback ioqueue_cb = +{ + &PJ_Event_Handler::read_complete_cb, + &PJ_Event_Handler::write_complete_cb, + &PJ_Event_Handler::accept_complete_cb, + &PJ_Event_Handler::connect_complete_cb, +}; + +PJ_Event_Handler::PJ_Event_Handler() +: proactor_(NULL), key_(NULL) +{ + pj_memset(&timer_, 0, sizeof(timer_)); + timer_.user_data = this; + timer_.cb = &timer_callback; +} + +PJ_Event_Handler::~PJ_Event_Handler() +{ +} + +#if PJ_HAS_TCP +bool PJ_Event_Handler::connect(const PJ_INET_Addr &addr) +{ + pj_assert(key_ != NULL && proactor_ != NULL); + + if (key_ == NULL || proactor_ == NULL) + return false; + + int status = pj_ioqueue_connect(proactor_->get_io_queue(), key_, + &addr, sizeof(PJ_INET_Addr)); + if (status == 0) { + on_connect_complete(0); + return true; + } else if (status == PJ_IOQUEUE_PENDING) { + return true; + } else { + return false; + } +} + +bool PJ_Event_Handler::accept(PJ_Socket *sock, PJ_INET_Addr *local, PJ_INET_Addr *remote) +{ + pj_assert(key_ != NULL && proactor_ != NULL); + + if (key_ == NULL || proactor_ == NULL) + return false; + + int status = pj_ioqueue_accept(proactor_->get_io_queue(), key_, + &sock->get_handle(), + local_addr, remote, + (remote? sizeof(*remote) : 0)); + if (status == 0) { + on_accept_complete(0); + return true; + } else if (status == PJ_IOQUEUE_PENDING) { + return true; + } else { + return false; + } +} + +#endif + +bool PJ_Event_Handler::read(void *buf, pj_size_t len) +{ + pj_assert(key_ != NULL && proactor_ != NULL); + + if (key_ == NULL || proactor_ == NULL) + return false; + + int bytes_status = pj_ioqueue_read(proactor_->get_io_queue(), + key_, buf, len); + if (bytes_status >= 0) { + on_read_complete(bytes_status); + return true; + } else if (bytes_status == PJ_IOQUEUE_PENDING) { + return true; + } else { + return false; + } +} + +bool PJ_Event_Handler::recvfrom(void *buf, pj_size_t len, PJ_INET_Addr *addr) +{ + pj_assert(key_ != NULL && proactor_ != NULL); + + if (key_ == NULL || proactor_ == NULL) + return false; + + + tmp_recvfrom_addr_len = sizeof(PJ_INET_Addr); + + int bytes_status = pj_ioqueue_recvfrom(proactor_->get_io_queue(), + key_, buf, len, + addr, + (addr? &tmp_recvfrom_addr_len : NULL)); + if (bytes_status >= 0) { + on_read_complete(bytes_status); + return true; + } else if (bytes_status == PJ_IOQUEUE_PENDING) { + return true; + } else { + return false; + } +} + +bool PJ_Event_Handler::write(const void *data, pj_size_t len) +{ + pj_assert(key_ != NULL && proactor_ != NULL); + + if (key_ == NULL || proactor_ == NULL) + return false; + + int bytes_status = pj_ioqueue_write(proactor_->get_io_queue(), + key_, data, len); + if (bytes_status >= 0) { + on_write_complete(bytes_status); + return true; + } else if (bytes_status == PJ_IOQUEUE_PENDING) { + return true; + } else { + return false; + } +} + +bool PJ_Event_Handler::sendto(const void *data, pj_size_t len, const PJ_INET_Addr &addr) +{ + pj_assert(key_ != NULL && proactor_ != NULL); + + if (key_ == NULL || proactor_ == NULL) + return false; + + int bytes_status = pj_ioqueue_sendto(proactor_->get_io_queue(), + key_, data, len, + &addr, sizeof(PJ_INET_Addr)); + if (bytes_status >= 0) { + on_write_complete(bytes_status); + return true; + } else if (bytes_status == PJ_IOQUEUE_PENDING) { + return true; + } else { + return false; + } +} + + +void PJ_Event_Handler::read_complete_cb(pj_ioqueue_key_t *key, pj_ssize_t bytes_read) +{ + PJ_Event_Handler *handler = + (PJ_Event_Handler*) pj_ioqueue_get_user_data(key); + + handler->on_read_complete(bytes_read); +} + +void PJ_Event_Handler::write_complete_cb(pj_ioqueue_key_t *key, pj_ssize_t bytes_sent) +{ + PJ_Event_Handler *handler = + (PJ_Event_Handler*) pj_ioqueue_get_user_data(key); + + handler->on_write_complete(bytes_sent); +} + +void PJ_Event_Handler::accept_complete_cb(pj_ioqueue_key_t *key, int status) +{ +#if PJ_HAS_TCP + PJ_Event_Handler *handler = + (PJ_Event_Handler*) pj_ioqueue_get_user_data(key); + + handler->on_accept_complete(status); +#endif +} + +void PJ_Event_Handler::connect_complete_cb(pj_ioqueue_key_t *key, int status) +{ +#if PJ_HAS_TCP + PJ_Event_Handler *handler = + (PJ_Event_Handler*) pj_ioqueue_get_user_data(key); + + handler->on_connect_complete(status); +#endif +} + +void PJ_Event_Handler::timer_callback( pj_timer_heap_t *timer_heap, + struct pj_timer_entry *entry) +{ + PJ_Event_Handler *handler = (PJ_Event_Handler*) entry->user_data; + handler->on_timeout(entry->id); +} + + +PJ_Proactor *PJ_Proactor::create(PJ_Pool *pool, pj_size_t max_fd, + pj_size_t timer_entry_count, unsigned timer_flags) +{ + PJ_Proactor *p = (PJ_Proactor*) pool->calloc(1, sizeof(PJ_Proactor)); + if (!p) return NULL; + + p->ioq_ = pj_ioqueue_create(pool->pool_(), max_fd); + if (!p->ioq_) return NULL; + + p->th_ = pj_timer_heap_create(pool->pool_(), timer_entry_count, timer_flags); + if (!p->th_) return NULL; + + return p; +} + +void PJ_Proactor::destroy() +{ + pj_ioqueue_destroy(ioq_); +} + +bool PJ_Proactor::register_handler(PJ_Pool *pool, PJ_Event_Handler *handler) +{ + pj_assert(handler->key_ == NULL && handler->proactor_ == NULL); + + if (handler->key_ != NULL) + return false; + + handler->key_ = pj_ioqueue_register_sock(pool->pool_(), ioq_, + handler->get_handle(), + handler, &ioqueue_cb); + if (handler->key_ != NULL) { + handler->proactor_ = this; + return true; + } else { + return false; + } +} + +void PJ_Proactor::unregister_handler(PJ_Event_Handler *handler) +{ + if (handler->key_ == NULL) return; + pj_ioqueue_unregister(ioq_, handler->key_); + handler->key_ = NULL; + handler->proactor_ = NULL; +} + +bool PJ_Proactor::schedule_timer( pj_timer_heap_t *timer, PJ_Event_Handler *handler, + const PJ_Time_Val &delay, int id) +{ + handler->timer_.id = id; + return pj_timer_heap_schedule(timer, &handler->timer_, &delay) == 0; +} + +bool PJ_Proactor::schedule_timer(PJ_Event_Handler *handler, const PJ_Time_Val &delay, + int id) +{ + return schedule_timer(th_, handler, delay, id); +} + +bool PJ_Proactor::cancel_timer(PJ_Event_Handler *handler) +{ + return pj_timer_heap_cancel(th_, &handler->timer_) == 1; +} + +bool PJ_Proactor::handle_events(PJ_Time_Val *max_timeout) +{ + pj_time_val timeout; + + timeout.sec = timeout.msec = 0; /* timeout is 'out' var. */ + + if (pj_timer_heap_poll( th_, &timeout ) > 0) + return true; + + if (timeout.sec < 0) timeout.sec = PJ_MAXINT32; + + /* If caller specifies maximum time to wait, then compare the value with + * the timeout to wait from timer, and use the minimum value. + */ + if (max_timeout && PJ_TIME_VAL_GT(timeout, *max_timeout)) { + timeout = *max_timeout; + } + + /* Poll events in ioqueue. */ + int result; + + result = pj_ioqueue_poll(ioq_, &timeout); + if (result != 1) + return false; + + return true; +} + +pj_ioqueue_t *PJ_Proactor::get_io_queue() +{ + return ioq_; +} + +pj_timer_heap_t *PJ_Proactor::get_timer_heap() +{ + return th_; +} + diff --git a/pjlib/src/pj++/proactor.hpp b/pjlib/src/pj++/proactor.hpp new file mode 100644 index 00000000..d5dc0367 --- /dev/null +++ b/pjlib/src/pj++/proactor.hpp @@ -0,0 +1,86 @@ +/* $Header: /pjproject/pjlib/src/pj++/proactor.hpp 3 8/24/05 10:29a Bennylp $ */ +#ifndef __PJPP_EVENT_HANDLER_H__ +#define __PJPP_EVENT_HANDLER_H__ + +#include +#include +#include +#include + +class PJ_Proactor; + + +class PJ_Event_Handler +{ + friend class PJ_Proactor; +public: + PJ_Event_Handler(); + virtual ~PJ_Event_Handler(); + + virtual pj_oshandle_t get_handle() = 0; + + bool read(void *buf, pj_size_t len); + bool recvfrom(void *buf, pj_size_t len, PJ_INET_Addr *addr); + bool write(const void *data, pj_size_t len); + bool sendto(const void *data, pj_size_t len, const PJ_INET_Addr &addr); +#if PJ_HAS_TCP + bool connect(const PJ_INET_Addr &addr); + bool accept(PJ_Socket *sock, PJ_INET_Addr *local=NULL, PJ_INET_Addr *remote=NULL); +#endif + +protected: + // + // Overridables + // + virtual void on_timeout(int data) {} + virtual void on_read_complete(pj_ssize_t bytes_read) {} + virtual void on_write_complete(pj_ssize_t bytes_sent) {} +#if PJ_HAS_TCP + virtual void on_connect_complete(int status) {} + virtual void on_accept_complete(int status) {} +#endif + +private: + PJ_Proactor *proactor_; + pj_ioqueue_key_t *key_; + pj_timer_entry timer_; + int tmp_recvfrom_addr_len; + +public: + // Internal IO Queue/timer callback. + static void timer_callback( pj_timer_heap_t *timer_heap, struct pj_timer_entry *entry); + static void read_complete_cb(pj_ioqueue_key_t *key, pj_ssize_t bytes_read); + static void write_complete_cb(pj_ioqueue_key_t *key, pj_ssize_t bytes_sent); + static void accept_complete_cb(pj_ioqueue_key_t *key, int status); + static void connect_complete_cb(pj_ioqueue_key_t *key, int status); +}; + +class PJ_Proactor +{ +public: + static PJ_Proactor *create(PJ_Pool *pool, pj_size_t max_fd, + pj_size_t timer_entry_count, unsigned timer_flags=0); + + void destroy(); + + bool register_handler(PJ_Pool *pool, PJ_Event_Handler *handler); + void unregister_handler(PJ_Event_Handler *handler); + + static bool schedule_timer( pj_timer_heap_t *timer, PJ_Event_Handler *handler, + const PJ_Time_Val &delay, int id=-1); + bool schedule_timer(PJ_Event_Handler *handler, const PJ_Time_Val &delay, int id=-1); + bool cancel_timer(PJ_Event_Handler *handler); + + bool handle_events(PJ_Time_Val *timeout); + + pj_ioqueue_t *get_io_queue(); + pj_timer_heap_t *get_timer_heap(); + +private: + pj_ioqueue_t *ioq_; + pj_timer_heap_t *th_; + + PJ_Proactor() {} +}; + +#endif /* __PJPP_EVENT_HANDLER_H__ */ diff --git a/pjlib/src/pj++/scanner.hpp b/pjlib/src/pj++/scanner.hpp new file mode 100644 index 00000000..1ab44e01 --- /dev/null +++ b/pjlib/src/pj++/scanner.hpp @@ -0,0 +1,171 @@ +/* $Header: /pjproject/pjlib/src/pj++/scanner.hpp 3 2/27/05 10:09p Bennylp $ */ +#ifndef __PJPP_SCANNER_H__ +#define __PJPP_SCANNER_H__ + +#include +#include + +class PJ_CharSpec +{ +public: + PJ_CharSpec() { pj_cs_init(cs__); } + + void set(int c) { pj_cs_set(cs__, c); } + void add_range(int begin, int end) { pj_cs_add_range(cs__, begin, end); } + void add_alpha() { pj_cs_add_alpha(cs__); } + void add_num() { pj_cs_add_num(cs__); } + void add_str(const char *str) { pj_cs_add_str(cs__, str); } + void del_range(int begin, int end) { pj_cs_del_range(cs__, begin, end); } + void del_str(const char *str) { pj_cs_del_str(cs__, str); } + void invert() { pj_cs_invert(cs__); } + int match(int c) { return pj_cs_match(cs__, c); } + + pj_char_spec_element_t *cs_() + { + return cs__; + } + + const pj_char_spec_element_t *cs_() const + { + return cs__; + } + +private: + pj_char_spec cs__; +}; + +class PJ_Scanner +{ +public: + PJ_Scanner() {} + + enum + { + SYNTAX_ERROR = 101 + }; + static void syntax_error_handler_throw_pj(pj_scanner *); + + typedef pj_scan_state State; + + void init(char *buf, int len, unsigned options=PJ_SCAN_AUTOSKIP_WS, + pj_syn_err_func_ptr callback = &syntax_error_handler_throw_pj) + { + pj_scan_init(&scanner_, buf, len, options, callback); + } + + void fini() + { + pj_scan_fini(&scanner_); + } + + int eof() const + { + return pj_scan_is_eof(&scanner_); + } + + int peek_char() const + { + return *scanner_.current; + } + + int peek(const PJ_CharSpec *cs, PJ_String *out) + { + return pj_scan_peek(&scanner_, cs->cs_(), out); + } + + int peek_n(pj_size_t len, PJ_String *out) + { + return pj_scan_peek_n(&scanner_, len, out); + } + + int peek_until(const PJ_CharSpec *cs, PJ_String *out) + { + return pj_scan_peek_until(&scanner_, cs->cs_(), out); + } + + void get(const PJ_CharSpec *cs, PJ_String *out) + { + pj_scan_get(&scanner_, cs->cs_(), out); + } + + void get_n(unsigned N, PJ_String *out) + { + pj_scan_get_n(&scanner_, N, out); + } + + int get_char() + { + return pj_scan_get_char(&scanner_); + } + + void get_quote(int begin_quote, int end_quote, PJ_String *out) + { + pj_scan_get_quote(&scanner_, begin_quote, end_quote, out); + } + + void get_newline() + { + pj_scan_get_newline(&scanner_); + } + + void get_until(const PJ_CharSpec *cs, PJ_String *out) + { + pj_scan_get_until(&scanner_, cs->cs_(), out); + } + + void get_until_ch(int until_ch, PJ_String *out) + { + pj_scan_get_until_ch(&scanner_, until_ch, out); + } + + void get_until_chr(const char *spec, PJ_String *out) + { + pj_scan_get_until_chr(&scanner_, spec, out); + } + + void advance_n(unsigned N, bool skip_ws=true) + { + pj_scan_advance_n(&scanner_, N, skip_ws); + } + + int strcmp(const char *s, int len) + { + return pj_scan_strcmp(&scanner_, s, len); + } + + int stricmp(const char *s, int len) + { + return pj_scan_stricmp(&scanner_, s, len); + } + + void skip_ws() + { + pj_scan_skip_whitespace(&scanner_); + } + + void save_state(State *state) + { + pj_scan_save_state(&scanner_, state); + } + + void restore_state(State *state) + { + pj_scan_restore_state(&scanner_, state); + } + + int get_pos_line() const + { + return scanner_.line; + } + + int get_pos_col() const + { + return scanner_.col; + } + + +private: + pj_scanner scanner_; +}; + +#endif /* __PJPP_SCANNER_H__ */ diff --git a/pjlib/src/pj++/sock.hpp b/pjlib/src/pj++/sock.hpp new file mode 100644 index 00000000..aa62c158 --- /dev/null +++ b/pjlib/src/pj++/sock.hpp @@ -0,0 +1,194 @@ +/* $Header: /pjproject/pjlib/src/pj++/sock.hpp 2 2/24/05 11:23a Bennylp $ */ +#ifndef __PJPP_SOCK_H__ +#define __PJPP_SOCK_H__ + +#include + +class PJ_Addr +{ +}; + +class PJ_INET_Addr : public pj_sockaddr_in, public PJ_Addr +{ +public: + pj_uint16_t get_port_number() const + { + return pj_sockaddr_get_port(this); + } + + void set_port_number(pj_uint16_t port) + { + sin_family = PJ_AF_INET; + pj_sockaddr_set_port(this, port); + } + + pj_uint32_t get_ip_address() const + { + return pj_sockaddr_get_addr(this); + } + + const char *get_address() const + { + return pj_sockaddr_get_str_addr(this); + } + + void set_ip_address(pj_uint32_t addr) + { + sin_family = PJ_AF_INET; + pj_sockaddr_set_addr(this, addr); + } + + pj_status_t set_address(const pj_str_t *addr) + { + return pj_sockaddr_set_str_addr(this, addr); + } + + pj_status_t set_address(const char *addr) + { + return pj_sockaddr_set_str_addr2(this, addr); + } + + int cmp(const PJ_INET_Addr &rhs) const + { + return pj_sockaddr_cmp(this, &rhs); + } + + bool operator==(const PJ_INET_Addr &rhs) const + { + return cmp(rhs) == 0; + } +}; + +class PJ_Socket +{ +public: + PJ_Socket() {} + PJ_Socket(const PJ_Socket &rhs) : sock_(rhs.sock_) {} + + void set_handle(pj_sock_t sock) + { + sock_ = sock; + } + + pj_sock_t get_handle() const + { + return sock_; + } + + pj_sock_t& get_handle() + { + return sock_; + } + + bool socket(int af, int type, int proto, pj_uint32_t flag=0) + { + sock_ = pj_sock_socket(af, type, proto, flag); + return sock_ != -1; + } + + bool bind(const PJ_INET_Addr &addr) + { + return pj_sock_bind(sock_, &addr, sizeof(PJ_INET_Addr)) == 0; + } + + bool close() + { + return pj_sock_close(sock_) == 0; + } + + bool getpeername(PJ_INET_Addr *addr) + { + int namelen; + return pj_sock_getpeername(sock_, addr, &namelen) == 0; + } + + bool getsockname(PJ_INET_Addr *addr) + { + int namelen; + return pj_sock_getsockname(sock_, addr, &namelen) == 0; + } + + bool getsockopt(int level, int optname, void *optval, int *optlen) + { + return pj_sock_getsockopt(sock_, level, optname, optval, optlen) == 0; + } + + bool setsockopt(int level, int optname, const void *optval, int optlen) + { + return pj_sock_setsockopt(sock_, level, optname, optval, optlen) == 0; + } + + bool ioctl(long cmd, pj_uint32_t *val) + { + return pj_sock_ioctl(sock_, cmd, val) == 0; + } + + int recv(void *buf, int len, int flag = 0) + { + return pj_sock_recv(sock_, buf, len, flag); + } + + int send(const void *buf, int len, int flag = 0) + { + return pj_sock_send(sock_, buf, len, flag); + } + +protected: + pj_sock_t sock_; +}; + +#if PJ_HAS_TCP +class PJ_Sock_Stream : public PJ_Socket +{ +public: + PJ_Sock_Stream() {} + PJ_Sock_Stream(const PJ_Sock_Stream &rhs) : PJ_Socket(rhs) {} + PJ_Sock_Stream &operator=(const PJ_Sock_Stream &rhs) { sock_ = rhs.sock_; return *this; } + + bool listen(int backlog = 5) + { + return pj_sock_listen(sock_, backlog) == 0; + } + + bool accept(PJ_Sock_Stream *new_sock, PJ_INET_Addr *addr, int *addrlen) + { + pj_sock_t s = pj_sock_accept(sock_, addr, addrlen); + if (s == -1) + return false; + new_sock->set_handle(s); + return true; + } + + bool connect(const PJ_INET_Addr &addr) + { + return pj_sock_connect(sock_, &addr, sizeof(PJ_INET_Addr)) == 0; + } + + bool shutdown(int how) + { + return pj_sock_shutdown(sock_, how) == 0; + } + +}; +#endif + +class PJ_Sock_Dgram : public PJ_Socket +{ +public: + PJ_Sock_Dgram() {} + PJ_Sock_Dgram(const PJ_Sock_Dgram &rhs) : PJ_Socket(rhs) {} + PJ_Sock_Dgram &operator=(const PJ_Sock_Dgram &rhs) { sock_ = rhs.sock_; return *this; } + + int recvfrom(void *buf, int len, int flag, PJ_INET_Addr *fromaddr) + { + int addrlen; + return pj_sock_recvfrom(sock_, buf, len, flag, fromaddr, &addrlen); + } + + int sendto(const void *buf, int len, int flag, const PJ_INET_Addr &addr) + { + return pj_sock_sendto(sock_, buf, len, flag, &addr, sizeof(PJ_INET_Addr)); + } +}; + +#endif /* __PJPP_SOCK_H__ */ diff --git a/pjlib/src/pj++/string.hpp b/pjlib/src/pj++/string.hpp new file mode 100644 index 00000000..8bbb680d --- /dev/null +++ b/pjlib/src/pj++/string.hpp @@ -0,0 +1,247 @@ +/* $Header: /pjproject/pjlib/src/pj++/string.hpp 2 2/24/05 11:23a Bennylp $ */ +#ifndef __PJPP_STRING_H__ +#define __PJPP_STRING_H__ + +#include +#include + +class PJ_String : public pj_str_t +{ +public: + PJ_String() + { + pj_assert(sizeof(PJ_String) == sizeof(pj_str_t)); + ptr=NULL; slen=0; + } + + explicit PJ_String(char *str) + { + set(str); + } + + PJ_String(PJ_Pool *pool, const char *src) + { + set(pool, src); + } + + explicit PJ_String(pj_str_t *s) + { + set(s); + } + + PJ_String(PJ_Pool *pool, const pj_str_t *s) + { + set(pool, s); + } + + explicit PJ_String(PJ_String &rhs) + { + set(rhs); + } + + PJ_String(PJ_Pool *pool, const PJ_String &rhs) + { + set(pool, rhs); + } + + PJ_String(char *str, pj_size_t len) + { + set(str, len); + } + + PJ_String(char *begin, char *end) + { + pj_strset3(this, begin, end); + } + + pj_size_t length() const + { + return pj_strlen(this); + } + + pj_size_t size() const + { + return length(); + } + + const char *buf() const + { + return ptr; + } + + void set(char *str) + { + pj_strset2(this, str); + } + + void set(PJ_Pool *pool, const char *s) + { + pj_strdup2(pool->pool_(), this, s); + } + + void set(pj_str_t *s) + { + pj_strassign(this, s); + } + + void set(PJ_Pool *pool, const pj_str_t *s) + { + pj_strdup(pool->pool_(), this, s); + } + + void set(char *str, pj_size_t len) + { + pj_strset(this, str, len); + } + + void set(char *begin, char *end) + { + pj_strset3(this, begin, end); + } + + void set(PJ_String &rhs) + { + pj_strassign(this, &rhs); + } + + void set(PJ_Pool *pool, const PJ_String *s) + { + pj_strdup(pool->pool_(), this, s); + } + + void set(PJ_Pool *pool, const PJ_String &s) + { + pj_strdup(pool->pool_(), this, &s); + } + + void strcpy(const pj_str_t *s) + { + pj_strcpy(this, s); + } + + void strcpy(const PJ_String &rhs) + { + pj_strcpy(this, &rhs); + } + + void strcpy(const char *s) + { + pj_strcpy2(this, s); + } + + int strcmp(const char *s) const + { + return pj_strcmp2(this, s); + } + + int strcmp(const pj_str_t *s) const + { + return pj_strcmp(this, s); + } + + int strcmp(const PJ_String &rhs) const + { + return pj_strcmp(this, &rhs); + } + + int strncmp(const char *s, pj_size_t len) const + { + return pj_strncmp2(this, s, len); + } + + int strncmp(const pj_str_t *s, pj_size_t len) const + { + return pj_strncmp(this, s, len); + } + + int strncmp(const PJ_String &rhs, pj_size_t len) const + { + return pj_strncmp(this, &rhs, len); + } + + int stricmp(const char *s) const + { + return pj_stricmp2(this, s); + } + + int stricmp(const pj_str_t *s) const + { + return pj_stricmp(this, s); + } + + int stricmp(const PJ_String &rhs) const + { + return stricmp(&rhs); + } + + int strnicmp(const char *s, pj_size_t len) const + { + return pj_strnicmp2(this, s, len); + } + + int strnicmp(const pj_str_t *s, pj_size_t len) const + { + return pj_strnicmp(this, s, len); + } + + int strnicmp(const PJ_String &rhs, pj_size_t len) const + { + return strnicmp(&rhs, len); + } + + bool operator==(const char *s) const + { + return strcmp(s) == 0; + } + + bool operator==(const pj_str_t *s) const + { + return strcmp(s) == 0; + } + + bool operator==(const PJ_String &rhs) const + { + return pj_strcmp(this, &rhs) == 0; + } + + char *strchr(int chr) + { + return pj_strchr(this, chr); + } + + char *find(int chr) + { + return strchr(chr); + } + + void strcat(const PJ_String &rhs) + { + pj_strcat(this, &rhs); + } + + void ltrim() + { + pj_strltrim(this); + } + + void rtrim() + { + pj_strrtrim(this); + } + + void trim() + { + pj_strtrim(this); + } + + unsigned long toul() const + { + return pj_strtoul(this); + } + +private: + //PJ_String(const PJ_String &rhs) {} + void operator=(const PJ_String &rhs) { pj_assert(false); } +}; + +#endif /* __PJPP_STRING_H__ */ diff --git a/pjlib/src/pj++/timer.hpp b/pjlib/src/pj++/timer.hpp new file mode 100644 index 00000000..ccca633a --- /dev/null +++ b/pjlib/src/pj++/timer.hpp @@ -0,0 +1,105 @@ +/* $Header: /pjproject/pjlib/src/pj++/timer.hpp 4 8/24/05 10:29a Bennylp $ */ +#ifndef __PJPP_TIMER_H__ +#define __PJPP_TIMER_H__ + +#include +#include + +class PJ_Timer_Heap; + +class PJ_Timer_Entry : private pj_timer_entry +{ + friend class PJ_Timer_Heap; + +public: + static void timer_heap_callback(pj_timer_heap_t *, pj_timer_entry *); + + PJ_Timer_Entry() { cb = &timer_heap_callback; } + PJ_Timer_Entry(int arg_id, void *arg_user_data) + { + cb = &timer_heap_callback; + init(arg_id, arg_user_data); + } + + virtual void on_timeout() = 0; + + void init(int arg_id, void *arg_user_data) + { + id = arg_id; + user_data = arg_user_data; + } + + int get_id() const + { + return id; + } + + void set_id(int arg_id) + { + id = arg_id; + } + + void set_user_data(void *arg_user_data) + { + user_data = arg_user_data; + } + + void *get_user_data() const + { + return user_data; + } + + const PJ_Time_Val &get_timeout() const + { + pj_assert(sizeof(PJ_Time_Val) == sizeof(pj_time_val)); + return (PJ_Time_Val&)_timer_value; + } +}; + +class PJ_Timer_Heap +{ +public: + PJ_Timer_Heap() {} + + bool create(PJ_Pool *pool, pj_size_t initial_count, + unsigned flag = PJ_TIMER_HEAP_SYNCHRONIZE) + { + ht_ = pj_timer_heap_create(pool->pool_(), initial_count, flag); + return ht_ != NULL; + } + + pj_timer_heap_t *get_timer_heap() + { + return ht_; + } + + bool schedule( PJ_Timer_Entry *ent, const PJ_Time_Val &delay) + { + return pj_timer_heap_schedule(ht_, ent, &delay) == 0; + } + + bool cancel(PJ_Timer_Entry *ent) + { + return pj_timer_heap_cancel(ht_, ent) == 1; + } + + pj_size_t count() + { + return pj_timer_heap_count(ht_); + } + + void earliest_time(PJ_Time_Val *t) + { + pj_timer_heap_earliest_time(ht_, t); + } + + int poll(PJ_Time_Val *next_delay = NULL) + { + return pj_timer_heap_poll(ht_, next_delay); + } + +private: + pj_timer_heap_t *ht_; +}; + +#endif /* __PJPP_TIMER_H__ */ diff --git a/pjlib/src/pj++/tree.hpp b/pjlib/src/pj++/tree.hpp new file mode 100644 index 00000000..d2243e57 --- /dev/null +++ b/pjlib/src/pj++/tree.hpp @@ -0,0 +1,107 @@ +/* $Header: /pjproject/pjlib/src/pj++/tree.hpp 2 2/24/05 11:23a Bennylp $ */ +#ifndef __PJPP_TREE_H__ +#define __PJPP_TREE_H__ + +#include + +class PJ_Tree +{ +public: + typedef pj_rbtree_comp Comp; + class iterator; + class reverse_iterator; + + class Node : private pj_rbtree_node + { + friend class PJ_Tree; + friend class iterator; + friend class reverse_iterator; + + public: + Node() {} + explicit Node(void *data) { user_data = data; } + void set_user_data(void *data) { user_data = data; } + void *get_user_data() const { return user_data; } + }; + + class iterator + { + public: + iterator() {} + iterator(const iterator &rhs) : tr_(rhs.tr_), nd_(rhs.nd_) {} + iterator(pj_rbtree *tr, pj_rbtree_node *nd) : tr_(tr), nd_(nd) {} + Node *operator*() { return (Node*)nd_; } + bool operator==(const iterator &rhs) const { return tr_==rhs.tr_ && nd_==rhs.nd_; } + iterator &operator=(const iterator &rhs) { tr_=rhs.tr_; nd_=rhs.nd_; return *this; } + void operator++() { nd_=pj_rbtree_next(tr_, nd_); } + void operator--() { nd_=pj_rbtree_prev(tr_, nd_); } + protected: + pj_rbtree *tr_; + pj_rbtree_node *nd_; + }; + + class reverse_iterator : public iterator + { + public: + reverse_iterator() {} + reverse_iterator(const reverse_iterator &it) : iterator(it) {} + reverse_iterator(pj_rbtree *t, pj_rbtree_node *n) : iterator(t, n) {} + reverse_iterator &operator=(const reverse_iterator &rhs) { iterator::operator=(rhs); return *this; } + Node *operator*() { return (Node*)nd_; } + bool operator==(const reverse_iterator &rhs) const { return iterator::operator==(rhs); } + void operator++() { nd_=pj_rbtree_prev(tr_, nd_); } + void operator--() { nd_=pj_rbtree_next(tr_, nd_); } + }; + + explicit PJ_Tree(Comp *comp) { pj_rbtree_init(&t_, comp); } + + iterator begin() + { + return iterator(&t_, pj_rbtree_first(&t_)); + } + + iterator end() + { + return iterator(&t_, NULL); + } + + reverse_iterator rbegin() + { + return reverse_iterator(&t_, pj_rbtree_last(&t_)); + } + + reverse_iterator rend() + { + return reverse_iterator(&t_, NULL); + } + + bool insert(Node *node) + { + return pj_rbtree_insert(&t_, node)==0 ? true : false; + } + + Node *find(const void *key) + { + return (Node*)pj_rbtree_find(&t_, key); + } + + Node *erase(Node *node) + { + return (Node*)pj_rbtree_erase(&t_, node); + } + + unsigned max_height(Node *node=NULL) + { + return pj_rbtree_max_height(&t_, node); + } + + unsigned min_height(Node *node=NULL) + { + return pj_rbtree_min_height(&t_, node); + } + +private: + pj_rbtree t_; +}; + +#endif /* __PJPP_TREE_H__ */ diff --git a/pjlib/src/pj++/types.hpp b/pjlib/src/pj++/types.hpp new file mode 100644 index 00000000..888c8456 --- /dev/null +++ b/pjlib/src/pj++/types.hpp @@ -0,0 +1,59 @@ +/* $Header: /pjproject/pjlib/src/pj++/types.hpp 3 4/17/05 11:59a Bennylp $ */ +#ifndef __PJPP_TYPES_H__ +#define __PJPP_TYPES_H__ + +#include + +class PJ_Pool; +class PJ_Socket; + + +class PJ_Time_Val : public pj_time_val +{ +public: + PJ_Time_Val() {} + PJ_Time_Val(const PJ_Time_Val &rhs) { sec=rhs.sec; msec=rhs.msec; } + explicit PJ_Time_Val(const pj_time_val &tv) { sec = tv.sec; msec = tv.msec; } + + long get_sec() const { return sec; } + long get_msec() const { return msec; } + void set_sec (long s) { sec = s; } + void set_msec(long ms) { msec = ms; normalize(); } + long to_msec() const { return PJ_TIME_VAL_MSEC((*this)); } + + bool operator == (const PJ_Time_Val &rhs) const { return PJ_TIME_VAL_EQ((*this), rhs); } + bool operator > (const PJ_Time_Val &rhs) const { return PJ_TIME_VAL_GT((*this), rhs); } + bool operator >= (const PJ_Time_Val &rhs) const { return PJ_TIME_VAL_GTE((*this), rhs); } + bool operator < (const PJ_Time_Val &rhs) const { return PJ_TIME_VAL_LT((*this), rhs); } + bool operator <= (const PJ_Time_Val &rhs) const { return PJ_TIME_VAL_LTE((*this), rhs); } + + PJ_Time_Val & operator = (const PJ_Time_Val &rhs) { + sec = rhs.sec; + msec = rhs.msec; + return *this; + } + + PJ_Time_Val & operator += (const PJ_Time_Val &rhs) { + PJ_TIME_VAL_ADD((*this), rhs); + return *this; + } + + PJ_Time_Val & operator -= (const PJ_Time_Val &rhs) { + PJ_TIME_VAL_SUB((*this), rhs); + return *this; + } + + /* Must include os.hpp to use these, otherwise unresolved in linking */ + pj_status_t gettimeofday(); + pj_parsed_time decode(); + pj_status_t encode(const pj_parsed_time *pt); + pj_status_t to_gmt(); + pj_status_t to_local(); + + +private: + void normalize() { pj_time_val_normalize(this); } + +}; + +#endif /* __PJPP_TYPES_H__ */ -- cgit v1.2.3