Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
63db293
windows.web: Cleanup struct json_value.
olivi-r Mar 24, 2026
ab2c9dd
windows.web: Use json_buffer struct & helper functions.
olivi-r Mar 25, 2026
903d1f2
windows.web: Support escaped characters.
olivi-r Mar 25, 2026
edb8419
windows.web: Additional string parsing tests.
olivi-r Mar 24, 2026
202829d
windows.web: Rename JsonObject class methods.
rbernon Mar 26, 2026
cbb01d2
windows.web: Skip whitespace in json_buffer_take.
rbernon Mar 26, 2026
b20ecc7
windows.web: Stub JsonArray runtime class.
olivi-r Mar 18, 2026
eab8ee8
windows.web: Support json array parsing.
olivi-r Mar 26, 2026
a535c16
windows.web: Add a IMap_HSTRING_IInspectable to json objects.
olivi-r Mar 18, 2026
3751ee8
windows.web: Support json object parsing.
olivi-r Mar 26, 2026
8cbdb8d
windows.web: Implement JsonArray element getters.
olivi-r Mar 26, 2026
aade741
windows.web: Support boolean & number value creation.
olivi-r Mar 18, 2026
0ff22c7
windows.web: Implement JsonObject typed getters.
olivi-r Mar 26, 2026
2d44307
xgameruntime: XUser stubs
olivi-r Jan 20, 2026
cae6a6b
xgameruntime: XUserAdd async provider
olivi-r Feb 2, 2026
c658266
xgameruntime: add getting device code
olivi-r Feb 3, 2026
33c177f
xgameruntime: Get user's tokens
olivi-r Feb 8, 2026
ed60869
xgameruntime: add xuser header
olivi-r Feb 9, 2026
0ba593e
xgameruntime: Move json response parsing to separate function
olivi-r Feb 10, 2026
1a0eff5
xgameruntime: extract user hash from user auth response
olivi-r Feb 10, 2026
610662f
xgameruntime: basic auth done
olivi-r Feb 10, 2026
0b694bb
xgameruntime: XUserGetTokenAndSignature async provider stub
olivi-r Feb 10, 2026
7fe3abe
xgameruntime: Stub XUser extension interfaces
olivi-r Feb 13, 2026
3a57be4
xgameruntime: Check for nullptrs, XUserCompare & XUserGetAgeGroup
olivi-r Feb 13, 2026
b27dc0a
xgameruntime: Release IXThreading references
olivi-r Feb 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dlls/windows.web/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ IMPORTS = combase

SOURCES = \
classes.idl \
json_array.c \
json_object.c \
json_value.c \
main.c
1 change: 1 addition & 0 deletions dlls/windows.web/classes.idl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import "windows.data.json.idl";

namespace Windows.Data.Json {
runtimeclass JsonArray;
runtimeclass JsonObject;
runtimeclass JsonValue;
}
302 changes: 302 additions & 0 deletions dlls/windows.web/json_array.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,302 @@
/* WinRT Windows.Data.Json.JsonArray Implementation
*
* Copyright (C) 2026 Olivia Ryan
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/

#include "private.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(web);

struct json_array
{
IJsonArray IJsonArray_iface;
LONG ref;
IJsonValue **elements;
ULONG capacity;
ULONG length;
};

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 );

TRACE( "iface %p, value %p.\n", iface, value );

if (impl->length == impl->capacity)
{
UINT32 capacity = max( 32, impl->capacity * 3 / 2 );
IJsonValue **new = impl->elements;
if (!(new = realloc( new, capacity * sizeof(*new) ))) return E_OUTOFMEMORY;
impl->elements = new;
impl->capacity = capacity;
}

impl->elements[impl->length++] = value;
IJsonValue_AddRef( value );
return S_OK;
}

static HRESULT WINAPI json_array_QueryInterface( IJsonArray *iface, REFIID iid, void **out )
{
struct json_array *impl = impl_from_IJsonArray( iface );

TRACE( "iface %p, iid %s, out %p.\n", iface, debugstr_guid( iid ), out );

if (IsEqualGUID( iid, &IID_IUnknown ) ||
IsEqualGUID( iid, &IID_IInspectable ) ||
IsEqualGUID( iid, &IID_IAgileObject ) ||
IsEqualGUID( iid, &IID_IJsonArray ))
{
*out = &impl->IJsonArray_iface;
IInspectable_AddRef( *out );
return S_OK;
}

FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) );
*out = NULL;
return E_NOINTERFACE;
}

static ULONG WINAPI json_array_AddRef( IJsonArray *iface )
{
struct json_array *impl = impl_from_IJsonArray( iface );
ULONG ref = InterlockedIncrement( &impl->ref );
TRACE( "iface %p, ref %lu.\n", iface, ref );
return ref;
}

static ULONG WINAPI json_array_Release( IJsonArray *iface )
{
struct json_array *impl = impl_from_IJsonArray( iface );
ULONG ref = InterlockedDecrement( &impl->ref );

TRACE( "iface %p, ref %lu.\n", iface, ref );

if (!ref)
{
for (UINT32 i = 0; i < impl->length; i++)
IJsonValue_Release( impl->elements[i] );

free( impl->elements );
free( impl );
}
return ref;
}

static HRESULT WINAPI json_array_GetIids( IJsonArray *iface, ULONG *iid_count, IID **iids )
{
FIXME( "iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids );
return E_NOTIMPL;
}

static HRESULT WINAPI json_array_GetRuntimeClassName( IJsonArray *iface, HSTRING *class_name )
{
FIXME( "iface %p, class_name %p stub!\n", iface, class_name );
return E_NOTIMPL;
}

static HRESULT WINAPI json_array_GetTrustLevel( IJsonArray *iface, TrustLevel *trust_level )
{
FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level );
return E_NOTIMPL;
}

static HRESULT WINAPI json_array_GetObjectAt( IJsonArray *iface, UINT32 index, IJsonObject **value )
{
struct json_array *impl = impl_from_IJsonArray( iface );

TRACE( "iface %p, index %u, value %p\n", iface, index, value );

if (!value) return E_INVALIDARG;
if (index >= impl->length) return E_BOUNDS;

return IJsonValue_GetObject( impl->elements[index], value );
}

static HRESULT WINAPI json_array_GetArrayAt( IJsonArray *iface, UINT32 index, IJsonArray **value )
{
struct json_array *impl = impl_from_IJsonArray( iface );

TRACE( "iface %p, index %u, value %p\n", iface, index, value );

if (!value) return E_INVALIDARG;
if (index >= impl->length) return E_BOUNDS;

return IJsonValue_GetArray( impl->elements[index], value );
}

static HRESULT WINAPI json_array_GetStringAt( IJsonArray *iface, UINT32 index, HSTRING *value )
{
struct json_array *impl = impl_from_IJsonArray( iface );

TRACE( "iface %p, index %u, value %p\n", iface, index, value );

if (!value) return E_INVALIDARG;
if (index >= impl->length) return E_BOUNDS;

return IJsonValue_GetString( impl->elements[index], value );
}

static HRESULT WINAPI json_array_GetNumberAt( IJsonArray *iface, UINT32 index, DOUBLE *value )
{
struct json_array *impl = impl_from_IJsonArray( iface );

TRACE( "iface %p, index %u, value %p\n", iface, index, value );

if (!value) return E_INVALIDARG;
if (index >= impl->length) return E_BOUNDS;

return IJsonValue_GetNumber( impl->elements[index], value );
}

static HRESULT WINAPI json_array_GetBooleanAt( IJsonArray *iface, UINT32 index, boolean *value )
{
struct json_array *impl = impl_from_IJsonArray( iface );

TRACE( "iface %p, index %u, value %p\n", iface, index, value );

if (!value) return E_INVALIDARG;
if (index >= impl->length) return E_BOUNDS;

return IJsonValue_GetBoolean( impl->elements[index], value );
}

static const struct IJsonArrayVtbl json_array_vtbl =
{
json_array_QueryInterface,
json_array_AddRef,
json_array_Release,
/* IInspectable methods */
json_array_GetIids,
json_array_GetRuntimeClassName,
json_array_GetTrustLevel,
/* IJsonArray methods */
json_array_GetObjectAt,
json_array_GetArrayAt,
json_array_GetStringAt,
json_array_GetNumberAt,
json_array_GetBooleanAt,
};

struct json_array_statics
{
IActivationFactory IActivationFactory_iface;
LONG ref;
};

static inline struct json_array_statics *impl_from_IActivationFactory( IActivationFactory *iface )
{
return CONTAINING_RECORD( iface, struct json_array_statics, IActivationFactory_iface );
}

static HRESULT WINAPI factory_QueryInterface( IActivationFactory *iface, REFIID iid, void **out )
{
struct json_array_statics *impl = impl_from_IActivationFactory( iface );

TRACE( "iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);

if (IsEqualGUID( iid, &IID_IUnknown ) ||
IsEqualGUID( iid, &IID_IInspectable ) ||
IsEqualGUID( iid, &IID_IAgileObject ) ||
IsEqualGUID( iid, &IID_IActivationFactory ))
{
*out = &impl->IActivationFactory_iface;
IInspectable_AddRef( *out );
return S_OK;
}

FIXME( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid( iid ) );
*out = NULL;
return E_NOINTERFACE;
}

static ULONG WINAPI factory_AddRef( IActivationFactory *iface )
{
struct json_array_statics *impl = impl_from_IActivationFactory( iface );
ULONG ref = InterlockedIncrement( &impl->ref );
TRACE( "iface %p, ref %lu.\n", iface, ref );
return ref;
}

static ULONG WINAPI factory_Release( IActivationFactory *iface )
{
struct json_array_statics *impl = impl_from_IActivationFactory( iface );
ULONG ref = InterlockedDecrement( &impl->ref );
TRACE( "iface %p, ref %lu.\n", iface, ref );
return ref;
}

static HRESULT WINAPI factory_GetIids( IActivationFactory *iface, ULONG *iid_count, IID **iids )
{
FIXME( "iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids );
return E_NOTIMPL;
}

static HRESULT WINAPI factory_GetRuntimeClassName( IActivationFactory *iface, HSTRING *class_name )
{
FIXME( "iface %p, class_name %p stub!\n", iface, class_name );
return E_NOTIMPL;
}

static HRESULT WINAPI factory_GetTrustLevel( IActivationFactory *iface, TrustLevel *trust_level )
{
FIXME( "iface %p, trust_level %p stub!\n", iface, trust_level );
return E_NOTIMPL;
}

static HRESULT WINAPI factory_ActivateInstance( IActivationFactory *iface, IInspectable **instance )
{
struct json_array *impl;

TRACE( "iface %p, instance %p.\n", iface, instance );

*instance = NULL;
if (!(impl = calloc( 1, sizeof(*impl) ))) return E_OUTOFMEMORY;

impl->IJsonArray_iface.lpVtbl = &json_array_vtbl;
impl->ref = 1;

*instance = (IInspectable *)&impl->IJsonArray_iface;
return S_OK;
}

static const struct IActivationFactoryVtbl factory_vtbl =
{
factory_QueryInterface,
factory_AddRef,
factory_Release,
/* IInspectable methods */
factory_GetIids,
factory_GetRuntimeClassName,
factory_GetTrustLevel,
/* IActivationFactory methods */
factory_ActivateInstance,
};

static struct json_array_statics json_array_statics =
{
{&factory_vtbl},
1,
};

IActivationFactory *json_array_factory = &json_array_statics.IActivationFactory_iface;
Loading