int jsonRpc_handleReply()

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;
}