172 lines
4.7 KiB
C
172 lines
4.7 KiB
C
|
#include "kpacket.h"
|
||
|
#include "ngx_slab.h"
|
||
|
#include "hlog.h"
|
||
|
#include "crc16.h"
|
||
|
|
||
|
static ngx_slab_pool_t *slab;
|
||
|
|
||
|
TLV *TLV_init(char *buf, uint32_t cap){
|
||
|
TLV *tlv = (TLV*)buf;
|
||
|
}
|
||
|
|
||
|
void kpacket_init(uint32_t packet_pool_size){
|
||
|
slab = ngx_slab_sizes_init(packet_pool_size);
|
||
|
}
|
||
|
|
||
|
|
||
|
uint16_t kpacket_calc_checksum(kpacket *packet){
|
||
|
char *p = (char*)&packet->tlv.magic;
|
||
|
return crc16(p, packet->tlv.L + sizeof(packet->tlv) -sizeof(packet->tlv.checksum));
|
||
|
}
|
||
|
|
||
|
uint16_t kpacket_checksum(kpacket *packet){
|
||
|
packet->tlv.checksum = kpacket_calc_checksum(packet);
|
||
|
return packet->tlv.checksum;
|
||
|
}
|
||
|
|
||
|
kpacket *kpacket_slab_alloc(uint32_t size){
|
||
|
if (slab) {
|
||
|
kpacket * p = (kpacket *)ngx_slab_alloc(slab, size);
|
||
|
return p;
|
||
|
}
|
||
|
hloge("%s err kpacket_init first ", __func__);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
void kpacket_slab_free(kpacket *packet){
|
||
|
ngx_slab_free(slab, packet);
|
||
|
}
|
||
|
|
||
|
|
||
|
static uint32_t put_rawdata(kpacket *p, const void *data, uint32_t size){
|
||
|
if (p){
|
||
|
if (kpacket_get_freesize(p) >= size){
|
||
|
char *payload = p->tlv.V;
|
||
|
memcpy(payload + p->tlv.L, data, size);
|
||
|
p->tlv.L += size;
|
||
|
return 0;
|
||
|
}else{
|
||
|
hloge("%s error outofmemory kpacket_get_freesize:%d, need:%u", __func__, kpacket_get_freesize(p), size);
|
||
|
exit(0);
|
||
|
}
|
||
|
}else{
|
||
|
hloge("%s error p NULL", __func__);
|
||
|
}
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
uint32_t kpacket_put_int(kpacket *p, int32_t val){
|
||
|
return put_rawdata(p, &val, sizeof(val));
|
||
|
}
|
||
|
|
||
|
uint32_t kpacket_put_string(kpacket *p, const char *str){
|
||
|
return put_rawdata(p, str, strlen(str) + 1);
|
||
|
}
|
||
|
|
||
|
uint32_t kpacket_put_data(kpacket *p, const char *data, uint32_t len){
|
||
|
uint32_t ret = 0;
|
||
|
ret += put_rawdata(p, &len, sizeof(len)) ;
|
||
|
ret += put_rawdata(p, data, len);
|
||
|
if (ret){
|
||
|
hloge("%s len err capacity:%u, and len:%u, tatal:%d, request:%u",
|
||
|
__func__, p->capacity, p->tlv.L, (uint32_t)(len+sizeof(len)), (uint32_t)(p->tlv.L + len + sizeof(len) - p->capacity));
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
|
||
|
uint32_t kpacket_put_data1data2(kpacket *p, const char *data, uint32_t len, const char *data2, uint32_t len2){
|
||
|
uint32_t ret = 0;
|
||
|
uint32_t total = len + len2;
|
||
|
ret += put_rawdata(p, &total, sizeof(total));
|
||
|
ret += put_rawdata(p, data, len);
|
||
|
ret += put_rawdata(p, data2, len2);
|
||
|
if (ret){
|
||
|
hloge("%s len err capacity:%u, and len:%u, tatal:%d, need:%u",
|
||
|
__func__, p->capacity, p->tlv.L, (uint32_t)(len+sizeof(len)), (uint32_t)(p->tlv.L + len + sizeof(len) - p->capacity));
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
void kpacket_reset(kpacket *p){
|
||
|
if (p){
|
||
|
p->tlv.L = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
uint32_t kpacket_get_freesize(const kpacket *p){
|
||
|
return p->capacity - p->tlv.L;
|
||
|
}
|
||
|
|
||
|
|
||
|
uint32_t kpacket_pop_int(kpacket *p, const int32_t defVal){
|
||
|
uint32_t val = defVal;
|
||
|
if (p && (p->tlv.L - p->offset >= sizeof(val))){
|
||
|
memcpy(&val, p->tlv.V + p->offset, sizeof(val));
|
||
|
p->offset += sizeof(val);
|
||
|
}
|
||
|
return val;
|
||
|
}
|
||
|
|
||
|
const char *kpacket_pop_string(kpacket *p, const char *defVal){
|
||
|
char *str = (char *)defVal;
|
||
|
uint32_t val;
|
||
|
if (p && p->tlv.L - p->offset > 1 && (val = strlen(p->tlv.V + p->offset)+1) <= p->tlv.L - p->offset){
|
||
|
str = p->tlv.V + p->offset;
|
||
|
p->offset += val;
|
||
|
}
|
||
|
return (const char *)str;
|
||
|
}
|
||
|
|
||
|
uint32_t kpacket_pop_data(kpacket *p, char **data){
|
||
|
uint32_t len = 0;
|
||
|
if (p && p->tlv.L - p->offset > sizeof(len)){
|
||
|
memcpy(&len, p->tlv.V + p->offset, sizeof(len));
|
||
|
if (len + sizeof(len) <= p->tlv.L - p->offset){
|
||
|
p->offset += sizeof(len);
|
||
|
*data = p->tlv.V + p->offset;
|
||
|
p->offset += len;
|
||
|
}else{
|
||
|
len = 0;
|
||
|
}
|
||
|
}
|
||
|
return len;
|
||
|
}
|
||
|
|
||
|
uint32_t kpacket_pop_reset(kpacket *p){
|
||
|
if (p){
|
||
|
p->offset = 0;
|
||
|
return 0;
|
||
|
}
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
void kpacket_dump(kpacket *p){
|
||
|
hlogi("ref:%u capacity:%u magic:0x%X event:%u pay_loadsize:%u", p->ref, p->capacity, p->tlv.magic, p->tlv.T, p->tlv.L);
|
||
|
}
|
||
|
|
||
|
void kpacket_test(void){
|
||
|
#define TEST_STR "123456\r\n"
|
||
|
kpacket *packet = kpacket(0, 100);
|
||
|
kpacket_put_int(packet, 987);
|
||
|
kpacket_put_int(packet, 789);
|
||
|
kpacket_put_data(packet, TEST_STR, strlen(TEST_STR));
|
||
|
kpacket_put_data1data2(packet, TEST_STR, strlen(TEST_STR), TEST_STR, strlen(TEST_STR));
|
||
|
kpacket_put_string(packet, TEST_STR);
|
||
|
kpacket_dump(packet);
|
||
|
|
||
|
char *data;
|
||
|
int len;
|
||
|
hlogi("kpacket kpacket_pop_int:%d", kpacket_pop_int(packet, 0));
|
||
|
hlogi("kpacket kpacket_pop_int:%d", kpacket_pop_int(packet, 0));
|
||
|
len = kpacket_pop_data(packet, &data);
|
||
|
hlogi("kpacket kpacket_pop_data sz:%d %s", len, data);
|
||
|
len = kpacket_pop_data(packet, &data);
|
||
|
hlogi("kpacket kpacket_pop_data sz:%d %s", len, data);
|
||
|
hlogi("kpacket kpacket_pop_string:%s", kpacket_pop_string(packet, "err"));
|
||
|
kpacket_dec(packet);
|
||
|
|
||
|
}
|
||
|
|