mirror of
https://github.com/sigmasternchen/libargo
synced 2025-03-15 05:08:54 +00:00
library function for managing marshallers looks good
This commit is contained in:
parent
e64d22b9d1
commit
35b7abea9a
3 changed files with 184 additions and 3 deletions
166
marshaller/marshaller.c
Normal file
166
marshaller/marshaller.c
Normal file
|
@ -0,0 +1,166 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <json.h>
|
||||
|
||||
#include "marshaller.h"
|
||||
|
||||
void _marshallPanic(const char* name, const char* reason) {
|
||||
if (reason == NULL) {
|
||||
reason = strerror(errno);
|
||||
}
|
||||
|
||||
fprintf(stderr, "panic: marshaller (%s): %s\n", name, reason);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
static struct marshaller {
|
||||
const char* name;
|
||||
(jsonValue_t*) (*marshaller)(void*);
|
||||
(void*) (*unmarshaller)(jsonValue_t*);
|
||||
}* marshallerList = NULL;
|
||||
static size_t marshallerListLength = 0;
|
||||
|
||||
static struct marshaller* findMarshaller(const char* type) {
|
||||
for (size_t i = 0; i < marshallerListLength; i++) {
|
||||
if (strcmp(type, marshallerList[i].name) == 0) {
|
||||
return &marshallerList[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _registerMarshaller(int namesCount, const char** names, (jsonValue_t*) (*marshaller)(void*), (void*) (*unmarshaller)(jsonValue_t*)) {
|
||||
marshallerList = realloc(marshallerList, (sizeof(struct marshaller)) * (marshallerListLength + namesCount));
|
||||
if (marshallerList == NULL) {
|
||||
_marshallPanic(names[0], NULL);
|
||||
}
|
||||
|
||||
for (int i = 0; i < namesCount; i++) {
|
||||
if (findMarshaller(names[i])) {
|
||||
_marshallPanic(names[i], "marshaller for name already present");
|
||||
}
|
||||
|
||||
marshallerList[marshallerListeLength++] = (struct marshaller) {
|
||||
.name = names[i],
|
||||
.marshaller = marshaller,
|
||||
.unmarshaller = unmarshaller
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
static jsonValue_t* json_marshall_long(void* value) {
|
||||
return json_long(*((long*) value));
|
||||
}
|
||||
|
||||
static jsonValue_t* json_marshall_double(void* value) {
|
||||
return json_long(*((double*) value));
|
||||
}
|
||||
|
||||
static jsonValue_t* json_marshall_string(void* value) {
|
||||
return json_string((const char*) value);
|
||||
}
|
||||
|
||||
static jsonValue_t* json_marshall_bool(void* value) {
|
||||
return json_bool((const char*) value);
|
||||
}
|
||||
|
||||
jsonValue_t* _json_marshall_value(const char* type, void* value) {
|
||||
if (value == NULL) {
|
||||
return json_null();
|
||||
} else if (strcmp(type, "long") == 0) {
|
||||
return json_marshall_long(value);
|
||||
} else if (strcmp(type, "double") == 0) {
|
||||
return json_marshall_double(value);
|
||||
} else if (strcmp(type, "string") == 0) {
|
||||
return json_marshall_string(value);
|
||||
} else if (strcmp(type, "bool") == 0) {
|
||||
return json_marshall_bool(value);
|
||||
} else {
|
||||
struct marshaller marshaller = findMarshaller(type);
|
||||
if (marshaller == NULL) {
|
||||
_marshallPanic(type, "unknown type");
|
||||
}
|
||||
return marshaller->marshaller(value);
|
||||
}
|
||||
}
|
||||
char* _json_marshall(const char* type, void* value) {
|
||||
return json_stringify(_json_marshall_value(type, value));
|
||||
}
|
||||
|
||||
static void* json_unmarshall_long(jsonValue_t* value) {
|
||||
if (value->type != JSON_LONG)
|
||||
return NULL;
|
||||
|
||||
long long* tmp = malloc(sizeof(long long));
|
||||
if (tmp == NULL)
|
||||
return NULL;
|
||||
|
||||
*tmp = value->value.integer;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static void* json_unmarshall_long(jsonValue_t* value) {
|
||||
if (value->type != JSON_DOUBLE)
|
||||
return NULL;
|
||||
|
||||
double* tmp = malloc(sizeof(double));
|
||||
if (tmp == NULL)
|
||||
return NULL;
|
||||
|
||||
*tmp = value->value.double;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static void* json_unmarshall_bool(jsonValue_t* value) {
|
||||
if (value->type != JSON_BOOL)
|
||||
return NULL;
|
||||
|
||||
bool* tmp = malloc(sizeof(bool));
|
||||
if (tmp == NULL)
|
||||
return NULL;
|
||||
|
||||
*tmp = value->value.boolean;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static void* json_unmarshall_long(jsonValue_t* value) {
|
||||
if (value->type != JSON_LONG)
|
||||
return NULL;
|
||||
|
||||
char* tmp = strdup(value->value.string);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void* _json_unmarshall_value(const char* type, jsonValue_t* value) {
|
||||
if (value->type == JSON_NULL) {
|
||||
return NULL;
|
||||
} else if (strcmp(type, "long") == 0) {
|
||||
return json_unmarshall_long(value);
|
||||
} else if (strcmp(type, "double") == 0) {
|
||||
return json_unmarshall_double(value);
|
||||
} else if (strcmp(type, "string") == 0) {
|
||||
return json_unmarshall_string(value);
|
||||
} else if (strcmp(type, "bool") == 0) {
|
||||
return json_unmarshall_bool(value);
|
||||
} else {
|
||||
struct marshaller marshaller = findMarshaller(type);
|
||||
if (marshaller == NULL) {
|
||||
_marshallPanic(type, "unknown type");
|
||||
}
|
||||
return marshaller->unmarshaller(value);
|
||||
}
|
||||
}
|
||||
|
||||
void* _json_unmarshall(const char* type, const char* json) {
|
||||
jsonValue_t* value = json_parse(json);
|
||||
if (value == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* tmp = _json_unmarshall_value(type, value);
|
||||
free(value);
|
||||
return tmp;
|
||||
}
|
13
marshaller/marshaller.h
Normal file
13
marshaller/marshaller.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#ifndef MARSHALL_H
|
||||
#define MARSHALL_H
|
||||
|
||||
jsonValue_t* _json_marshall_value(const char* type, void* value);
|
||||
char* _json_marshall(const char* type, void* value)
|
||||
|
||||
void* _json_unmarshall_value(const char* type, jsonValue_t* value);
|
||||
void* _json_unmarshall(const char* type, const char* json);
|
||||
|
||||
#define json_marshall(t, v) _json_marshall(# t, (void*) v)
|
||||
#define json_unmarshall(t, j) (t*) _json_marshall(#t, j)
|
||||
|
||||
#endif
|
|
@ -16,7 +16,7 @@ void generatePreamble(FILE* output) {
|
|||
fprintf(output, "#include <alloc.h>\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "#include <json.h>\n");
|
||||
fprintf(output, "#include <marshall.h>\n");
|
||||
fprintf(output, "#include <marshaller.h>\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "extern void _marshallPanic(const char*, const char*);\n");
|
||||
fprintf(output, "extern void _registerMarshaller(int, const char**, (jsonValue_t*)(*)(void*), (void*)(*)(jsonValue_t*));\n");
|
||||
|
@ -118,6 +118,8 @@ char* generateUnmarshallFunction(FILE* output, struct structinfo* info, char* su
|
|||
return functionName;
|
||||
}
|
||||
|
||||
bool isDefaultType
|
||||
|
||||
void generateCodeStruct(FILE* output, struct structinfo* info) {
|
||||
char* suffix = fixStructName(info->names[0]);
|
||||
|
||||
|
@ -127,8 +129,8 @@ void generateCodeStruct(FILE* output, struct structinfo* info) {
|
|||
fprintf(output, "__attribute__((constructor)) static void _register_marshaller_%s_() {\n", suffix);
|
||||
int namesno = info->names[1] == 0 ? 1 : 2;
|
||||
fprintf(output, "\tchar* tmp = alloca(sizeof(char*) * %d);\n", namesno);
|
||||
fprintf(output, "\ttmp[0] = info->names[0];\n");
|
||||
fprintf(output, "\ttmp[1] = info->names[1];\n");
|
||||
fprintf(output, "\ttmp[0] = \"%s\";\n", info->names[0]);
|
||||
fprintf(output, "\ttmp[1] = \"%s\";\n", info->names[1]);
|
||||
fprintf(output, "\t_registerMarshaller(%d, tmp, &%s, &%s);\n", namesno, marshall, unmarshall);
|
||||
fprintf(output, "}\n\n");
|
||||
|
||||
|
|
Loading…
Reference in a new issue