static AppMessage * _new_deserialize_id(AppMessage * message, char const * data, const size_t size, size_t * pos) { int ret = 0; size_t s = size; Variable * v; #ifdef DEBUG fprintf(stderr, "DEBUG: %s()\n", __func__); #endif if((v = variable_new_deserialize_type(VT_UINT32, &s, &data[*pos])) == NULL) { error_set_code(1, "%s", "Could not obtain the AppMessage ID"); appmessage_delete(message); return NULL; } ret = variable_get_as(v, VT_UINT32, &message->id); variable_delete(v); if(ret != 0) { appmessage_delete(message); return NULL; } *pos += s; return message; }
/* variable_new_deserialize */ Variable * variable_new_deserialize(size_t * size, char const * data) { Variable * variable; uint8_t u8; size_t s; /* check the arguments */ if(size == NULL || *size < sizeof(u8) || data == NULL) { error_set_code(-EINVAL, "%s", strerror(EINVAL)); return NULL; } /* obtain the type from the data */ u8 = data[0]; s = *size - sizeof(u8); /* deserialize according to the type */ variable = variable_new_deserialize_type(u8, &s, &data[sizeof(u8)]); *size = s + sizeof(u8); return variable; }
AppMessage * appmessage_new_deserialize(Buffer * buffer) { AppMessage * message; char const * data = buffer_get_data(buffer); size_t size = buffer_get_size(buffer); size_t pos = 0; size_t s; Variable * v; uint8_t u8; #ifdef DEBUG fprintf(stderr, "DEBUG: %s()\n", __func__); #endif if((message = object_new(sizeof(*message))) == NULL) return NULL; s = size; if((v = variable_new_deserialize_type(VT_UINT8, &s, &data[pos])) == NULL) { object_delete(message); return NULL; } pos += s; size -= s; /* XXX may fail */ variable_get_as(v, VT_UINT8, &u8); variable_delete(v); switch((message->type = u8)) { case AMT_ACKNOWLEDGEMENT: return _new_deserialize_acknowledgement(message, data, size, pos); case AMT_CALL: return _new_deserialize_call(message, data, size, pos); default: error_set_code(1, "%s%u", "Unknown message type ", u8); /* XXX should not happen */ object_delete(message); return NULL; } }
/* variable */ static int _variable(char const * progname) { int ret = 0; Variable * variable; const int samples[] = { 0, -1, 1, -127, -128, 126, 127 }; size_t i; int32_t j; int8_t i8; size_t s; void * p; /* variable_new */ for(i = 0; i < sizeof(samples) / sizeof(*samples); i++) { printf("%s: Testing variable_new_deserialize_type(): %d\n", progname, samples[i]); i8 = samples[i]; s = sizeof(i8); p = &i8; if((variable = variable_new_deserialize_type(VT_INT8, &s, p)) == NULL) { error_print(progname); ret += 1; continue; } p = &j; if(variable_get_as(variable, VT_INT32, p) != 0 || j != samples[i]) { error_print(progname); ret += 1; } variable_delete(variable); } return ret; }
static AppMessage * _socket_callback_message(SSLSocket * sslsocket) { AppMessage * message = NULL; size_t size; Variable * variable; Buffer * buffer; size = sslsocket->bufin_cnt; /* deserialize the data as a buffer (containing a message) */ if((variable = variable_new_deserialize_type(VT_BUFFER, &size, sslsocket->bufin)) == NULL) /* XXX assumes not enough data was available */ return NULL; sslsocket->bufin_cnt -= size; memmove(sslsocket->bufin, &sslsocket->bufin[size], sslsocket->bufin_cnt); if((variable_get_as(variable, VT_BUFFER, &buffer)) == 0) { message = appmessage_new_deserialize(buffer); buffer_delete(buffer); } variable_delete(variable); return message; }
static AppMessage * _new_deserialize_call(AppMessage * message, char const * data, const size_t size, size_t pos) { size_t s; Variable * v; size_t i; AppMessageCallArgument * p; #ifdef DEBUG fprintf(stderr, "DEBUG: %s()\n", __func__); #endif if(_new_deserialize_id(message, data, size, &pos) == NULL) return NULL; message->t.call.method = NULL; message->t.call.args = NULL; message->t.call.args_cnt = 0; s = size; if((v = variable_new_deserialize_type(VT_STRING, &s, &data[pos])) == NULL) { error_set_code(1, "%s", "Could not obtain the AppMessage call" " method"); appmessage_delete(message); return NULL; } pos += s; /* XXX may fail */ variable_get_as(v, VT_STRING, &message->t.call.method); variable_delete(v); #ifdef DEBUG fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__, message->t.call.method); #endif /* deserialize the arguments */ for(i = 0; pos < size; i++) { #ifdef DEBUG fprintf(stderr, "DEBUG: %s() %lu\n", __func__, i); #endif if((p = realloc(message->t.call.args, sizeof(*p) * (i + 1))) == NULL) { appmessage_delete(message); return NULL; } message->t.call.args = p; s = size - pos; if((v = variable_new_deserialize(&s, &data[pos])) == NULL) { appmessage_delete(message); return NULL; } #ifdef DEBUG fprintf(stderr, "DEBUG: %s() %lu (%u)\n", __func__, i, variable_get_type(v)); #endif pos += s; message->t.call.args[i].direction = AMCD_IN; /* XXX */ message->t.call.args[i].arg = v; message->t.call.args_cnt = i + 1; } return message; }