[PATCH 1/6] mfplat: Implement Compare() for attributes.

Nikolay Sivov nsivov at codeweavers.com
Mon Mar 18 05:00:56 CDT 2019


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/mfplat/main.c         | 101 +++++++++++++++--
 dlls/mfplat/tests/mfplat.c | 223 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 315 insertions(+), 9 deletions(-)

diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c
index 88945f6724..4589840c21 100644
--- a/dlls/mfplat/main.c
+++ b/dlls/mfplat/main.c
@@ -724,9 +724,24 @@ static HRESULT WINAPI mfattributes_GetItem(IMFAttributes *iface, REFGUID key, PR
 
 static HRESULT WINAPI mfattributes_GetItemType(IMFAttributes *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type)
 {
-    FIXME("%p, %s, %p.\n", iface, debugstr_attr(key), type);
+    struct attributes *attributes = impl_from_IMFAttributes(iface);
+    struct attribute *attribute;
+    HRESULT hr = S_OK;
 
-    return E_NOTIMPL;
+    TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), type);
+
+    EnterCriticalSection(&attributes->cs);
+
+    if ((attribute = attributes_find_item(attributes, key, NULL)))
+    {
+        *type = attribute->value.vt;
+    }
+    else
+        hr = MF_E_ATTRIBUTENOTFOUND;
+
+    LeaveCriticalSection(&attributes->cs);
+
+    return hr;
 }
 
 static HRESULT WINAPI mfattributes_CompareItem(IMFAttributes *iface, REFGUID key, REFPROPVARIANT value, BOOL *result)
@@ -748,14 +763,86 @@ static HRESULT WINAPI mfattributes_CompareItem(IMFAttributes *iface, REFGUID key
     return S_OK;
 }
 
-static HRESULT WINAPI mfattributes_Compare(IMFAttributes *iface, IMFAttributes *theirs, MF_ATTRIBUTES_MATCH_TYPE type,
-                BOOL *result)
+static HRESULT WINAPI mfattributes_Compare(IMFAttributes *iface, IMFAttributes *theirs,
+        MF_ATTRIBUTES_MATCH_TYPE match_type, BOOL *ret)
 {
-    mfattributes *This = impl_from_IMFAttributes(iface);
+    struct attributes *attributes = impl_from_IMFAttributes(iface);
+    IMFAttributes *smaller, *other;
+    MF_ATTRIBUTE_TYPE type;
+    HRESULT hr = S_OK;
+    UINT32 count;
+    BOOL result;
+    size_t i;
 
-    FIXME("%p, %p, %d, %p\n", This, theirs, type, result);
+    TRACE("%p, %p, %d, %p.\n", iface, theirs, match_type, ret);
 
-    return E_NOTIMPL;
+    if (FAILED(hr = IMFAttributes_GetCount(theirs, &count)))
+        return hr;
+
+    EnterCriticalSection(&attributes->cs);
+
+    result = TRUE;
+
+    switch (match_type)
+    {
+        case MF_ATTRIBUTES_MATCH_OUR_ITEMS:
+            for (i = 0; i < attributes->count; ++i)
+            {
+                if (FAILED(hr = IMFAttributes_CompareItem(theirs, &attributes->attributes[i].key,
+                        &attributes->attributes[i].value, &result)))
+                    break;
+                if (!result)
+                    break;
+            }
+            break;
+        case MF_ATTRIBUTES_MATCH_THEIR_ITEMS:
+            hr = IMFAttributes_Compare(theirs, iface, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
+            break;
+        case MF_ATTRIBUTES_MATCH_ALL_ITEMS:
+            if (count != attributes->count)
+            {
+                result = FALSE;
+                break;
+            }
+            for (i = 0; i < count; ++i)
+            {
+                if (FAILED(hr = IMFAttributes_CompareItem(theirs, &attributes->attributes[i].key,
+                        &attributes->attributes[i].value, &result)))
+                    break;
+                if (!result)
+                    break;
+            }
+            break;
+        case MF_ATTRIBUTES_MATCH_INTERSECTION:
+            for (i = 0; i < attributes->count; ++i)
+            {
+                if (FAILED(IMFAttributes_GetItemType(theirs, &attributes->attributes[i].key, &type)))
+                    continue;
+
+                if (FAILED(hr = IMFAttributes_CompareItem(theirs, &attributes->attributes[i].key,
+                        &attributes->attributes[i].value, &result)))
+                    break;
+
+                if (!result)
+                    break;
+            }
+            break;
+        case MF_ATTRIBUTES_MATCH_SMALLER:
+            smaller = attributes->count > count ? theirs : iface;
+            other = attributes->count > count ? iface : theirs;
+            hr = IMFAttributes_Compare(smaller, other, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
+            break;
+        default:
+            WARN("Unknown match type %d.\n", match_type);
+            hr = E_INVALIDARG;
+    }
+
+    LeaveCriticalSection(&attributes->cs);
+
+    if (SUCCEEDED(hr))
+        *ret = result;
+
+    return hr;
 }
 
 static HRESULT WINAPI mfattributes_GetUINT32(IMFAttributes *iface, REFGUID key, UINT32 *value)
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
index 38151d9020..d012acc524 100644
--- a/dlls/mfplat/tests/mfplat.c
+++ b/dlls/mfplat/tests/mfplat.c
@@ -496,14 +496,27 @@ static void check_attr_count(IMFAttributes* obj, UINT32 expected, int line)
     ok_(__FILE__, line)(count == expected, "Unexpected count %u, expected %u.\n", count, expected);
 }
 
-static void test_MFCreateAttributes(void)
+#define CHECK_ATTR_TYPE(obj, key, expected) check_attr_type(obj, key, expected, __LINE__)
+static void check_attr_type(IMFAttributes *obj, const GUID *key, MF_ATTRIBUTE_TYPE expected, int line)
+{
+    MF_ATTRIBUTE_TYPE type;
+    HRESULT hr;
+
+    hr = IMFAttributes_GetItemType(obj, key, &type);
+    ok_(__FILE__, line)(hr == S_OK, "Failed to get item type, hr %#x.\n", hr);
+    ok_(__FILE__, line)(type == expected, "Unexpected item type %d, expected %d.\n", type, expected);
+}
+
+static void test_attributes(void)
 {
     static const WCHAR stringW[] = {'W','i','n','e',0};
     static const UINT8 blob[] = {0,1,2,3,4,5};
     IMFAttributes *attributes, *attributes1;
     UINT8 blob_value[256], *blob_buf = NULL;
+    MF_ATTRIBUTES_MATCH_TYPE match_type;
     UINT32 value, string_length, size;
     PROPVARIANT propvar, ret_propvar;
+    MF_ATTRIBUTE_TYPE type;
     double double_value;
     IUnknown *unk_value;
     WCHAR bufferW[256];
@@ -516,10 +529,14 @@ static void test_MFCreateAttributes(void)
     hr = MFCreateAttributes( &attributes, 3 );
     ok(hr == S_OK, "got 0x%08x\n", hr);
 
+    hr = IMFAttributes_GetItemType(attributes, &GUID_NULL, &type);
+    ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
+
     CHECK_ATTR_COUNT(attributes, 0);
     hr = IMFAttributes_SetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 123);
     ok(hr == S_OK, "Failed to set UINT32 value, hr %#x.\n", hr);
     CHECK_ATTR_COUNT(attributes, 1);
+    CHECK_ATTR_TYPE(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, MF_ATTRIBUTE_UINT32);
 
     value = 0xdeadbeef;
     hr = IMFAttributes_GetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value);
@@ -534,6 +551,7 @@ static void test_MFCreateAttributes(void)
     hr = IMFAttributes_SetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 65536);
     ok(hr == S_OK, "Failed to set UINT64 value, hr %#x.\n", hr);
     CHECK_ATTR_COUNT(attributes, 1);
+    CHECK_ATTR_TYPE(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, MF_ATTRIBUTE_UINT64);
 
     hr = IMFAttributes_GetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value64);
     ok(hr == S_OK, "Failed to get UINT64 value, hr %#x.\n", hr);
@@ -643,6 +661,7 @@ static void test_MFCreateAttributes(void)
     hr = IMFAttributes_SetDouble(attributes, &GUID_NULL, 22.0);
     ok(hr == S_OK, "Failed to set double value, hr %#x.\n", hr);
     CHECK_ATTR_COUNT(attributes, 3);
+    CHECK_ATTR_TYPE(attributes, &GUID_NULL, MF_ATTRIBUTE_DOUBLE);
 
     double_value = 0xdeadbeef;
     hr = IMFAttributes_GetDouble(attributes, &GUID_NULL, &double_value);
@@ -664,6 +683,7 @@ static void test_MFCreateAttributes(void)
     hr = IMFAttributes_SetString(attributes, &DUMMY_GUID1, stringW);
     ok(hr == S_OK, "Failed to set string attribute, hr %#x.\n", hr);
     CHECK_ATTR_COUNT(attributes, 3);
+    CHECK_ATTR_TYPE(attributes, &DUMMY_GUID1, MF_ATTRIBUTE_STRING);
 
     hr = IMFAttributes_GetStringLength(attributes, &DUMMY_GUID1, &string_length);
     ok(hr == S_OK, "Failed to get string length, hr %#x.\n", hr);
@@ -701,6 +721,7 @@ static void test_MFCreateAttributes(void)
     hr = IMFAttributes_SetUnknown(attributes, &DUMMY_GUID2, (IUnknown *)attributes);
     ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
     CHECK_ATTR_COUNT(attributes, 4);
+    CHECK_ATTR_TYPE(attributes, &DUMMY_GUID2, MF_ATTRIBUTE_IUNKNOWN);
 
     hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IUnknown, (void **)&unk_value);
     ok(hr == S_OK, "Failed to get value, hr %#x.\n", hr);
@@ -747,6 +768,7 @@ static void test_MFCreateAttributes(void)
     hr = IMFAttributes_SetBlob(attributes, &DUMMY_GUID1, blob, sizeof(blob));
     ok(hr == S_OK, "Failed to set blob attribute, hr %#x.\n", hr);
     CHECK_ATTR_COUNT(attributes, 1);
+    CHECK_ATTR_TYPE(attributes, &DUMMY_GUID1, MF_ATTRIBUTE_BLOB);
     hr = IMFAttributes_GetBlobSize(attributes, &DUMMY_GUID1, &size);
     ok(hr == S_OK, "Failed to get blob size, hr %#x.\n", hr);
     ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
@@ -779,6 +801,203 @@ static void test_MFCreateAttributes(void)
 
     IMFAttributes_Release(attributes);
     IMFAttributes_Release(attributes1);
+
+    /* Compare() */
+    hr = MFCreateAttributes(&attributes, 0);
+    ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
+    hr = MFCreateAttributes(&attributes1, 0);
+    ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
+
+    hr = IMFAttributes_Compare(attributes, attributes, MF_ATTRIBUTES_MATCH_SMALLER + 1, &result);
+    ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+
+    for (match_type = MF_ATTRIBUTES_MATCH_OUR_ITEMS; match_type <= MF_ATTRIBUTES_MATCH_SMALLER; ++match_type)
+    {
+        result = FALSE;
+        hr = IMFAttributes_Compare(attributes, attributes, match_type, &result);
+        ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+        ok(result, "Unexpected result %d.\n", result);
+
+        result = FALSE;
+        hr = IMFAttributes_Compare(attributes, attributes1, match_type, &result);
+        ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+        ok(result, "Unexpected result %d.\n", result);
+    }
+
+    hr = IMFAttributes_SetUINT32(attributes, &DUMMY_GUID1, 1);
+    ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
+
+    result = TRUE;
+    hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(!result, "Unexpected result %d.\n", result);
+
+    result = TRUE;
+    hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(!result, "Unexpected result %d.\n", result);
+
+    result = FALSE;
+    hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(result, "Unexpected result %d.\n", result);
+
+    result = FALSE;
+    hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(result, "Unexpected result %d.\n", result);
+
+    hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID1, 2);
+    ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
+
+    result = TRUE;
+    hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(!result, "Unexpected result %d.\n", result);
+
+    result = TRUE;
+    hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(!result, "Unexpected result %d.\n", result);
+
+    result = TRUE;
+    hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(!result, "Unexpected result %d.\n", result);
+
+    result = TRUE;
+    hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(!result, "Unexpected result %d.\n", result);
+
+    result = TRUE;
+    hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(!result, "Unexpected result %d.\n", result);
+
+    result = TRUE;
+    hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(!result, "Unexpected result %d.\n", result);
+
+    result = TRUE;
+    hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(!result, "Unexpected result %d.\n", result);
+
+    result = TRUE;
+    hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(!result, "Unexpected result %d.\n", result);
+
+    result = TRUE;
+    hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(!result, "Unexpected result %d.\n", result);
+
+    result = TRUE;
+    hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(!result, "Unexpected result %d.\n", result);
+
+    hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID1, 1);
+    ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
+
+    result = FALSE;
+    hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(result, "Unexpected result %d.\n", result);
+
+    result = FALSE;
+    hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(result, "Unexpected result %d.\n", result);
+
+    result = FALSE;
+    hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(result, "Unexpected result %d.\n", result);
+
+    result = FALSE;
+    hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(result, "Unexpected result %d.\n", result);
+
+    result = FALSE;
+    hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(result, "Unexpected result %d.\n", result);
+
+    result = FALSE;
+    hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(result, "Unexpected result %d.\n", result);
+
+    result = FALSE;
+    hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(result, "Unexpected result %d.\n", result);
+
+    result = FALSE;
+    hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(result, "Unexpected result %d.\n", result);
+
+    hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID2, 2);
+    ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
+
+    result = TRUE;
+    hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(!result, "Unexpected result %d.\n", result);
+
+    result = TRUE;
+    hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(!result, "Unexpected result %d.\n", result);
+
+    result = FALSE;
+    hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(result, "Unexpected result %d.\n", result);
+
+    result = FALSE;
+    hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(result, "Unexpected result %d.\n", result);
+
+    result = FALSE;
+    hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(result, "Unexpected result %d.\n", result);
+
+    result = TRUE;
+    hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(!result, "Unexpected result %d.\n", result);
+
+    result = FALSE;
+    hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(result, "Unexpected result %d.\n", result);
+
+    result = TRUE;
+    hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(!result, "Unexpected result %d.\n", result);
+
+    result = FALSE;
+    hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(result, "Unexpected result %d.\n", result);
+
+    result = FALSE;
+    hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
+    ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
+    ok(result, "Unexpected result %d.\n", result);
+
+    IMFAttributes_Release(attributes);
+    IMFAttributes_Release(attributes1);
 }
 
 static void test_MFCreateMFByteStreamOnStream(void)
@@ -2112,7 +2331,7 @@ START_TEST(mfplat)
     test_register();
     test_media_type();
     test_MFCreateMediaEvent();
-    test_MFCreateAttributes();
+    test_attributes();
     test_sample();
     test_MFCreateFile();
     test_MFCreateMFByteStreamOnStream();
-- 
2.20.1




More information about the wine-devel mailing list