mirror of
https://github.com/djhackersdev/saltytools.git
synced 2026-09-07 10:06:13 -05:00
feat(573file): add support for prop-valued arrays
This commit is contained in:
@@ -391,7 +391,7 @@ static int prop_binary_slice_value(struct prop_binary_parser *bp, uint8_t type,
|
||||
|
||||
orig_nbytes = prop_type_to_size(type);
|
||||
|
||||
if (orig_nbytes < 0) {
|
||||
if (orig_nbytes < 0 || prop_type_is_array(type)) {
|
||||
is_variable = true;
|
||||
r = iobuf_read_be32(&bp->body, &nbytes);
|
||||
|
||||
|
||||
@@ -22,7 +22,13 @@ static const int prop_type_sizes[64] = {
|
||||
[PROP_ATTR] = -1, [PROP_BOOL] = 1,
|
||||
};
|
||||
|
||||
bool prop_type_is_array(enum prop_type type) {
|
||||
return (type & PROP_ARRAY_FLAG) != 0;
|
||||
}
|
||||
|
||||
bool prop_type_is_valid(enum prop_type type) {
|
||||
type &= ~PROP_ARRAY_FLAG;
|
||||
|
||||
if (type < 0 || type >= lengthof(prop_type_names)) {
|
||||
return false;
|
||||
}
|
||||
@@ -33,11 +39,11 @@ bool prop_type_is_valid(enum prop_type type) {
|
||||
const char *prop_type_to_string(enum prop_type type) {
|
||||
assert(prop_type_is_valid(type));
|
||||
|
||||
return prop_type_names[type];
|
||||
return prop_type_names[type & ~PROP_ARRAY_FLAG];
|
||||
}
|
||||
|
||||
int prop_type_to_size(enum prop_type type) {
|
||||
assert(type == PROP_ATTR /* hack */ || prop_type_is_valid(type));
|
||||
|
||||
return prop_type_sizes[type];
|
||||
return prop_type_sizes[type & ~PROP_ARRAY_FLAG];
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ enum prop_type {
|
||||
PROP_ARRAY_FLAG = 0x40
|
||||
};
|
||||
|
||||
bool prop_type_is_array(enum prop_type type);
|
||||
bool prop_type_is_valid(enum prop_type type);
|
||||
const char *prop_type_to_string(enum prop_type type);
|
||||
int prop_type_to_size(enum prop_type type);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "573file/prop-type.h"
|
||||
#include "573file/prop-xml-writer.h"
|
||||
#include "573file/prop.h"
|
||||
|
||||
@@ -26,6 +27,10 @@ static void prop_xml_write_void(struct strbuf *dest, const struct prop *p,
|
||||
unsigned int indent);
|
||||
static void prop_xml_write_text(struct strbuf *dest, const struct prop *p,
|
||||
enum prop_xml_escape ctx);
|
||||
static void prop_xml_write_text_element(struct strbuf *dest,
|
||||
enum prop_type type,
|
||||
struct const_iobuf *src,
|
||||
enum prop_xml_escape ctx);
|
||||
static void prop_xml_write_text_s8(struct strbuf *dest,
|
||||
struct const_iobuf *src);
|
||||
static void prop_xml_write_text_s16(struct strbuf *dest,
|
||||
@@ -154,6 +159,10 @@ static void prop_xml_write_nonvoid(struct strbuf *dest, const struct prop *p,
|
||||
prop_xml_write_indent(dest, indent);
|
||||
strbuf_printf(dest, "<%s __type=\"%s\"", name, type_str);
|
||||
|
||||
if (prop_type_is_array(type)) {
|
||||
strbuf_printf(dest, " __count=\"%lu\"", (unsigned long)prop_get_count(p));
|
||||
}
|
||||
|
||||
first_child = prop_get_first_child_const(p);
|
||||
|
||||
if (first_child != NULL) {
|
||||
@@ -275,91 +284,124 @@ static void prop_xml_write_indent(struct strbuf *dest, unsigned int indent) {
|
||||
|
||||
static void prop_xml_write_text(struct strbuf *dest, const struct prop *p,
|
||||
enum prop_xml_escape ctx) {
|
||||
struct const_iobuf src;
|
||||
struct const_iobuf value;
|
||||
struct const_iobuf item;
|
||||
enum prop_type type;
|
||||
uint32_t count;
|
||||
uint32_t i;
|
||||
int item_size;
|
||||
int r;
|
||||
|
||||
type = prop_get_type(p);
|
||||
prop_borrow_value(p, &src);
|
||||
prop_borrow_value(p, &value);
|
||||
|
||||
if (prop_type_is_array(type)) {
|
||||
item_size = prop_type_to_size(type);
|
||||
count = prop_get_count(p);
|
||||
|
||||
assert(item_size > 0);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (i > 0) {
|
||||
strbuf_putc(dest, ' ');
|
||||
}
|
||||
|
||||
r = iobuf_slice(&item, &value, item_size);
|
||||
|
||||
assert(r >= 0);
|
||||
|
||||
prop_xml_write_text_element(dest, type, &item, ctx);
|
||||
}
|
||||
} else {
|
||||
prop_xml_write_text_element(dest, type, &value, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
static void prop_xml_write_text_element(struct strbuf *dest,
|
||||
enum prop_type type,
|
||||
struct const_iobuf *src,
|
||||
enum prop_xml_escape ctx) {
|
||||
type &= ~PROP_ARRAY_FLAG;
|
||||
|
||||
switch (type) {
|
||||
case PROP_S8:
|
||||
prop_xml_write_text_s8(dest, &src);
|
||||
prop_xml_write_text_s8(dest, src);
|
||||
|
||||
break;
|
||||
|
||||
case PROP_S16:
|
||||
prop_xml_write_text_s16(dest, &src);
|
||||
prop_xml_write_text_s16(dest, src);
|
||||
|
||||
break;
|
||||
|
||||
case PROP_S32:
|
||||
prop_xml_write_text_s32(dest, &src);
|
||||
prop_xml_write_text_s32(dest, src);
|
||||
|
||||
break;
|
||||
|
||||
case PROP_S64:
|
||||
prop_xml_write_text_s64(dest, &src);
|
||||
prop_xml_write_text_s64(dest, src);
|
||||
|
||||
break;
|
||||
|
||||
case PROP_U8:
|
||||
prop_xml_write_text_u8(dest, &src);
|
||||
prop_xml_write_text_u8(dest, src);
|
||||
|
||||
break;
|
||||
|
||||
case PROP_U16:
|
||||
prop_xml_write_text_u16(dest, &src);
|
||||
prop_xml_write_text_u16(dest, src);
|
||||
|
||||
break;
|
||||
|
||||
case PROP_U32:
|
||||
prop_xml_write_text_u32(dest, &src);
|
||||
prop_xml_write_text_u32(dest, src);
|
||||
|
||||
break;
|
||||
|
||||
case PROP_U64:
|
||||
prop_xml_write_text_u64(dest, &src);
|
||||
prop_xml_write_text_u64(dest, src);
|
||||
|
||||
break;
|
||||
|
||||
case PROP_BIN:
|
||||
prop_xml_write_text_bin(dest, &src);
|
||||
prop_xml_write_text_bin(dest, src);
|
||||
|
||||
break;
|
||||
|
||||
case PROP_STR:
|
||||
prop_xml_write_text_str(dest, &src, ctx);
|
||||
prop_xml_write_text_str(dest, src, ctx);
|
||||
|
||||
break;
|
||||
|
||||
case PROP_IP4:
|
||||
prop_xml_write_text_ip4(dest, &src);
|
||||
prop_xml_write_text_ip4(dest, src);
|
||||
|
||||
break;
|
||||
|
||||
case PROP_TIME:
|
||||
/* Reuse the u32 writer for timestamps */
|
||||
prop_xml_write_text_u32(dest, &src);
|
||||
prop_xml_write_text_u32(dest, src);
|
||||
|
||||
break;
|
||||
|
||||
case PROP_2U16:
|
||||
prop_xml_write_text_u16_tuple(dest, &src, 2);
|
||||
prop_xml_write_text_u16_tuple(dest, src, 2);
|
||||
|
||||
break;
|
||||
|
||||
case PROP_3S32:
|
||||
prop_xml_write_text_s32_tuple(dest, &src, 3);
|
||||
prop_xml_write_text_s32_tuple(dest, src, 3);
|
||||
|
||||
break;
|
||||
|
||||
case PROP_4U16:
|
||||
prop_xml_write_text_u16_tuple(dest, &src, 4);
|
||||
prop_xml_write_text_u16_tuple(dest, src, 4);
|
||||
|
||||
break;
|
||||
|
||||
case PROP_BOOL:
|
||||
prop_xml_write_text_bool(dest, &src);
|
||||
prop_xml_write_text_bool(dest, src);
|
||||
|
||||
break;
|
||||
|
||||
|
||||
@@ -37,13 +37,8 @@ static int prop_validate(const char *name, enum prop_type type,
|
||||
static int prop_validate(const char *name, enum prop_type type,
|
||||
const void *bytes, uint32_t nbytes) {
|
||||
const char *chars;
|
||||
int expected_nbytes;
|
||||
|
||||
if (type & PROP_ARRAY_FLAG) {
|
||||
log_write("\"%s\": Arrays are not currently supported", name);
|
||||
|
||||
return -ENOTSUP;
|
||||
}
|
||||
const char *type_str;
|
||||
int item_size;
|
||||
|
||||
if (!prop_type_is_valid(type)) {
|
||||
log_write("\"%s\": Unsupported type code %#x", name, type);
|
||||
@@ -51,13 +46,30 @@ static int prop_validate(const char *name, enum prop_type type,
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
expected_nbytes = prop_type_to_size(type);
|
||||
item_size = prop_type_to_size(type);
|
||||
type_str = prop_type_to_string(type);
|
||||
|
||||
if (expected_nbytes >= 0 && nbytes != expected_nbytes) {
|
||||
log_write("\"%s\": Incorrect size %#x for type %s (expected %#x)", name,
|
||||
nbytes, prop_type_to_string(type), expected_nbytes);
|
||||
if (prop_type_is_array(type)) {
|
||||
if (item_size <= 0) {
|
||||
log_write("\"%s\": Nonsensical array type %#x", name, type);
|
||||
|
||||
return -EINVAL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (nbytes % item_size != 0) {
|
||||
log_write(
|
||||
"\"%s\": %s item size %i does not divide value length %#x evenly",
|
||||
name, type_str, item_size, nbytes);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
if (item_size >= 0 && nbytes != item_size) {
|
||||
log_write("\"%s\": Incorrect size %#x for type %s (expected %#x)", name,
|
||||
nbytes, type_str, item_size);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (type == PROP_STR) {
|
||||
@@ -194,6 +206,20 @@ const char *prop_get_attr(const struct prop *p, const char *key) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t prop_get_count(const struct prop *p) {
|
||||
int item_size;
|
||||
|
||||
assert(p != NULL);
|
||||
assert(prop_type_is_array(p->type));
|
||||
|
||||
item_size = prop_type_to_size(p->type);
|
||||
|
||||
assert(item_size > 0);
|
||||
assert(p->nbytes % item_size == 0);
|
||||
|
||||
return p->nbytes / item_size;
|
||||
}
|
||||
|
||||
const struct attr *prop_get_first_attr(const struct prop *p) {
|
||||
struct list_node *attr;
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ void prop_free(struct prop *p);
|
||||
void prop_append(struct prop *p, struct prop *child);
|
||||
void prop_borrow_value(const struct prop *p, struct const_iobuf *out);
|
||||
const char *prop_get_attr(const struct prop *p, const char *key);
|
||||
uint32_t prop_get_count(const struct prop *p);
|
||||
const struct attr *prop_get_first_attr(const struct prop *p);
|
||||
struct prop *prop_get_first_child(struct prop *p);
|
||||
const struct prop *prop_get_first_child_const(const struct prop *p);
|
||||
|
||||
Reference in New Issue
Block a user