2 * Copyright 2015 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"
28 WINE_DEFAULT_DEBUG_CHANNEL(webservices
);
30 static inline void *heap_alloc( SIZE_T size
)
32 return HeapAlloc( GetProcessHeap(), 0, size
);
35 static inline void *heap_alloc_zero( SIZE_T size
)
37 return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
40 static inline void *heap_realloc( void *mem
, SIZE_T size
)
42 return HeapReAlloc( GetProcessHeap(), 0, mem
, size
);
45 static inline BOOL
heap_free( void *mem
)
47 return HeapFree( GetProcessHeap(), 0, mem
);
57 { sizeof(ULONG
), TRUE
}, /* WS_ERROR_PROPERTY_STRING_COUNT */
58 { sizeof(ULONG
), FALSE
}, /* WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE */
59 { sizeof(LANGID
), FALSE
} /* WS_ERROR_PROPERTY_LANGID */
65 WS_ERROR_PROPERTY prop
[sizeof(error_props
)/sizeof(error_props
[0])];
68 static struct error
*alloc_error(void)
70 static const ULONG count
= sizeof(error_props
)/sizeof(error_props
[0]);
72 ULONG i
, size
= sizeof(*ret
) + count
* sizeof(WS_ERROR_PROPERTY
);
75 for (i
= 0; i
< count
; i
++) size
+= error_props
[i
].size
;
76 if (!(ret
= heap_alloc_zero( size
))) return NULL
;
78 ptr
= (char *)&ret
->prop
[count
];
79 for (i
= 0; i
< count
; i
++)
81 ret
->prop
[i
].value
= ptr
;
82 ret
->prop
[i
].valueSize
= error_props
[i
].size
;
83 ptr
+= ret
->prop
[i
].valueSize
;
85 ret
->prop_count
= count
;
89 static HRESULT
set_error_prop( struct error
*error
, WS_ERROR_PROPERTY_ID id
, const void *value
, ULONG size
)
91 if (id
>= error
->prop_count
|| size
!= error_props
[id
].size
|| error_props
[id
].readonly
)
94 memcpy( error
->prop
[id
].value
, value
, size
);
98 static HRESULT
get_error_prop( struct error
*error
, WS_ERROR_PROPERTY_ID id
, void *buf
, ULONG size
)
100 if (id
>= error
->prop_count
|| size
!= error_props
[id
].size
)
103 memcpy( buf
, error
->prop
[id
].value
, error
->prop
[id
].valueSize
);
107 /**************************************************************************
108 * WsCreateError [webservices.@]
110 HRESULT WINAPI
WsCreateError( const WS_ERROR_PROPERTY
*properties
, ULONG count
, WS_ERROR
**handle
)
113 LANGID langid
= GetUserDefaultUILanguage();
117 TRACE( "%p %u %p\n", properties
, count
, handle
);
119 if (!handle
) return E_INVALIDARG
;
120 if (!(error
= alloc_error())) return E_OUTOFMEMORY
;
122 set_error_prop( error
, WS_ERROR_PROPERTY_LANGID
, &langid
, sizeof(langid
) );
123 for (i
= 0; i
< count
; i
++)
125 if (properties
[i
].id
== WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE
)
130 hr
= set_error_prop( error
, properties
[i
].id
, properties
[i
].value
, properties
[i
].valueSize
);
138 *handle
= (WS_ERROR
*)error
;
142 /**************************************************************************
143 * WsFreeError [webservices.@]
145 void WINAPI
WsFreeError( WS_ERROR
*handle
)
147 struct error
*error
= (struct error
*)handle
;
149 TRACE( "%p\n", handle
);
160 { sizeof(SIZE_T
), FALSE
}, /* WS_HEAP_PROPERTY_MAX_SIZE */
161 { sizeof(SIZE_T
), FALSE
}, /* WS_HEAP_PROPERTY_TRIM_SIZE */
162 { sizeof(SIZE_T
), TRUE
}, /* WS_HEAP_PROPERTY_REQUESTED_SIZE */
163 { sizeof(SIZE_T
), TRUE
} /* WS_HEAP_PROPERTY_ACTUAL_SIZE */
170 WS_HEAP_PROPERTY prop
[sizeof(heap_props
)/sizeof(heap_props
[0])];
173 static struct heap
*alloc_heap(void)
175 static const ULONG count
= sizeof(heap_props
)/sizeof(heap_props
[0]);
177 ULONG i
, size
= sizeof(*ret
) + count
* sizeof(WS_HEAP_PROPERTY
);
180 for (i
= 0; i
< count
; i
++) size
+= heap_props
[i
].size
;
181 if (!(ret
= heap_alloc_zero( size
))) return NULL
;
183 ptr
= (char *)&ret
->prop
[count
];
184 for (i
= 0; i
< count
; i
++)
186 ret
->prop
[i
].value
= ptr
;
187 ret
->prop
[i
].valueSize
= heap_props
[i
].size
;
188 ptr
+= ret
->prop
[i
].valueSize
;
190 ret
->prop_count
= count
;
194 static HRESULT
set_heap_prop( struct heap
*heap
, WS_HEAP_PROPERTY_ID id
, const void *value
, ULONG size
)
196 if (id
>= heap
->prop_count
|| size
!= heap_props
[id
].size
|| heap_props
[id
].readonly
)
199 memcpy( heap
->prop
[id
].value
, value
, size
);
203 static HRESULT
get_heap_prop( struct heap
*heap
, WS_HEAP_PROPERTY_ID id
, void *buf
, ULONG size
)
205 if (id
>= heap
->prop_count
|| size
!= heap_props
[id
].size
)
208 memcpy( buf
, heap
->prop
[id
].value
, heap
->prop
[id
].valueSize
);
212 /**************************************************************************
213 * WsCreateHeap [webservices.@]
215 HRESULT WINAPI
WsCreateHeap( SIZE_T max_size
, SIZE_T trim_size
, const WS_HEAP_PROPERTY
*properties
,
216 ULONG count
, WS_HEAP
**handle
, WS_ERROR
*error
)
220 TRACE( "%u %u %p %u %p %p\n", (ULONG
)max_size
, (ULONG
)trim_size
, properties
, count
, handle
, error
);
221 if (error
) FIXME( "ignoring error parameter\n" );
223 if (!handle
|| count
) return E_INVALIDARG
;
224 if (!(heap
= alloc_heap())) return E_OUTOFMEMORY
;
226 set_heap_prop( heap
, WS_HEAP_PROPERTY_MAX_SIZE
, &max_size
, sizeof(max_size
) );
227 set_heap_prop( heap
, WS_HEAP_PROPERTY_TRIM_SIZE
, &trim_size
, sizeof(trim_size
) );
229 if (!(heap
->handle
= HeapCreate( 0, 0, max_size
)))
232 return E_OUTOFMEMORY
;
235 *handle
= (WS_HEAP
*)heap
;
239 /**************************************************************************
240 * WsFreeHeap [webservices.@]
242 void WINAPI
WsFreeHeap( WS_HEAP
*handle
)
244 struct heap
*heap
= (struct heap
*)handle
;
246 TRACE( "%p\n", handle
);
249 HeapDestroy( heap
->handle
);
260 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_MAX_DEPTH */
261 { sizeof(BOOL
), FALSE
}, /* WS_XML_READER_PROPERTY_ALLOW_FRAGMENT */
262 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_MAX_ATTRIBUTES */
263 { sizeof(BOOL
), FALSE
}, /* WS_XML_READER_PROPERTY_READ_DECLARATION */
264 { sizeof(WS_CHARSET
), FALSE
}, /* WS_XML_READER_PROPERTY_CHARSET */
265 { sizeof(ULONGLONG
), TRUE
}, /* WS_XML_READER_PROPERTY_ROW */
266 { sizeof(ULONGLONG
), TRUE
}, /* WS_XML_READER_PROPERTY_COLUMN */
267 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_UTF8_TRIM_SIZE */
268 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_STREAM_BUFFER_SIZE */
269 { sizeof(BOOL
), TRUE
}, /* WS_XML_READER_PROPERTY_IN_ATTRIBUTE */
270 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_STREAM_MAX_ROOT_MIME_PART_SIZE */
271 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_STREAM_MAX_MIME_HEADERS_SIZE */
272 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_MAX_MIME_PARTS */
273 { sizeof(BOOL
), FALSE
}, /* WS_XML_READER_PROPERTY_ALLOW_INVALID_CHARACTER_REFERENCES */
274 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_MAX_NAMESPACES */
280 WS_XML_READER_PROPERTY prop
[sizeof(reader_props
)/sizeof(reader_props
[0])];
283 static struct reader
*alloc_reader(void)
285 static const ULONG count
= sizeof(reader_props
)/sizeof(reader_props
[0]);
287 ULONG i
, size
= sizeof(*ret
) + count
* sizeof(WS_XML_READER_PROPERTY
);
290 for (i
= 0; i
< count
; i
++) size
+= reader_props
[i
].size
;
291 if (!(ret
= heap_alloc_zero( size
))) return NULL
;
293 ptr
= (char *)&ret
->prop
[count
];
294 for (i
= 0; i
< count
; i
++)
296 ret
->prop
[i
].value
= ptr
;
297 ret
->prop
[i
].valueSize
= reader_props
[i
].size
;
298 ptr
+= ret
->prop
[i
].valueSize
;
300 ret
->prop_count
= count
;
304 static HRESULT
set_reader_prop( struct reader
*reader
, WS_XML_READER_PROPERTY_ID id
, const void *value
, ULONG size
)
306 if (id
>= reader
->prop_count
|| size
!= reader_props
[id
].size
|| reader_props
[id
].readonly
)
309 memcpy( reader
->prop
[id
].value
, value
, size
);
313 /**************************************************************************
314 * WsCreateReader [webservices.@]
316 HRESULT WINAPI
WsCreateReader( const WS_XML_READER_PROPERTY
*properties
, ULONG count
,
317 WS_XML_READER
**handle
, WS_ERROR
*error
)
319 struct reader
*reader
;
320 ULONG i
, max_depth
= 32, max_attrs
= 128, max_ns
= 32;
321 WS_CHARSET charset
= WS_CHARSET_UTF8
;
322 BOOL read_decl
= TRUE
;
325 TRACE( "%p %u %p %p\n", properties
, count
, handle
, error
);
326 if (error
) FIXME( "ignoring error parameter\n" );
328 if (!handle
) return E_INVALIDARG
;
329 if (!(reader
= alloc_reader())) return E_OUTOFMEMORY
;
331 set_reader_prop( reader
, WS_XML_READER_PROPERTY_MAX_DEPTH
, &max_depth
, sizeof(max_depth
) );
332 set_reader_prop( reader
, WS_XML_READER_PROPERTY_MAX_ATTRIBUTES
, &max_attrs
, sizeof(max_attrs
) );
333 set_reader_prop( reader
, WS_XML_READER_PROPERTY_READ_DECLARATION
, &read_decl
, sizeof(read_decl
) );
334 set_reader_prop( reader
, WS_XML_READER_PROPERTY_CHARSET
, &charset
, sizeof(charset
) );
335 set_reader_prop( reader
, WS_XML_READER_PROPERTY_MAX_NAMESPACES
, &max_ns
, sizeof(max_ns
) );
337 for (i
= 0; i
< count
; i
++)
339 hr
= set_reader_prop( reader
, properties
[i
].id
, properties
[i
].value
, properties
[i
].valueSize
);
347 *handle
= (WS_XML_READER
*)reader
;
351 /**************************************************************************
352 * WsFreeReader [webservices.@]
354 void WINAPI
WsFreeReader( WS_XML_READER
*handle
)
356 struct reader
*reader
= (struct reader
*)handle
;
358 TRACE( "%p\n", handle
);
364 /**************************************************************************
365 * WsGetErrorProperty [webservices.@]
367 HRESULT WINAPI
WsGetErrorProperty( WS_ERROR
*handle
, WS_ERROR_PROPERTY_ID id
, void *buf
,
370 struct error
*error
= (struct error
*)handle
;
372 TRACE( "%p %u %p %u\n", handle
, id
, buf
, size
);
373 return get_error_prop( error
, id
, buf
, size
);
376 /**************************************************************************
377 * WsGetHeapProperty [webservices.@]
379 HRESULT WINAPI
WsGetHeapProperty( WS_HEAP
*handle
, WS_HEAP_PROPERTY_ID id
, void *buf
,
380 ULONG size
, WS_ERROR
*error
)
382 struct heap
*heap
= (struct heap
*)handle
;
384 TRACE( "%p %u %p %u %p\n", handle
, id
, buf
, size
, error
);
385 if (error
) FIXME( "ignoring error parameter\n" );
387 return get_heap_prop( heap
, id
, buf
, size
);
390 /**************************************************************************
391 * WsSetErrorProperty [webservices.@]
393 HRESULT WINAPI
WsSetErrorProperty( WS_ERROR
*handle
, WS_ERROR_PROPERTY_ID id
, const void *value
,
396 struct error
*error
= (struct error
*)handle
;
398 TRACE( "%p %u %p %u\n", handle
, id
, value
, size
);
400 if (id
== WS_ERROR_PROPERTY_LANGID
) return WS_E_INVALID_OPERATION
;
401 return set_error_prop( error
, id
, value
, size
);