AGENT_DATA_TYPES_RESULT CreateAgentDataType_From_String()

in serializer/src/agenttypesystem.c [3080:3871]


AGENT_DATA_TYPES_RESULT CreateAgentDataType_From_String(const char* source, AGENT_DATA_TYPE_TYPE type, AGENT_DATA_TYPE* agentData)
{

    AGENT_DATA_TYPES_RESULT result;

    if ((source == NULL) ||
        (agentData == NULL))
    {
        result = AGENT_DATA_TYPES_INVALID_ARG;
        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
    }
    else
    {
        switch (type)
        {
            default:
                result = AGENT_DATA_TYPES_NOT_IMPLEMENTED;
                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                break;

            case EDM_BOOLEAN_TYPE:
            {
                if (strcmp(source, "true") == 0)
                {
                    agentData->type = EDM_BOOLEAN_TYPE;
                    agentData->value.edmBoolean.value = EDM_TRUE;
                    result = AGENT_DATA_TYPES_OK;
                }
                else if (strcmp(source, "false") == 0)
                {
                    agentData->type = EDM_BOOLEAN_TYPE;
                    agentData->value.edmBoolean.value = EDM_FALSE;
                    result = AGENT_DATA_TYPES_OK;
                }
                else
                {
                    result = AGENT_DATA_TYPES_INVALID_ARG;
                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                }

                break;
            }
            case EDM_NULL_TYPE:
            {
                if (strcmp(source, "null") == 0)
                {
                    agentData->type = EDM_NULL_TYPE;
                    result = AGENT_DATA_TYPES_OK;
                }
                else
                {
                    result = AGENT_DATA_TYPES_INVALID_ARG;
                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                }

                break;
            }

            case EDM_SBYTE_TYPE:
            {
                int sByteValue;
                if ((sscanfd(source, &sByteValue) != 1) ||
                    (sByteValue < -128) ||
                    (sByteValue > 127))
                {
                    result = AGENT_DATA_TYPES_INVALID_ARG;
                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                }
                else
                {
                    agentData->type = EDM_SBYTE_TYPE;
                    agentData->value.edmSbyte.value = (int8_t)sByteValue;
                    result = AGENT_DATA_TYPES_OK;
                }

                break;
            }

            case EDM_BYTE_TYPE:
            {
                int byteValue;
                if ((sscanfd(source, &byteValue) != 1) ||
                    (byteValue < 0) ||
                    (byteValue > 255))
                {
                    result = AGENT_DATA_TYPES_INVALID_ARG;
                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                }
                else
                {
                    agentData->type = EDM_BYTE_TYPE;
                    agentData->value.edmByte.value = (uint8_t)byteValue;
                    result = AGENT_DATA_TYPES_OK;
                }

                break;
            }

            case EDM_INT16_TYPE:
            {
                int int16Value;
                if ((sscanfd(source, &int16Value) != 1) ||
                    (int16Value < -32768) ||
                    (int16Value > 32767))
                {
                    result = AGENT_DATA_TYPES_INVALID_ARG;
                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                }
                else
                {
                    agentData->type = EDM_INT16_TYPE;
                    agentData->value.edmInt16.value = (int16_t)int16Value;
                    result = AGENT_DATA_TYPES_OK;
                }

                break;
            }

            case EDM_INT32_TYPE:
            {
                int32_t int32Value;
                unsigned char isNegative;
                uint32_t uint32Value;
                const char* pos;
                size_t strLength;

                if (source[0] == '-')
                {
                    isNegative = 1;
                    pos = &source[1];
                }
                else
                {
                    isNegative = 0;
                    pos = &source[0];
                }

                strLength = strlen(source);

                if ((sscanfu(pos, &uint32Value) != 1) ||
                    (strLength > 11) ||
                    ((uint32Value > 2147483648UL) && isNegative) ||
                    ((uint32Value > 2147483647UL) && (!isNegative)))
                {
                    result = AGENT_DATA_TYPES_INVALID_ARG;
                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                }
                else
                {
                    if (isNegative)
                    {
                        if (uint32Value == 2147483648UL)
                        {
                           int32Value = -2147483647L - 1L;
                        }
                        else
                        {
                            int32Value = -(int32_t)uint32Value;
                        }
                    }
                    else
                    {
                        int32Value = uint32Value;
                    }

                    agentData->type = EDM_INT32_TYPE;
                    agentData->value.edmInt32.value = (int32_t)int32Value;
                    result = AGENT_DATA_TYPES_OK;
                }

                break;
            }

            case EDM_INT64_TYPE:
            {
                long long int64Value;
                unsigned char isNegative;
                unsigned long long ullValue;
                const char* pos;
                size_t strLength;

                if (source[0] == '-')
                {
                    isNegative = 1;
                    pos = &source[1];
                }
                else
                {
                    isNegative = 0;
                    pos = &source[0];
                }

                strLength = strlen(source);

                if ((sscanfllu(&pos, &ullValue) != 1) ||
                    (strLength > 20) ||
                    ((ullValue > 9223372036854775808ULL) && isNegative) ||
                    ((ullValue > 9223372036854775807ULL) && (!isNegative)))
                {
                    result = AGENT_DATA_TYPES_INVALID_ARG;
                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                }
                else
                {
                    if (isNegative)
                    {
                        if (ullValue == 9223372036854775808ULL)
                        {
                            int64Value = -9223372036854775807LL - 1LL;
                        }
                        else
                        {
                            int64Value = -(long long)ullValue;
                        }
                    }
                    else
                    {
                        int64Value = ullValue;
                    }
                    agentData->type = EDM_INT64_TYPE;
                    agentData->value.edmInt64.value = (int64_t)int64Value;
                    result = AGENT_DATA_TYPES_OK;
                }

                break;
            }

            case EDM_DATE_TYPE:
            {
                int year;
                int month;
                int day;
                size_t strLength = strlen(source);

                if ((strLength < 2) ||
                    (source[0] != '"') ||
                    (source[strLength - 1] != '"'))
                {
                    result = AGENT_DATA_TYPES_INVALID_ARG;
                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                }
                else
                {
                    size_t pos = 1;
                    int sign;
                    scanOptionalMinusSign(source, 2, &pos, &sign);

                    if ((scanAndReadNDigitsInt(source, &pos, &year, 4) != 0) ||
                        (source[pos++] != '-') ||
                        (scanAndReadNDigitsInt(source, &pos, &month, 2) != 0) ||
                        (source[pos++] != '-') ||
                        (scanAndReadNDigitsInt(source, &pos, &day, 2) != 0) ||
                        (Create_AGENT_DATA_TYPE_from_date(agentData, (int16_t)(sign*year), (uint8_t)month, (uint8_t)day) != AGENT_DATA_TYPES_OK))
                    {
                        result = AGENT_DATA_TYPES_INVALID_ARG;
                        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                    }
                    else
                    {
                        result = AGENT_DATA_TYPES_OK;
                    }
                }

                break;
            }

            case EDM_DATE_TIME_OFFSET_TYPE:
            {
                int year;
                int month;
                int day;
                int hour;
                int min;
                int sec = 0;
                int hourOffset;
                int minOffset;
                unsigned long long fractionalSeconds = 0;
                size_t strLength = strlen(source);

                agentData->value.edmDateTimeOffset.hasFractionalSecond = 0;
                agentData->value.edmDateTimeOffset.hasTimeZone = 0;
                /* The value of tm_isdst is positive if Daylight Saving Time is in effect, zero if Daylight
                   Saving Time is not in effect, and negative if the information is not available.*/
                agentData->value.edmDateTimeOffset.dateTime.tm_isdst = -1;

                if ((strLength < 2) ||
                    (source[0] != '"') ||
                    (source[strLength - 1] != '"'))
                {
                    result = AGENT_DATA_TYPES_INVALID_ARG;
                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                }
                else
                {
                    size_t pos = 1;
                    int sign;
                    scanOptionalMinusSign(source, 2, &pos, &sign);

                    if ((scanAndReadNDigitsInt(source, &pos, &year, 4) != 0) ||
                        (source[pos++] != '-') ||
                        (scanAndReadNDigitsInt(source, &pos, &month, 2) != 0) ||
                        (source[pos++] != '-') ||
                        (scanAndReadNDigitsInt(source, &pos, &day, 2) != 0) ||
                        (source[pos++] != 'T') ||
                        (scanAndReadNDigitsInt(source, &pos, &hour, 2) != 0) ||
                        (source[pos++] != ':') ||
                        (scanAndReadNDigitsInt(source, &pos, &min, 2) != 0))
                    {
                        result = AGENT_DATA_TYPES_INVALID_ARG;
                        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                    }
                    else
                    {
                        const char* pos2;
                        year = year*sign;
                        if ((pos2 = strchr(source, ':')) == NULL)
                        {
                            result = AGENT_DATA_TYPES_INVALID_ARG;
                            LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                        }
                        else
                        {
                            pos2 += 3;
                            if (*pos2 == ':')
                            {
                                if (sscanf2d(pos2, &sec) != 1)
                                {
                                    pos2 = NULL;
                                }
                                else
                                {
                                    pos2 += 3;
                                }
                            }

                            if ((pos2 != NULL) &&
                                (*pos2 == '.'))
                            {
                                if (sscanfdotllu(pos2, &fractionalSeconds) != 1)
                                {
                                    pos2 = NULL;
                                }
                                else
                                {
                                    pos2++;

                                    agentData->value.edmDateTimeOffset.hasFractionalSecond = 1;

                                    while ((*pos2 != '\0') &&
                                        (IS_DIGIT(*pos2)))
                                    {
                                        pos2++;
                                    }

                                    if (*pos2 == '\0')
                                    {
                                        pos2 = NULL;
                                    }
                                }
                            }

                            if (pos2 == NULL)
                            {
                                result = AGENT_DATA_TYPES_INVALID_ARG;
                                LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                            }
                            else
                            {
                                hourOffset = 0;
                                minOffset = 0;

                                if (sscanf3d2d(pos2, &hourOffset, &minOffset) == 2)
                                {
                                    agentData->value.edmDateTimeOffset.hasTimeZone = 1;
                                }

                                if ((strcmp(pos2, "Z\"") == 0) ||
                                    agentData->value.edmDateTimeOffset.hasTimeZone)
                                {
                                    if ((ValidateDate(year, month, day) != 0) ||
                                        (hour < 0) ||
                                        (hour > 23) ||
                                        (min < 0) ||
                                        (min > 59) ||
                                        (sec < 0) ||
                                        (sec > 59) ||
                                        (fractionalSeconds > 999999999999) ||
                                        (hourOffset < -23) ||
                                        (hourOffset > 23) ||
                                        (minOffset < 0) ||
                                        (minOffset > 59))
                                    {
                                        result = AGENT_DATA_TYPES_INVALID_ARG;
                                        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                                    }
                                    else
                                    {
                                        agentData->type = EDM_DATE_TIME_OFFSET_TYPE;
                                        agentData->value.edmDateTimeOffset.dateTime.tm_year= year-1900;
                                        agentData->value.edmDateTimeOffset.dateTime.tm_mon = month-1;
                                        agentData->value.edmDateTimeOffset.dateTime.tm_mday = day;
                                        agentData->value.edmDateTimeOffset.dateTime.tm_hour = hour;
                                        agentData->value.edmDateTimeOffset.dateTime.tm_min = min;
                                        agentData->value.edmDateTimeOffset.dateTime.tm_sec = sec;
                                        /*fill in tm_wday and tm_yday*/
                                        fill_tm_yday_and_tm_wday(&agentData->value.edmDateTimeOffset.dateTime);
                                        agentData->value.edmDateTimeOffset.fractionalSecond = (uint64_t)fractionalSeconds;
                                        agentData->value.edmDateTimeOffset.timeZoneHour = (int8_t)hourOffset;
                                        agentData->value.edmDateTimeOffset.timeZoneMinute = (uint8_t)minOffset;
                                        result = AGENT_DATA_TYPES_OK;
                                    }
                                }
                                else
                                {
                                    result = AGENT_DATA_TYPES_INVALID_ARG;
                                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                                }
                            }
                        }
                    }
                }

                break;
            }

            case EDM_DOUBLE_TYPE:
            {
                if (strcmp(source, "\"NaN\"") == 0)
                {
                    agentData->type = EDM_DOUBLE_TYPE;
#pragma warning(disable:26451) // warning C26451: overflow in constant arithmetic
                    agentData->value.edmDouble.value = NAN;
#pragma warning (default:26451)
                    result = AGENT_DATA_TYPES_OK;
                }
                else if (strcmp(source, "\"INF\"") == 0)
                {
                    agentData->type = EDM_DOUBLE_TYPE;
                    agentData->value.edmDouble.value = INFINITY;
                    result = AGENT_DATA_TYPES_OK;
                }
                else if (strcmp(source, "\"-INF\"") == 0)
                {
                    agentData->type = EDM_DOUBLE_TYPE;
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4056) /* Known warning for INIFNITY */
#endif
                    agentData->value.edmDouble.value = -INFINITY;
#ifdef _MSC_VER
#pragma warning(pop)
#endif
                    result = AGENT_DATA_TYPES_OK;
                }
                else if (sscanflf(source, &(agentData->value.edmDouble.value)) != 1)
                {
                    result = AGENT_DATA_TYPES_INVALID_ARG;
                }
                else
                {
                    agentData->type = EDM_DOUBLE_TYPE;
                    result = AGENT_DATA_TYPES_OK;
                }
                break;
            }

            case EDM_SINGLE_TYPE:
            {
                if (strcmp(source, "\"NaN\"") == 0)
                {
                    agentData->type = EDM_SINGLE_TYPE;
                    agentData->value.edmSingle.value = NAN;
                    result = AGENT_DATA_TYPES_OK;
                }
                else if (strcmp(source, "\"INF\"") == 0)
                {
                    agentData->type = EDM_SINGLE_TYPE;
                    agentData->value.edmSingle.value = INFINITY;
                    result = AGENT_DATA_TYPES_OK;
                }
                else if (strcmp(source, "\"-INF\"") == 0)
                {
                    agentData->type = EDM_SINGLE_TYPE;
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4056) /* Known warning for INIFNITY */
#endif
                    agentData->value.edmSingle.value = -INFINITY;
#ifdef _MSC_VER
#pragma warning(pop)
#endif
result = AGENT_DATA_TYPES_OK;
                }
                else if (sscanff(source, &agentData->value.edmSingle.value) != 1)
                {
                    result = AGENT_DATA_TYPES_INVALID_ARG;
                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                }
                else
                {
                    agentData->type = EDM_SINGLE_TYPE;
                    result = AGENT_DATA_TYPES_OK;
                }
                break;
            }

            case EDM_DECIMAL_TYPE:
            {
                size_t strLength = strlen(source);
                if ((strLength < 2) ||
                    (source[0] != '"') ||
                    (source[strLength - 1] != '"') ||
                    (ValidateDecimal(source + 1, strLength - 2) != 0))
                {
                    result = AGENT_DATA_TYPES_INVALID_ARG;
                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                }
                else
                {
                    agentData->type = EDM_DECIMAL_TYPE;
                    agentData->value.edmDecimal.value = STRING_construct_n(source + 1, strLength-2);
                    if (agentData->value.edmDecimal.value == NULL)
                    {
                        result = AGENT_DATA_TYPES_ERROR;
                        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                    }
                    else
                    {
                        result = AGENT_DATA_TYPES_OK;
                    }
                }
                break;
            }

            case EDM_STRING_TYPE:
            {
                size_t strLength = strlen(source);
                if ((strLength < 2) ||
                    (source[0] != '"') ||
                    (source[strLength - 1] != '"'))
                {
                    result = AGENT_DATA_TYPES_INVALID_ARG;
                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                }
                else
                {
                    char* temp;
                    size_t malloc_size = safe_subtract_size_t(strLength, 1);
                    if (malloc_size == SIZE_MAX ||
                        (temp = (char*)malloc(malloc_size)) == NULL)
                    {
                        result = AGENT_DATA_TYPES_ERROR;
                        LogError("(result = %s), size:%zu", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result), malloc_size);
                    }
                    else if (memcpy(temp, source + 1, strLength - 2) == NULL)
                    {
                        free(temp);

                        result = AGENT_DATA_TYPES_ERROR;
                        LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                    }
                    else
                    {
                        // Removes the "
                        temp[strLength - 2] = 0;
                        agentData->type = EDM_STRING_TYPE;
                        agentData->value.edmString.chars = temp;
                        agentData->value.edmString.length = strLength - 2;
                        result = AGENT_DATA_TYPES_OK;
                    }
                }
                break;
            }
            case EDM_STRING_NO_QUOTES_TYPE:
            {
                char* temp;
                size_t strLength = strlen(source);
                if (mallocAndStrcpy_s(&temp, source) != 0)
                {
                    result = AGENT_DATA_TYPES_ERROR;
                    LogError("(result = %s)", MU_ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result));
                }
                else
                {
                    agentData->type = EDM_STRING_NO_QUOTES_TYPE;
                    agentData->value.edmStringNoQuotes.chars = temp;
                    agentData->value.edmStringNoQuotes.length = strLength;
                    result = AGENT_DATA_TYPES_OK;
                }
                break;
            }
            case EDM_GUID_TYPE:
            {
                if (strlen(source) != GUID_STRING_LENGTH)
                {
                    result = AGENT_DATA_TYPES_INVALID_ARG;
                }
                else
                {
                    if (source[0] != '"')
                    {
                        result = AGENT_DATA_TYPES_INVALID_ARG;
                    }
                    else if (scanMandatory2CapitalHexDigits(source + 1, &(agentData->value.edmGuid.GUID[0])) != 0)
                    {
                        result = AGENT_DATA_TYPES_INVALID_ARG;
                    }
                    else if (scanMandatory2CapitalHexDigits(source + 3, &(agentData->value.edmGuid.GUID[1])) != 0)
                    {
                        result = AGENT_DATA_TYPES_INVALID_ARG;
                    }
                    else if (scanMandatory2CapitalHexDigits(source + 5, &(agentData->value.edmGuid.GUID[2])) != 0)
                    {
                        result = AGENT_DATA_TYPES_INVALID_ARG;
                    }
                    else if (scanMandatory2CapitalHexDigits(source + 7, &(agentData->value.edmGuid.GUID[3])) != 0)
                    {
                        result = AGENT_DATA_TYPES_INVALID_ARG;
                    }
                    else if (source[9] != '-')
                    {
                        result = AGENT_DATA_TYPES_INVALID_ARG;
                    }
                    else if (scanMandatory2CapitalHexDigits(source + 10, &(agentData->value.edmGuid.GUID[4])) != 0)
                    {
                        result = AGENT_DATA_TYPES_INVALID_ARG;
                    }
                    else if (scanMandatory2CapitalHexDigits(source + 12, &(agentData->value.edmGuid.GUID[5])) != 0)
                    {
                        result = AGENT_DATA_TYPES_INVALID_ARG;
                    }
                    else if (source[14] != '-')
                    {
                        result = AGENT_DATA_TYPES_INVALID_ARG;
                    }
                    else if (scanMandatory2CapitalHexDigits(source + 15, &(agentData->value.edmGuid.GUID[6])) != 0)
                    {
                        result = AGENT_DATA_TYPES_INVALID_ARG;
                    }
                    else if (scanMandatory2CapitalHexDigits(source + 17, &(agentData->value.edmGuid.GUID[7])) != 0)
                    {
                        result = AGENT_DATA_TYPES_INVALID_ARG;
                    }
                    else if (source[19] != '-')
                    {
                        result = AGENT_DATA_TYPES_INVALID_ARG;
                    }
                    else if (scanMandatory2CapitalHexDigits(source + 20, &(agentData->value.edmGuid.GUID[8])) != 0)
                    {
                        result = AGENT_DATA_TYPES_INVALID_ARG;
                    }
                    else if (scanMandatory2CapitalHexDigits(source + 22, &(agentData->value.edmGuid.GUID[9])) != 0)
                    {
                        result = AGENT_DATA_TYPES_INVALID_ARG;
                    }
                    else if (source[24] != '-')
                    {
                        result = AGENT_DATA_TYPES_INVALID_ARG;
                    }
                    else if (scanMandatory2CapitalHexDigits(source + 25, &(agentData->value.edmGuid.GUID[10])) != 0)
                    {
                        result = AGENT_DATA_TYPES_INVALID_ARG;
                    }
                    else if (scanMandatory2CapitalHexDigits(source + 27, &(agentData->value.edmGuid.GUID[11])) != 0)
                    {
                        result = AGENT_DATA_TYPES_INVALID_ARG;
                    }
                    else if (scanMandatory2CapitalHexDigits(source + 29, &(agentData->value.edmGuid.GUID[12])) != 0)
                    {
                        result = AGENT_DATA_TYPES_INVALID_ARG;
                    }
                    else if (scanMandatory2CapitalHexDigits(source + 31, &(agentData->value.edmGuid.GUID[13])) != 0)
                    {
                        result = AGENT_DATA_TYPES_INVALID_ARG;
                    }
                    else if (scanMandatory2CapitalHexDigits(source + 33, &(agentData->value.edmGuid.GUID[14])) != 0)
                    {
                        result = AGENT_DATA_TYPES_INVALID_ARG;
                    }
                    else if (scanMandatory2CapitalHexDigits(source + 35, &(agentData->value.edmGuid.GUID[15])) != 0)
                    {
                        result = AGENT_DATA_TYPES_INVALID_ARG;
                    }
                    else if (source[37] != '"')
                    {
                        result = AGENT_DATA_TYPES_INVALID_ARG;
                    }
                    else
                    {
                        agentData->type = EDM_GUID_TYPE;
                        result = AGENT_DATA_TYPES_OK;
                    }
                }
                break;
            }
            case EDM_BINARY_TYPE:
            {
                size_t sourceLength = strlen(source);
                if (sourceLength < 2)
                {
                    result = AGENT_DATA_TYPES_INVALID_ARG;
                }
                else if (sourceLength == 2)
                {
                    agentData->type = EDM_BINARY_TYPE;
                    agentData->value.edmBinary.data = NULL;
                    agentData->value.edmBinary.size = 0;
                    result = AGENT_DATA_TYPES_OK;
                }
                else
                {
                    size_t sourcePosition = 0;
                    if (source[sourcePosition++] != '"') /*if it doesn't start with a quote then... */
                    {
                        result = AGENT_DATA_TYPES_INVALID_ARG;
                    }
                    else
                    {
                        /*1. read groups of 4 base64 character and transfer those into groups of 3 "normal" characters.
                        2. read the end of the string and produce from that the ending characters*/

                        /*compute the amount of memory to allocate*/
                        agentData->value.edmBinary.size = (((sourceLength - 2) + 4) / 4) * 3; /*this is overallocation, shall be trimmed later*/
                        agentData->value.edmBinary.data = (unsigned char*)malloc(agentData->value.edmBinary.size); /*this is overallocation, shall be trimmed later*/
                        if (agentData->value.edmBinary.data == NULL)
                        {
                            result = AGENT_DATA_TYPES_ERROR;
                        }
                        else
                        {

                            size_t destinationPosition = 0;
                            size_t consumed;
                            /*read and store "solid" groups of 4 base64 chars*/
                            while (scan4base64char(source + sourcePosition, sourceLength - sourcePosition, agentData->value.edmBinary.data + destinationPosition, agentData->value.edmBinary.data + destinationPosition + 1, agentData->value.edmBinary.data + destinationPosition + 2) == 0)
                            {
                                sourcePosition += 4;
                                destinationPosition += 3;
                            }

                            if (scanbase64b16(source + sourcePosition, sourceLength - sourcePosition, &consumed, agentData->value.edmBinary.data + destinationPosition, agentData->value.edmBinary.data + destinationPosition + 1) == 0)
                            {
                                sourcePosition += consumed;
                                destinationPosition += 2;

                            }
                            else if (scanbase64b8(source + sourcePosition, sourceLength - sourcePosition, &consumed, agentData->value.edmBinary.data + destinationPosition) == 0)
                            {
                                sourcePosition += consumed;
                                destinationPosition += 1;
                            }

                            if (source[sourcePosition++] != '"') /*if it doesn't end with " then bail out*/
                            {
                                free(agentData->value.edmBinary.data);
                                agentData->value.edmBinary.data = NULL;
                                result = AGENT_DATA_TYPES_INVALID_ARG;
                            }
                            else if (sourcePosition != sourceLength)
                            {
                                free(agentData->value.edmBinary.data);
                                agentData->value.edmBinary.data = NULL;
                                result = AGENT_DATA_TYPES_INVALID_ARG;
                            }
                            else
                            {
                                /*trim the result*/
                                void* temp = realloc(agentData->value.edmBinary.data, destinationPosition);
                                if (temp == NULL) /*this is extremely unlikely to happen, but whatever*/
                                {
                                    free(agentData->value.edmBinary.data);
                                    agentData->value.edmBinary.data = NULL;
                                    result = AGENT_DATA_TYPES_ERROR;
                                }
                                else
                                {
                                    agentData->type = EDM_BINARY_TYPE;
                                    agentData->value.edmBinary.data = (unsigned char*)temp;
                                    agentData->value.edmBinary.size = destinationPosition;
                                    result = AGENT_DATA_TYPES_OK;
                                }
                            }
                        }
                    }
                }
                break;
            }
        }
    }

    return result;
}