/** * @brief Adds a path of interest to a Set operation, as a request to create an optional Resource. * If the path refers to an optional resource that does not exist, the operation will result in the creation of the resource. * The resource will have the default value assigned, if not overridden in the same operation. * @param[in] operation The current Set operation to add the create request to. * @param[in] path The path of the resource requested for creation. * @return Error_Success on success, error code on failure. */ AwaError AwaClientSetOperation_CreateOptionalResource(AwaClientSetOperation * operation, const char * path) { AwaError result = AwaError_Unspecified; if (operation != NULL) { TreeNode objectsTree = OperationCommon_GetObjectsTree(operation->Common); if (objectsTree != NULL) { if (path != NULL) { if (Path_IsValidForResource(path)) { TreeNode resultNode; if (ObjectsTree_AddPath(objectsTree, path, &resultNode) == InternalError_Success && resultNode != NULL) { if (ClientSetOperation_AddCreate(resultNode) == InternalError_Success) { result = AwaError_Success; } else { result = LogErrorWithEnum(AwaError_Internal, "Failed to add value to path"); } } else { result = LogErrorWithEnum(AwaError_Internal, "AddPath failed"); } } else { result = LogErrorWithEnum(AwaError_PathInvalid, "%s is not a resource path", path); } } else { result = LogErrorWithEnum(AwaError_PathInvalid, "Path is NULL"); } } else { result = LogErrorWithEnum(AwaError_Internal, "ObjectsTree is NULL"); } } else { result = LogErrorWithEnum(AwaError_OperationInvalid, "Operation is NULL"); } return result; }
AwaError AwaServerExecuteOperation_AddPath(AwaServerExecuteOperation * operation, const char * clientID, const char * path, const AwaExecuteArguments * arguments) { AwaError result = AwaError_Unspecified; if (operation != NULL) { if (Path_IsValidForResource(path)) { TreeNode resultNode = NULL; if ((result = ServerOperation_AddPath(operation->ServerOperation, clientID, path, &resultNode)) == AwaError_Success) { if (resultNode != NULL) { char * encodedValue = NULL; if (arguments != NULL && arguments->Size > 0) { encodedValue = xmlif_EncodeValue(AwaResourceType_Opaque, arguments->Data, arguments->Size); } if (encodedValue == NULL || SetWriteCommon_SetResourceNodeValue(resultNode, encodedValue) == InternalError_Success) { result = AwaError_Success; } else { result = LogErrorWithEnum(AwaError_Internal, "Failed to set resource value"); } if (encodedValue) { Awa_MemSafeFree(encodedValue); } } else { result = LogErrorWithEnum(AwaError_Internal, "AddPath failed to return result node"); } } } else { result = LogErrorWithEnum(AwaError_PathInvalid, "%s is not a valid path to an executable resource", path); } } else { result = LogErrorWithEnum(AwaError_OperationInvalid, "Operation is NULL"); } return result; }
AwaError OperationCommon_AddPathWithArrayRange(OperationCommon * operation, const char * path, AwaArrayIndex startIndex, AwaArrayLength indexCount) { AwaError result = AwaError_Unspecified; if (operation != NULL) { if (path != NULL) { if (Path_IsValid(path)) { if (Path_IsValidForResource(path)) { // catch zero count and index overflow if (startIndex + indexCount > startIndex) { // build up the required tree (may already exist) if (ObjectsTree_AddPath(operation->ObjectsTree, path, NULL) == InternalError_Success) { // find the corresponding Property/Resource node TreeNode resourceNode = NULL; if (ObjectsTree_FindPathNode(operation->ObjectsTree, path, &resourceNode) == InternalError_Success) { if (resourceNode != NULL) { if (AddIDRange(resourceNode, startIndex, startIndex + indexCount) != NULL) { result = AwaError_Success; } else { result = LogErrorWithEnum(AwaError_Internal, "failed to add IDRange"); } } else { result = LogErrorWithEnum(AwaError_Internal, "propertyNode is NULL"); } } else { result = LogErrorWithEnum(AwaError_Internal, "propertyNode not found"); } } else { result = LogErrorWithEnum(AwaError_Internal, "unable to build tree"); } } else { if (indexCount == 0) { result = LogErrorWithEnum(AwaError_AddInvalid, "Index count is not greater than zero"); } else { result = LogErrorWithEnum(AwaError_AddInvalid, "Range overflow"); } } } else { result = LogErrorWithEnum(AwaError_PathInvalid, "Path %s is not supported for this operation", path); } } else { result = LogErrorWithEnum(AwaError_PathInvalid, "Path %s is not valid", path); } } else { result = LogErrorWithEnum(AwaError_PathInvalid, "Path is NULL"); } } else { result = LogErrorWithEnum(AwaError_OperationInvalid, "Operation is NULL"); } return result; }
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; }
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; }