rle compression for binary blobs
parent
44ade35dd0
commit
8055302bdf
|
@ -1,2 +1,2 @@
|
||||||
file(GLOB_RECURSE SRCS *.h *.c)
|
file(GLOB_RECURSE SRCS *.h *.c packets/*.c)
|
||||||
add_library(eco2d-common STATIC ${SRCS})
|
add_library(eco2d-common STATIC ${SRCS})
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
#include "compress.h"
|
||||||
|
|
||||||
|
uint32_t compress_rle(void* data, uint32_t size, uint8_t *dest) {
|
||||||
|
if (size < 1) return 0;
|
||||||
|
uint32_t total_size = 0;
|
||||||
|
uint8_t *buf = (uint8_t*)data;
|
||||||
|
uint8_t byte = buf[0];
|
||||||
|
uint16_t occurences = 1;
|
||||||
|
for (uint32_t i = 1; i <= size; i += 1){
|
||||||
|
if (buf[i] != byte || i == size) {
|
||||||
|
*(uint16_t*)dest = occurences; dest += 2;
|
||||||
|
*dest++ = byte;
|
||||||
|
byte = buf[i];
|
||||||
|
occurences = 1;
|
||||||
|
total_size += 3;
|
||||||
|
}
|
||||||
|
else occurences++;
|
||||||
|
}
|
||||||
|
return total_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t decompress_rle(void* data, uint32_t size, uint8_t *dest) {
|
||||||
|
if (size < 1) return 0;
|
||||||
|
uint32_t total_size = 0;
|
||||||
|
uint8_t *buf = (uint8_t*)data;
|
||||||
|
for (uint32_t i = 0; i < size; i += 3){
|
||||||
|
uint16_t len = *(uint16_t*)&buf[i];
|
||||||
|
for (uint16_t j = 0; j < len; j += 1){
|
||||||
|
*dest++ = buf[i+2];
|
||||||
|
total_size++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return total_size;
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
#pragma once
|
||||||
|
#include "cwpack/cwpack.h"
|
||||||
|
|
||||||
|
uint32_t compress_rle(void* data, uint32_t size, uint8_t *dest);
|
||||||
|
uint32_t decompress_rle(void* data, uint32_t size, uint8_t *dest);
|
|
@ -1,5 +1,6 @@
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
#include "packet_utils.h"
|
#include "packet_utils.h"
|
||||||
|
#include "compress.h"
|
||||||
#include "cwpack/cwpack.h"
|
#include "cwpack/cwpack.h"
|
||||||
|
|
||||||
#define PKT_HEADER_ELEMENTS 2
|
#define PKT_HEADER_ELEMENTS 2
|
||||||
|
@ -12,7 +13,6 @@ pkt_handler pkt_handlers[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t pkt_buffer[PKT_BUFSIZ];
|
uint8_t pkt_buffer[PKT_BUFSIZ];
|
||||||
uint8_t pkt_pack_buffer[PKT_BUFSIZ];
|
|
||||||
|
|
||||||
int32_t pkt_header_encode(pkt_header *table) {
|
int32_t pkt_header_encode(pkt_header *table) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -52,8 +52,11 @@ int32_t pkt_unpack_struct(cw_unpack_context *uc, pkt_desc *desc, void *raw_blob,
|
||||||
zpl_memcopy(blob + field->offset, (uint8_t*)&uc->item.as.u64, field->size);
|
zpl_memcopy(blob + field->offset, (uint8_t*)&uc->item.as.u64, field->size);
|
||||||
}break;
|
}break;
|
||||||
case CWP_ITEM_BIN: {
|
case CWP_ITEM_BIN: {
|
||||||
if (uc->item.as.bin.length != field->size) return -1; // bin size mismatch
|
if (uc->item.as.bin.length >= PKT_BUFSIZ) return -1; // bin blob too big
|
||||||
zpl_memcopy(blob + field->offset, (uint8_t*)uc->item.as.bin.start, uc->item.as.bin.length);
|
static uint8_t bin_buf[PKT_BUFSIZ] = {0};
|
||||||
|
uint32_t actual_size = decompress_rle(uc->item.as.bin.start, uc->item.as.bin.length, bin_buf);
|
||||||
|
if (actual_size != field->size) return -1; // bin size mismatch
|
||||||
|
zpl_memcopy(blob + field->offset, bin_buf, actual_size);
|
||||||
}break;
|
}break;
|
||||||
default: {
|
default: {
|
||||||
zpl_printf("[WARN] unsupported pkt field type %lld !\n", field->type);
|
zpl_printf("[WARN] unsupported pkt field type %lld !\n", field->type);
|
||||||
|
@ -67,11 +70,13 @@ int32_t pkt_unpack_struct(cw_unpack_context *uc, pkt_desc *desc, void *raw_blob,
|
||||||
|
|
||||||
int32_t pkt_pack_struct(cw_pack_context *pc, pkt_desc *desc, void *raw_blob, uint32_t blob_size) {
|
int32_t pkt_pack_struct(cw_pack_context *pc, pkt_desc *desc, void *raw_blob, uint32_t blob_size) {
|
||||||
uint8_t *blob = (uint8_t*)raw_blob;
|
uint8_t *blob = (uint8_t*)raw_blob;
|
||||||
zpl_zero_item(pkt_pack_buffer);
|
|
||||||
for (pkt_desc *field = desc; field->type != CWP_NOT_AN_ITEM; ++field) {
|
for (pkt_desc *field = desc; field->type != CWP_NOT_AN_ITEM; ++field) {
|
||||||
switch (field->type) {
|
switch (field->type) {
|
||||||
case CWP_ITEM_BIN: {
|
case CWP_ITEM_BIN: {
|
||||||
cw_pack_bin(pc, blob + field->offset, field->size);
|
if (field->size >= PKT_BUFSIZ) return -1; // bin blob too big
|
||||||
|
static uint8_t bin_buf[PKT_BUFSIZ] = {0};
|
||||||
|
uint32_t size = compress_rle(blob + field->offset, field->size, bin_buf);
|
||||||
|
cw_pack_bin(pc, bin_buf, size);
|
||||||
}break;
|
}break;
|
||||||
case CWP_ITEM_POSITIVE_INTEGER: {
|
case CWP_ITEM_POSITIVE_INTEGER: {
|
||||||
uint64_t num;
|
uint64_t num;
|
||||||
|
|
|
@ -29,6 +29,7 @@ int32_t pkt_header_decode(pkt_header *table, void *data, size_t datalen);
|
||||||
|
|
||||||
extern pkt_handler pkt_handlers[];
|
extern pkt_handler pkt_handlers[];
|
||||||
extern uint8_t pkt_buffer[];
|
extern uint8_t pkt_buffer[];
|
||||||
extern uint8_t pkt_pack_buffer[];
|
|
||||||
|
|
||||||
#include "packet_list.h"
|
// NOTE(zaklaus): packets
|
||||||
|
|
||||||
|
#include "pkt_01_welcome.h"
|
|
@ -4,18 +4,3 @@
|
||||||
|
|
||||||
// NOTE(zaklaus): pkt data
|
// NOTE(zaklaus): pkt data
|
||||||
|
|
||||||
#define PKT_01_NUMBERS_SIZ 32
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t chunk_size;
|
|
||||||
uint32_t chunk_amount;
|
|
||||||
uint16_t numbers[PKT_01_NUMBERS_SIZ];
|
|
||||||
} pkt_01_welcome;
|
|
||||||
|
|
||||||
size_t pkt_01_welcome_encode(pkt_01_welcome *table);
|
|
||||||
extern pkt_desc pkt_01_welcome_desc[];
|
|
||||||
|
|
||||||
// NOTE(zaklaus): pkt handlers
|
|
||||||
|
|
||||||
PKT_HANDLER_PROC(pkt_01_welcome_handler);
|
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
#include "packet.h"
|
#include "pkt_01_welcome.h"
|
||||||
#include "packet_utils.h"
|
|
||||||
|
|
||||||
pkt_desc pkt_01_welcome_desc[] = {
|
pkt_desc pkt_01_welcome_desc[] = {
|
||||||
{ PKT_FIELD(CWP_ITEM_POSITIVE_INTEGER, pkt_01_welcome, chunk_size) },
|
{ PKT_FIELD(CWP_ITEM_POSITIVE_INTEGER, pkt_01_welcome, chunk_size) },
|
||||||
{ PKT_FIELD(CWP_ITEM_POSITIVE_INTEGER, pkt_01_welcome, chunk_amount) },
|
{ PKT_FIELD(CWP_ITEM_POSITIVE_INTEGER, pkt_01_welcome, chunk_amount) },
|
||||||
{ PKT_ARRAY(pkt_01_welcome, numbers) },
|
{ PKT_ARRAY(pkt_01_welcome, numbers) },
|
||||||
|
{ PKT_ARRAY(pkt_01_welcome, structs) },
|
||||||
{ PKT_END },
|
{ PKT_END },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,17 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "packet_utils.h"
|
||||||
|
|
||||||
|
#define PKT_01_NUMBERS_SIZ 32
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t chunk_size;
|
||||||
|
uint32_t chunk_amount;
|
||||||
|
uint16_t numbers[PKT_01_NUMBERS_SIZ];
|
||||||
|
pkt_header structs[64];
|
||||||
|
} pkt_01_welcome;
|
||||||
|
|
||||||
|
size_t pkt_01_welcome_encode(pkt_01_welcome *table);
|
||||||
|
extern pkt_desc pkt_01_welcome_desc[];
|
||||||
|
|
||||||
|
PKT_HANDLER_PROC(pkt_01_welcome_handler);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue