in libs/dfi/src/json_rpc.c [252:323]
int jsonRpc_handleReply(const dyn_function_type* func, const char* reply, void* args[], int* rsErrno) {
int status = OK;
json_error_t error;
json_auto_t* replyJson = json_loads(reply, JSON_DECODE_ANY, &error);
if (replyJson == NULL) {
celix_err_pushf("Error parsing json '%s', got error '%s'", reply, error.text);
return ERROR;
}
json_t* result = NULL;
json_t* rsError = NULL;
*rsErrno = 0;
const struct dyn_function_arguments_head* arguments = dynFunction_arguments(func);
dyn_function_argument_type* last = TAILQ_LAST(arguments, dyn_function_arguments_head);
const dyn_type* argType = dynType_realType(last->type);
enum dyn_function_argument_meta meta = last->argumentMeta;
rsError = json_object_get(replyJson, "e");
if (rsError != NULL) {
//get the invocation error of remote service function
*rsErrno = (int) json_integer_value(rsError);
return OK;
}
if (meta != DYN_FUNCTION_ARGUMENT_META__PRE_ALLOCATED_OUTPUT && meta != DYN_FUNCTION_ARGUMENT_META__OUTPUT) {
return OK;
}
result = json_object_get(replyJson, "r");
if (result == NULL) {
celix_err_pushf("Expected result in reply. got '%s'", reply);
return ERROR;
}
void** lastArg = (void **) args[last->index];
if (*lastArg == NULL) {
// caller provides nullptr, no need to deserialize
return OK;
}
if (meta == DYN_FUNCTION_ARGUMENT_META__PRE_ALLOCATED_OUTPUT) {
void* tmp = NULL;
void** out = lastArg;
size_t size = 0;
const dyn_type* subType = dynType_typedPointer_getTypedType(argType);
status = jsonSerializer_deserializeJson(subType, result, &tmp);
if (tmp != NULL) {
size = dynType_size(subType);
memcpy(*out, tmp, size);
dynType_free(subType, tmp);
}
} else {
const dyn_type* subType = dynType_typedPointer_getTypedType(argType);
if (celix_argType_isStringOrBuiltInObject(subType)) {
void*** out = (void***) lastArg;
void** ptrToPtr = NULL;//pointer to char*, celix_properties_t*, celix_array_list_t*
status = jsonSerializer_deserializeJson(subType, result, (void**)&ptrToPtr);
if (ptrToPtr != NULL) {
**out = *ptrToPtr;
free(ptrToPtr);
}
} else {
const dyn_type* subSubType = dynType_typedPointer_getTypedType(subType);
void*** out = (void ***) lastArg;
if (json_is_null(result)) {
**out = NULL;
} else {
status = jsonSerializer_deserializeJson(subSubType, result, *out);
}
}
}
return status;
}