SCHEMA_MODEL_TYPE_HANDLE Schema_CreateModelType()

in serializer/src/schema.c [578:717]


SCHEMA_MODEL_TYPE_HANDLE Schema_CreateModelType(SCHEMA_HANDLE schemaHandle, const char* modelName)
{
    SCHEMA_MODEL_TYPE_HANDLE result;

    if ((schemaHandle == NULL) ||
        (modelName == NULL))
    {
        result = NULL;
        LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_INVALID_ARG));
    }
    else
    {
        SCHEMA_HANDLE_DATA* schema = (SCHEMA_HANDLE_DATA*)schemaHandle;

        size_t i;
        for (i = 0; i < schema->ModelTypeCount; i++)
        {
            SCHEMA_MODEL_TYPE_HANDLE_DATA* model = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)(schema->ModelTypes[i]);
            if (strcmp(model->Name, modelName) == 0)
            {
                break;
            }
        }

        if (i < schema->ModelTypeCount)
        {
            result = NULL;
            LogError("%s Model Name already exists", modelName);
        }

        else
        {
            SCHEMA_MODEL_TYPE_HANDLE* newModelTypes;
            size_t realloc_size = safe_multiply_size_t(sizeof(SCHEMA_MODEL_TYPE_HANDLE), safe_add_size_t(schema->ModelTypeCount, 1));
            if (realloc_size == SIZE_MAX ||
                (newModelTypes = (SCHEMA_MODEL_TYPE_HANDLE*)realloc(schema->ModelTypes, realloc_size)) == NULL)
            {
                result = NULL;
                LogError("(Error code:%s), size:%zu", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_ERROR), realloc_size);
            }
            else
            {
                SCHEMA_MODEL_TYPE_HANDLE_DATA* modelType;
                schema->ModelTypes = newModelTypes;

                if ((modelType = (SCHEMA_MODEL_TYPE_HANDLE_DATA*)calloc(1, sizeof(SCHEMA_MODEL_TYPE_HANDLE_DATA))) == NULL)
                {

                    result = NULL;
                    LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_ERROR));
                }
                else if (mallocAndStrcpy_s((char**)&modelType->Name, modelName) != 0)
                {
                    result = NULL;
                    free(modelType);
                    LogError("(Error code:%s)", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_ERROR));
                }
                else
                {
                    modelType->models = VECTOR_create(sizeof(MODEL_IN_MODEL));
                    if (modelType->models == NULL)
                    {
                        LogError("unable to VECTOR_create");
                        free((void*)modelType->Name);
                        free((void*)modelType);
                        result = NULL;
                    }
                    else
                    {
                        if ((modelType->reportedProperties = VECTOR_create(sizeof(SCHEMA_REPORTED_PROPERTY_HANDLE))) == NULL)
                        {
                            LogError("failed to VECTOR_create (reported properties)");
                            VECTOR_destroy(modelType->models);
                            free((void*)modelType->Name);
                            free((void*)modelType);
                            result = NULL;

                        }
                        else
                        {
                            if ((modelType->desiredProperties = VECTOR_create(sizeof(SCHEMA_DESIRED_PROPERTY_HANDLE))) == NULL)
                            {
                                LogError("failure in VECTOR_create (desired properties)");
                                VECTOR_destroy(modelType->reportedProperties);
                                VECTOR_destroy(modelType->models);
                                free((void*)modelType->Name);
                                free((void*)modelType);
                                result = NULL;
                            }
                            else
                            {
                                if ((modelType->methods = VECTOR_create(sizeof(SCHEMA_METHOD_HANDLE))) == NULL)
                                {
                                    LogError("failure in VECTOR_create (desired properties)");
                                    VECTOR_destroy(modelType->desiredProperties);
                                    VECTOR_destroy(modelType->reportedProperties);
                                    VECTOR_destroy(modelType->models);
                                    free((void*)modelType->Name);
                                    free((void*)modelType);
                                    result = NULL;
                                }
                                else
                                {
                                    modelType->PropertyCount = 0;
                                    modelType->Properties = NULL;
                                    modelType->ActionCount = 0;
                                    modelType->Actions = NULL;
                                    modelType->SchemaHandle = schemaHandle;
                                    modelType->DeviceCount = 0;

                                    schema->ModelTypes[schema->ModelTypeCount] = modelType;
                                    schema->ModelTypeCount++;
                                    result = (SCHEMA_MODEL_TYPE_HANDLE)modelType;
                                }
                            }
                        }
                    }
                }

                /* If possible, reduce the memory of over allocation */
                if ((result == NULL) &&(schema->ModelTypeCount>0))
                {
                    SCHEMA_MODEL_TYPE_HANDLE* oldModelTypes;
                    realloc_size = safe_multiply_size_t(sizeof(SCHEMA_MODEL_TYPE_HANDLE), schema->ModelTypeCount);
                    if (realloc_size == SIZE_MAX ||
                        (oldModelTypes = (SCHEMA_MODEL_TYPE_HANDLE*)realloc(schema->ModelTypes, realloc_size)) == NULL)
                    {
                        LogError("(Error code:%s), size:%zu", MU_ENUM_TO_STRING(SCHEMA_RESULT, SCHEMA_ERROR), realloc_size);
                    }
                    else
                    {
                        schema->ModelTypes = oldModelTypes;
                    }
                }
            }
        }
    }

    return result;
}