コード例 #1
0
static AwaError ClientSubscribeOperation_Add(AwaClientSubscribeOperation * operation, AwaClientSubscription * subscription, bool cancel)
{
    AwaError result = AwaError_Unspecified;

    if (operation != NULL)
    {
        if (subscription != NULL)
        {
            AwaClientSubscription * existingSubscription = NULL;
            Map_Get(operation->Subscribers, subscription->Path,
                    (void **)&existingSubscription);
            if (existingSubscription == NULL)
            {
                if (Map_Put(operation->Subscribers, subscription->Path, subscription))
                {
                    List_Add(subscription->Operations, operation);
                    subscription->Cancel = cancel;
                    result = AwaError_Success;
                }
                else
                {
                    result = LogErrorWithEnum(AwaError_Internal, "Failed to add subscription to operation");
                }
            }
            else
            {
                result = LogErrorWithEnum(AwaError_OperationInvalid, "A subscription already exists for path %s in the given operation.", subscription->Path);
            }
        }
        else
        {
            result = LogErrorWithEnum(AwaError_SubscriptionInvalid, "Subscription is NULL");
        }
    }
    else
    {
        result = LogErrorWithEnum(AwaError_OperationInvalid, "Operation is NULL");
    }

    return result;
}
コード例 #2
0
static void ClientSubscribe_PerformSuccessfulCallback(const char * path, void * value, void * context)
{
    AwaClientSubscription * subscription = (AwaClientSubscription *)value;
    PerformSuccessfulCallbackContext * successContext = (PerformSuccessfulCallbackContext *)context;

    const AwaPathResult * result = AwaClientSubscribeResponse_GetPathResult(successContext->Response, subscription->Path);
    if (!subscription->Cancel)
    {
        if (AwaPathResult_GetError(result) == AwaError_Success)
        {
            Map_Put(ClientSession_GetSubscribers(successContext->Session), subscription->Path, subscription);

            // map the subscription to this session.
            subscription->Session = successContext->Session;
        }
        else
        {
            LogErrorWithEnum(AwaPathResult_GetError(result), "Failed to subscribe to path %s\n", subscription->Path);
            successContext->Result = AwaError_Response;
        }
    }
}
コード例 #3
0
// TODO: is maintaining a separate ClientResponseMap unnecessary? Can the ServerResponse's own Map be used instead?
const AwaServerListClientsResponse * AwaServerListClientsOperation_GetResponse(const AwaServerListClientsOperation * operation, const char * clientID)
{
    AwaServerListClientsResponse * listClientsResponse = NULL;
    if (operation != NULL)
    {
        if (clientID != NULL)
        {
            if (operation->ServerResponse != NULL)
            {
                // check that client response exists:
                const ResponseCommon * clientResponse = ServerResponse_GetClientResponse(operation->ServerResponse, clientID);
                if (clientResponse != NULL)
                {
                    // look up existing Response in map, return it.
                    // if it doesn't exist, create new Response and add to map, return it.
                    Map_Get(operation->ClientResponseMap, clientID, (void *)&listClientsResponse);
                    if (listClientsResponse == NULL)
                    {
                        LogDebug("Create new AwaServerListClientsResponse");
                        listClientsResponse = Awa_MemAlloc(sizeof(*listClientsResponse));
                        if (listClientsResponse != NULL)
                        {
                            memset(listClientsResponse, 0, sizeof(*listClientsResponse));
                            listClientsResponse->Response = clientResponse;

                            // cache the listClientsResponse
                            if (Map_Put(operation->ClientResponseMap, clientID, (void *)listClientsResponse) == false)
                            {
                                // do not return the response if we can't retain it, as it will eventually leak
                                LogErrorWithEnum(AwaError_Internal, "Map put failed");
                                Awa_MemSafeFree(listClientsResponse);
                                listClientsResponse = NULL;
                            }
                        }
                        else
                        {
                            LogErrorWithEnum(AwaError_OutOfMemory);
                        }
                    }
                    else
                    {
                        LogDebug("Retrieved cached AwaServerListClientsResponse");
                    }
                }
                else
                {
                    LogErrorWithEnum(AwaError_ClientNotFound, "Client ID %s not found", clientID);
                }
            }
            else
            {
                LogErrorWithEnum(AwaError_ResponseInvalid, "operation response is NULL");
            }
        }
        else
        {
            LogErrorWithEnum(AwaError_ClientIDInvalid, "clientID is NULL");
        }
    }
    else
    {
        LogErrorWithEnum(AwaError_OperationInvalid, "operation is NULL");
    }
    return listClientsResponse;
}
コード例 #4
0
AwaError GetValuePointer(const ResponseCommon * response, const char * path, const void ** value, size_t * valueSize, AwaResourceType resourceType, int resourceSize, bool withNull)
{
    AwaError result = AwaError_Unspecified;
    if (path != NULL)
    {
        if (Path_IsValidForResource(path))
        {
            if (response != NULL)
            {
                if (value != NULL)
                {
                    const Value * storedValue = ResponseCommon_GetValue(response, path);
                    if (storedValue != NULL)
                    {
                        AwaResourceType type = Value_GetType(storedValue);
                        if (type == resourceType || (type == AwaResourceType_None && resourceType == AwaResourceType_Opaque /* Execute arguments payload */))
                        {
                            const void * data = Value_GetData(storedValue);
                            size_t length = Value_GetLength(storedValue);
                            // -1 used for e.g. string values as we can't know how long they are without reading them first
                            if (resourceSize != -1 && length != resourceSize)
                            {
                                result = LogErrorWithEnum(AwaError_Internal, "Unexpected length for %s value: %zu expects %d", Utils_ResourceTypeToString(resourceType), length, resourceSize);
                            }
                            else
                            {
                                if (withNull)
                                {
                                    char * nulledValue = (char *)malloc(length+1);

                                    if ((nulledValue != NULL))
                                    {
                                        memcpy(nulledValue, data, length);
                                        nulledValue[length] = '\0';
                                        if (valueSize != NULL)
                                        {
                                            *valueSize = length + 1;
                                        }

                                        Map_Put(response->NulledValues, path, nulledValue);

                                        *value = nulledValue;
                                        result = AwaError_Success;
                                    }
                                    else
                                    {
                                        result = LogErrorWithEnum(AwaError_OutOfMemory);
                                    }
                                }
                                else
                                {
                                    *value = (length > 0) ? data : NULL;
                                    if (valueSize != NULL)
                                    {
                                        *valueSize = length;
                                    }

                                    result = AwaError_Success;
                                }
                            }
                        }
                        else
                        {
                            result = LogErrorWithEnum(AwaError_TypeMismatch, "Resource %s is not of type %s", path, Utils_ResourceTypeToString(resourceType));
                        }
                    }
                    else
                    {
                        // no value stored for this path
                        result = LogErrorWithEnum(AwaError_PathNotFound, "No value for path %s", path);
                    }
                }
                else
                {
                    result = LogErrorWithEnum(AwaError_OperationInvalid, "Value is null");
                }
            }
            else
            {
                result = LogErrorWithEnum(AwaError_OperationInvalid, "Invalid Get Response");
            }
        }
        else
        {
            result = LogErrorWithEnum(AwaError_PathInvalid, "%s is not a resource path", path);
        }
    }
    else
    {
        result = LogErrorWithEnum(AwaError_PathInvalid, "No path specified");
    }
    return result;
}
コード例 #5
0
AwaError ResponseCommon_BuildPathResults(ResponseCommon * response)
{
    AwaError result = AwaError_Success;  // success if no path results are found
    if (response != NULL)
    {
        FreeSimpleMap(&response->PathResults);
        response->PathResults = Map_New();
        if (response->PathResults != NULL)
        {
            TreeNode currentLeafNode = response->ObjectsNode;
            while ((currentLeafNode = ObjectsTree_GetNextLeafNode(currentLeafNode)) != NULL)
            {
                TreeNode currentNode = currentLeafNode;  // start at leaf and add path results for parents as well
                while (currentNode != NULL)
                {
                    char path[MAX_PATH_LENGTH] = { 0 };
                    ObjectsTree_GetPath(currentNode, path, sizeof(path));

                    TreeNode resultNode = Xml_Find(currentNode, "Result");
                    if (resultNode != NULL)
                    {
                        PathResult * pathResult = PathResult_New(resultNode);
                        if (pathResult != NULL)
                        {
                            if (!Map_Contains(response->PathResults, path))
                            {
                                Map_Put(response->PathResults, path, pathResult);
                                result = AwaError_Success;
                            }
                            else if (currentNode == currentLeafNode)
                            {
                                PathResult_Free(&pathResult);
                                result = LogErrorWithEnum(AwaError_Internal, "A pathResult already exists for %s\n", path);
                                goto error;
                            }
                            else
                            {
                                // Already added parent node
                                PathResult_Free(&pathResult);
                            }
                        }
                        else
                        {
                            result = LogErrorWithEnum(AwaError_Internal, "Could not create pathResult for %s", path);
                            goto error;
                        }
                    }
                    else
                    {
                        // not all leaves or responses have PathResults, so skip
                    }
                    currentNode = ObjectsTree_IsObjectNode(currentNode)? NULL : TreeNode_GetParent(currentNode);
                }
            }
        }
        else
        {
            result = LogErrorWithEnum(AwaError_OutOfMemory);
        }
    }
    else
    {
        result = LogErrorWithEnum(AwaError_ResponseInvalid, "response is NULL");
    }
error:
    return result;
}
コード例 #6
0
AwaError ResponseCommon_BuildValues(ResponseCommon * response)
{
    AwaError result = AwaError_Success;  // success if no values are found
    if (response != NULL)
    {
        FreeValues(&response->Values);
        response->Values = Map_New();
        if (response->Values != NULL)
        {
            // get the resource type for the path
            const OperationCommon * operation = ResponseCommon_GetOperation(response);
            if (operation != NULL)
            {
                const SessionCommon * sessionCommon = OperationCommon_GetSessionCommon(operation);
                if (sessionCommon != NULL)
                {
                    TreeNode currentNode = response->ObjectsNode;
                    while ((currentNode = ObjectsTree_GetNextLeafNode(currentNode)) != NULL)
                    {
                        char path[MAX_PATH_LENGTH] = { 0 };
                        ObjectsTree_GetPath(currentNode, path, sizeof(path));

                        if (Path_IsValidForResource(path))
                        {
                            LogDebug("Build values path: %s", path);

                            const AwaResourceDefinition * resourceDefinition = SessionCommon_GetResourceDefinitionFromPath(sessionCommon, path);
                            if (resourceDefinition != NULL)
                            {
                                AwaResourceType resourceType = AwaResourceDefinition_GetType(resourceDefinition);
                                if (resourceType != AwaResourceType_Invalid)
                                {
                                    Value * value = Value_New(currentNode, resourceType);

                                    if (value != NULL)
                                    {
                                        if (!Map_Contains(response->Values, path))
                                        {
                                            LogDebug("MAP item path: %s", path);
                                            Map_Put(response->Values, path, value);
                                            result = AwaError_Success;
                                        }
                                        else
                                        {
                                            result = LogErrorWithEnum(AwaError_Internal, "A value already exists for %s", path);
                                        }
                                    }
                                    else
                                    {
                                        // No value is fine - occurs in operations where we only expect path results in the response.
                                    }

                                }
                                else
                                {
                                    result = LogErrorWithEnum(AwaError_DefinitionInvalid, "resourceDefinition for %s has invalid type", path);
                                }
                            }
                            else
                            {
                                result = LogErrorWithEnum(AwaError_DefinitionInvalid, "resourceDefinition for %s is NULL", path);
                            }
                        }
                    }
                }
                else
                {
                    result = LogErrorWithEnum(AwaError_SessionInvalid, "session is NULL");
                }
            }
            else
            {
                result = LogErrorWithEnum(AwaError_OperationInvalid, "operation is NULL");
            }
        }
        else
        {
            result = LogErrorWithEnum(AwaError_OutOfMemory);
        }
    }
    else
    {
        result = LogErrorWithEnum(AwaError_ResponseInvalid, "response is NULL");
    }
    return result;
}