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
);
45 { sizeof(ULONG
), TRUE
}, /* WS_ERROR_PROPERTY_STRING_COUNT */
46 { sizeof(ULONG
), FALSE
}, /* WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE */
47 { sizeof(LANGID
), FALSE
} /* WS_ERROR_PROPERTY_LANGID */
53 WS_ERROR_PROPERTY prop
[sizeof(error_props
)/sizeof(error_props
[0])];
56 static struct error
*alloc_error(void)
58 static const ULONG count
= sizeof(error_props
)/sizeof(error_props
[0]);
60 ULONG i
, size
= sizeof(*ret
) + count
* sizeof(WS_ERROR_PROPERTY
);
63 for (i
= 0; i
< count
; i
++) size
+= error_props
[i
].size
;
64 if (!(ret
= heap_alloc_zero( size
))) return NULL
;
66 ptr
= (char *)&ret
->prop
[count
];
67 for (i
= 0; i
< count
; i
++)
69 ret
->prop
[i
].value
= ptr
;
70 ret
->prop
[i
].valueSize
= error_props
[i
].size
;
71 ptr
+= ret
->prop
[i
].valueSize
;
73 ret
->prop_count
= count
;
77 static HRESULT
set_error_prop( struct error
*error
, WS_ERROR_PROPERTY_ID id
, const void *value
, ULONG size
)
79 if (id
>= error
->prop_count
|| size
!= error_props
[id
].size
|| error_props
[id
].readonly
)
82 memcpy( error
->prop
[id
].value
, value
, size
);
86 static HRESULT
get_error_prop( struct error
*error
, WS_ERROR_PROPERTY_ID id
, void *buf
, ULONG size
)
88 if (id
>= error
->prop_count
|| size
!= error_props
[id
].size
)
91 memcpy( buf
, error
->prop
[id
].value
, error
->prop
[id
].valueSize
);
95 /**************************************************************************
96 * WsCreateError [webservices.@]
98 HRESULT WINAPI
WsCreateError( const WS_ERROR_PROPERTY
*properties
, ULONG count
, WS_ERROR
**handle
)
101 LANGID langid
= GetUserDefaultUILanguage();
105 TRACE( "%p %u %p\n", properties
, count
, handle
);
107 if (!handle
) return E_INVALIDARG
;
108 if (!(error
= alloc_error())) return E_OUTOFMEMORY
;
110 set_error_prop( error
, WS_ERROR_PROPERTY_LANGID
, &langid
, sizeof(langid
) );
111 for (i
= 0; i
< count
; i
++)
113 if (properties
[i
].id
== WS_ERROR_PROPERTY_ORIGINAL_ERROR_CODE
)
118 hr
= set_error_prop( error
, properties
[i
].id
, properties
[i
].value
, properties
[i
].valueSize
);
126 *handle
= (WS_ERROR
*)error
;
130 /**************************************************************************
131 * WsFreeError [webservices.@]
133 void WINAPI
WsFreeError( WS_ERROR
*handle
)
135 struct error
*error
= (struct error
*)handle
;
137 TRACE( "%p\n", handle
);
148 { sizeof(SIZE_T
), FALSE
}, /* WS_HEAP_PROPERTY_MAX_SIZE */
149 { sizeof(SIZE_T
), FALSE
}, /* WS_HEAP_PROPERTY_TRIM_SIZE */
150 { sizeof(SIZE_T
), TRUE
}, /* WS_HEAP_PROPERTY_REQUESTED_SIZE */
151 { sizeof(SIZE_T
), TRUE
} /* WS_HEAP_PROPERTY_ACTUAL_SIZE */
158 WS_HEAP_PROPERTY prop
[sizeof(heap_props
)/sizeof(heap_props
[0])];
161 void *ws_alloc( WS_HEAP
*handle
, SIZE_T size
)
163 struct heap
*heap
= (struct heap
*)handle
;
164 return HeapAlloc( heap
->handle
, 0, size
);
167 static void *ws_alloc_zero( WS_HEAP
*handle
, SIZE_T size
)
169 struct heap
*heap
= (struct heap
*)handle
;
170 return HeapAlloc( heap
->handle
, HEAP_ZERO_MEMORY
, size
);
173 void *ws_realloc( WS_HEAP
*handle
, void *ptr
, SIZE_T size
)
175 struct heap
*heap
= (struct heap
*)handle
;
176 return HeapReAlloc( heap
->handle
, 0, ptr
, size
);
179 static void *ws_realloc_zero( WS_HEAP
*handle
, void *ptr
, SIZE_T size
)
181 struct heap
*heap
= (struct heap
*)handle
;
182 return HeapReAlloc( heap
->handle
, HEAP_ZERO_MEMORY
, ptr
, size
);
185 void ws_free( WS_HEAP
*handle
, void *ptr
)
187 struct heap
*heap
= (struct heap
*)handle
;
188 HeapFree( heap
->handle
, 0, ptr
);
191 /**************************************************************************
192 * WsAlloc [webservices.@]
194 HRESULT WINAPI
WsAlloc( WS_HEAP
*handle
, SIZE_T size
, void **ptr
, WS_ERROR
*error
)
198 TRACE( "%p %u %p %p\n", handle
, (ULONG
)size
, ptr
, error
);
199 if (error
) FIXME( "ignoring error parameter\n" );
201 if (!handle
|| !ptr
) return E_INVALIDARG
;
203 if (!(mem
= ws_alloc( handle
, size
))) return E_OUTOFMEMORY
;
208 static struct heap
*alloc_heap(void)
210 static const ULONG count
= sizeof(heap_props
)/sizeof(heap_props
[0]);
212 ULONG i
, size
= sizeof(*ret
) + count
* sizeof(WS_HEAP_PROPERTY
);
215 for (i
= 0; i
< count
; i
++) size
+= heap_props
[i
].size
;
216 if (!(ret
= heap_alloc_zero( size
))) return NULL
;
218 ptr
= (char *)&ret
->prop
[count
];
219 for (i
= 0; i
< count
; i
++)
221 ret
->prop
[i
].value
= ptr
;
222 ret
->prop
[i
].valueSize
= heap_props
[i
].size
;
223 ptr
+= ret
->prop
[i
].valueSize
;
225 ret
->prop_count
= count
;
229 static HRESULT
set_heap_prop( struct heap
*heap
, WS_HEAP_PROPERTY_ID id
, const void *value
, ULONG size
)
231 if (id
>= heap
->prop_count
|| size
!= heap_props
[id
].size
|| heap_props
[id
].readonly
)
234 memcpy( heap
->prop
[id
].value
, value
, size
);
238 static HRESULT
get_heap_prop( struct heap
*heap
, WS_HEAP_PROPERTY_ID id
, void *buf
, ULONG size
)
240 if (id
>= heap
->prop_count
|| size
!= heap_props
[id
].size
)
243 memcpy( buf
, heap
->prop
[id
].value
, heap
->prop
[id
].valueSize
);
247 /**************************************************************************
248 * WsCreateHeap [webservices.@]
250 HRESULT WINAPI
WsCreateHeap( SIZE_T max_size
, SIZE_T trim_size
, const WS_HEAP_PROPERTY
*properties
,
251 ULONG count
, WS_HEAP
**handle
, WS_ERROR
*error
)
255 TRACE( "%u %u %p %u %p %p\n", (ULONG
)max_size
, (ULONG
)trim_size
, properties
, count
, handle
, error
);
256 if (error
) FIXME( "ignoring error parameter\n" );
258 if (!handle
|| count
) return E_INVALIDARG
;
259 if (!(heap
= alloc_heap())) return E_OUTOFMEMORY
;
261 set_heap_prop( heap
, WS_HEAP_PROPERTY_MAX_SIZE
, &max_size
, sizeof(max_size
) );
262 set_heap_prop( heap
, WS_HEAP_PROPERTY_TRIM_SIZE
, &trim_size
, sizeof(trim_size
) );
264 if (!(heap
->handle
= HeapCreate( 0, 0, max_size
)))
267 return E_OUTOFMEMORY
;
270 *handle
= (WS_HEAP
*)heap
;
274 /**************************************************************************
275 * WsFreeHeap [webservices.@]
277 void WINAPI
WsFreeHeap( WS_HEAP
*handle
)
279 struct heap
*heap
= (struct heap
*)handle
;
281 TRACE( "%p\n", handle
);
284 HeapDestroy( heap
->handle
);
288 struct node
*alloc_node( WS_XML_NODE_TYPE type
)
292 if (!(ret
= heap_alloc_zero( sizeof(*ret
) ))) return NULL
;
293 ret
->hdr
.node
.nodeType
= type
;
294 list_init( &ret
->entry
);
295 list_init( &ret
->children
);
299 void free_attribute( WS_XML_ATTRIBUTE
*attr
)
302 heap_free( attr
->prefix
);
303 heap_free( attr
->localName
);
304 heap_free( attr
->ns
);
305 heap_free( attr
->value
);
309 void free_node( struct node
*node
)
312 switch (node_type( node
))
314 case WS_XML_NODE_TYPE_ELEMENT
:
316 WS_XML_ELEMENT_NODE
*elem
= &node
->hdr
;
319 for (i
= 0; i
< elem
->attributeCount
; i
++) free_attribute( elem
->attributes
[i
] );
320 heap_free( elem
->attributes
);
321 heap_free( elem
->prefix
);
322 heap_free( elem
->localName
);
323 heap_free( elem
->ns
);
326 case WS_XML_NODE_TYPE_TEXT
:
328 WS_XML_TEXT_NODE
*text
= (WS_XML_TEXT_NODE
*)node
;
329 heap_free( text
->text
);
332 case WS_XML_NODE_TYPE_COMMENT
:
334 WS_XML_COMMENT_NODE
*comment
= (WS_XML_COMMENT_NODE
*)node
;
335 heap_free( comment
->value
.bytes
);
338 case WS_XML_NODE_TYPE_CDATA
:
339 case WS_XML_NODE_TYPE_END_CDATA
:
340 case WS_XML_NODE_TYPE_END_ELEMENT
:
341 case WS_XML_NODE_TYPE_EOF
:
342 case WS_XML_NODE_TYPE_BOF
:
346 ERR( "unhandled type %u\n", node_type( node
) );
352 void destroy_nodes( struct node
*node
)
357 while ((ptr
= list_head( &node
->children
)))
359 struct node
*child
= LIST_ENTRY( ptr
, struct node
, entry
);
360 list_remove( &child
->entry
);
361 destroy_nodes( child
);
373 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_MAX_DEPTH */
374 { sizeof(BOOL
), FALSE
}, /* WS_XML_READER_PROPERTY_ALLOW_FRAGMENT */
375 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_MAX_ATTRIBUTES */
376 { sizeof(BOOL
), FALSE
}, /* WS_XML_READER_PROPERTY_READ_DECLARATION */
377 { sizeof(WS_CHARSET
), FALSE
}, /* WS_XML_READER_PROPERTY_CHARSET */
378 { sizeof(ULONGLONG
), TRUE
}, /* WS_XML_READER_PROPERTY_ROW */
379 { sizeof(ULONGLONG
), TRUE
}, /* WS_XML_READER_PROPERTY_COLUMN */
380 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_UTF8_TRIM_SIZE */
381 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_STREAM_BUFFER_SIZE */
382 { sizeof(BOOL
), TRUE
}, /* WS_XML_READER_PROPERTY_IN_ATTRIBUTE */
383 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_STREAM_MAX_ROOT_MIME_PART_SIZE */
384 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_STREAM_MAX_MIME_HEADERS_SIZE */
385 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_MAX_MIME_PARTS */
386 { sizeof(BOOL
), FALSE
}, /* WS_XML_READER_PROPERTY_ALLOW_INVALID_CHARACTER_REFERENCES */
387 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_MAX_NAMESPACES */
392 READER_STATE_INITIAL
,
394 READER_STATE_STARTELEMENT
,
395 READER_STATE_STARTATTRIBUTE
,
396 READER_STATE_STARTCDATA
,
399 READER_STATE_ENDELEMENT
,
400 READER_STATE_ENDCDATA
,
401 READER_STATE_COMMENT
,
415 const unsigned char *read_bufptr
;
416 enum reader_state state
;
418 struct node
*current
;
420 struct prefix
*prefixes
;
422 ULONG nb_prefixes_allocated
;
423 WS_XML_READER_INPUT_TYPE input_type
;
424 const unsigned char *input_data
;
427 WS_XML_READER_PROPERTY prop
[sizeof(reader_props
)/sizeof(reader_props
[0])];
430 static struct reader
*alloc_reader(void)
432 static const ULONG count
= sizeof(reader_props
)/sizeof(reader_props
[0]);
434 ULONG i
, size
= sizeof(*ret
) + count
* sizeof(WS_XML_READER_PROPERTY
);
437 for (i
= 0; i
< count
; i
++) size
+= reader_props
[i
].size
;
438 if (!(ret
= heap_alloc_zero( size
))) return NULL
;
440 if (!(ret
->prefixes
= heap_alloc_zero( sizeof(*ret
->prefixes
) )))
445 ret
->nb_prefixes
= ret
->nb_prefixes_allocated
= 1;
447 ptr
= (char *)&ret
->prop
[count
];
448 for (i
= 0; i
< count
; i
++)
450 ret
->prop
[i
].value
= ptr
;
451 ret
->prop
[i
].valueSize
= reader_props
[i
].size
;
452 ptr
+= ret
->prop
[i
].valueSize
;
454 ret
->prop_count
= count
;
458 static void clear_prefixes( struct prefix
*prefixes
, ULONG count
)
461 for (i
= 0; i
< count
; i
++)
463 heap_free( prefixes
[i
].str
.bytes
);
464 prefixes
[i
].str
.bytes
= NULL
;
465 prefixes
[i
].str
.length
= 0;
467 heap_free( prefixes
[i
].ns
.bytes
);
468 prefixes
[i
].ns
.bytes
= NULL
;
469 prefixes
[i
].ns
.length
= 0;
473 static void free_reader( struct reader
*reader
)
476 destroy_nodes( reader
->root
);
477 clear_prefixes( reader
->prefixes
, reader
->nb_prefixes
);
478 heap_free( reader
->prefixes
);
482 static HRESULT
set_prefix( struct prefix
*prefix
, const WS_XML_STRING
*str
, const WS_XML_STRING
*ns
)
486 heap_free( prefix
->str
.bytes
);
487 if (!(prefix
->str
.bytes
= heap_alloc( str
->length
))) return E_OUTOFMEMORY
;
488 memcpy( prefix
->str
.bytes
, str
->bytes
, str
->length
);
489 prefix
->str
.length
= str
->length
;
492 heap_free( prefix
->ns
.bytes
);
493 if (!(prefix
->ns
.bytes
= heap_alloc( ns
->length
))) return E_OUTOFMEMORY
;
494 memcpy( prefix
->ns
.bytes
, ns
->bytes
, ns
->length
);
495 prefix
->ns
.length
= ns
->length
;
500 static HRESULT
bind_prefix( struct reader
*reader
, const WS_XML_STRING
*prefix
, const WS_XML_STRING
*ns
)
505 for (i
= 0; i
< reader
->nb_prefixes
; i
++)
507 if (WsXmlStringEquals( prefix
, &reader
->prefixes
[i
].str
, NULL
) == S_OK
)
508 return set_prefix( &reader
->prefixes
[i
], NULL
, ns
);
510 if (i
>= reader
->nb_prefixes_allocated
)
512 ULONG new_size
= reader
->nb_prefixes_allocated
* sizeof(*reader
->prefixes
) * 2;
513 struct prefix
*tmp
= heap_realloc_zero( reader
->prefixes
, new_size
);
514 if (!tmp
) return E_OUTOFMEMORY
;
515 reader
->prefixes
= tmp
;
516 reader
->nb_prefixes_allocated
*= 2;
519 if ((hr
= set_prefix( &reader
->prefixes
[i
], prefix
, ns
)) != S_OK
) return hr
;
520 reader
->nb_prefixes
++;
524 static const WS_XML_STRING
*get_namespace( struct reader
*reader
, const WS_XML_STRING
*prefix
)
527 for (i
= 0; i
< reader
->nb_prefixes
; i
++)
529 if (WsXmlStringEquals( prefix
, &reader
->prefixes
[i
].str
, NULL
) == S_OK
)
530 return &reader
->prefixes
[i
].ns
;
535 static HRESULT
set_reader_prop( struct reader
*reader
, WS_XML_READER_PROPERTY_ID id
, const void *value
, ULONG size
)
537 if (id
>= reader
->prop_count
|| size
!= reader_props
[id
].size
|| reader_props
[id
].readonly
)
540 memcpy( reader
->prop
[id
].value
, value
, size
);
544 static HRESULT
get_reader_prop( struct reader
*reader
, WS_XML_READER_PROPERTY_ID id
, void *buf
, ULONG size
)
546 if (id
>= reader
->prop_count
|| size
!= reader_props
[id
].size
)
549 memcpy( buf
, reader
->prop
[id
].value
, reader
->prop
[id
].valueSize
);
553 static void read_insert_eof( struct reader
*reader
, struct node
*eof
)
555 if (!reader
->root
) reader
->root
= eof
;
558 eof
->parent
= reader
->root
;
559 list_add_tail( &reader
->root
->children
, &eof
->entry
);
561 reader
->current
= eof
;
564 static void read_insert_bof( struct reader
*reader
, struct node
*bof
)
566 reader
->root
->parent
= bof
;
567 list_add_tail( &bof
->children
, &reader
->root
->entry
);
568 reader
->current
= reader
->root
= bof
;
571 static void read_insert_node( struct reader
*reader
, struct node
*parent
, struct node
*node
)
573 node
->parent
= parent
;
574 if (node
->parent
== reader
->root
)
576 struct list
*eof
= list_tail( &reader
->root
->children
);
577 list_add_before( eof
, &node
->entry
);
579 else list_add_tail( &parent
->children
, &node
->entry
);
580 reader
->current
= node
;
583 static HRESULT
read_init_state( struct reader
*reader
)
587 destroy_nodes( reader
->root
);
589 clear_prefixes( reader
->prefixes
, reader
->nb_prefixes
);
590 reader
->nb_prefixes
= 1;
591 if (!(node
= alloc_node( WS_XML_NODE_TYPE_EOF
))) return E_OUTOFMEMORY
;
592 read_insert_eof( reader
, node
);
593 reader
->state
= READER_STATE_INITIAL
;
597 /**************************************************************************
598 * WsCreateReader [webservices.@]
600 HRESULT WINAPI
WsCreateReader( const WS_XML_READER_PROPERTY
*properties
, ULONG count
,
601 WS_XML_READER
**handle
, WS_ERROR
*error
)
603 struct reader
*reader
;
604 ULONG i
, max_depth
= 32, max_attrs
= 128, max_ns
= 32;
605 WS_CHARSET charset
= WS_CHARSET_UTF8
;
606 BOOL read_decl
= TRUE
;
609 TRACE( "%p %u %p %p\n", properties
, count
, handle
, error
);
610 if (error
) FIXME( "ignoring error parameter\n" );
612 if (!handle
) return E_INVALIDARG
;
613 if (!(reader
= alloc_reader())) return E_OUTOFMEMORY
;
615 set_reader_prop( reader
, WS_XML_READER_PROPERTY_MAX_DEPTH
, &max_depth
, sizeof(max_depth
) );
616 set_reader_prop( reader
, WS_XML_READER_PROPERTY_MAX_ATTRIBUTES
, &max_attrs
, sizeof(max_attrs
) );
617 set_reader_prop( reader
, WS_XML_READER_PROPERTY_READ_DECLARATION
, &read_decl
, sizeof(read_decl
) );
618 set_reader_prop( reader
, WS_XML_READER_PROPERTY_CHARSET
, &charset
, sizeof(charset
) );
619 set_reader_prop( reader
, WS_XML_READER_PROPERTY_MAX_NAMESPACES
, &max_ns
, sizeof(max_ns
) );
621 for (i
= 0; i
< count
; i
++)
623 hr
= set_reader_prop( reader
, properties
[i
].id
, properties
[i
].value
, properties
[i
].valueSize
);
626 free_reader( reader
);
631 if ((hr
= read_init_state( reader
)) != S_OK
)
633 free_reader( reader
);
637 *handle
= (WS_XML_READER
*)reader
;
641 /**************************************************************************
642 * WsFreeReader [webservices.@]
644 void WINAPI
WsFreeReader( WS_XML_READER
*handle
)
646 struct reader
*reader
= (struct reader
*)handle
;
648 TRACE( "%p\n", handle
);
649 free_reader( reader
);
652 /**************************************************************************
653 * WsFillReader [webservices.@]
655 HRESULT WINAPI
WsFillReader( WS_XML_READER
*handle
, ULONG min_size
, const WS_ASYNC_CONTEXT
*ctx
,
658 struct reader
*reader
= (struct reader
*)handle
;
660 TRACE( "%p %u %p %p\n", handle
, min_size
, ctx
, error
);
661 if (error
) FIXME( "ignoring error parameter\n" );
663 if (!reader
) return E_INVALIDARG
;
665 /* FIXME: add support for stream input */
666 reader
->read_size
= min( min_size
, reader
->input_size
);
667 reader
->read_pos
= 0;
672 /**************************************************************************
673 * WsGetErrorProperty [webservices.@]
675 HRESULT WINAPI
WsGetErrorProperty( WS_ERROR
*handle
, WS_ERROR_PROPERTY_ID id
, void *buf
,
678 struct error
*error
= (struct error
*)handle
;
680 TRACE( "%p %u %p %u\n", handle
, id
, buf
, size
);
681 return get_error_prop( error
, id
, buf
, size
);
684 /**************************************************************************
685 * WsGetErrorString [webservices.@]
687 HRESULT WINAPI
WsGetErrorString( WS_ERROR
*handle
, ULONG index
, WS_STRING
*str
)
689 FIXME( "%p %u %p: stub\n", handle
, index
, str
);
693 /**************************************************************************
694 * WsGetHeapProperty [webservices.@]
696 HRESULT WINAPI
WsGetHeapProperty( WS_HEAP
*handle
, WS_HEAP_PROPERTY_ID id
, void *buf
,
697 ULONG size
, WS_ERROR
*error
)
699 struct heap
*heap
= (struct heap
*)handle
;
701 TRACE( "%p %u %p %u %p\n", handle
, id
, buf
, size
, error
);
702 if (error
) FIXME( "ignoring error parameter\n" );
704 return get_heap_prop( heap
, id
, buf
, size
);
707 /**************************************************************************
708 * WsGetNamespaceFromPrefix [webservices.@]
710 HRESULT WINAPI
WsGetNamespaceFromPrefix( WS_XML_READER
*handle
, const WS_XML_STRING
*prefix
,
711 BOOL required
, const WS_XML_STRING
**ns
, WS_ERROR
*error
)
713 static const WS_XML_STRING xml
= {3, (BYTE
*)"xml"};
714 static const WS_XML_STRING xmlns
= {5, (BYTE
*)"xmlns"};
715 static const WS_XML_STRING empty_ns
= {0, NULL
};
716 static const WS_XML_STRING xml_ns
= {36, (BYTE
*)"http://www.w3.org/XML/1998/namespace"};
717 static const WS_XML_STRING xmlns_ns
= {29, (BYTE
*)"http://www.w3.org/2000/xmlns/"};
718 struct reader
*reader
= (struct reader
*)handle
;
721 TRACE( "%p %s %d %p %p\n", handle
, debugstr_xmlstr(prefix
), required
, ns
, error
);
722 if (error
) FIXME( "ignoring error parameter\n" );
724 if (!reader
|| !prefix
|| !ns
) return E_INVALIDARG
;
725 if (reader
->state
!= READER_STATE_STARTELEMENT
) return WS_E_INVALID_OPERATION
;
732 else if (WsXmlStringEquals( prefix
, &xml
, NULL
) == S_OK
)
737 else if (WsXmlStringEquals( prefix
, &xmlns
, NULL
) == S_OK
)
744 WS_XML_ELEMENT_NODE
*elem
= &reader
->current
->hdr
;
747 for (i
= 0; i
< elem
->attributeCount
; i
++)
749 if (!elem
->attributes
[i
]->isXmlNs
) continue;
750 if (WsXmlStringEquals( prefix
, elem
->attributes
[i
]->prefix
, NULL
) == S_OK
)
752 *ns
= elem
->attributes
[i
]->ns
;
761 if (required
) return WS_E_INVALID_FORMAT
;
768 /**************************************************************************
769 * WsGetReaderNode [webservices.@]
771 HRESULT WINAPI
WsGetReaderNode( WS_XML_READER
*handle
, const WS_XML_NODE
**node
,
774 struct reader
*reader
= (struct reader
*)handle
;
776 TRACE( "%p %p %p\n", handle
, node
, error
);
777 if (error
) FIXME( "ignoring error parameter\n" );
779 if (!reader
|| !node
) return E_INVALIDARG
;
781 *node
= &reader
->current
->hdr
.node
;
785 /**************************************************************************
786 * WsGetReaderProperty [webservices.@]
788 HRESULT WINAPI
WsGetReaderProperty( WS_XML_READER
*handle
, WS_XML_READER_PROPERTY_ID id
,
789 void *buf
, ULONG size
, WS_ERROR
*error
)
791 struct reader
*reader
= (struct reader
*)handle
;
793 TRACE( "%p %u %p %u %p\n", handle
, id
, buf
, size
, error
);
794 if (error
) FIXME( "ignoring error parameter\n" );
796 if (!reader
->input_type
) return WS_E_INVALID_OPERATION
;
798 if (id
== WS_XML_READER_PROPERTY_CHARSET
)
803 if ((hr
= get_reader_prop( reader
, id
, &charset
, size
)) != S_OK
) return hr
;
804 if (!charset
) return WS_E_INVALID_FORMAT
;
805 *(WS_CHARSET
*)buf
= charset
;
808 return get_reader_prop( reader
, id
, buf
, size
);
811 /**************************************************************************
812 * WsGetXmlAttribute [webservices.@]
814 HRESULT WINAPI
WsGetXmlAttribute( WS_XML_READER
*handle
, const WS_XML_STRING
*attr
,
815 WS_HEAP
*heap
, WCHAR
**str
, ULONG
*len
, WS_ERROR
*error
)
817 FIXME( "%p %s %p %p %p %p: stub\n", handle
, debugstr_xmlstr(attr
), heap
, str
, len
, error
);
821 WS_XML_STRING
*alloc_xml_string( const unsigned char *data
, ULONG len
)
825 if (!(ret
= heap_alloc( sizeof(*ret
) + len
))) return NULL
;
827 ret
->bytes
= len
? (BYTE
*)(ret
+ 1) : NULL
;
828 ret
->dictionary
= NULL
;
830 if (data
) memcpy( ret
->bytes
, data
, len
);
834 WS_XML_UTF8_TEXT
*alloc_utf8_text( const unsigned char *data
, ULONG len
)
836 WS_XML_UTF8_TEXT
*ret
;
838 if (!(ret
= heap_alloc( sizeof(*ret
) + len
))) return NULL
;
839 ret
->text
.textType
= WS_XML_TEXT_TYPE_UTF8
;
840 ret
->value
.length
= len
;
841 ret
->value
.bytes
= len
? (BYTE
*)(ret
+ 1) : NULL
;
842 ret
->value
.dictionary
= NULL
;
844 if (data
) memcpy( ret
->value
.bytes
, data
, len
);
848 static inline BOOL
read_end_of_data( struct reader
*reader
)
850 return reader
->read_pos
>= reader
->read_size
;
853 static inline const unsigned char *read_current_ptr( struct reader
*reader
)
855 return &reader
->read_bufptr
[reader
->read_pos
];
858 /* UTF-8 support based on libs/wine/utf8.c */
860 /* number of following bytes in sequence based on first byte value (for bytes above 0x7f) */
861 static const char utf8_length
[128] =
863 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x80-0x8f */
864 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x90-0x9f */
865 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xa0-0xaf */
866 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xb0-0xbf */
867 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0xc0-0xcf */
868 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0xd0-0xdf */
869 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, /* 0xe0-0xef */
870 3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0 /* 0xf0-0xff */
873 /* first byte mask depending on UTF-8 sequence length */
874 static const unsigned char utf8_mask
[4] = { 0x7f, 0x1f, 0x0f, 0x07 };
876 /* minimum Unicode value depending on UTF-8 sequence length */
877 static const unsigned int utf8_minval
[4] = { 0x0, 0x80, 0x800, 0x10000 };
879 static inline unsigned int read_utf8_char( struct reader
*reader
, unsigned int *skip
)
881 unsigned int len
, res
;
882 unsigned char ch
= reader
->read_bufptr
[reader
->read_pos
];
883 const unsigned char *end
;
885 if (reader
->read_pos
>= reader
->read_size
) return 0;
892 len
= utf8_length
[ch
- 0x80];
893 if (reader
->read_pos
+ len
>= reader
->read_size
) return 0;
894 end
= reader
->read_bufptr
+ reader
->read_pos
+ len
;
895 res
= ch
& utf8_mask
[len
];
900 if ((ch
= end
[-3] ^ 0x80) >= 0x40) break;
901 res
= (res
<< 6) | ch
;
903 if ((ch
= end
[-2] ^ 0x80) >= 0x40) break;
904 res
= (res
<< 6) | ch
;
906 if ((ch
= end
[-1] ^ 0x80) >= 0x40) break;
907 res
= (res
<< 6) | ch
;
908 if (res
< utf8_minval
[len
]) break;
916 static inline void read_skip( struct reader
*reader
, unsigned int count
)
918 if (reader
->read_pos
+ count
> reader
->read_size
) return;
919 reader
->read_pos
+= count
;
922 static inline BOOL
read_isnamechar( unsigned int ch
)
924 /* FIXME: incomplete */
925 return (ch
>= 'A' && ch
<= 'Z') ||
926 (ch
>= 'a' && ch
<= 'z') ||
927 (ch
>= '0' && ch
<= '9') ||
928 ch
== '_' || ch
== '-' || ch
== '.' || ch
== ':';
931 static inline BOOL
read_isspace( unsigned int ch
)
933 return ch
== ' ' || ch
== '\t' || ch
== '\r' || ch
== '\n';
936 static inline void read_skip_whitespace( struct reader
*reader
)
938 while (reader
->read_pos
< reader
->read_size
&& read_isspace( reader
->read_bufptr
[reader
->read_pos
] ))
942 static inline int read_cmp( struct reader
*reader
, const char *str
, int len
)
944 const unsigned char *ptr
= read_current_ptr( reader
);
946 if (len
< 0) len
= strlen( str
);
947 if (reader
->read_pos
+ len
> reader
->read_size
) return -1;
950 if (*str
!= *ptr
) return *ptr
- *str
;
956 static HRESULT
read_xmldecl( struct reader
*reader
)
958 if (!reader
->read_size
) return WS_E_INVALID_FORMAT
;
960 if (read_cmp( reader
, "<", 1 ) || read_cmp( reader
, "<?", 2 ))
962 reader
->state
= READER_STATE_BOF
;
965 if (read_cmp( reader
, "<?xml ", 6 )) return WS_E_INVALID_FORMAT
;
966 read_skip( reader
, 6 );
968 /* FIXME: parse attributes */
969 while (reader
->read_pos
< reader
->read_size
&& reader
->read_bufptr
[reader
->read_pos
] != '?')
972 if (read_cmp( reader
, "?>", 2 )) return WS_E_INVALID_FORMAT
;
973 read_skip( reader
, 2 );
975 reader
->state
= READER_STATE_BOF
;
979 HRESULT
append_attribute( WS_XML_ELEMENT_NODE
*elem
, WS_XML_ATTRIBUTE
*attr
)
981 if (elem
->attributeCount
)
983 WS_XML_ATTRIBUTE
**tmp
;
984 if (!(tmp
= heap_realloc( elem
->attributes
, (elem
->attributeCount
+ 1) * sizeof(attr
) )))
985 return E_OUTOFMEMORY
;
986 elem
->attributes
= tmp
;
988 else if (!(elem
->attributes
= heap_alloc( sizeof(attr
) ))) return E_OUTOFMEMORY
;
989 elem
->attributes
[elem
->attributeCount
++] = attr
;
993 static HRESULT
parse_name( const unsigned char *str
, unsigned int len
,
994 WS_XML_STRING
**prefix
, WS_XML_STRING
**localname
)
996 const unsigned char *name_ptr
= str
, *prefix_ptr
= NULL
;
997 unsigned int i
, name_len
= len
, prefix_len
= 0;
999 for (i
= 0; i
< len
; i
++)
1005 name_ptr
= &str
[i
+ 1];
1010 if (!(*prefix
= alloc_xml_string( prefix_ptr
, prefix_len
))) return E_OUTOFMEMORY
;
1011 if (!(*localname
= alloc_xml_string( name_ptr
, name_len
)))
1013 heap_free( *prefix
);
1014 return E_OUTOFMEMORY
;
1019 static HRESULT
read_attribute( struct reader
*reader
, WS_XML_ATTRIBUTE
**ret
)
1021 static const WS_XML_STRING xmlns
= {5, (BYTE
*)"xmlns"};
1022 WS_XML_ATTRIBUTE
*attr
;
1023 WS_XML_UTF8_TEXT
*text
;
1024 unsigned int len
= 0, ch
, skip
, quote
;
1025 const unsigned char *start
;
1026 WS_XML_STRING
*prefix
, *localname
;
1027 HRESULT hr
= WS_E_INVALID_FORMAT
;
1029 if (!(attr
= heap_alloc_zero( sizeof(*attr
) ))) return E_OUTOFMEMORY
;
1031 start
= read_current_ptr( reader
);
1034 if (!(ch
= read_utf8_char( reader
, &skip
))) goto error
;
1035 if (!read_isnamechar( ch
)) break;
1036 read_skip( reader
, skip
);
1039 if (!len
) goto error
;
1041 if ((hr
= parse_name( start
, len
, &prefix
, &localname
)) != S_OK
) goto error
;
1043 if (WsXmlStringEquals( prefix
, &xmlns
, NULL
) == S_OK
)
1045 heap_free( prefix
);
1047 if (!(attr
->prefix
= alloc_xml_string( localname
->bytes
, localname
->length
)))
1049 heap_free( localname
);
1052 attr
->localName
= localname
;
1054 else if (!prefix
->length
&& WsXmlStringEquals( localname
, &xmlns
, NULL
) == S_OK
)
1057 attr
->prefix
= prefix
;
1058 attr
->localName
= localname
;
1062 attr
->prefix
= prefix
;
1063 attr
->localName
= localname
;
1066 hr
= WS_E_INVALID_FORMAT
;
1067 read_skip_whitespace( reader
);
1068 if (read_cmp( reader
, "=", 1 )) goto error
;
1069 read_skip( reader
, 1 );
1071 read_skip_whitespace( reader
);
1072 if (read_cmp( reader
, "\"", 1 ) && read_cmp( reader
, "'", 1 )) goto error
;
1073 quote
= read_utf8_char( reader
, &skip
);
1074 read_skip( reader
, 1 );
1077 start
= read_current_ptr( reader
);
1080 if (!(ch
= read_utf8_char( reader
, &skip
))) goto error
;
1081 if (ch
== quote
) break;
1082 read_skip( reader
, skip
);
1085 read_skip( reader
, 1 );
1090 if (!(attr
->ns
= alloc_xml_string( start
, len
))) goto error
;
1091 if ((hr
= bind_prefix( reader
, attr
->prefix
, attr
->ns
)) != S_OK
) goto error
;
1092 if (!(text
= alloc_utf8_text( NULL
, 0 ))) goto error
;
1094 else if (!(text
= alloc_utf8_text( start
, len
))) goto error
;
1096 attr
->value
= &text
->text
;
1097 attr
->singleQuote
= (quote
== '\'');
1103 free_attribute( attr
);
1107 static int cmp_name( const unsigned char *name1
, ULONG len1
, const unsigned char *name2
, ULONG len2
)
1110 if (len1
!= len2
) return 1;
1111 for (i
= 0; i
< len1
; i
++) { if (toupper( name1
[i
] ) != toupper( name2
[i
] )) return 1; }
1115 static struct node
*read_find_parent( struct reader
*reader
, const WS_XML_STRING
*prefix
,
1116 const WS_XML_STRING
*localname
)
1118 struct node
*parent
;
1119 const WS_XML_STRING
*str
;
1121 for (parent
= reader
->current
; parent
; parent
= parent
->parent
)
1123 if (node_type( parent
) == WS_XML_NODE_TYPE_BOF
)
1125 if (!localname
) return parent
;
1128 else if (node_type( parent
) == WS_XML_NODE_TYPE_ELEMENT
)
1130 if (!localname
) return parent
;
1132 str
= parent
->hdr
.prefix
;
1133 if (cmp_name( str
->bytes
, str
->length
, prefix
->bytes
, prefix
->length
)) continue;
1134 str
= parent
->hdr
.localName
;
1135 if (cmp_name( str
->bytes
, str
->length
, localname
->bytes
, localname
->length
)) continue;
1143 static HRESULT
set_namespaces( struct reader
*reader
, WS_XML_ELEMENT_NODE
*elem
)
1145 static const WS_XML_STRING xml
= {3, (BYTE
*)"xml"};
1146 const WS_XML_STRING
*ns
;
1149 if (!(ns
= get_namespace( reader
, elem
->prefix
))) return WS_E_INVALID_FORMAT
;
1150 if (!(elem
->ns
= alloc_xml_string( ns
->bytes
, ns
->length
))) return E_OUTOFMEMORY
;
1151 if (!elem
->ns
->length
) elem
->ns
->bytes
= (BYTE
*)(elem
->ns
+ 1); /* quirk */
1153 for (i
= 0; i
< elem
->attributeCount
; i
++)
1155 WS_XML_ATTRIBUTE
*attr
= elem
->attributes
[i
];
1156 if (attr
->isXmlNs
|| WsXmlStringEquals( attr
->prefix
, &xml
, NULL
) == S_OK
) continue;
1157 if (!(ns
= get_namespace( reader
, attr
->prefix
))) return WS_E_INVALID_FORMAT
;
1158 if (!(attr
->ns
= alloc_xml_string( ns
->bytes
, ns
->length
))) return E_OUTOFMEMORY
;
1163 static HRESULT
read_element( struct reader
*reader
)
1165 unsigned int len
= 0, ch
, skip
;
1166 const unsigned char *start
;
1167 struct node
*node
= NULL
, *parent
;
1168 WS_XML_ELEMENT_NODE
*elem
;
1169 WS_XML_ATTRIBUTE
*attr
= NULL
;
1170 HRESULT hr
= WS_E_INVALID_FORMAT
;
1172 if (read_end_of_data( reader
))
1174 struct list
*eof
= list_tail( &reader
->root
->children
);
1175 reader
->current
= LIST_ENTRY( eof
, struct node
, entry
);
1176 reader
->state
= READER_STATE_EOF
;
1180 if (read_cmp( reader
, "<", 1 )) goto error
;
1181 read_skip( reader
, 1 );
1183 start
= read_current_ptr( reader
);
1186 if (!(ch
= read_utf8_char( reader
, &skip
))) goto error
;
1187 if (!read_isnamechar( ch
)) break;
1188 read_skip( reader
, skip
);
1191 if (!len
) goto error
;
1193 if (!(parent
= read_find_parent( reader
, NULL
, NULL
))) goto error
;
1196 if (!(node
= alloc_node( WS_XML_NODE_TYPE_ELEMENT
))) goto error
;
1197 elem
= (WS_XML_ELEMENT_NODE
*)node
;
1198 if ((hr
= parse_name( start
, len
, &elem
->prefix
, &elem
->localName
)) != S_OK
) goto error
;
1200 reader
->current_attr
= 0;
1203 read_skip_whitespace( reader
);
1204 if (!read_cmp( reader
, ">", 1 ) || !read_cmp( reader
, "/>", 2 )) break;
1205 if ((hr
= read_attribute( reader
, &attr
)) != S_OK
) goto error
;
1206 if ((hr
= append_attribute( elem
, attr
)) != S_OK
)
1208 free_attribute( attr
);
1211 reader
->current_attr
++;
1213 if ((hr
= set_namespaces( reader
, elem
)) != S_OK
) goto error
;
1215 read_insert_node( reader
, parent
, node
);
1216 reader
->state
= READER_STATE_STARTELEMENT
;
1224 static HRESULT
read_text( struct reader
*reader
)
1226 unsigned int len
= 0, ch
, skip
;
1227 const unsigned char *start
;
1229 WS_XML_TEXT_NODE
*text
;
1230 WS_XML_UTF8_TEXT
*utf8
;
1232 start
= read_current_ptr( reader
);
1235 if (read_end_of_data( reader
)) break;
1236 if (!(ch
= read_utf8_char( reader
, &skip
))) return WS_E_INVALID_FORMAT
;
1237 if (ch
== '<') break;
1238 read_skip( reader
, skip
);
1242 if (!(node
= alloc_node( WS_XML_NODE_TYPE_TEXT
))) return E_OUTOFMEMORY
;
1243 text
= (WS_XML_TEXT_NODE
*)node
;
1244 if (!(utf8
= alloc_utf8_text( start
, len
)))
1247 return E_OUTOFMEMORY
;
1249 text
->text
= &utf8
->text
;
1251 read_insert_node( reader
, reader
->current
, node
);
1252 reader
->state
= READER_STATE_TEXT
;
1256 static HRESULT
read_node( struct reader
* );
1258 static HRESULT
read_startelement( struct reader
*reader
)
1262 read_skip_whitespace( reader
);
1263 if (!read_cmp( reader
, "/>", 2 ))
1265 read_skip( reader
, 2 );
1266 if (!(node
= alloc_node( WS_XML_NODE_TYPE_END_ELEMENT
))) return E_OUTOFMEMORY
;
1267 read_insert_node( reader
, reader
->current
, node
);
1268 reader
->state
= READER_STATE_ENDELEMENT
;
1271 else if (!read_cmp( reader
, ">", 1 ))
1273 read_skip( reader
, 1 );
1274 return read_node( reader
);
1276 return WS_E_INVALID_FORMAT
;
1279 static HRESULT
read_to_startelement( struct reader
*reader
, BOOL
*found
)
1283 switch (reader
->state
)
1285 case READER_STATE_INITIAL
:
1286 if ((hr
= read_xmldecl( reader
)) != S_OK
) return hr
;
1289 case READER_STATE_STARTELEMENT
:
1290 if (found
) *found
= TRUE
;
1297 read_skip_whitespace( reader
);
1298 if ((hr
= read_element( reader
)) == S_OK
&& found
)
1300 if (reader
->state
== READER_STATE_STARTELEMENT
)
1309 static HRESULT
read_endelement( struct reader
*reader
)
1311 struct node
*node
, *parent
;
1312 unsigned int len
= 0, ch
, skip
;
1313 const unsigned char *start
;
1314 WS_XML_STRING
*prefix
, *localname
;
1317 if (reader
->state
== READER_STATE_EOF
) return WS_E_INVALID_FORMAT
;
1319 if (read_end_of_data( reader
))
1321 struct list
*eof
= list_tail( &reader
->root
->children
);
1322 reader
->current
= LIST_ENTRY( eof
, struct node
, entry
);
1323 reader
->state
= READER_STATE_EOF
;
1327 if (read_cmp( reader
, "</", 2 )) return WS_E_INVALID_FORMAT
;
1328 read_skip( reader
, 2 );
1330 start
= read_current_ptr( reader
);
1333 if (!(ch
= read_utf8_char( reader
, &skip
))) return WS_E_INVALID_FORMAT
;
1336 read_skip( reader
, 1 );
1339 if (!read_isnamechar( ch
)) return WS_E_INVALID_FORMAT
;
1340 read_skip( reader
, skip
);
1344 if ((hr
= parse_name( start
, len
, &prefix
, &localname
)) != S_OK
) return hr
;
1345 parent
= read_find_parent( reader
, prefix
, localname
);
1346 heap_free( prefix
);
1347 heap_free( localname
);
1348 if (!parent
) return WS_E_INVALID_FORMAT
;
1350 if (!(node
= alloc_node( WS_XML_NODE_TYPE_END_ELEMENT
))) return E_OUTOFMEMORY
;
1351 read_insert_node( reader
, parent
, node
);
1352 reader
->state
= READER_STATE_ENDELEMENT
;
1356 static HRESULT
read_comment( struct reader
*reader
)
1358 unsigned int len
= 0, ch
, skip
;
1359 const unsigned char *start
;
1361 WS_XML_COMMENT_NODE
*comment
;
1363 if (read_cmp( reader
, "<!--", 4 )) return WS_E_INVALID_FORMAT
;
1364 read_skip( reader
, 4 );
1366 start
= read_current_ptr( reader
);
1369 if (!read_cmp( reader
, "-->", 3 ))
1371 read_skip( reader
, 3 );
1374 if (!(ch
= read_utf8_char( reader
, &skip
))) return WS_E_INVALID_FORMAT
;
1375 read_skip( reader
, skip
);
1379 if (!(node
= alloc_node( WS_XML_NODE_TYPE_COMMENT
))) return E_OUTOFMEMORY
;
1380 comment
= (WS_XML_COMMENT_NODE
*)node
;
1381 if (!(comment
->value
.bytes
= heap_alloc( len
)))
1384 return E_OUTOFMEMORY
;
1386 memcpy( comment
->value
.bytes
, start
, len
);
1387 comment
->value
.length
= len
;
1389 read_insert_node( reader
, reader
->current
, node
);
1390 reader
->state
= READER_STATE_COMMENT
;
1394 static HRESULT
read_startcdata( struct reader
*reader
)
1398 if (read_cmp( reader
, "<![CDATA[", 9 )) return WS_E_INVALID_FORMAT
;
1399 read_skip( reader
, 9 );
1401 if (!(node
= alloc_node( WS_XML_NODE_TYPE_CDATA
))) return E_OUTOFMEMORY
;
1402 read_insert_node( reader
, reader
->current
, node
);
1403 reader
->state
= READER_STATE_STARTCDATA
;
1407 static HRESULT
read_cdata( struct reader
*reader
)
1409 unsigned int len
= 0, ch
, skip
;
1410 const unsigned char *start
;
1412 WS_XML_TEXT_NODE
*text
;
1413 WS_XML_UTF8_TEXT
*utf8
;
1415 start
= read_current_ptr( reader
);
1418 if (!read_cmp( reader
, "]]>", 3 )) break;
1419 if (!(ch
= read_utf8_char( reader
, &skip
))) return WS_E_INVALID_FORMAT
;
1420 read_skip( reader
, skip
);
1424 if (!(node
= alloc_node( WS_XML_NODE_TYPE_TEXT
))) return E_OUTOFMEMORY
;
1425 text
= (WS_XML_TEXT_NODE
*)node
;
1426 if (!(utf8
= alloc_utf8_text( start
, len
)))
1429 return E_OUTOFMEMORY
;
1431 text
->text
= &utf8
->text
;
1433 read_insert_node( reader
, reader
->current
, node
);
1434 reader
->state
= READER_STATE_CDATA
;
1438 static HRESULT
read_endcdata( struct reader
*reader
)
1442 if (read_cmp( reader
, "]]>", 3 )) return WS_E_INVALID_FORMAT
;
1443 read_skip( reader
, 3 );
1445 if (!(node
= alloc_node( WS_XML_NODE_TYPE_END_CDATA
))) return E_OUTOFMEMORY
;
1446 read_insert_node( reader
, reader
->current
->parent
, node
);
1447 reader
->state
= READER_STATE_ENDCDATA
;
1451 static HRESULT
read_node( struct reader
*reader
)
1457 if (read_end_of_data( reader
))
1459 struct list
*eof
= list_tail( &reader
->root
->children
);
1460 reader
->current
= LIST_ENTRY( eof
, struct node
, entry
);
1461 reader
->state
= READER_STATE_EOF
;
1464 if (reader
->state
== READER_STATE_STARTCDATA
) return read_cdata( reader
);
1465 else if (reader
->state
== READER_STATE_CDATA
) return read_endcdata( reader
);
1466 else if (!read_cmp( reader
, "<?", 2 ))
1468 hr
= read_xmldecl( reader
);
1469 if (FAILED( hr
)) return hr
;
1471 else if (!read_cmp( reader
, "</", 2 )) return read_endelement( reader
);
1472 else if (!read_cmp( reader
, "<![CDATA[", 9 )) return read_startcdata( reader
);
1473 else if (!read_cmp( reader
, "<!--", 4 )) return read_comment( reader
);
1474 else if (!read_cmp( reader
, "<", 1 )) return read_element( reader
);
1475 else if (!read_cmp( reader
, "/>", 2 ) || !read_cmp( reader
, ">", 1 )) return read_startelement( reader
);
1476 else return read_text( reader
);
1480 /**************************************************************************
1481 * WsReadEndElement [webservices.@]
1483 HRESULT WINAPI
WsReadEndElement( WS_XML_READER
*handle
, WS_ERROR
*error
)
1485 struct reader
*reader
= (struct reader
*)handle
;
1487 TRACE( "%p %p\n", handle
, error
);
1488 if (error
) FIXME( "ignoring error parameter\n" );
1490 if (!reader
) return E_INVALIDARG
;
1491 return read_endelement( reader
);
1494 /**************************************************************************
1495 * WsReadNode [webservices.@]
1497 HRESULT WINAPI
WsReadNode( WS_XML_READER
*handle
, WS_ERROR
*error
)
1499 struct reader
*reader
= (struct reader
*)handle
;
1501 TRACE( "%p %p\n", handle
, error
);
1502 if (error
) FIXME( "ignoring error parameter\n" );
1504 if (!reader
) return E_INVALIDARG
;
1505 return read_node( reader
);
1508 /**************************************************************************
1509 * WsReadStartElement [webservices.@]
1511 HRESULT WINAPI
WsReadStartElement( WS_XML_READER
*handle
, WS_ERROR
*error
)
1513 struct reader
*reader
= (struct reader
*)handle
;
1515 TRACE( "%p %p\n", handle
, error
);
1516 if (error
) FIXME( "ignoring error parameter\n" );
1518 if (!reader
) return E_INVALIDARG
;
1519 return read_startelement( reader
);
1522 /**************************************************************************
1523 * WsReadToStartElement [webservices.@]
1525 HRESULT WINAPI
WsReadToStartElement( WS_XML_READER
*handle
, const WS_XML_STRING
*localname
,
1526 const WS_XML_STRING
*ns
, BOOL
*found
, WS_ERROR
*error
)
1528 struct reader
*reader
= (struct reader
*)handle
;
1530 TRACE( "%p %s %s %p %p\n", handle
, debugstr_xmlstr(localname
), debugstr_xmlstr(ns
), found
, error
);
1531 if (error
) FIXME( "ignoring error parameter\n" );
1533 if (!reader
) return E_INVALIDARG
;
1534 if (localname
|| ns
) FIXME( "name and/or namespace not verified\n" );
1536 return read_to_startelement( reader
, found
);
1539 static BOOL
move_to_root_element( struct reader
*reader
)
1544 if (!(ptr
= list_head( &reader
->root
->children
))) return FALSE
;
1545 node
= LIST_ENTRY( ptr
, struct node
, entry
);
1546 if (node_type( node
) == WS_XML_NODE_TYPE_ELEMENT
)
1548 reader
->current
= node
;
1551 while ((ptr
= list_next( &reader
->root
->children
, &node
->entry
)))
1553 struct node
*next
= LIST_ENTRY( ptr
, struct node
, entry
);
1554 if (node_type( next
) == WS_XML_NODE_TYPE_ELEMENT
)
1556 reader
->current
= next
;
1564 static BOOL
move_to_next_element( struct reader
*reader
)
1567 struct node
*node
= reader
->current
;
1569 while ((ptr
= list_next( &node
->parent
->children
, &node
->entry
)))
1571 struct node
*next
= LIST_ENTRY( ptr
, struct node
, entry
);
1572 if (node_type( next
) == WS_XML_NODE_TYPE_ELEMENT
)
1574 reader
->current
= next
;
1582 static BOOL
move_to_prev_element( struct reader
*reader
)
1585 struct node
*node
= reader
->current
;
1587 while ((ptr
= list_prev( &node
->parent
->children
, &node
->entry
)))
1589 struct node
*prev
= LIST_ENTRY( ptr
, struct node
, entry
);
1590 if (node_type( prev
) == WS_XML_NODE_TYPE_ELEMENT
)
1592 reader
->current
= prev
;
1600 static BOOL
move_to_child_element( struct reader
*reader
)
1605 if (!(ptr
= list_head( &reader
->current
->children
))) return FALSE
;
1606 node
= LIST_ENTRY( ptr
, struct node
, entry
);
1607 if (node_type( node
) == WS_XML_NODE_TYPE_ELEMENT
)
1609 reader
->current
= node
;
1612 while ((ptr
= list_next( &reader
->current
->children
, &node
->entry
)))
1614 struct node
*next
= LIST_ENTRY( ptr
, struct node
, entry
);
1615 if (node_type( next
) == WS_XML_NODE_TYPE_ELEMENT
)
1617 reader
->current
= next
;
1625 static BOOL
move_to_end_element( struct reader
*reader
)
1628 struct node
*node
= reader
->current
;
1630 if (node_type( node
) != WS_XML_NODE_TYPE_ELEMENT
) return FALSE
;
1632 if ((ptr
= list_tail( &node
->children
)))
1634 struct node
*tail
= LIST_ENTRY( ptr
, struct node
, entry
);
1635 if (node_type( tail
) == WS_XML_NODE_TYPE_END_ELEMENT
)
1637 reader
->current
= tail
;
1644 static BOOL
move_to_parent_element( struct reader
*reader
)
1646 struct node
*parent
= reader
->current
->parent
;
1648 if (parent
&& (node_type( parent
) == WS_XML_NODE_TYPE_ELEMENT
||
1649 node_type( parent
) == WS_XML_NODE_TYPE_BOF
))
1651 reader
->current
= parent
;
1657 static HRESULT
read_move_to( struct reader
*reader
, WS_MOVE_TO move
, BOOL
*found
)
1660 BOOL success
= FALSE
;
1663 if (!read_end_of_data( reader
))
1665 while (reader
->state
!= READER_STATE_EOF
&& (hr
= read_node( reader
)) == S_OK
) { /* nothing */ };
1666 if (hr
!= S_OK
) return hr
;
1670 case WS_MOVE_TO_ROOT_ELEMENT
:
1671 success
= move_to_root_element( reader
);
1674 case WS_MOVE_TO_NEXT_ELEMENT
:
1675 success
= move_to_next_element( reader
);
1678 case WS_MOVE_TO_PREVIOUS_ELEMENT
:
1679 success
= move_to_prev_element( reader
);
1682 case WS_MOVE_TO_CHILD_ELEMENT
:
1683 success
= move_to_child_element( reader
);
1686 case WS_MOVE_TO_END_ELEMENT
:
1687 success
= move_to_end_element( reader
);
1690 case WS_MOVE_TO_PARENT_ELEMENT
:
1691 success
= move_to_parent_element( reader
);
1694 case WS_MOVE_TO_FIRST_NODE
:
1695 if ((ptr
= list_head( &reader
->current
->parent
->children
)))
1697 reader
->current
= LIST_ENTRY( ptr
, struct node
, entry
);
1702 case WS_MOVE_TO_NEXT_NODE
:
1703 if ((ptr
= list_next( &reader
->current
->parent
->children
, &reader
->current
->entry
)))
1705 reader
->current
= LIST_ENTRY( ptr
, struct node
, entry
);
1710 case WS_MOVE_TO_PREVIOUS_NODE
:
1711 if ((ptr
= list_prev( &reader
->current
->parent
->children
, &reader
->current
->entry
)))
1713 reader
->current
= LIST_ENTRY( ptr
, struct node
, entry
);
1718 case WS_MOVE_TO_CHILD_NODE
:
1719 if ((ptr
= list_head( &reader
->current
->children
)))
1721 reader
->current
= LIST_ENTRY( ptr
, struct node
, entry
);
1726 case WS_MOVE_TO_BOF
:
1727 reader
->current
= reader
->root
;
1731 case WS_MOVE_TO_EOF
:
1732 if ((ptr
= list_tail( &reader
->root
->children
)))
1734 reader
->current
= LIST_ENTRY( ptr
, struct node
, entry
);
1740 FIXME( "unhandled move %u\n", move
);
1749 return success
? S_OK
: WS_E_INVALID_FORMAT
;
1752 /**************************************************************************
1753 * WsMoveReader [webservices.@]
1755 HRESULT WINAPI
WsMoveReader( WS_XML_READER
*handle
, WS_MOVE_TO move
, BOOL
*found
, WS_ERROR
*error
)
1757 struct reader
*reader
= (struct reader
*)handle
;
1759 TRACE( "%p %u %p %p\n", handle
, move
, found
, error
);
1760 if (error
) FIXME( "ignoring error parameter\n" );
1762 if (!reader
) return E_INVALIDARG
;
1763 if (!reader
->input_type
) return WS_E_INVALID_OPERATION
;
1765 return read_move_to( reader
, move
, found
);
1768 /**************************************************************************
1769 * WsReadStartAttribute [webservices.@]
1771 HRESULT WINAPI
WsReadStartAttribute( WS_XML_READER
*handle
, ULONG index
, WS_ERROR
*error
)
1773 struct reader
*reader
= (struct reader
*)handle
;
1774 WS_XML_ELEMENT_NODE
*elem
;
1776 TRACE( "%p %u %p\n", handle
, index
, error
);
1777 if (error
) FIXME( "ignoring error parameter\n" );
1779 if (!reader
) return E_INVALIDARG
;
1781 elem
= &reader
->current
->hdr
;
1782 if (reader
->state
!= READER_STATE_STARTELEMENT
|| index
>= elem
->attributeCount
)
1783 return WS_E_INVALID_FORMAT
;
1785 reader
->current_attr
= index
;
1786 reader
->state
= READER_STATE_STARTATTRIBUTE
;
1790 /**************************************************************************
1791 * WsReadEndAttribute [webservices.@]
1793 HRESULT WINAPI
WsReadEndAttribute( WS_XML_READER
*handle
, WS_ERROR
*error
)
1795 struct reader
*reader
= (struct reader
*)handle
;
1797 TRACE( "%p %p\n", handle
, error
);
1798 if (error
) FIXME( "ignoring error parameter\n" );
1800 if (!reader
) return E_INVALIDARG
;
1802 if (reader
->state
!= READER_STATE_STARTATTRIBUTE
)
1803 return WS_E_INVALID_FORMAT
;
1805 reader
->state
= READER_STATE_STARTELEMENT
;
1809 static WCHAR
*xmltext_to_widechar( WS_HEAP
*heap
, const WS_XML_TEXT
*text
)
1813 switch (text
->textType
)
1815 case WS_XML_TEXT_TYPE_UTF8
:
1817 const WS_XML_UTF8_TEXT
*utf8
= (const WS_XML_UTF8_TEXT
*)text
;
1818 int len
= MultiByteToWideChar( CP_UTF8
, 0, (char *)utf8
->value
.bytes
, utf8
->value
.length
, NULL
, 0 );
1819 if (!(ret
= ws_alloc( heap
, (len
+ 1) * sizeof(WCHAR
) ))) return NULL
;
1820 MultiByteToWideChar( CP_UTF8
, 0, (char *)utf8
->value
.bytes
, utf8
->value
.length
, ret
, len
);
1825 FIXME( "unhandled type %u\n", text
->textType
);
1832 #define MAX_INT8 0x7f
1833 #define MIN_INT8 (-MAX_INT8 - 1)
1834 #define MAX_INT16 0x7fff
1835 #define MIN_INT16 (-MAX_INT16 - 1)
1836 #define MAX_INT32 0x7fffffff
1837 #define MIN_INT32 (-MAX_INT32 - 1)
1838 #define MAX_INT64 (((INT64)0x7fffffff << 32) | 0xffffffff)
1839 #define MIN_INT64 (-MAX_INT64 - 1)
1840 #define MAX_UINT8 0xff
1841 #define MAX_UINT16 0xffff
1842 #define MAX_UINT32 0xffffffff
1843 #define MAX_UINT64 (((UINT64)0xffffffff << 32) | 0xffffffff)
1845 static HRESULT
str_to_int64( const unsigned char *str
, ULONG len
, INT64 min
, INT64 max
, INT64
*ret
)
1847 BOOL negative
= FALSE
;
1848 const unsigned char *ptr
= str
;
1851 while (len
&& read_isspace( *ptr
)) { ptr
++; len
--; }
1852 while (len
&& read_isspace( ptr
[len
- 1] )) { len
--; }
1853 if (!len
) return WS_E_INVALID_FORMAT
;
1861 if (!len
) return WS_E_INVALID_FORMAT
;
1867 if (!isdigit( *ptr
)) return WS_E_INVALID_FORMAT
;
1869 if (negative
) val
= -val
;
1871 if ((!negative
&& (*ret
> max
/ 10 || *ret
* 10 > max
- val
)) ||
1872 (negative
&& (*ret
< min
/ 10 || *ret
* 10 < min
- val
)))
1874 return WS_E_NUMERIC_OVERFLOW
;
1876 *ret
= *ret
* 10 + val
;
1883 static HRESULT
str_to_uint64( const unsigned char *str
, ULONG len
, UINT64 max
, UINT64
*ret
)
1885 const unsigned char *ptr
= str
;
1888 while (len
&& read_isspace( *ptr
)) { ptr
++; len
--; }
1889 while (len
&& read_isspace( ptr
[len
- 1] )) { len
--; }
1890 if (!len
) return WS_E_INVALID_FORMAT
;
1896 if (!isdigit( *ptr
)) return WS_E_INVALID_FORMAT
;
1899 if ((*ret
> max
/ 10 || *ret
* 10 > max
- val
)) return WS_E_NUMERIC_OVERFLOW
;
1900 *ret
= *ret
* 10 + val
;
1907 static HRESULT
read_get_node_text( struct reader
*reader
, WS_XML_UTF8_TEXT
**ret
)
1909 WS_XML_TEXT_NODE
*text
;
1911 if (node_type( reader
->current
) != WS_XML_NODE_TYPE_TEXT
)
1912 return WS_E_INVALID_FORMAT
;
1914 text
= (WS_XML_TEXT_NODE
*)&reader
->current
->hdr
.node
;
1915 if (text
->text
->textType
!= WS_XML_TEXT_TYPE_UTF8
)
1917 FIXME( "text type %u not supported\n", text
->text
->textType
);
1920 *ret
= (WS_XML_UTF8_TEXT
*)text
->text
;
1924 static HRESULT
read_get_attribute_text( struct reader
*reader
, ULONG index
, WS_XML_UTF8_TEXT
**ret
)
1926 WS_XML_ELEMENT_NODE
*elem
= &reader
->current
->hdr
;
1927 WS_XML_ATTRIBUTE
*attr
;
1929 if (node_type( reader
->current
) != WS_XML_NODE_TYPE_ELEMENT
)
1930 return WS_E_INVALID_FORMAT
;
1932 attr
= elem
->attributes
[index
];
1933 if (attr
->value
->textType
!= WS_XML_TEXT_TYPE_UTF8
)
1935 FIXME( "text type %u not supported\n", attr
->value
->textType
);
1938 *ret
= (WS_XML_UTF8_TEXT
*)attr
->value
;
1942 static BOOL
find_attribute( struct reader
*reader
, const WS_XML_STRING
*localname
,
1943 const WS_XML_STRING
*ns
, ULONG
*index
)
1946 WS_XML_ELEMENT_NODE
*elem
= &reader
->current
->hdr
;
1950 *index
= reader
->current_attr
;
1953 for (i
= 0; i
< elem
->attributeCount
; i
++)
1955 const WS_XML_STRING
*localname2
= elem
->attributes
[i
]->localName
;
1956 const WS_XML_STRING
*ns2
= elem
->attributes
[i
]->ns
;
1958 if (!cmp_name( localname
->bytes
, localname
->length
, localname2
->bytes
, localname2
->length
) &&
1959 !cmp_name( ns
->bytes
, ns
->length
, ns2
->bytes
, ns2
->length
))
1968 /**************************************************************************
1969 * WsFindAttribute [webservices.@]
1971 HRESULT WINAPI
WsFindAttribute( WS_XML_READER
*handle
, const WS_XML_STRING
*localname
,
1972 const WS_XML_STRING
*ns
, BOOL required
, ULONG
*index
,
1975 struct reader
*reader
= (struct reader
*)handle
;
1977 TRACE( "%p %s %s %d %p %p\n", handle
, debugstr_xmlstr(localname
), debugstr_xmlstr(ns
),
1978 required
, index
, error
);
1979 if (error
) FIXME( "ignoring error parameter\n" );
1981 if (!reader
|| !localname
|| !ns
|| !index
) return E_INVALIDARG
;
1983 if (node_type( reader
->current
) != WS_XML_NODE_TYPE_ELEMENT
)
1984 return WS_E_INVALID_OPERATION
;
1986 if (!find_attribute( reader
, localname
, ns
, index
))
1988 if (required
) return WS_E_INVALID_FORMAT
;
1995 static HRESULT
read_get_text( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
1996 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
,
1997 WS_XML_UTF8_TEXT
**ret
, BOOL
*found
)
2001 case WS_ATTRIBUTE_TYPE_MAPPING
:
2004 if (!(*found
= find_attribute( reader
, localname
, ns
, &index
))) return S_OK
;
2005 return read_get_attribute_text( reader
, index
, ret
);
2007 case WS_ELEMENT_TYPE_MAPPING
:
2008 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
2014 const WS_XML_ELEMENT_NODE
*elem
= &reader
->current
->hdr
;
2016 if (WsXmlStringEquals( localname
, elem
->localName
, NULL
) != S_OK
||
2017 WsXmlStringEquals( ns
, elem
->ns
, NULL
) != S_OK
)
2022 if ((hr
= read_startelement( reader
)) != S_OK
) return hr
;
2024 return read_get_node_text( reader
, ret
);
2027 FIXME( "mapping %u not supported\n", mapping
);
2032 static HRESULT
read_type_bool( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2033 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
,
2034 const WS_BOOL_DESCRIPTION
*desc
, WS_READ_OPTION option
,
2035 WS_HEAP
*heap
, void *ret
, ULONG size
)
2037 WS_XML_UTF8_TEXT
*utf8
;
2039 BOOL found
, val
= FALSE
;
2043 FIXME( "description not supported\n" );
2046 if ((hr
= read_get_text( reader
, mapping
, localname
, ns
, &utf8
, &found
)) != S_OK
) return hr
;
2049 ULONG len
= utf8
->value
.length
;
2050 if (len
== 4 && !memcmp( utf8
->value
.bytes
, "true", 4 )) val
= TRUE
;
2051 else if (len
== 1 && !memcmp( utf8
->value
.bytes
, "1", 1 )) val
= TRUE
;
2052 else if (len
== 5 && !memcmp( utf8
->value
.bytes
, "false", 5 )) val
= FALSE
;
2053 else if (len
== 1 && !memcmp( utf8
->value
.bytes
, "0", 1 )) val
= FALSE
;
2054 else return WS_E_INVALID_FORMAT
;
2059 case WS_READ_REQUIRED_VALUE
:
2060 if (!found
) return WS_E_INVALID_FORMAT
;
2061 if (size
!= sizeof(BOOL
)) return E_INVALIDARG
;
2065 case WS_READ_REQUIRED_POINTER
:
2066 if (!found
) return WS_E_INVALID_FORMAT
;
2069 case WS_READ_OPTIONAL_POINTER
:
2071 BOOL
*heap_val
= NULL
;
2072 if (size
!= sizeof(heap_val
)) return E_INVALIDARG
;
2075 if (!(heap_val
= ws_alloc( heap
, sizeof(*heap_val
) ))) return WS_E_QUOTA_EXCEEDED
;
2078 *(BOOL
**)ret
= heap_val
;
2082 FIXME( "read option %u not supported\n", option
);
2089 static HRESULT
read_type_int8( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2090 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
,
2091 const WS_INT8_DESCRIPTION
*desc
, WS_READ_OPTION option
,
2092 WS_HEAP
*heap
, void *ret
, ULONG size
)
2094 WS_XML_UTF8_TEXT
*utf8
;
2101 FIXME( "description not supported\n" );
2104 if ((hr
= read_get_text( reader
, mapping
, localname
, ns
, &utf8
, &found
)) != S_OK
) return hr
;
2105 if (found
&& (hr
= str_to_int64( utf8
->value
.bytes
, utf8
->value
.length
, MIN_INT8
, MAX_INT8
, &val
)) != S_OK
)
2110 case WS_READ_REQUIRED_VALUE
:
2111 if (!found
) return WS_E_INVALID_FORMAT
;
2112 if (size
!= sizeof(INT8
)) return E_INVALIDARG
;
2116 case WS_READ_REQUIRED_POINTER
:
2117 if (!found
) return WS_E_INVALID_FORMAT
;
2120 case WS_READ_OPTIONAL_POINTER
:
2122 INT8
*heap_val
= NULL
;
2123 if (size
!= sizeof(heap_val
)) return E_INVALIDARG
;
2126 if (!(heap_val
= ws_alloc( heap
, sizeof(*heap_val
) ))) return WS_E_QUOTA_EXCEEDED
;
2129 *(INT8
**)ret
= heap_val
;
2133 FIXME( "read option %u not supported\n", option
);
2140 static HRESULT
read_type_int16( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2141 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
,
2142 const WS_INT16_DESCRIPTION
*desc
, WS_READ_OPTION option
,
2143 WS_HEAP
*heap
, void *ret
, ULONG size
)
2145 WS_XML_UTF8_TEXT
*utf8
;
2152 FIXME( "description not supported\n" );
2155 if ((hr
= read_get_text( reader
, mapping
, localname
, ns
, &utf8
, &found
)) != S_OK
) return hr
;
2156 if (found
&& (hr
= str_to_int64( utf8
->value
.bytes
, utf8
->value
.length
, MIN_INT16
, MAX_INT16
, &val
)) != S_OK
)
2161 case WS_READ_REQUIRED_VALUE
:
2162 if (!found
) return WS_E_INVALID_FORMAT
;
2163 if (size
!= sizeof(INT16
)) return E_INVALIDARG
;
2164 *(INT16
*)ret
= val
;
2167 case WS_READ_REQUIRED_POINTER
:
2168 if (!found
) return WS_E_INVALID_FORMAT
;
2171 case WS_READ_OPTIONAL_POINTER
:
2173 INT16
*heap_val
= NULL
;
2174 if (size
!= sizeof(heap_val
)) return E_INVALIDARG
;
2177 if (!(heap_val
= ws_alloc( heap
, sizeof(*heap_val
) ))) return WS_E_QUOTA_EXCEEDED
;
2180 *(INT16
**)ret
= heap_val
;
2184 FIXME( "read option %u not supported\n", option
);
2191 static HRESULT
read_type_int32( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2192 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
,
2193 const WS_INT32_DESCRIPTION
*desc
, WS_READ_OPTION option
,
2194 WS_HEAP
*heap
, void *ret
, ULONG size
)
2196 WS_XML_UTF8_TEXT
*utf8
;
2203 FIXME( "description not supported\n" );
2206 if ((hr
= read_get_text( reader
, mapping
, localname
, ns
, &utf8
, &found
)) != S_OK
) return hr
;
2207 if (found
&& (hr
= str_to_int64( utf8
->value
.bytes
, utf8
->value
.length
, MIN_INT32
, MAX_INT32
, &val
)) != S_OK
)
2212 case WS_READ_REQUIRED_VALUE
:
2213 if (!found
) return WS_E_INVALID_FORMAT
;
2214 if (size
!= sizeof(INT32
)) return E_INVALIDARG
;
2215 *(INT32
*)ret
= val
;
2218 case WS_READ_REQUIRED_POINTER
:
2219 if (!found
) return WS_E_INVALID_FORMAT
;
2222 case WS_READ_OPTIONAL_POINTER
:
2224 INT32
*heap_val
= NULL
;
2225 if (size
!= sizeof(heap_val
)) return E_INVALIDARG
;
2228 if (!(heap_val
= ws_alloc( heap
, sizeof(*heap_val
) ))) return WS_E_QUOTA_EXCEEDED
;
2231 *(INT32
**)ret
= heap_val
;
2235 FIXME( "read option %u not supported\n", option
);
2242 static HRESULT
read_type_int64( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2243 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
,
2244 const WS_INT64_DESCRIPTION
*desc
, WS_READ_OPTION option
,
2245 WS_HEAP
*heap
, void *ret
, ULONG size
)
2247 WS_XML_UTF8_TEXT
*utf8
;
2254 FIXME( "description not supported\n" );
2257 if ((hr
= read_get_text( reader
, mapping
, localname
, ns
, &utf8
, &found
)) != S_OK
) return hr
;
2258 if (found
&& (hr
= str_to_int64( utf8
->value
.bytes
, utf8
->value
.length
, MIN_INT64
, MAX_INT64
, &val
)) != S_OK
)
2263 case WS_READ_REQUIRED_VALUE
:
2264 if (!found
) return WS_E_INVALID_FORMAT
;
2265 if (size
!= sizeof(INT64
)) return E_INVALIDARG
;
2266 *(INT64
*)ret
= val
;
2269 case WS_READ_REQUIRED_POINTER
:
2270 if (!found
) return WS_E_INVALID_FORMAT
;
2273 case WS_READ_OPTIONAL_POINTER
:
2275 INT64
*heap_val
= NULL
;
2276 if (size
!= sizeof(heap_val
)) return E_INVALIDARG
;
2279 if (!(heap_val
= ws_alloc( heap
, sizeof(*heap_val
) ))) return WS_E_QUOTA_EXCEEDED
;
2282 *(INT64
**)ret
= heap_val
;
2286 FIXME( "read option %u not supported\n", option
);
2293 static HRESULT
read_type_uint8( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2294 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
,
2295 const WS_UINT8_DESCRIPTION
*desc
, WS_READ_OPTION option
,
2296 WS_HEAP
*heap
, void *ret
, ULONG size
)
2298 WS_XML_UTF8_TEXT
*utf8
;
2305 FIXME( "description not supported\n" );
2308 if ((hr
= read_get_text( reader
, mapping
, localname
, ns
, &utf8
, &found
)) != S_OK
) return hr
;
2309 if (found
&& (hr
= str_to_uint64( utf8
->value
.bytes
, utf8
->value
.length
, MAX_UINT8
, &val
)) != S_OK
)
2314 case WS_READ_REQUIRED_VALUE
:
2315 if (!found
) return WS_E_INVALID_FORMAT
;
2316 if (size
!= sizeof(UINT8
)) return E_INVALIDARG
;
2317 *(UINT8
*)ret
= val
;
2320 case WS_READ_REQUIRED_POINTER
:
2321 if (!found
) return WS_E_INVALID_FORMAT
;
2324 case WS_READ_OPTIONAL_POINTER
:
2326 UINT8
*heap_val
= NULL
;
2327 if (size
!= sizeof(heap_val
)) return E_INVALIDARG
;
2330 if (!(heap_val
= ws_alloc( heap
, sizeof(*heap_val
) ))) return WS_E_QUOTA_EXCEEDED
;
2333 *(UINT8
**)ret
= heap_val
;
2337 FIXME( "read option %u not supported\n", option
);
2344 static HRESULT
read_type_uint16( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2345 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
,
2346 const WS_UINT16_DESCRIPTION
*desc
, WS_READ_OPTION option
,
2347 WS_HEAP
*heap
, void *ret
, ULONG size
)
2349 WS_XML_UTF8_TEXT
*utf8
;
2356 FIXME( "description not supported\n" );
2359 if ((hr
= read_get_text( reader
, mapping
, localname
, ns
, &utf8
, &found
)) != S_OK
) return hr
;
2360 if (found
&& (hr
= str_to_uint64( utf8
->value
.bytes
, utf8
->value
.length
, MAX_UINT16
, &val
)) != S_OK
)
2365 case WS_READ_REQUIRED_VALUE
:
2366 if (!found
) return WS_E_INVALID_FORMAT
;
2367 if (size
!= sizeof(UINT16
)) return E_INVALIDARG
;
2368 *(UINT16
*)ret
= val
;
2371 case WS_READ_REQUIRED_POINTER
:
2372 if (!found
) return WS_E_INVALID_FORMAT
;
2375 case WS_READ_OPTIONAL_POINTER
:
2377 UINT16
*heap_val
= NULL
;
2378 if (size
!= sizeof(heap_val
)) return E_INVALIDARG
;
2381 if (!(heap_val
= ws_alloc( heap
, sizeof(*heap_val
) ))) return WS_E_QUOTA_EXCEEDED
;
2384 *(UINT16
**)ret
= heap_val
;
2388 FIXME( "read option %u not supported\n", option
);
2395 static HRESULT
read_type_uint32( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2396 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
,
2397 const WS_UINT32_DESCRIPTION
*desc
, WS_READ_OPTION option
,
2398 WS_HEAP
*heap
, void *ret
, ULONG size
)
2400 WS_XML_UTF8_TEXT
*utf8
;
2407 FIXME( "description not supported\n" );
2410 if ((hr
= read_get_text( reader
, mapping
, localname
, ns
, &utf8
, &found
)) != S_OK
) return hr
;
2411 if (found
&& (hr
= str_to_uint64( utf8
->value
.bytes
, utf8
->value
.length
, MAX_UINT32
, &val
)) != S_OK
)
2416 case WS_READ_REQUIRED_VALUE
:
2417 if (!found
) return WS_E_INVALID_FORMAT
;
2418 if (size
!= sizeof(UINT32
)) return E_INVALIDARG
;
2419 *(UINT32
*)ret
= val
;
2422 case WS_READ_REQUIRED_POINTER
:
2423 if (!found
) return WS_E_INVALID_FORMAT
;
2426 case WS_READ_OPTIONAL_POINTER
:
2428 UINT32
*heap_val
= NULL
;
2429 if (size
!= sizeof(heap_val
)) return E_INVALIDARG
;
2432 if (!(heap_val
= ws_alloc( heap
, sizeof(*heap_val
) ))) return WS_E_QUOTA_EXCEEDED
;
2435 *(UINT32
**)ret
= heap_val
;
2439 FIXME( "read option %u not supported\n", option
);
2446 static HRESULT
read_type_uint64( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2447 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
,
2448 const WS_UINT64_DESCRIPTION
*desc
, WS_READ_OPTION option
,
2449 WS_HEAP
*heap
, void *ret
, ULONG size
)
2451 WS_XML_UTF8_TEXT
*utf8
;
2458 FIXME( "description not supported\n" );
2461 if ((hr
= read_get_text( reader
, mapping
, localname
, ns
, &utf8
, &found
)) != S_OK
) return hr
;
2462 if (found
&& (hr
= str_to_uint64( utf8
->value
.bytes
, utf8
->value
.length
, MAX_UINT64
, &val
)) != S_OK
)
2467 case WS_READ_REQUIRED_VALUE
:
2468 if (!found
) return WS_E_INVALID_FORMAT
;
2469 if (size
!= sizeof(UINT64
)) return E_INVALIDARG
;
2470 *(UINT64
*)ret
= val
;
2473 case WS_READ_REQUIRED_POINTER
:
2474 if (!found
) return WS_E_INVALID_FORMAT
;
2477 case WS_READ_OPTIONAL_POINTER
:
2479 UINT64
*heap_val
= NULL
;
2480 if (size
!= sizeof(heap_val
)) return E_INVALIDARG
;
2483 if (!(heap_val
= ws_alloc( heap
, sizeof(*heap_val
) ))) return WS_E_QUOTA_EXCEEDED
;
2486 *(UINT64
**)ret
= heap_val
;
2490 FIXME( "read option %u not supported\n", option
);
2497 static HRESULT
read_type_wsz( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2498 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
,
2499 const WS_WSZ_DESCRIPTION
*desc
, WS_READ_OPTION option
,
2500 WS_HEAP
*heap
, WCHAR
**ret
, ULONG size
)
2502 WS_XML_UTF8_TEXT
*utf8
;
2509 FIXME( "description not supported\n" );
2512 if ((hr
= read_get_text( reader
, mapping
, localname
, ns
, &utf8
, &found
)) != S_OK
) return hr
;
2513 if (found
&& !(str
= xmltext_to_widechar( heap
, &utf8
->text
))) return WS_E_QUOTA_EXCEEDED
;
2517 case WS_READ_REQUIRED_POINTER
:
2518 if (!found
) return WS_E_INVALID_FORMAT
;
2521 case WS_READ_OPTIONAL_POINTER
:
2522 if (size
!= sizeof(str
)) return E_INVALIDARG
;
2527 FIXME( "read option %u not supported\n", option
);
2534 static ULONG
get_type_size( WS_TYPE type
, const WS_STRUCT_DESCRIPTION
*desc
)
2540 return sizeof(INT8
);
2543 case WS_UINT16_TYPE
:
2544 return sizeof(INT16
);
2548 case WS_UINT32_TYPE
:
2549 return sizeof(INT32
);
2552 case WS_UINT64_TYPE
:
2553 return sizeof(INT64
);
2556 return sizeof(WCHAR
*);
2558 case WS_STRUCT_TYPE
:
2562 ERR( "unhandled type %u\n", type
);
2567 static HRESULT
read_type( struct reader
*, WS_TYPE_MAPPING
, WS_TYPE
, const WS_XML_STRING
*,
2568 const WS_XML_STRING
*, const void *, WS_READ_OPTION
, WS_HEAP
*,
2571 static HRESULT
read_type_repeating_element( struct reader
*reader
, const WS_FIELD_DESCRIPTION
*desc
,
2572 WS_READ_OPTION option
, WS_HEAP
*heap
, void **ret
,
2573 ULONG size
, ULONG
*count
)
2576 ULONG item_size
, nb_items
= 0, nb_allocated
= 1, offset
= 0;
2579 if (size
!= sizeof(void *)) return E_INVALIDARG
;
2581 /* wrapper element */
2582 if (desc
->localName
&& ((hr
= read_node( reader
)) != S_OK
)) return hr
;
2584 item_size
= get_type_size( desc
->type
, desc
->typeDescription
);
2585 if (!(buf
= ws_alloc_zero( heap
, item_size
))) return WS_E_QUOTA_EXCEEDED
;
2588 if (nb_items
>= nb_allocated
)
2590 if (!(buf
= ws_realloc_zero( heap
, buf
, nb_allocated
* 2 * item_size
)))
2591 return WS_E_QUOTA_EXCEEDED
;
2594 hr
= read_type( reader
, WS_ELEMENT_TYPE_MAPPING
, desc
->type
, desc
->itemLocalName
, desc
->itemNs
,
2595 desc
->typeDescription
, WS_READ_REQUIRED_VALUE
, heap
, buf
+ offset
, item_size
);
2596 if (hr
== WS_E_INVALID_FORMAT
) break;
2599 ws_free( heap
, buf
);
2602 if ((hr
= read_node( reader
)) != S_OK
)
2604 ws_free( heap
, buf
);
2607 offset
+= item_size
;
2611 if (desc
->localName
&& ((hr
= read_node( reader
)) != S_OK
)) return hr
;
2613 if (desc
->itemRange
&& (nb_items
< desc
->itemRange
->minItemCount
|| nb_items
> desc
->itemRange
->maxItemCount
))
2615 TRACE( "number of items %u out of range (%u-%u)\n", nb_items
, desc
->itemRange
->minItemCount
,
2616 desc
->itemRange
->maxItemCount
);
2617 ws_free( heap
, buf
);
2618 return WS_E_INVALID_FORMAT
;
2627 static HRESULT
read_type_text( struct reader
*reader
, const WS_FIELD_DESCRIPTION
*desc
,
2628 WS_READ_OPTION option
, WS_HEAP
*heap
, void *ret
, ULONG size
)
2633 if ((hr
= read_to_startelement( reader
, &found
)) != S_OK
) return S_OK
;
2634 if (!found
) return WS_E_INVALID_FORMAT
;
2635 if ((hr
= read_node( reader
)) != S_OK
) return hr
;
2637 return read_type( reader
, WS_ELEMENT_CONTENT_TYPE_MAPPING
, desc
->type
, NULL
, NULL
,
2638 desc
->typeDescription
, option
, heap
, ret
, size
);
2641 static WS_READ_OPTION
map_field_options( WS_TYPE type
, ULONG options
)
2643 if (options
& !(WS_FIELD_POINTER
| WS_FIELD_OPTIONAL
))
2645 FIXME( "options %08x not supported\n", options
);
2657 case WS_UINT16_TYPE
:
2658 case WS_UINT32_TYPE
:
2659 case WS_UINT64_TYPE
:
2660 return WS_READ_REQUIRED_VALUE
;
2663 case WS_STRUCT_TYPE
:
2664 return WS_READ_REQUIRED_POINTER
;
2667 FIXME( "unhandled type %u\n", type
);
2672 static HRESULT
read_type_struct_field( struct reader
*reader
, const WS_FIELD_DESCRIPTION
*desc
,
2673 WS_HEAP
*heap
, char *buf
)
2675 char *ptr
= buf
+ desc
->offset
;
2676 WS_READ_OPTION option
;
2680 if (!(option
= map_field_options( desc
->type
, desc
->options
))) return E_INVALIDARG
;
2682 if (option
== WS_READ_REQUIRED_VALUE
)
2683 size
= get_type_size( desc
->type
, desc
->typeDescription
);
2685 size
= sizeof(void *);
2687 switch (desc
->mapping
)
2689 case WS_ATTRIBUTE_FIELD_MAPPING
:
2690 hr
= read_type( reader
, WS_ATTRIBUTE_TYPE_MAPPING
, desc
->type
, desc
->localName
, desc
->ns
,
2691 desc
->typeDescription
, option
, heap
, ptr
, size
);
2694 case WS_ELEMENT_FIELD_MAPPING
:
2695 hr
= read_type( reader
, WS_ELEMENT_TYPE_MAPPING
, desc
->type
, desc
->localName
, desc
->ns
,
2696 desc
->typeDescription
, option
, heap
, ptr
, size
);
2699 case WS_REPEATING_ELEMENT_FIELD_MAPPING
:
2702 hr
= read_type_repeating_element( reader
, desc
, option
, heap
, (void **)ptr
, size
, &count
);
2703 if (hr
== S_OK
) *(ULONG
*)(ptr
+ desc
->countOffset
) = count
;
2706 case WS_TEXT_FIELD_MAPPING
:
2707 hr
= read_type_text( reader
, desc
, option
, heap
, ptr
, size
);
2711 FIXME( "unhandled field mapping %u\n", desc
->mapping
);
2716 if (hr
== WS_E_INVALID_FORMAT
&& desc
->options
& WS_FIELD_OPTIONAL
)
2720 case WS_READ_REQUIRED_VALUE
:
2721 if (desc
->defaultValue
) memcpy( ptr
, desc
->defaultValue
->value
, desc
->defaultValue
->valueSize
);
2722 else memset( ptr
, 0, size
);
2725 case WS_READ_REQUIRED_POINTER
:
2726 *(void **)ptr
= NULL
;
2730 ERR( "unhandled option %u\n", option
);
2738 static HRESULT
read_type_struct( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2739 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
,
2740 const WS_STRUCT_DESCRIPTION
*desc
, WS_READ_OPTION option
,
2741 WS_HEAP
*heap
, void *ret
, ULONG size
)
2747 if (!desc
) return E_INVALIDARG
;
2749 if (desc
->structOptions
)
2751 FIXME( "struct options %08x not supported\n", desc
->structOptions
);
2757 case WS_READ_REQUIRED_POINTER
:
2758 case WS_READ_OPTIONAL_POINTER
:
2759 if (size
!= sizeof(void *)) return E_INVALIDARG
;
2760 if (!(buf
= ws_alloc_zero( heap
, desc
->size
))) return WS_E_QUOTA_EXCEEDED
;
2763 case WS_READ_REQUIRED_VALUE
:
2764 if (size
!= desc
->size
) return E_INVALIDARG
;
2769 FIXME( "unhandled read option %u\n", option
);
2773 for (i
= 0; i
< desc
->fieldCount
; i
++)
2775 if ((hr
= read_type_struct_field( reader
, desc
->fields
[i
], heap
, buf
)) != S_OK
)
2781 case WS_READ_REQUIRED_POINTER
:
2784 ws_free( heap
, buf
);
2787 *(char **)ret
= buf
;
2790 case WS_READ_OPTIONAL_POINTER
:
2793 ws_free( heap
, buf
);
2796 *(char **)ret
= buf
;
2799 case WS_READ_REQUIRED_VALUE
:
2803 ERR( "unhandled read option %u\n", option
);
2808 static BOOL
is_empty_text_node( const struct node
*node
)
2810 const WS_XML_TEXT_NODE
*text
= (const WS_XML_TEXT_NODE
*)node
;
2811 const WS_XML_UTF8_TEXT
*utf8
;
2814 if (node_type( node
) != WS_XML_NODE_TYPE_TEXT
) return FALSE
;
2815 if (text
->text
->textType
!= WS_XML_TEXT_TYPE_UTF8
)
2817 ERR( "unhandled text type %u\n", text
->text
->textType
);
2820 utf8
= (const WS_XML_UTF8_TEXT
*)text
->text
;
2821 for (i
= 0; i
< utf8
->value
.length
; i
++) if (!read_isspace( utf8
->value
.bytes
[i
] )) return FALSE
;
2825 static HRESULT
read_type_next_node( struct reader
*reader
, const WS_XML_STRING
*localname
,
2826 const WS_XML_STRING
*ns
)
2828 const WS_XML_ELEMENT_NODE
*elem
;
2829 WS_XML_NODE_TYPE type
;
2833 if (!localname
) return S_OK
; /* assume reader is already correctly positioned */
2834 if ((hr
= read_to_startelement( reader
, &found
) != S_OK
)) return hr
;
2835 if (!found
) return WS_E_INVALID_FORMAT
;
2837 elem
= &reader
->current
->hdr
;
2838 if (WsXmlStringEquals( localname
, elem
->localName
, NULL
) == S_OK
&&
2839 WsXmlStringEquals( ns
, elem
->ns
, NULL
) == S_OK
) return S_OK
;
2843 if ((hr
= read_node( reader
) != S_OK
)) return hr
;
2844 type
= node_type( reader
->current
);
2845 if (type
== WS_XML_NODE_TYPE_COMMENT
||
2846 (type
== WS_XML_NODE_TYPE_TEXT
&& is_empty_text_node( reader
->current
))) continue;
2853 static HRESULT
read_type( struct reader
*reader
, WS_TYPE_MAPPING mapping
, WS_TYPE type
,
2854 const WS_XML_STRING
*localname
, const WS_XML_STRING
*ns
,
2855 const void *desc
, WS_READ_OPTION option
, WS_HEAP
*heap
,
2856 void *value
, ULONG size
)
2862 case WS_ELEMENT_TYPE_MAPPING
:
2863 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
2864 if ((hr
= read_type_next_node( reader
, localname
, ns
)) != S_OK
) return hr
;
2867 case WS_ATTRIBUTE_TYPE_MAPPING
:
2871 FIXME( "unhandled mapping %u\n", mapping
);
2877 case WS_STRUCT_TYPE
:
2878 if ((hr
= read_type_struct( reader
, mapping
, localname
, ns
, desc
, option
, heap
, value
, size
)) != S_OK
)
2883 if ((hr
= read_type_bool( reader
, mapping
, localname
, ns
, desc
, option
, heap
, value
, size
)) != S_OK
)
2888 if ((hr
= read_type_int8( reader
, mapping
, localname
, ns
, desc
, option
, heap
, value
, size
)) != S_OK
)
2893 if ((hr
= read_type_int16( reader
, mapping
, localname
, ns
, desc
, option
, heap
, value
, size
)) != S_OK
)
2898 if ((hr
= read_type_int32( reader
, mapping
, localname
, ns
, desc
, option
, heap
, value
, size
)) != S_OK
)
2903 if ((hr
= read_type_int64( reader
, mapping
, localname
, ns
, desc
, option
, heap
, value
, size
)) != S_OK
)
2908 if ((hr
= read_type_uint8( reader
, mapping
, localname
, ns
, desc
, option
, heap
, value
, size
)) != S_OK
)
2912 case WS_UINT16_TYPE
:
2913 if ((hr
= read_type_uint16( reader
, mapping
, localname
, ns
, desc
, option
, heap
, value
, size
)) != S_OK
)
2917 case WS_UINT32_TYPE
:
2918 if ((hr
= read_type_uint32( reader
, mapping
, localname
, ns
, desc
, option
, heap
, value
, size
)) != S_OK
)
2922 case WS_UINT64_TYPE
:
2923 if ((hr
= read_type_uint64( reader
, mapping
, localname
, ns
, desc
, option
, heap
, value
, size
)) != S_OK
)
2928 if ((hr
= read_type_wsz( reader
, mapping
, localname
, ns
, desc
, option
, heap
, value
, size
)) != S_OK
)
2933 FIXME( "type %u not supported\n", type
);
2939 case WS_ELEMENT_TYPE_MAPPING
:
2940 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
2941 return read_node( reader
);
2943 case WS_ATTRIBUTE_TYPE_MAPPING
:
2949 /**************************************************************************
2950 * WsReadType [webservices.@]
2952 HRESULT WINAPI
WsReadType( WS_XML_READER
*handle
, WS_TYPE_MAPPING mapping
, WS_TYPE type
,
2953 const void *desc
, WS_READ_OPTION option
, WS_HEAP
*heap
, void *value
,
2954 ULONG size
, WS_ERROR
*error
)
2956 struct reader
*reader
= (struct reader
*)handle
;
2959 TRACE( "%p %u %u %p %u %p %p %u %p\n", handle
, mapping
, type
, desc
, option
, heap
, value
,
2961 if (error
) FIXME( "ignoring error parameter\n" );
2963 if (!reader
|| !value
) return E_INVALIDARG
;
2965 if ((hr
= read_type( reader
, mapping
, type
, NULL
, NULL
, desc
, option
, heap
, value
, size
)) != S_OK
)
2968 if ((hr
= read_node( reader
)) != S_OK
) return hr
;
2969 if (!read_end_of_data( reader
)) return WS_E_INVALID_FORMAT
;
2973 /**************************************************************************
2974 * WsSetErrorProperty [webservices.@]
2976 HRESULT WINAPI
WsSetErrorProperty( WS_ERROR
*handle
, WS_ERROR_PROPERTY_ID id
, const void *value
,
2979 struct error
*error
= (struct error
*)handle
;
2981 TRACE( "%p %u %p %u\n", handle
, id
, value
, size
);
2983 if (id
== WS_ERROR_PROPERTY_LANGID
) return WS_E_INVALID_OPERATION
;
2984 return set_error_prop( error
, id
, value
, size
);
2987 static inline BOOL
is_utf8( const unsigned char *data
, ULONG size
, ULONG
*offset
)
2989 static const char bom
[] = {0xef,0xbb,0xbf};
2990 const unsigned char *p
= data
;
2992 return (size
>= sizeof(bom
) && !memcmp( p
, bom
, sizeof(bom
) ) && (*offset
= sizeof(bom
))) ||
2993 (size
> 2 && !(*offset
= 0));
2996 static inline BOOL
is_utf16le( const unsigned char *data
, ULONG size
, ULONG
*offset
)
2998 static const char bom
[] = {0xff,0xfe};
2999 const unsigned char *p
= data
;
3001 return (size
>= sizeof(bom
) && !memcmp( p
, bom
, sizeof(bom
) ) && (*offset
= sizeof(bom
))) ||
3002 (size
>= 4 && p
[0] == '<' && !p
[1] && !(*offset
= 0));
3005 static WS_CHARSET
detect_charset( const unsigned char *data
, ULONG size
, ULONG
*offset
)
3009 /* FIXME: parse xml declaration */
3011 if (is_utf16le( data
, size
, offset
)) ret
= WS_CHARSET_UTF16LE
;
3012 else if (is_utf8( data
, size
, offset
)) ret
= WS_CHARSET_UTF8
;
3015 FIXME( "charset not recognized\n" );
3019 TRACE( "detected charset %u\n", ret
);
3023 static void set_input_buffer( struct reader
*reader
, const unsigned char *data
, ULONG size
)
3025 reader
->input_type
= WS_XML_READER_INPUT_TYPE_BUFFER
;
3026 reader
->input_data
= data
;
3027 reader
->input_size
= size
;
3029 reader
->read_size
= reader
->input_size
;
3030 reader
->read_pos
= 0;
3031 reader
->read_bufptr
= reader
->input_data
;
3034 /**************************************************************************
3035 * WsSetInput [webservices.@]
3037 HRESULT WINAPI
WsSetInput( WS_XML_READER
*handle
, const WS_XML_READER_ENCODING
*encoding
,
3038 const WS_XML_READER_INPUT
*input
, const WS_XML_READER_PROPERTY
*properties
,
3039 ULONG count
, WS_ERROR
*error
)
3041 struct reader
*reader
= (struct reader
*)handle
;
3044 ULONG i
, offset
= 0;
3046 TRACE( "%p %p %p %p %u %p\n", handle
, encoding
, input
, properties
, count
, error
);
3047 if (error
) FIXME( "ignoring error parameter\n" );
3049 if (!reader
) return E_INVALIDARG
;
3051 for (i
= 0; i
< count
; i
++)
3053 hr
= set_reader_prop( reader
, properties
[i
].id
, properties
[i
].value
, properties
[i
].valueSize
);
3054 if (hr
!= S_OK
) return hr
;
3057 if ((hr
= read_init_state( reader
)) != S_OK
) return hr
;
3059 switch (encoding
->encodingType
)
3061 case WS_XML_READER_ENCODING_TYPE_TEXT
:
3063 WS_XML_READER_TEXT_ENCODING
*text
= (WS_XML_READER_TEXT_ENCODING
*)encoding
;
3064 WS_XML_READER_BUFFER_INPUT
*buf
= (WS_XML_READER_BUFFER_INPUT
*)input
;
3065 WS_CHARSET charset
= text
->charSet
;
3067 if (input
->inputType
!= WS_XML_READER_INPUT_TYPE_BUFFER
)
3069 FIXME( "charset detection on input type %u not supported\n", input
->inputType
);
3073 if (charset
== WS_CHARSET_AUTO
)
3074 charset
= detect_charset( buf
->encodedData
, buf
->encodedDataSize
, &offset
);
3076 hr
= set_reader_prop( reader
, WS_XML_READER_PROPERTY_CHARSET
, &charset
, sizeof(charset
) );
3077 if (hr
!= S_OK
) return hr
;
3081 FIXME( "encoding type %u not supported\n", encoding
->encodingType
);
3084 switch (input
->inputType
)
3086 case WS_XML_READER_INPUT_TYPE_BUFFER
:
3088 WS_XML_READER_BUFFER_INPUT
*buf
= (WS_XML_READER_BUFFER_INPUT
*)input
;
3089 set_input_buffer( reader
, (const unsigned char *)buf
->encodedData
+ offset
, buf
->encodedDataSize
- offset
);
3093 FIXME( "input type %u not supported\n", input
->inputType
);
3097 if (!(node
= alloc_node( WS_XML_NODE_TYPE_BOF
))) return E_OUTOFMEMORY
;
3098 read_insert_bof( reader
, node
);
3102 /**************************************************************************
3103 * WsSetInputToBuffer [webservices.@]
3105 HRESULT WINAPI
WsSetInputToBuffer( WS_XML_READER
*handle
, WS_XML_BUFFER
*buffer
,
3106 const WS_XML_READER_PROPERTY
*properties
, ULONG count
,
3109 struct reader
*reader
= (struct reader
*)handle
;
3110 struct xmlbuf
*xmlbuf
= (struct xmlbuf
*)buffer
;
3114 ULONG i
, offset
= 0;
3116 TRACE( "%p %p %p %u %p\n", handle
, buffer
, properties
, count
, error
);
3117 if (error
) FIXME( "ignoring error parameter\n" );
3119 if (!reader
|| !xmlbuf
) return E_INVALIDARG
;
3121 for (i
= 0; i
< count
; i
++)
3123 hr
= set_reader_prop( reader
, properties
[i
].id
, properties
[i
].value
, properties
[i
].valueSize
);
3124 if (hr
!= S_OK
) return hr
;
3127 if ((hr
= read_init_state( reader
)) != S_OK
) return hr
;
3129 charset
= detect_charset( xmlbuf
->ptr
, xmlbuf
->size
, &offset
);
3130 hr
= set_reader_prop( reader
, WS_XML_READER_PROPERTY_CHARSET
, &charset
, sizeof(charset
) );
3131 if (hr
!= S_OK
) return hr
;
3133 set_input_buffer( reader
, (const unsigned char *)xmlbuf
->ptr
+ offset
, xmlbuf
->size
- offset
);
3134 if (!(node
= alloc_node( WS_XML_NODE_TYPE_BOF
))) return E_OUTOFMEMORY
;
3135 read_insert_bof( reader
, node
);
3139 /**************************************************************************
3140 * WsXmlStringEquals [webservices.@]
3142 HRESULT WINAPI
WsXmlStringEquals( const WS_XML_STRING
*str1
, const WS_XML_STRING
*str2
, WS_ERROR
*error
)
3144 TRACE( "%s %s %p\n", debugstr_xmlstr(str1
), debugstr_xmlstr(str2
), error
);
3145 if (error
) FIXME( "ignoring error parameter\n" );
3147 if (!str1
|| !str2
) return E_INVALIDARG
;
3149 if (str1
->length
!= str2
->length
) return S_FALSE
;
3150 if (!memcmp( str1
->bytes
, str2
->bytes
, str1
->length
)) return S_OK
;