Use a union in fieldset->value

Instead of unreliably casting uint64_t's to (void *)
This commit is contained in:
Eric 2013-10-03 21:53:42 -04:00
parent a74f1d877b
commit ae07374bb9
3 changed files with 36 additions and 23 deletions

View File

@ -36,7 +36,7 @@ fieldset_t *fs_new_fieldset(void)
} }
static inline void fs_add_word(fieldset_t *fs, const char *name, int type, static inline void fs_add_word(fieldset_t *fs, const char *name, int type,
int free_, size_t len, void *value) int free_, size_t len, field_val_t value)
{ {
if (fs->len + 1 >= MAX_FIELDS) { if (fs->len + 1 >= MAX_FIELDS) {
log_fatal("fieldset", "out of room in fieldset"); log_fatal("fieldset", "out of room in fieldset");
@ -46,24 +46,24 @@ static inline void fs_add_word(fieldset_t *fs, const char *name, int type,
f->type = type; f->type = type;
f->name = name; f->name = name;
f->len = len; f->len = len;
f->value = (uint64_t) value; f->value = value;
f->free_ = free_; f->free_ = free_;
} }
static void fs_modify_word(fieldset_t *fs, const char *name, int type, static void fs_modify_word(fieldset_t *fs, const char *name, int type,
int free_, size_t len, void *value) int free_, size_t len, field_val_t value)
{ {
int i; int i;
for (i=0; i<fs->len; i++) { for (i=0; i<fs->len; i++) {
if (!strcmp(fs->fields[i].name, name)) { if (!strcmp(fs->fields[i].name, name)) {
if (fs->fields[i].free_) { if (fs->fields[i].free_) {
free((void*)fs->fields[i].value); free(fs->fields[i].value.ptr);
fs->fields[i].value = 0; fs->fields[i].value.ptr = NULL;
} }
fs->fields[i].type = type; fs->fields[i].type = type;
fs->fields[i].free_ = free_; fs->fields[i].free_ = free_;
fs->fields[i].len = len; fs->fields[i].len = len;
fs->fields[i].value = (uint64_t)value; fs->fields[i].value = value;
return; return;
} }
} }
@ -72,55 +72,63 @@ static void fs_modify_word(fieldset_t *fs, const char *name, int type,
void fs_add_null(fieldset_t *fs, const char *name) void fs_add_null(fieldset_t *fs, const char *name)
{ {
fs_add_word(fs, name, FS_NULL, 0, 0, NULL); field_val_t val = { .ptr = NULL };
fs_add_word(fs, name, FS_NULL, 0, 0, val);
} }
void fs_add_string(fieldset_t *fs, const char *name, char *value, int free_) void fs_add_string(fieldset_t *fs, const char *name, char *value, int free_)
{ {
fs_add_word(fs, name, FS_STRING, free_, strlen(value), (void*) value); field_val_t val = { .ptr = value };
fs_add_word(fs, name, FS_STRING, free_, strlen(value), val);
} }
void fs_add_uint64(fieldset_t *fs, const char *name, uint64_t value) void fs_add_uint64(fieldset_t *fs, const char *name, uint64_t value)
{ {
fs_add_word(fs, name, FS_UINT64, 0, sizeof(uint64_t), (void*) value); field_val_t val = { .num = value };
fs_add_word(fs, name, FS_UINT64, 0, sizeof(uint64_t), val);
} }
void fs_add_binary(fieldset_t *fs, const char *name, size_t len, void fs_add_binary(fieldset_t *fs, const char *name, size_t len,
void *value, int free_) void *value, int free_)
{ {
fs_add_word(fs, name, FS_BINARY, free_, len, value); field_val_t val = { .ptr = value };
fs_add_word(fs, name, FS_BINARY, free_, len, val);
} }
// Modify // Modify
void fs_modify_null(fieldset_t *fs, const char *name) void fs_modify_null(fieldset_t *fs, const char *name)
{ {
fs_modify_word(fs, name, FS_NULL, 0, 0, NULL); field_val_t val = { .ptr = NULL };
fs_modify_word(fs, name, FS_NULL, 0, 0, val);
} }
void fs_modify_string(fieldset_t *fs, const char *name, char *value, int free_) void fs_modify_string(fieldset_t *fs, const char *name, char *value, int free_)
{ {
fs_modify_word(fs, name, FS_STRING, free_, strlen(value), (void*) value); field_val_t val = { .ptr = value };
fs_modify_word(fs, name, FS_STRING, free_, strlen(value), val);
} }
void fs_modify_uint64(fieldset_t *fs, const char *name, uint64_t value) void fs_modify_uint64(fieldset_t *fs, const char *name, uint64_t value)
{ {
fs_modify_word(fs, name, FS_UINT64, 0, sizeof(uint64_t), (void*) value); field_val_t val = { .num = value };
fs_modify_word(fs, name, FS_UINT64, 0, sizeof(uint64_t), val);
} }
void fs_modify_binary(fieldset_t *fs, const char *name, size_t len, void fs_modify_binary(fieldset_t *fs, const char *name, size_t len,
void *value, int free_) void *value, int free_)
{ {
fs_modify_word(fs, name, FS_BINARY, free_, len, value); field_val_t val = { .ptr = value };
fs_modify_word(fs, name, FS_BINARY, free_, len, val);
} }
uint64_t fs_get_uint64_by_index(fieldset_t *fs, int index) uint64_t fs_get_uint64_by_index(fieldset_t *fs, int index)
{ {
return (uint64_t) fs->fields[index].value; return (uint64_t) fs->fields[index].value.num;
} }
char* fs_get_string_by_index(fieldset_t *fs, int index) char* fs_get_string_by_index(fieldset_t *fs, int index)
{ {
return (char*) fs->fields[index].value; return (char*) fs->fields[index].value.ptr;
} }
int fds_get_index_by_name(fielddefset_t *fds, char *name) int fds_get_index_by_name(fielddefset_t *fds, char *name)
@ -141,7 +149,7 @@ void fs_free(fieldset_t *fs)
for (int i=0; i < fs->len; i++) { for (int i=0; i < fs->len; i++) {
field_t *f = &(fs->fields[i]); field_t *f = &(fs->fields[i]);
if (f->free_) { if (f->free_) {
free((void*) f->value); free(f->value.ptr);
} }
} }
free(fs); free(fs);

View File

@ -36,13 +36,18 @@ typedef struct fielddef_set {
int len; int len;
} fielddefset_t; } fielddefset_t;
typedef union field_val {
void *ptr;
uint64_t num;
} field_val_t;
// the internal field type used by fieldset // the internal field type used by fieldset
typedef struct field { typedef struct field {
const char *name; const char *name;
int type; int type;
int free_; int free_;
size_t len; size_t len;
uint64_t value; union field_val value;
} field_t; } field_t;
// data structure that is populated by the probe module // data structure that is populated by the probe module

View File

@ -79,11 +79,11 @@ int csv_process(fieldset_t *fs)
fprintf(file, ", "); fprintf(file, ", ");
} }
if (f->type == FS_STRING) { if (f->type == FS_STRING) {
fprintf(file, "%s", (char*) f->value); fprintf(file, "%s", (char*) f->value.ptr);
} else if (f->type == FS_UINT64) { } else if (f->type == FS_UINT64) {
fprintf(file, "%lu", (uint64_t) f->value); fprintf(file, "%llu", (uint64_t) f->value.num);
} else if (f->type == FS_BINARY) { } else if (f->type == FS_BINARY) {
hex_encode(file, (unsigned char*) f->value, f->len); hex_encode(file, (unsigned char*) f->value.ptr, f->len);
} else if (f->type == FS_NULL) { } else if (f->type == FS_NULL) {
// do nothing // do nothing
} else { } else {