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 */
342 struct node
*current
;
343 const char *input_data
;
346 WS_XML_READER_PROPERTY prop
[sizeof(reader_props
)/sizeof(reader_props
[0])];
349 static struct reader
*alloc_reader(void)
351 static const ULONG count
= sizeof(reader_props
)/sizeof(reader_props
[0]);
353 ULONG i
, size
= sizeof(*ret
) + count
* sizeof(WS_XML_READER_PROPERTY
);
356 for (i
= 0; i
< count
; i
++) size
+= reader_props
[i
].size
;
357 if (!(ret
= heap_alloc_zero( size
))) return NULL
;
359 ptr
= (char *)&ret
->prop
[count
];
360 for (i
= 0; i
< count
; i
++)
362 ret
->prop
[i
].value
= ptr
;
363 ret
->prop
[i
].valueSize
= reader_props
[i
].size
;
364 ptr
+= ret
->prop
[i
].valueSize
;
366 ret
->prop_count
= count
;
370 static HRESULT
set_reader_prop( struct reader
*reader
, WS_XML_READER_PROPERTY_ID id
, const void *value
, ULONG size
)
372 if (id
>= reader
->prop_count
|| size
!= reader_props
[id
].size
|| reader_props
[id
].readonly
)
375 memcpy( reader
->prop
[id
].value
, value
, size
);
379 static HRESULT
get_reader_prop( struct reader
*reader
, WS_XML_READER_PROPERTY_ID id
, void *buf
, ULONG size
)
381 if (id
>= reader
->prop_count
|| size
!= reader_props
[id
].size
)
384 memcpy( buf
, reader
->prop
[id
].value
, reader
->prop
[id
].valueSize
);
388 /**************************************************************************
389 * WsCreateReader [webservices.@]
391 HRESULT WINAPI
WsCreateReader( const WS_XML_READER_PROPERTY
*properties
, ULONG count
,
392 WS_XML_READER
**handle
, WS_ERROR
*error
)
394 struct reader
*reader
;
396 ULONG i
, max_depth
= 32, max_attrs
= 128, max_ns
= 32;
397 WS_CHARSET charset
= WS_CHARSET_UTF8
;
398 BOOL read_decl
= TRUE
;
401 TRACE( "%p %u %p %p\n", properties
, count
, handle
, error
);
402 if (error
) FIXME( "ignoring error parameter\n" );
404 if (!handle
) return E_INVALIDARG
;
405 if (!(reader
= alloc_reader())) return E_OUTOFMEMORY
;
407 set_reader_prop( reader
, WS_XML_READER_PROPERTY_MAX_DEPTH
, &max_depth
, sizeof(max_depth
) );
408 set_reader_prop( reader
, WS_XML_READER_PROPERTY_MAX_ATTRIBUTES
, &max_attrs
, sizeof(max_attrs
) );
409 set_reader_prop( reader
, WS_XML_READER_PROPERTY_READ_DECLARATION
, &read_decl
, sizeof(read_decl
) );
410 set_reader_prop( reader
, WS_XML_READER_PROPERTY_CHARSET
, &charset
, sizeof(charset
) );
411 set_reader_prop( reader
, WS_XML_READER_PROPERTY_MAX_NAMESPACES
, &max_ns
, sizeof(max_ns
) );
413 for (i
= 0; i
< count
; i
++)
415 hr
= set_reader_prop( reader
, properties
[i
].id
, properties
[i
].value
, properties
[i
].valueSize
);
423 if (!(node
= alloc_node( WS_XML_NODE_TYPE_EOF
)))
426 return E_OUTOFMEMORY
;
428 list_init( &reader
->nodes
);
429 list_add_tail( &reader
->nodes
, &node
->entry
);
430 reader
->current
= node
;
432 *handle
= (WS_XML_READER
*)reader
;
436 /**************************************************************************
437 * WsFreeReader [webservices.@]
439 void WINAPI
WsFreeReader( WS_XML_READER
*handle
)
441 struct reader
*reader
= (struct reader
*)handle
;
443 TRACE( "%p\n", handle
);
446 destroy_nodes( &reader
->nodes
);
450 /**************************************************************************
451 * WsFillReader [webservices.@]
453 HRESULT WINAPI
WsFillReader( WS_XML_READER
*handle
, ULONG min_size
, const WS_ASYNC_CONTEXT
*ctx
,
456 struct reader
*reader
= (struct reader
*)handle
;
458 TRACE( "%p %u %p %p\n", handle
, min_size
, ctx
, error
);
459 if (error
) FIXME( "ignoring error parameter\n" );
461 if (!reader
) return E_INVALIDARG
;
463 /* FIXME: add support for stream input */
464 reader
->read_size
= min( min_size
, reader
->input_size
);
465 reader
->read_pos
= 0;
470 /**************************************************************************
471 * WsGetErrorProperty [webservices.@]
473 HRESULT WINAPI
WsGetErrorProperty( WS_ERROR
*handle
, WS_ERROR_PROPERTY_ID id
, void *buf
,
476 struct error
*error
= (struct error
*)handle
;
478 TRACE( "%p %u %p %u\n", handle
, id
, buf
, size
);
479 return get_error_prop( error
, id
, buf
, size
);
482 /**************************************************************************
483 * WsGetHeapProperty [webservices.@]
485 HRESULT WINAPI
WsGetHeapProperty( WS_HEAP
*handle
, WS_HEAP_PROPERTY_ID id
, void *buf
,
486 ULONG size
, WS_ERROR
*error
)
488 struct heap
*heap
= (struct heap
*)handle
;
490 TRACE( "%p %u %p %u %p\n", handle
, id
, buf
, size
, error
);
491 if (error
) FIXME( "ignoring error parameter\n" );
493 return get_heap_prop( heap
, id
, buf
, size
);
496 /**************************************************************************
497 * WsGetReaderNode [webservices.@]
499 HRESULT WINAPI
WsGetReaderNode( WS_XML_READER
*handle
, const WS_XML_NODE
**node
,
502 struct reader
*reader
= (struct reader
*)handle
;
504 TRACE( "%p %p %p\n", handle
, node
, error
);
505 if (error
) FIXME( "ignoring error parameter\n" );
507 if (!reader
|| !node
) return E_INVALIDARG
;
509 *node
= &reader
->current
->hdr
.node
;
513 /**************************************************************************
514 * WsGetReaderProperty [webservices.@]
516 HRESULT WINAPI
WsGetReaderProperty( WS_XML_READER
*handle
, WS_XML_READER_PROPERTY_ID id
,
517 void *buf
, ULONG size
, WS_ERROR
*error
)
519 struct reader
*reader
= (struct reader
*)handle
;
521 TRACE( "%p %u %p %u %p\n", handle
, id
, buf
, size
, error
);
522 if (error
) FIXME( "ignoring error parameter\n" );
524 if (!reader
->input_data
) return WS_E_INVALID_OPERATION
;
525 return get_reader_prop( reader
, id
, buf
, size
);
528 /**************************************************************************
529 * WsSetErrorProperty [webservices.@]
531 HRESULT WINAPI
WsSetErrorProperty( WS_ERROR
*handle
, WS_ERROR_PROPERTY_ID id
, const void *value
,
534 struct error
*error
= (struct error
*)handle
;
536 TRACE( "%p %u %p %u\n", handle
, id
, value
, size
);
538 if (id
== WS_ERROR_PROPERTY_LANGID
) return WS_E_INVALID_OPERATION
;
539 return set_error_prop( error
, id
, value
, size
);
542 /**************************************************************************
543 * WsSetInput [webservices.@]
545 HRESULT WINAPI
WsSetInput( WS_XML_READER
*handle
, const WS_XML_READER_ENCODING
*encoding
,
546 const WS_XML_READER_INPUT
*input
, const WS_XML_READER_PROPERTY
*properties
,
547 ULONG count
, WS_ERROR
*error
)
549 struct reader
*reader
= (struct reader
*)handle
;
554 TRACE( "%p %p %p %p %u %p\n", handle
, encoding
, input
, properties
, count
, error
);
555 if (error
) FIXME( "ignoring error parameter\n" );
557 if (!reader
) return E_INVALIDARG
;
559 switch (encoding
->encodingType
)
561 case WS_XML_READER_ENCODING_TYPE_TEXT
:
563 WS_XML_READER_TEXT_ENCODING
*text
= (WS_XML_READER_TEXT_ENCODING
*)encoding
;
564 if (text
->charSet
!= WS_CHARSET_UTF8
)
566 FIXME( "charset %u not supported\n", text
->charSet
);
572 FIXME( "encoding type %u not supported\n", encoding
->encodingType
);
575 switch (input
->inputType
)
577 case WS_XML_READER_INPUT_TYPE_BUFFER
:
579 WS_XML_READER_BUFFER_INPUT
*buf
= (WS_XML_READER_BUFFER_INPUT
*)input
;
580 reader
->input_data
= buf
->encodedData
;
581 reader
->input_size
= buf
->encodedDataSize
;
585 FIXME( "input type %u not supported\n", input
->inputType
);
589 for (i
= 0; i
< count
; i
++)
591 hr
= set_reader_prop( reader
, properties
[i
].id
, properties
[i
].value
, properties
[i
].valueSize
);
592 if (hr
!= S_OK
) return hr
;
595 if (!(node
= alloc_node( WS_XML_NODE_TYPE_BOF
))) return E_OUTOFMEMORY
;
596 list_add_head( &reader
->nodes
, &node
->entry
);
597 reader
->current
= node
;