2 * Copyright 2015, 2016 Hans Leidekker for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "webservices.h"
26 #include "wine/debug.h"
27 #include "wine/list.h"
28 #include "webservices_private.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(webservices
);
32 static const struct prop_desc heap_props
[] =
34 { sizeof(SIZE_T
), FALSE
}, /* WS_HEAP_PROPERTY_MAX_SIZE */
35 { sizeof(SIZE_T
), FALSE
}, /* WS_HEAP_PROPERTY_TRIM_SIZE */
36 { sizeof(SIZE_T
), TRUE
}, /* WS_HEAP_PROPERTY_REQUESTED_SIZE */
37 { sizeof(SIZE_T
), TRUE
} /* WS_HEAP_PROPERTY_ACTUAL_SIZE */
48 struct prop prop
[sizeof(heap_props
)/sizeof(heap_props
[0])];
51 #define HEAP_MAGIC (('H' << 24) | ('E' << 16) | ('A' << 8) | 'P')
53 static BOOL
ensure_heap( struct heap
*heap
)
56 if (heap
->handle
) return TRUE
;
57 prop_get( heap
->prop
, heap
->prop_count
, WS_HEAP_PROPERTY_MAX_SIZE
, &size
, sizeof(size
) );
58 if (!(heap
->handle
= HeapCreate( 0, 0, 0 ))) return FALSE
;
59 heap
->max_size
= size
;
64 void *ws_alloc( WS_HEAP
*handle
, SIZE_T size
)
66 struct heap
*heap
= (struct heap
*)handle
;
69 EnterCriticalSection( &heap
->cs
);
71 if (heap
->magic
!= HEAP_MAGIC
) goto done
;
72 if (!ensure_heap( heap
) || size
> heap
->max_size
- heap
->allocated
) goto done
;
73 if ((ret
= HeapAlloc( heap
->handle
, 0, size
))) heap
->allocated
+= size
;
76 LeaveCriticalSection( &heap
->cs
);
80 void *ws_alloc_zero( WS_HEAP
*handle
, SIZE_T size
)
82 struct heap
*heap
= (struct heap
*)handle
;
85 EnterCriticalSection( &heap
->cs
);
87 if (heap
->magic
!= HEAP_MAGIC
) goto done
;
88 if (!ensure_heap( heap
) || size
> heap
->max_size
- heap
->allocated
) goto done
;
89 if ((ret
= HeapAlloc( heap
->handle
, HEAP_ZERO_MEMORY
, size
))) heap
->allocated
+= size
;
92 LeaveCriticalSection( &heap
->cs
);
96 void *ws_realloc( WS_HEAP
*handle
, void *ptr
, SIZE_T old_size
, SIZE_T new_size
)
98 struct heap
*heap
= (struct heap
*)handle
;
101 EnterCriticalSection( &heap
->cs
);
103 if (heap
->magic
!= HEAP_MAGIC
|| !ensure_heap( heap
)) goto done
;
104 if (new_size
>= old_size
)
106 SIZE_T size
= new_size
- old_size
;
107 if (size
> heap
->max_size
- heap
->allocated
) goto done
;
108 if ((ret
= HeapReAlloc( heap
->handle
, 0, ptr
, new_size
))) heap
->allocated
+= size
;
112 SIZE_T size
= old_size
- new_size
;
113 if ((ret
= HeapReAlloc( heap
->handle
, 0, ptr
, new_size
))) heap
->allocated
-= size
;
117 LeaveCriticalSection( &heap
->cs
);
121 void *ws_realloc_zero( WS_HEAP
*handle
, void *ptr
, SIZE_T old_size
, SIZE_T new_size
)
123 struct heap
*heap
= (struct heap
*)handle
;
126 EnterCriticalSection( &heap
->cs
);
128 if (heap
->magic
!= HEAP_MAGIC
|| !ensure_heap( heap
)) goto done
;
129 if (new_size
>= old_size
)
131 SIZE_T size
= new_size
- old_size
;
132 if (size
> heap
->max_size
- heap
->allocated
) goto done
;
133 if ((ret
= HeapReAlloc( heap
->handle
, HEAP_ZERO_MEMORY
, ptr
, new_size
))) heap
->allocated
+= size
;
137 SIZE_T size
= old_size
- new_size
;
138 if ((ret
= HeapReAlloc( heap
->handle
, HEAP_ZERO_MEMORY
, ptr
, new_size
))) heap
->allocated
-= size
;
142 LeaveCriticalSection( &heap
->cs
);
146 void ws_free( WS_HEAP
*handle
, void *ptr
, SIZE_T size
)
148 struct heap
*heap
= (struct heap
*)handle
;
150 EnterCriticalSection( &heap
->cs
);
152 if (heap
->magic
== HEAP_MAGIC
)
154 HeapFree( heap
->handle
, 0, ptr
);
155 heap
->allocated
-= size
;
158 LeaveCriticalSection( &heap
->cs
);
161 /**************************************************************************
162 * WsAlloc [webservices.@]
164 HRESULT WINAPI
WsAlloc( WS_HEAP
*handle
, SIZE_T size
, void **ptr
, WS_ERROR
*error
)
168 TRACE( "%p %u %p %p\n", handle
, (ULONG
)size
, ptr
, error
);
169 if (error
) FIXME( "ignoring error parameter\n" );
171 if (!handle
|| !ptr
) return E_INVALIDARG
;
172 if (!(mem
= ws_alloc( handle
, size
))) return WS_E_QUOTA_EXCEEDED
;
177 static struct heap
*alloc_heap(void)
179 static const ULONG count
= sizeof(heap_props
)/sizeof(heap_props
[0]);
181 ULONG size
= sizeof(*ret
) + prop_size( heap_props
, count
);
183 if (!(ret
= heap_alloc_zero( size
))) return NULL
;
185 ret
->magic
= HEAP_MAGIC
;
186 InitializeCriticalSection( &ret
->cs
);
187 ret
->cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": heap.cs");
189 prop_init( heap_props
, count
, ret
->prop
, &ret
[1] );
190 ret
->prop_count
= count
;
194 /**************************************************************************
195 * WsCreateHeap [webservices.@]
197 HRESULT WINAPI
WsCreateHeap( SIZE_T max_size
, SIZE_T trim_size
, const WS_HEAP_PROPERTY
*properties
,
198 ULONG count
, WS_HEAP
**handle
, WS_ERROR
*error
)
202 TRACE( "%u %u %p %u %p %p\n", (ULONG
)max_size
, (ULONG
)trim_size
, properties
, count
, handle
, error
);
203 if (error
) FIXME( "ignoring error parameter\n" );
205 if (!handle
|| count
) return E_INVALIDARG
;
206 if (!(heap
= alloc_heap())) return E_OUTOFMEMORY
;
208 prop_set( heap
->prop
, heap
->prop_count
, WS_HEAP_PROPERTY_MAX_SIZE
, &max_size
, sizeof(max_size
) );
209 prop_set( heap
->prop
, heap
->prop_count
, WS_HEAP_PROPERTY_TRIM_SIZE
, &trim_size
, sizeof(trim_size
) );
211 TRACE( "created %p\n", heap
);
212 *handle
= (WS_HEAP
*)heap
;
216 static void reset_heap( struct heap
*heap
)
218 HeapDestroy( heap
->handle
);
220 heap
->max_size
= heap
->allocated
= 0;
223 /**************************************************************************
224 * WsFreeHeap [webservices.@]
226 void WINAPI
WsFreeHeap( WS_HEAP
*handle
)
228 struct heap
*heap
= (struct heap
*)handle
;
230 TRACE( "%p\n", handle
);
234 EnterCriticalSection( &heap
->cs
);
236 if (heap
->magic
!= HEAP_MAGIC
)
238 LeaveCriticalSection( &heap
->cs
);
245 LeaveCriticalSection( &heap
->cs
);
247 heap
->cs
.DebugInfo
->Spare
[0] = 0;
248 DeleteCriticalSection( &heap
->cs
);
252 /**************************************************************************
253 * WsResetHeap [webservices.@]
255 HRESULT WINAPI
WsResetHeap( WS_HEAP
*handle
, WS_ERROR
*error
)
257 struct heap
*heap
= (struct heap
*)handle
;
259 TRACE( "%p %p\n", handle
, error
);
260 if (error
) FIXME( "ignoring error parameter\n" );
262 if (!heap
) return E_INVALIDARG
;
264 EnterCriticalSection( &heap
->cs
);
266 if (heap
->magic
!= HEAP_MAGIC
)
268 LeaveCriticalSection( &heap
->cs
);
274 LeaveCriticalSection( &heap
->cs
);
278 /**************************************************************************
279 * WsGetHeapProperty [webservices.@]
281 HRESULT WINAPI
WsGetHeapProperty( WS_HEAP
*handle
, WS_HEAP_PROPERTY_ID id
, void *buf
,
282 ULONG size
, WS_ERROR
*error
)
284 struct heap
*heap
= (struct heap
*)handle
;
287 TRACE( "%p %u %p %u %p\n", handle
, id
, buf
, size
, error
);
288 if (error
) FIXME( "ignoring error parameter\n" );
290 if (!heap
) return E_INVALIDARG
;
292 EnterCriticalSection( &heap
->cs
);
294 if (heap
->magic
!= HEAP_MAGIC
)
296 LeaveCriticalSection( &heap
->cs
);
302 case WS_HEAP_PROPERTY_REQUESTED_SIZE
:
303 case WS_HEAP_PROPERTY_ACTUAL_SIZE
:
305 SIZE_T
*heap_size
= buf
;
306 if (!buf
|| size
!= sizeof(heap_size
)) hr
= E_INVALIDARG
;
307 else *heap_size
= heap
->allocated
;
311 hr
= prop_get( heap
->prop
, heap
->prop_count
, id
, buf
, size
);
314 LeaveCriticalSection( &heap
->cs
);
318 #define XML_BUFFER_INITIAL_ALLOCATED_SIZE 256
319 struct xmlbuf
*alloc_xmlbuf( WS_HEAP
*heap
, SIZE_T size
, WS_XML_WRITER_ENCODING_TYPE encoding
, WS_CHARSET charset
,
320 const WS_XML_DICTIONARY
*dict_static
, WS_XML_DICTIONARY
*dict
)
324 if (!size
) size
= XML_BUFFER_INITIAL_ALLOCATED_SIZE
;
325 if (!(ret
= ws_alloc( heap
, sizeof(*ret
) ))) return NULL
;
326 if (!(ret
->bytes
.bytes
= ws_alloc( heap
, size
)))
328 ws_free( heap
, ret
, sizeof(*ret
) );
333 ret
->bytes
.length
= 0;
334 ret
->encoding
= encoding
;
335 ret
->charset
= charset
;
336 ret
->dict_static
= dict_static
;
341 void free_xmlbuf( struct xmlbuf
*xmlbuf
)
344 ws_free( xmlbuf
->heap
, xmlbuf
->bytes
.bytes
, xmlbuf
->size
);
345 ws_free( xmlbuf
->heap
, xmlbuf
, sizeof(*xmlbuf
) );
348 /**************************************************************************
349 * WsCreateXmlBuffer [webservices.@]
351 HRESULT WINAPI
WsCreateXmlBuffer( WS_HEAP
*heap
, const WS_XML_BUFFER_PROPERTY
*properties
,
352 ULONG count
, WS_XML_BUFFER
**handle
, WS_ERROR
*error
)
354 struct xmlbuf
*xmlbuf
;
356 TRACE( "%p %p %u %p %p\n", heap
, properties
, count
, handle
, error
);
357 if (error
) FIXME( "ignoring error parameter\n" );
359 if (!heap
|| !handle
) return E_INVALIDARG
;
360 if (count
) FIXME( "properties not implemented\n" );
362 if (!(xmlbuf
= alloc_xmlbuf( heap
, 0, WS_XML_WRITER_ENCODING_TYPE_TEXT
, WS_CHARSET_UTF8
, NULL
, NULL
)))
364 return WS_E_QUOTA_EXCEEDED
;
367 TRACE( "created %p\n", xmlbuf
);
368 *handle
= (WS_XML_BUFFER
*)xmlbuf
;