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 const char *debugstr_xmlstr( const WS_XML_STRING
*str
)
34 if (!str
) return "(null)";
35 return debugstr_an( (const char *)str
->bytes
, str
->length
);
38 ULONG
prop_size( const struct prop_desc
*desc
, ULONG count
)
40 ULONG i
, ret
= count
* sizeof(struct prop
);
41 for (i
= 0; i
< count
; i
++) ret
+= desc
[i
].size
;
45 void prop_init( const struct prop_desc
*desc
, ULONG count
, struct prop
*prop
, void *data
)
49 for (i
= 0; i
< count
; i
++)
52 prop
[i
].size
= desc
[i
].size
;
53 prop
[i
].readonly
= desc
[i
].readonly
;
54 prop
[i
].writeonly
= desc
[i
].writeonly
;
59 HRESULT
prop_set( const struct prop
*prop
, ULONG count
, ULONG id
, const void *value
, ULONG size
)
61 if (id
>= count
|| size
!= prop
[id
].size
|| prop
[id
].readonly
) return E_INVALIDARG
;
62 memcpy( prop
[id
].value
, value
, size
);
66 HRESULT
prop_get( const struct prop
*prop
, ULONG count
, ULONG id
, void *buf
, ULONG size
)
68 if (id
>= count
|| size
!= prop
[id
].size
|| prop
[id
].writeonly
) return E_INVALIDARG
;
69 memcpy( buf
, prop
[id
].value
, prop
[id
].size
);
73 static const struct prop_desc error_props
[] =
75 { sizeof(ULONG
), TRUE
}, /* WS_ERROR_PROPERTY_STRING_COUNT */
76 { sizeof(ULONG
), FALSE
}, /* WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE */
77 { sizeof(LANGID
), FALSE
} /* WS_ERROR_PROPERTY_LANGID */
83 struct prop prop
[sizeof(error_props
)/sizeof(error_props
[0])];
86 static struct error
*alloc_error(void)
88 static const ULONG count
= sizeof(error_props
)/sizeof(error_props
[0]);
90 ULONG size
= sizeof(*ret
) + prop_size( error_props
, count
);
92 if (!(ret
= heap_alloc_zero( size
))) return NULL
;
93 prop_init( error_props
, count
, ret
->prop
, &ret
[1] );
94 ret
->prop_count
= count
;
98 /**************************************************************************
99 * WsCreateError [webservices.@]
101 HRESULT WINAPI
WsCreateError( const WS_ERROR_PROPERTY
*properties
, ULONG count
, WS_ERROR
**handle
)
104 LANGID langid
= GetUserDefaultUILanguage();
108 TRACE( "%p %u %p\n", properties
, count
, handle
);
110 if (!handle
) return E_INVALIDARG
;
111 if (!(error
= alloc_error())) return E_OUTOFMEMORY
;
113 prop_set( error
->prop
, error
->prop_count
, WS_ERROR_PROPERTY_LANGID
, &langid
, sizeof(langid
) );
114 for (i
= 0; i
< count
; i
++)
116 if (properties
[i
].id
== WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE
)
121 hr
= prop_set( error
->prop
, error
->prop_count
, properties
[i
].id
, properties
[i
].value
,
122 properties
[i
].valueSize
);
130 *handle
= (WS_ERROR
*)error
;
134 /**************************************************************************
135 * WsFreeError [webservices.@]
137 void WINAPI
WsFreeError( WS_ERROR
*handle
)
139 struct error
*error
= (struct error
*)handle
;
141 TRACE( "%p\n", handle
);
145 static const struct prop_desc heap_props
[] =
147 { sizeof(SIZE_T
), FALSE
}, /* WS_HEAP_PROPERTY_MAX_SIZE */
148 { sizeof(SIZE_T
), FALSE
}, /* WS_HEAP_PROPERTY_TRIM_SIZE */
149 { sizeof(SIZE_T
), TRUE
}, /* WS_HEAP_PROPERTY_REQUESTED_SIZE */
150 { sizeof(SIZE_T
), TRUE
} /* WS_HEAP_PROPERTY_ACTUAL_SIZE */
157 struct prop prop
[sizeof(heap_props
)/sizeof(heap_props
[0])];
160 void *ws_alloc( WS_HEAP
*handle
, SIZE_T size
)
162 struct heap
*heap
= (struct heap
*)handle
;
163 return HeapAlloc( heap
->handle
, 0, size
);
166 static void *ws_alloc_zero( WS_HEAP
*handle
, SIZE_T size
)
168 struct heap
*heap
= (struct heap
*)handle
;
169 return HeapAlloc( heap
->handle
, HEAP_ZERO_MEMORY
, size
);
172 void *ws_realloc( WS_HEAP
*handle
, void *ptr
, SIZE_T size
)
174 struct heap
*heap
= (struct heap
*)handle
;
175 return HeapReAlloc( heap
->handle
, 0, ptr
, size
);
178 static void *ws_realloc_zero( WS_HEAP
*handle
, void *ptr
, SIZE_T size
)
180 struct heap
*heap
= (struct heap
*)handle
;
181 return HeapReAlloc( heap
->handle
, HEAP_ZERO_MEMORY
, ptr
, size
);
184 void ws_free( WS_HEAP
*handle
, void *ptr
)
186 struct heap
*heap
= (struct heap
*)handle
;
187 HeapFree( heap
->handle
, 0, ptr
);
190 /**************************************************************************
191 * WsAlloc [webservices.@]
193 HRESULT WINAPI
WsAlloc( WS_HEAP
*handle
, SIZE_T size
, void **ptr
, WS_ERROR
*error
)
197 TRACE( "%p %u %p %p\n", handle
, (ULONG
)size
, ptr
, error
);
198 if (error
) FIXME( "ignoring error parameter\n" );
200 if (!handle
|| !ptr
) return E_INVALIDARG
;
202 if (!(mem
= ws_alloc( handle
, size
))) return E_OUTOFMEMORY
;
207 static struct heap
*alloc_heap(void)
209 static const ULONG count
= sizeof(heap_props
)/sizeof(heap_props
[0]);
211 ULONG size
= sizeof(*ret
) + prop_size( heap_props
, count
);
213 if (!(ret
= heap_alloc_zero( size
))) return NULL
;
214 prop_init( heap_props
, count
, ret
->prop
, &ret
[1] );
215 ret
->prop_count
= count
;
219 /**************************************************************************
220 * WsCreateHeap [webservices.@]
222 HRESULT WINAPI
WsCreateHeap( SIZE_T max_size
, SIZE_T trim_size
, const WS_HEAP_PROPERTY
*properties
,
223 ULONG count
, WS_HEAP
**handle
, WS_ERROR
*error
)
227 TRACE( "%u %u %p %u %p %p\n", (ULONG
)max_size
, (ULONG
)trim_size
, properties
, count
, handle
, error
);
228 if (error
) FIXME( "ignoring error parameter\n" );
230 if (!handle
|| count
) return E_INVALIDARG
;
231 if (!(heap
= alloc_heap())) return E_OUTOFMEMORY
;
233 prop_set( heap
->prop
, heap
->prop_count
, WS_HEAP_PROPERTY_MAX_SIZE
, &max_size
, sizeof(max_size
) );
234 prop_set( heap
->prop
, heap
->prop_count
, WS_HEAP_PROPERTY_TRIM_SIZE
, &trim_size
, sizeof(trim_size
) );
236 if (!(heap
->handle
= HeapCreate( 0, 0, max_size
)))
239 return E_OUTOFMEMORY
;
242 *handle
= (WS_HEAP
*)heap
;
246 /**************************************************************************
247 * WsFreeHeap [webservices.@]
249 void WINAPI
WsFreeHeap( WS_HEAP
*handle
)
251 struct heap
*heap
= (struct heap
*)handle
;
253 TRACE( "%p\n", handle
);
256 HeapDestroy( heap
->handle
);
260 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
);
267 list_init( &ret
->children
);
271 void free_attribute( WS_XML_ATTRIBUTE
*attr
)
274 heap_free( attr
->prefix
);
275 heap_free( attr
->localName
);
276 heap_free( attr
->ns
);
277 heap_free( attr
->value
);
281 void free_node( struct node
*node
)
284 switch (node_type( node
))
286 case WS_XML_NODE_TYPE_ELEMENT
:
288 WS_XML_ELEMENT_NODE
*elem
= &node
->hdr
;
291 for (i
= 0; i
< elem
->attributeCount
; i
++) free_attribute( elem
->attributes
[i
] );
292 heap_free( elem
->attributes
);
293 heap_free( elem
->prefix
);
294 heap_free( elem
->localName
);
295 heap_free( elem
->ns
);
298 case WS_XML_NODE_TYPE_TEXT
:
300 WS_XML_TEXT_NODE
*text
= (WS_XML_TEXT_NODE
*)node
;
301 heap_free( text
->text
);
304 case WS_XML_NODE_TYPE_COMMENT
:
306 WS_XML_COMMENT_NODE
*comment
= (WS_XML_COMMENT_NODE
*)node
;
307 heap_free( comment
->value
.bytes
);
310 case WS_XML_NODE_TYPE_CDATA
:
311 case WS_XML_NODE_TYPE_END_CDATA
:
312 case WS_XML_NODE_TYPE_END_ELEMENT
:
313 case WS_XML_NODE_TYPE_EOF
:
314 case WS_XML_NODE_TYPE_BOF
:
318 ERR( "unhandled type %u\n", node_type( node
) );
324 void destroy_nodes( struct node
*node
)
329 while ((ptr
= list_head( &node
->children
)))
331 struct node
*child
= LIST_ENTRY( ptr
, struct node
, entry
);
332 list_remove( &child
->entry
);
333 destroy_nodes( child
);
338 static const struct prop_desc reader_props
[] =
340 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_MAX_DEPTH */
341 { sizeof(BOOL
), FALSE
}, /* WS_XML_READER_PROPERTY_ALLOW_FRAGMENT */
342 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_MAX_ATTRIBUTES */
343 { sizeof(BOOL
), FALSE
}, /* WS_XML_READER_PROPERTY_READ_DECLARATION */
344 { sizeof(WS_CHARSET
), FALSE
}, /* WS_XML_READER_PROPERTY_CHARSET */
345 { sizeof(ULONGLONG
), TRUE
}, /* WS_XML_READER_PROPERTY_ROW */
346 { sizeof(ULONGLONG
), TRUE
}, /* WS_XML_READER_PROPERTY_COLUMN */
347 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_UTF8_TRIM_SIZE */
348 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_STREAM_BUFFER_SIZE */
349 { sizeof(BOOL
), TRUE
}, /* WS_XML_READER_PROPERTY_IN_ATTRIBUTE */
350 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_STREAM_MAX_ROOT_MIME_PART_SIZE */
351 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_STREAM_MAX_MIME_HEADERS_SIZE */
352 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_MAX_MIME_PARTS */
353 { sizeof(BOOL
), FALSE
}, /* WS_XML_READER_PROPERTY_ALLOW_INVALID_CHARACTER_REFERENCES */
354 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_MAX_NAMESPACES */
359 READER_STATE_INITIAL
,
361 READER_STATE_STARTELEMENT
,
362 READER_STATE_STARTATTRIBUTE
,
363 READER_STATE_STARTCDATA
,
366 READER_STATE_ENDELEMENT
,
367 READER_STATE_ENDCDATA
,
368 READER_STATE_COMMENT
,
382 const unsigned char *read_bufptr
;
383 enum reader_state state
;
385 struct node
*current
;
387 struct prefix
*prefixes
;
389 ULONG nb_prefixes_allocated
;
390 WS_XML_READER_INPUT_TYPE input_type
;
391 const unsigned char *input_data
;
394 struct prop prop
[sizeof(reader_props
)/sizeof(reader_props
[0])];
397 static struct reader
*alloc_reader(void)
399 static const ULONG count
= sizeof(reader_props
)/sizeof(reader_props
[0]);
401 ULONG size
= sizeof(*ret
) + prop_size( reader_props
, count
);
403 if (!(ret
= heap_alloc_zero( size
))) return NULL
;
404 if (!(ret
->prefixes
= heap_alloc_zero( sizeof(*ret
->prefixes
) )))
409 ret
->nb_prefixes
= ret
->nb_prefixes_allocated
= 1;
411 prop_init( reader_props
, count
, ret
->prop
, &ret
[1] );
412 ret
->prop_count
= count
;
416 static void clear_prefixes( struct prefix
*prefixes
, ULONG count
)
419 for (i
= 0; i
< count
; i
++)
421 heap_free( prefixes
[i
].str
.bytes
);
422 prefixes
[i
].str
.bytes
= NULL
;
423 prefixes
[i
].str
.length
= 0;
425 heap_free( prefixes
[i
].ns
.bytes
);
426 prefixes
[i
].ns
.bytes
= NULL
;
427 prefixes
[i
].ns
.length
= 0;
431 static void free_reader( struct reader
*reader
)
434 destroy_nodes( reader
->root
);
435 clear_prefixes( reader
->prefixes
, reader
->nb_prefixes
);
436 heap_free( reader
->prefixes
);
440 static HRESULT
set_prefix( struct prefix
*prefix
, const WS_XML_STRING
*str
, const WS_XML_STRING
*ns
)
444 heap_free( prefix
->str
.bytes
);
445 if (!(prefix
->str
.bytes
= heap_alloc( str
->length
))) return E_OUTOFMEMORY
;
446 memcpy( prefix
->str
.bytes
, str
->bytes
, str
->length
);
447 prefix
->str
.length
= str
->length
;
450 heap_free( prefix
->ns
.bytes
);
451 if (!(prefix
->ns
.bytes
= heap_alloc( ns
->length
))) return E_OUTOFMEMORY
;
452 memcpy( prefix
->ns
.bytes
, ns
->bytes
, ns
->length
);
453 prefix
->ns
.length
= ns
->length
;
458 static HRESULT
bind_prefix( struct reader
*reader
, const WS_XML_STRING
*prefix
, const WS_XML_STRING
*ns
)
463 for (i
= 0; i
< reader
->nb_prefixes
; i
++)
465 if (WsXmlStringEquals( prefix
, &reader
->prefixes
[i
].str
, NULL
) == S_OK
)
466 return set_prefix( &reader
->prefixes
[i
], NULL
, ns
);
468 if (i
>= reader
->nb_prefixes_allocated
)
470 ULONG new_size
= reader
->nb_prefixes_allocated
* sizeof(*reader
->prefixes
) * 2;
471 struct prefix
*tmp
= heap_realloc_zero( reader
->prefixes
, new_size
);
472 if (!tmp
) return E_OUTOFMEMORY
;
473 reader
->prefixes
= tmp
;
474 reader
->nb_prefixes_allocated
*= 2;
477 if ((hr
= set_prefix( &reader
->prefixes
[i
], prefix
, ns
)) != S_OK
) return hr
;
478 reader
->nb_prefixes
++;
482 static const WS_XML_STRING
*get_namespace( struct reader
*reader
, const WS_XML_STRING
*prefix
)
485 for (i
= 0; i
< reader
->nb_prefixes
; i
++)
487 if (WsXmlStringEquals( prefix
, &reader
->prefixes
[i
].str
, NULL
) == S_OK
)
488 return &reader
->prefixes
[i
].ns
;
493 static void read_insert_eof( struct reader
*reader
, struct node
*eof
)
495 if (!reader
->root
) reader
->root
= eof
;
498 eof
->parent
= reader
->root
;
499 list_add_tail( &reader
->root
->children
, &eof
->entry
);
501 reader
->current
= eof
;
504 static void read_insert_bof( struct reader
*reader
, struct node
*bof
)
506 reader
->root
->parent
= bof
;
507 list_add_tail( &bof
->children
, &reader
->root
->entry
);
508 reader
->current
= reader
->root
= bof
;
511 static void read_insert_node( struct reader
*reader
, struct node
*parent
, struct node
*node
)
513 node
->parent
= parent
;
514 if (node
->parent
== reader
->root
)
516 struct list
*eof
= list_tail( &reader
->root
->children
);
517 list_add_before( eof
, &node
->entry
);
519 else list_add_tail( &parent
->children
, &node
->entry
);
520 reader
->current
= node
;
523 static HRESULT
read_init_state( struct reader
*reader
)
527 destroy_nodes( reader
->root
);
529 clear_prefixes( reader
->prefixes
, reader
->nb_prefixes
);
530 reader
->nb_prefixes
= 1;
531 if (!(node
= alloc_node( WS_XML_NODE_TYPE_EOF
))) return E_OUTOFMEMORY
;
532 read_insert_eof( reader
, node
);
533 reader
->state
= READER_STATE_INITIAL
;
537 /**************************************************************************
538 * WsCreateReader [webservices.@]
540 HRESULT WINAPI
WsCreateReader( const WS_XML_READER_PROPERTY
*properties
, ULONG count
,
541 WS_XML_READER
**handle
, WS_ERROR
*error
)
543 struct reader
*reader
;
544 ULONG i
, max_depth
= 32, max_attrs
= 128, max_ns
= 32;
545 WS_CHARSET charset
= WS_CHARSET_UTF8
;
546 BOOL read_decl
= TRUE
;
549 TRACE( "%p %u %p %p\n", properties
, count
, handle
, error
);
550 if (error
) FIXME( "ignoring error parameter\n" );
552 if (!handle
) return E_INVALIDARG
;
553 if (!(reader
= alloc_reader())) return E_OUTOFMEMORY
;
555 prop_set( reader
->prop
, reader
->prop_count
, WS_XML_READER_PROPERTY_MAX_DEPTH
, &max_depth
, sizeof(max_depth
) );
556 prop_set( reader
->prop
, reader
->prop_count
, WS_XML_READER_PROPERTY_MAX_ATTRIBUTES
, &max_attrs
, sizeof(max_attrs
) );
557 prop_set( reader
->prop
, reader
->prop_count
, WS_XML_READER_PROPERTY_READ_DECLARATION
, &read_decl
, sizeof(read_decl
) );
558 prop_set( reader
->prop
, reader
->prop_count
, WS_XML_READER_PROPERTY_CHARSET
, &charset
, sizeof(charset
) );
559 prop_set( reader
->prop
, reader
->prop_count
, WS_XML_READER_PROPERTY_MAX_NAMESPACES
, &max_ns
, sizeof(max_ns
) );
561 for (i
= 0; i
< count
; i
++)
563 hr
= prop_set( reader
->prop
, reader
->prop_count
, properties
[i
].id
, properties
[i
].value
,
564 properties
[i
].valueSize
);
567 free_reader( reader
);
572 if ((hr
= read_init_state( reader
)) != S_OK
)
574 free_reader( reader
);
578 *handle
= (WS_XML_READER
*)reader
;
582 /**************************************************************************
583 * WsFreeReader [webservices.@]
585 void WINAPI
WsFreeReader( WS_XML_READER
*handle
)
587 struct reader
*reader
= (struct reader
*)handle
;
589 TRACE( "%p\n", handle
);
590 free_reader( reader
);
593 /**************************************************************************
594 * WsFillReader [webservices.@]
596 HRESULT WINAPI
WsFillReader( WS_XML_READER
*handle
, ULONG min_size
, const WS_ASYNC_CONTEXT
*ctx
,
599 struct reader
*reader
= (struct reader
*)handle
;
601 TRACE( "%p %u %p %p\n", handle
, min_size
, ctx
, error
);
602 if (error
) FIXME( "ignoring error parameter\n" );
604 if (!reader
) return E_INVALIDARG
;
606 /* FIXME: add support for stream input */
607 reader
->read_size
= min( min_size
, reader
->input_size
);
608 reader
->read_pos
= 0;
613 /**************************************************************************
614 * WsGetErrorProperty [webservices.@]
616 HRESULT WINAPI
WsGetErrorProperty( WS_ERROR
*handle
, WS_ERROR_PROPERTY_ID id
, void *buf
,
619 struct error
*error
= (struct error
*)handle
;
621 TRACE( "%p %u %p %u\n", handle
, id
, buf
, size
);
622 return prop_get( error
->prop
, error
->prop_count
, id
, buf
, size
);
625 /**************************************************************************
626 * WsGetErrorString [webservices.@]
628 HRESULT WINAPI
WsGetErrorString( WS_ERROR
*handle
, ULONG index
, WS_STRING
*str
)
630 FIXME( "%p %u %p: stub\n", handle
, index
, str
);
634 /**************************************************************************
635 * WsGetHeapProperty [webservices.@]
637 HRESULT WINAPI
WsGetHeapProperty( WS_HEAP
*handle
, WS_HEAP_PROPERTY_ID id
, void *buf
,
638 ULONG size
, WS_ERROR
*error
)
640 struct heap
*heap
= (struct heap
*)handle
;
642 TRACE( "%p %u %p %u %p\n", handle
, id
, buf
, size
, error
);
643 if (error
) FIXME( "ignoring error parameter\n" );
645 return prop_get( heap
->prop
, heap
->prop_count
, id
, buf
, size
);
648 /**************************************************************************
649 * WsGetNamespaceFromPrefix [webservices.@]
651 HRESULT WINAPI
WsGetNamespaceFromPrefix( WS_XML_READER
*handle
, const WS_XML_STRING
*prefix
,
652 BOOL required
, const WS_XML_STRING
**ns
, WS_ERROR
*error
)
654 static const WS_XML_STRING xml
= {3, (BYTE
*)"xml"};
655 static const WS_XML_STRING xmlns
= {5, (BYTE
*)"xmlns"};
656 static const WS_XML_STRING empty_ns
= {0, NULL
};
657 static const WS_XML_STRING xml_ns
= {36, (BYTE
*)"http://www.w3.org/XML/1998/namespace"};
658 static const WS_XML_STRING xmlns_ns
= {29, (BYTE
*)"http://www.w3.org/2000/xmlns/"};
659 struct reader
*reader
= (struct reader
*)handle
;
662 TRACE( "%p %s %d %p %p\n", handle
, debugstr_xmlstr(prefix
), required
, ns
, error
);
663 if (error
) FIXME( "ignoring error parameter\n" );
665 if (!reader
|| !prefix
|| !ns
) return E_INVALIDARG
;
666 if (reader
->state
!= READER_STATE_STARTELEMENT
) return WS_E_INVALID_OPERATION
;
673 else if (WsXmlStringEquals( prefix
, &xml
, NULL
) == S_OK
)
678 else if (WsXmlStringEquals( prefix
, &xmlns
, NULL
) == S_OK
)
685 WS_XML_ELEMENT_NODE
*elem
= &reader
->current
->hdr
;
688 for (i
= 0; i
< elem
->attributeCount
; i
++)
690 if (!elem
->attributes
[i
]->isXmlNs
) continue;
691 if (WsXmlStringEquals( prefix
, elem
->attributes
[i
]->prefix
, NULL
) == S_OK
)
693 *ns
= elem
->attributes
[i
]->ns
;
702 if (required
) return WS_E_INVALID_FORMAT
;
709 /**************************************************************************
710 * WsGetReaderNode [webservices.@]
712 HRESULT WINAPI
WsGetReaderNode( WS_XML_READER
*handle
, const WS_XML_NODE
**node
,
715 struct reader
*reader
= (struct reader
*)handle
;
717 TRACE( "%p %p %p\n", handle
, node
, error
);
718 if (error
) FIXME( "ignoring error parameter\n" );
720 if (!reader
|| !node
) return E_INVALIDARG
;
722 *node
= &reader
->current
->hdr
.node
;
726 /**************************************************************************
727 * WsGetReaderProperty [webservices.@]
729 HRESULT WINAPI
WsGetReaderProperty( WS_XML_READER
*handle
, WS_XML_READER_PROPERTY_ID id
,
730 void *buf
, ULONG size
, WS_ERROR
*error
)
732 struct reader
*reader
= (struct reader
*)handle
;
734 TRACE( "%p %u %p %u %p\n", handle
, id
, buf
, size
, error
);
735 if (error
) FIXME( "ignoring error parameter\n" );
737 if (!reader
->input_type
) return WS_E_INVALID_OPERATION
;
739 if (id
== WS_XML_READER_PROPERTY_CHARSET
)
744 if ((hr
= prop_get( reader
->prop
, reader
->prop_count
, id
, &charset
, size
)) != S_OK
) return hr
;
745 if (!charset
) return WS_E_INVALID_FORMAT
;
746 *(WS_CHARSET
*)buf
= charset
;
749 return prop_get( reader
->prop
, reader
->prop_count
, id
, buf
, size
);
752 /**************************************************************************
753 * WsGetXmlAttribute [webservices.@]
755 HRESULT WINAPI
WsGetXmlAttribute( WS_XML_READER
*handle
, const WS_XML_STRING
*attr
,
756 WS_HEAP
*heap
, WCHAR
**str
, ULONG
*len
, WS_ERROR
*error
)
758 FIXME( "%p %s %p %p %p %p: stub\n", handle
, debugstr_xmlstr(attr
), heap
, str
, len
, error
);
762 WS_XML_STRING
*alloc_xml_string( const unsigned char *data
, ULONG len
)
766 if (!(ret
= heap_alloc( sizeof(*ret
) + len
))) return NULL
;
768 ret
->bytes
= len
? (BYTE
*)(ret
+ 1) : NULL
;
769 ret
->dictionary
= NULL
;
771 if (data
) memcpy( ret
->bytes
, data
, len
);
775 WS_XML_UTF8_TEXT
*alloc_utf8_text( const unsigned char *data
, ULONG len
)
777 WS_XML_UTF8_TEXT
*ret
;
779 if (!(ret
= heap_alloc( sizeof(*ret
) + len
))) return NULL
;
780 ret
->text
.textType
= WS_XML_TEXT_TYPE_UTF8
;
781 ret
->value
.length
= len
;
782 ret
->value
.bytes
= len
? (BYTE
*)(ret
+ 1) : NULL
;
783 ret
->value
.dictionary
= NULL
;
785 if (data
) memcpy( ret
->value
.bytes
, data
, len
);
789 static inline BOOL
read_end_of_data( struct reader
*reader
)
791 return reader
->read_pos
>= reader
->read_size
;
794 static inline const unsigned char *read_current_ptr( struct reader
*reader
)
796 return &reader
->read_bufptr
[reader
->read_pos
];
799 /* UTF-8 support based on libs/wine/utf8.c */
801 /* number of following bytes in sequence based on first byte value (for bytes above 0x7f) */
802 static const char utf8_length
[128] =
804 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x80-0x8f */
805 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x90-0x9f */
806 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xa0-0xaf */
807 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xb0-0xbf */
808 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0xc0-0xcf */
809 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0xd0-0xdf */
810 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, /* 0xe0-0xef */
811 3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0 /* 0xf0-0xff */
814 /* first byte mask depending on UTF-8 sequence length */
815 static const unsigned char utf8_mask
[4] = { 0x7f, 0x1f, 0x0f, 0x07 };
817 /* minimum Unicode value depending on UTF-8 sequence length */
818 static const unsigned int utf8_minval
[4] = { 0x0, 0x80, 0x800, 0x10000 };
820 static inline unsigned int read_utf8_char( struct reader
*reader
, unsigned int *skip
)
822 unsigned int len
, res
;
823 unsigned char ch
= reader
->read_bufptr
[reader
->read_pos
];
824 const unsigned char *end
;
826 if (reader
->read_pos
>= reader
->read_size
) return 0;
833 len
= utf8_length
[ch
- 0x80];
834 if (reader
->read_pos
+ len
>= reader
->read_size
) return 0;
835 end
= reader
->read_bufptr
+ reader
->read_pos
+ len
;
836 res
= ch
& utf8_mask
[len
];
841 if ((ch
= end
[-3] ^ 0x80) >= 0x40) break;
842 res
= (res
<< 6) | ch
;
844 if ((ch
= end
[-2] ^ 0x80) >= 0x40) break;
845 res
= (res
<< 6) | ch
;
847 if ((ch
= end
[-1] ^ 0x80) >= 0x40) break;
848 res
= (res
<< 6) | ch
;
849 if (res
< utf8_minval
[len
]) break;
857 static inline void read_skip( struct reader
*reader
, unsigned int count
)
859 if (reader
->read_pos
+ count
> reader
->read_size
) return;
860 reader
->read_pos
+= count
;
863 static inline void read_rewind( struct reader
*reader
, unsigned int count
)
865 reader
->read_pos
-= count
;
868 static inline BOOL
read_isnamechar( unsigned int ch
)
870 /* FIXME: incomplete */
871 return (ch
>= 'A' && ch
<= 'Z') ||
872 (ch
>= 'a' && ch
<= 'z') ||
873 (ch
>= '0' && ch
<= '9') ||
874 ch
== '_' || ch
== '-' || ch
== '.' || ch
== ':';
877 static inline BOOL
read_isspace( unsigned int ch
)
879 return ch
== ' ' || ch
== '\t' || ch
== '\r' || ch
== '\n';
882 static inline void read_skip_whitespace( struct reader
*reader
)
884 while (reader
->read_pos
< reader
->read_size
&& read_isspace( reader
->read_bufptr
[reader
->read_pos
] ))
888 static inline int read_cmp( struct reader
*reader
, const char *str
, int len
)
890 const unsigned char *ptr
= read_current_ptr( reader
);
892 if (len
< 0) len
= strlen( str
);
893 if (reader
->read_pos
+ len
> reader
->read_size
) return -1;
896 if (*str
!= *ptr
) return *ptr
- *str
;
902 static HRESULT
read_xmldecl( struct reader
*reader
)
904 if (!reader
->read_size
) return WS_E_INVALID_FORMAT
;
906 if (read_cmp( reader
, "<", 1 ) || read_cmp( reader
, "<?", 2 ))
908 reader
->state
= READER_STATE_BOF
;
911 if (read_cmp( reader
, "<?xml ", 6 )) return WS_E_INVALID_FORMAT
;
912 read_skip( reader
, 6 );
914 /* FIXME: parse attributes */
915 while (reader
->read_pos
< reader
->read_size
&& reader
->read_bufptr
[reader
->read_pos
] != '?')
918 if (read_cmp( reader
, "?>", 2 )) return WS_E_INVALID_FORMAT
;
919 read_skip( reader
, 2 );
921 reader
->state
= READER_STATE_BOF
;
925 HRESULT
append_attribute( WS_XML_ELEMENT_NODE
*elem
, WS_XML_ATTRIBUTE
*attr
)
927 if (elem
->attributeCount
)
929 WS_XML_ATTRIBUTE
**tmp
;
930 if (!(tmp
= heap_realloc( elem
->attributes
, (elem
->attributeCount
+ 1) * sizeof(attr
) )))
931 return E_OUTOFMEMORY
;
932 elem
->attributes
= tmp
;
934 else if (!(elem
->attributes
= heap_alloc( sizeof(attr
) ))) return E_OUTOFMEMORY
;
935 elem
->attributes
[elem
->attributeCount
++] = attr
;
939 static HRESULT
parse_name( const unsigned char *str
, unsigned int len
,
940 WS_XML_STRING
**prefix
, WS_XML_STRING
**localname
)
942 const unsigned char *name_ptr
= str
, *prefix_ptr
= NULL
;
943 unsigned int i
, name_len
= len
, prefix_len
= 0;
945 for (i
= 0; i
< len
; i
++)
951 name_ptr
= &str
[i
+ 1];
956 if (!(*prefix
= alloc_xml_string( prefix_ptr
, prefix_len
))) return E_OUTOFMEMORY
;
957 if (!(*localname
= alloc_xml_string( name_ptr
, name_len
)))
959 heap_free( *prefix
);
960 return E_OUTOFMEMORY
;
965 static HRESULT
read_attribute( struct reader
*reader
, WS_XML_ATTRIBUTE
**ret
)
967 static const WS_XML_STRING xmlns
= {5, (BYTE
*)"xmlns"};
968 WS_XML_ATTRIBUTE
*attr
;
969 WS_XML_UTF8_TEXT
*text
;
970 unsigned int len
= 0, ch
, skip
, quote
;
971 const unsigned char *start
;
972 WS_XML_STRING
*prefix
, *localname
;
973 HRESULT hr
= WS_E_INVALID_FORMAT
;
975 if (!(attr
= heap_alloc_zero( sizeof(*attr
) ))) return E_OUTOFMEMORY
;
977 start
= read_current_ptr( reader
);
980 if (!(ch
= read_utf8_char( reader
, &skip
))) goto error
;
981 if (!read_isnamechar( ch
)) break;
982 read_skip( reader
, skip
);
985 if (!len
) goto error
;
987 if ((hr
= parse_name( start
, len
, &prefix
, &localname
)) != S_OK
) goto error
;
989 if (WsXmlStringEquals( prefix
, &xmlns
, NULL
) == S_OK
)
993 if (!(attr
->prefix
= alloc_xml_string( localname
->bytes
, localname
->length
)))
995 heap_free( localname
);
998 attr
->localName
= localname
;
1000 else if (!prefix
->length
&& WsXmlStringEquals( localname
, &xmlns
, NULL
) == S_OK
)
1003 attr
->prefix
= prefix
;
1004 attr
->localName
= localname
;
1008 attr
->prefix
= prefix
;
1009 attr
->localName
= localname
;
1012 hr
= WS_E_INVALID_FORMAT
;
1013 read_skip_whitespace( reader
);
1014 if (read_cmp( reader
, "=", 1 )) goto error
;
1015 read_skip( reader
, 1 );
1017 read_skip_whitespace( reader
);
1018 if (read_cmp( reader
, "\"", 1 ) && read_cmp( reader
, "'", 1 )) goto error
;
1019 quote
= read_utf8_char( reader
, &skip
);
1020 read_skip( reader
, 1 );
1023 start
= read_current_ptr( reader
);
1026 if (!(ch
= read_utf8_char( reader
, &skip
))) goto error
;
1027 if (ch
== quote
) break;
1028 read_skip( reader
, skip
);
1031 read_skip( reader
, 1 );
1036 if (!(attr
->ns
= alloc_xml_string( start
, len
))) goto error
;
1037 if ((hr
= bind_prefix( reader
, attr
->prefix
, attr
->ns
)) != S_OK
) goto error
;
1038 if (!(text
= alloc_utf8_text( NULL
, 0 ))) goto error
;
1040 else if (!(text
= alloc_utf8_text( start
, len
))) goto error
;
1042 attr
->value
= &text
->text
;
1043 attr
->singleQuote
= (quote
== '\'');
1049 free_attribute( attr
);
1053 static int cmp_name( const unsigned char *name1
, ULONG len1
, const unsigned char *name2
, ULONG len2
)
1056 if (len1
!= len2
) return 1;
1057 for (i
= 0; i
< len1
; i
++) { if (toupper( name1
[i
] ) != toupper( name2
[i
] )) return 1; }
1061 static struct node
*read_find_parent( struct reader
*reader
, const WS_XML_STRING
*prefix
,
1062 const WS_XML_STRING
*localname
)
1064 struct node
*parent
;
1065 const WS_XML_STRING
*str
;
1067 for (parent
= reader
->current
; parent
; parent
= parent
->parent
)
1069 if (node_type( parent
) == WS_XML_NODE_TYPE_BOF
)
1071 if (!localname
) return parent
;
1074 else if (node_type( parent
) == WS_XML_NODE_TYPE_ELEMENT
)
1076 if (!localname
) return parent
;
1078 str
= parent
->hdr
.prefix
;
1079 if (cmp_name( str
->bytes
, str
->length
, prefix
->bytes
, prefix
->length
)) continue;
1080 str
= parent
->hdr
.localName
;
1081 if (cmp_name( str
->bytes
, str
->length
, localname
->bytes
, localname
->length
)) continue;
1089 static HRESULT
set_namespaces( struct reader
*reader
, WS_XML_ELEMENT_NODE
*elem
)
1091 static const WS_XML_STRING xml
= {3, (BYTE
*)"xml"};
1092 const WS_XML_STRING
*ns
;
1095 if (!(ns
= get_namespace( reader
, elem
->prefix
))) return WS_E_INVALID_FORMAT
;
1096 if (!(elem
->ns
= alloc_xml_string( ns
->bytes
, ns
->length
))) return E_OUTOFMEMORY
;
1097 if (!elem
->ns
->length
) elem
->ns
->bytes
= (BYTE
*)(elem
->ns
+ 1); /* quirk */
1099 for (i
= 0; i
< elem
->attributeCount
; i
++)
1101 WS_XML_ATTRIBUTE
*attr
= elem
->attributes
[i
];
1102 if (attr
->isXmlNs
|| WsXmlStringEquals( attr
->prefix
, &xml
, NULL
) == S_OK
) continue;
1103 if (!(ns
= get_namespace( reader
, attr
->prefix
))) return WS_E_INVALID_FORMAT
;
1104 if (!(attr
->ns
= alloc_xml_string( ns
->bytes
, ns
->length
))) return E_OUTOFMEMORY
;
1109 static HRESULT
read_element( struct reader
*reader
)
1111 unsigned int len
= 0, ch
, skip
;
1112 const unsigned char *start
;
1113 struct node
*node
= NULL
, *parent
;
1114 WS_XML_ELEMENT_NODE
*elem
;
1115 WS_XML_ATTRIBUTE
*attr
= NULL
;
1116 HRESULT hr
= WS_E_INVALID_FORMAT
;
1118 if (read_end_of_data( reader
))
1120 struct list
*eof
= list_tail( &reader
->root
->children
);
1121 reader
->current
= LIST_ENTRY( eof
, struct node
, entry
);
1122 reader
->state
= READER_STATE_EOF
;
1126 if (read_cmp( reader
, "<", 1 )) goto error
;
1127 read_skip( reader
, 1 );
1128 if (!read_isnamechar( read_utf8_char( reader
, &skip
)))
1130 read_rewind( reader
, 1 );
1134 start
= read_current_ptr( reader
);
1137 if (!(ch
= read_utf8_char( reader
, &skip
))) goto error
;
1138 if (!read_isnamechar( ch
)) break;
1139 read_skip( reader
, skip
);
1142 if (!len
) goto error
;
1144 if (!(parent
= read_find_parent( reader
, NULL
, NULL
))) goto error
;
1147 if (!(node
= alloc_node( WS_XML_NODE_TYPE_ELEMENT
))) goto error
;
1148 elem
= (WS_XML_ELEMENT_NODE
*)node
;
1149 if ((hr
= parse_name( start
, len
, &elem
->prefix
, &elem
->localName
)) != S_OK
) goto error
;
1151 reader
->current_attr
= 0;
1154 read_skip_whitespace( reader
);
1155 if (!read_cmp( reader
, ">", 1 ) || !read_cmp( reader
, "/>", 2 )) break;
1156 if ((hr
= read_attribute( reader
, &attr
)) != S_OK
) goto error
;
1157 if ((hr
= append_attribute( elem
, attr
)) != S_OK
)
1159 free_attribute( attr
);
1162 reader
->current_attr
++;
1164 if ((hr
= set_namespaces( reader
, elem
)) != S_OK
) goto error
;
1166 read_insert_node( reader
, parent
, node
);
1167 reader
->state
= READER_STATE_STARTELEMENT
;
1175 static HRESULT
read_text( struct reader
*reader
)
1177 unsigned int len
= 0, ch
, skip
;
1178 const unsigned char *start
;
1180 WS_XML_TEXT_NODE
*text
;
1181 WS_XML_UTF8_TEXT
*utf8
;
1183 start
= read_current_ptr( reader
);
1186 if (read_end_of_data( reader
)) break;
1187 if (!(ch
= read_utf8_char( reader
, &skip
))) return WS_E_INVALID_FORMAT
;
1188 if (ch
== '<') break;
1189 read_skip( reader
, skip
);
1193 if (!(node
= alloc_node( WS_XML_NODE_TYPE_TEXT
))) return E_OUTOFMEMORY
;
1194 text
= (WS_XML_TEXT_NODE
*)node
;
1195 if (!(utf8
= alloc_utf8_text( start
, len
)))
1198 return E_OUTOFMEMORY
;
1200 text
->text
= &utf8
->text
;
1202 read_insert_node( reader
, reader
->current
, node
);
1203 reader
->state
= READER_STATE_TEXT
;
1207 static HRESULT
read_node( struct reader
* );
1209 static HRESULT
read_startelement( struct reader
*reader
)
1213 read_skip_whitespace( reader
);
1214 if (!read_cmp( reader
, "/>", 2 ))
1216 read_skip( reader
, 2 );
1217 if (!(node
= alloc_node( WS_XML_NODE_TYPE_END_ELEMENT
))) return E_OUTOFMEMORY
;
1218 read_insert_node( reader
, reader
->current
, node
);
1219 reader
->state
= READER_STATE_ENDELEMENT
;
1222 else if (!read_cmp( reader
, ">", 1 ))
1224 read_skip( reader
, 1 );
1225 return read_node( reader
);
1227 return WS_E_INVALID_FORMAT
;
1230 static HRESULT
read_to_startelement( struct reader
*reader
, BOOL
*found
)
1234 switch (reader
->state
)
1236 case READER_STATE_INITIAL
:
1237 if ((hr
= read_xmldecl( reader
)) != S_OK
) return hr
;
1240 case READER_STATE_STARTELEMENT
:
1241 if (found
) *found
= TRUE
;
1248 read_skip_whitespace( reader
);
1249 if ((hr
= read_element( reader
)) == S_OK
&& found
)
1251 if (reader
->state
== READER_STATE_STARTELEMENT
)
1260 static HRESULT
read_endelement( struct reader
*reader
)
1262 struct node
*node
, *parent
;
1263 unsigned int len
= 0, ch
, skip
;
1264 const unsigned char *start
;
1265 WS_XML_STRING
*prefix
, *localname
;
1268 if (reader
->state
== READER_STATE_EOF
) return WS_E_INVALID_FORMAT
;
1270 if (read_end_of_data( reader
))
1272 struct list
*eof
= list_tail( &reader
->root
->children
);
1273 reader
->current
= LIST_ENTRY( eof
, struct node
, entry
);
1274 reader
->state
= READER_STATE_EOF
;
1278 if (read_cmp( reader
, "</", 2 )) return WS_E_INVALID_FORMAT
;
1279 read_skip( reader
, 2 );
1281 start
= read_current_ptr( reader
);
1284 if (!(ch
= read_utf8_char( reader
, &skip
))) return WS_E_INVALID_FORMAT
;
1287 read_skip( reader
, 1 );
1290 if (!read_isnamechar( ch
)) return WS_E_INVALID_FORMAT
;
1291 read_skip( reader
, skip
);
1295 if ((hr
= parse_name( start
, len
, &prefix
, &localname
)) != S_OK
) return hr
;
1296 parent
= read_find_parent( reader
, prefix
, localname
);
1297 heap_free( prefix
);
1298 heap_free( localname
);
1299 if (!parent
) return WS_E_INVALID_FORMAT
;
1301 if (!(node
= alloc_node( WS_XML_NODE_TYPE_END_ELEMENT
))) return E_OUTOFMEMORY
;
1302 read_insert_node( reader
, parent
, node
);
1303 reader
->state
= READER_STATE_ENDELEMENT
;
1307 static HRESULT
read_comment( struct reader
*reader
)
1309 unsigned int len
= 0, ch
, skip
;
1310 const unsigned char *start
;
1312 WS_XML_COMMENT_NODE
*comment
;
1314 if (read_cmp( reader
, "<!--", 4 )) return WS_E_INVALID_FORMAT
;
1315 read_skip( reader
, 4 );
1317 start
= read_current_ptr( reader
);
1320 if (!read_cmp( reader
, "-->", 3 ))
1322 read_skip( reader
, 3 );
1325 if (!(ch
= read_utf8_char( reader
, &skip
))) return WS_E_INVALID_FORMAT
;
1326 read_skip( reader
, skip
);
1330 if (!(node
= alloc_node( WS_XML_NODE_TYPE_COMMENT
))) return E_OUTOFMEMORY
;
1331 comment
= (WS_XML_COMMENT_NODE
*)node
;
1332 if (!(comment
->value
.bytes
= heap_alloc( len
)))
1335 return E_OUTOFMEMORY
;
1337 memcpy( comment
->value
.bytes
, start
, len
);
1338 comment
->value
.length
= len
;
1340 read_insert_node( reader
, reader
->current
, node
);
1341 reader
->state
= READER_STATE_COMMENT
;
1345 static HRESULT
read_startcdata( struct reader
*reader
)
1349 if (read_cmp( reader
, "<![CDATA[", 9 )) return WS_E_INVALID_FORMAT
;
1350 read_skip( reader
, 9 );
1352 if (!(node
= alloc_node( WS_XML_NODE_TYPE_CDATA
))) return E_OUTOFMEMORY
;
1353 read_insert_node( reader
, reader
->current
, node
);
1354 reader
->state
= READER_STATE_STARTCDATA
;
1358 static HRESULT
read_cdata( struct reader
*reader
)
1360 unsigned int len
= 0, ch
, skip
;
1361 const unsigned char *start
;
1363 WS_XML_TEXT_NODE
*text
;
1364 WS_XML_UTF8_TEXT
*utf8
;
1366 start
= read_current_ptr( reader
);
1369 if (!read_cmp( reader
, "]]>", 3 )) break;
1370 if (!(ch
= read_utf8_char( reader
, &skip
))) return WS_E_INVALID_FORMAT
;
1371 read_skip( reader
, skip
);
1375 if (!(node
= alloc_node( WS_XML_NODE_TYPE_TEXT
))) return E_OUTOFMEMORY
;
1376 text
= (WS_XML_TEXT_NODE
*)node
;
1377 if (!(utf8
= alloc_utf8_text( start
, len
)))
1380 return E_OUTOFMEMORY
;
1382 text
->text
= &utf8
->text
;
1384 read_insert_node( reader
, reader
->current
, node
);
1385 reader
->state
= READER_STATE_CDATA
;
1389 static HRESULT
read_endcdata( struct reader
*reader
)
1393 if (read_cmp( reader
, "]]>", 3 )) return WS_E_INVALID_FORMAT
;
1394 read_skip( reader
, 3 );
1396 if (!(node
= alloc_node( WS_XML_NODE_TYPE_END_CDATA
))) return E_OUTOFMEMORY
;
1397 read_insert_node( reader
, reader
->current
->parent
, node
);
1398 reader
->state
= READER_STATE_ENDCDATA
;
1402 static HRESULT
read_node( struct reader
*reader
)
1408 if (read_end_of_data( reader
))
1410 struct list
*eof
= list_tail( &reader
->root
->children
);
1411 reader
->current
= LIST_ENTRY( eof
, struct node
, entry
);
1412 reader
->state
= READER_STATE_EOF
;
1415 if (reader
->state
== READER_STATE_STARTCDATA
) return read_cdata( reader
);
1416 else if (reader
->state
== READER_STATE_CDATA
) return read_endcdata( reader
);
1417 else if (!read_cmp( reader
, "<?", 2 ))
1419 hr
= read_xmldecl( reader
);
1420 if (FAILED( hr
)) return hr
;
1422 else if (!read_cmp( reader
, "</", 2 )) return read_endelement( reader
);
1423 else if (!read_cmp( reader
, "<![CDATA[", 9 )) return read_startcdata( reader
);
1424 else if (!read_cmp( reader
, "<!--", 4 )) return read_comment( reader
);
1425 else if (!read_cmp( reader
, "<", 1 )) return read_element( reader
);
1426 else if (!read_cmp( reader
, "/>", 2 ) || !read_cmp( reader
, ">", 1 )) return read_startelement( reader
);
1427 else return read_text( reader
);
1431 /**************************************************************************
1432 * WsReadEndElement [webservices.@]
1434 HRESULT WINAPI
WsReadEndElement( WS_XML_READER
*handle
, WS_ERROR
*error
)
1436 struct reader
*reader
= (struct reader
*)handle
;
1438 TRACE( "%p %p\n", handle
, error
);
1439 if (error
) FIXME( "ignoring error parameter\n" );
1441 if (!reader
) return E_INVALIDARG
;
1442 return read_endelement( reader
);
1445 /**************************************************************************
1446 * WsReadNode [webservices.@]
1448 HRESULT WINAPI
WsReadNode( WS_XML_READER
*handle
, WS_ERROR
*error
)
1450 struct reader
*reader
= (struct reader
*)handle
;
1452 TRACE( "%p %p\n", handle
, error
);
1453 if (error
) FIXME( "ignoring error parameter\n" );
1455 if (!reader
) return E_INVALIDARG
;
1456 return read_node( reader
);
1459 /**************************************************************************
1460 * WsReadStartElement [webservices.@]
1462 HRESULT WINAPI
WsReadStartElement( WS_XML_READER
*handle
, WS_ERROR
*error
)
1464 struct reader
*reader
= (struct reader
*)handle
;
1466 TRACE( "%p %p\n", handle
, error
);
1467 if (error
) FIXME( "ignoring error parameter\n" );
1469 if (!reader
) return E_INVALIDARG
;
1470 return read_startelement( reader
);
1473 /**************************************************************************
1474 * WsReadToStartElement [webservices.@]
1476 HRESULT WINAPI
WsReadToStartElement( WS_XML_READER
*handle
, const WS_XML_STRING
*localname
,
1477 const WS_XML_STRING
*ns
, BOOL
*found
, WS_ERROR
*error
)
1479 struct reader
*reader
= (struct reader
*)handle
;
1481 TRACE( "%p %s %s %p %p\n", handle
, debugstr_xmlstr(localname
), debugstr_xmlstr(ns
), found
, error
);
1482 if (error
) FIXME( "ignoring error parameter\n" );
1484 if (!reader
) return E_INVALIDARG
;
1485 if (localname
|| ns
) FIXME( "name and/or namespace not verified\n" );
1487 return read_to_startelement( reader
, found
);
1490 static BOOL
move_to_root_element( struct reader
*reader
)
1495 if (!(ptr
= list_head( &reader
->root
->children
))) return FALSE
;
1496 node
= LIST_ENTRY( ptr
, struct node
, entry
);
1497 if (node_type( node
) == WS_XML_NODE_TYPE_ELEMENT
)
1499 reader
->current
= node
;
1502 while ((ptr
= list_next( &reader
->root
->children
, &node
->entry
)))
1504 struct node
*next
= LIST_ENTRY( ptr
, struct node
, entry
);
1505 if (node_type( next
) == WS_XML_NODE_TYPE_ELEMENT
)
1507 reader
->current
= next
;
1515 static BOOL
move_to_next_element( struct reader
*reader
)
1518 struct node
*node
= reader
->current
;
1520 while ((ptr
= list_next( &node
->parent
->children
, &node
->entry
)))
1522 struct node
*next
= LIST_ENTRY( ptr
, struct node
, entry
);
1523 if (node_type( next
) == WS_XML_NODE_TYPE_ELEMENT
)
1525 reader
->current
= next
;
1533 static BOOL
move_to_prev_element( struct reader
*reader
)
1536 struct node
*node
= reader
->current
;
1538 while ((ptr
= list_prev( &node
->parent
->children
, &node
->entry
)))
1540 struct node
*prev
= LIST_ENTRY( ptr
, struct node
, entry
);
1541 if (node_type( prev
) == WS_XML_NODE_TYPE_ELEMENT
)
1543 reader
->current
= prev
;
1551 static BOOL
move_to_child_element( struct reader
*reader
)
1556 if (!(ptr
= list_head( &reader
->current
->children
))) return FALSE
;
1557 node
= LIST_ENTRY( ptr
, struct node
, entry
);
1558 if (node_type( node
) == WS_XML_NODE_TYPE_ELEMENT
)
1560 reader
->current
= node
;
1563 while ((ptr
= list_next( &reader
->current
->children
, &node
->entry
)))
1565 struct node
*next
= LIST_ENTRY( ptr
, struct node
, entry
);
1566 if (node_type( next
) == WS_XML_NODE_TYPE_ELEMENT
)
1568 reader
->current
= next
;
1576 static BOOL
move_to_end_element( struct reader
*reader
)
1579 struct node
*node
= reader
->current
;
1581 if (node_type( node
) != WS_XML_NODE_TYPE_ELEMENT
) return FALSE
;
1583 if ((ptr
= list_tail( &node
->children
)))
1585 struct node
*tail
= LIST_ENTRY( ptr
, struct node
, entry
);
1586 if (node_type( tail
) == WS_XML_NODE_TYPE_END_ELEMENT
)
1588 reader
->current
= tail
;
1595 static BOOL
move_to_parent_element( struct reader
*reader
)
1597 struct node
*parent
= reader
->current
->parent
;
1599 if (parent
&& (node_type( parent
) == WS_XML_NODE_TYPE_ELEMENT
||
1600 node_type( parent
) == WS_XML_NODE_TYPE_BOF
))
1602 reader
->current
= parent
;
1608 static HRESULT
read_move_to( struct reader
*reader
, WS_MOVE_TO move
, BOOL
*found
)
1611 BOOL success
= FALSE
;
1614 if (!read_end_of_data( reader
))
1616 while (reader
->state
!= READER_STATE_EOF
&& (hr
= read_node( reader
)) == S_OK
) { /* nothing */ };
1617 if (hr
!= S_OK
) return hr
;
1621 case WS_MOVE_TO_ROOT_ELEMENT
:
1622 success
= move_to_root_element( reader
);
1625 case WS_MOVE_TO_NEXT_ELEMENT
:
1626 success
= move_to_next_element( reader
);
1629 case WS_MOVE_TO_PREVIOUS_ELEMENT
:
1630 success
= move_to_prev_element( reader
);
1633 case WS_MOVE_TO_CHILD_ELEMENT
:
1634 success
= move_to_child_element( reader
);
1637 case WS_MOVE_TO_END_ELEMENT
:
1638 success
= move_to_end_element( reader
);
1641 case WS_MOVE_TO_PARENT_ELEMENT
:
1642 success
= move_to_parent_element( reader
);
1645 case WS_MOVE_TO_FIRST_NODE
:
1646 if ((ptr
= list_head( &reader
->current
->parent
->children
)))
1648 reader
->current
= LIST_ENTRY( ptr
, struct node
, entry
);
1653 case WS_MOVE_TO_NEXT_NODE
:
1654 if ((ptr
= list_next( &reader
->current
->parent
->children
, &reader
->current
->entry
)))
1656 reader
->current
= LIST_ENTRY( ptr
, struct node
, entry
);
1661 case WS_MOVE_TO_PREVIOUS_NODE
:
1662 if ((ptr
= list_prev( &reader
->current
->parent
->children
, &reader
->current
->entry
)))
1664 reader
->current
= LIST_ENTRY( ptr
, struct node
, entry
);
1669 case WS_MOVE_TO_CHILD_NODE
:
1670 if ((ptr
= list_head( &reader
->current
->children
)))
1672 reader
->current
= LIST_ENTRY( ptr
, struct node
, entry
);
1677 case WS_MOVE_TO_BOF
:
1678 reader
->current
= reader
->root
;
1682 case WS_MOVE_TO_EOF
:
1683 if ((ptr
= list_tail( &reader
->root
->children
)))
1685 reader
->current
= LIST_ENTRY( ptr
, struct node
, entry
);
1691 FIXME( "unhandled move %u\n", move
);
1700 return success
? S_OK
: WS_E_INVALID_FORMAT
;
1703 /**************************************************************************
1704 * WsMoveReader [webservices.@]
1706 HRESULT WINAPI
WsMoveReader( WS_XML_READER
*handle
, WS_MOVE_TO move
, BOOL
*found
, WS_ERROR
*error
)
1708 struct reader
*reader
= (struct reader
*)handle
;
1710 TRACE( "%p %u %p %p\n", handle
, move
, found
, error
);
1711 if (error
) FIXME( "ignoring error parameter\n" );
1713 if (!reader
) return E_INVALIDARG
;
1714 if (!reader
->input_type
) return WS_E_INVALID_OPERATION
;
1716 return read_move_to( reader
, move
, found
);
1719 /**************************************************************************
1720 * WsReadStartAttribute [webservices.@]
1722 HRESULT WINAPI
WsReadStartAttribute( WS_XML_READER
*handle
, ULONG index
, WS_ERROR
*error
)
1724 struct reader
*reader
= (struct reader
*)handle
;
1725 WS_XML_ELEMENT_NODE
*elem
;
1727 TRACE( "%p %u %p\n", handle
, index
, error
);
1728 if (error
) FIXME( "ignoring error parameter\n" );
1730 if (!reader
) return E_INVALIDARG
;
1732 elem
= &reader
->current
->hdr
;
1733 if (reader
->state
!= READER_STATE_STARTELEMENT
|| index
>= elem
->attributeCount
)
1734 return WS_E_INVALID_FORMAT
;
1736 reader
->current_attr
= index
;
1737 reader
->state
= READER_STATE_STARTATTRIBUTE
;
1741 /**************************************************************************
1742 * WsReadEndAttribute [webservices.@]
1744 HRESULT WINAPI
WsReadEndAttribute( WS_XML_READER
*handle
, WS_ERROR
*error
)
1746 struct reader
*reader
= (struct reader
*)handle
;
1748 TRACE( "%p %p\n", handle
, error
);
1749 if (error
) FIXME( "ignoring error parameter\n" );
1751 if (!reader
) return E_INVALIDARG
;
1753 if (reader
->state
!= READER_STATE_STARTATTRIBUTE
)
1754 return WS_E_INVALID_FORMAT
;
1756 reader
->state
= READER_STATE_STARTELEMENT
;
1760 static WCHAR
*xmltext_to_widechar( WS_HEAP
*heap
, const WS_XML_TEXT
*text
)
1764 switch (text
->textType
)
1766 case WS_XML_TEXT_TYPE_UTF8
:
1768 const WS_XML_UTF8_TEXT
*utf8
= (const WS_XML_UTF8_TEXT
*)text
;
1769 int len
= MultiByteToWideChar( CP_UTF8
, 0, (char *)utf8
->value
.bytes
, utf8
->value
.length
, NULL
, 0 );
1770 if (!(ret
= ws_alloc( heap
, (len
+ 1) * sizeof(WCHAR
) ))) return NULL
;
1771 MultiByteToWideChar( CP_UTF8
, 0, (char *)utf8
->value
.bytes
, utf8
->value
.length
, ret
, len
);
1776 FIXME( "unhandled type %u\n", text
->textType
);
1783 #define MAX_INT8 0x7f
1784 #define MIN_INT8 (-MAX_INT8 - 1)
1785 #define MAX_INT16 0x7fff
1786 #define MIN_INT16 (-MAX_INT16 - 1)
1787 #define MAX_INT32 0x7fffffff
1788 #define MIN_INT32 (-MAX_INT32 - 1)
1789 #define MAX_INT64 (((INT64)0x7fffffff << 32) | 0xffffffff)
1790 #define MIN_INT64 (-MAX_INT64 - 1)
1791 #define MAX_UINT8 0xff
1792 #define MAX_UINT16 0xffff
1793 #define MAX_UINT32 0xffffffff
1794 #define MAX_UINT64 (((UINT64)0xffffffff << 32) | 0xffffffff)
1796 static HRESULT
str_to_int64( const unsigned char *str
, ULONG len
, INT64 min
, INT64 max
, INT64
*ret
)
1798 BOOL negative
= FALSE
;
1799 const unsigned char *ptr
= str
;
1802 while (len
&& read_isspace( *ptr
)) { ptr
++; len
--; }
1803 while (len
&& read_isspace( ptr
[len
- 1] )) { len
--; }
1804 if (!len
) return WS_E_INVALID_FORMAT
;
1812 if (!len
) return WS_E_INVALID_FORMAT
;
1818 if (!isdigit( *ptr
)) return WS_E_INVALID_FORMAT
;
1820 if (negative
) val
= -val
;
1822 if ((!negative
&& (*ret
> max
/ 10 || *ret
* 10 > max
- val
)) ||
1823 (negative
&& (*ret
< min
/ 10 || *ret
* 10 < min
- val
)))
1825 return WS_E_NUMERIC_OVERFLOW
;
1827 *ret
= *ret
* 10 + val
;
1834 static HRESULT
str_to_uint64( const unsigned char *str
, ULONG len
, UINT64 max
, UINT64
*ret
)
1836 const unsigned char *ptr
= str
;
1839 while (len
&& read_isspace( *ptr
)) { ptr
++; len
--; }
1840 while (len
&& read_isspace( ptr
[len
- 1] )) { len
--; }
1841 if (!len
) return WS_E_INVALID_FORMAT
;
1847 if (!isdigit( *ptr
)) return WS_E_INVALID_FORMAT
;
1850 if ((*ret
> max
/ 10 || *ret
* 10 > max
- val
)) return WS_E_NUMERIC_OVERFLOW
;
1851 *ret
= *ret
* 10 + val
;
1858 static HRESULT
read_get_node_text( struct reader
*reader
, WS_XML_UTF8_TEXT
**ret
)
1860 WS_XML_TEXT_NODE
*text
;
1862 if (node_type( reader
->current
) != WS_XML_NODE_TYPE_TEXT
)
1863 return WS_E_INVALID_FORMAT
;
1865 text
= (WS_XML_TEXT_NODE
*)&reader
->current
->hdr
.node
;
1866 if (text
->text
->textType
!= WS_XML_TEXT_TYPE_UTF8
)
1868 FIXME( "text type %u not supported\n", text
->text
->textType
);
1871 *ret
= (WS_XML_UTF8_TEXT
*)text
->text
;
1875 static HRESULT
read_get_attribute_text( struct reader
*reader
, ULONG index
, WS_XML_UTF8_TEXT
**ret
)
1877 WS_XML_ELEMENT_NODE
*elem
= &reader
->current
->hdr
;
1878 WS_XML_ATTRIBUTE
*attr
;
1880 if (node_type( reader
->current
) != WS_XML_NODE_TYPE_ELEMENT
)
1881 return WS_E_INVALID_FORMAT
;
1883 attr
= elem
->attributes
[index
];
1884 if (attr
->value
->textType
!= WS_XML_TEXT_TYPE_UTF8
)
1886 FIXME( "text type %u not supported\n", attr
->value
->textType
);
1889 *ret
= (WS_XML_UTF8_TEXT
*)attr
->value
;
1893 static BOOL
find_attribute( struct reader
*reader
, const WS_XML_STRING
*localname
,
1894 const WS_XML_STRING
*ns
, ULONG
*index
)
1897 WS_XML_ELEMENT_NODE
*elem
= &reader
->current
->hdr
;
1901 *index
= reader
->current_attr
;
1904 for (i
= 0; i
< elem
->attributeCount
; i
++)
1906 const WS_XML_STRING
*localname2
= elem
->attributes
[i
]->localName
;
1907 const WS_XML_STRING
*ns2
= elem
->attributes
[i
]->ns
;
1909 if (!cmp_name( localname
->bytes
, localname
->length
, localname2
->bytes
, localname2
->length
) &&
1910 !cmp_name( ns
->bytes
, ns
->length
, ns2
->bytes
, ns2
->length
))
1919 /**************************************************************************
1920 * WsFindAttribute [webservices.@]
1922 HRESULT WINAPI
WsFindAttribute( WS_XML_READER
*handle
, const WS_XML_STRING
*localname
,
1923 const WS_XML_STRING
*ns
, BOOL required
, ULONG
*index
,
1926 struct reader
*reader
= (struct reader
*)handle
;
1928 TRACE( "%p %s %s %d %p %p\n", handle
, debugstr_xmlstr(localname
), debugstr_xmlstr(ns
),
1929 required
, index
, error
);
1930 if (error
) FIXME( "ignoring error parameter\n" );
1932 if (!reader
|| !localname
|| !ns
|| !index
) return E_INVALIDARG
;
1934 if (node_type( reader
->current
) != WS_XML_NODE_TYPE_ELEMENT
)
1935 return WS_E_INVALID_OPERATION
;
1937 if (!find_attribute( reader
, localname
, ns
, index
))
1939 if (required
) return WS_E_INVALID_FORMAT
;
1946 static HRESULT
read_get_text( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
1947 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
,
1948 WS_XML_UTF8_TEXT
**ret
, BOOL
*found
)
1952 case WS_ATTRIBUTE_TYPE_MAPPING
:
1955 if (!(*found
= find_attribute( reader
, localname
, ns
, &index
))) return S_OK
;
1956 return read_get_attribute_text( reader
, index
, ret
);
1958 case WS_ELEMENT_TYPE_MAPPING
:
1959 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
1960 case WS_ANY_ELEMENT_TYPE_MAPPING
:
1966 const WS_XML_ELEMENT_NODE
*elem
= &reader
->current
->hdr
;
1968 if (WsXmlStringEquals( localname
, elem
->localName
, NULL
) != S_OK
||
1969 WsXmlStringEquals( ns
, elem
->ns
, NULL
) != S_OK
)
1974 if ((hr
= read_startelement( reader
)) != S_OK
) return hr
;
1976 return read_get_node_text( reader
, ret
);
1979 FIXME( "mapping %u not supported\n", mapping
);
1984 static HRESULT
read_type_bool( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
1985 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
,
1986 const WS_BOOL_DESCRIPTION
*desc
, WS_READ_OPTION option
,
1987 WS_HEAP
*heap
, void *ret
, ULONG size
)
1989 WS_XML_UTF8_TEXT
*utf8
;
1991 BOOL found
, val
= FALSE
;
1995 FIXME( "description not supported\n" );
1998 if ((hr
= read_get_text( reader
, mapping
, localname
, ns
, &utf8
, &found
)) != S_OK
) return hr
;
2001 ULONG len
= utf8
->value
.length
;
2002 if (len
== 4 && !memcmp( utf8
->value
.bytes
, "true", 4 )) val
= TRUE
;
2003 else if (len
== 1 && !memcmp( utf8
->value
.bytes
, "1", 1 )) val
= TRUE
;
2004 else if (len
== 5 && !memcmp( utf8
->value
.bytes
, "false", 5 )) val
= FALSE
;
2005 else if (len
== 1 && !memcmp( utf8
->value
.bytes
, "0", 1 )) val
= FALSE
;
2006 else return WS_E_INVALID_FORMAT
;
2011 case WS_READ_REQUIRED_VALUE
:
2012 if (!found
) return WS_E_INVALID_FORMAT
;
2013 if (size
!= sizeof(BOOL
)) return E_INVALIDARG
;
2017 case WS_READ_REQUIRED_POINTER
:
2018 if (!found
) return WS_E_INVALID_FORMAT
;
2021 case WS_READ_OPTIONAL_POINTER
:
2023 BOOL
*heap_val
= NULL
;
2024 if (size
!= sizeof(heap_val
)) return E_INVALIDARG
;
2027 if (!(heap_val
= ws_alloc( heap
, sizeof(*heap_val
) ))) return WS_E_QUOTA_EXCEEDED
;
2030 *(BOOL
**)ret
= heap_val
;
2034 FIXME( "read option %u not supported\n", option
);
2041 static HRESULT
read_type_int8( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2042 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
,
2043 const WS_INT8_DESCRIPTION
*desc
, WS_READ_OPTION option
,
2044 WS_HEAP
*heap
, void *ret
, ULONG size
)
2046 WS_XML_UTF8_TEXT
*utf8
;
2053 FIXME( "description not supported\n" );
2056 if ((hr
= read_get_text( reader
, mapping
, localname
, ns
, &utf8
, &found
)) != S_OK
) return hr
;
2057 if (found
&& (hr
= str_to_int64( utf8
->value
.bytes
, utf8
->value
.length
, MIN_INT8
, MAX_INT8
, &val
)) != S_OK
)
2062 case WS_READ_REQUIRED_VALUE
:
2063 if (!found
) return WS_E_INVALID_FORMAT
;
2064 if (size
!= sizeof(INT8
)) return E_INVALIDARG
;
2068 case WS_READ_REQUIRED_POINTER
:
2069 if (!found
) return WS_E_INVALID_FORMAT
;
2072 case WS_READ_OPTIONAL_POINTER
:
2074 INT8
*heap_val
= NULL
;
2075 if (size
!= sizeof(heap_val
)) return E_INVALIDARG
;
2078 if (!(heap_val
= ws_alloc( heap
, sizeof(*heap_val
) ))) return WS_E_QUOTA_EXCEEDED
;
2081 *(INT8
**)ret
= heap_val
;
2085 FIXME( "read option %u not supported\n", option
);
2092 static HRESULT
read_type_int16( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2093 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
,
2094 const WS_INT16_DESCRIPTION
*desc
, WS_READ_OPTION option
,
2095 WS_HEAP
*heap
, void *ret
, ULONG size
)
2097 WS_XML_UTF8_TEXT
*utf8
;
2104 FIXME( "description not supported\n" );
2107 if ((hr
= read_get_text( reader
, mapping
, localname
, ns
, &utf8
, &found
)) != S_OK
) return hr
;
2108 if (found
&& (hr
= str_to_int64( utf8
->value
.bytes
, utf8
->value
.length
, MIN_INT16
, MAX_INT16
, &val
)) != S_OK
)
2113 case WS_READ_REQUIRED_VALUE
:
2114 if (!found
) return WS_E_INVALID_FORMAT
;
2115 if (size
!= sizeof(INT16
)) return E_INVALIDARG
;
2116 *(INT16
*)ret
= val
;
2119 case WS_READ_REQUIRED_POINTER
:
2120 if (!found
) return WS_E_INVALID_FORMAT
;
2123 case WS_READ_OPTIONAL_POINTER
:
2125 INT16
*heap_val
= NULL
;
2126 if (size
!= sizeof(heap_val
)) return E_INVALIDARG
;
2129 if (!(heap_val
= ws_alloc( heap
, sizeof(*heap_val
) ))) return WS_E_QUOTA_EXCEEDED
;
2132 *(INT16
**)ret
= heap_val
;
2136 FIXME( "read option %u not supported\n", option
);
2143 static HRESULT
read_type_int32( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2144 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
,
2145 const WS_INT32_DESCRIPTION
*desc
, WS_READ_OPTION option
,
2146 WS_HEAP
*heap
, void *ret
, ULONG size
)
2148 WS_XML_UTF8_TEXT
*utf8
;
2155 FIXME( "description not supported\n" );
2158 if ((hr
= read_get_text( reader
, mapping
, localname
, ns
, &utf8
, &found
)) != S_OK
) return hr
;
2159 if (found
&& (hr
= str_to_int64( utf8
->value
.bytes
, utf8
->value
.length
, MIN_INT32
, MAX_INT32
, &val
)) != S_OK
)
2164 case WS_READ_REQUIRED_VALUE
:
2165 if (!found
) return WS_E_INVALID_FORMAT
;
2166 if (size
!= sizeof(INT32
)) return E_INVALIDARG
;
2167 *(INT32
*)ret
= val
;
2170 case WS_READ_REQUIRED_POINTER
:
2171 if (!found
) return WS_E_INVALID_FORMAT
;
2174 case WS_READ_OPTIONAL_POINTER
:
2176 INT32
*heap_val
= NULL
;
2177 if (size
!= sizeof(heap_val
)) return E_INVALIDARG
;
2180 if (!(heap_val
= ws_alloc( heap
, sizeof(*heap_val
) ))) return WS_E_QUOTA_EXCEEDED
;
2183 *(INT32
**)ret
= heap_val
;
2187 FIXME( "read option %u not supported\n", option
);
2194 static HRESULT
read_type_int64( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2195 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
,
2196 const WS_INT64_DESCRIPTION
*desc
, WS_READ_OPTION option
,
2197 WS_HEAP
*heap
, void *ret
, ULONG size
)
2199 WS_XML_UTF8_TEXT
*utf8
;
2206 FIXME( "description not supported\n" );
2209 if ((hr
= read_get_text( reader
, mapping
, localname
, ns
, &utf8
, &found
)) != S_OK
) return hr
;
2210 if (found
&& (hr
= str_to_int64( utf8
->value
.bytes
, utf8
->value
.length
, MIN_INT64
, MAX_INT64
, &val
)) != S_OK
)
2215 case WS_READ_REQUIRED_VALUE
:
2216 if (!found
) return WS_E_INVALID_FORMAT
;
2217 if (size
!= sizeof(INT64
)) return E_INVALIDARG
;
2218 *(INT64
*)ret
= val
;
2221 case WS_READ_REQUIRED_POINTER
:
2222 if (!found
) return WS_E_INVALID_FORMAT
;
2225 case WS_READ_OPTIONAL_POINTER
:
2227 INT64
*heap_val
= NULL
;
2228 if (size
!= sizeof(heap_val
)) return E_INVALIDARG
;
2231 if (!(heap_val
= ws_alloc( heap
, sizeof(*heap_val
) ))) return WS_E_QUOTA_EXCEEDED
;
2234 *(INT64
**)ret
= heap_val
;
2238 FIXME( "read option %u not supported\n", option
);
2245 static HRESULT
read_type_uint8( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2246 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
,
2247 const WS_UINT8_DESCRIPTION
*desc
, WS_READ_OPTION option
,
2248 WS_HEAP
*heap
, void *ret
, ULONG size
)
2250 WS_XML_UTF8_TEXT
*utf8
;
2257 FIXME( "description not supported\n" );
2260 if ((hr
= read_get_text( reader
, mapping
, localname
, ns
, &utf8
, &found
)) != S_OK
) return hr
;
2261 if (found
&& (hr
= str_to_uint64( utf8
->value
.bytes
, utf8
->value
.length
, MAX_UINT8
, &val
)) != S_OK
)
2266 case WS_READ_REQUIRED_VALUE
:
2267 if (!found
) return WS_E_INVALID_FORMAT
;
2268 if (size
!= sizeof(UINT8
)) return E_INVALIDARG
;
2269 *(UINT8
*)ret
= val
;
2272 case WS_READ_REQUIRED_POINTER
:
2273 if (!found
) return WS_E_INVALID_FORMAT
;
2276 case WS_READ_OPTIONAL_POINTER
:
2278 UINT8
*heap_val
= NULL
;
2279 if (size
!= sizeof(heap_val
)) return E_INVALIDARG
;
2282 if (!(heap_val
= ws_alloc( heap
, sizeof(*heap_val
) ))) return WS_E_QUOTA_EXCEEDED
;
2285 *(UINT8
**)ret
= heap_val
;
2289 FIXME( "read option %u not supported\n", option
);
2296 static HRESULT
read_type_uint16( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2297 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
,
2298 const WS_UINT16_DESCRIPTION
*desc
, WS_READ_OPTION option
,
2299 WS_HEAP
*heap
, void *ret
, ULONG size
)
2301 WS_XML_UTF8_TEXT
*utf8
;
2308 FIXME( "description not supported\n" );
2311 if ((hr
= read_get_text( reader
, mapping
, localname
, ns
, &utf8
, &found
)) != S_OK
) return hr
;
2312 if (found
&& (hr
= str_to_uint64( utf8
->value
.bytes
, utf8
->value
.length
, MAX_UINT16
, &val
)) != S_OK
)
2317 case WS_READ_REQUIRED_VALUE
:
2318 if (!found
) return WS_E_INVALID_FORMAT
;
2319 if (size
!= sizeof(UINT16
)) return E_INVALIDARG
;
2320 *(UINT16
*)ret
= val
;
2323 case WS_READ_REQUIRED_POINTER
:
2324 if (!found
) return WS_E_INVALID_FORMAT
;
2327 case WS_READ_OPTIONAL_POINTER
:
2329 UINT16
*heap_val
= NULL
;
2330 if (size
!= sizeof(heap_val
)) return E_INVALIDARG
;
2333 if (!(heap_val
= ws_alloc( heap
, sizeof(*heap_val
) ))) return WS_E_QUOTA_EXCEEDED
;
2336 *(UINT16
**)ret
= heap_val
;
2340 FIXME( "read option %u not supported\n", option
);
2347 static HRESULT
read_type_uint32( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2348 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
,
2349 const WS_UINT32_DESCRIPTION
*desc
, WS_READ_OPTION option
,
2350 WS_HEAP
*heap
, void *ret
, ULONG size
)
2352 WS_XML_UTF8_TEXT
*utf8
;
2359 FIXME( "description not supported\n" );
2362 if ((hr
= read_get_text( reader
, mapping
, localname
, ns
, &utf8
, &found
)) != S_OK
) return hr
;
2363 if (found
&& (hr
= str_to_uint64( utf8
->value
.bytes
, utf8
->value
.length
, MAX_UINT32
, &val
)) != S_OK
)
2368 case WS_READ_REQUIRED_VALUE
:
2369 if (!found
) return WS_E_INVALID_FORMAT
;
2370 if (size
!= sizeof(UINT32
)) return E_INVALIDARG
;
2371 *(UINT32
*)ret
= val
;
2374 case WS_READ_REQUIRED_POINTER
:
2375 if (!found
) return WS_E_INVALID_FORMAT
;
2378 case WS_READ_OPTIONAL_POINTER
:
2380 UINT32
*heap_val
= NULL
;
2381 if (size
!= sizeof(heap_val
)) return E_INVALIDARG
;
2384 if (!(heap_val
= ws_alloc( heap
, sizeof(*heap_val
) ))) return WS_E_QUOTA_EXCEEDED
;
2387 *(UINT32
**)ret
= heap_val
;
2391 FIXME( "read option %u not supported\n", option
);
2398 static HRESULT
read_type_uint64( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2399 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
,
2400 const WS_UINT64_DESCRIPTION
*desc
, WS_READ_OPTION option
,
2401 WS_HEAP
*heap
, void *ret
, ULONG size
)
2403 WS_XML_UTF8_TEXT
*utf8
;
2410 FIXME( "description not supported\n" );
2413 if ((hr
= read_get_text( reader
, mapping
, localname
, ns
, &utf8
, &found
)) != S_OK
) return hr
;
2414 if (found
&& (hr
= str_to_uint64( utf8
->value
.bytes
, utf8
->value
.length
, MAX_UINT64
, &val
)) != S_OK
)
2419 case WS_READ_REQUIRED_VALUE
:
2420 if (!found
) return WS_E_INVALID_FORMAT
;
2421 if (size
!= sizeof(UINT64
)) return E_INVALIDARG
;
2422 *(UINT64
*)ret
= val
;
2425 case WS_READ_REQUIRED_POINTER
:
2426 if (!found
) return WS_E_INVALID_FORMAT
;
2429 case WS_READ_OPTIONAL_POINTER
:
2431 UINT64
*heap_val
= NULL
;
2432 if (size
!= sizeof(heap_val
)) return E_INVALIDARG
;
2435 if (!(heap_val
= ws_alloc( heap
, sizeof(*heap_val
) ))) return WS_E_QUOTA_EXCEEDED
;
2438 *(UINT64
**)ret
= heap_val
;
2442 FIXME( "read option %u not supported\n", option
);
2449 static HRESULT
read_type_wsz( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2450 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
,
2451 const WS_WSZ_DESCRIPTION
*desc
, WS_READ_OPTION option
,
2452 WS_HEAP
*heap
, WCHAR
**ret
, ULONG size
)
2454 WS_XML_UTF8_TEXT
*utf8
;
2461 FIXME( "description not supported\n" );
2464 if ((hr
= read_get_text( reader
, mapping
, localname
, ns
, &utf8
, &found
)) != S_OK
) return hr
;
2465 if (found
&& !(str
= xmltext_to_widechar( heap
, &utf8
->text
))) return WS_E_QUOTA_EXCEEDED
;
2469 case WS_READ_REQUIRED_POINTER
:
2470 if (!found
) return WS_E_INVALID_FORMAT
;
2473 case WS_READ_OPTIONAL_POINTER
:
2474 if (size
!= sizeof(str
)) return E_INVALIDARG
;
2479 FIXME( "read option %u not supported\n", option
);
2486 static HRESULT
get_enum_value( const WS_XML_UTF8_TEXT
*text
, const WS_ENUM_DESCRIPTION
*desc
, int *ret
)
2489 for (i
= 0; i
< desc
->valueCount
; i
++)
2491 if (WsXmlStringEquals( &text
->value
, desc
->values
[i
].name
, NULL
) == S_OK
)
2493 *ret
= desc
->values
[i
].value
;
2497 return WS_E_INVALID_FORMAT
;
2500 static HRESULT
read_type_enum( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2501 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
,
2502 const WS_ENUM_DESCRIPTION
*desc
, WS_READ_OPTION option
,
2503 WS_HEAP
*heap
, void *ret
, ULONG size
)
2505 WS_XML_UTF8_TEXT
*utf8
;
2510 if (!desc
) return E_INVALIDARG
;
2512 if ((hr
= read_get_text( reader
, mapping
, localname
, ns
, &utf8
, &found
)) != S_OK
) return hr
;
2513 if (found
&& (hr
= get_enum_value( utf8
, desc
, &val
)) != S_OK
) return hr
;
2517 case WS_READ_REQUIRED_VALUE
:
2518 if (!found
) return WS_E_INVALID_FORMAT
;
2519 if (size
!= sizeof(int)) return E_INVALIDARG
;
2523 case WS_READ_REQUIRED_POINTER
:
2524 if (!found
) return WS_E_INVALID_FORMAT
;
2527 case WS_READ_OPTIONAL_POINTER
:
2529 int *heap_val
= NULL
;
2530 if (size
!= sizeof(heap_val
)) return E_INVALIDARG
;
2533 if (!(heap_val
= ws_alloc( heap
, sizeof(*heap_val
) ))) return WS_E_QUOTA_EXCEEDED
;
2536 *(int **)ret
= heap_val
;
2540 FIXME( "read option %u not supported\n", option
);
2547 static BOOL
is_empty_text_node( const struct node
*node
)
2549 const WS_XML_TEXT_NODE
*text
= (const WS_XML_TEXT_NODE
*)node
;
2550 const WS_XML_UTF8_TEXT
*utf8
;
2553 if (node_type( node
) != WS_XML_NODE_TYPE_TEXT
) return FALSE
;
2554 if (text
->text
->textType
!= WS_XML_TEXT_TYPE_UTF8
)
2556 ERR( "unhandled text type %u\n", text
->text
->textType
);
2559 utf8
= (const WS_XML_UTF8_TEXT
*)text
->text
;
2560 for (i
= 0; i
< utf8
->value
.length
; i
++) if (!read_isspace( utf8
->value
.bytes
[i
] )) return FALSE
;
2564 /* skips comment and empty text nodes */
2565 static HRESULT
read_type_next_node( struct reader
*reader
)
2570 WS_XML_NODE_TYPE type
;
2572 if ((hr
= read_node( reader
)) != S_OK
) return hr
;
2573 type
= node_type( reader
->current
);
2574 if (type
== WS_XML_NODE_TYPE_COMMENT
||
2575 (type
== WS_XML_NODE_TYPE_TEXT
&& is_empty_text_node( reader
->current
))) continue;
2580 static HRESULT
read_type_next_element_node( struct reader
*reader
, const WS_XML_STRING
*localname
,
2581 const WS_XML_STRING
*ns
)
2583 const WS_XML_ELEMENT_NODE
*elem
;
2587 if (!localname
) return S_OK
; /* assume reader is already correctly positioned */
2588 if ((hr
= read_to_startelement( reader
, &found
)) != S_OK
) return hr
;
2589 if (!found
) return WS_E_INVALID_FORMAT
;
2591 elem
= &reader
->current
->hdr
;
2592 if (WsXmlStringEquals( localname
, elem
->localName
, NULL
) == S_OK
&&
2593 WsXmlStringEquals( ns
, elem
->ns
, NULL
) == S_OK
) return S_OK
;
2595 return read_type_next_node( reader
);
2598 static ULONG
get_type_size( WS_TYPE type
, const WS_STRUCT_DESCRIPTION
*desc
)
2604 return sizeof(INT8
);
2607 case WS_UINT16_TYPE
:
2608 return sizeof(INT16
);
2612 case WS_UINT32_TYPE
:
2614 return sizeof(INT32
);
2617 case WS_UINT64_TYPE
:
2618 return sizeof(INT64
);
2621 return sizeof(WCHAR
*);
2623 case WS_STRUCT_TYPE
:
2627 ERR( "unhandled type %u\n", type
);
2632 static HRESULT
read_type( struct reader
*, WS_TYPE_MAPPING
, WS_TYPE
, const WS_XML_STRING
*,
2633 const WS_XML_STRING
*, const void *, WS_READ_OPTION
, WS_HEAP
*,
2636 static HRESULT
read_type_repeating_element( struct reader
*reader
, const WS_FIELD_DESCRIPTION
*desc
,
2637 WS_READ_OPTION option
, WS_HEAP
*heap
, void **ret
,
2638 ULONG size
, ULONG
*count
)
2641 ULONG item_size
, nb_items
= 0, nb_allocated
= 1, offset
= 0;
2644 if (size
!= sizeof(void *)) return E_INVALIDARG
;
2646 /* wrapper element */
2647 if (desc
->localName
&& ((hr
= read_type_next_element_node( reader
, desc
->localName
, desc
->ns
)) != S_OK
))
2650 item_size
= get_type_size( desc
->type
, desc
->typeDescription
);
2651 if (!(buf
= ws_alloc_zero( heap
, item_size
))) return WS_E_QUOTA_EXCEEDED
;
2654 if (nb_items
>= nb_allocated
)
2656 if (!(buf
= ws_realloc_zero( heap
, buf
, nb_allocated
* 2 * item_size
)))
2657 return WS_E_QUOTA_EXCEEDED
;
2660 hr
= read_type( reader
, WS_ELEMENT_TYPE_MAPPING
, desc
->type
, desc
->itemLocalName
, desc
->itemNs
,
2661 desc
->typeDescription
, WS_READ_REQUIRED_VALUE
, heap
, buf
+ offset
, item_size
);
2662 if (hr
== WS_E_INVALID_FORMAT
) break;
2665 ws_free( heap
, buf
);
2668 offset
+= item_size
;
2672 if (desc
->localName
&& ((hr
= read_type_next_node( reader
)) != S_OK
)) return hr
;
2674 if (desc
->itemRange
&& (nb_items
< desc
->itemRange
->minItemCount
|| nb_items
> desc
->itemRange
->maxItemCount
))
2676 TRACE( "number of items %u out of range (%u-%u)\n", nb_items
, desc
->itemRange
->minItemCount
,
2677 desc
->itemRange
->maxItemCount
);
2678 ws_free( heap
, buf
);
2679 return WS_E_INVALID_FORMAT
;
2688 static HRESULT
read_type_text( struct reader
*reader
, const WS_FIELD_DESCRIPTION
*desc
,
2689 WS_READ_OPTION option
, WS_HEAP
*heap
, void *ret
, ULONG size
)
2694 if ((hr
= read_to_startelement( reader
, &found
)) != S_OK
) return S_OK
;
2695 if (!found
) return WS_E_INVALID_FORMAT
;
2696 if ((hr
= read_node( reader
)) != S_OK
) return hr
;
2697 if (node_type( reader
->current
) != WS_XML_NODE_TYPE_TEXT
) return WS_E_INVALID_FORMAT
;
2699 return read_type( reader
, WS_ANY_ELEMENT_TYPE_MAPPING
, desc
->type
, NULL
, NULL
,
2700 desc
->typeDescription
, option
, heap
, ret
, size
);
2703 static WS_READ_OPTION
map_field_options( WS_TYPE type
, ULONG options
)
2705 if (options
& ~(WS_FIELD_POINTER
| WS_FIELD_OPTIONAL
))
2707 FIXME( "options %08x not supported\n", options
);
2719 case WS_UINT16_TYPE
:
2720 case WS_UINT32_TYPE
:
2721 case WS_UINT64_TYPE
:
2723 return WS_READ_REQUIRED_VALUE
;
2726 case WS_STRUCT_TYPE
:
2727 return WS_READ_REQUIRED_POINTER
;
2730 FIXME( "unhandled type %u\n", type
);
2735 static HRESULT
read_type_struct_field( struct reader
*reader
, const WS_FIELD_DESCRIPTION
*desc
,
2736 WS_HEAP
*heap
, char *buf
)
2739 WS_READ_OPTION option
;
2743 if (!desc
|| !(option
= map_field_options( desc
->type
, desc
->options
))) return E_INVALIDARG
;
2745 if (option
== WS_READ_REQUIRED_VALUE
)
2746 size
= get_type_size( desc
->type
, desc
->typeDescription
);
2748 size
= sizeof(void *);
2750 ptr
= buf
+ desc
->offset
;
2751 switch (desc
->mapping
)
2753 case WS_ATTRIBUTE_FIELD_MAPPING
:
2754 hr
= read_type( reader
, WS_ATTRIBUTE_TYPE_MAPPING
, desc
->type
, desc
->localName
, desc
->ns
,
2755 desc
->typeDescription
, option
, heap
, ptr
, size
);
2758 case WS_ELEMENT_FIELD_MAPPING
:
2759 hr
= read_type( reader
, WS_ELEMENT_TYPE_MAPPING
, desc
->type
, desc
->localName
, desc
->ns
,
2760 desc
->typeDescription
, option
, heap
, ptr
, size
);
2763 case WS_REPEATING_ELEMENT_FIELD_MAPPING
:
2766 hr
= read_type_repeating_element( reader
, desc
, option
, heap
, (void **)ptr
, size
, &count
);
2767 if (hr
== S_OK
) *(ULONG
*)(buf
+ desc
->countOffset
) = count
;
2770 case WS_TEXT_FIELD_MAPPING
:
2771 hr
= read_type_text( reader
, desc
, option
, heap
, ptr
, size
);
2775 FIXME( "unhandled field mapping %u\n", desc
->mapping
);
2779 if (hr
== WS_E_INVALID_FORMAT
&& desc
->options
& WS_FIELD_OPTIONAL
)
2783 case WS_READ_REQUIRED_VALUE
:
2784 if (desc
->defaultValue
) memcpy( ptr
, desc
->defaultValue
->value
, desc
->defaultValue
->valueSize
);
2785 else memset( ptr
, 0, size
);
2788 case WS_READ_REQUIRED_POINTER
:
2789 *(void **)ptr
= NULL
;
2793 ERR( "unhandled option %u\n", option
);
2801 static HRESULT
read_type_struct( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2802 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
,
2803 const WS_STRUCT_DESCRIPTION
*desc
, WS_READ_OPTION option
,
2804 WS_HEAP
*heap
, void *ret
, ULONG size
)
2810 if (!desc
) return E_INVALIDARG
;
2812 if (desc
->structOptions
)
2814 FIXME( "struct options %08x not supported\n", desc
->structOptions
);
2820 case WS_READ_REQUIRED_POINTER
:
2821 case WS_READ_OPTIONAL_POINTER
:
2822 if (size
!= sizeof(void *)) return E_INVALIDARG
;
2823 if (!(buf
= ws_alloc_zero( heap
, desc
->size
))) return WS_E_QUOTA_EXCEEDED
;
2826 case WS_READ_REQUIRED_VALUE
:
2827 if (size
!= desc
->size
) return E_INVALIDARG
;
2832 FIXME( "unhandled read option %u\n", option
);
2836 for (i
= 0; i
< desc
->fieldCount
; i
++)
2838 if ((hr
= read_type_struct_field( reader
, desc
->fields
[i
], heap
, buf
)) != S_OK
)
2844 case WS_READ_REQUIRED_POINTER
:
2847 ws_free( heap
, buf
);
2850 *(char **)ret
= buf
;
2853 case WS_READ_OPTIONAL_POINTER
:
2856 ws_free( heap
, buf
);
2859 *(char **)ret
= buf
;
2862 case WS_READ_REQUIRED_VALUE
:
2866 ERR( "unhandled read option %u\n", option
);
2871 static HRESULT
read_type( struct reader
*reader
, WS_TYPE_MAPPING mapping
, WS_TYPE type
,
2872 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
,
2873 const void *desc
, WS_READ_OPTION option
, WS_HEAP
*heap
,
2874 void *value
, ULONG size
)
2880 case WS_ELEMENT_TYPE_MAPPING
:
2881 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
2882 if ((hr
= read_type_next_element_node( reader
, localname
, ns
)) != S_OK
) return hr
;
2885 case WS_ANY_ELEMENT_TYPE_MAPPING
:
2886 case WS_ATTRIBUTE_TYPE_MAPPING
:
2890 FIXME( "unhandled mapping %u\n", mapping
);
2896 case WS_STRUCT_TYPE
:
2897 if ((hr
= read_type_struct( reader
, mapping
, localname
, ns
, desc
, option
, heap
, value
, size
)) != S_OK
)
2902 if ((hr
= read_type_bool( reader
, mapping
, localname
, ns
, desc
, option
, heap
, value
, size
)) != S_OK
)
2907 if ((hr
= read_type_int8( reader
, mapping
, localname
, ns
, desc
, option
, heap
, value
, size
)) != S_OK
)
2912 if ((hr
= read_type_int16( reader
, mapping
, localname
, ns
, desc
, option
, heap
, value
, size
)) != S_OK
)
2917 if ((hr
= read_type_int32( reader
, mapping
, localname
, ns
, desc
, option
, heap
, value
, size
)) != S_OK
)
2922 if ((hr
= read_type_int64( reader
, mapping
, localname
, ns
, desc
, option
, heap
, value
, size
)) != S_OK
)
2927 if ((hr
= read_type_uint8( reader
, mapping
, localname
, ns
, desc
, option
, heap
, value
, size
)) != S_OK
)
2931 case WS_UINT16_TYPE
:
2932 if ((hr
= read_type_uint16( reader
, mapping
, localname
, ns
, desc
, option
, heap
, value
, size
)) != S_OK
)
2936 case WS_UINT32_TYPE
:
2937 if ((hr
= read_type_uint32( reader
, mapping
, localname
, ns
, desc
, option
, heap
, value
, size
)) != S_OK
)
2941 case WS_UINT64_TYPE
:
2942 if ((hr
= read_type_uint64( reader
, mapping
, localname
, ns
, desc
, option
, heap
, value
, size
)) != S_OK
)
2947 if ((hr
= read_type_wsz( reader
, mapping
, localname
, ns
, desc
, option
, heap
, value
, size
)) != S_OK
)
2952 if ((hr
= read_type_enum( reader
, mapping
, localname
, ns
, desc
, option
, heap
, value
, size
)) != S_OK
)
2957 FIXME( "type %u not supported\n", type
);
2963 case WS_ELEMENT_TYPE_MAPPING
:
2964 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
2965 return read_type_next_node( reader
);
2967 case WS_ATTRIBUTE_TYPE_MAPPING
:
2973 /**************************************************************************
2974 * WsReadType [webservices.@]
2976 HRESULT WINAPI
WsReadType( WS_XML_READER
*handle
, WS_TYPE_MAPPING mapping
, WS_TYPE type
,
2977 const void *desc
, WS_READ_OPTION option
, WS_HEAP
*heap
, void *value
,
2978 ULONG size
, WS_ERROR
*error
)
2980 struct reader
*reader
= (struct reader
*)handle
;
2983 TRACE( "%p %u %u %p %u %p %p %u %p\n", handle
, mapping
, type
, desc
, option
, heap
, value
,
2985 if (error
) FIXME( "ignoring error parameter\n" );
2987 if (!reader
|| !value
) return E_INVALIDARG
;
2989 if ((hr
= read_type( reader
, mapping
, type
, NULL
, NULL
, desc
, option
, heap
, value
, size
)) != S_OK
)
2994 case WS_ELEMENT_TYPE_MAPPING
:
2995 if ((hr
= read_node( reader
)) != S_OK
) return hr
;
3002 if (!read_end_of_data( reader
)) return WS_E_INVALID_FORMAT
;
3006 /**************************************************************************
3007 * WsSetErrorProperty [webservices.@]
3009 HRESULT WINAPI
WsSetErrorProperty( WS_ERROR
*handle
, WS_ERROR_PROPERTY_ID id
, const void *value
,
3012 struct error
*error
= (struct error
*)handle
;
3014 TRACE( "%p %u %p %u\n", handle
, id
, value
, size
);
3016 if (id
== WS_ERROR_PROPERTY_LANGID
) return WS_E_INVALID_OPERATION
;
3017 return prop_set( error
->prop
, error
->prop_count
, id
, value
, size
);
3020 static inline BOOL
is_utf8( const unsigned char *data
, ULONG size
, ULONG
*offset
)
3022 static const char bom
[] = {0xef,0xbb,0xbf};
3023 const unsigned char *p
= data
;
3025 return (size
>= sizeof(bom
) && !memcmp( p
, bom
, sizeof(bom
) ) && (*offset
= sizeof(bom
))) ||
3026 (size
> 2 && !(*offset
= 0));
3029 static inline BOOL
is_utf16le( const unsigned char *data
, ULONG size
, ULONG
*offset
)
3031 static const char bom
[] = {0xff,0xfe};
3032 const unsigned char *p
= data
;
3034 return (size
>= sizeof(bom
) && !memcmp( p
, bom
, sizeof(bom
) ) && (*offset
= sizeof(bom
))) ||
3035 (size
>= 4 && p
[0] == '<' && !p
[1] && !(*offset
= 0));
3038 static WS_CHARSET
detect_charset( const unsigned char *data
, ULONG size
, ULONG
*offset
)
3042 /* FIXME: parse xml declaration */
3044 if (is_utf16le( data
, size
, offset
)) ret
= WS_CHARSET_UTF16LE
;
3045 else if (is_utf8( data
, size
, offset
)) ret
= WS_CHARSET_UTF8
;
3048 FIXME( "charset not recognized\n" );
3052 TRACE( "detected charset %u\n", ret
);
3056 static void set_input_buffer( struct reader
*reader
, const unsigned char *data
, ULONG size
)
3058 reader
->input_type
= WS_XML_READER_INPUT_TYPE_BUFFER
;
3059 reader
->input_data
= data
;
3060 reader
->input_size
= size
;
3062 reader
->read_size
= reader
->input_size
;
3063 reader
->read_pos
= 0;
3064 reader
->read_bufptr
= reader
->input_data
;
3067 /**************************************************************************
3068 * WsSetInput [webservices.@]
3070 HRESULT WINAPI
WsSetInput( WS_XML_READER
*handle
, const WS_XML_READER_ENCODING
*encoding
,
3071 const WS_XML_READER_INPUT
*input
, const WS_XML_READER_PROPERTY
*properties
,
3072 ULONG count
, WS_ERROR
*error
)
3074 struct reader
*reader
= (struct reader
*)handle
;
3077 ULONG i
, offset
= 0;
3079 TRACE( "%p %p %p %p %u %p\n", handle
, encoding
, input
, properties
, count
, error
);
3080 if (error
) FIXME( "ignoring error parameter\n" );
3082 if (!reader
) return E_INVALIDARG
;
3084 for (i
= 0; i
< count
; i
++)
3086 hr
= prop_set( reader
->prop
, reader
->prop_count
, properties
[i
].id
, properties
[i
].value
,
3087 properties
[i
].valueSize
);
3088 if (hr
!= S_OK
) return hr
;
3091 if ((hr
= read_init_state( reader
)) != S_OK
) return hr
;
3093 switch (encoding
->encodingType
)
3095 case WS_XML_READER_ENCODING_TYPE_TEXT
:
3097 WS_XML_READER_TEXT_ENCODING
*text
= (WS_XML_READER_TEXT_ENCODING
*)encoding
;
3098 WS_XML_READER_BUFFER_INPUT
*buf
= (WS_XML_READER_BUFFER_INPUT
*)input
;
3099 WS_CHARSET charset
= text
->charSet
;
3101 if (input
->inputType
!= WS_XML_READER_INPUT_TYPE_BUFFER
)
3103 FIXME( "charset detection on input type %u not supported\n", input
->inputType
);
3107 if (charset
== WS_CHARSET_AUTO
)
3108 charset
= detect_charset( buf
->encodedData
, buf
->encodedDataSize
, &offset
);
3110 hr
= prop_set( reader
->prop
, reader
->prop_count
, WS_XML_READER_PROPERTY_CHARSET
,
3111 &charset
, sizeof(charset
) );
3112 if (hr
!= S_OK
) return hr
;
3116 FIXME( "encoding type %u not supported\n", encoding
->encodingType
);
3119 switch (input
->inputType
)
3121 case WS_XML_READER_INPUT_TYPE_BUFFER
:
3123 WS_XML_READER_BUFFER_INPUT
*buf
= (WS_XML_READER_BUFFER_INPUT
*)input
;
3124 set_input_buffer( reader
, (const unsigned char *)buf
->encodedData
+ offset
, buf
->encodedDataSize
- offset
);
3128 FIXME( "input type %u not supported\n", input
->inputType
);
3132 if (!(node
= alloc_node( WS_XML_NODE_TYPE_BOF
))) return E_OUTOFMEMORY
;
3133 read_insert_bof( reader
, node
);
3137 /**************************************************************************
3138 * WsSetInputToBuffer [webservices.@]
3140 HRESULT WINAPI
WsSetInputToBuffer( WS_XML_READER
*handle
, WS_XML_BUFFER
*buffer
,
3141 const WS_XML_READER_PROPERTY
*properties
, ULONG count
,
3144 struct reader
*reader
= (struct reader
*)handle
;
3145 struct xmlbuf
*xmlbuf
= (struct xmlbuf
*)buffer
;
3149 ULONG i
, offset
= 0;
3151 TRACE( "%p %p %p %u %p\n", handle
, buffer
, properties
, count
, error
);
3152 if (error
) FIXME( "ignoring error parameter\n" );
3154 if (!reader
|| !xmlbuf
) return E_INVALIDARG
;
3156 for (i
= 0; i
< count
; i
++)
3158 hr
= prop_set( reader
->prop
, reader
->prop_count
, properties
[i
].id
, properties
[i
].value
,
3159 properties
[i
].valueSize
);
3160 if (hr
!= S_OK
) return hr
;
3163 if ((hr
= read_init_state( reader
)) != S_OK
) return hr
;
3165 charset
= detect_charset( xmlbuf
->ptr
, xmlbuf
->size
, &offset
);
3166 hr
= prop_set( reader
->prop
, reader
->prop_count
, WS_XML_READER_PROPERTY_CHARSET
,
3167 &charset
, sizeof(charset
) );
3168 if (hr
!= S_OK
) return hr
;
3170 set_input_buffer( reader
, (const unsigned char *)xmlbuf
->ptr
+ offset
, xmlbuf
->size
- offset
);
3171 if (!(node
= alloc_node( WS_XML_NODE_TYPE_BOF
))) return E_OUTOFMEMORY
;
3172 read_insert_bof( reader
, node
);
3176 /**************************************************************************
3177 * WsXmlStringEquals [webservices.@]
3179 HRESULT WINAPI
WsXmlStringEquals( const WS_XML_STRING
*str1
, const WS_XML_STRING
*str2
, WS_ERROR
*error
)
3181 TRACE( "%s %s %p\n", debugstr_xmlstr(str1
), debugstr_xmlstr(str2
), error
);
3182 if (error
) FIXME( "ignoring error parameter\n" );
3184 if (!str1
|| !str2
) return E_INVALIDARG
;
3186 if (str1
->length
!= str2
->length
) return S_FALSE
;
3187 if (!memcmp( str1
->bytes
, str2
->bytes
, str1
->length
)) return S_OK
;