response serialisation/deserialisation
This commit is contained in:
parent
3470d4bebc
commit
c32af03d20
@ -40,6 +40,7 @@ struct response_body_get_world_data_t {
|
||||
|
||||
|
||||
struct response_t {
|
||||
enum request_type_t type;
|
||||
bool success;
|
||||
void *body;
|
||||
// The body's type depends on the request's type
|
||||
|
@ -22,11 +22,14 @@ struct world_t {
|
||||
enum error_t world_init(struct world_t *, size_t, size_t);
|
||||
void world_free(struct world_t *);
|
||||
|
||||
enum error_t world_serialise_str(struct world_t *, char const **);
|
||||
enum error_t world_serialise(struct world_t const *, struct json_t **);
|
||||
enum error_t world_deserialise(struct world_t *, struct json_t *);
|
||||
|
||||
enum error_t world_serialise_str(struct world_t const *, char const **);
|
||||
enum error_t world_deserialise_str(struct world_t *, char const *);
|
||||
// Operates on strings; serialise allocates so make sure to free
|
||||
|
||||
enum error_t world_serialise_buf(struct world_t *, char *, size_t);
|
||||
enum error_t world_serialise_buf(struct world_t const *, char *, size_t);
|
||||
// Operates on buffers; need not be zero-terminated
|
||||
|
||||
enum error_t world_register_entity(struct world_t *, char const *, char);
|
||||
|
@ -11,6 +11,9 @@ static char const *REQUEST_JSON_FMT = "{si, so}";
|
||||
static char const *REQUEST_BODY_GET_WORLD_DATA_JSON_FMT = "{sI}";
|
||||
|
||||
// Response Format Strings
|
||||
static char const *RESPONSE_JSON_FMT = "{sb, si, so}";
|
||||
|
||||
static char const *RESPONSE_BODY_GET_WORLD_DATA_JSON_FMT = "{so}";
|
||||
|
||||
|
||||
static enum error_t request_serialise_body_get_world_data(
|
||||
@ -44,6 +47,7 @@ static enum error_t request_serialise_body(
|
||||
|
||||
default: return ERR_JSON_SERIALISE;
|
||||
}
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
@ -237,16 +241,233 @@ enum error_t request_deserialise_str(struct request_t *self, char const *str) {
|
||||
}
|
||||
|
||||
|
||||
static enum error_t response_serialise_body_get_world_data(
|
||||
struct response_body_get_world_data_t const *self,
|
||||
struct json_t **jsonptr
|
||||
) {
|
||||
assert(self != NULL);
|
||||
assert(jsonptr != NULL);
|
||||
|
||||
struct json_t *json = NULL;
|
||||
enum error_t err = world_serialise(&self->world, &json);
|
||||
if (err != ERR_OK) return err;
|
||||
|
||||
*jsonptr = json;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
static enum error_t response_serialise_body(
|
||||
struct response_t const *self,
|
||||
struct json_t **jsonptr
|
||||
) {
|
||||
assert(self != NULL);
|
||||
assert(jsonptr != NULL);
|
||||
|
||||
switch (self->type) {
|
||||
case REQUEST_GET_WORLD_DATA:
|
||||
return response_serialise_body_get_world_data(self->body, jsonptr);
|
||||
|
||||
default: return ERR_JSON_SERIALISE;
|
||||
}
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
static enum error_t response_serialise_parts(
|
||||
struct json_t *body_json, enum request_type_t request_type, bool success,
|
||||
struct json_t **jsonptr
|
||||
) {
|
||||
assert(body_json != NULL);
|
||||
assert(jsonptr != NULL);
|
||||
|
||||
struct json_t *json = json_pack(RESPONSE_JSON_FMT,
|
||||
"success", success,
|
||||
"request-code", request_type,
|
||||
"response", body_json
|
||||
);
|
||||
|
||||
if (json == NULL) return ERR_JSON_SERIALISE;
|
||||
|
||||
*jsonptr = json;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
static enum error_t response_serialise(
|
||||
struct response_t const *self,
|
||||
struct json_t **jsonptr
|
||||
) {
|
||||
assert(self != NULL);
|
||||
assert(jsonptr != NULL);
|
||||
|
||||
// Serialise response body
|
||||
struct json_t *body_json = NULL;
|
||||
enum error_t err = response_serialise_body(self, &body_json);
|
||||
if (err != ERR_OK) return err;
|
||||
|
||||
// Serialise full structure
|
||||
struct json_t *response_json = NULL;
|
||||
err = response_serialise_parts(
|
||||
body_json, self->success, self->type,
|
||||
&response_json
|
||||
);
|
||||
|
||||
if (err != ERR_OK) {
|
||||
json_decref(body_json);
|
||||
return err;
|
||||
}
|
||||
|
||||
*jsonptr = response_json;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
enum error_t response_serialise_str(
|
||||
struct response_t const *self,
|
||||
char const **strptr
|
||||
);
|
||||
) {
|
||||
assert(self != NULL);
|
||||
assert(strptr != NULL);
|
||||
|
||||
struct json_t *json = NULL;
|
||||
enum error_t err = response_serialise(self, &json);
|
||||
if (err != ERR_OK) return err;
|
||||
|
||||
const char *str = json_dumps(json, 0);
|
||||
if (str == NULL) {
|
||||
json_decref(json);
|
||||
return ERR_JSON_SERIALISE;
|
||||
}
|
||||
|
||||
json_decref(json);
|
||||
|
||||
*strptr = str;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
enum error_t response_serialise_buf(
|
||||
struct response_t const *self,
|
||||
char *buf, size_t len
|
||||
) {
|
||||
assert(self != NULL);
|
||||
assert(buf != NULL);
|
||||
assert(len > 0);
|
||||
|
||||
struct json_t *json = NULL;
|
||||
enum error_t err = response_serialise(self, &json);
|
||||
if (err != ERR_OK) return err;
|
||||
|
||||
size_t bytes_written = json_dumpb(json, buf, len, 0);
|
||||
if (bytes_written == 0) {
|
||||
json_decref(json);
|
||||
return ERR_JSON_SERIALISE;
|
||||
}
|
||||
|
||||
json_decref(json);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
static enum error_t response_deserialise_parts(
|
||||
struct json_t **body_json,
|
||||
enum request_type_t *type,
|
||||
bool *success,
|
||||
struct json_t *json
|
||||
) {
|
||||
assert(body_json != NULL);
|
||||
assert(type != NULL);
|
||||
assert(success != NULL);
|
||||
assert(json != NULL);
|
||||
|
||||
int err = json_unpack(json, RESPONSE_JSON_FMT,
|
||||
"success", success,
|
||||
"request-code", type,
|
||||
"response", body_json
|
||||
);
|
||||
|
||||
if (err < 0) return ERR_JSON_DESERIALISE;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
enum error_t response_deserialise_str(struct response_t *self, char const *str);
|
||||
|
||||
static enum error_t response_deserialise_body_get_world_data(
|
||||
struct response_body_get_world_data_t *self,
|
||||
struct json_t *json
|
||||
) {
|
||||
assert(self != NULL);
|
||||
assert(json != NULL);
|
||||
|
||||
enum error_t err = world_deserialise(&self->world, json);
|
||||
if (err != ERR_OK) return err;
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
static enum error_t response_deserialise_body(
|
||||
struct response_t *self,
|
||||
struct json_t *json
|
||||
) {
|
||||
assert(self != NULL);
|
||||
assert(json != NULL);
|
||||
|
||||
switch (self->type) {
|
||||
case REQUEST_GET_WORLD_DATA:
|
||||
self->body = malloc(sizeof(struct response_body_get_world_data_t));
|
||||
if (self->body == NULL) return ERR_ALLOC;
|
||||
|
||||
return response_deserialise_body_get_world_data(self->body, json);
|
||||
|
||||
default: return ERR_JSON_SERIALISE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static enum error_t response_deserialise(
|
||||
struct response_t *self,
|
||||
struct json_t *json
|
||||
) {
|
||||
assert(self != NULL);
|
||||
assert(json != NULL);
|
||||
|
||||
struct response_t temp_response = { 0 };
|
||||
struct json_t *body_json = NULL;
|
||||
|
||||
enum error_t err = response_deserialise_parts(
|
||||
&body_json, &temp_response.type, &temp_response.success, json
|
||||
);
|
||||
if (err != ERR_OK) return err;
|
||||
|
||||
err = response_deserialise_body(&temp_response, body_json);
|
||||
if (err != ERR_OK) {
|
||||
json_decref(body_json);
|
||||
return err;
|
||||
}
|
||||
|
||||
*self = temp_response;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
enum error_t response_deserialise_str(
|
||||
struct response_t *self,
|
||||
char const *str
|
||||
) {
|
||||
assert(self != NULL);
|
||||
assert(str != NULL);
|
||||
|
||||
struct json_t *json = json_loads(str, 0, NULL);
|
||||
if (json == NULL) return ERR_JSON_DESERIALISE;
|
||||
|
||||
enum error_t err = response_deserialise(self, json);
|
||||
if (err != ERR_OK) {
|
||||
json_decref(json);
|
||||
return err;
|
||||
}
|
||||
|
||||
json_decref(json);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
@ -104,7 +104,10 @@ static enum error_t world_serialise_parts(
|
||||
}
|
||||
|
||||
|
||||
static enum error_t world_serialise(struct world_t *self, struct json_t **json) {
|
||||
enum error_t world_serialise(
|
||||
struct world_t const *self,
|
||||
struct json_t **json
|
||||
) {
|
||||
assert(self != NULL);
|
||||
assert(json != NULL);
|
||||
|
||||
@ -212,7 +215,7 @@ static enum error_t world_deserialise_entities(
|
||||
}
|
||||
|
||||
|
||||
static enum error_t world_deserialise(struct world_t *self, struct json_t *json) {
|
||||
enum error_t world_deserialise(struct world_t *self, struct json_t *json) {
|
||||
assert(self != NULL);
|
||||
assert(json != NULL);
|
||||
|
||||
@ -256,7 +259,10 @@ error:
|
||||
}
|
||||
|
||||
|
||||
enum error_t world_serialise_str(struct world_t *self, char const **strptr) {
|
||||
enum error_t world_serialise_str(
|
||||
struct world_t const *self,
|
||||
char const **strptr
|
||||
) {
|
||||
assert(self != NULL);
|
||||
assert(strptr != NULL);
|
||||
|
||||
@ -277,7 +283,10 @@ enum error_t world_serialise_str(struct world_t *self, char const **strptr) {
|
||||
}
|
||||
|
||||
|
||||
enum error_t world_serialise_buf(struct world_t *self, char *buf, size_t len) {
|
||||
enum error_t world_serialise_buf(
|
||||
struct world_t const *self,
|
||||
char *buf, size_t len
|
||||
) {
|
||||
assert(self != NULL);
|
||||
assert(buf != NULL);
|
||||
assert(len > 0);
|
||||
|
@ -27,25 +27,30 @@ enum error_t game_loop(struct data_t *data) {
|
||||
enum error_t err = ERR_OK;
|
||||
|
||||
// TEMP
|
||||
struct request_body_get_world_data_t request_body = { 69 };
|
||||
struct request_t request = { REQUEST_GET_WORLD_DATA, &request_body };
|
||||
struct response_body_get_world_data_t response_body = { data->world };
|
||||
struct response_t response = { true, REQUEST_GET_WORLD_DATA, &response_body };
|
||||
|
||||
char const *request_json_str = NULL;
|
||||
err = request_serialise_str(&request, &request_json_str);
|
||||
char const *response_json_str = NULL;
|
||||
err = response_serialise_str(&response, &response_json_str);
|
||||
if (err) return err;
|
||||
|
||||
printf("serialised request: %s\n", request_json_str);
|
||||
printf("serialised response: %s\n", response_json_str);
|
||||
|
||||
struct request_t request2 = { 0 };
|
||||
err = request_deserialise_str(&request2, request_json_str);
|
||||
struct response_t response2 = { 0 };
|
||||
err = response_deserialise_str(&response2, response_json_str);
|
||||
if (err) return err;
|
||||
|
||||
struct request_body_get_world_data_t *request2_body = request2.body;
|
||||
printf("deserialised request: (%d, %zu)\n",
|
||||
request2.type,
|
||||
request2_body->world_id
|
||||
struct response_body_get_world_data_t *response2_body = response2.body;
|
||||
|
||||
char const *world_json_str = NULL;
|
||||
err = world_serialise_str(&response2_body->world, &world_json_str);
|
||||
if (err) return err;
|
||||
printf("deserialised response: (%d, %d, %s\n",
|
||||
response2.success,
|
||||
response2.type,
|
||||
world_json_str
|
||||
);
|
||||
free((void *)request_json_str);
|
||||
free((void *)response_json_str);
|
||||
|
||||
// TEMP
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user