STDMETHODIMP CPropertyValueInternalStatics::ComparePropertyValues()

in src/foundation/PropertyValueInternalStatics.cpp [846:1040]


STDMETHODIMP CPropertyValueInternalStatics::ComparePropertyValues(
    _In_ IPropertyValue *pPropertyValue1,
    _In_ IPropertyValue *pPropertyValue2,
    _Out_ int *pCompareResult)
{
    foundation_assert(pPropertyValue1);
    foundation_assert(pPropertyValue2);

    PropertyType type1,type2;
    IFR_ASSERT(pPropertyValue1->get_Type(&type1));
    IFR_ASSERT(pPropertyValue2->get_Type(&type2));

    *pCompareResult = -1;
    if(type1 != type2)
    {
        if(isValueType(type1) && isValueType(type2))
        {
            if(isRealType(type1) || isRealType(type2))
            {
                type1 = PropertyType_Double;
            }
            else
            {
                // TODO: we should select the proper unsigned type when needed
                type1 = PropertyType_Int64;
            }
        }
        else if (isValueType(type2) && type1 == PropertyType_DateTime)
        {
            return CompareDateTimeWithValue(pPropertyValue1, pPropertyValue2, pCompareResult,false);
        }
        else if (isValueType(type1) && type2 == PropertyType_DateTime)
        {
            return CompareDateTimeWithValue(pPropertyValue2, pPropertyValue1, pCompareResult,true);
        }
        else
        {
            // cast will fail when getting values
            return E_UNEXPECTED;
        }
    }

    switch (type1)
    {
    case PropertyType_Empty:
        *pCompareResult = 0;
        break;
    case PropertyType_UInt8:
        {
            BYTE value1;
            BYTE value2;
            IFR_ASSERT(pPropertyValue1->GetUInt8(&value1));
            IFR_ASSERT(pPropertyValue2->GetUInt8(&value2));
            *pCompareResult = value1 - value2;
        }
        break;
    case PropertyType_Int16:
        {
            INT16 value1;
            INT16 value2;
            IFR_ASSERT(pPropertyValue1->GetInt16(&value1));
            IFR_ASSERT(pPropertyValue2->GetInt16(&value2));
            *pCompareResult = value1 - value2;
        }
        break;
    case PropertyType_UInt16:
        {
            UINT16 value1;
            UINT16 value2;
            IFR_ASSERT(pPropertyValue1->GetUInt16(&value1));
            IFR_ASSERT(pPropertyValue2->GetUInt16(&value2));
            *pCompareResult = value1 - value2;
        }
        break;
    case PropertyType_Int32:
        {
            INT32 value1;
            INT32 value2;
            IFR_ASSERT(pPropertyValue1->GetInt32(&value1));
            IFR_ASSERT(pPropertyValue2->GetInt32(&value2));
            *pCompareResult = value1 - value2;
        }
        break;
    case PropertyType_UInt32:
        {
            UINT32 value1;
            UINT32 value2;
            IFR_ASSERT(pPropertyValue1->GetUInt32(&value1));
            IFR_ASSERT(pPropertyValue2->GetUInt32(&value2));
            *pCompareResult = value1 - value2;
        }
        break;
    case PropertyType_Int64:
        {
            INT64 value1;
            INT64 value2;
            IFR_ASSERT(pPropertyValue1->GetInt64(&value1));
            IFR_ASSERT(pPropertyValue2->GetInt64(&value2));
            *pCompareResult = CompareValues(value1,value2);
        }
        break;
    case PropertyType_UInt64:
        {
            UINT64 value1;
            UINT64 value2;
            IFR_ASSERT(pPropertyValue1->GetUInt64(&value1));
            IFR_ASSERT(pPropertyValue2->GetUInt64(&value2));
            *pCompareResult = CompareValues(value1,value2);
        }
        break;
    case PropertyType_Single:
        {
            FLOAT value1;
            FLOAT value2;
            IFR_ASSERT(pPropertyValue1->GetSingle(&value1));
            IFR_ASSERT(pPropertyValue2->GetSingle(&value2));
            *pCompareResult = CompareValues(value1,value2);
        }
        break;
    case PropertyType_Double:
        {
            DOUBLE value1;
            DOUBLE value2;
            IFR_ASSERT(pPropertyValue1->GetDouble(&value1));
            IFR_ASSERT(pPropertyValue2->GetDouble(&value2));
            *pCompareResult = CompareValues(value1,value2);
        }
        break;
    case PropertyType_Char16:
        {
            WCHAR value1;
            WCHAR value2;
            IFR_ASSERT(pPropertyValue1->GetChar16(&value1));
            IFR_ASSERT(pPropertyValue2->GetChar16(&value2));
            *pCompareResult = value1 - value2;
        }
        break;
    case PropertyType_Boolean:
        {
            boolean value1;
            boolean value2;
            IFR_ASSERT(pPropertyValue1->GetBoolean(&value1));
            IFR_ASSERT(pPropertyValue2->GetBoolean(&value2));
            *pCompareResult = value1 - value2;
        }
        break;
    case PropertyType_String:
        {
            foundation::HStringPtr value1;
            foundation::HStringPtr value2;
            IFR_ASSERT(pPropertyValue1->GetString(value1.GetAddressOf()));
            IFR_ASSERT(pPropertyValue2->GetString(value2.GetAddressOf()));
            IFR_ASSERT(_pal_CompareStringOrdinal(value1, value2, pCompareResult));
        }
        break;
    case PropertyType_Inspectable:
        foundation_assert(false);
        break;
    case PropertyType_DateTime:
        {
            foundation::DateTime dt1,dt2;
            IFR_ASSERT(pPropertyValue1->GetDateTime(&dt1));
            IFR_ASSERT(pPropertyValue2->GetDateTime(&dt2));
            *pCompareResult = (int)(dt1.UniversalTime - dt2.UniversalTime);
        }
        break;
    case PropertyType_TimeSpan:
        {
            foundation::TimeSpan t1, t2;
            IFR_ASSERT(pPropertyValue1->GetTimeSpan(&t1));
            IFR_ASSERT(pPropertyValue2->GetTimeSpan(&t2));
            *pCompareResult = (int)(t1.Duration - t2.Duration);
        }
        break;
    case PropertyType_Guid:
        {
            GUID value1;
            GUID value2;
            IFR_ASSERT(pPropertyValue1->GetGuid(&value1));
            IFR_ASSERT(pPropertyValue2->GetGuid(&value2));
            if (value1 == value2)
            {
                *pCompareResult = 0;
            }
            else
            {
                *pCompareResult = foundation::library::GuidLessThan::compare(value1, value2) ? -1 : 1;
            }
        }
        break;
    default:
        return E_NOTIMPL;
    }
    return S_OK;
}