Nikolay Sivov : opcservices: Keep parts in a set.
Alexandre Julliard
julliard at winehq.org
Wed Sep 5 16:15:27 CDT 2018
Module: wine
Branch: master
Commit: 8fd70ff2bf06f4bc23b75747c6ccde09ebda8db5
URL: https://source.winehq.org/git/wine.git/?a=commit;h=8fd70ff2bf06f4bc23b75747c6ccde09ebda8db5
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Wed Sep 5 08:37:23 2018 +0300
opcservices: Keep parts in a set.
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/opcservices/opc_private.h | 26 ++++++++++++++++++++++++++
dlls/opcservices/package.c | 23 +++++++++++++++++++++--
2 files changed, 47 insertions(+), 2 deletions(-)
diff --git a/dlls/opcservices/opc_private.h b/dlls/opcservices/opc_private.h
index 4784b6c..30bcb00 100644
--- a/dlls/opcservices/opc_private.h
+++ b/dlls/opcservices/opc_private.h
@@ -19,5 +19,31 @@
#include "msopc.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_part_uri_create(const WCHAR *uri, IOpcPartUri **part_uri) DECLSPEC_HIDDEN;
diff --git a/dlls/opcservices/package.c b/dlls/opcservices/package.c
index cd4741d..869fb03 100644
--- a/dlls/opcservices/package.c
+++ b/dlls/opcservices/package.c
@@ -53,6 +53,10 @@ struct opc_part_set
{
IOpcPartSet IOpcPartSet_iface;
LONG refcount;
+
+ struct opc_part **parts;
+ size_t size;
+ size_t count;
};
struct opc_relationship
@@ -220,7 +224,7 @@ static const IOpcPartVtbl opc_part_vtbl =
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)
{
struct opc_part *part;
@@ -228,6 +232,9 @@ static HRESULT opc_part_create(IOpcPartUri *name, const WCHAR *content_type,
if (!name)
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))))
return E_OUTOFMEMORY;
@@ -242,6 +249,9 @@ static HRESULT opc_part_create(IOpcPartUri *name, const WCHAR *content_type,
return E_OUTOFMEMORY;
}
+ set->parts[set->count++] = part;
+ IOpcPart_AddRef(&part->IOpcPart_iface);
+
*out = &part->IOpcPart_iface;
TRACE("Created part %p.\n", *out);
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);
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);
+ }
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,
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,
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)
More information about the wine-cvs
mailing list