123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- #ifndef skynet_databuffer_h
- #define skynet_databuffer_h
- #include <stdlib.h>
- #include <string.h>
- #include <assert.h>
- #define MESSAGEPOOL 1023
- struct message {
- char * buffer;
- int size;
- struct message * next;
- };
- struct databuffer {
- int header;
- int offset;
- int size;
- struct message * head;
- struct message * tail;
- };
- struct messagepool_list {
- struct messagepool_list *next;
- struct message pool[MESSAGEPOOL];
- };
- struct messagepool {
- struct messagepool_list * pool;
- struct message * freelist;
- };
- // use memset init struct
- static void
- messagepool_free(struct messagepool *pool) {
- struct messagepool_list *p = pool->pool;
- while(p) {
- struct messagepool_list *tmp = p;
- p=p->next;
- skynet_free(tmp);
- }
- pool->pool = NULL;
- pool->freelist = NULL;
- }
- static inline void
- _return_message(struct databuffer *db, struct messagepool *mp) {
- struct message *m = db->head;
- if (m->next == NULL) {
- assert(db->tail == m);
- db->head = db->tail = NULL;
- } else {
- db->head = m->next;
- }
- skynet_free(m->buffer);
- m->buffer = NULL;
- m->size = 0;
- m->next = mp->freelist;
- mp->freelist = m;
- }
- static void
- databuffer_read(struct databuffer *db, struct messagepool *mp, char * buffer, int sz) {
- assert(db->size >= sz);
- db->size -= sz;
- for (;;) {
- struct message *current = db->head;
- int bsz = current->size - db->offset;
- if (bsz > sz) {
- memcpy(buffer, current->buffer + db->offset, sz);
- db->offset += sz;
- return;
- }
- if (bsz == sz) {
- memcpy(buffer, current->buffer + db->offset, sz);
- db->offset = 0;
- _return_message(db, mp);
- return;
- } else {
- memcpy(buffer, current->buffer + db->offset, bsz);
- _return_message(db, mp);
- db->offset = 0;
- buffer+=bsz;
- sz-=bsz;
- }
- }
- }
- static void
- databuffer_push(struct databuffer *db, struct messagepool *mp, void *data, int sz) {
- struct message * m;
- if (mp->freelist) {
- m = mp->freelist;
- mp->freelist = m->next;
- } else {
- struct messagepool_list * mpl = skynet_malloc(sizeof(*mpl));
- struct message * temp = mpl->pool;
- int i;
- for (i=1;i<MESSAGEPOOL;i++) {
- temp[i].buffer = NULL;
- temp[i].size = 0;
- temp[i].next = &temp[i+1];
- }
- temp[MESSAGEPOOL-1].next = NULL;
- mpl->next = mp->pool;
- mp->pool = mpl;
- m = &temp[0];
- mp->freelist = &temp[1];
- }
- m->buffer = data;
- m->size = sz;
- m->next = NULL;
- db->size += sz;
- if (db->head == NULL) {
- assert(db->tail == NULL);
- db->head = db->tail = m;
- } else {
- db->tail->next = m;
- db->tail = m;
- }
- }
- static int
- databuffer_readheader(struct databuffer *db, struct messagepool *mp, int header_size) {
- if (db->header == 0) {
- // parser header (2 or 4)
- if (db->size < header_size) {
- return -1;
- }
- uint8_t plen[4];
- databuffer_read(db,mp,(char *)plen,header_size);
- // big-endian
- if (header_size == 2) {
- db->header = plen[0] << 8 | plen[1];
- } else {
- db->header = plen[0] << 24 | plen[1] << 16 | plen[2] << 8 | plen[3];
- }
- }
- if (db->size < db->header)
- return -1;
- return db->header;
- }
- static inline void
- databuffer_reset(struct databuffer *db) {
- db->header = 0;
- }
- static void
- databuffer_clear(struct databuffer *db, struct messagepool *mp) {
- while (db->head) {
- _return_message(db,mp);
- }
- memset(db, 0, sizeof(*db));
- }
- #endif
|