From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56914 --- dlls/windows.web/json_value.c | 101 +++++++++++++++++++++++++++++++++- dlls/windows.web/private.h | 1 + 2 files changed, 100 insertions(+), 2 deletions(-)
diff --git a/dlls/windows.web/json_value.c b/dlls/windows.web/json_value.c index dfd3820b915..e10dc8b9345 100644 --- a/dlls/windows.web/json_value.c +++ b/dlls/windows.web/json_value.c @@ -121,6 +121,9 @@ struct json_value LONG ref;
JsonValueType json_value_type; + HSTRING parsed_string; + double parsed_number; + boolean parsed_boolean; HSTRING string_value; };
@@ -167,6 +170,7 @@ static ULONG WINAPI json_value_Release( IJsonValue *iface )
if (!ref) { + WindowsDeleteString( impl->parsed_string ); WindowsDeleteString( impl->string_value ); free( impl ); } @@ -260,10 +264,103 @@ static const struct IJsonValueVtbl json_value_vtbl =
DEFINE_IINSPECTABLE( json_value_statics, IJsonValueStatics, struct json_value_statics, IActivationFactory_iface )
+static HRESULT trim_string( HSTRING input, const WCHAR *token, HSTRING *trimmed_string ) +{ + HSTRING pattern = NULL, new_string = NULL; + HRESULT hr = WindowsCreateString( token, wcslen( token ), &pattern ); + + if (SUCCEEDED(hr)) hr = WindowsTrimStringStart( input, pattern, &new_string ); + if (SUCCEEDED(hr)) hr = WindowsTrimStringEnd( new_string, pattern, trimmed_string ); + + WindowsDeleteString( pattern ); + WindowsDeleteString( new_string ); + return hr; +} + +static HRESULT parse_json_value( HSTRING input, struct json_value *impl ) +{ + UINT json_len; + const WCHAR *json = WindowsGetStringRawBuffer( input, &json_len ); + HRESULT hr = S_OK; + + /* FIXME: Handle all JSON edge cases */ + + if (json_len == 4 && !wcsncmp( L"null", json, 4 )) + { + impl->json_value_type = JsonValueType_Null; + } + else if ((json_len == 4 && !wcsncmp( L"true", json, 4 )) || (json_len == 5 && !wcsncmp( L"false", json, 5 ))) + { + impl->parsed_boolean = json_len == 4; + impl->json_value_type = JsonValueType_Boolean; + } + else if (json[0] == '"' && json[json_len - 1] == '"') + { + if (FAILED(hr = trim_string( input, L"\"", &impl->parsed_string ))) return hr; + impl->json_value_type = JsonValueType_String; + } + else if (json[0] == '[' && json[json_len - 1] == ']') + { + FIXME( "Array parsing not implemented!\n" ); + impl->json_value_type = JsonValueType_Array; + } + else if (json[0] == '{' && json[json_len - 1] == '}') + { + FIXME( "Object parsing not implemented!\n" ); + impl->json_value_type = JsonValueType_Object; + } + else + { + double result = 0; + WCHAR *end; + + errno = 0; + result = wcstold( json, &end ); + + if (errno == ERANGE) return WEB_E_INVALID_JSON_NUMBER; + if (errno || end != json + json_len) return WEB_E_INVALID_JSON_NUMBER; + + impl->parsed_number = result; + impl->json_value_type = JsonValueType_Number; + } + + return hr; +} + +static HRESULT parse_json( HSTRING json, struct json_value *impl ) +{ + HSTRING trimmed_json = NULL; + HRESULT hr = trim_string( json, L" ", &trimmed_json ); + + if (SUCCEEDED(hr) && WindowsIsStringEmpty( trimmed_json )) hr = WEB_E_INVALID_JSON_STRING; + if (SUCCEEDED(hr)) hr = parse_json_value( trimmed_json, impl ); + + WindowsDeleteString( trimmed_json ); + return hr; +} + static HRESULT WINAPI json_value_statics_Parse( IJsonValueStatics *iface, HSTRING input, IJsonValue **value ) { - FIXME( "iface %p, input %s, value %p stub!\n", iface, debugstr_hstring( input ), value ); - return E_NOTIMPL; + struct json_value *impl; + HRESULT hr; + + FIXME( "iface %p, input %s, value %p semi-stub\n", iface, debugstr_hstring( input ), value ); + + if (!value) return E_POINTER; + if (!input) return WEB_E_INVALID_JSON_STRING; + if (!(impl = calloc( 1, sizeof( *impl ) ))) return E_OUTOFMEMORY; + + if (FAILED(hr = parse_json( input, impl ))) + { + free( impl ); + return hr; + } + impl->IJsonValue_iface.lpVtbl = &json_value_vtbl; + impl->ref = 1; + + *value = &impl->IJsonValue_iface; + TRACE( "created IJsonValue %p.\n", *value ); + return S_OK; }
static HRESULT WINAPI json_value_statics_TryParse( IJsonValueStatics *iface, HSTRING input, IJsonValue **result, boolean *succeeded ) diff --git a/dlls/windows.web/private.h b/dlls/windows.web/private.h index 393affd61e1..d5f0e76d641 100644 --- a/dlls/windows.web/private.h +++ b/dlls/windows.web/private.h @@ -21,6 +21,7 @@ #define __WINE_WINDOWS_WEB_PRIVATE_H
#include <stdarg.h> +#include <errno.h>
#define COBJMACROS #include "windef.h"