void decoder_del(decoder *d) { if(d->dctor) d->dctor(d); if(d->buff) bytebuffer_set(&d->buff,NULL); free(d); }
void datagram_dctor(void *_) { datagram *d = (datagram*)_; bytebuffer_set(&d->next_recv_buf,NULL); decoder_del(d->decoder_); free(d); }
static packet* rpk_unpack(decoder *d,int32_t *err) { TYPE_HEAD pk_len; uint32_t pk_total,size; buffer_reader reader; rpacket *rpk; if(err) *err = 0; if(d->size <= SIZE_HEAD) return NULL; buffer_reader_init(&reader,d->buff,d->pos); if(SIZE_HEAD != buffer_read(&reader,(char*)&pk_len,SIZE_HEAD)) return NULL; pk_len = _ntoh16(pk_len); pk_total = pk_len + SIZE_HEAD; if(pk_total > d->max_packet_size){ if(err) *err = DERR_TOOLARGE; return NULL; } if(pk_total > d->size) return NULL; rpk = rpacket_new(d->buff,d->pos); do{ size = d->buff->size - d->pos; size = pk_total > size ? size:pk_total; d->pos += size; pk_total -= size; d->size -= size; if(d->pos >= d->buff->cap) { bytebuffer_set(&d->buff,d->buff->next); d->pos = 0; if(!d->buff){ assert(pk_total == 0); break; } } }while(pk_total); return (packet*)rpk; }
static inline void update_next_recv_pos(datagram *d,int32_t _bytestransfer) { assert(_bytestransfer >= 0); uint32_t bytes = (uint32_t)_bytestransfer; uint32_t size; d->decoder_->decoder_update(d->decoder_,d->next_recv_buf,d->next_recv_pos,bytes); do{ size = d->next_recv_buf->cap - d->next_recv_pos; size = size > bytes ? bytes:size; d->next_recv_buf->size += size; d->next_recv_pos += size; bytes -= size; if(d->next_recv_pos >= d->next_recv_buf->cap) { bytebuffer_set(&d->next_recv_buf,d->next_recv_buf->next); d->next_recv_pos = 0; } }while(bytes); }