static inline void prepare_recv(datagram *d) { bytebuffer *buf; int32_t i = 0; uint32_t free_buffer_size,recv_size,pos; if(!d->next_recv_buf){ d->next_recv_buf = bytebuffer_new(d->recv_bufsize); d->next_recv_pos = 0; } buf = d->next_recv_buf; pos = d->next_recv_pos; recv_size = d->recv_bufsize; do { free_buffer_size = buf->cap - pos; free_buffer_size = recv_size > free_buffer_size ? free_buffer_size:recv_size; d->wrecvbuf[i].iov_len = free_buffer_size; d->wrecvbuf[i].iov_base = buf->data + pos; recv_size -= free_buffer_size; pos += free_buffer_size; if(recv_size && pos >= buf->cap) { pos = 0; if(!buf->next) buf->next = bytebuffer_new(d->recv_bufsize); buf = buf->next; } ++i; }while(recv_size); d->recv_overlap.iovec_count = i; d->recv_overlap.iovec = d->wrecvbuf; }
const void* rpacket_read_binary(rpacket *r,uint16_t *len) { void *addr = 0; uint16_t size = rpacket_read_uint16(r); if(size == 0 || size > r->data_remain) return NULL; if(len) *len = size; if(reader_check_size(&r->reader,size)){ addr = &r->reader.cur->data[r->reader.pos]; r->reader.pos += size; r->data_remain -= size; if(r->data_remain && r->reader.pos >= r->reader.cur->size) buffer_reader_init(&r->reader,r->reader.cur->next,0); }else{ if(!r->binbuf){ r->binbuf = bytebuffer_new(((packet*)r)->len_packet); r->binpos = 0; } addr = r->binbuf->data + r->binpos; while(size) { uint32_t copy_size = r->reader.cur->size - r->reader.pos; copy_size = copy_size >= size ? size:copy_size; memcpy(r->binbuf->data + r->binpos,r->reader.cur->data + r->reader.pos,copy_size); size -= copy_size; r->reader.pos += copy_size; r->data_remain -= copy_size; r->binpos += copy_size; if(r->data_remain && r->reader.pos >= r->reader.cur->size) buffer_reader_init(&r->reader,r->reader.cur->next,0); } } return addr; }
rawpacket* rawpacket_new(uint32_t size) { size = size_of_pow2(size); if(size < MIN_BUFFER_SIZE) size = MIN_BUFFER_SIZE; bytebuffer *b = bytebuffer_new(size); rawpacket *raw = (rawpacket*)CALLOC(g_rawpk_allocator,1,sizeof(*raw)); ((packet*)raw)->type = RAWPACKET; ((packet*)raw)->head = b; buffer_writer_init(&raw->writer,b,0); INIT_CONSTROUCTOR(raw); return raw; }
rawpacket *rawpacket_new(uint32_t size) { bytebuffer *b; rawpacket *raw; size = size_of_pow2(size); if(size < MIN_BUFFER_SIZE) size = MIN_BUFFER_SIZE; b = bytebuffer_new(size); raw = calloc(1,sizeof(*raw)); cast(packet*,raw)->type = RAWPACKET; cast(packet*,raw)->head = b; buffer_writer_init(&raw->writer,b,0); INIT_CONSTROUCTOR(raw); return raw; }
datagram *datagram_new(int32_t fd,uint32_t buffersize,decoder *d) { buffersize = size_of_pow2(buffersize); if(buffersize < MIN_RECV_BUFSIZE) buffersize = MIN_RECV_BUFSIZE; datagram *dgarm = calloc(1,sizeof(*dgarm)); datagram_socket_init((dgram_socket_*)dgarm,fd); dgarm->recv_bufsize = buffersize; dgarm->next_recv_buf = bytebuffer_new(buffersize); //save socket_ imp_engine_add,and replace with self if(!base_engine_add) base_engine_add = ((handle*)dgarm)->imp_engine_add; dgarm->imp_engine_add = imp_engine_add; dgarm->dctor = datagram_dctor; dgarm->decoder_ = d ? d:dgram_raw_decoder_new(); return dgarm; }
wpacket* wpacket_new(uint16_t size) { size = size_of_pow2(size); if(size < MIN_BUFFER_SIZE) size = MIN_BUFFER_SIZE; bytebuffer *b = bytebuffer_new(size); wpacket *w = (wpacket*)CALLOC(g_wpk_allocator,1,sizeof(*w)); ((packet*)w)->type = WPACKET; ((packet*)w)->head = b; buffer_writer_init(&w->writer,b,sizeof(*w->len)); w->len = (TYPE_HEAD*)b->data; ((packet*)w)->len_packet = SIZE_HEAD; ((packet*)w)->head->size = SIZE_HEAD; INIT_CONSTROUCTOR(w); return w; }