From: Olivia Ryan <olivia.r.dev@gmail.com> --- dlls/windows.web/json_value.c | 90 ++++++++++++++++++++++++++++++++--- dlls/windows.web/tests/web.c | 2 - 2 files changed, 83 insertions(+), 9 deletions(-) diff --git a/dlls/windows.web/json_value.c b/dlls/windows.web/json_value.c index c014b70ae65..6fb5670a014 100644 --- a/dlls/windows.web/json_value.c +++ b/dlls/windows.web/json_value.c @@ -126,6 +126,7 @@ struct json_value double parsed_number; boolean parsed_boolean; IJsonArray *parsed_array; + IJsonObject *parsed_object; }; static inline struct json_value *impl_from_IJsonValue( IJsonValue *iface ) @@ -173,6 +174,7 @@ static ULONG WINAPI json_value_Release( IJsonValue *iface ) { WindowsDeleteString( impl->parsed_string ); if ( impl->parsed_array ) IJsonArray_Release( impl->parsed_array ); + if ( impl->parsed_object ) IJsonObject_Release( impl->parsed_object ); free( impl ); } return ref; @@ -270,12 +272,14 @@ static HRESULT WINAPI json_value_GetObject( IJsonValue *iface, IJsonObject **val { 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_Object) return E_ILLEGAL_METHOD_CALL; - return E_NOTIMPL; + IJsonObject_AddRef( impl->parsed_object ); + *value = impl->parsed_object; + return S_OK; } static const struct IJsonValueVtbl json_value_vtbl = @@ -472,12 +476,85 @@ static HRESULT parse_json_string( const WCHAR **json, UINT32 *len, HSTRING *outp return WindowsPromoteStringBuffer( buf, output ); } +static HRESULT parse_json_object( const WCHAR **json, UINT32 *len, struct json_value *impl ) +{ + struct json_value *child; + HSTRING name; + HRESULT hr; + + TRACE( "json %s, impl %p", debugstr_wn( *json, *len ), impl ); + + if (FAILED(hr = IActivationFactory_ActivateInstance( + json_object_factory, (IInspectable**)&impl->parsed_object ))) return hr; + + (*json)++; + (*len)--; + + trim_string( json, len ); + while (*len && **json != '}') + { + if (FAILED(hr = parse_json_string( json, len, &name ))) + { + IJsonObject_Release( impl->parsed_object ); + return hr; + } + + trim_string( json, len ); + if (!*len || **json != ':') + { + IJsonObject_Release( impl->parsed_object ); + WindowsDeleteString( name ); + return WEB_E_INVALID_JSON_STRING; + } + (*json)++; + (*len)--; + trim_string( json, len ); + + if (!(child = calloc( 1, sizeof( *child ) ))) + { + IJsonObject_Release( impl->parsed_object ); + WindowsDeleteString( name ); + 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 ); + IJsonObject_Release( impl->parsed_object ); + WindowsDeleteString( name ); + return hr; + } + + hr = IJsonObject_SetNamedValue( impl->parsed_object, name, &child->IJsonValue_iface ); + IJsonValue_Release( &child->IJsonValue_iface ); + if (FAILED(hr)) + { + IJsonObject_Release( impl->parsed_object ); + WindowsDeleteString( name ); + return hr; + } + + trim_string( json, len ); + if (**json == ',') (*json)++; + else if (**json != '}') return WEB_E_INVALID_JSON_STRING; + trim_string( json, len ); + } + + if (!*len) return WEB_E_INVALID_JSON_STRING; + (*json)++; + (*len)--; + + impl->json_value_type = JsonValueType_Object; + return S_OK; +} + static HRESULT parse_json_value( const WCHAR **json, UINT32 *len, struct json_value *impl ) { HRESULT hr = S_OK; - /* FIXME: Handle all JSON edge cases */ - if (!*len) return WEB_E_INVALID_JSON_STRING; if (*len >= 4 && !wcsncmp( L"null", *json, 4 )) @@ -511,8 +588,7 @@ static HRESULT parse_json_value( const WCHAR **json, UINT32 *len, struct json_va } else if (**json == '{') { - FIXME( "Object parsing not implemented!\n" ); - return WEB_E_INVALID_JSON_STRING; + if (FAILED(hr = parse_json_object( json, len, impl ))) return hr; } else { @@ -552,7 +628,7 @@ static HRESULT WINAPI json_value_statics_Parse( IJsonValueStatics *iface, HSTRIN struct json_value *impl; HRESULT hr; - FIXME( "iface %p, input %s, value %p semi-stub\n", iface, debugstr_hstring( input ), value ); + TRACE( "iface %p, input %s, value %p\n", iface, debugstr_hstring( input ), value ); if (!value) return E_POINTER; if (!input) return WEB_E_INVALID_JSON_STRING; diff --git a/dlls/windows.web/tests/web.c b/dlls/windows.web/tests/web.c index 53fccf29572..3c6b2faee18 100644 --- a/dlls/windows.web/tests/web.c +++ b/dlls/windows.web/tests/web.c @@ -350,7 +350,6 @@ static void check_json_( unsigned int line, IJsonValueStatics *json_value_static if (expected_json_value_type == JsonValueType_Number) ok_(__FILE__, line)( hr == WEB_E_INVALID_JSON_NUMBER, "got hr %#lx.\n", hr ); else - todo_wine ok_(__FILE__, line)( hr == WEB_E_INVALID_JSON_STRING, "got hr %#lx.\n", hr ); WindowsDeleteString( str ); @@ -430,7 +429,6 @@ static void check_json_( unsigned int line, IJsonValueStatics *json_value_static break; case JsonValueType_Object: hr = IJsonValue_GetObject( json_value, &json_object ); - todo_wine ok_(__FILE__, line)( hr == S_OK, "got hr %#lx.\n", hr ); if (hr == S_OK) IJsonObject_Release( json_object ); break; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10263