HRESULT CPropertyValueInternalStatics::ChangeTypeInternal()

in src/foundation/PropertyValueInternalStatics.cpp [1430:1701]


HRESULT CPropertyValueInternalStatics::ChangeTypeInternal(
    _In_    foundation::PropertyType type,
    _Inout_ foundation::IInspectable **ppValue
    )
{
    foundation_assert(ppValue);
    // for null values we will return a 'default' value
    if(*ppValue == nullptr)
    {
        return CreateDefaultValueInternal(type, ppValue);
    }

    foundation::ComPtr<foundation::IPropertyValue> spPropertyValue;
    IFR_ASSERT(foundation::QueryInterface(*ppValue,foundation_IID_IPropertyValue,spPropertyValue.GetAddressOf()));

    foundation::PropertyType valuePropertyType;
    IFR_ASSERT(spPropertyValue->get_Type(&valuePropertyType));

    if(type == valuePropertyType)
    {
        return S_OK;
    }
    foundation::IInspectable *pValue = *ppValue;

    if(type & 0x400)
    {
        foundation::IInspectable *pArrayValue = nullptr;
        // we need array cast
        _IFR_(CastToArray(type, spPropertyValue, &pArrayValue));
        *ppValue = pArrayValue;
    }
    else if (valuePropertyType == PropertyType_Boolean)
    {
        boolean boolValue;
        spPropertyValue->GetBoolean(&boolValue);
        switch (type)
        {
        case PropertyType_UInt8:
            IFR_ASSERT(pv_util::CreateUInt8Value(boolValue ? 1:0, ppValue));
            break;
        case PropertyType_Int16:
            IFR_ASSERT(pv_util::CreateInt16Value(boolValue ? 1 : 0, ppValue));
            break;
        case PropertyType_UInt16:
            IFR_ASSERT(pv_util::CreateUInt16Value(boolValue ? 1 : 0, ppValue));
            break;
        case PropertyType_Int32:
            IFR_ASSERT(pv_util::CreateInt32Value(boolValue ? 1 : 0, ppValue));
            break;
        case PropertyType_UInt32:
            IFR_ASSERT(pv_util::CreateUInt32Value(boolValue ? 1 : 0, ppValue));
            break;
        case PropertyType_Int64:
            IFR_ASSERT(pv_util::CreateInt64Value(boolValue ? 1 : 0, ppValue));
            break;
        case PropertyType_UInt64:
            IFR_ASSERT(pv_util::CreateUInt64Value(boolValue ? 1 : 0, ppValue));
            break;
        case PropertyType_String:
            IFR_ASSERT(pv_util::CreateStringValue(boolValue ? U("true") : U("false"), ppValue));
            break;
        default:
            return E_WRONG_TYPE;
        }
    }
    else
    {
    switch (type)
    {
    case PropertyType_UInt8:
        {
            BYTE value;
            _IFR_(spPropertyValue->GetUInt8(&value));
            IFR_ASSERT(pv_util::CreateUInt8Value(value,ppValue));
        }
        break;
    case PropertyType_Int16:
        {
            INT16 value;
            _IFR_(spPropertyValue->GetInt16(&value));
            IFR_ASSERT(pv_util::CreateInt16Value(value,ppValue));
        }
        break;
    case PropertyType_UInt16:
        {
            UINT16 value;
            _IFR_(spPropertyValue->GetUInt16(&value));
            IFR_ASSERT(pv_util::CreateUInt16Value(value,ppValue));
        }
        break;
    case PropertyType_Int32:
        {
            INT32 value;
            if (valuePropertyType == PropertyType_String)
            {
                foundation::HStringPtr hstr;
                _IFR_(spPropertyValue->GetString(hstr.GetAddressOf()));
                _IFR_(StringToInt(hstr, value));
            }
            else
            {
                _IFR_(spPropertyValue->GetInt32(&value));
            }
            IFR_ASSERT(pv_util::CreateInt32Value(value,ppValue));
        }
        break;
    case PropertyType_UInt32:
        {
            UINT32 value;
            if (valuePropertyType == PropertyType_String)
            {
                foundation::HStringPtr hstr;
                _IFR_(spPropertyValue->GetString(hstr.GetAddressOf()));
                _IFR_(StringToUInt(hstr, value));
            }
            else
            {
                _IFR_(spPropertyValue->GetUInt32(&value));
            }
            IFR_ASSERT(pv_util::CreateUInt32Value(value,ppValue));
        }
        break;
    case PropertyType_Int64:
        {
            INT64 value;
            _IFR_(spPropertyValue->GetInt64(&value));
            IFR_ASSERT(pv_util::CreateInt64Value(value,ppValue));
        }
        break;
    case PropertyType_UInt64:
        {
            UINT64 value;
            _IFR_(spPropertyValue->GetUInt64(&value));
            IFR_ASSERT(pv_util::CreateUInt64Value(value,ppValue));
        }
        break;
    case PropertyType_Single:
        {
            FLOAT value;
            if (valuePropertyType == PropertyType_Double)
            {
                DOUBLE doubleValue;
                _IFR_(spPropertyValue->GetDouble(&doubleValue));
                value = static_cast<FLOAT>(doubleValue);
            }
            else if (
                valuePropertyType == PropertyType_UInt8 ||
                valuePropertyType == PropertyType_UInt16 ||
                valuePropertyType == PropertyType_UInt32 ||
                valuePropertyType == PropertyType_UInt64)
            {
                UINT64 uint64;
                _IFR_(spPropertyValue->GetUInt64(&uint64));
                value = static_cast<FLOAT>(uint64);
            }
            else if (
                valuePropertyType == PropertyType_Int16 ||
                valuePropertyType == PropertyType_Int32 ||
                valuePropertyType == PropertyType_Int64)
            {
                INT64 int64;
                _IFR_(spPropertyValue->GetInt64(&int64));
                value = static_cast<FLOAT>(int64);
            }
            else
            {
                _IFR_(spPropertyValue->GetSingle(&value));
            }
            IFR_ASSERT(pv_util::CreateSingleValue(value,ppValue));
        }
        break;
    case PropertyType_Double:
        {
            DOUBLE value;
            _IFR_(spPropertyValue->GetDouble(&value));
            IFR_ASSERT(pv_util::CreateDoubleValue(value,ppValue));
        }
        break;
    case PropertyType_Char16:
        {
            WCHAR value;
            _IFR_(spPropertyValue->GetChar16(&value));
            IFR_ASSERT(pv_util::CreateChar16Value(value,ppValue));
        }
        break;
    case PropertyType_Boolean:
        {
            if (valuePropertyType == PropertyType_String)
            {
                foundation::HStringPtr value;
                spPropertyValue->GetString(value.GetAddressOf());

                if (_pal_strcmp(value.GetRawBuffer(), U("true")) == 0)
                {
                    IFR_ASSERT(pv_util::CreateBooleanValue(true, ppValue));
                }
                else if (_pal_strcmp(value.GetRawBuffer(), U("false")) == 0)
                {
                    IFR_ASSERT(pv_util::CreateBooleanValue(false, ppValue));
                }
                else
                {
                    return E_WRONG_TYPE;
                }
            }
            else
            {
                UINT8 value;
                _IFR_(spPropertyValue->GetUInt8(&value));
                IFR_ASSERT(pv_util::CreateBooleanValue(value ? true : false, ppValue));
            }
        }
        break;
    case PropertyType_String:
    case PropertyType_Guid:
        {
            if (type == PropertyType_Guid)
            {
                foundation::HStringPtr value;
                _IFR_(spPropertyValue->GetString(value.GetAddressOf()));

                IID iid;
                if (!::FromString(foundation::to_utf8_string(value).c_str(), iid))
                {
                    _IFR_(E_WRONG_TYPE);
                }
                IFR_ASSERT(pv_util::CreateGuidValue(iid, ppValue));
            }
            else // target is String
            {
                foundation::string_t string_value = ToString(spPropertyValue);
                IFR_ASSERT(pv_util::CreateStringValue(string_value.c_str(), ppValue));
            }
        }
        break;
    case PropertyType_DateTime:
        {
            foundation::HStringPtr value;
            _IFR_(spPropertyValue->GetString(value.GetAddressOf()));

            SystemTime systemTime;
            _IFR_(StringToSystmeTime(_pal_GetStringRawBuffer(value, nullptr), systemTime));

            DateTime dateTime;
            _IFR_(_pal_SystemTimeToDateTime(systemTime, &dateTime));

            IFR_ASSERT(pv_util::CreateDateTimeValue(dateTime,ppValue));
        }
        break;
    case PropertyType_Inspectable:
        {
            if(valuePropertyType == foundation::PropertyType_Empty)
            {
                // convert Empt type to a null value
                *ppValue = nullptr;
            }
            else
            {
                return E_UNEXPECTED;
            }
        }
        break;
    case PropertyType_TimeSpan:
    default:
        return E_NOTIMPL;
    }
    }
    // if we arrive here a new values is being returned in ppValue
    // so we Release the old value reference
    pValue->Release();
    return S_OK;
}