static int DecodeValueFromNode()

in serializer/src/commanddecoder.c [30:158]


static int DecodeValueFromNode(SCHEMA_HANDLE schemaHandle, AGENT_DATA_TYPE* agentDataType, MULTITREE_HANDLE node, const char* edmTypeName)
{
    /* because "pottentially uninitialized variable on MS compiler" */
    int result = 0;
    const char* argStringValue;
    AGENT_DATA_TYPE_TYPE primitiveType;

    if ((primitiveType = CodeFirst_GetPrimitiveType(edmTypeName)) == EDM_NO_TYPE)
    {
        SCHEMA_STRUCT_TYPE_HANDLE structTypeHandle;
        size_t propertyCount;

        if (((structTypeHandle = Schema_GetStructTypeByName(schemaHandle, edmTypeName)) == NULL) ||
            (Schema_GetStructTypePropertyCount(structTypeHandle, &propertyCount) != SCHEMA_OK))
        {
            result = MU_FAILURE;
            LogError("Getting Struct information failed.");
        }
        else
        {
            if (propertyCount == 0)
            {
                result = MU_FAILURE;
                LogError("Struct type with 0 members is not allowed");
            }
            else
            {
                AGENT_DATA_TYPE* memberValues;
                size_t calloc_size = safe_multiply_size_t(sizeof(AGENT_DATA_TYPE), propertyCount);
                if (calloc_size == SIZE_MAX ||
                    (memberValues = (AGENT_DATA_TYPE*)calloc(1, calloc_size)) == NULL)
                {
                    result = MU_FAILURE;
                    LogError("Failed allocating member values for command argument, size:%zu", calloc_size);
                }
                else
                {
                    const char** memberNames;
                    size_t malloc_size = safe_multiply_size_t(sizeof(const char*), propertyCount);
                    if (malloc_size == SIZE_MAX || 
                        (memberNames = (const char**)malloc(malloc_size)) == NULL)
                    {
                        result = MU_FAILURE;
                        LogError("Failed allocating member names for command argument, size:%zu", malloc_size);
                    }
                    else
                    {
                        size_t j;
                        size_t k;

                        for (j = 0; j < propertyCount; j++)
                        {
                            SCHEMA_PROPERTY_HANDLE propertyHandle;
                            MULTITREE_HANDLE memberNode;
                            const char* propertyName;
                            const char* propertyType;

                            if ((propertyHandle = Schema_GetStructTypePropertyByIndex(structTypeHandle, j)) == NULL)
                            {
                                result = MU_FAILURE;
                                LogError("Getting struct member failed.");
                                break;
                            }
                            else if (((propertyName = Schema_GetPropertyName(propertyHandle)) == NULL) ||
                                     ((propertyType = Schema_GetPropertyType(propertyHandle)) == NULL))
                            {
                                result = MU_FAILURE;
                                LogError("Getting the struct member information failed.");
                                break;
                            }
                            else
                            {
                                memberNames[j] = propertyName;

                                if (MultiTree_GetChildByName(node, memberNames[j], &memberNode) != MULTITREE_OK)
                                {
                                    result = MU_FAILURE;
                                    LogError("Getting child %s failed", propertyName);
                                    break;
                                }
                                else if ((result = DecodeValueFromNode(schemaHandle, &memberValues[j], memberNode, propertyType)) != 0)
                                {
                                    break;
                                }
                            }
                        }

                        if (j == propertyCount)
                        {
                            if (Create_AGENT_DATA_TYPE_from_Members(agentDataType, edmTypeName, propertyCount, (const char* const*)memberNames, memberValues) != AGENT_DATA_TYPES_OK)
                            {
                                result = MU_FAILURE;
                                LogError("Creating the agent data type from members failed.");
                            }
                            else
                            {
                                result = 0;
                            }
                        }

                        for (k = 0; k < j; k++)
                        {
                            Destroy_AGENT_DATA_TYPE(&memberValues[k]);
                        }

                        free((void*)memberNames);
                    }

                    free(memberValues);
                }
            }
        }
    }
    else
    {
        if (MultiTree_GetValue(node, (const void **)&argStringValue) != MULTITREE_OK)
        {
            result = MU_FAILURE;
            LogError("Getting the string from the multitree failed.");
        }
        else if (CreateAgentDataType_From_String(argStringValue, primitiveType, agentDataType) != AGENT_DATA_TYPES_OK)
        {
            result = MU_FAILURE;
            LogError("Failed parsing node %s.", argStringValue);
        }
    }

    return result;
}