[PATCH 5/5] windows.media.speech: Store speech commands in listconstraint.

Bernhard Kölbl besentv at gmail.com
Mon Mar 28 11:15:15 CDT 2022


And make them obtainable with ISpeechRecognitionListConstraint_get_Commands.

Signed-off-by: Bernhard Kölbl <besentv at gmail.com>
---
 dlls/windows.media.speech/listconstraint.c | 31 +++++++++++-----
 dlls/windows.media.speech/private.h        |  1 +
 dlls/windows.media.speech/tests/speech.c   | 25 ++++++++-----
 dlls/windows.media.speech/vector.c         | 43 ++++++++++++++++++++++
 4 files changed, 81 insertions(+), 19 deletions(-)

diff --git a/dlls/windows.media.speech/listconstraint.c b/dlls/windows.media.speech/listconstraint.c
index 0c486a415a7..ef0dff0e4d5 100644
--- a/dlls/windows.media.speech/listconstraint.c
+++ b/dlls/windows.media.speech/listconstraint.c
@@ -120,8 +120,19 @@ static HRESULT WINAPI list_constraint_GetTrustLevel( ISpeechRecognitionListConst
 
 static HRESULT WINAPI list_constraint_get_Commands(  ISpeechRecognitionListConstraint *iface, IVector_HSTRING **value )
 {
-    FIXME("iface %p, value %p stub!\n", iface, value);
-    return E_NOTIMPL;
+    struct list_constraint *impl = impl_from_ISpeechRecognitionListConstraint(iface);
+    IIterable_HSTRING *iterable;
+    HRESULT hr;
+
+    TRACE("iface %p, value %p.\n", iface, value);
+
+    hr = IVector_HSTRING_QueryInterface(impl->commands, &IID_IIterable_HSTRING, (void **)&iterable);
+    if (FAILED(hr)) return hr;
+
+    hr = vector_hstring_create_copy(iterable, value);
+    IIterable_HSTRING_Release(iterable);
+
+    return hr;
 }
 
 static const struct ISpeechRecognitionListConstraintVtbl speech_recognition_list_constraint_vtbl =
@@ -135,7 +146,7 @@ static const struct ISpeechRecognitionListConstraintVtbl speech_recognition_list
     list_constraint_GetRuntimeClassName,
     list_constraint_GetTrustLevel,
     /* ISpeechRecognitionListConstraint methods */
-    list_constraint_get_Commands
+    list_constraint_get_Commands,
 };
 
 /*
@@ -209,7 +220,7 @@ static const struct ISpeechRecognitionConstraintVtbl speech_recognition_constrai
     constraint_put_Tag,
     constraint_get_Type,
     constraint_get_Probability,
-    constraint_put_Probability
+    constraint_put_Probability,
 };
 
 /*
@@ -338,6 +349,7 @@ static HRESULT WINAPI constraint_factory_CreateWithTag( ISpeechRecognitionListCo
                                                         ISpeechRecognitionListConstraint** listconstraint )
 {
     struct list_constraint *impl;
+    HRESULT hr;
 
     TRACE("iface %p, commands %p, tag %p, listconstraint %p.\n", iface, commands, tag, listconstraint);
 
@@ -347,11 +359,7 @@ static HRESULT WINAPI constraint_factory_CreateWithTag( ISpeechRecognitionListCo
         return E_POINTER;
 
     if (!(impl = calloc(1, sizeof(*impl)))) return E_OUTOFMEMORY;
-    if (FAILED(vector_hstring_create(&impl->commands)))
-    {
-        free(impl);
-        return E_OUTOFMEMORY;
-    }
+    if (FAILED(hr = vector_hstring_create_copy(commands, &impl->commands))) goto error;
 
     impl->ISpeechRecognitionListConstraint_iface.lpVtbl = &speech_recognition_list_constraint_vtbl;
     impl->ISpeechRecognitionConstraint_iface.lpVtbl = &speech_recognition_constraint_vtbl;
@@ -361,6 +369,11 @@ static HRESULT WINAPI constraint_factory_CreateWithTag( ISpeechRecognitionListCo
 
     *listconstraint = &impl->ISpeechRecognitionListConstraint_iface;
     return S_OK;
+
+error:
+    if (impl->commands) IVector_HSTRING_Release(impl->commands);
+    if (impl) free(impl);
+    return hr;
 }
 
 static const struct ISpeechRecognitionListConstraintFactoryVtbl speech_recognition_list_constraint_factory_vtbl =
diff --git a/dlls/windows.media.speech/private.h b/dlls/windows.media.speech/private.h
index a09b5f5ef7e..3c8371ccdbe 100644
--- a/dlls/windows.media.speech/private.h
+++ b/dlls/windows.media.speech/private.h
@@ -67,6 +67,7 @@ HRESULT typed_event_handlers_notify( struct list *list, IInspectable *sender, II
 HRESULT typed_event_handlers_clear( struct list* list );
 
 HRESULT vector_hstring_create( IVector_HSTRING **out );
+HRESULT vector_hstring_create_copy( IIterable_HSTRING *iterable, IVector_HSTRING **out );
 
 #define DEFINE_IINSPECTABLE_( pfx, iface_type, impl_type, impl_from, iface_mem, expr )             \
     static inline impl_type *impl_from( iface_type *iface )                                        \
diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c
index fc0a8d762c1..2b785cb98ac 100644
--- a/dlls/windows.media.speech/tests/speech.c
+++ b/dlls/windows.media.speech/tests/speech.c
@@ -106,6 +106,7 @@ static inline struct completed_event_handler *impl_from_IHandler_RecognitionComp
 HRESULT WINAPI completed_event_handler_QueryInterface( IHandler_RecognitionCompleted *iface, REFIID iid, void **out )
 {
     if (IsEqualGUID(iid, &IID_IUnknown) ||
+        IsEqualGUID(iid, &IID_IAgileObject) ||
         IsEqualGUID(iid, &IID_IHandler_RecognitionCompleted))
     {
         IUnknown_AddRef(iface);
@@ -172,6 +173,7 @@ static inline struct recognition_result_handler *impl_from_IHandler_RecognitionR
 HRESULT WINAPI recognition_result_handler_QueryInterface( IHandler_RecognitionResult *iface, REFIID iid, void **out )
 {
     if (IsEqualGUID(iid, &IID_IUnknown) ||
+        IsEqualGUID(iid, &IID_IAgileObject) ||
         IsEqualGUID(iid, &IID_IHandler_RecognitionResult))
     {
         IUnknown_AddRef(iface);
@@ -417,9 +419,11 @@ static HRESULT WINAPI iterable_hstring_GetTrustLevel( IIterable_HSTRING *iface,
 static HRESULT WINAPI iterable_hstring_First( IIterable_HSTRING *iface, IIterator_HSTRING **value )
 {
     struct iterable_hstring *impl = impl_from_Iterable_HSTRING(iface);
+    struct iterator_hstring *impl_iter = impl->iterator;
 
     trace("iface %p, value %p.\n", iface, value);
 
+    impl_iter->index = 0;
     IIterator_HSTRING_AddRef((*value = impl->iterator));
     return S_OK;
 }
@@ -944,33 +948,34 @@ static void test_SpeechRecognitionListConstraint(void)
     ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
 
     hr = ISpeechRecognitionListConstraint_get_Commands(listconstraint, &hstring_vector);
-    todo_wine ok(hr == S_OK, "ISpeechRecognitionListConstraint_Commands failed, hr %#lx.\n", hr);
-
-    if (!SUCCEEDED(hr))
-        goto skip_tests;
+    ok(hr == S_OK, "ISpeechRecognitionListConstraint_Commands failed, hr %#lx.\n", hr);
 
     hr = IVector_HSTRING_get_Size(hstring_vector, &vector_size);
-    todo_wine ok(hr == S_OK, "IVector_HSTRING_get_Size failed, hr %#lx.\n", hr);
-    todo_wine ok(vector_size == ARRAY_SIZE(commands), "Got unexpected vector_size %u.\n", vector_size);
+    ok(hr == S_OK, "IVector_HSTRING_get_Size failed, hr %#lx.\n", hr);
+    ok(vector_size == ARRAY_SIZE(commands), "Got unexpected vector_size %u.\n", vector_size);
 
     for (i = 0; i < vector_size; i++)
     {
         HSTRING str;
 
         hr = IVector_HSTRING_GetAt(hstring_vector, i, &str);
-        todo_wine ok(hr == S_OK, "IVector_HSTRING_GetAt failed, hr %#lx.\n", hr);
+        ok(hr == S_OK, "IVector_HSTRING_GetAt failed, hr %#lx.\n", hr);
         hr = WindowsCompareStringOrdinal(commands[i], str, &str_cmp);
-        todo_wine ok(hr == S_OK, "WindowsCompareStringOrdinal failed, hr %#lx.\n", hr);
-        todo_wine ok(!str_cmp, "Strings not equal.\n");
+        ok(hr == S_OK, "WindowsCompareStringOrdinal failed, hr %#lx.\n", hr);
+        ok(!str_cmp, "Strings not equal.\n");
 
         WindowsDeleteString(str);
     }
 
     ref = IVector_HSTRING_Release(hstring_vector);
-    todo_wine ok(ref == 0, "Got unexpected ref %lu.\n", ref);
+    ok(ref == 0, "Got unexpected ref %lu.\n", ref);
 
     hr = ISpeechRecognitionConstraint_get_Tag(constraint, &tag_out);
     todo_wine ok(hr == S_OK, "ISpeechRecognitionConstraint_get_Tag failed, hr %#lx.\n", hr);
+
+    if (FAILED(hr))
+        goto skip_tests;
+
     hr = WindowsCompareStringOrdinal(tag, tag_out, &str_cmp);
     todo_wine ok(hr == S_OK, "WindowsCompareStringOrdinal failed, hr %#lx.\n", hr);
     todo_wine ok(!str_cmp, "Strings not equal.\n");
diff --git a/dlls/windows.media.speech/vector.c b/dlls/windows.media.speech/vector.c
index 4c850aad15b..e754cc15889 100644
--- a/dlls/windows.media.speech/vector.c
+++ b/dlls/windows.media.speech/vector.c
@@ -701,3 +701,46 @@ HRESULT vector_hstring_create( IVector_HSTRING **out )
     TRACE("created %p\n", *out);
     return S_OK;
 }
+
+HRESULT vector_hstring_create_copy( IIterable_HSTRING *iterable, IVector_HSTRING **out )
+{
+    struct vector_hstring *impl;
+    IIterator_HSTRING *iterator;
+    UINT32 capacity = 0;
+    BOOL available;
+    HRESULT hr;
+
+    TRACE("iterable %p, out %p.\n", iterable, out);
+
+    if (FAILED(hr = vector_hstring_create(out))) return hr;
+    if (FAILED(hr = IIterable_HSTRING_First(iterable, &iterator))) goto error;
+
+    for (IIterator_HSTRING_get_HasCurrent(iterator, &available); available; IIterator_HSTRING_MoveNext(iterator, &available))
+        capacity++;
+
+    IIterator_HSTRING_Release(iterator);
+
+    impl = impl_from_IVector_HSTRING(*out);
+    impl->size = 0;
+    impl->capacity = capacity;
+    impl->elements = realloc(impl->elements, impl->capacity * sizeof(*impl->elements));
+
+    if (FAILED(hr = IIterable_HSTRING_First(iterable, &iterator))) goto error;
+
+    for (IIterator_HSTRING_get_HasCurrent(iterator, &available); available; IIterator_HSTRING_MoveNext(iterator, &available))
+    {
+        HSTRING str;
+        IIterator_HSTRING_get_Current(iterator, &str);
+        WindowsDuplicateString(str, &impl->elements[impl->size++]);
+        WindowsDeleteString(str);
+    }
+
+    IIterator_HSTRING_Release(iterator);
+
+    TRACE("created %p\n", *out);
+    return S_OK;
+
+error:
+    IVector_HSTRING_Release(*out);
+    return hr;
+}
-- 
2.35.1




More information about the wine-devel mailing list