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"
27 #include "wine/list.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(webservices
);
31 static inline void *heap_alloc( SIZE_T size
)
33 return HeapAlloc( GetProcessHeap(), 0, size
);
36 static inline void *heap_alloc_zero( SIZE_T size
)
38 return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, size
);
41 static inline void *heap_realloc( void *mem
, SIZE_T size
)
43 return HeapReAlloc( GetProcessHeap(), 0, mem
, size
);
46 static inline BOOL
heap_free( void *mem
)
48 return HeapFree( GetProcessHeap(), 0, mem
);
58 { sizeof(ULONG
), TRUE
}, /* WS_ERROR_PROPERTY_STRING_COUNT */
59 { sizeof(ULONG
), FALSE
}, /* WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE */
60 { sizeof(LANGID
), FALSE
} /* WS_ERROR_PROPERTY_LANGID */
66 WS_ERROR_PROPERTY prop
[sizeof(error_props
)/sizeof(error_props
[0])];
69 static struct error
*alloc_error(void)
71 static const ULONG count
= sizeof(error_props
)/sizeof(error_props
[0]);
73 ULONG i
, size
= sizeof(*ret
) + count
* sizeof(WS_ERROR_PROPERTY
);
76 for (i
= 0; i
< count
; i
++) size
+= error_props
[i
].size
;
77 if (!(ret
= heap_alloc_zero( size
))) return NULL
;
79 ptr
= (char *)&ret
->prop
[count
];
80 for (i
= 0; i
< count
; i
++)
82 ret
->prop
[i
].value
= ptr
;
83 ret
->prop
[i
].valueSize
= error_props
[i
].size
;
84 ptr
+= ret
->prop
[i
].valueSize
;
86 ret
->prop_count
= count
;
90 static HRESULT
set_error_prop( struct error
*error
, WS_ERROR_PROPERTY_ID id
, const void *value
, ULONG size
)
92 if (id
>= error
->prop_count
|| size
!= error_props
[id
].size
|| error_props
[id
].readonly
)
95 memcpy( error
->prop
[id
].value
, value
, size
);
99 static HRESULT
get_error_prop( struct error
*error
, WS_ERROR_PROPERTY_ID id
, void *buf
, ULONG size
)
101 if (id
>= error
->prop_count
|| size
!= error_props
[id
].size
)
104 memcpy( buf
, error
->prop
[id
].value
, error
->prop
[id
].valueSize
);
108 /**************************************************************************
109 * WsCreateError [webservices.@]
111 HRESULT WINAPI
WsCreateError( const WS_ERROR_PROPERTY
*properties
, ULONG count
, WS_ERROR
**handle
)
114 LANGID langid
= GetUserDefaultUILanguage();
118 TRACE( "%p %u %p\n", properties
, count
, handle
);
120 if (!handle
) return E_INVALIDARG
;
121 if (!(error
= alloc_error())) return E_OUTOFMEMORY
;
123 set_error_prop( error
, WS_ERROR_PROPERTY_LANGID
, &langid
, sizeof(langid
) );
124 for (i
= 0; i
< count
; i
++)
126 if (properties
[i
].id
== WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE
)
131 hr
= set_error_prop( error
, properties
[i
].id
, properties
[i
].value
, properties
[i
].valueSize
);
139 *handle
= (WS_ERROR
*)error
;
143 /**************************************************************************
144 * WsFreeError [webservices.@]
146 void WINAPI
WsFreeError( WS_ERROR
*handle
)
148 struct error
*error
= (struct error
*)handle
;
150 TRACE( "%p\n", handle
);
161 { sizeof(SIZE_T
), FALSE
}, /* WS_HEAP_PROPERTY_MAX_SIZE */
162 { sizeof(SIZE_T
), FALSE
}, /* WS_HEAP_PROPERTY_TRIM_SIZE */
163 { sizeof(SIZE_T
), TRUE
}, /* WS_HEAP_PROPERTY_REQUESTED_SIZE */
164 { sizeof(SIZE_T
), TRUE
} /* WS_HEAP_PROPERTY_ACTUAL_SIZE */
171 WS_HEAP_PROPERTY prop
[sizeof(heap_props
)/sizeof(heap_props
[0])];
174 static struct heap
*alloc_heap(void)
176 static const ULONG count
= sizeof(heap_props
)/sizeof(heap_props
[0]);
178 ULONG i
, size
= sizeof(*ret
) + count
* sizeof(WS_HEAP_PROPERTY
);
181 for (i
= 0; i
< count
; i
++) size
+= heap_props
[i
].size
;
182 if (!(ret
= heap_alloc_zero( size
))) return NULL
;
184 ptr
= (char *)&ret
->prop
[count
];
185 for (i
= 0; i
< count
; i
++)
187 ret
->prop
[i
].value
= ptr
;
188 ret
->prop
[i
].valueSize
= heap_props
[i
].size
;
189 ptr
+= ret
->prop
[i
].valueSize
;
191 ret
->prop_count
= count
;
195 static HRESULT
set_heap_prop( struct heap
*heap
, WS_HEAP_PROPERTY_ID id
, const void *value
, ULONG size
)
197 if (id
>= heap
->prop_count
|| size
!= heap_props
[id
].size
|| heap_props
[id
].readonly
)
200 memcpy( heap
->prop
[id
].value
, value
, size
);
204 static HRESULT
get_heap_prop( struct heap
*heap
, WS_HEAP_PROPERTY_ID id
, void *buf
, ULONG size
)
206 if (id
>= heap
->prop_count
|| size
!= heap_props
[id
].size
)
209 memcpy( buf
, heap
->prop
[id
].value
, heap
->prop
[id
].valueSize
);
213 /**************************************************************************
214 * WsCreateHeap [webservices.@]
216 HRESULT WINAPI
WsCreateHeap( SIZE_T max_size
, SIZE_T trim_size
, const WS_HEAP_PROPERTY
*properties
,
217 ULONG count
, WS_HEAP
**handle
, WS_ERROR
*error
)
221 TRACE( "%u %u %p %u %p %p\n", (ULONG
)max_size
, (ULONG
)trim_size
, properties
, count
, handle
, error
);
222 if (error
) FIXME( "ignoring error parameter\n" );
224 if (!handle
|| count
) return E_INVALIDARG
;
225 if (!(heap
= alloc_heap())) return E_OUTOFMEMORY
;
227 set_heap_prop( heap
, WS_HEAP_PROPERTY_MAX_SIZE
, &max_size
, sizeof(max_size
) );
228 set_heap_prop( heap
, WS_HEAP_PROPERTY_TRIM_SIZE
, &trim_size
, sizeof(trim_size
) );
230 if (!(heap
->handle
= HeapCreate( 0, 0, max_size
)))
233 return E_OUTOFMEMORY
;
236 *handle
= (WS_HEAP
*)heap
;
240 /**************************************************************************
241 * WsFreeHeap [webservices.@]
243 void WINAPI
WsFreeHeap( WS_HEAP
*handle
)
245 struct heap
*heap
= (struct heap
*)handle
;
247 TRACE( "%p\n", handle
);
250 HeapDestroy( heap
->handle
);
256 WS_XML_ELEMENT_NODE hdr
;
260 static struct node
*alloc_node( WS_XML_NODE_TYPE type
)
264 if (!(ret
= heap_alloc_zero( sizeof(*ret
) ))) return NULL
;
265 ret
->hdr
.node
.nodeType
= type
;
266 list_init( &ret
->entry
);
270 static void free_node( struct node
*node
)
273 switch (node
->hdr
.node
.nodeType
)
275 case WS_XML_NODE_TYPE_ELEMENT
:
277 WS_XML_ELEMENT_NODE
*elem
= (WS_XML_ELEMENT_NODE
*)node
;
278 heap_free( elem
->prefix
);
279 heap_free( elem
->localName
);
280 heap_free( elem
->ns
);
283 case WS_XML_NODE_TYPE_TEXT
:
285 WS_XML_TEXT_NODE
*text
= (WS_XML_TEXT_NODE
*)node
;
286 heap_free( text
->text
);
289 case WS_XML_NODE_TYPE_END_ELEMENT
:
290 case WS_XML_NODE_TYPE_EOF
:
291 case WS_XML_NODE_TYPE_BOF
:
295 ERR( "unhandled type %u\n", node
->hdr
.node
.nodeType
);
301 static void destroy_nodes( struct list
*list
)
305 while ((ptr
= list_head( list
)))
307 struct node
*node
= LIST_ENTRY( ptr
, struct node
, entry
);
308 list_remove( &node
->entry
);
320 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_MAX_DEPTH */
321 { sizeof(BOOL
), FALSE
}, /* WS_XML_READER_PROPERTY_ALLOW_FRAGMENT */
322 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_MAX_ATTRIBUTES */
323 { sizeof(BOOL
), FALSE
}, /* WS_XML_READER_PROPERTY_READ_DECLARATION */
324 { sizeof(WS_CHARSET
), FALSE
}, /* WS_XML_READER_PROPERTY_CHARSET */
325 { sizeof(ULONGLONG
), TRUE
}, /* WS_XML_READER_PROPERTY_ROW */
326 { sizeof(ULONGLONG
), TRUE
}, /* WS_XML_READER_PROPERTY_COLUMN */
327 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_UTF8_TRIM_SIZE */
328 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_STREAM_BUFFER_SIZE */
329 { sizeof(BOOL
), TRUE
}, /* WS_XML_READER_PROPERTY_IN_ATTRIBUTE */
330 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_STREAM_MAX_ROOT_MIME_PART_SIZE */
331 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_STREAM_MAX_MIME_HEADERS_SIZE */
332 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_MAX_MIME_PARTS */
333 { sizeof(BOOL
), FALSE
}, /* WS_XML_READER_PROPERTY_ALLOW_INVALID_CHARACTER_REFERENCES */
334 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_MAX_NAMESPACES */
340 struct node
*current
;
341 const char *input_data
;
344 WS_XML_READER_PROPERTY prop
[sizeof(reader_props
)/sizeof(reader_props
[0])];
347 static struct reader
*alloc_reader(void)
349 static const ULONG count
= sizeof(reader_props
)/sizeof(reader_props
[0]);
351 ULONG i
, size
= sizeof(*ret
) + count
* sizeof(WS_XML_READER_PROPERTY
);
354 for (i
= 0; i
< count
; i
++) size
+= reader_props
[i
].size
;
355 if (!(ret
= heap_alloc_zero( size
))) return NULL
;
357 ptr
= (char *)&ret
->prop
[count
];
358 for (i
= 0; i
< count
; i
++)
360 ret
->prop
[i
].value
= ptr
;
361 ret
->prop
[i
].valueSize
= reader_props
[i
].size
;
362 ptr
+= ret
->prop
[i
].valueSize
;
364 ret
->prop_count
= count
;
368 static HRESULT
set_reader_prop( struct reader
*reader
, WS_XML_READER_PROPERTY_ID id
, const void *value
, ULONG size
)
370 if (id
>= reader
->prop_count
|| size
!= reader_props
[id
].size
|| reader_props
[id
].readonly
)
373 memcpy( reader
->prop
[id
].value
, value
, size
);
377 static HRESULT
get_reader_prop( struct reader
*reader
, WS_XML_READER_PROPERTY_ID id
, void *buf
, ULONG size
)
379 if (id
>= reader
->prop_count
|| size
!= reader_props
[id
].size
)
382 memcpy( buf
, reader
->prop
[id
].value
, reader
->prop
[id
].valueSize
);
386 /**************************************************************************
387 * WsCreateReader [webservices.@]
389 HRESULT WINAPI
WsCreateReader( const WS_XML_READER_PROPERTY
*properties
, ULONG count
,
390 WS_XML_READER
**handle
, WS_ERROR
*error
)
392 struct reader
*reader
;
394 ULONG i
, max_depth
= 32, max_attrs
= 128, max_ns
= 32;
395 WS_CHARSET charset
= WS_CHARSET_UTF8
;
396 BOOL read_decl
= TRUE
;
399 TRACE( "%p %u %p %p\n", properties
, count
, handle
, error
);
400 if (error
) FIXME( "ignoring error parameter\n" );
402 if (!handle
) return E_INVALIDARG
;
403 if (!(reader
= alloc_reader())) return E_OUTOFMEMORY
;
405 set_reader_prop( reader
, WS_XML_READER_PROPERTY_MAX_DEPTH
, &max_depth
, sizeof(max_depth
) );
406 set_reader_prop( reader
, WS_XML_READER_PROPERTY_MAX_ATTRIBUTES
, &max_attrs
, sizeof(max_attrs
) );
407 set_reader_prop( reader
, WS_XML_READER_PROPERTY_READ_DECLARATION
, &read_decl
, sizeof(read_decl
) );
408 set_reader_prop( reader
, WS_XML_READER_PROPERTY_CHARSET
, &charset
, sizeof(charset
) );
409 set_reader_prop( reader
, WS_XML_READER_PROPERTY_MAX_NAMESPACES
, &max_ns
, sizeof(max_ns
) );
411 for (i
= 0; i
< count
; i
++)
413 hr
= set_reader_prop( reader
, properties
[i
].id
, properties
[i
].value
, properties
[i
].valueSize
);
421 if (!(node
= alloc_node( WS_XML_NODE_TYPE_EOF
)))
424 return E_OUTOFMEMORY
;
426 list_init( &reader
->nodes
);
427 list_add_tail( &reader
->nodes
, &node
->entry
);
428 reader
->current
= node
;
430 *handle
= (WS_XML_READER
*)reader
;
434 /**************************************************************************
435 * WsFreeReader [webservices.@]
437 void WINAPI
WsFreeReader( WS_XML_READER
*handle
)
439 struct reader
*reader
= (struct reader
*)handle
;
441 TRACE( "%p\n", handle
);
444 destroy_nodes( &reader
->nodes
);
448 /**************************************************************************
449 * WsGetErrorProperty [webservices.@]
451 HRESULT WINAPI
WsGetErrorProperty( WS_ERROR
*handle
, WS_ERROR_PROPERTY_ID id
, void *buf
,
454 struct error
*error
= (struct error
*)handle
;
456 TRACE( "%p %u %p %u\n", handle
, id
, buf
, size
);
457 return get_error_prop( error
, id
, buf
, size
);
460 /**************************************************************************
461 * WsGetHeapProperty [webservices.@]
463 HRESULT WINAPI
WsGetHeapProperty( WS_HEAP
*handle
, WS_HEAP_PROPERTY_ID id
, void *buf
,
464 ULONG size
, WS_ERROR
*error
)
466 struct heap
*heap
= (struct heap
*)handle
;
468 TRACE( "%p %u %p %u %p\n", handle
, id
, buf
, size
, error
);
469 if (error
) FIXME( "ignoring error parameter\n" );
471 return get_heap_prop( heap
, id
, buf
, size
);
474 /**************************************************************************
475 * WsGetReaderNode [webservices.@]
477 HRESULT WINAPI
WsGetReaderNode( WS_XML_READER
*handle
, const WS_XML_NODE
**node
,
480 struct reader
*reader
= (struct reader
*)handle
;
482 TRACE( "%p %p %p\n", handle
, node
, error
);
483 if (error
) FIXME( "ignoring error parameter\n" );
485 if (!reader
|| !node
) return E_INVALIDARG
;
487 *node
= &reader
->current
->hdr
.node
;
491 /**************************************************************************
492 * WsGetReaderProperty [webservices.@]
494 HRESULT WINAPI
WsGetReaderProperty( WS_XML_READER
*handle
, WS_XML_READER_PROPERTY_ID id
,
495 void *buf
, ULONG size
, WS_ERROR
*error
)
497 struct reader
*reader
= (struct reader
*)handle
;
499 TRACE( "%p %u %p %u %p\n", handle
, id
, buf
, size
, error
);
500 if (error
) FIXME( "ignoring error parameter\n" );
502 if (!reader
->input_data
) return WS_E_INVALID_OPERATION
;
503 return get_reader_prop( reader
, id
, buf
, size
);
506 /**************************************************************************
507 * WsSetErrorProperty [webservices.@]
509 HRESULT WINAPI
WsSetErrorProperty( WS_ERROR
*handle
, WS_ERROR_PROPERTY_ID id
, const void *value
,
512 struct error
*error
= (struct error
*)handle
;
514 TRACE( "%p %u %p %u\n", handle
, id
, value
, size
);
516 if (id
== WS_ERROR_PROPERTY_LANGID
) return WS_E_INVALID_OPERATION
;
517 return set_error_prop( error
, id
, value
, size
);
520 /**************************************************************************
521 * WsSetInput [webservices.@]
523 HRESULT WINAPI
WsSetInput( WS_XML_READER
*handle
, const WS_XML_READER_ENCODING
*encoding
,
524 const WS_XML_READER_INPUT
*input
, const WS_XML_READER_PROPERTY
*properties
,
525 ULONG count
, WS_ERROR
*error
)
527 struct reader
*reader
= (struct reader
*)handle
;
532 TRACE( "%p %p %p %p %u %p\n", handle
, encoding
, input
, properties
, count
, error
);
533 if (error
) FIXME( "ignoring error parameter\n" );
535 if (!reader
) return E_INVALIDARG
;
537 switch (encoding
->encodingType
)
539 case WS_XML_READER_ENCODING_TYPE_TEXT
:
541 WS_XML_READER_TEXT_ENCODING
*text
= (WS_XML_READER_TEXT_ENCODING
*)encoding
;
542 if (text
->charSet
!= WS_CHARSET_UTF8
)
544 FIXME( "charset %u not supported\n", text
->charSet
);
550 FIXME( "encoding type %u not supported\n", encoding
->encodingType
);
553 switch (input
->inputType
)
555 case WS_XML_READER_INPUT_TYPE_BUFFER
:
557 WS_XML_READER_BUFFER_INPUT
*buf
= (WS_XML_READER_BUFFER_INPUT
*)input
;
558 reader
->input_data
= buf
->encodedData
;
559 reader
->input_size
= buf
->encodedDataSize
;
563 FIXME( "input type %u not supported\n", input
->inputType
);
567 for (i
= 0; i
< count
; i
++)
569 hr
= set_reader_prop( reader
, properties
[i
].id
, properties
[i
].value
, properties
[i
].valueSize
);
570 if (hr
!= S_OK
) return hr
;
573 if (!(node
= alloc_node( WS_XML_NODE_TYPE_BOF
))) return E_OUTOFMEMORY
;
574 list_add_head( &reader
->nodes
, &node
->entry
);
575 reader
->current
= node
;