opcservices: Keep parts in a set.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
68e35eb745
commit
8fd70ff2bf
|
@ -19,5 +19,31 @@
|
||||||
#include "msopc.h"
|
#include "msopc.h"
|
||||||
#include "wine/heap.h"
|
#include "wine/heap.h"
|
||||||
|
|
||||||
|
static inline BOOL opc_array_reserve(void **elements, size_t *capacity, size_t count, size_t size)
|
||||||
|
{
|
||||||
|
size_t new_capacity, max_capacity;
|
||||||
|
void *new_elements;
|
||||||
|
|
||||||
|
if (count <= *capacity)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
max_capacity = ~(SIZE_T)0 / size;
|
||||||
|
if (count > max_capacity)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
new_capacity = max(4, *capacity);
|
||||||
|
while (new_capacity < count && new_capacity <= max_capacity / 2)
|
||||||
|
new_capacity *= 2;
|
||||||
|
if (new_capacity < count)
|
||||||
|
new_capacity = max_capacity;
|
||||||
|
|
||||||
|
if (!(new_elements = heap_realloc(*elements, new_capacity * size)))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
*elements = new_elements;
|
||||||
|
*capacity = new_capacity;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
extern HRESULT opc_package_create(IOpcPackage **package) DECLSPEC_HIDDEN;
|
extern HRESULT opc_package_create(IOpcPackage **package) DECLSPEC_HIDDEN;
|
||||||
extern HRESULT opc_part_uri_create(const WCHAR *uri, IOpcPartUri **part_uri) DECLSPEC_HIDDEN;
|
extern HRESULT opc_part_uri_create(const WCHAR *uri, IOpcPartUri **part_uri) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -53,6 +53,10 @@ struct opc_part_set
|
||||||
{
|
{
|
||||||
IOpcPartSet IOpcPartSet_iface;
|
IOpcPartSet IOpcPartSet_iface;
|
||||||
LONG refcount;
|
LONG refcount;
|
||||||
|
|
||||||
|
struct opc_part **parts;
|
||||||
|
size_t size;
|
||||||
|
size_t count;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct opc_relationship
|
struct opc_relationship
|
||||||
|
@ -220,7 +224,7 @@ static const IOpcPartVtbl opc_part_vtbl =
|
||||||
opc_part_GetCompressionOptions,
|
opc_part_GetCompressionOptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
static HRESULT opc_part_create(IOpcPartUri *name, const WCHAR *content_type,
|
static HRESULT opc_part_create(struct opc_part_set *set, IOpcPartUri *name, const WCHAR *content_type,
|
||||||
DWORD compression_options, IOpcPart **out)
|
DWORD compression_options, IOpcPart **out)
|
||||||
{
|
{
|
||||||
struct opc_part *part;
|
struct opc_part *part;
|
||||||
|
@ -228,6 +232,9 @@ static HRESULT opc_part_create(IOpcPartUri *name, const WCHAR *content_type,
|
||||||
if (!name)
|
if (!name)
|
||||||
return E_POINTER;
|
return E_POINTER;
|
||||||
|
|
||||||
|
if (!opc_array_reserve((void **)&set->parts, &set->size, set->count + 1, sizeof(*set->parts)))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
if (!(part = heap_alloc_zero(sizeof(*part))))
|
if (!(part = heap_alloc_zero(sizeof(*part))))
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
@ -242,6 +249,9 @@ static HRESULT opc_part_create(IOpcPartUri *name, const WCHAR *content_type,
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set->parts[set->count++] = part;
|
||||||
|
IOpcPart_AddRef(&part->IOpcPart_iface);
|
||||||
|
|
||||||
*out = &part->IOpcPart_iface;
|
*out = &part->IOpcPart_iface;
|
||||||
TRACE("Created part %p.\n", *out);
|
TRACE("Created part %p.\n", *out);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -281,7 +291,14 @@ static ULONG WINAPI opc_part_set_Release(IOpcPartSet *iface)
|
||||||
TRACE("%p decreasing refcount to %u.\n", iface, refcount);
|
TRACE("%p decreasing refcount to %u.\n", iface, refcount);
|
||||||
|
|
||||||
if (!refcount)
|
if (!refcount)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < part_set->count; ++i)
|
||||||
|
IOpcPart_Release(&part_set->parts[i]->IOpcPart_iface);
|
||||||
|
heap_free(part_set->parts);
|
||||||
heap_free(part_set);
|
heap_free(part_set);
|
||||||
|
}
|
||||||
|
|
||||||
return refcount;
|
return refcount;
|
||||||
}
|
}
|
||||||
|
@ -296,10 +313,12 @@ static HRESULT WINAPI opc_part_set_GetPart(IOpcPartSet *iface, IOpcPartUri *name
|
||||||
static HRESULT WINAPI opc_part_set_CreatePart(IOpcPartSet *iface, IOpcPartUri *name, LPCWSTR content_type,
|
static HRESULT WINAPI opc_part_set_CreatePart(IOpcPartSet *iface, IOpcPartUri *name, LPCWSTR content_type,
|
||||||
OPC_COMPRESSION_OPTIONS compression_options, IOpcPart **part)
|
OPC_COMPRESSION_OPTIONS compression_options, IOpcPart **part)
|
||||||
{
|
{
|
||||||
|
struct opc_part_set *part_set = impl_from_IOpcPartSet(iface);
|
||||||
|
|
||||||
TRACE("iface %p, name %p, content_type %s, compression_options %#x, part %p.\n", iface, name,
|
TRACE("iface %p, name %p, content_type %s, compression_options %#x, part %p.\n", iface, name,
|
||||||
debugstr_w(content_type), compression_options, part);
|
debugstr_w(content_type), compression_options, part);
|
||||||
|
|
||||||
return opc_part_create(name, content_type, compression_options, part);
|
return opc_part_create(part_set, name, content_type, compression_options, part);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI opc_part_set_DeletePart(IOpcPartSet *iface, IOpcPartUri *name)
|
static HRESULT WINAPI opc_part_set_DeletePart(IOpcPartSet *iface, IOpcPartUri *name)
|
||||||
|
|
Loading…
Reference in New Issue