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 void ws_free( WS_HEAP
*handle
, void *ptr
)
181 struct heap
*heap
= (struct heap
*)handle
;
182 HeapFree( heap
->handle
, 0, ptr
);
185 /**************************************************************************
186 * WsAlloc [webservices.@]
188 HRESULT WINAPI
WsAlloc( WS_HEAP
*handle
, SIZE_T size
, void **ptr
, WS_ERROR
*error
)
192 TRACE( "%p %u %p %p\n", handle
, (ULONG
)size
, ptr
, error
);
193 if (error
) FIXME( "ignoring error parameter\n" );
195 if (!handle
|| !ptr
) return E_INVALIDARG
;
197 if (!(mem
= ws_alloc( handle
, size
))) return E_OUTOFMEMORY
;
202 static struct heap
*alloc_heap(void)
204 static const ULONG count
= sizeof(heap_props
)/sizeof(heap_props
[0]);
206 ULONG i
, size
= sizeof(*ret
) + count
* sizeof(WS_HEAP_PROPERTY
);
209 for (i
= 0; i
< count
; i
++) size
+= heap_props
[i
].size
;
210 if (!(ret
= heap_alloc_zero( size
))) return NULL
;
212 ptr
= (char *)&ret
->prop
[count
];
213 for (i
= 0; i
< count
; i
++)
215 ret
->prop
[i
].value
= ptr
;
216 ret
->prop
[i
].valueSize
= heap_props
[i
].size
;
217 ptr
+= ret
->prop
[i
].valueSize
;
219 ret
->prop_count
= count
;
223 static HRESULT
set_heap_prop( struct heap
*heap
, WS_HEAP_PROPERTY_ID id
, const void *value
, ULONG size
)
225 if (id
>= heap
->prop_count
|| size
!= heap_props
[id
].size
|| heap_props
[id
].readonly
)
228 memcpy( heap
->prop
[id
].value
, value
, size
);
232 static HRESULT
get_heap_prop( struct heap
*heap
, WS_HEAP_PROPERTY_ID id
, void *buf
, ULONG size
)
234 if (id
>= heap
->prop_count
|| size
!= heap_props
[id
].size
)
237 memcpy( buf
, heap
->prop
[id
].value
, heap
->prop
[id
].valueSize
);
241 /**************************************************************************
242 * WsCreateHeap [webservices.@]
244 HRESULT WINAPI
WsCreateHeap( SIZE_T max_size
, SIZE_T trim_size
, const WS_HEAP_PROPERTY
*properties
,
245 ULONG count
, WS_HEAP
**handle
, WS_ERROR
*error
)
249 TRACE( "%u %u %p %u %p %p\n", (ULONG
)max_size
, (ULONG
)trim_size
, properties
, count
, handle
, error
);
250 if (error
) FIXME( "ignoring error parameter\n" );
252 if (!handle
|| count
) return E_INVALIDARG
;
253 if (!(heap
= alloc_heap())) return E_OUTOFMEMORY
;
255 set_heap_prop( heap
, WS_HEAP_PROPERTY_MAX_SIZE
, &max_size
, sizeof(max_size
) );
256 set_heap_prop( heap
, WS_HEAP_PROPERTY_TRIM_SIZE
, &trim_size
, sizeof(trim_size
) );
258 if (!(heap
->handle
= HeapCreate( 0, 0, max_size
)))
261 return E_OUTOFMEMORY
;
264 *handle
= (WS_HEAP
*)heap
;
268 /**************************************************************************
269 * WsFreeHeap [webservices.@]
271 void WINAPI
WsFreeHeap( WS_HEAP
*handle
)
273 struct heap
*heap
= (struct heap
*)handle
;
275 TRACE( "%p\n", handle
);
278 HeapDestroy( heap
->handle
);
282 struct node
*alloc_node( WS_XML_NODE_TYPE type
)
286 if (!(ret
= heap_alloc_zero( sizeof(*ret
) ))) return NULL
;
287 ret
->hdr
.node
.nodeType
= type
;
288 list_init( &ret
->entry
);
289 list_init( &ret
->children
);
293 void free_attribute( WS_XML_ATTRIBUTE
*attr
)
296 heap_free( attr
->prefix
);
297 heap_free( attr
->localName
);
298 heap_free( attr
->ns
);
299 heap_free( attr
->value
);
303 void free_node( struct node
*node
)
306 switch (node
->hdr
.node
.nodeType
)
308 case WS_XML_NODE_TYPE_ELEMENT
:
310 WS_XML_ELEMENT_NODE
*elem
= &node
->hdr
;
313 for (i
= 0; i
< elem
->attributeCount
; i
++) free_attribute( elem
->attributes
[i
] );
314 heap_free( elem
->attributes
);
315 heap_free( elem
->prefix
);
316 heap_free( elem
->localName
);
317 heap_free( elem
->ns
);
320 case WS_XML_NODE_TYPE_TEXT
:
322 WS_XML_TEXT_NODE
*text
= (WS_XML_TEXT_NODE
*)node
;
323 heap_free( text
->text
);
326 case WS_XML_NODE_TYPE_COMMENT
:
328 WS_XML_COMMENT_NODE
*comment
= (WS_XML_COMMENT_NODE
*)node
;
329 heap_free( comment
->value
.bytes
);
332 case WS_XML_NODE_TYPE_CDATA
:
333 case WS_XML_NODE_TYPE_END_CDATA
:
334 case WS_XML_NODE_TYPE_END_ELEMENT
:
335 case WS_XML_NODE_TYPE_EOF
:
336 case WS_XML_NODE_TYPE_BOF
:
340 ERR( "unhandled type %u\n", node
->hdr
.node
.nodeType
);
346 void destroy_nodes( struct node
*node
)
351 while ((ptr
= list_head( &node
->children
)))
353 struct node
*child
= LIST_ENTRY( ptr
, struct node
, entry
);
354 list_remove( &child
->entry
);
355 destroy_nodes( child
);
367 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_MAX_DEPTH */
368 { sizeof(BOOL
), FALSE
}, /* WS_XML_READER_PROPERTY_ALLOW_FRAGMENT */
369 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_MAX_ATTRIBUTES */
370 { sizeof(BOOL
), FALSE
}, /* WS_XML_READER_PROPERTY_READ_DECLARATION */
371 { sizeof(WS_CHARSET
), FALSE
}, /* WS_XML_READER_PROPERTY_CHARSET */
372 { sizeof(ULONGLONG
), TRUE
}, /* WS_XML_READER_PROPERTY_ROW */
373 { sizeof(ULONGLONG
), TRUE
}, /* WS_XML_READER_PROPERTY_COLUMN */
374 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_UTF8_TRIM_SIZE */
375 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_STREAM_BUFFER_SIZE */
376 { sizeof(BOOL
), TRUE
}, /* WS_XML_READER_PROPERTY_IN_ATTRIBUTE */
377 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_STREAM_MAX_ROOT_MIME_PART_SIZE */
378 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_STREAM_MAX_MIME_HEADERS_SIZE */
379 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_MAX_MIME_PARTS */
380 { sizeof(BOOL
), FALSE
}, /* WS_XML_READER_PROPERTY_ALLOW_INVALID_CHARACTER_REFERENCES */
381 { sizeof(ULONG
), FALSE
}, /* WS_XML_READER_PROPERTY_MAX_NAMESPACES */
386 READER_STATE_INITIAL
,
388 READER_STATE_STARTELEMENT
,
389 READER_STATE_STARTATTRIBUTE
,
390 READER_STATE_STARTCDATA
,
393 READER_STATE_ENDELEMENT
,
394 READER_STATE_ENDCDATA
,
395 READER_STATE_COMMENT
,
403 const unsigned char *read_bufptr
;
404 enum reader_state state
;
406 struct node
*current
;
408 WS_XML_READER_INPUT_TYPE input_type
;
409 const unsigned char *input_data
;
412 WS_XML_READER_PROPERTY prop
[sizeof(reader_props
)/sizeof(reader_props
[0])];
415 static struct reader
*alloc_reader(void)
417 static const ULONG count
= sizeof(reader_props
)/sizeof(reader_props
[0]);
419 ULONG i
, size
= sizeof(*ret
) + count
* sizeof(WS_XML_READER_PROPERTY
);
422 for (i
= 0; i
< count
; i
++) size
+= reader_props
[i
].size
;
423 if (!(ret
= heap_alloc_zero( size
))) return NULL
;
425 ptr
= (char *)&ret
->prop
[count
];
426 for (i
= 0; i
< count
; i
++)
428 ret
->prop
[i
].value
= ptr
;
429 ret
->prop
[i
].valueSize
= reader_props
[i
].size
;
430 ptr
+= ret
->prop
[i
].valueSize
;
432 ret
->prop_count
= count
;
436 static HRESULT
set_reader_prop( struct reader
*reader
, WS_XML_READER_PROPERTY_ID id
, const void *value
, ULONG size
)
438 if (id
>= reader
->prop_count
|| size
!= reader_props
[id
].size
|| reader_props
[id
].readonly
)
441 memcpy( reader
->prop
[id
].value
, value
, size
);
445 static HRESULT
get_reader_prop( struct reader
*reader
, WS_XML_READER_PROPERTY_ID id
, void *buf
, ULONG size
)
447 if (id
>= reader
->prop_count
|| size
!= reader_props
[id
].size
)
450 memcpy( buf
, reader
->prop
[id
].value
, reader
->prop
[id
].valueSize
);
454 static void read_insert_eof( struct reader
*reader
, struct node
*eof
)
456 if (!reader
->root
) reader
->root
= eof
;
459 eof
->parent
= reader
->root
;
460 list_add_tail( &reader
->root
->children
, &eof
->entry
);
462 reader
->current
= eof
;
465 static void read_insert_bof( struct reader
*reader
, struct node
*bof
)
467 reader
->root
->parent
= bof
;
468 list_add_tail( &bof
->children
, &reader
->root
->entry
);
469 reader
->current
= reader
->root
= bof
;
472 static void read_insert_node( struct reader
*reader
, struct node
*parent
, struct node
*node
)
474 node
->parent
= parent
;
475 if (node
->parent
== reader
->root
)
477 struct list
*eof
= list_tail( &reader
->root
->children
);
478 list_add_before( eof
, &node
->entry
);
480 else list_add_tail( &parent
->children
, &node
->entry
);
481 reader
->current
= node
;
484 static HRESULT
read_init_state( struct reader
*reader
)
488 destroy_nodes( reader
->root
);
490 if (!(node
= alloc_node( WS_XML_NODE_TYPE_EOF
))) return E_OUTOFMEMORY
;
491 read_insert_eof( reader
, node
);
492 reader
->state
= READER_STATE_INITIAL
;
496 /**************************************************************************
497 * WsCreateReader [webservices.@]
499 HRESULT WINAPI
WsCreateReader( const WS_XML_READER_PROPERTY
*properties
, ULONG count
,
500 WS_XML_READER
**handle
, WS_ERROR
*error
)
502 struct reader
*reader
;
503 ULONG i
, max_depth
= 32, max_attrs
= 128, max_ns
= 32;
504 WS_CHARSET charset
= WS_CHARSET_UTF8
;
505 BOOL read_decl
= TRUE
;
508 TRACE( "%p %u %p %p\n", properties
, count
, handle
, error
);
509 if (error
) FIXME( "ignoring error parameter\n" );
511 if (!handle
) return E_INVALIDARG
;
512 if (!(reader
= alloc_reader())) return E_OUTOFMEMORY
;
514 set_reader_prop( reader
, WS_XML_READER_PROPERTY_MAX_DEPTH
, &max_depth
, sizeof(max_depth
) );
515 set_reader_prop( reader
, WS_XML_READER_PROPERTY_MAX_ATTRIBUTES
, &max_attrs
, sizeof(max_attrs
) );
516 set_reader_prop( reader
, WS_XML_READER_PROPERTY_READ_DECLARATION
, &read_decl
, sizeof(read_decl
) );
517 set_reader_prop( reader
, WS_XML_READER_PROPERTY_CHARSET
, &charset
, sizeof(charset
) );
518 set_reader_prop( reader
, WS_XML_READER_PROPERTY_MAX_NAMESPACES
, &max_ns
, sizeof(max_ns
) );
520 for (i
= 0; i
< count
; i
++)
522 hr
= set_reader_prop( reader
, properties
[i
].id
, properties
[i
].value
, properties
[i
].valueSize
);
530 if ((hr
= read_init_state( reader
)) != S_OK
)
536 *handle
= (WS_XML_READER
*)reader
;
540 /**************************************************************************
541 * WsFreeReader [webservices.@]
543 void WINAPI
WsFreeReader( WS_XML_READER
*handle
)
545 struct reader
*reader
= (struct reader
*)handle
;
547 TRACE( "%p\n", handle
);
550 destroy_nodes( reader
->root
);
554 /**************************************************************************
555 * WsFillReader [webservices.@]
557 HRESULT WINAPI
WsFillReader( WS_XML_READER
*handle
, ULONG min_size
, const WS_ASYNC_CONTEXT
*ctx
,
560 struct reader
*reader
= (struct reader
*)handle
;
562 TRACE( "%p %u %p %p\n", handle
, min_size
, ctx
, error
);
563 if (error
) FIXME( "ignoring error parameter\n" );
565 if (!reader
) return E_INVALIDARG
;
567 /* FIXME: add support for stream input */
568 reader
->read_size
= min( min_size
, reader
->input_size
);
569 reader
->read_pos
= 0;
574 /**************************************************************************
575 * WsGetErrorProperty [webservices.@]
577 HRESULT WINAPI
WsGetErrorProperty( WS_ERROR
*handle
, WS_ERROR_PROPERTY_ID id
, void *buf
,
580 struct error
*error
= (struct error
*)handle
;
582 TRACE( "%p %u %p %u\n", handle
, id
, buf
, size
);
583 return get_error_prop( error
, id
, buf
, size
);
586 /**************************************************************************
587 * WsGetErrorString [webservices.@]
589 HRESULT WINAPI
WsGetErrorString( WS_ERROR
*handle
, ULONG index
, WS_STRING
*str
)
591 FIXME( "%p %u %p: stub\n", handle
, index
, str
);
595 /**************************************************************************
596 * WsGetHeapProperty [webservices.@]
598 HRESULT WINAPI
WsGetHeapProperty( WS_HEAP
*handle
, WS_HEAP_PROPERTY_ID id
, void *buf
,
599 ULONG size
, WS_ERROR
*error
)
601 struct heap
*heap
= (struct heap
*)handle
;
603 TRACE( "%p %u %p %u %p\n", handle
, id
, buf
, size
, error
);
604 if (error
) FIXME( "ignoring error parameter\n" );
606 return get_heap_prop( heap
, id
, buf
, size
);
609 /**************************************************************************
610 * WsGetNamespaceFromPrefix [webservices.@]
612 HRESULT WINAPI
WsGetNamespaceFromPrefix( WS_XML_READER
*handle
, const WS_XML_STRING
*prefix
,
613 BOOL required
, const WS_XML_STRING
**ns
, WS_ERROR
*error
)
615 static const WS_XML_STRING xml
= {3, (BYTE
*)"xml"};
616 static const WS_XML_STRING xmlns
= {5, (BYTE
*)"xmlns"};
617 static const WS_XML_STRING empty_ns
= {0, NULL
};
618 static const WS_XML_STRING xml_ns
= {36, (BYTE
*)"http://www.w3.org/XML/1998/namespace"};
619 static const WS_XML_STRING xmlns_ns
= {29, (BYTE
*)"http://www.w3.org/2000/xmlns/"};
620 struct reader
*reader
= (struct reader
*)handle
;
623 TRACE( "%p %s %d %p %p\n", handle
, debugstr_xmlstr(prefix
), required
, ns
, error
);
624 if (error
) FIXME( "ignoring error parameter\n" );
626 if (!reader
|| !prefix
|| !ns
) return E_INVALIDARG
;
627 if (reader
->state
!= READER_STATE_STARTELEMENT
) return WS_E_INVALID_OPERATION
;
634 else if (WsXmlStringEquals( prefix
, &xml
, NULL
) == S_OK
)
639 else if (WsXmlStringEquals( prefix
, &xmlns
, NULL
) == S_OK
)
646 WS_XML_ELEMENT_NODE
*elem
= &reader
->current
->hdr
;
649 for (i
= 0; i
< elem
->attributeCount
; i
++)
651 if (!elem
->attributes
[i
]->isXmlNs
) continue;
652 if (WsXmlStringEquals( prefix
, elem
->attributes
[i
]->prefix
, NULL
) == S_OK
)
654 *ns
= elem
->attributes
[i
]->ns
;
663 if (required
) return WS_E_INVALID_FORMAT
;
670 /**************************************************************************
671 * WsGetReaderNode [webservices.@]
673 HRESULT WINAPI
WsGetReaderNode( WS_XML_READER
*handle
, const WS_XML_NODE
**node
,
676 struct reader
*reader
= (struct reader
*)handle
;
678 TRACE( "%p %p %p\n", handle
, node
, error
);
679 if (error
) FIXME( "ignoring error parameter\n" );
681 if (!reader
|| !node
) return E_INVALIDARG
;
683 *node
= &reader
->current
->hdr
.node
;
687 /**************************************************************************
688 * WsGetReaderProperty [webservices.@]
690 HRESULT WINAPI
WsGetReaderProperty( WS_XML_READER
*handle
, WS_XML_READER_PROPERTY_ID id
,
691 void *buf
, ULONG size
, WS_ERROR
*error
)
693 struct reader
*reader
= (struct reader
*)handle
;
695 TRACE( "%p %u %p %u %p\n", handle
, id
, buf
, size
, error
);
696 if (error
) FIXME( "ignoring error parameter\n" );
698 if (!reader
->input_type
) return WS_E_INVALID_OPERATION
;
700 if (id
== WS_XML_READER_PROPERTY_CHARSET
)
705 if ((hr
= get_reader_prop( reader
, id
, &charset
, size
)) != S_OK
) return hr
;
706 if (!charset
) return WS_E_INVALID_FORMAT
;
707 *(WS_CHARSET
*)buf
= charset
;
710 return get_reader_prop( reader
, id
, buf
, size
);
713 /**************************************************************************
714 * WsGetXmlAttribute [webservices.@]
716 HRESULT WINAPI
WsGetXmlAttribute( WS_XML_READER
*handle
, const WS_XML_STRING
*attr
,
717 WS_HEAP
*heap
, WCHAR
**str
, ULONG
*len
, WS_ERROR
*error
)
719 FIXME( "%p %s %p %p %p %p: stub\n", handle
, debugstr_xmlstr(attr
), heap
, str
, len
, error
);
723 WS_XML_STRING
*alloc_xml_string( const unsigned char *data
, ULONG len
)
727 if (!(ret
= heap_alloc( sizeof(*ret
) + len
))) return NULL
;
729 ret
->bytes
= len
? (BYTE
*)(ret
+ 1) : NULL
;
730 ret
->dictionary
= NULL
;
732 if (data
) memcpy( ret
->bytes
, data
, len
);
736 WS_XML_UTF8_TEXT
*alloc_utf8_text( const unsigned char *data
, ULONG len
)
738 WS_XML_UTF8_TEXT
*ret
;
740 if (!(ret
= heap_alloc( sizeof(*ret
) + len
))) return NULL
;
741 ret
->text
.textType
= WS_XML_TEXT_TYPE_UTF8
;
742 ret
->value
.length
= len
;
743 ret
->value
.bytes
= len
? (BYTE
*)(ret
+ 1) : NULL
;
744 ret
->value
.dictionary
= NULL
;
746 if (data
) memcpy( ret
->value
.bytes
, data
, len
);
750 static inline BOOL
read_end_of_data( struct reader
*reader
)
752 return reader
->read_pos
>= reader
->read_size
;
755 static inline const unsigned char *read_current_ptr( struct reader
*reader
)
757 return &reader
->read_bufptr
[reader
->read_pos
];
760 /* UTF-8 support based on libs/wine/utf8.c */
762 /* number of following bytes in sequence based on first byte value (for bytes above 0x7f) */
763 static const char utf8_length
[128] =
765 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x80-0x8f */
766 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x90-0x9f */
767 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xa0-0xaf */
768 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xb0-0xbf */
769 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0xc0-0xcf */
770 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0xd0-0xdf */
771 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, /* 0xe0-0xef */
772 3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0 /* 0xf0-0xff */
775 /* first byte mask depending on UTF-8 sequence length */
776 static const unsigned char utf8_mask
[4] = { 0x7f, 0x1f, 0x0f, 0x07 };
778 /* minimum Unicode value depending on UTF-8 sequence length */
779 static const unsigned int utf8_minval
[4] = { 0x0, 0x80, 0x800, 0x10000 };
781 static inline unsigned int read_utf8_char( struct reader
*reader
, unsigned int *skip
)
783 unsigned int len
, res
;
784 unsigned char ch
= reader
->read_bufptr
[reader
->read_pos
];
785 const unsigned char *end
;
787 if (reader
->read_pos
>= reader
->read_size
) return 0;
794 len
= utf8_length
[ch
- 0x80];
795 if (reader
->read_pos
+ len
>= reader
->read_size
) return 0;
796 end
= reader
->read_bufptr
+ reader
->read_pos
+ len
;
797 res
= ch
& utf8_mask
[len
];
802 if ((ch
= end
[-3] ^ 0x80) >= 0x40) break;
803 res
= (res
<< 6) | ch
;
805 if ((ch
= end
[-2] ^ 0x80) >= 0x40) break;
806 res
= (res
<< 6) | ch
;
808 if ((ch
= end
[-1] ^ 0x80) >= 0x40) break;
809 res
= (res
<< 6) | ch
;
810 if (res
< utf8_minval
[len
]) break;
818 static inline void read_skip( struct reader
*reader
, unsigned int count
)
820 while (reader
->read_pos
< reader
->read_size
&& count
)
827 static inline BOOL
read_isnamechar( unsigned int ch
)
829 /* FIXME: incomplete */
830 return (ch
>= 'A' && ch
<= 'Z') ||
831 (ch
>= 'a' && ch
<= 'z') ||
832 (ch
>= '0' && ch
<= '9') ||
833 ch
== '_' || ch
== '-' || ch
== '.' || ch
== ':';
836 static inline BOOL
read_isspace( unsigned int ch
)
838 return ch
== ' ' || ch
== '\t' || ch
== '\r' || ch
== '\n';
841 static inline void read_skip_whitespace( struct reader
*reader
)
843 while (reader
->read_pos
< reader
->read_size
&& read_isspace( reader
->read_bufptr
[reader
->read_pos
] ))
847 static inline int read_cmp( struct reader
*reader
, const char *str
, int len
)
849 const unsigned char *ptr
= read_current_ptr( reader
);
851 if (len
< 0) len
= strlen( str
);
852 if (reader
->read_pos
+ len
> reader
->read_size
) return -1;
855 if (*str
!= *ptr
) return *ptr
- *str
;
861 static HRESULT
read_xmldecl( struct reader
*reader
)
863 if (!reader
->read_size
) return WS_E_INVALID_FORMAT
;
865 if (read_cmp( reader
, "<", 1 ) || read_cmp( reader
, "<?", 2 ))
867 reader
->state
= READER_STATE_BOF
;
870 if (read_cmp( reader
, "<?xml ", 6 )) return WS_E_INVALID_FORMAT
;
871 read_skip( reader
, 6 );
873 /* FIXME: parse attributes */
874 while (reader
->read_pos
< reader
->read_size
&& reader
->read_bufptr
[reader
->read_pos
] != '?')
877 if (read_cmp( reader
, "?>", 2 )) return WS_E_INVALID_FORMAT
;
878 read_skip( reader
, 2 );
880 reader
->state
= READER_STATE_BOF
;
884 HRESULT
append_attribute( WS_XML_ELEMENT_NODE
*elem
, WS_XML_ATTRIBUTE
*attr
)
886 if (elem
->attributeCount
)
888 WS_XML_ATTRIBUTE
**tmp
;
889 if (!(tmp
= heap_realloc( elem
->attributes
, (elem
->attributeCount
+ 1) * sizeof(attr
) )))
890 return E_OUTOFMEMORY
;
891 elem
->attributes
= tmp
;
893 else if (!(elem
->attributes
= heap_alloc( sizeof(attr
) ))) return E_OUTOFMEMORY
;
894 elem
->attributes
[elem
->attributeCount
++] = attr
;
898 static HRESULT
parse_name( const unsigned char *str
, unsigned int len
,
899 WS_XML_STRING
**prefix
, WS_XML_STRING
**localname
)
901 const unsigned char *name_ptr
= str
, *prefix_ptr
= NULL
;
902 unsigned int i
, name_len
= len
, prefix_len
= 0;
904 for (i
= 0; i
< len
; i
++)
910 name_ptr
= &str
[i
+ 1];
915 if (!(*prefix
= alloc_xml_string( prefix_ptr
, prefix_len
))) return E_OUTOFMEMORY
;
916 if (!(*localname
= alloc_xml_string( name_ptr
, name_len
)))
918 heap_free( *prefix
);
919 return E_OUTOFMEMORY
;
924 static HRESULT
read_attribute( struct reader
*reader
, WS_XML_ATTRIBUTE
**ret
)
926 static const WS_XML_STRING xmlns
= {5, (BYTE
*)"xmlns"};
927 WS_XML_ATTRIBUTE
*attr
;
928 WS_XML_UTF8_TEXT
*text
;
929 unsigned int len
= 0, ch
, skip
, quote
;
930 const unsigned char *start
;
931 WS_XML_STRING
*prefix
, *localname
;
932 HRESULT hr
= WS_E_INVALID_FORMAT
;
934 if (!(attr
= heap_alloc_zero( sizeof(*attr
) ))) return E_OUTOFMEMORY
;
936 start
= read_current_ptr( reader
);
939 if (!(ch
= read_utf8_char( reader
, &skip
))) goto error
;
940 if (!read_isnamechar( ch
)) break;
941 read_skip( reader
, skip
);
944 if (!len
) goto error
;
946 if ((hr
= parse_name( start
, len
, &prefix
, &localname
)) != S_OK
) goto error
;
948 if (WsXmlStringEquals( prefix
, &xmlns
, NULL
) == S_OK
)
951 if (!(attr
->prefix
= alloc_xml_string( localname
->bytes
, localname
->length
))) goto error
;
952 attr
->localName
= localname
;
956 attr
->prefix
= prefix
;
957 attr
->localName
= localname
;
960 hr
= WS_E_INVALID_FORMAT
;
961 read_skip_whitespace( reader
);
962 if (read_cmp( reader
, "=", 1 )) goto error
;
963 read_skip( reader
, 1 );
965 read_skip_whitespace( reader
);
966 if (read_cmp( reader
, "\"", 1 ) && read_cmp( reader
, "'", 1 )) goto error
;
967 quote
= read_utf8_char( reader
, &skip
);
968 read_skip( reader
, 1 );
971 start
= read_current_ptr( reader
);
974 if (!(ch
= read_utf8_char( reader
, &skip
))) goto error
;
975 if (ch
== quote
) break;
976 read_skip( reader
, skip
);
979 read_skip( reader
, 1 );
984 if (!(attr
->ns
= alloc_xml_string( start
, len
))) goto error
;
985 if (!(text
= alloc_utf8_text( NULL
, 0 ))) goto error
;
986 attr
->value
= &text
->text
;
990 if (!(attr
->ns
= alloc_xml_string( NULL
, 0 ))) goto error
;
991 if (!(text
= alloc_utf8_text( start
, len
))) goto error
;
992 attr
->value
= &text
->text
;
994 attr
->singleQuote
= (quote
== '\'');
1000 free_attribute( attr
);
1004 static int cmp_name( const unsigned char *name1
, ULONG len1
, const unsigned char *name2
, ULONG len2
)
1007 if (len1
!= len2
) return 1;
1008 for (i
= 0; i
< len1
; i
++) { if (toupper( name1
[i
] ) != toupper( name2
[i
] )) return 1; }
1012 static struct node
*read_find_parent( struct reader
*reader
, const WS_XML_STRING
*prefix
,
1013 const WS_XML_STRING
*localname
)
1015 struct node
*parent
;
1016 const WS_XML_STRING
*str
;
1018 for (parent
= reader
->current
; parent
; parent
= parent
->parent
)
1020 if (parent
->hdr
.node
.nodeType
== WS_XML_NODE_TYPE_BOF
)
1022 if (!localname
) return parent
;
1025 else if (parent
->hdr
.node
.nodeType
== WS_XML_NODE_TYPE_ELEMENT
)
1027 if (!localname
) return parent
;
1029 str
= parent
->hdr
.prefix
;
1030 if (cmp_name( str
->bytes
, str
->length
, prefix
->bytes
, prefix
->length
)) continue;
1031 str
= parent
->hdr
.localName
;
1032 if (cmp_name( str
->bytes
, str
->length
, localname
->bytes
, localname
->length
)) continue;
1040 static HRESULT
read_element( struct reader
*reader
)
1042 unsigned int len
= 0, ch
, skip
;
1043 const unsigned char *start
;
1044 struct node
*node
= NULL
, *parent
;
1045 WS_XML_ELEMENT_NODE
*elem
;
1046 WS_XML_ATTRIBUTE
*attr
;
1047 HRESULT hr
= WS_E_INVALID_FORMAT
;
1049 if (read_end_of_data( reader
))
1051 struct list
*eof
= list_tail( &reader
->root
->children
);
1052 reader
->current
= LIST_ENTRY( eof
, struct node
, entry
);
1053 reader
->state
= READER_STATE_EOF
;
1057 if (read_cmp( reader
, "<", 1 )) goto error
;
1058 read_skip( reader
, 1 );
1060 start
= read_current_ptr( reader
);
1063 if (!(ch
= read_utf8_char( reader
, &skip
))) goto error
;
1064 if (!read_isnamechar( ch
)) break;
1065 read_skip( reader
, skip
);
1068 if (!len
) goto error
;
1070 if (!(parent
= read_find_parent( reader
, NULL
, NULL
))) goto error
;
1073 if (!(node
= alloc_node( WS_XML_NODE_TYPE_ELEMENT
))) goto error
;
1074 elem
= (WS_XML_ELEMENT_NODE
*)node
;
1076 if ((hr
= parse_name( start
, len
, &elem
->prefix
, &elem
->localName
)) != S_OK
) goto error
;
1078 if (!(elem
->ns
= alloc_xml_string( NULL
, 0 ))) goto error
;
1079 elem
->ns
->bytes
= (BYTE
*)(elem
->ns
+ 1);
1081 reader
->current_attr
= 0;
1084 read_skip_whitespace( reader
);
1085 if (!read_cmp( reader
, ">", 1 ) || !read_cmp( reader
, "/>", 2 )) break;
1086 if ((hr
= read_attribute( reader
, &attr
)) != S_OK
) goto error
;
1087 if ((hr
= append_attribute( elem
, attr
)) != S_OK
)
1089 free_attribute( attr
);
1092 reader
->current_attr
++;
1095 read_insert_node( reader
, parent
, node
);
1096 reader
->state
= READER_STATE_STARTELEMENT
;
1104 static HRESULT
read_text( struct reader
*reader
)
1106 unsigned int len
= 0, ch
, skip
;
1107 const unsigned char *start
;
1109 WS_XML_TEXT_NODE
*text
;
1110 WS_XML_UTF8_TEXT
*utf8
;
1112 start
= read_current_ptr( reader
);
1115 if (read_end_of_data( reader
)) break;
1116 if (!(ch
= read_utf8_char( reader
, &skip
))) return WS_E_INVALID_FORMAT
;
1117 if (ch
== '<') break;
1118 read_skip( reader
, skip
);
1122 if (!(node
= alloc_node( WS_XML_NODE_TYPE_TEXT
))) return E_OUTOFMEMORY
;
1123 text
= (WS_XML_TEXT_NODE
*)node
;
1124 if (!(utf8
= alloc_utf8_text( start
, len
)))
1127 return E_OUTOFMEMORY
;
1129 text
->text
= &utf8
->text
;
1131 read_insert_node( reader
, reader
->current
, node
);
1132 reader
->state
= READER_STATE_TEXT
;
1136 static HRESULT
read_node( struct reader
* );
1138 static HRESULT
read_startelement( struct reader
*reader
)
1142 read_skip_whitespace( reader
);
1143 if (!read_cmp( reader
, "/>", 2 ))
1145 read_skip( reader
, 2 );
1146 if (!(node
= alloc_node( WS_XML_NODE_TYPE_END_ELEMENT
))) return E_OUTOFMEMORY
;
1147 read_insert_node( reader
, reader
->current
, node
);
1148 reader
->state
= READER_STATE_ENDELEMENT
;
1151 else if (!read_cmp( reader
, ">", 1 ))
1153 read_skip( reader
, 1 );
1154 return read_node( reader
);
1156 return WS_E_INVALID_FORMAT
;
1159 static HRESULT
read_to_startelement( struct reader
*reader
, BOOL
*found
)
1163 switch (reader
->state
)
1165 case READER_STATE_INITIAL
:
1166 if ((hr
= read_xmldecl( reader
)) != S_OK
) return hr
;
1169 case READER_STATE_STARTELEMENT
:
1170 if (found
) *found
= TRUE
;
1177 read_skip_whitespace( reader
);
1178 if ((hr
= read_element( reader
)) == S_OK
&& found
)
1180 if (reader
->state
== READER_STATE_STARTELEMENT
)
1189 static HRESULT
read_endelement( struct reader
*reader
)
1191 struct node
*node
, *parent
;
1192 unsigned int len
= 0, ch
, skip
;
1193 const unsigned char *start
;
1194 WS_XML_STRING
*prefix
, *localname
;
1197 if (reader
->state
== READER_STATE_EOF
) return WS_E_INVALID_FORMAT
;
1199 if (read_end_of_data( reader
))
1201 struct list
*eof
= list_tail( &reader
->root
->children
);
1202 reader
->current
= LIST_ENTRY( eof
, struct node
, entry
);
1203 reader
->state
= READER_STATE_EOF
;
1207 if (read_cmp( reader
, "</", 2 )) return WS_E_INVALID_FORMAT
;
1208 read_skip( reader
, 2 );
1210 start
= read_current_ptr( reader
);
1213 if (!(ch
= read_utf8_char( reader
, &skip
))) return WS_E_INVALID_FORMAT
;
1216 read_skip( reader
, 1 );
1219 if (!read_isnamechar( ch
)) return WS_E_INVALID_FORMAT
;
1220 read_skip( reader
, skip
);
1224 if ((hr
= parse_name( start
, len
, &prefix
, &localname
)) != S_OK
) return hr
;
1225 parent
= read_find_parent( reader
, prefix
, localname
);
1226 heap_free( prefix
);
1227 heap_free( localname
);
1228 if (!parent
) return WS_E_INVALID_FORMAT
;
1230 if (!(node
= alloc_node( WS_XML_NODE_TYPE_END_ELEMENT
))) return E_OUTOFMEMORY
;
1231 read_insert_node( reader
, parent
, node
);
1232 reader
->state
= READER_STATE_ENDELEMENT
;
1236 static HRESULT
read_comment( struct reader
*reader
)
1238 unsigned int len
= 0, ch
, skip
;
1239 const unsigned char *start
;
1241 WS_XML_COMMENT_NODE
*comment
;
1243 if (read_cmp( reader
, "<!--", 4 )) return WS_E_INVALID_FORMAT
;
1244 read_skip( reader
, 4 );
1246 start
= read_current_ptr( reader
);
1249 if (!read_cmp( reader
, "-->", 3 ))
1251 read_skip( reader
, 3 );
1254 if (!(ch
= read_utf8_char( reader
, &skip
))) return WS_E_INVALID_FORMAT
;
1255 read_skip( reader
, skip
);
1259 if (!(node
= alloc_node( WS_XML_NODE_TYPE_COMMENT
))) return E_OUTOFMEMORY
;
1260 comment
= (WS_XML_COMMENT_NODE
*)node
;
1261 if (!(comment
->value
.bytes
= heap_alloc( len
)))
1264 return E_OUTOFMEMORY
;
1266 memcpy( comment
->value
.bytes
, start
, len
);
1267 comment
->value
.length
= len
;
1269 read_insert_node( reader
, reader
->current
, node
);
1270 reader
->state
= READER_STATE_COMMENT
;
1274 static HRESULT
read_startcdata( struct reader
*reader
)
1278 if (read_cmp( reader
, "<![CDATA[", 9 )) return WS_E_INVALID_FORMAT
;
1279 read_skip( reader
, 9 );
1281 if (!(node
= alloc_node( WS_XML_NODE_TYPE_CDATA
))) return E_OUTOFMEMORY
;
1282 read_insert_node( reader
, reader
->current
, node
);
1283 reader
->state
= READER_STATE_STARTCDATA
;
1287 static HRESULT
read_cdata( struct reader
*reader
)
1289 unsigned int len
= 0, ch
, skip
;
1290 const unsigned char *start
;
1292 WS_XML_TEXT_NODE
*text
;
1293 WS_XML_UTF8_TEXT
*utf8
;
1295 start
= read_current_ptr( reader
);
1298 if (!read_cmp( reader
, "]]>", 3 )) break;
1299 if (!(ch
= read_utf8_char( reader
, &skip
))) return WS_E_INVALID_FORMAT
;
1300 read_skip( reader
, skip
);
1304 if (!(node
= alloc_node( WS_XML_NODE_TYPE_TEXT
))) return E_OUTOFMEMORY
;
1305 text
= (WS_XML_TEXT_NODE
*)node
;
1306 if (!(utf8
= alloc_utf8_text( start
, len
)))
1309 return E_OUTOFMEMORY
;
1311 text
->text
= &utf8
->text
;
1313 read_insert_node( reader
, reader
->current
, node
);
1314 reader
->state
= READER_STATE_CDATA
;
1318 static HRESULT
read_endcdata( struct reader
*reader
)
1322 if (read_cmp( reader
, "]]>", 3 )) return WS_E_INVALID_FORMAT
;
1323 read_skip( reader
, 3 );
1325 if (!(node
= alloc_node( WS_XML_NODE_TYPE_END_CDATA
))) return E_OUTOFMEMORY
;
1326 read_insert_node( reader
, reader
->current
->parent
, node
);
1327 reader
->state
= READER_STATE_ENDCDATA
;
1331 static HRESULT
read_node( struct reader
*reader
)
1337 if (read_end_of_data( reader
))
1339 struct list
*eof
= list_tail( &reader
->root
->children
);
1340 reader
->current
= LIST_ENTRY( eof
, struct node
, entry
);
1341 reader
->state
= READER_STATE_EOF
;
1344 if (reader
->state
== READER_STATE_STARTCDATA
) return read_cdata( reader
);
1345 else if (reader
->state
== READER_STATE_CDATA
) return read_endcdata( reader
);
1346 else if (!read_cmp( reader
, "<?", 2 ))
1348 hr
= read_xmldecl( reader
);
1349 if (FAILED( hr
)) return hr
;
1351 else if (!read_cmp( reader
, "</", 2 )) return read_endelement( reader
);
1352 else if (!read_cmp( reader
, "<![CDATA[", 9 )) return read_startcdata( reader
);
1353 else if (!read_cmp( reader
, "<!--", 4 )) return read_comment( reader
);
1354 else if (!read_cmp( reader
, "<", 1 )) return read_element( reader
);
1355 else if (!read_cmp( reader
, "/>", 2 ) || !read_cmp( reader
, ">", 1 )) return read_startelement( reader
);
1356 else return read_text( reader
);
1360 /**************************************************************************
1361 * WsReadEndElement [webservices.@]
1363 HRESULT WINAPI
WsReadEndElement( WS_XML_READER
*handle
, WS_ERROR
*error
)
1365 struct reader
*reader
= (struct reader
*)handle
;
1367 TRACE( "%p %p\n", handle
, error
);
1368 if (error
) FIXME( "ignoring error parameter\n" );
1370 if (!reader
) return E_INVALIDARG
;
1371 return read_endelement( reader
);
1374 /**************************************************************************
1375 * WsReadNode [webservices.@]
1377 HRESULT WINAPI
WsReadNode( WS_XML_READER
*handle
, WS_ERROR
*error
)
1379 struct reader
*reader
= (struct reader
*)handle
;
1381 TRACE( "%p %p\n", handle
, error
);
1382 if (error
) FIXME( "ignoring error parameter\n" );
1384 if (!reader
) return E_INVALIDARG
;
1385 return read_node( reader
);
1388 /**************************************************************************
1389 * WsReadStartElement [webservices.@]
1391 HRESULT WINAPI
WsReadStartElement( WS_XML_READER
*handle
, WS_ERROR
*error
)
1393 struct reader
*reader
= (struct reader
*)handle
;
1395 TRACE( "%p %p\n", handle
, error
);
1396 if (error
) FIXME( "ignoring error parameter\n" );
1398 if (!reader
) return E_INVALIDARG
;
1399 return read_startelement( reader
);
1402 /**************************************************************************
1403 * WsReadToStartElement [webservices.@]
1405 HRESULT WINAPI
WsReadToStartElement( WS_XML_READER
*handle
, const WS_XML_STRING
*localname
,
1406 const WS_XML_STRING
*ns
, BOOL
*found
, WS_ERROR
*error
)
1408 struct reader
*reader
= (struct reader
*)handle
;
1410 TRACE( "%p %s %s %p %p\n", handle
, debugstr_xmlstr(localname
), debugstr_xmlstr(ns
), found
, error
);
1411 if (error
) FIXME( "ignoring error parameter\n" );
1413 if (!reader
) return E_INVALIDARG
;
1414 if (localname
|| ns
) FIXME( "name and/or namespace not verified\n" );
1416 return read_to_startelement( reader
, found
);
1419 static BOOL
move_to_root_element( struct reader
*reader
)
1424 if (!(ptr
= list_head( &reader
->root
->children
))) return FALSE
;
1425 node
= LIST_ENTRY( ptr
, struct node
, entry
);
1426 if (node
->hdr
.node
.nodeType
== WS_XML_NODE_TYPE_ELEMENT
)
1428 reader
->current
= node
;
1431 while ((ptr
= list_next( &reader
->root
->children
, &node
->entry
)))
1433 struct node
*next
= LIST_ENTRY( ptr
, struct node
, entry
);
1434 if (next
->hdr
.node
.nodeType
== WS_XML_NODE_TYPE_ELEMENT
)
1436 reader
->current
= next
;
1444 static BOOL
move_to_next_element( struct reader
*reader
)
1447 struct node
*node
= reader
->current
;
1449 while ((ptr
= list_next( &node
->parent
->children
, &node
->entry
)))
1451 struct node
*next
= LIST_ENTRY( ptr
, struct node
, entry
);
1452 if (next
->hdr
.node
.nodeType
== WS_XML_NODE_TYPE_ELEMENT
)
1454 reader
->current
= next
;
1462 static BOOL
move_to_prev_element( struct reader
*reader
)
1465 struct node
*node
= reader
->current
;
1467 while ((ptr
= list_prev( &node
->parent
->children
, &node
->entry
)))
1469 struct node
*prev
= LIST_ENTRY( ptr
, struct node
, entry
);
1470 if (prev
->hdr
.node
.nodeType
== WS_XML_NODE_TYPE_ELEMENT
)
1472 reader
->current
= prev
;
1480 static BOOL
move_to_child_element( struct reader
*reader
)
1485 if (!(ptr
= list_head( &reader
->current
->children
))) return FALSE
;
1486 node
= LIST_ENTRY( ptr
, struct node
, entry
);
1487 if (node
->hdr
.node
.nodeType
== WS_XML_NODE_TYPE_ELEMENT
)
1489 reader
->current
= node
;
1492 while ((ptr
= list_next( &reader
->current
->children
, &node
->entry
)))
1494 struct node
*next
= LIST_ENTRY( ptr
, struct node
, entry
);
1495 if (next
->hdr
.node
.nodeType
== WS_XML_NODE_TYPE_ELEMENT
)
1497 reader
->current
= next
;
1505 static BOOL
move_to_end_element( struct reader
*reader
)
1508 struct node
*node
= reader
->current
;
1510 if (node
->hdr
.node
.nodeType
!= WS_XML_NODE_TYPE_ELEMENT
) return FALSE
;
1512 if ((ptr
= list_tail( &node
->children
)))
1514 struct node
*tail
= LIST_ENTRY( ptr
, struct node
, entry
);
1515 if (tail
->hdr
.node
.nodeType
== WS_XML_NODE_TYPE_END_ELEMENT
)
1517 reader
->current
= tail
;
1524 static BOOL
move_to_parent_element( struct reader
*reader
)
1526 struct node
*parent
= reader
->current
->parent
;
1528 if (parent
&& (parent
->hdr
.node
.nodeType
== WS_XML_NODE_TYPE_ELEMENT
||
1529 parent
->hdr
.node
.nodeType
== WS_XML_NODE_TYPE_BOF
))
1531 reader
->current
= parent
;
1537 static HRESULT
read_move_to( struct reader
*reader
, WS_MOVE_TO move
, BOOL
*found
)
1540 BOOL success
= FALSE
;
1543 if (!read_end_of_data( reader
))
1545 while (reader
->state
!= READER_STATE_EOF
&& (hr
= read_node( reader
)) == S_OK
) { /* nothing */ };
1546 if (hr
!= S_OK
) return hr
;
1550 case WS_MOVE_TO_ROOT_ELEMENT
:
1551 success
= move_to_root_element( reader
);
1554 case WS_MOVE_TO_NEXT_ELEMENT
:
1555 success
= move_to_next_element( reader
);
1558 case WS_MOVE_TO_PREVIOUS_ELEMENT
:
1559 success
= move_to_prev_element( reader
);
1562 case WS_MOVE_TO_CHILD_ELEMENT
:
1563 success
= move_to_child_element( reader
);
1566 case WS_MOVE_TO_END_ELEMENT
:
1567 success
= move_to_end_element( reader
);
1570 case WS_MOVE_TO_PARENT_ELEMENT
:
1571 success
= move_to_parent_element( reader
);
1574 case WS_MOVE_TO_FIRST_NODE
:
1575 if ((ptr
= list_head( &reader
->current
->parent
->children
)))
1577 reader
->current
= LIST_ENTRY( ptr
, struct node
, entry
);
1582 case WS_MOVE_TO_NEXT_NODE
:
1583 if ((ptr
= list_next( &reader
->current
->parent
->children
, &reader
->current
->entry
)))
1585 reader
->current
= LIST_ENTRY( ptr
, struct node
, entry
);
1590 case WS_MOVE_TO_PREVIOUS_NODE
:
1591 if ((ptr
= list_prev( &reader
->current
->parent
->children
, &reader
->current
->entry
)))
1593 reader
->current
= LIST_ENTRY( ptr
, struct node
, entry
);
1598 case WS_MOVE_TO_CHILD_NODE
:
1599 if ((ptr
= list_head( &reader
->current
->children
)))
1601 reader
->current
= LIST_ENTRY( ptr
, struct node
, entry
);
1606 case WS_MOVE_TO_BOF
:
1607 reader
->current
= reader
->root
;
1611 case WS_MOVE_TO_EOF
:
1612 if ((ptr
= list_tail( &reader
->root
->children
)))
1614 reader
->current
= LIST_ENTRY( ptr
, struct node
, entry
);
1620 FIXME( "unhandled move %u\n", move
);
1629 return success
? S_OK
: WS_E_INVALID_FORMAT
;
1632 /**************************************************************************
1633 * WsMoveReader [webservices.@]
1635 HRESULT WINAPI
WsMoveReader( WS_XML_READER
*handle
, WS_MOVE_TO move
, BOOL
*found
, WS_ERROR
*error
)
1637 struct reader
*reader
= (struct reader
*)handle
;
1639 TRACE( "%p %u %p %p\n", handle
, move
, found
, error
);
1640 if (error
) FIXME( "ignoring error parameter\n" );
1642 if (!reader
) return E_INVALIDARG
;
1643 if (!reader
->input_type
) return WS_E_INVALID_OPERATION
;
1645 return read_move_to( reader
, move
, found
);
1648 /**************************************************************************
1649 * WsReadStartAttribute [webservices.@]
1651 HRESULT WINAPI
WsReadStartAttribute( WS_XML_READER
*handle
, ULONG index
, WS_ERROR
*error
)
1653 struct reader
*reader
= (struct reader
*)handle
;
1654 WS_XML_ELEMENT_NODE
*elem
;
1656 TRACE( "%p %u %p\n", handle
, index
, error
);
1657 if (error
) FIXME( "ignoring error parameter\n" );
1659 if (!reader
) return E_INVALIDARG
;
1661 elem
= &reader
->current
->hdr
;
1662 if (reader
->state
!= READER_STATE_STARTELEMENT
|| index
>= elem
->attributeCount
)
1663 return WS_E_INVALID_FORMAT
;
1665 reader
->current_attr
= index
;
1666 reader
->state
= READER_STATE_STARTATTRIBUTE
;
1670 /**************************************************************************
1671 * WsReadEndAttribute [webservices.@]
1673 HRESULT WINAPI
WsReadEndAttribute( WS_XML_READER
*handle
, WS_ERROR
*error
)
1675 struct reader
*reader
= (struct reader
*)handle
;
1677 TRACE( "%p %p\n", handle
, error
);
1678 if (error
) FIXME( "ignoring error parameter\n" );
1680 if (!reader
) return E_INVALIDARG
;
1682 if (reader
->state
!= READER_STATE_STARTATTRIBUTE
)
1683 return WS_E_INVALID_FORMAT
;
1685 reader
->state
= READER_STATE_STARTELEMENT
;
1689 static WCHAR
*xmltext_to_widechar( WS_HEAP
*heap
, const WS_XML_TEXT
*text
)
1693 switch (text
->textType
)
1695 case WS_XML_TEXT_TYPE_UTF8
:
1697 const WS_XML_UTF8_TEXT
*utf8
= (const WS_XML_UTF8_TEXT
*)text
;
1698 int len
= MultiByteToWideChar( CP_UTF8
, 0, (char *)utf8
->value
.bytes
, utf8
->value
.length
, NULL
, 0 );
1699 if (!(ret
= ws_alloc( heap
, (len
+ 1) * sizeof(WCHAR
) ))) return NULL
;
1700 MultiByteToWideChar( CP_UTF8
, 0, (char *)utf8
->value
.bytes
, utf8
->value
.length
, ret
, len
);
1705 FIXME( "unhandled type %u\n", text
->textType
);
1712 #define MAX_INT8 0x7f
1713 #define MIN_INT8 (-MAX_INT8 - 1)
1714 #define MAX_INT16 0x7fff
1715 #define MIN_INT16 (-MAX_INT16 - 1)
1716 #define MAX_INT32 0x7fffffff
1717 #define MIN_INT32 (-MAX_INT32 - 1)
1718 #define MAX_INT64 (((INT64)0x7fffffff << 32) | 0xffffffff)
1719 #define MIN_INT64 (-MAX_INT64 - 1)
1720 #define MAX_UINT8 0xff
1721 #define MAX_UINT16 0xffff
1722 #define MAX_UINT32 0xffffffff
1723 #define MAX_UINT64 (((UINT64)0xffffffff << 32) | 0xffffffff)
1725 static HRESULT
str_to_int64( const unsigned char *str
, ULONG len
, INT64 min
, INT64 max
, INT64
*ret
)
1727 BOOL negative
= FALSE
;
1728 const unsigned char *ptr
= str
;
1731 while (len
&& read_isspace( *ptr
)) { ptr
++; len
--; }
1732 while (len
&& read_isspace( ptr
[len
- 1] )) { len
--; }
1733 if (!len
) return WS_E_INVALID_FORMAT
;
1741 if (!len
) return WS_E_INVALID_FORMAT
;
1747 if (!isdigit( *ptr
)) return WS_E_INVALID_FORMAT
;
1749 if (negative
) val
= -val
;
1751 if ((!negative
&& (*ret
> max
/ 10 || *ret
* 10 > max
- val
)) ||
1752 (negative
&& (*ret
< min
/ 10 || *ret
* 10 < min
- val
)))
1754 return WS_E_NUMERIC_OVERFLOW
;
1756 *ret
= *ret
* 10 + val
;
1763 static HRESULT
str_to_uint64( const unsigned char *str
, ULONG len
, UINT64 max
, UINT64
*ret
)
1765 const unsigned char *ptr
= str
;
1768 while (len
&& read_isspace( *ptr
)) { ptr
++; len
--; }
1769 while (len
&& read_isspace( ptr
[len
- 1] )) { len
--; }
1770 if (!len
) return WS_E_INVALID_FORMAT
;
1776 if (!isdigit( *ptr
)) return WS_E_INVALID_FORMAT
;
1779 if ((*ret
> max
/ 10 || *ret
* 10 > max
- val
)) return WS_E_NUMERIC_OVERFLOW
;
1780 *ret
= *ret
* 10 + val
;
1787 static HRESULT
read_get_node_text( struct reader
*reader
, WS_XML_UTF8_TEXT
**ret
)
1789 WS_XML_TEXT_NODE
*text
;
1791 if (reader
->current
->hdr
.node
.nodeType
!= WS_XML_NODE_TYPE_TEXT
)
1792 return WS_E_INVALID_FORMAT
;
1794 text
= (WS_XML_TEXT_NODE
*)&reader
->current
->hdr
.node
;
1795 if (text
->text
->textType
!= WS_XML_TEXT_TYPE_UTF8
)
1797 FIXME( "text type %u not supported\n", text
->text
->textType
);
1800 *ret
= (WS_XML_UTF8_TEXT
*)text
->text
;
1804 static HRESULT
read_get_attribute_text( struct reader
*reader
, WS_XML_UTF8_TEXT
**ret
)
1806 WS_XML_ELEMENT_NODE
*elem
= &reader
->current
->hdr
;
1807 WS_XML_ATTRIBUTE
*attr
;
1809 if (reader
->current
->hdr
.node
.nodeType
!= WS_XML_NODE_TYPE_ELEMENT
||
1810 reader
->current_attr
>= elem
->attributeCount
) return WS_E_INVALID_FORMAT
;
1812 attr
= elem
->attributes
[reader
->current_attr
];
1813 if (attr
->value
->textType
!= WS_XML_TEXT_TYPE_UTF8
)
1815 FIXME( "text type %u not supported\n", attr
->value
->textType
);
1818 *ret
= (WS_XML_UTF8_TEXT
*)attr
->value
;
1819 reader
->current_attr
++;
1823 static BOOL
find_attribute( struct reader
*reader
, const WS_XML_STRING
*localname
,
1824 const WS_XML_STRING
*ns
, ULONG
*index
)
1827 WS_XML_ELEMENT_NODE
*elem
= &reader
->current
->hdr
;
1831 *index
= reader
->current_attr
;
1834 for (i
= 0; i
< elem
->attributeCount
; i
++)
1836 const WS_XML_STRING
*localname2
= elem
->attributes
[i
]->localName
;
1837 const WS_XML_STRING
*ns2
= elem
->attributes
[i
]->ns
;
1839 if (!cmp_name( localname
->bytes
, localname
->length
, localname2
->bytes
, localname2
->length
) &&
1840 !cmp_name( ns
->bytes
, ns
->length
, ns2
->bytes
, ns2
->length
))
1849 /**************************************************************************
1850 * WsFindAttribute [webservices.@]
1852 HRESULT WINAPI
WsFindAttribute( WS_XML_READER
*handle
, const WS_XML_STRING
*localname
,
1853 const WS_XML_STRING
*ns
, BOOL required
, ULONG
*index
,
1856 struct reader
*reader
= (struct reader
*)handle
;
1858 TRACE( "%p %s %s %d %p %p\n", handle
, debugstr_xmlstr(localname
), debugstr_xmlstr(ns
),
1859 required
, index
, error
);
1860 if (error
) FIXME( "ignoring error parameter\n" );
1862 if (!reader
|| !localname
|| !ns
|| !index
) return E_INVALIDARG
;
1864 if (reader
->current
->hdr
.node
.nodeType
!= WS_XML_NODE_TYPE_ELEMENT
)
1865 return WS_E_INVALID_OPERATION
;
1867 if (!find_attribute( reader
, localname
, ns
, index
))
1869 if (required
) return WS_E_INVALID_FORMAT
;
1876 static HRESULT
read_type_bool( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
1877 const WS_BOOL_DESCRIPTION
*desc
, BOOL
*ret
)
1879 WS_XML_UTF8_TEXT
*utf8
;
1885 FIXME( "description not supported\n" );
1890 case WS_ATTRIBUTE_TYPE_MAPPING
:
1891 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
1892 len
= utf8
->value
.length
;
1895 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
1896 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
1897 len
= utf8
->value
.length
;
1901 FIXME( "mapping %u not supported\n", mapping
);
1905 if (len
== 4 && !memcmp( utf8
->value
.bytes
, "true", 4 )) *ret
= TRUE
;
1906 else if (len
== 1 && !memcmp( utf8
->value
.bytes
, "1", 1 )) *ret
= TRUE
;
1907 else if (len
== 5 && !memcmp( utf8
->value
.bytes
, "false", 5 )) *ret
= FALSE
;
1908 else if (len
== 1 && !memcmp( utf8
->value
.bytes
, "0", 1 )) *ret
= FALSE
;
1909 else return WS_E_INVALID_FORMAT
;
1914 static HRESULT
read_type_int8( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
1915 const WS_INT8_DESCRIPTION
*desc
, INT8
*ret
)
1917 WS_XML_UTF8_TEXT
*utf8
;
1923 FIXME( "description not supported\n" );
1928 case WS_ATTRIBUTE_TYPE_MAPPING
:
1929 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
1932 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
1933 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
1937 FIXME( "mapping %u not supported\n", mapping
);
1941 if ((hr
= str_to_int64( utf8
->value
.bytes
, utf8
->value
.length
, MIN_INT8
, MAX_INT8
, &val
)) != S_OK
)
1948 static HRESULT
read_type_int16( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
1949 const WS_INT16_DESCRIPTION
*desc
, INT16
*ret
)
1951 WS_XML_UTF8_TEXT
*utf8
;
1957 FIXME( "description not supported\n" );
1962 case WS_ATTRIBUTE_TYPE_MAPPING
:
1963 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
1966 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
1967 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
1971 FIXME( "mapping %u not supported\n", mapping
);
1975 if ((hr
= str_to_int64( utf8
->value
.bytes
, utf8
->value
.length
, MIN_INT16
, MAX_INT16
, &val
)) != S_OK
)
1982 static HRESULT
read_type_int32( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
1983 const WS_INT32_DESCRIPTION
*desc
, INT32
*ret
)
1985 WS_XML_UTF8_TEXT
*utf8
;
1991 FIXME( "description not supported\n" );
1996 case WS_ATTRIBUTE_TYPE_MAPPING
:
1997 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
2000 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
2001 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
2005 FIXME( "mapping %u not supported\n", mapping
);
2009 if ((hr
= str_to_int64( utf8
->value
.bytes
, utf8
->value
.length
, MIN_INT32
, MAX_INT32
, &val
)) != S_OK
)
2016 static HRESULT
read_type_int64( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2017 const WS_INT64_DESCRIPTION
*desc
, INT64
*ret
)
2019 WS_XML_UTF8_TEXT
*utf8
;
2025 FIXME( "description not supported\n" );
2030 case WS_ATTRIBUTE_TYPE_MAPPING
:
2031 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
2034 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
2035 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
2039 FIXME( "mapping %u not supported\n", mapping
);
2043 if ((hr
= str_to_int64( utf8
->value
.bytes
, utf8
->value
.length
, MIN_INT64
, MAX_INT64
, &val
)) != S_OK
)
2050 static HRESULT
read_type_uint8( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2051 const WS_UINT8_DESCRIPTION
*desc
, UINT8
*ret
)
2053 WS_XML_UTF8_TEXT
*utf8
;
2059 FIXME( "description not supported\n" );
2064 case WS_ATTRIBUTE_TYPE_MAPPING
:
2065 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
2068 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
2069 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
2073 FIXME( "mapping %u not supported\n", mapping
);
2077 if ((hr
= str_to_uint64( utf8
->value
.bytes
, utf8
->value
.length
, MAX_UINT8
, &val
)) != S_OK
)
2084 static HRESULT
read_type_uint16( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2085 const WS_UINT16_DESCRIPTION
*desc
, UINT16
*ret
)
2087 WS_XML_UTF8_TEXT
*utf8
;
2093 FIXME( "description not supported\n" );
2098 case WS_ATTRIBUTE_TYPE_MAPPING
:
2099 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
2102 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
2103 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
2107 FIXME( "mapping %u not supported\n", mapping
);
2111 if ((hr
= str_to_uint64( utf8
->value
.bytes
, utf8
->value
.length
, MAX_UINT16
, &val
)) != S_OK
)
2118 static HRESULT
read_type_uint32( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2119 const WS_UINT32_DESCRIPTION
*desc
, UINT32
*ret
)
2121 WS_XML_UTF8_TEXT
*utf8
;
2127 FIXME( "description not supported\n" );
2132 case WS_ATTRIBUTE_TYPE_MAPPING
:
2133 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
2136 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
2137 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
2141 FIXME( "mapping %u not supported\n", mapping
);
2145 if ((hr
= str_to_uint64( utf8
->value
.bytes
, utf8
->value
.length
, MAX_UINT32
, &val
)) != S_OK
)
2152 static HRESULT
read_type_uint64( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2153 const WS_UINT64_DESCRIPTION
*desc
, UINT64
*ret
)
2155 WS_XML_UTF8_TEXT
*utf8
;
2161 FIXME( "description not supported\n" );
2166 case WS_ATTRIBUTE_TYPE_MAPPING
:
2167 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
2170 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
2171 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
2175 FIXME( "mapping %u not supported\n", mapping
);
2179 if ((hr
= str_to_uint64( utf8
->value
.bytes
, utf8
->value
.length
, MAX_UINT64
, &val
)) != S_OK
)
2186 static HRESULT
read_type_wsz( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2187 const WS_WSZ_DESCRIPTION
*desc
, WS_HEAP
*heap
, WCHAR
**ret
)
2189 WS_XML_UTF8_TEXT
*utf8
;
2195 FIXME( "description not supported\n" );
2200 case WS_ATTRIBUTE_TYPE_MAPPING
:
2201 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
2204 case WS_ELEMENT_TYPE_MAPPING
:
2205 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
2206 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
2210 FIXME( "mapping %u not supported\n", mapping
);
2214 if (!(str
= xmltext_to_widechar( heap
, &utf8
->text
))) return WS_E_QUOTA_EXCEEDED
;
2219 static HRESULT
read_type_struct( struct reader
*, WS_TYPE_MAPPING
, const WS_STRUCT_DESCRIPTION
*,
2220 WS_HEAP
*, void ** );
2222 static HRESULT
read_type_struct_field( struct reader
*reader
, const WS_FIELD_DESCRIPTION
*desc
,
2223 WS_HEAP
*heap
, char *buf
)
2225 char *ptr
= buf
+ desc
->offset
;
2226 WS_TYPE_MAPPING mapping
;
2229 if (desc
->options
&& desc
->options
!= WS_FIELD_POINTER
&&
2230 desc
->options
!= WS_FIELD_OPTIONAL
&&
2231 desc
->options
!= (WS_FIELD_POINTER
| WS_FIELD_OPTIONAL
))
2233 FIXME( "options 0x%x not supported\n", desc
->options
);
2237 switch (desc
->mapping
)
2239 case WS_ATTRIBUTE_FIELD_MAPPING
:
2240 mapping
= WS_ATTRIBUTE_TYPE_MAPPING
;
2243 case WS_ELEMENT_FIELD_MAPPING
:
2244 mapping
= WS_ELEMENT_TYPE_MAPPING
;
2248 FIXME( "unhandled field mapping %u\n", desc
->mapping
);
2254 case WS_STRUCT_TYPE
:
2255 hr
= read_type_struct( reader
, mapping
, desc
->typeDescription
, heap
, (void **)ptr
);
2259 hr
= read_type_bool( reader
, mapping
, desc
->typeDescription
, (BOOL
*)ptr
);
2263 hr
= read_type_int8( reader
, mapping
, desc
->typeDescription
, (INT8
*)ptr
);
2267 hr
= read_type_int16( reader
, mapping
, desc
->typeDescription
, (INT16
*)ptr
);
2271 hr
= read_type_int32( reader
, mapping
, desc
->typeDescription
, (INT32
*)ptr
);
2275 hr
= read_type_int64( reader
, mapping
, desc
->typeDescription
, (INT64
*)ptr
);
2279 hr
= read_type_uint8( reader
, mapping
, desc
->typeDescription
, (UINT8
*)ptr
);
2282 case WS_UINT16_TYPE
:
2283 hr
= read_type_uint16( reader
, mapping
, desc
->typeDescription
, (UINT16
*)ptr
);
2286 case WS_UINT32_TYPE
:
2287 hr
= read_type_uint32( reader
, mapping
, desc
->typeDescription
, (UINT32
*)ptr
);
2290 case WS_UINT64_TYPE
:
2291 hr
= read_type_uint64( reader
, mapping
, desc
->typeDescription
, (UINT64
*)ptr
);
2295 hr
= read_type_wsz( reader
, mapping
, desc
->typeDescription
, heap
, (WCHAR
**)ptr
);
2299 FIXME( "type %u not implemented\n", desc
->type
);
2306 static HRESULT
read_type_struct( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2307 const WS_STRUCT_DESCRIPTION
*desc
, WS_HEAP
*heap
, void **ret
)
2313 if (!desc
) return E_INVALIDARG
;
2315 if (desc
->structOptions
)
2317 FIXME( "struct options 0x%x not supported\n", desc
->structOptions
);
2323 case WS_ELEMENT_TYPE_MAPPING
:
2324 if ((hr
= read_to_startelement( reader
, NULL
)) != S_OK
) return hr
;
2327 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
2328 if ((hr
= read_to_startelement( reader
, NULL
)) != S_OK
) return hr
;
2329 if ((hr
= read_startelement( reader
)) != S_OK
) return hr
;
2333 FIXME( "unhandled mapping %u\n", mapping
);
2337 if (!(buf
= ws_alloc_zero( heap
, desc
->size
))) return WS_E_QUOTA_EXCEEDED
;
2339 for (i
= 0; i
< desc
->fieldCount
; i
++)
2341 if ((hr
= read_type_struct_field( reader
, desc
->fields
[i
], heap
, buf
)) != S_OK
)
2343 ws_free( heap
, buf
);
2350 case WS_ELEMENT_TYPE_MAPPING
:
2351 if ((hr
= read_endelement( reader
)) != S_OK
) return hr
;
2354 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
2355 if ((hr
= read_endelement( reader
)) != S_OK
) return hr
;
2356 if ((hr
= read_node( reader
)) != S_OK
) return hr
;
2357 if (reader
->state
!= READER_STATE_EOF
) return WS_E_INVALID_FORMAT
;
2367 static HRESULT
read_type( struct reader
*reader
, WS_TYPE_MAPPING mapping
, WS_TYPE type
,
2368 const void *desc
, WS_READ_OPTION option
, WS_HEAP
*heap
,
2369 void *value
, ULONG size
)
2373 case WS_STRUCT_TYPE
:
2376 if (option
!= WS_READ_REQUIRED_POINTER
|| size
!= sizeof(*ptr
))
2377 return E_INVALIDARG
;
2379 return read_type_struct( reader
, mapping
, desc
, heap
, ptr
);
2384 if (option
!= WS_READ_REQUIRED_VALUE
)
2386 FIXME( "read option %u not supported\n", option
);
2389 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2390 return read_type_bool( reader
, mapping
, desc
, ptr
);
2395 if (option
!= WS_READ_REQUIRED_VALUE
)
2397 FIXME( "read option %u not supported\n", option
);
2400 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2401 return read_type_int8( reader
, mapping
, desc
, ptr
);
2406 if (option
!= WS_READ_REQUIRED_VALUE
)
2408 FIXME( "read option %u not supported\n", option
);
2411 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2412 return read_type_int16( reader
, mapping
, desc
, ptr
);
2417 if (option
!= WS_READ_REQUIRED_VALUE
)
2419 FIXME( "read option %u not supported\n", option
);
2422 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2423 return read_type_int32( reader
, mapping
, desc
, ptr
);
2428 if (option
!= WS_READ_REQUIRED_VALUE
)
2430 FIXME( "read option %u not supported\n", option
);
2433 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2434 return read_type_int64( reader
, mapping
, desc
, ptr
);
2439 if (option
!= WS_READ_REQUIRED_VALUE
)
2441 FIXME( "read option %u not supported\n", option
);
2444 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2445 return read_type_uint8( reader
, mapping
, desc
, ptr
);
2447 case WS_UINT16_TYPE
:
2449 UINT16
*ptr
= value
;
2450 if (option
!= WS_READ_REQUIRED_VALUE
)
2452 FIXME( "read option %u not supported\n", option
);
2455 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2456 return read_type_uint16( reader
, mapping
, desc
, ptr
);
2458 case WS_UINT32_TYPE
:
2460 UINT32
*ptr
= value
;
2461 if (option
!= WS_READ_REQUIRED_VALUE
)
2463 FIXME( "read option %u not supported\n", option
);
2466 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2467 return read_type_uint32( reader
, mapping
, desc
, ptr
);
2469 case WS_UINT64_TYPE
:
2471 UINT64
*ptr
= value
;
2472 if (option
!= WS_READ_REQUIRED_VALUE
)
2474 FIXME( "read option %u not supported\n", option
);
2477 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2478 return read_type_uint64( reader
, mapping
, desc
, ptr
);
2482 WCHAR
**ptr
= value
;
2483 if (option
!= WS_READ_REQUIRED_POINTER
)
2485 FIXME( "read option %u not supported\n", option
);
2488 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2489 return read_type_wsz( reader
, mapping
, desc
, heap
, ptr
);
2492 FIXME( "type %u not supported\n", type
);
2497 /**************************************************************************
2498 * WsReadType [webservices.@]
2500 HRESULT WINAPI
WsReadType( WS_XML_READER
*handle
, WS_TYPE_MAPPING mapping
, WS_TYPE type
,
2501 const void *desc
, WS_READ_OPTION option
, WS_HEAP
*heap
, void *value
,
2502 ULONG size
, WS_ERROR
*error
)
2504 struct reader
*reader
= (struct reader
*)handle
;
2506 TRACE( "%p %u %u %p %u %p %p %u %p\n", handle
, mapping
, type
, desc
, option
, heap
, value
,
2508 if (error
) FIXME( "ignoring error parameter\n" );
2510 if (!reader
|| !value
) return E_INVALIDARG
;
2512 return read_type( reader
, mapping
, type
, desc
, option
, heap
, value
, size
);
2515 /**************************************************************************
2516 * WsSetErrorProperty [webservices.@]
2518 HRESULT WINAPI
WsSetErrorProperty( WS_ERROR
*handle
, WS_ERROR_PROPERTY_ID id
, const void *value
,
2521 struct error
*error
= (struct error
*)handle
;
2523 TRACE( "%p %u %p %u\n", handle
, id
, value
, size
);
2525 if (id
== WS_ERROR_PROPERTY_LANGID
) return WS_E_INVALID_OPERATION
;
2526 return set_error_prop( error
, id
, value
, size
);
2529 static inline BOOL
is_utf8( const unsigned char *data
, ULONG size
, ULONG
*offset
)
2531 static const char bom
[] = {0xef,0xbb,0xbf};
2532 const unsigned char *p
= data
;
2534 return (size
>= sizeof(bom
) && !memcmp( p
, bom
, sizeof(bom
) ) && (*offset
= sizeof(bom
))) ||
2535 (size
> 2 && !(*offset
= 0));
2538 static inline BOOL
is_utf16le( const unsigned char *data
, ULONG size
, ULONG
*offset
)
2540 static const char bom
[] = {0xff,0xfe};
2541 const unsigned char *p
= data
;
2543 return (size
>= sizeof(bom
) && !memcmp( p
, bom
, sizeof(bom
) ) && (*offset
= sizeof(bom
))) ||
2544 (size
>= 4 && p
[0] == '<' && !p
[1] && !(*offset
= 0));
2547 static WS_CHARSET
detect_charset( const unsigned char *data
, ULONG size
, ULONG
*offset
)
2551 /* FIXME: parse xml declaration */
2553 if (is_utf16le( data
, size
, offset
)) ret
= WS_CHARSET_UTF16LE
;
2554 else if (is_utf8( data
, size
, offset
)) ret
= WS_CHARSET_UTF8
;
2557 FIXME( "charset not recognized\n" );
2561 TRACE( "detected charset %u\n", ret
);
2565 static void set_input_buffer( struct reader
*reader
, const unsigned char *data
, ULONG size
)
2567 reader
->input_type
= WS_XML_READER_INPUT_TYPE_BUFFER
;
2568 reader
->input_data
= data
;
2569 reader
->input_size
= size
;
2571 reader
->read_size
= reader
->input_size
;
2572 reader
->read_pos
= 0;
2573 reader
->read_bufptr
= reader
->input_data
;
2576 /**************************************************************************
2577 * WsSetInput [webservices.@]
2579 HRESULT WINAPI
WsSetInput( WS_XML_READER
*handle
, const WS_XML_READER_ENCODING
*encoding
,
2580 const WS_XML_READER_INPUT
*input
, const WS_XML_READER_PROPERTY
*properties
,
2581 ULONG count
, WS_ERROR
*error
)
2583 struct reader
*reader
= (struct reader
*)handle
;
2586 ULONG i
, offset
= 0;
2588 TRACE( "%p %p %p %p %u %p\n", handle
, encoding
, input
, properties
, count
, error
);
2589 if (error
) FIXME( "ignoring error parameter\n" );
2591 if (!reader
) return E_INVALIDARG
;
2593 for (i
= 0; i
< count
; i
++)
2595 hr
= set_reader_prop( reader
, properties
[i
].id
, properties
[i
].value
, properties
[i
].valueSize
);
2596 if (hr
!= S_OK
) return hr
;
2599 if ((hr
= read_init_state( reader
)) != S_OK
) return hr
;
2601 switch (encoding
->encodingType
)
2603 case WS_XML_READER_ENCODING_TYPE_TEXT
:
2605 WS_XML_READER_TEXT_ENCODING
*text
= (WS_XML_READER_TEXT_ENCODING
*)encoding
;
2606 WS_XML_READER_BUFFER_INPUT
*buf
= (WS_XML_READER_BUFFER_INPUT
*)input
;
2607 WS_CHARSET charset
= text
->charSet
;
2609 if (input
->inputType
!= WS_XML_READER_INPUT_TYPE_BUFFER
)
2611 FIXME( "charset detection on input type %u not supported\n", input
->inputType
);
2615 if (charset
== WS_CHARSET_AUTO
)
2616 charset
= detect_charset( buf
->encodedData
, buf
->encodedDataSize
, &offset
);
2618 hr
= set_reader_prop( reader
, WS_XML_READER_PROPERTY_CHARSET
, &charset
, sizeof(charset
) );
2619 if (hr
!= S_OK
) return hr
;
2623 FIXME( "encoding type %u not supported\n", encoding
->encodingType
);
2626 switch (input
->inputType
)
2628 case WS_XML_READER_INPUT_TYPE_BUFFER
:
2630 WS_XML_READER_BUFFER_INPUT
*buf
= (WS_XML_READER_BUFFER_INPUT
*)input
;
2631 set_input_buffer( reader
, (const unsigned char *)buf
->encodedData
+ offset
, buf
->encodedDataSize
- offset
);
2635 FIXME( "input type %u not supported\n", input
->inputType
);
2639 if (!(node
= alloc_node( WS_XML_NODE_TYPE_BOF
))) return E_OUTOFMEMORY
;
2640 read_insert_bof( reader
, node
);
2644 /**************************************************************************
2645 * WsSetInputToBuffer [webservices.@]
2647 HRESULT WINAPI
WsSetInputToBuffer( WS_XML_READER
*handle
, WS_XML_BUFFER
*buffer
,
2648 const WS_XML_READER_PROPERTY
*properties
, ULONG count
,
2651 struct reader
*reader
= (struct reader
*)handle
;
2652 struct xmlbuf
*xmlbuf
= (struct xmlbuf
*)buffer
;
2656 ULONG i
, offset
= 0;
2658 TRACE( "%p %p %p %u %p\n", handle
, buffer
, properties
, count
, error
);
2659 if (error
) FIXME( "ignoring error parameter\n" );
2661 if (!reader
|| !xmlbuf
) return E_INVALIDARG
;
2663 for (i
= 0; i
< count
; i
++)
2665 hr
= set_reader_prop( reader
, properties
[i
].id
, properties
[i
].value
, properties
[i
].valueSize
);
2666 if (hr
!= S_OK
) return hr
;
2669 if ((hr
= read_init_state( reader
)) != S_OK
) return hr
;
2671 charset
= detect_charset( xmlbuf
->ptr
, xmlbuf
->size
, &offset
);
2672 hr
= set_reader_prop( reader
, WS_XML_READER_PROPERTY_CHARSET
, &charset
, sizeof(charset
) );
2673 if (hr
!= S_OK
) return hr
;
2675 set_input_buffer( reader
, (const unsigned char *)xmlbuf
->ptr
+ offset
, xmlbuf
->size
- offset
);
2676 if (!(node
= alloc_node( WS_XML_NODE_TYPE_BOF
))) return E_OUTOFMEMORY
;
2677 read_insert_bof( reader
, node
);
2681 /**************************************************************************
2682 * WsXmlStringEquals [webservices.@]
2684 HRESULT WINAPI
WsXmlStringEquals( const WS_XML_STRING
*str1
, const WS_XML_STRING
*str2
, WS_ERROR
*error
)
2686 TRACE( "%s %s %p\n", debugstr_xmlstr(str1
), debugstr_xmlstr(str2
), error
);
2687 if (error
) FIXME( "ignoring error parameter\n" );
2689 if (!str1
|| !str2
) return E_INVALIDARG
;
2691 if (str1
->length
!= str2
->length
) return S_FALSE
;
2692 if (!memcmp( str1
->bytes
, str2
->bytes
, str1
->length
)) return S_OK
;