From: Olivia Ryan <olivia.r.dev@gmail.com> --- dlls/windows.web/json_array.c | 19 +++++++++ dlls/windows.web/json_value.c | 77 +++++++++++++++++++++++++++++++++-- dlls/windows.web/private.h | 2 + dlls/windows.web/tests/web.c | 1 - 4 files changed, 94 insertions(+), 5 deletions(-) diff --git a/dlls/windows.web/json_array.c b/dlls/windows.web/json_array.c index c48b868e062..4a4c5a730fe 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 ); + + new = realloc( new, ++impl->length * sizeof(*new) ); + if (!new) + { + impl->length--; + return E_OUTOFMEMORY; + } + + impl->elements = new; + 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 11018415536..c014b70ae65 100644 --- a/dlls/windows.web/json_value.c +++ b/dlls/windows.web/json_value.c @@ -125,6 +125,7 @@ struct json_value HSTRING parsed_string; double parsed_number; boolean parsed_boolean; + IJsonArray *parsed_array; }; static inline struct json_value *impl_from_IJsonValue( IJsonValue *iface ) @@ -171,6 +172,7 @@ static ULONG WINAPI json_value_Release( IJsonValue *iface ) if (!ref) { WindowsDeleteString( impl->parsed_string ); + if ( impl->parsed_array ) IJsonArray_Release( impl->parsed_array ); free( impl ); } return ref; @@ -254,12 +256,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->parsed_array ); + *value = impl->parsed_array; + return S_OK; } static HRESULT WINAPI json_value_GetObject( IJsonValue *iface, IJsonObject **value ) @@ -307,6 +311,72 @@ static void trim_string( const WCHAR **input, UINT32 *len ) *input += start; } +static HRESULT parse_json_value( const WCHAR **json, UINT32 *len, struct json_value *impl ); + +static HRESULT parse_json_array( const WCHAR **json, UINT32 *len, struct json_value *impl ) +{ + struct json_value *child; + IJsonArray *array; + HRESULT hr; + + TRACE( "json %s, impl %p", debugstr_wn( *json, *len ), impl ); + + if (FAILED(hr = IActivationFactory_ActivateInstance( + json_array_factory, (IInspectable**)&array ))) return hr; + + (*json)++; + (*len)--; + + trim_string( json, len ); + while (len && **json != ']') + { + if (!(child = calloc( 1, sizeof( *child ) ))) + { + IJsonArray_Release( array ); + return E_OUTOFMEMORY; + } + + child->IJsonValue_iface.lpVtbl = &json_value_vtbl; + child->ref = 1; + + if (FAILED(hr = parse_json_value( json, len, child ))) + { + IJsonValue_Release( &child->IJsonValue_iface ); + IJsonArray_Release( array ); + return hr; + } + + if (FAILED(hr = json_array_push( array, &child->IJsonValue_iface ))) + { + IJsonValue_Release( &child->IJsonValue_iface ); + IJsonArray_Release( array ); + return hr; + } + + trim_string( json, len ); + + if (**json == ',') + { + (*json)++; + (*len)--; + } + else if (**json != ']') + { + IJsonArray_Release( array ); + return WEB_E_INVALID_JSON_STRING; + } + + trim_string( json, len ); + } + + (*json)++; + (*len)--; + + impl->parsed_array = array; + impl->json_value_type = JsonValueType_Array; + return S_OK; +} + static HRESULT parse_json_string( const WCHAR **json, UINT32 *len, HSTRING *output ) { const WCHAR valid_hex_chars[] = L"abcdefABCDEF0123456789"; @@ -437,8 +507,7 @@ static HRESULT parse_json_value( const WCHAR **json, UINT32 *len, struct json_va } else if (**json == '[') { - FIXME( "Array parsing not implemented!\n" ); - return WEB_E_INVALID_JSON_STRING; + if (FAILED(hr = parse_json_array( json, len, impl ))) return hr; } else if (**json == '{') { 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 1f97ed05608..c5332bd4764 100644 --- a/dlls/windows.web/tests/web.c +++ b/dlls/windows.web/tests/web.c @@ -381,7 +381,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