Format
This commit is contained in:
+157
-151
@@ -1,21 +1,21 @@
|
||||
|
||||
#include "iron_armpack.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "iron_gc.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static const int PTR_SIZE = 8;
|
||||
static uint32_t di; // Decoded index
|
||||
static uint32_t ei; // Encoded index
|
||||
static uint32_t bottom; // Decoded bottom
|
||||
static uint8_t *decoded;
|
||||
static uint8_t *encoded;
|
||||
static uint32_t capacity;
|
||||
static uint32_t array_count;
|
||||
static uint32_t string_length;
|
||||
static void read_store();
|
||||
static uint32_t di; // Decoded index
|
||||
static uint32_t ei; // Encoded index
|
||||
static uint32_t bottom; // Decoded bottom
|
||||
static uint8_t *decoded;
|
||||
static uint8_t *encoded;
|
||||
static uint32_t capacity;
|
||||
static uint32_t array_count;
|
||||
static uint32_t string_length;
|
||||
static void read_store();
|
||||
|
||||
static inline uint64_t pad(int di, int n) {
|
||||
return (n - (di % n)) % n;
|
||||
@@ -73,10 +73,10 @@ static void store_string(char *str) {
|
||||
// Put string at the bottom and store a pointer to it
|
||||
store_ptr(bottom);
|
||||
uint32_t _di = di;
|
||||
di = bottom;
|
||||
di = bottom;
|
||||
store_string_bytes(str);
|
||||
bottom = pad(di, PTR_SIZE) + di;
|
||||
di = _di;
|
||||
di = _di;
|
||||
}
|
||||
|
||||
static uint8_t read_u8() {
|
||||
@@ -111,7 +111,7 @@ static float read_f32() {
|
||||
|
||||
static char *read_string() {
|
||||
string_length = read_u32();
|
||||
char *str = (char *)(encoded + ei);
|
||||
char *str = (char *)(encoded + ei);
|
||||
ei += string_length;
|
||||
return str;
|
||||
}
|
||||
@@ -132,20 +132,20 @@ static uint32_t traverse(int di, bool count_arrays) {
|
||||
ei += 4;
|
||||
return pad(di, 4) + 4;
|
||||
case 0xdf: { // map
|
||||
uint32_t len = 0;
|
||||
int count = read_i32();
|
||||
uint32_t len = 0;
|
||||
int count = read_i32();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
read_u8(); // 0xdb string
|
||||
read_string(); // key
|
||||
read_u8(); // 0xdb string
|
||||
read_string(); // key
|
||||
len += traverse(di + len, count_arrays); // value
|
||||
}
|
||||
len += pad(di + len, PTR_SIZE) + PTR_SIZE; // void *_
|
||||
return len;
|
||||
}
|
||||
case 0xdd: { // array
|
||||
uint32_t len = 0;
|
||||
uint32_t len = 0;
|
||||
uint32_t count = read_u32();
|
||||
uint8_t flag2 = count > 0 ? read_u8() : 0x0;
|
||||
uint8_t flag2 = count > 0 ? read_u8() : 0x0;
|
||||
switch (flag2) {
|
||||
case 0x0: // Empty array
|
||||
break;
|
||||
@@ -175,7 +175,7 @@ static uint32_t traverse(int di, bool count_arrays) {
|
||||
ei += count;
|
||||
len += count;
|
||||
break;
|
||||
default: // Dynamic (type (array / map / string) - value)
|
||||
default: // Dynamic (type (array / map / string) - value)
|
||||
ei -= 1; // Undo flag2 read
|
||||
for (uint32_t j = 0; j < count; ++j) {
|
||||
len += traverse(0, count_arrays);
|
||||
@@ -189,7 +189,7 @@ static uint32_t traverse(int di, bool count_arrays) {
|
||||
len += pad(di, PTR_SIZE) + PTR_SIZE;
|
||||
return len;
|
||||
}
|
||||
case 0xdb: { // string
|
||||
case 0xdb: { // string
|
||||
uint32_t len = read_u32(); // string_length
|
||||
ei += len;
|
||||
len += 1; // '\0'
|
||||
@@ -207,7 +207,7 @@ static uint32_t traverse(int di, bool count_arrays) {
|
||||
static uint32_t get_struct_length() {
|
||||
uint32_t _ei = ei;
|
||||
uint32_t len = traverse(0, false);
|
||||
ei = _ei;
|
||||
ei = _ei;
|
||||
return len;
|
||||
}
|
||||
|
||||
@@ -220,9 +220,9 @@ static void read_store_map(uint32_t count) {
|
||||
ei += 5;
|
||||
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
read_u8(); // 0xdb string
|
||||
read_u8(); // 0xdb string
|
||||
read_string(); // key
|
||||
read_store(); // value
|
||||
read_store(); // value
|
||||
}
|
||||
di += pad(di, PTR_SIZE);
|
||||
di += PTR_SIZE; // void *_ for runtime storage
|
||||
@@ -233,12 +233,18 @@ static bool is_typed_array(uint8_t flag) {
|
||||
}
|
||||
|
||||
static uint8_t flag_to_byte_size(uint8_t flag) {
|
||||
if (flag == 0xca) return 4; // f32
|
||||
if (flag == 0xd2) return 4; // i32
|
||||
if (flag == 0xd1) return 2; // i16
|
||||
if (flag == 0xc4) return 1; // u8
|
||||
if (flag == 0xc2) return 1; // u8 (true)
|
||||
if (flag == 0xc3) return 1; // u8 (false)
|
||||
if (flag == 0xca)
|
||||
return 4; // f32
|
||||
if (flag == 0xd2)
|
||||
return 4; // i32
|
||||
if (flag == 0xd1)
|
||||
return 2; // i16
|
||||
if (flag == 0xc4)
|
||||
return 1; // u8
|
||||
if (flag == 0xc2)
|
||||
return 1; // u8 (true)
|
||||
if (flag == 0xc3)
|
||||
return 1; // u8 (false)
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -262,7 +268,7 @@ static void read_store_array(uint32_t count) { // Store in any/i32/../_array_t f
|
||||
store_ptr(bottom);
|
||||
|
||||
uint32_t _di = di;
|
||||
di = bottom;
|
||||
di = bottom;
|
||||
|
||||
if (count > 0) {
|
||||
store_ptr(di + PTR_SIZE + 4 + 4); // Pointer to buffer contents
|
||||
@@ -271,7 +277,7 @@ static void read_store_array(uint32_t count) { // Store in any/i32/../_array_t f
|
||||
store_ptr_abs(NULL);
|
||||
}
|
||||
store_u32(count); // Element count
|
||||
store_u32(0); // Capacity = 0 -> do not free on first realloc
|
||||
store_u32(0); // Capacity = 0 -> do not free on first realloc
|
||||
bottom = di;
|
||||
|
||||
if (count == 0) {
|
||||
@@ -294,12 +300,12 @@ static void read_store_array(uint32_t count) { // Store in any/i32/../_array_t f
|
||||
// Strings
|
||||
if (flag == 0xdb) {
|
||||
// String pointers
|
||||
uint32_t _ei = ei;
|
||||
uint32_t _ei = ei;
|
||||
uint32_t strings_length = 0;
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
store_ptr(bottom + count * PTR_SIZE + strings_length);
|
||||
if (i < count - 1) {
|
||||
ei += 1; // String flag
|
||||
ei += 1; // String flag
|
||||
uint32_t length = read_u32(); // String length
|
||||
ei += length;
|
||||
strings_length += length;
|
||||
@@ -318,12 +324,12 @@ static void read_store_array(uint32_t count) { // Store in any/i32/../_array_t f
|
||||
// Arrays
|
||||
else if (flag == 0xdd) {
|
||||
// Array pointers
|
||||
uint32_t _ei = ei;
|
||||
uint32_t _ei = ei;
|
||||
uint32_t arrays_length = 0;
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
store_ptr(bottom + count * PTR_SIZE + arrays_length);
|
||||
if (i < count - 1) {
|
||||
ei += 1; // Array flag
|
||||
ei += 1; // Array flag
|
||||
uint32_t length = read_u32(); // Array length
|
||||
ei += length;
|
||||
length += pad(length, PTR_SIZE);
|
||||
@@ -359,7 +365,7 @@ static void read_store_array(uint32_t count) { // Store in any/i32/../_array_t f
|
||||
array_count = count;
|
||||
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
di = pad(di, PTR_SIZE) + di;
|
||||
di = pad(di, PTR_SIZE) + di;
|
||||
uint8_t flag = read_u8();
|
||||
read_store_map(read_i32());
|
||||
}
|
||||
@@ -402,14 +408,14 @@ static void read_store() {
|
||||
}
|
||||
|
||||
static void reset() {
|
||||
di = 0;
|
||||
ei = 0;
|
||||
di = 0;
|
||||
ei = 0;
|
||||
bottom = 0;
|
||||
}
|
||||
|
||||
void *armpack_decode(buffer_t *b) {
|
||||
reset();
|
||||
encoded = b->buffer;
|
||||
encoded = b->buffer;
|
||||
capacity = traverse(0, true);
|
||||
reset();
|
||||
decoded = gc_alloc(capacity);
|
||||
@@ -419,7 +425,7 @@ void *armpack_decode(buffer_t *b) {
|
||||
|
||||
void armpack_encode_start(void *_encoded) {
|
||||
encoded = _encoded;
|
||||
ei = 0;
|
||||
ei = 0;
|
||||
}
|
||||
|
||||
int armpack_encode_end() {
|
||||
@@ -597,7 +603,7 @@ uint32_t armpack_size_bool() {
|
||||
}
|
||||
|
||||
static char *read_string_alloc() {
|
||||
char *s = read_string();
|
||||
char *s = read_string();
|
||||
char *allocated = gc_alloc(string_length + 1);
|
||||
memcpy(allocated, s, string_length);
|
||||
allocated[string_length] = '\0';
|
||||
@@ -608,14 +614,14 @@ typedef union ptr_storage {
|
||||
void *p;
|
||||
struct {
|
||||
float f;
|
||||
int type; // 0 - float, 1 - int
|
||||
int type; // 0 - float, 1 - int
|
||||
};
|
||||
int i;
|
||||
} ptr_storage_t;
|
||||
|
||||
any_map_t *_armpack_decode_to_map() {
|
||||
any_map_t *result = any_map_create();
|
||||
uint32_t count = read_u32();
|
||||
uint32_t count = read_u32();
|
||||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
read_u8(); // 0xdb string
|
||||
@@ -623,120 +629,120 @@ any_map_t *_armpack_decode_to_map() {
|
||||
|
||||
uint8_t flag = read_u8();
|
||||
switch (flag) {
|
||||
case 0xc0: { // NULL
|
||||
any_map_set(result, key, NULL);
|
||||
break;
|
||||
case 0xc0: { // NULL
|
||||
any_map_set(result, key, NULL);
|
||||
break;
|
||||
}
|
||||
case 0xc2: { // false
|
||||
ptr_storage_t s;
|
||||
s.i = 0;
|
||||
s.type = 1;
|
||||
any_map_set(result, key, s.p);
|
||||
break;
|
||||
}
|
||||
case 0xc3: { // true
|
||||
ptr_storage_t s;
|
||||
s.i = 1;
|
||||
s.type = 1;
|
||||
any_map_set(result, key, s.p);
|
||||
break;
|
||||
}
|
||||
case 0xca: { // f32
|
||||
ptr_storage_t s;
|
||||
s.f = read_f32();
|
||||
s.type = 0;
|
||||
any_map_set(result, key, s.p);
|
||||
break;
|
||||
}
|
||||
case 0xd2: { // i32
|
||||
ptr_storage_t s;
|
||||
s.i = read_i32();
|
||||
s.type = 1;
|
||||
any_map_set(result, key, s.p);
|
||||
break;
|
||||
}
|
||||
case 0xdb: { // string
|
||||
any_map_set(result, key, read_string_alloc());
|
||||
break;
|
||||
}
|
||||
case 0xdf: { // map
|
||||
any_map_t *nested_map = _armpack_decode_to_map();
|
||||
any_map_set(result, key, nested_map);
|
||||
break;
|
||||
}
|
||||
case 0xdd: { // array
|
||||
uint32_t array_count = read_u32();
|
||||
uint8_t element_flag = read_u8();
|
||||
if (element_flag == 0xca) { // f32
|
||||
f32_array_t *array = f32_array_create(array_count);
|
||||
for (uint32_t j = 0; j < array_count; j++) {
|
||||
array->buffer[j] = read_f32();
|
||||
}
|
||||
any_map_set(result, key, array);
|
||||
}
|
||||
case 0xc2: { // false
|
||||
ptr_storage_t s;
|
||||
s.i = 0;
|
||||
s.type = 1;
|
||||
any_map_set(result, key, s.p);
|
||||
break;
|
||||
else if (element_flag == 0xd2) { // i32
|
||||
i32_array_t *array = i32_array_create(array_count);
|
||||
for (uint32_t j = 0; j < array_count; j++) {
|
||||
array->buffer[j] = read_i32();
|
||||
}
|
||||
any_map_set(result, key, array);
|
||||
}
|
||||
case 0xc3: { // true
|
||||
ptr_storage_t s;
|
||||
s.i = 1;
|
||||
s.type = 1;
|
||||
any_map_set(result, key, s.p);
|
||||
break;
|
||||
else if (element_flag == 0xd1) { // i16
|
||||
i16_array_t *array = i16_array_create(array_count);
|
||||
for (uint32_t j = 0; j < array_count; j++) {
|
||||
array->buffer[j] = read_i16();
|
||||
}
|
||||
any_map_set(result, key, array);
|
||||
}
|
||||
case 0xca: { // f32
|
||||
ptr_storage_t s;
|
||||
s.f = read_f32();
|
||||
s.type = 0;
|
||||
any_map_set(result, key, s.p);
|
||||
break;
|
||||
else if (element_flag == 0xc4) { // u8
|
||||
u8_array_t *array = u8_array_create(array_count);
|
||||
for (uint32_t j = 0; j < array_count; j++) {
|
||||
array->buffer[j] = read_u8();
|
||||
}
|
||||
any_map_set(result, key, array);
|
||||
}
|
||||
case 0xd2: { // i32
|
||||
ptr_storage_t s;
|
||||
s.i = read_i32();
|
||||
s.type = 1;
|
||||
any_map_set(result, key, s.p);
|
||||
break;
|
||||
else if (element_flag == 0xdb) { // string
|
||||
ei--;
|
||||
char_ptr_array_t *array = char_ptr_array_create(array_count);
|
||||
for (uint32_t j = 0; j < array_count; j++) {
|
||||
read_u8(); // flag
|
||||
array->buffer[j] = read_string_alloc();
|
||||
}
|
||||
any_map_set(result, key, array);
|
||||
}
|
||||
case 0xdb: { // string
|
||||
any_map_set(result, key, read_string_alloc());
|
||||
break;
|
||||
else if (element_flag == 0xdf) { // map
|
||||
ei--;
|
||||
any_array_t *array = any_array_create(array_count);
|
||||
for (uint32_t j = 0; j < array_count; j++) {
|
||||
read_u8(); // flag
|
||||
array->buffer[j] = _armpack_decode_to_map();
|
||||
}
|
||||
any_map_set(result, key, array);
|
||||
}
|
||||
case 0xdf: { // map
|
||||
any_map_t *nested_map = _armpack_decode_to_map();
|
||||
any_map_set(result, key, nested_map);
|
||||
break;
|
||||
}
|
||||
case 0xdd: { // array
|
||||
uint32_t array_count = read_u32();
|
||||
uint8_t element_flag = read_u8();
|
||||
if (element_flag == 0xca) { // f32
|
||||
f32_array_t *array = f32_array_create(array_count);
|
||||
for (uint32_t j = 0; j < array_count; j++) {
|
||||
array->buffer[j] = read_f32();
|
||||
else if (element_flag == 0xc6) { // buffer_t (deprecated)
|
||||
ei--;
|
||||
any_array_t *array = any_array_create(array_count);
|
||||
for (uint32_t j = 0; j < array_count; j++) {
|
||||
read_u8(); // flag
|
||||
uint32_t buffer_size = read_u32();
|
||||
buffer_t *buffer = buffer_create(buffer_size);
|
||||
for (uint32_t k = 0; k < buffer_size; k++) {
|
||||
buffer->buffer[k] = read_u8();
|
||||
}
|
||||
any_map_set(result, key, array);
|
||||
array->buffer[j] = buffer;
|
||||
}
|
||||
else if (element_flag == 0xd2) { // i32
|
||||
i32_array_t *array = i32_array_create(array_count);
|
||||
for (uint32_t j = 0; j < array_count; j++) {
|
||||
array->buffer[j] = read_i32();
|
||||
}
|
||||
any_map_set(result, key, array);
|
||||
}
|
||||
else if (element_flag == 0xd1) { // i16
|
||||
i16_array_t *array = i16_array_create(array_count);
|
||||
for (uint32_t j = 0; j < array_count; j++) {
|
||||
array->buffer[j] = read_i16();
|
||||
}
|
||||
any_map_set(result, key, array);
|
||||
}
|
||||
else if (element_flag == 0xc4) { // u8
|
||||
u8_array_t *array = u8_array_create(array_count);
|
||||
for (uint32_t j = 0; j < array_count; j++) {
|
||||
array->buffer[j] = read_u8();
|
||||
}
|
||||
any_map_set(result, key, array);
|
||||
}
|
||||
else if (element_flag == 0xdb) { // string
|
||||
ei--;
|
||||
char_ptr_array_t *array = char_ptr_array_create(array_count);
|
||||
for (uint32_t j = 0; j < array_count; j++) {
|
||||
read_u8(); // flag
|
||||
array->buffer[j] = read_string_alloc();
|
||||
}
|
||||
any_map_set(result, key, array);
|
||||
}
|
||||
else if (element_flag == 0xdf) { // map
|
||||
ei--;
|
||||
any_array_t *array = any_array_create(array_count);
|
||||
for (uint32_t j = 0; j < array_count; j++) {
|
||||
read_u8(); // flag
|
||||
array->buffer[j] = _armpack_decode_to_map();
|
||||
}
|
||||
any_map_set(result, key, array);
|
||||
}
|
||||
else if (element_flag == 0xc6) { // buffer_t (deprecated)
|
||||
ei--;
|
||||
any_array_t *array = any_array_create(array_count);
|
||||
for (uint32_t j = 0; j < array_count; j++) {
|
||||
read_u8(); // flag
|
||||
uint32_t buffer_size = read_u32();
|
||||
buffer_t *buffer = buffer_create(buffer_size);
|
||||
for (uint32_t k = 0; k < buffer_size; k++) {
|
||||
buffer->buffer[k] = read_u8();
|
||||
}
|
||||
array->buffer[j] = buffer;
|
||||
}
|
||||
any_map_set(result, key, array);
|
||||
}
|
||||
break;
|
||||
any_map_set(result, key, array);
|
||||
}
|
||||
case 0xc6: { // buffer_t (deprecated)
|
||||
uint32_t buffer_size = read_u32();
|
||||
buffer_t *buffer = buffer_create(buffer_size);
|
||||
for (uint32_t j = 0; j < buffer_size; j++) {
|
||||
buffer->buffer[j] = read_u8();
|
||||
}
|
||||
any_map_set(result, key, buffer);
|
||||
break;
|
||||
}
|
||||
case 0xc6: { // buffer_t (deprecated)
|
||||
uint32_t buffer_size = read_u32();
|
||||
buffer_t *buffer = buffer_create(buffer_size);
|
||||
for (uint32_t j = 0; j < buffer_size; j++) {
|
||||
buffer->buffer[j] = read_u8();
|
||||
}
|
||||
any_map_set(result, key, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -745,7 +751,7 @@ any_map_t *_armpack_decode_to_map() {
|
||||
|
||||
any_map_t *armpack_decode_to_map(buffer_t *b) {
|
||||
encoded = b->buffer;
|
||||
ei = 0;
|
||||
ei = 0;
|
||||
read_u8(); // Must be 0xdf for a map
|
||||
return _armpack_decode_to_map();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user