From 8b30ef11cf9a5bd7ffc1b0c22b8681dfa68dfefa Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Thu, 28 Jun 2012 13:25:05 +0900 Subject: [PATCH] windowscodecs: Implement MetadataHandler_GetValue. --- dlls/windowscodecs/metadatahandler.c | 81 ++++++++++++++++++++++++++-- dlls/windowscodecs/tests/metadata.c | 41 +++++++++++++- 2 files changed, 117 insertions(+), 5 deletions(-) diff --git a/dlls/windowscodecs/metadatahandler.c b/dlls/windowscodecs/metadatahandler.c index a3eea1f63b..7072a95489 100644 --- a/dlls/windowscodecs/metadatahandler.c +++ b/dlls/windowscodecs/metadatahandler.c @@ -213,11 +213,84 @@ static HRESULT WINAPI MetadataHandler_GetValueByIndex(IWICMetadataWriter *iface, return hr; } -static HRESULT WINAPI MetadataHandler_GetValue(IWICMetadataWriter *iface, - const PROPVARIANT *pvarSchema, const PROPVARIANT *pvarId, PROPVARIANT *pvarValue) +static BOOL get_int_value(const PROPVARIANT *pv, LONGLONG *value) { - FIXME("(%p,%p,%p,%p): stub\n", iface, pvarSchema, pvarId, pvarValue); - return E_NOTIMPL; + switch (pv->vt) + { + case VT_NULL: + case VT_EMPTY: + *value = 0; + break; + case VT_I1: + *value = pv->u.cVal; + break; + case VT_UI1: + *value = pv->u.bVal; + break; + case VT_I2: + *value = pv->u.iVal; + break; + case VT_UI2: + *value = pv->u.uiVal; + break; + case VT_I4: + *value = pv->u.lVal; + break; + case VT_UI4: + *value = pv->u.ulVal; + break; + case VT_I8: + case VT_UI8: + *value = pv->u.hVal.QuadPart; + break; + default: + FIXME("not supported variant type %d\n", pv->vt); + return FALSE; + } + return TRUE; +} + +/* FiXME: Use propsys.PropVariantCompareEx once it's implemented */ +static int propvar_cmp(const PROPVARIANT *v1, const PROPVARIANT *v2) +{ + LONGLONG value1, value2; + + if (!get_int_value(v1, &value1)) return -1; + if (!get_int_value(v2, &value2)) return -1; + + value1 -= value2; + if (value1) return value1 < 0 ? -1 : 1; + return 0; +} + +static HRESULT WINAPI MetadataHandler_GetValue(IWICMetadataWriter *iface, + const PROPVARIANT *schema, const PROPVARIANT *id, PROPVARIANT *value) +{ + UINT i; + HRESULT hr = WINCODEC_ERR_PROPERTYNOTFOUND; + MetadataHandler *This = impl_from_IWICMetadataWriter(iface); + + TRACE("(%p,%p,%p,%p)\n", iface, schema, id, value); + + if (!id) return E_INVALIDARG; + + EnterCriticalSection(&This->lock); + + for (i = 0; i < This->item_count; i++) + { + if (schema && This->items[i].schema.vt != VT_EMPTY) + { + if (propvar_cmp(schema, &This->items[i].schema) != 0) continue; + } + + if (propvar_cmp(id, &This->items[i].id) != 0) continue; + + hr = value ? PropVariantCopy(value, &This->items[i].value) : S_OK; + break; + } + + LeaveCriticalSection(&This->lock); + return hr; } static HRESULT WINAPI MetadataHandler_GetEnumerator(IWICMetadataWriter *iface, diff --git a/dlls/windowscodecs/tests/metadata.c b/dlls/windowscodecs/tests/metadata.c index 76fd241bca..d3b2869570 100644 --- a/dlls/windowscodecs/tests/metadata.c +++ b/dlls/windowscodecs/tests/metadata.c @@ -726,7 +726,46 @@ static void test_metadata_IFD(void) PropVariantClear(&value); hr = IWICMetadataReader_GetValueByIndex(reader, count, &schema, NULL, NULL); - ok(hr == E_INVALIDARG, "GetValueByIndex should fail\n"); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + + PropVariantInit(&schema); + PropVariantInit(&id); + PropVariantInit(&value); + + hr = IWICMetadataReader_GetValue(reader, &schema, &id, &value); + ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "expected WINCODEC_ERR_PROPERTYNOTFOUND, got %#x\n", hr); + + hr = IWICMetadataReader_GetValue(reader, NULL, &id, NULL); + ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "expected WINCODEC_ERR_PROPERTYNOTFOUND, got %#x\n", hr); + + hr = IWICMetadataReader_GetValue(reader, &schema, NULL, NULL); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + + hr = IWICMetadataReader_GetValue(reader, &schema, &id, NULL); + ok(hr == WINCODEC_ERR_PROPERTYNOTFOUND, "expected WINCODEC_ERR_PROPERTYNOTFOUND, got %#x\n", hr); + + hr = IWICMetadataReader_GetValue(reader, &schema, NULL, &value); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); + + id.vt = VT_UI2; + U(id).uiVal = 0xf00e; + hr = IWICMetadataReader_GetValue(reader, NULL, &id, NULL); + ok(hr == S_OK, "GetValue error %#x\n", hr); + + /* schema is ignored by Ifd metadata reader */ + schema.vt = VT_UI4; + U(schema).ulVal = 0xdeadbeef; + hr = IWICMetadataReader_GetValue(reader, &schema, &id, &value); + ok(hr == S_OK, "GetValue error %#x\n", hr); + ok(value.vt == VT_LPSTR, "unexpected vt: %i\n", id.vt); + ok(!strcmp(U(value).pszVal, "Hello World!"), "unexpected value: %s\n", U(value).pszVal); + PropVariantClear(&value); + + hr = IWICMetadataReader_GetValue(reader, NULL, &id, &value); + ok(hr == S_OK, "GetValue error %#x\n", hr); + ok(value.vt == VT_LPSTR, "unexpected vt: %i\n", id.vt); + ok(!strcmp(U(value).pszVal, "Hello World!"), "unexpected value: %s\n", U(value).pszVal); + PropVariantClear(&value); hr = IWICMetadataReader_QueryInterface(reader, &IID_IWICMetadataBlockReader, (void**)&blockreader); ok(hr == E_NOINTERFACE, "QueryInterface failed, hr=%x\n", hr);