From: Olivia Ryan <olivia.r.dev@gmail.com> --- dlls/windows.web/json_array.c | 19 ++++++++++++ dlls/windows.web/json_value.c | 56 ++++++++++++++++++++++++++++++++--- dlls/windows.web/private.h | 2 ++ dlls/windows.web/tests/web.c | 3 +- 4 files changed, 74 insertions(+), 6 deletions(-) diff --git a/dlls/windows.web/json_array.c b/dlls/windows.web/json_array.c index c48b868e062..1bb7bef6b84 100644 --- a/dlls/windows.web/json_array.c +++ b/dlls/windows.web/json_array.c @@ -35,6 +35,25 @@ static inline struct json_array *impl_from_IJsonArray( IJsonArray *iface ) return CONTAINING_RECORD( iface, struct json_array, IJsonArray_iface ); } +HRESULT json_array_push( IJsonArray *iface, IJsonValue *value ) +{ + struct json_array *impl = impl_from_IJsonArray( iface ); + IJsonValue **new = impl->elements; + + TRACE( "iface %p, value %p.\n", iface, value ); + + if (!(new = realloc( new, ++impl->length * sizeof(*new) ))) + { + impl->length--; + return E_OUTOFMEMORY; + } + + impl->elements = new; + IJsonValue_AddRef( value ); + impl->elements[impl->length - 1] = value; + return S_OK; +} + static HRESULT WINAPI json_array_statics_QueryInterface( IJsonArray *iface, REFIID iid, void **out ) { struct json_array *impl = impl_from_IJsonArray( iface ); diff --git a/dlls/windows.web/json_value.c b/dlls/windows.web/json_value.c index f34ce5b73d9..ed539219ef4 100644 --- a/dlls/windows.web/json_value.c +++ b/dlls/windows.web/json_value.c @@ -127,6 +127,7 @@ struct json_value boolean boolean_value; HSTRING string_value; double number_value; + IJsonArray *array_value; }; }; @@ -175,6 +176,8 @@ static ULONG WINAPI json_value_Release( IJsonValue *iface ) { if (impl->json_value_type == JsonValueType_String) WindowsDeleteString( impl->string_value ); + else if (impl->json_value_type == JsonValueType_Array) + IJsonArray_Release( impl->array_value ); free( impl ); } @@ -259,12 +262,14 @@ static HRESULT WINAPI json_value_GetArray( IJsonValue *iface, IJsonArray **value { struct json_value *impl = impl_from_IJsonValue( iface ); - FIXME( "iface %p, value %p stub!\n", iface, value ); + TRACE( "iface %p, value %p\n", iface, value ); if (!value) return E_POINTER; if (impl->json_value_type != JsonValueType_Array) return E_ILLEGAL_METHOD_CALL; - return E_NOTIMPL; + IJsonArray_AddRef( impl->array_value ); + *value = impl->array_value; + return S_OK; } static HRESULT WINAPI json_value_GetObject( IJsonValue *iface, IJsonObject **value ) @@ -341,6 +346,50 @@ static WCHAR json_buffer_next( struct json_buffer *json, const WCHAR *valid ) return chr; } +static HRESULT parse_json_value( struct json_buffer *json, IJsonValue **value ); + +static HRESULT parse_json_array( struct json_buffer *json, IJsonArray **value ) +{ + IJsonArray *array; + IJsonValue *child; + HRESULT hr; + + if (!json_buffer_take( json, L"[" )) return WEB_E_INVALID_JSON_STRING; + if (FAILED(hr = IActivationFactory_ActivateInstance( + json_array_factory, (IInspectable**)&array ))) return hr; + + json_buffer_trim( json ); + while (json->len && *json->str != ']') + { + if (FAILED(hr = parse_json_value( json, &child ))) + { + IJsonArray_Release( array ); + return hr; + } + + hr = json_array_push( array, child ); + IJsonValue_Release( child ); + if (FAILED(hr)) + { + IJsonArray_Release( array ); + return hr; + } + + json_buffer_trim( json ); + if (!json_buffer_take( json, L"," )) break; + json_buffer_trim( json ); + } + + if (!json_buffer_take( json, L"]" )) + { + IJsonArray_Release( array ); + return WEB_E_INVALID_JSON_STRING; + } + + *value = array; + return S_OK; +} + static HRESULT parse_json_string( struct json_buffer *json, HSTRING *output ) { const WCHAR valid_hex_chars[] = L"abcdefABCDEF0123456789"; @@ -437,9 +486,8 @@ static HRESULT parse_json_value( struct json_buffer *json, IJsonValue **value ) } else if (*json->str == '[') { - FIXME( "Array parsing not implemented!\n" ); + hr = parse_json_array( json, &impl->array_value ); impl->json_value_type = JsonValueType_Array; - hr = WEB_E_INVALID_JSON_STRING; } else if (*json->str == '{') { diff --git a/dlls/windows.web/private.h b/dlls/windows.web/private.h index 9dda1e095f1..b8cc30cda42 100644 --- a/dlls/windows.web/private.h +++ b/dlls/windows.web/private.h @@ -40,6 +40,8 @@ extern IActivationFactory *json_array_factory; extern IActivationFactory *json_object_factory; extern IActivationFactory *json_value_factory; +HRESULT json_array_push( IJsonArray *iface, IJsonValue *value ); + #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.web/tests/web.c b/dlls/windows.web/tests/web.c index 87c7f7fb66a..1b29447dfd2 100644 --- a/dlls/windows.web/tests/web.c +++ b/dlls/windows.web/tests/web.c @@ -327,7 +327,7 @@ static void check_json_( unsigned int line, IJsonValueStatics *json_value_static return; } - todo_wine_if(expected_json_value_type == JsonValueType_Array || expected_json_value_type == JsonValueType_Object) + todo_wine_if(expected_json_value_type == JsonValueType_Object) ok_(__FILE__, line)( hr == S_OK, "got hr %#lx.\n", hr ); if (FAILED(hr)) return; hr = IJsonValue_get_ValueType( json_value, &json_value_type ); @@ -398,7 +398,6 @@ static void check_json_( unsigned int line, IJsonValueStatics *json_value_static break; case JsonValueType_Array: hr = IJsonValue_GetArray( json_value, &json_array ); - todo_wine ok_(__FILE__, line)( hr == S_OK, "got hr %#lx.\n", hr ); if (hr == S_OK) IJsonArray_Release( json_array ); break; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10263