AGENT_DATA_TYPES_RESULT Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE()

in serializer/src/agenttypesystem.c [2333:2706]


AGENT_DATA_TYPES_RESULT Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE(AGENT_DATA_TYPE* dest, const AGENT_DATA_TYPE* src)
{
    AGENT_DATA_TYPES_RESULT result;
    size_t i;
    if ((dest == NULL) || (src == NULL))
    {
        result = AGENT_DATA_TYPES_INVALID_ARG;
        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
    }
    else
    {
        switch (src->type)
        {
            default:
            {
                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                break;
            }
            case(EDM_NO_TYPE) :
            case(EDM_NULL_TYPE) :
            {
                dest->type = src->type;
                result = AGENT_DATA_TYPES_OK;
                break;
            }
            case(EDM_BOOLEAN_TYPE) :
            {
                dest->type = src->type;
                dest->value.edmBoolean= src->value.edmBoolean;
                result = AGENT_DATA_TYPES_OK;
                break;
            }
            case(EDM_BYTE_TYPE) :
            {
                dest->type = src->type;
                dest->value.edmByte= src->value.edmByte;
                result = AGENT_DATA_TYPES_OK;
                break;
            }
            case(EDM_DATE_TYPE) :
            {
                dest->type = src->type;
                dest->value.edmDate = src->value.edmDate;
                result = AGENT_DATA_TYPES_OK;
                break;
            }
            case(EDM_DATE_TIME_OFFSET_TYPE) :
            {
                dest->type = src->type;
                dest->value.edmDateTimeOffset = src->value.edmDateTimeOffset;
                result = AGENT_DATA_TYPES_OK;
                break;
            }
            case(EDM_DECIMAL_TYPE) :
            {
                if ((dest->value.edmDecimal.value = STRING_clone(src->value.edmDecimal.value)) == NULL)
                {
                    result = AGENT_DATA_TYPES_ERROR;
                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                }
                else
                {
                    dest->type = src->type;
                    result = AGENT_DATA_TYPES_OK;
                    /*all is fine*/
                }
                break;
            }
            case(EDM_DOUBLE_TYPE) :
            {
                dest->type = src->type;
                dest->value.edmDouble = src->value.edmDouble;
                result = AGENT_DATA_TYPES_OK;
                break;
            }
            case(EDM_DURATION_TYPE) :
            {
                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                break;
            }
            case(EDM_GUID_TYPE) :
            {
                dest->type = src->type;
                dest->value.edmGuid = src->value.edmGuid;
                result = AGENT_DATA_TYPES_OK;
                break;
            }
            case EDM_BINARY_TYPE:
            {
                if (src->value.edmBinary.size == 0)
                {
                    dest->value.edmBinary.size = 0;
                    dest->value.edmBinary.data = NULL;
                    dest->type = EDM_BINARY_TYPE;
                    result = AGENT_DATA_TYPES_OK;
                }
                else
                {
                    if ((dest->value.edmBinary.data = (unsigned char*)malloc(src->value.edmBinary.size)) == NULL)
                    {
                        result = AGENT_DATA_TYPES_ERROR;
                    }
                    else
                    {
                        dest->value.edmBinary.size = src->value.edmBinary.size;
                        (void)memcpy(dest->value.edmBinary.data, src->value.edmBinary.data, src->value.edmBinary.size);
                        dest->type = EDM_BINARY_TYPE;
                        result = AGENT_DATA_TYPES_OK;
                    }
                }
                break;
            }
            case(EDM_INT16_TYPE) :
            {
                dest->type = src->type;
                dest->value.edmInt16 = src->value.edmInt16;
                result = AGENT_DATA_TYPES_OK;
                break;
            }
            case(EDM_INT32_TYPE) :
            {
                dest->type = src->type;
                dest->value.edmInt32 = src->value.edmInt32;
                result = AGENT_DATA_TYPES_OK;
                break;
            }
            case(EDM_INT64_TYPE) :
            {
                dest->type = src->type;
                dest->value.edmInt64 = src->value.edmInt64;
                result = AGENT_DATA_TYPES_OK;
                break;
            }
            case(EDM_SBYTE_TYPE) :
            {
                dest->type = src->type;
                dest->value.edmSbyte = src->value.edmSbyte;
                result = AGENT_DATA_TYPES_OK;
                break;
            }
            case(EDM_SINGLE_TYPE) :
            {
                dest->type = src->type;
                dest->value.edmSingle = src->value.edmSingle;
                result = AGENT_DATA_TYPES_OK;
                break;
            }
            case(EDM_STREAM) :
            {
                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                break;
            } /*not supported, because what is stream?*/
            case(EDM_STRING_TYPE) :
            {
                dest->type = src->type;
                dest->value.edmString.length = src->value.edmString.length;
                if (mallocAndStrcpy_s((char**)&(dest->value.edmString.chars), (char*)src->value.edmString.chars) != 0)
                {
                    result = AGENT_DATA_TYPES_ERROR;
                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                }
                else
                {
                    result = AGENT_DATA_TYPES_OK;
                    /*all is fine*/
                }
                break;
            }
            case(EDM_STRING_NO_QUOTES_TYPE) :
            {
                dest->type = src->type;
                dest->value.edmStringNoQuotes.length = src->value.edmStringNoQuotes.length;
                if (mallocAndStrcpy_s((char**)&(dest->value.edmStringNoQuotes.chars), (char*)src->value.edmStringNoQuotes.chars) != 0)
                {
                    result = AGENT_DATA_TYPES_ERROR;
                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                }
                else
                {
                    result = AGENT_DATA_TYPES_OK;
                    /*all is fine*/
                }
                break;
            }
            case(EDM_TIME_OF_DAY_TYPE) :
            {
                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                break;
            }
            case(EDM_GEOGRAPHY_TYPE) :
            {
                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                break;
            } /*not supported because what is "abstract base type"*/
            case(EDM_GEOGRAPHY_POINT_TYPE) :
            {
                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                break;
            }
            case(EDM_GEOGRAPHY_LINE_STRING_TYPE) :
            {
                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                break;
            }
            case(EDM_GEOGRAPHY_POLYGON_TYPE) :
            {
                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                break;
            }
            case(EDM_GEOGRAPHY_MULTI_POINT_TYPE) :
            {
                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                break;
            }
            case(EDM_GEOGRAPHY_MULTI_LINE_STRING_TYPE) :
            {
                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                break;
            }
            case(EDM_GEOGRAPHY_MULTI_POLYGON_TYPE) :
            {
                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                break;
            }
            case(EDM_GEOGRAPHY_COLLECTION_TYPE) :
            {
                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                break;
            }
            case(EDM_GEOMETRY_TYPE) :
            {
                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                break;
            } /*not supported because what is "abstract base type"*/
            case(EDM_GEOMETRY_POINT_TYPE) :
            {
                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                break;
            }
            case(EDM_GEOMETRY_LINE_STRING_TYPE) :
            {
                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                break;
            }
            case(EDM_GEOMETRY_POLYGON_TYPE) :
            {
                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                break;
            }
            case(EDM_GEOMETRY_MULTI_POINT_TYPE) :
            {
                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                break;
            }
            case(EDM_GEOMETRY_MULTI_LINE_STRING_TYPE) :
            {
                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                break;
            }
            case(EDM_GEOMETRY_MULTI_POLYGON_TYPE) :
            {
                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                break;
            }
            case(EDM_GEOMETRY_COLLECTION_TYPE) :
            {
                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                break;
            }
            case(EDM_COMPLEX_TYPE_TYPE) :
            {
                result = AGENT_DATA_TYPES_OK;
                /*copying a COMPLEX_TYPE means to copy all its member names and all its fields*/
                dest->type = src->type;
                if (src->value.edmComplexType.nMembers == 0)
                {
                    /*error*/
                    result = AGENT_DATA_TYPES_INVALID_ARG;
                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                }
                else
                {
                    dest->value.edmComplexType.nMembers = src->value.edmComplexType.nMembers;
                    size_t malloc_size = safe_multiply_size_t(dest->value.edmComplexType.nMembers, sizeof(COMPLEX_TYPE_FIELD_TYPE));
                    if (malloc_size == SIZE_MAX ||
                        (dest->value.edmComplexType.fields = (COMPLEX_TYPE_FIELD_TYPE*)malloc(malloc_size)) == NULL)
                    {
                        result = AGENT_DATA_TYPES_ERROR;
                        dest->value.edmComplexType.fields = NULL;
                        LogError("(result = %s), size:%zu", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result), malloc_size);
                    }
                    else
                    {
                        for (i = 0; i < dest->value.edmComplexType.nMembers; i++)
                        {
                            dest->value.edmComplexType.fields[i].fieldName = NULL;
                            dest->value.edmComplexType.fields[i].value = NULL;
                        }

                        for (i = 0; i < dest->value.edmComplexType.nMembers; i++)
                        {
                            /*copy the name of this field*/
                            if (mallocAndStrcpy_s((char**)(&(dest->value.edmComplexType.fields[i].fieldName)), src->value.edmComplexType.fields[i].fieldName) != 0)
                            {
                                result = AGENT_DATA_TYPES_ERROR;
                                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                                break;
                            }
                            else
                            {
                                /*field name copied success*/
                                /*field value copy follows*/
                                dest->value.edmComplexType.fields[i].value = (AGENT_DATA_TYPE*)calloc(1, sizeof(AGENT_DATA_TYPE));
                                if (dest->value.edmComplexType.fields[i].value == NULL)
                                {
                                    result = AGENT_DATA_TYPES_ERROR;
                                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                                    break;
                                }
                                else
                                {
                                    if (Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE(dest->value.edmComplexType.fields[i].value, src->value.edmComplexType.fields[i].value) != AGENT_DATA_TYPES_OK)
                                    {
                                        result = AGENT_DATA_TYPES_ERROR;
                                        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                                        break;
                                    }
                                    else
                                    {
                                        /*all is fine*/
                                    }
                                }
                            }
                        }

                        if (result != AGENT_DATA_TYPES_OK)
                        {
                            /*unbuild*/
                            DestroyHalfBakedComplexType(dest);
                        }
                    }
                }
                break;
            } /*ANY CHANGE (?!) here must be reflected in the tool providing the binary file (XML2BINARY) */
        }

        if (result != AGENT_DATA_TYPES_OK)
        {
            dest->type = EDM_NO_TYPE;
        }
    }

    return result;
}