#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); }