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 * WsGetReaderNode [webservices.@]
612 HRESULT WINAPI
WsGetReaderNode( WS_XML_READER
*handle
, const WS_XML_NODE
**node
,
615 struct reader
*reader
= (struct reader
*)handle
;
617 TRACE( "%p %p %p\n", handle
, node
, error
);
618 if (error
) FIXME( "ignoring error parameter\n" );
620 if (!reader
|| !node
) return E_INVALIDARG
;
622 *node
= &reader
->current
->hdr
.node
;
626 /**************************************************************************
627 * WsGetReaderProperty [webservices.@]
629 HRESULT WINAPI
WsGetReaderProperty( WS_XML_READER
*handle
, WS_XML_READER_PROPERTY_ID id
,
630 void *buf
, ULONG size
, WS_ERROR
*error
)
632 struct reader
*reader
= (struct reader
*)handle
;
634 TRACE( "%p %u %p %u %p\n", handle
, id
, buf
, size
, error
);
635 if (error
) FIXME( "ignoring error parameter\n" );
637 if (!reader
->input_type
) return WS_E_INVALID_OPERATION
;
639 if (id
== WS_XML_READER_PROPERTY_CHARSET
)
644 if ((hr
= get_reader_prop( reader
, id
, &charset
, size
)) != S_OK
) return hr
;
645 if (!charset
) return WS_E_INVALID_FORMAT
;
646 *(WS_CHARSET
*)buf
= charset
;
649 return get_reader_prop( reader
, id
, buf
, size
);
652 /**************************************************************************
653 * WsGetXmlAttribute [webservices.@]
655 HRESULT WINAPI
WsGetXmlAttribute( WS_XML_READER
*handle
, const WS_XML_STRING
*attr
,
656 WS_HEAP
*heap
, WCHAR
**str
, ULONG
*len
, WS_ERROR
*error
)
658 FIXME( "%p %p %p %p %p %p: stub\n", handle
, debugstr_xmlstr(attr
), heap
, str
, len
, error
);
662 WS_XML_STRING
*alloc_xml_string( const unsigned char *data
, ULONG len
)
666 if (!(ret
= heap_alloc( sizeof(*ret
) + len
))) return NULL
;
668 ret
->bytes
= (BYTE
*)(ret
+ 1);
669 ret
->dictionary
= NULL
;
671 if (data
) memcpy( ret
->bytes
, data
, len
);
675 WS_XML_UTF8_TEXT
*alloc_utf8_text( const unsigned char *data
, ULONG len
)
677 WS_XML_UTF8_TEXT
*ret
;
679 if (!(ret
= heap_alloc( sizeof(*ret
) + len
))) return NULL
;
680 ret
->text
.textType
= WS_XML_TEXT_TYPE_UTF8
;
681 ret
->value
.length
= len
;
682 ret
->value
.bytes
= (BYTE
*)(ret
+ 1);
683 ret
->value
.dictionary
= NULL
;
685 if (data
) memcpy( ret
->value
.bytes
, data
, len
);
689 static inline BOOL
read_end_of_data( struct reader
*reader
)
691 return reader
->read_pos
>= reader
->read_size
;
694 static inline const unsigned char *read_current_ptr( struct reader
*reader
)
696 return &reader
->read_bufptr
[reader
->read_pos
];
699 /* UTF-8 support based on libs/wine/utf8.c */
701 /* number of following bytes in sequence based on first byte value (for bytes above 0x7f) */
702 static const char utf8_length
[128] =
704 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x80-0x8f */
705 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x90-0x9f */
706 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xa0-0xaf */
707 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xb0-0xbf */
708 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0xc0-0xcf */
709 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 0xd0-0xdf */
710 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, /* 0xe0-0xef */
711 3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0 /* 0xf0-0xff */
714 /* first byte mask depending on UTF-8 sequence length */
715 static const unsigned char utf8_mask
[4] = { 0x7f, 0x1f, 0x0f, 0x07 };
717 /* minimum Unicode value depending on UTF-8 sequence length */
718 static const unsigned int utf8_minval
[4] = { 0x0, 0x80, 0x800, 0x10000 };
720 static inline unsigned int read_utf8_char( struct reader
*reader
, unsigned int *skip
)
722 unsigned int len
, res
;
723 unsigned char ch
= reader
->read_bufptr
[reader
->read_pos
];
724 const unsigned char *end
;
726 if (reader
->read_pos
>= reader
->read_size
) return 0;
733 len
= utf8_length
[ch
- 0x80];
734 if (reader
->read_pos
+ len
>= reader
->read_size
) return 0;
735 end
= reader
->read_bufptr
+ reader
->read_pos
+ len
;
736 res
= ch
& utf8_mask
[len
];
741 if ((ch
= end
[-3] ^ 0x80) >= 0x40) break;
742 res
= (res
<< 6) | ch
;
744 if ((ch
= end
[-2] ^ 0x80) >= 0x40) break;
745 res
= (res
<< 6) | ch
;
747 if ((ch
= end
[-1] ^ 0x80) >= 0x40) break;
748 res
= (res
<< 6) | ch
;
749 if (res
< utf8_minval
[len
]) break;
757 static inline void read_skip( struct reader
*reader
, unsigned int count
)
759 while (reader
->read_pos
< reader
->read_size
&& count
)
766 static inline BOOL
read_isnamechar( unsigned int ch
)
768 /* FIXME: incomplete */
769 return (ch
>= 'A' && ch
<= 'Z') ||
770 (ch
>= 'a' && ch
<= 'z') ||
771 (ch
>= '0' && ch
<= '9') ||
772 ch
== '_' || ch
== '-' || ch
== '.' || ch
== ':';
775 static inline BOOL
read_isspace( unsigned int ch
)
777 return ch
== ' ' || ch
== '\t' || ch
== '\r' || ch
== '\n';
780 static inline void read_skip_whitespace( struct reader
*reader
)
782 while (reader
->read_pos
< reader
->read_size
&& read_isspace( reader
->read_bufptr
[reader
->read_pos
] ))
786 static inline int read_cmp( struct reader
*reader
, const char *str
, int len
)
788 const unsigned char *ptr
= read_current_ptr( reader
);
790 if (len
< 0) len
= strlen( str
);
791 if (reader
->read_pos
+ len
> reader
->read_size
) return -1;
794 if (*str
!= *ptr
) return *ptr
- *str
;
800 static HRESULT
read_xmldecl( struct reader
*reader
)
802 if (!reader
->read_size
) return WS_E_INVALID_FORMAT
;
804 if (read_cmp( reader
, "<", 1 ) || read_cmp( reader
, "<?", 2 ))
806 reader
->state
= READER_STATE_BOF
;
809 if (read_cmp( reader
, "<?xml ", 6 )) return WS_E_INVALID_FORMAT
;
810 read_skip( reader
, 6 );
812 /* FIXME: parse attributes */
813 while (reader
->read_pos
< reader
->read_size
&& reader
->read_bufptr
[reader
->read_pos
] != '?')
816 if (read_cmp( reader
, "?>", 2 )) return WS_E_INVALID_FORMAT
;
817 read_skip( reader
, 2 );
819 reader
->state
= READER_STATE_BOF
;
823 HRESULT
append_attribute( WS_XML_ELEMENT_NODE
*elem
, WS_XML_ATTRIBUTE
*attr
)
825 if (elem
->attributeCount
)
827 WS_XML_ATTRIBUTE
**tmp
;
828 if (!(tmp
= heap_realloc( elem
->attributes
, (elem
->attributeCount
+ 1) * sizeof(attr
) )))
829 return E_OUTOFMEMORY
;
830 elem
->attributes
= tmp
;
832 else if (!(elem
->attributes
= heap_alloc( sizeof(attr
) ))) return E_OUTOFMEMORY
;
833 elem
->attributes
[elem
->attributeCount
++] = attr
;
837 static HRESULT
parse_name( const unsigned char *str
, unsigned int len
,
838 WS_XML_STRING
**prefix
, WS_XML_STRING
**localname
)
840 const unsigned char *name_ptr
= str
, *prefix_ptr
= NULL
;
841 unsigned int i
, name_len
= len
, prefix_len
= 0;
843 for (i
= 0; i
< len
; i
++)
849 name_ptr
= &str
[i
+ 1];
854 if (!(*prefix
= alloc_xml_string( prefix_ptr
, prefix_len
))) return E_OUTOFMEMORY
;
855 if (!(*localname
= alloc_xml_string( name_ptr
, name_len
)))
857 heap_free( *prefix
);
858 return E_OUTOFMEMORY
;
863 static HRESULT
read_attribute( struct reader
*reader
, WS_XML_ATTRIBUTE
**ret
)
865 WS_XML_ATTRIBUTE
*attr
;
866 WS_XML_UTF8_TEXT
*text
;
867 unsigned int len
= 0, ch
, skip
, quote
;
868 const unsigned char *start
;
869 HRESULT hr
= WS_E_INVALID_FORMAT
;
871 if (!(attr
= heap_alloc_zero( sizeof(*attr
) ))) return E_OUTOFMEMORY
;
873 start
= read_current_ptr( reader
);
876 if (!(ch
= read_utf8_char( reader
, &skip
))) goto error
;
877 if (!read_isnamechar( ch
)) break;
878 read_skip( reader
, skip
);
881 if (!len
) goto error
;
883 if ((hr
= parse_name( start
, len
, &attr
->prefix
, &attr
->localName
)) != S_OK
) goto error
;
884 if (!attr
->prefix
->length
) attr
->prefix
->bytes
= NULL
;
886 if (!(attr
->ns
= alloc_xml_string( NULL
, 0 ))) goto error
;
887 attr
->ns
->bytes
= NULL
;
889 hr
= WS_E_INVALID_FORMAT
;
890 read_skip_whitespace( reader
);
891 if (read_cmp( reader
, "=", 1 )) goto error
;
892 read_skip( reader
, 1 );
894 read_skip_whitespace( reader
);
895 if (read_cmp( reader
, "\"", 1 ) && read_cmp( reader
, "'", 1 )) goto error
;
896 quote
= read_utf8_char( reader
, &skip
);
897 read_skip( reader
, 1 );
900 start
= read_current_ptr( reader
);
903 if (!(ch
= read_utf8_char( reader
, &skip
))) goto error
;
904 if (ch
== quote
) break;
905 read_skip( reader
, skip
);
908 read_skip( reader
, 1 );
910 if (!(text
= alloc_utf8_text( start
, len
)))
912 free_attribute( attr
);
913 return E_OUTOFMEMORY
;
915 attr
->value
= &text
->text
;
916 attr
->singleQuote
= (quote
== '\'');
922 free_attribute( attr
);
926 static HRESULT
read_element( struct reader
*reader
)
928 unsigned int len
= 0, ch
, skip
;
929 const unsigned char *start
;
931 WS_XML_ELEMENT_NODE
*elem
;
932 WS_XML_ATTRIBUTE
*attr
;
933 HRESULT hr
= WS_E_INVALID_FORMAT
;
935 if (read_end_of_data( reader
))
937 struct list
*eof
= list_tail( &reader
->root
->children
);
938 reader
->current
= LIST_ENTRY( eof
, struct node
, entry
);
939 reader
->state
= READER_STATE_EOF
;
943 if (!(node
= alloc_node( WS_XML_NODE_TYPE_ELEMENT
))) return E_OUTOFMEMORY
;
944 elem
= (WS_XML_ELEMENT_NODE
*)node
;
946 if (read_cmp( reader
, "<", 1 )) goto error
;
947 read_skip( reader
, 1 );
949 start
= read_current_ptr( reader
);
952 if (!(ch
= read_utf8_char( reader
, &skip
))) goto error
;
953 if (!read_isnamechar( ch
)) break;
954 read_skip( reader
, skip
);
957 if (!len
) goto error
;
959 if ((hr
= parse_name( start
, len
, &elem
->prefix
, &elem
->localName
)) != S_OK
) goto error
;
960 if (!elem
->prefix
->length
) elem
->prefix
->bytes
= NULL
;
962 if (!(elem
->ns
= alloc_xml_string( NULL
, 0 ))) goto error
;
964 reader
->current_attr
= 0;
967 read_skip_whitespace( reader
);
968 if (!read_cmp( reader
, ">", 1 ) || !read_cmp( reader
, "/>", 2 )) break;
969 if ((hr
= read_attribute( reader
, &attr
)) != S_OK
) goto error
;
970 if ((hr
= append_attribute( elem
, attr
)) != S_OK
)
972 free_attribute( attr
);
975 reader
->current_attr
++;
978 read_skip_whitespace( reader
);
979 if (read_cmp( reader
, ">", 1 ) && read_cmp( reader
, "/>", 2 ))
981 hr
= WS_E_INVALID_FORMAT
;
985 read_insert_node( reader
, reader
->current
, node
);
986 if (!read_cmp( reader
, "/>", 2 ))
988 read_skip( reader
, 2 );
989 if (!(node
= alloc_node( WS_XML_NODE_TYPE_END_ELEMENT
))) return E_OUTOFMEMORY
;
990 read_insert_node( reader
, reader
->current
, node
);
991 reader
->state
= READER_STATE_ENDELEMENT
;
995 read_skip( reader
, 1 );
996 reader
->state
= READER_STATE_STARTELEMENT
;
1005 static HRESULT
read_text( struct reader
*reader
)
1007 unsigned int len
= 0, ch
, skip
;
1008 const unsigned char *start
;
1010 WS_XML_TEXT_NODE
*text
;
1011 WS_XML_UTF8_TEXT
*utf8
;
1013 start
= read_current_ptr( reader
);
1016 if (read_end_of_data( reader
)) break;
1017 if (!(ch
= read_utf8_char( reader
, &skip
))) return WS_E_INVALID_FORMAT
;
1018 if (ch
== '<') break;
1019 read_skip( reader
, skip
);
1023 if (!(node
= alloc_node( WS_XML_NODE_TYPE_TEXT
))) return E_OUTOFMEMORY
;
1024 text
= (WS_XML_TEXT_NODE
*)node
;
1025 if (!(utf8
= alloc_utf8_text( start
, len
)))
1028 return E_OUTOFMEMORY
;
1030 text
->text
= &utf8
->text
;
1032 read_insert_node( reader
, reader
->current
, node
);
1033 reader
->state
= READER_STATE_TEXT
;
1037 static HRESULT
read_startelement( struct reader
*reader
)
1039 if (!read_cmp( reader
, "<", 1 )) return read_element( reader
);
1040 return read_text( reader
);
1043 static HRESULT
read_to_startelement( struct reader
*reader
, BOOL
*found
)
1047 switch (reader
->state
)
1049 case READER_STATE_INITIAL
:
1050 if ((hr
= read_xmldecl( reader
)) != S_OK
) return hr
;
1053 case READER_STATE_STARTELEMENT
:
1054 if (found
) *found
= TRUE
;
1061 read_skip_whitespace( reader
);
1062 if ((hr
= read_element( reader
)) == S_OK
&& found
)
1064 if (reader
->state
== READER_STATE_STARTELEMENT
)
1073 static int cmp_name( const unsigned char *name1
, ULONG len1
, const unsigned char *name2
, ULONG len2
)
1076 if (len1
!= len2
) return 1;
1077 for (i
= 0; i
< len1
; i
++) { if (toupper( name1
[i
] ) != toupper( name2
[i
] )) return 1; }
1081 struct node
*find_parent_element( struct node
*node
, const WS_XML_STRING
*prefix
,
1082 const WS_XML_STRING
*localname
)
1084 struct node
*parent
;
1085 const WS_XML_STRING
*str
;
1087 for (parent
= node
; parent
; parent
= parent
->parent
)
1089 if (parent
->hdr
.node
.nodeType
!= WS_XML_NODE_TYPE_ELEMENT
) continue;
1090 if (!localname
) return parent
;
1092 str
= parent
->hdr
.prefix
;
1093 if (cmp_name( str
->bytes
, str
->length
, prefix
->bytes
, prefix
->length
)) continue;
1095 str
= parent
->hdr
.localName
;
1096 if (cmp_name( str
->bytes
, str
->length
, localname
->bytes
, localname
->length
)) continue;
1103 static HRESULT
read_endelement( struct reader
*reader
)
1105 struct node
*node
, *parent
;
1106 unsigned int len
= 0, ch
, skip
;
1107 const unsigned char *start
;
1108 WS_XML_STRING
*prefix
, *localname
;
1111 if (read_cmp( reader
, "</", 2 )) return WS_E_INVALID_FORMAT
;
1112 read_skip( reader
, 2 );
1114 start
= read_current_ptr( reader
);
1117 if (!(ch
= read_utf8_char( reader
, &skip
))) return WS_E_INVALID_FORMAT
;
1120 read_skip( reader
, 1 );
1123 if (!read_isnamechar( ch
)) return WS_E_INVALID_FORMAT
;
1124 read_skip( reader
, skip
);
1128 if ((hr
= parse_name( start
, len
, &prefix
, &localname
)) != S_OK
) return hr
;
1129 parent
= find_parent_element( reader
->current
, prefix
, localname
);
1130 heap_free( prefix
);
1131 heap_free( localname
);
1132 if (!parent
) return WS_E_INVALID_FORMAT
;
1134 if (!(node
= alloc_node( WS_XML_NODE_TYPE_END_ELEMENT
))) return E_OUTOFMEMORY
;
1135 read_insert_node( reader
, parent
, node
);
1136 reader
->state
= READER_STATE_ENDELEMENT
;
1140 static HRESULT
read_comment( struct reader
*reader
)
1142 unsigned int len
= 0, ch
, skip
;
1143 const unsigned char *start
;
1145 WS_XML_COMMENT_NODE
*comment
;
1147 if (read_cmp( reader
, "<!--", 4 )) return WS_E_INVALID_FORMAT
;
1148 read_skip( reader
, 4 );
1150 start
= read_current_ptr( reader
);
1153 if (!read_cmp( reader
, "-->", 3 ))
1155 read_skip( reader
, 3 );
1158 if (!(ch
= read_utf8_char( reader
, &skip
))) return WS_E_INVALID_FORMAT
;
1159 read_skip( reader
, skip
);
1163 if (!(node
= alloc_node( WS_XML_NODE_TYPE_COMMENT
))) return E_OUTOFMEMORY
;
1164 comment
= (WS_XML_COMMENT_NODE
*)node
;
1165 if (!(comment
->value
.bytes
= heap_alloc( len
)))
1168 return E_OUTOFMEMORY
;
1170 memcpy( comment
->value
.bytes
, start
, len
);
1171 comment
->value
.length
= len
;
1173 read_insert_node( reader
, reader
->current
, node
);
1174 reader
->state
= READER_STATE_COMMENT
;
1178 static HRESULT
read_startcdata( struct reader
*reader
)
1182 if (read_cmp( reader
, "<![CDATA[", 9 )) return WS_E_INVALID_FORMAT
;
1183 read_skip( reader
, 9 );
1185 if (!(node
= alloc_node( WS_XML_NODE_TYPE_CDATA
))) return E_OUTOFMEMORY
;
1186 read_insert_node( reader
, reader
->current
, node
);
1187 reader
->state
= READER_STATE_STARTCDATA
;
1191 static HRESULT
read_cdata( struct reader
*reader
)
1193 unsigned int len
= 0, ch
, skip
;
1194 const unsigned char *start
;
1196 WS_XML_TEXT_NODE
*text
;
1197 WS_XML_UTF8_TEXT
*utf8
;
1199 start
= read_current_ptr( reader
);
1202 if (!read_cmp( reader
, "]]>", 3 )) break;
1203 if (!(ch
= read_utf8_char( reader
, &skip
))) return WS_E_INVALID_FORMAT
;
1204 read_skip( reader
, skip
);
1208 if (!(node
= alloc_node( WS_XML_NODE_TYPE_TEXT
))) return E_OUTOFMEMORY
;
1209 text
= (WS_XML_TEXT_NODE
*)node
;
1210 if (!(utf8
= alloc_utf8_text( start
, len
)))
1213 return E_OUTOFMEMORY
;
1215 text
->text
= &utf8
->text
;
1217 read_insert_node( reader
, reader
->current
, node
);
1218 reader
->state
= READER_STATE_CDATA
;
1222 static HRESULT
read_endcdata( struct reader
*reader
)
1226 if (read_cmp( reader
, "]]>", 3 )) return WS_E_INVALID_FORMAT
;
1227 read_skip( reader
, 3 );
1229 if (!(node
= alloc_node( WS_XML_NODE_TYPE_END_CDATA
))) return E_OUTOFMEMORY
;
1230 read_insert_node( reader
, reader
->current
->parent
, node
);
1231 reader
->state
= READER_STATE_ENDCDATA
;
1235 static HRESULT
read_node( struct reader
*reader
)
1241 if (read_end_of_data( reader
))
1243 struct list
*eof
= list_tail( &reader
->root
->children
);
1244 reader
->current
= LIST_ENTRY( eof
, struct node
, entry
);
1245 reader
->state
= READER_STATE_EOF
;
1248 if (reader
->state
== READER_STATE_STARTCDATA
) return read_cdata( reader
);
1249 else if (reader
->state
== READER_STATE_CDATA
) return read_endcdata( reader
);
1250 else if (!read_cmp( reader
, "<?", 2 ))
1252 hr
= read_xmldecl( reader
);
1253 if (FAILED( hr
)) return hr
;
1255 else if (!read_cmp( reader
, "</", 2 )) return read_endelement( reader
);
1256 else if (!read_cmp( reader
, "<![CDATA[", 9 )) return read_startcdata( reader
);
1257 else if (!read_cmp( reader
, "<!--", 4 )) return read_comment( reader
);
1258 else if (!read_cmp( reader
, "<", 1 )) return read_startelement( reader
);
1259 else return read_text( reader
);
1263 /**************************************************************************
1264 * WsReadEndElement [webservices.@]
1266 HRESULT WINAPI
WsReadEndElement( WS_XML_READER
*handle
, WS_ERROR
*error
)
1268 struct reader
*reader
= (struct reader
*)handle
;
1270 TRACE( "%p %p\n", handle
, error
);
1271 if (error
) FIXME( "ignoring error parameter\n" );
1273 if (!reader
) return E_INVALIDARG
;
1274 return read_endelement( reader
);
1277 /**************************************************************************
1278 * WsReadNode [webservices.@]
1280 HRESULT WINAPI
WsReadNode( WS_XML_READER
*handle
, WS_ERROR
*error
)
1282 struct reader
*reader
= (struct reader
*)handle
;
1284 TRACE( "%p %p\n", handle
, error
);
1285 if (error
) FIXME( "ignoring error parameter\n" );
1287 if (!reader
) return E_INVALIDARG
;
1288 return read_node( reader
);
1291 /**************************************************************************
1292 * WsReadStartElement [webservices.@]
1294 HRESULT WINAPI
WsReadStartElement( WS_XML_READER
*handle
, WS_ERROR
*error
)
1296 struct reader
*reader
= (struct reader
*)handle
;
1298 TRACE( "%p %p\n", handle
, error
);
1299 if (error
) FIXME( "ignoring error parameter\n" );
1301 if (!reader
) return E_INVALIDARG
;
1302 return read_startelement( reader
);
1305 /**************************************************************************
1306 * WsReadToStartElement [webservices.@]
1308 HRESULT WINAPI
WsReadToStartElement( WS_XML_READER
*handle
, const WS_XML_STRING
*localname
,
1309 const WS_XML_STRING
*ns
, BOOL
*found
, WS_ERROR
*error
)
1311 struct reader
*reader
= (struct reader
*)handle
;
1313 TRACE( "%p %s %s %p %p\n", handle
, debugstr_xmlstr(localname
), debugstr_xmlstr(ns
), found
, error
);
1314 if (error
) FIXME( "ignoring error parameter\n" );
1316 if (!reader
) return E_INVALIDARG
;
1317 if (localname
|| ns
) FIXME( "name and/or namespace not verified\n" );
1319 return read_to_startelement( reader
, found
);
1322 static BOOL
move_to_root_element( struct reader
*reader
)
1327 if (!(ptr
= list_head( &reader
->root
->children
))) return FALSE
;
1328 node
= LIST_ENTRY( ptr
, struct node
, entry
);
1329 if (node
->hdr
.node
.nodeType
== WS_XML_NODE_TYPE_ELEMENT
)
1331 reader
->current
= node
;
1334 while ((ptr
= list_next( &reader
->root
->children
, &node
->entry
)))
1336 struct node
*next
= LIST_ENTRY( ptr
, struct node
, entry
);
1337 if (next
->hdr
.node
.nodeType
== WS_XML_NODE_TYPE_ELEMENT
)
1339 reader
->current
= next
;
1347 static BOOL
move_to_next_element( struct reader
*reader
)
1350 struct node
*node
= reader
->current
;
1352 while ((ptr
= list_next( &node
->parent
->children
, &node
->entry
)))
1354 struct node
*next
= LIST_ENTRY( ptr
, struct node
, entry
);
1355 if (next
->hdr
.node
.nodeType
== WS_XML_NODE_TYPE_ELEMENT
)
1357 reader
->current
= next
;
1365 static BOOL
move_to_prev_element( struct reader
*reader
)
1368 struct node
*node
= reader
->current
;
1370 while ((ptr
= list_prev( &node
->parent
->children
, &node
->entry
)))
1372 struct node
*prev
= LIST_ENTRY( ptr
, struct node
, entry
);
1373 if (prev
->hdr
.node
.nodeType
== WS_XML_NODE_TYPE_ELEMENT
)
1375 reader
->current
= prev
;
1383 static BOOL
move_to_child_element( struct reader
*reader
)
1388 if (!(ptr
= list_head( &reader
->current
->children
))) return FALSE
;
1389 node
= LIST_ENTRY( ptr
, struct node
, entry
);
1390 if (node
->hdr
.node
.nodeType
== WS_XML_NODE_TYPE_ELEMENT
)
1392 reader
->current
= node
;
1395 while ((ptr
= list_next( &reader
->current
->children
, &node
->entry
)))
1397 struct node
*next
= LIST_ENTRY( ptr
, struct node
, entry
);
1398 if (next
->hdr
.node
.nodeType
== WS_XML_NODE_TYPE_ELEMENT
)
1400 reader
->current
= next
;
1408 static HRESULT
read_move_to( struct reader
*reader
, WS_MOVE_TO move
, BOOL
*found
)
1411 BOOL success
= FALSE
;
1414 if (!read_end_of_data( reader
))
1416 while (reader
->state
!= READER_STATE_EOF
&& (hr
= read_node( reader
)) == S_OK
) { /* nothing */ };
1417 if (hr
!= S_OK
) return hr
;
1421 case WS_MOVE_TO_ROOT_ELEMENT
:
1422 success
= move_to_root_element( reader
);
1425 case WS_MOVE_TO_NEXT_ELEMENT
:
1426 success
= move_to_next_element( reader
);
1429 case WS_MOVE_TO_PREVIOUS_ELEMENT
:
1430 success
= move_to_prev_element( reader
);
1433 case WS_MOVE_TO_CHILD_ELEMENT
:
1434 success
= move_to_child_element( reader
);
1437 case WS_MOVE_TO_FIRST_NODE
:
1438 if ((ptr
= list_head( &reader
->current
->parent
->children
)))
1440 reader
->current
= LIST_ENTRY( ptr
, struct node
, entry
);
1445 case WS_MOVE_TO_NEXT_NODE
:
1446 if ((ptr
= list_next( &reader
->current
->parent
->children
, &reader
->current
->entry
)))
1448 reader
->current
= LIST_ENTRY( ptr
, struct node
, entry
);
1453 case WS_MOVE_TO_PREVIOUS_NODE
:
1454 if ((ptr
= list_prev( &reader
->current
->parent
->children
, &reader
->current
->entry
)))
1456 reader
->current
= LIST_ENTRY( ptr
, struct node
, entry
);
1461 case WS_MOVE_TO_CHILD_NODE
:
1462 if ((ptr
= list_head( &reader
->current
->children
)))
1464 reader
->current
= LIST_ENTRY( ptr
, struct node
, entry
);
1469 case WS_MOVE_TO_BOF
:
1470 reader
->current
= reader
->root
;
1474 case WS_MOVE_TO_EOF
:
1475 if ((ptr
= list_tail( &reader
->root
->children
)))
1477 reader
->current
= LIST_ENTRY( ptr
, struct node
, entry
);
1483 FIXME( "unhandled move %u\n", move
);
1492 return success
? S_OK
: WS_E_INVALID_FORMAT
;
1495 /**************************************************************************
1496 * WsMoveReader [webservices.@]
1498 HRESULT WINAPI
WsMoveReader( WS_XML_READER
*handle
, WS_MOVE_TO move
, BOOL
*found
, WS_ERROR
*error
)
1500 struct reader
*reader
= (struct reader
*)handle
;
1502 TRACE( "%p %u %p %p\n", handle
, move
, found
, error
);
1503 if (error
) FIXME( "ignoring error parameter\n" );
1505 if (!reader
) return E_INVALIDARG
;
1506 if (!reader
->input_type
) return WS_E_INVALID_OPERATION
;
1508 return read_move_to( reader
, move
, found
);
1511 /**************************************************************************
1512 * WsReadStartAttribute [webservices.@]
1514 HRESULT WINAPI
WsReadStartAttribute( WS_XML_READER
*handle
, ULONG index
, WS_ERROR
*error
)
1516 struct reader
*reader
= (struct reader
*)handle
;
1517 WS_XML_ELEMENT_NODE
*elem
;
1519 TRACE( "%p %u %p\n", handle
, index
, error
);
1520 if (error
) FIXME( "ignoring error parameter\n" );
1522 if (!reader
) return E_INVALIDARG
;
1524 elem
= &reader
->current
->hdr
;
1525 if (reader
->state
!= READER_STATE_STARTELEMENT
|| index
>= elem
->attributeCount
)
1526 return WS_E_INVALID_FORMAT
;
1528 reader
->current_attr
= index
;
1529 reader
->state
= READER_STATE_STARTATTRIBUTE
;
1533 /**************************************************************************
1534 * WsReadEndAttribute [webservices.@]
1536 HRESULT WINAPI
WsReadEndAttribute( WS_XML_READER
*handle
, WS_ERROR
*error
)
1538 struct reader
*reader
= (struct reader
*)handle
;
1540 TRACE( "%p %p\n", handle
, error
);
1541 if (error
) FIXME( "ignoring error parameter\n" );
1543 if (!reader
) return E_INVALIDARG
;
1545 if (reader
->state
!= READER_STATE_STARTATTRIBUTE
)
1546 return WS_E_INVALID_FORMAT
;
1548 reader
->state
= READER_STATE_STARTELEMENT
;
1552 static WCHAR
*xmltext_to_widechar( WS_HEAP
*heap
, const WS_XML_TEXT
*text
)
1556 switch (text
->textType
)
1558 case WS_XML_TEXT_TYPE_UTF8
:
1560 const WS_XML_UTF8_TEXT
*utf8
= (const WS_XML_UTF8_TEXT
*)text
;
1561 int len
= MultiByteToWideChar( CP_UTF8
, 0, (char *)utf8
->value
.bytes
, utf8
->value
.length
, NULL
, 0 );
1562 if (!(ret
= ws_alloc( heap
, (len
+ 1) * sizeof(WCHAR
) ))) return NULL
;
1563 MultiByteToWideChar( CP_UTF8
, 0, (char *)utf8
->value
.bytes
, utf8
->value
.length
, ret
, len
);
1568 FIXME( "unhandled type %u\n", text
->textType
);
1575 #define MAX_INT8 0x7f
1576 #define MIN_INT8 (-MAX_INT8 - 1)
1577 #define MAX_INT16 0x7fff
1578 #define MIN_INT16 (-MAX_INT16 - 1)
1579 #define MAX_INT32 0x7fffffff
1580 #define MIN_INT32 (-MAX_INT32 - 1)
1581 #define MAX_INT64 (((INT64)0x7fffffff << 32) | 0xffffffff)
1582 #define MIN_INT64 (-MAX_INT64 - 1)
1583 #define MAX_UINT8 0xff
1584 #define MAX_UINT16 0xffff
1585 #define MAX_UINT32 0xffffffff
1586 #define MAX_UINT64 (((UINT64)0xffffffff << 32) | 0xffffffff)
1588 static HRESULT
str_to_int64( const unsigned char *str
, ULONG len
, INT64 min
, INT64 max
, INT64
*ret
)
1590 BOOL negative
= FALSE
;
1591 const unsigned char *ptr
= str
;
1594 while (len
&& read_isspace( *ptr
)) { ptr
++; len
--; }
1595 while (len
&& read_isspace( ptr
[len
- 1] )) { len
--; }
1596 if (!len
) return WS_E_INVALID_FORMAT
;
1604 if (!len
) return WS_E_INVALID_FORMAT
;
1610 if (!isdigit( *ptr
)) return WS_E_INVALID_FORMAT
;
1612 if (negative
) val
= -val
;
1614 if ((!negative
&& (*ret
> max
/ 10 || *ret
* 10 > max
- val
)) ||
1615 (negative
&& (*ret
< min
/ 10 || *ret
* 10 < min
- val
)))
1617 return WS_E_NUMERIC_OVERFLOW
;
1619 *ret
= *ret
* 10 + val
;
1626 static HRESULT
str_to_uint64( const unsigned char *str
, ULONG len
, UINT64 max
, UINT64
*ret
)
1628 const unsigned char *ptr
= str
;
1631 while (len
&& read_isspace( *ptr
)) { ptr
++; len
--; }
1632 while (len
&& read_isspace( ptr
[len
- 1] )) { len
--; }
1633 if (!len
) return WS_E_INVALID_FORMAT
;
1639 if (!isdigit( *ptr
)) return WS_E_INVALID_FORMAT
;
1642 if ((*ret
> max
/ 10 || *ret
* 10 > max
- val
)) return WS_E_NUMERIC_OVERFLOW
;
1643 *ret
= *ret
* 10 + val
;
1650 static HRESULT
read_get_node_text( struct reader
*reader
, WS_XML_UTF8_TEXT
**ret
)
1652 WS_XML_TEXT_NODE
*text
;
1654 if (reader
->current
->hdr
.node
.nodeType
!= WS_XML_NODE_TYPE_TEXT
)
1655 return WS_E_INVALID_FORMAT
;
1657 text
= (WS_XML_TEXT_NODE
*)&reader
->current
->hdr
.node
;
1658 if (text
->text
->textType
!= WS_XML_TEXT_TYPE_UTF8
)
1660 FIXME( "text type %u not supported\n", text
->text
->textType
);
1663 *ret
= (WS_XML_UTF8_TEXT
*)text
->text
;
1667 static HRESULT
read_get_attribute_text( struct reader
*reader
, WS_XML_UTF8_TEXT
**ret
)
1669 WS_XML_ELEMENT_NODE
*elem
= &reader
->current
->hdr
;
1670 WS_XML_ATTRIBUTE
*attr
;
1672 if (reader
->current
->hdr
.node
.nodeType
!= WS_XML_NODE_TYPE_ELEMENT
||
1673 reader
->current_attr
>= elem
->attributeCount
) return WS_E_INVALID_FORMAT
;
1675 attr
= elem
->attributes
[reader
->current_attr
];
1676 if (attr
->value
->textType
!= WS_XML_TEXT_TYPE_UTF8
)
1678 FIXME( "text type %u not supported\n", attr
->value
->textType
);
1681 *ret
= (WS_XML_UTF8_TEXT
*)attr
->value
;
1682 reader
->current_attr
++;
1686 static BOOL
find_attribute( struct reader
*reader
, const WS_XML_STRING
*localname
,
1687 const WS_XML_STRING
*ns
, ULONG
*index
)
1690 WS_XML_ELEMENT_NODE
*elem
= &reader
->current
->hdr
;
1694 *index
= reader
->current_attr
;
1697 for (i
= 0; i
< elem
->attributeCount
; i
++)
1699 const WS_XML_STRING
*localname2
= elem
->attributes
[i
]->localName
;
1700 const WS_XML_STRING
*ns2
= elem
->attributes
[i
]->ns
;
1702 if (!cmp_name( localname
->bytes
, localname
->length
, localname2
->bytes
, localname2
->length
) &&
1703 !cmp_name( ns
->bytes
, ns
->length
, ns2
->bytes
, ns2
->length
))
1712 /**************************************************************************
1713 * WsFindAttribute [webservices.@]
1715 HRESULT WINAPI
WsFindAttribute( WS_XML_READER
*handle
, const WS_XML_STRING
*localname
,
1716 const WS_XML_STRING
*ns
, BOOL required
, ULONG
*index
,
1719 struct reader
*reader
= (struct reader
*)handle
;
1721 TRACE( "%p %s %s %d %p %p\n", handle
, debugstr_xmlstr(localname
), debugstr_xmlstr(ns
),
1722 required
, index
, error
);
1723 if (error
) FIXME( "ignoring error parameter\n" );
1725 if (!reader
|| !localname
|| !ns
|| !index
) return E_INVALIDARG
;
1727 if (reader
->current
->hdr
.node
.nodeType
!= WS_XML_NODE_TYPE_ELEMENT
)
1728 return WS_E_INVALID_OPERATION
;
1730 if (!find_attribute( reader
, localname
, ns
, index
))
1732 if (required
) return WS_E_INVALID_FORMAT
;
1739 static HRESULT
read_type_bool( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
1740 const WS_BOOL_DESCRIPTION
*desc
, BOOL
*ret
)
1742 WS_XML_UTF8_TEXT
*utf8
;
1748 FIXME( "description not supported\n" );
1753 case WS_ATTRIBUTE_TYPE_MAPPING
:
1754 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
1755 len
= utf8
->value
.length
;
1758 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
1759 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
1760 len
= utf8
->value
.length
;
1764 FIXME( "mapping %u not supported\n", mapping
);
1768 if (len
== 4 && !memcmp( utf8
->value
.bytes
, "true", 4 )) *ret
= TRUE
;
1769 else if (len
== 1 && !memcmp( utf8
->value
.bytes
, "1", 1 )) *ret
= TRUE
;
1770 else if (len
== 5 && !memcmp( utf8
->value
.bytes
, "false", 5 )) *ret
= FALSE
;
1771 else if (len
== 1 && !memcmp( utf8
->value
.bytes
, "0", 1 )) *ret
= FALSE
;
1772 else return WS_E_INVALID_FORMAT
;
1777 static HRESULT
read_type_int8( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
1778 const WS_INT8_DESCRIPTION
*desc
, INT8
*ret
)
1780 WS_XML_UTF8_TEXT
*utf8
;
1786 FIXME( "description not supported\n" );
1791 case WS_ATTRIBUTE_TYPE_MAPPING
:
1792 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
1795 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
1796 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
1800 FIXME( "mapping %u not supported\n", mapping
);
1804 if ((hr
= str_to_int64( utf8
->value
.bytes
, utf8
->value
.length
, MIN_INT8
, MAX_INT8
, &val
)) != S_OK
)
1811 static HRESULT
read_type_int16( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
1812 const WS_INT16_DESCRIPTION
*desc
, INT16
*ret
)
1814 WS_XML_UTF8_TEXT
*utf8
;
1820 FIXME( "description not supported\n" );
1825 case WS_ATTRIBUTE_TYPE_MAPPING
:
1826 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
1829 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
1830 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
1834 FIXME( "mapping %u not supported\n", mapping
);
1838 if ((hr
= str_to_int64( utf8
->value
.bytes
, utf8
->value
.length
, MIN_INT16
, MAX_INT16
, &val
)) != S_OK
)
1845 static HRESULT
read_type_int32( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
1846 const WS_INT32_DESCRIPTION
*desc
, INT32
*ret
)
1848 WS_XML_UTF8_TEXT
*utf8
;
1854 FIXME( "description not supported\n" );
1859 case WS_ATTRIBUTE_TYPE_MAPPING
:
1860 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
1863 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
1864 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
1868 FIXME( "mapping %u not supported\n", mapping
);
1872 if ((hr
= str_to_int64( utf8
->value
.bytes
, utf8
->value
.length
, MIN_INT32
, MAX_INT32
, &val
)) != S_OK
)
1879 static HRESULT
read_type_int64( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
1880 const WS_INT64_DESCRIPTION
*desc
, INT64
*ret
)
1882 WS_XML_UTF8_TEXT
*utf8
;
1888 FIXME( "description not supported\n" );
1893 case WS_ATTRIBUTE_TYPE_MAPPING
:
1894 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
1897 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
1898 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
1902 FIXME( "mapping %u not supported\n", mapping
);
1906 if ((hr
= str_to_int64( utf8
->value
.bytes
, utf8
->value
.length
, MIN_INT64
, MAX_INT64
, &val
)) != S_OK
)
1913 static HRESULT
read_type_uint8( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
1914 const WS_UINT8_DESCRIPTION
*desc
, UINT8
*ret
)
1916 WS_XML_UTF8_TEXT
*utf8
;
1922 FIXME( "description not supported\n" );
1927 case WS_ATTRIBUTE_TYPE_MAPPING
:
1928 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
1931 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
1932 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
1936 FIXME( "mapping %u not supported\n", mapping
);
1940 if ((hr
= str_to_uint64( utf8
->value
.bytes
, utf8
->value
.length
, MAX_UINT8
, &val
)) != S_OK
)
1947 static HRESULT
read_type_uint16( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
1948 const WS_UINT16_DESCRIPTION
*desc
, UINT16
*ret
)
1950 WS_XML_UTF8_TEXT
*utf8
;
1956 FIXME( "description not supported\n" );
1961 case WS_ATTRIBUTE_TYPE_MAPPING
:
1962 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
1965 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
1966 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
1970 FIXME( "mapping %u not supported\n", mapping
);
1974 if ((hr
= str_to_uint64( utf8
->value
.bytes
, utf8
->value
.length
, MAX_UINT16
, &val
)) != S_OK
)
1981 static HRESULT
read_type_uint32( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
1982 const WS_UINT32_DESCRIPTION
*desc
, UINT32
*ret
)
1984 WS_XML_UTF8_TEXT
*utf8
;
1990 FIXME( "description not supported\n" );
1995 case WS_ATTRIBUTE_TYPE_MAPPING
:
1996 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
1999 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
2000 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
2004 FIXME( "mapping %u not supported\n", mapping
);
2008 if ((hr
= str_to_uint64( utf8
->value
.bytes
, utf8
->value
.length
, MAX_UINT32
, &val
)) != S_OK
)
2015 static HRESULT
read_type_uint64( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2016 const WS_UINT64_DESCRIPTION
*desc
, UINT64
*ret
)
2018 WS_XML_UTF8_TEXT
*utf8
;
2024 FIXME( "description not supported\n" );
2029 case WS_ATTRIBUTE_TYPE_MAPPING
:
2030 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
2033 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
2034 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
2038 FIXME( "mapping %u not supported\n", mapping
);
2042 if ((hr
= str_to_uint64( utf8
->value
.bytes
, utf8
->value
.length
, MAX_UINT64
, &val
)) != S_OK
)
2049 static HRESULT
read_type_wsz( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2050 const WS_WSZ_DESCRIPTION
*desc
, WS_HEAP
*heap
, WCHAR
**ret
)
2052 WS_XML_UTF8_TEXT
*utf8
;
2058 FIXME( "description not supported\n" );
2063 case WS_ATTRIBUTE_TYPE_MAPPING
:
2064 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
2067 case WS_ELEMENT_TYPE_MAPPING
:
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 (!(str
= xmltext_to_widechar( heap
, &utf8
->text
))) return WS_E_QUOTA_EXCEEDED
;
2082 static HRESULT
read_type_struct( struct reader
*, WS_TYPE_MAPPING
, const WS_STRUCT_DESCRIPTION
*,
2083 WS_HEAP
*, void ** );
2085 static HRESULT
read_type_struct_field( struct reader
*reader
, const WS_FIELD_DESCRIPTION
*desc
,
2086 WS_HEAP
*heap
, char *buf
)
2088 char *ptr
= buf
+ desc
->offset
;
2089 WS_TYPE_MAPPING mapping
;
2092 if (desc
->options
&& desc
->options
!= WS_FIELD_POINTER
&&
2093 desc
->options
!= WS_FIELD_OPTIONAL
&&
2094 desc
->options
!= (WS_FIELD_POINTER
| WS_FIELD_OPTIONAL
))
2096 FIXME( "options 0x%x not supported\n", desc
->options
);
2100 switch (desc
->mapping
)
2102 case WS_ATTRIBUTE_FIELD_MAPPING
:
2103 mapping
= WS_ATTRIBUTE_TYPE_MAPPING
;
2106 case WS_ELEMENT_FIELD_MAPPING
:
2107 mapping
= WS_ELEMENT_TYPE_MAPPING
;
2111 FIXME( "unhandled field mapping %u\n", desc
->mapping
);
2117 case WS_STRUCT_TYPE
:
2118 hr
= read_type_struct( reader
, mapping
, desc
->typeDescription
, heap
, (void **)ptr
);
2122 hr
= read_type_bool( reader
, mapping
, desc
->typeDescription
, (BOOL
*)ptr
);
2126 hr
= read_type_int8( reader
, mapping
, desc
->typeDescription
, (INT8
*)ptr
);
2130 hr
= read_type_int16( reader
, mapping
, desc
->typeDescription
, (INT16
*)ptr
);
2134 hr
= read_type_int32( reader
, mapping
, desc
->typeDescription
, (INT32
*)ptr
);
2138 hr
= read_type_int64( reader
, mapping
, desc
->typeDescription
, (INT64
*)ptr
);
2142 hr
= read_type_uint8( reader
, mapping
, desc
->typeDescription
, (UINT8
*)ptr
);
2145 case WS_UINT16_TYPE
:
2146 hr
= read_type_uint16( reader
, mapping
, desc
->typeDescription
, (UINT16
*)ptr
);
2149 case WS_UINT32_TYPE
:
2150 hr
= read_type_uint32( reader
, mapping
, desc
->typeDescription
, (UINT32
*)ptr
);
2153 case WS_UINT64_TYPE
:
2154 hr
= read_type_uint64( reader
, mapping
, desc
->typeDescription
, (UINT64
*)ptr
);
2158 hr
= read_type_wsz( reader
, mapping
, desc
->typeDescription
, heap
, (WCHAR
**)ptr
);
2162 FIXME( "type %u not implemented\n", desc
->type
);
2169 static HRESULT
read_type_struct( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2170 const WS_STRUCT_DESCRIPTION
*desc
, WS_HEAP
*heap
, void **ret
)
2176 if (!desc
) return E_INVALIDARG
;
2178 if (desc
->structOptions
)
2180 FIXME( "struct options 0x%x not supported\n", desc
->structOptions
);
2186 case WS_ELEMENT_TYPE_MAPPING
:
2187 if ((hr
= read_to_startelement( reader
, NULL
)) != S_OK
) return hr
;
2190 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
2191 if ((hr
= read_to_startelement( reader
, NULL
)) != S_OK
) return hr
;
2192 if ((hr
= read_startelement( reader
)) != S_OK
) return hr
;
2196 FIXME( "unhandled mapping %u\n", mapping
);
2200 if (!(buf
= ws_alloc_zero( heap
, desc
->size
))) return WS_E_QUOTA_EXCEEDED
;
2202 for (i
= 0; i
< desc
->fieldCount
; i
++)
2204 if ((hr
= read_type_struct_field( reader
, desc
->fields
[i
], heap
, buf
)) != S_OK
)
2206 ws_free( heap
, buf
);
2213 case WS_ELEMENT_TYPE_MAPPING
:
2214 if ((hr
= read_endelement( reader
)) != S_OK
) return hr
;
2217 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
2218 if ((hr
= read_endelement( reader
)) != S_OK
) return hr
;
2219 if ((hr
= read_node( reader
)) != S_OK
) return hr
;
2220 if (reader
->state
!= READER_STATE_EOF
) return WS_E_INVALID_FORMAT
;
2230 static HRESULT
read_type( struct reader
*reader
, WS_TYPE_MAPPING mapping
, WS_TYPE type
,
2231 const void *desc
, WS_READ_OPTION option
, WS_HEAP
*heap
,
2232 void *value
, ULONG size
)
2236 case WS_STRUCT_TYPE
:
2239 if (option
!= WS_READ_REQUIRED_POINTER
|| size
!= sizeof(*ptr
))
2240 return E_INVALIDARG
;
2242 return read_type_struct( reader
, mapping
, desc
, heap
, ptr
);
2247 if (option
!= WS_READ_REQUIRED_VALUE
)
2249 FIXME( "read option %u not supported\n", option
);
2252 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2253 return read_type_bool( reader
, mapping
, desc
, ptr
);
2258 if (option
!= WS_READ_REQUIRED_VALUE
)
2260 FIXME( "read option %u not supported\n", option
);
2263 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2264 return read_type_int8( reader
, mapping
, desc
, ptr
);
2269 if (option
!= WS_READ_REQUIRED_VALUE
)
2271 FIXME( "read option %u not supported\n", option
);
2274 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2275 return read_type_int16( reader
, mapping
, desc
, ptr
);
2280 if (option
!= WS_READ_REQUIRED_VALUE
)
2282 FIXME( "read option %u not supported\n", option
);
2285 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2286 return read_type_int32( reader
, mapping
, desc
, ptr
);
2291 if (option
!= WS_READ_REQUIRED_VALUE
)
2293 FIXME( "read option %u not supported\n", option
);
2296 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2297 return read_type_int64( reader
, mapping
, desc
, ptr
);
2302 if (option
!= WS_READ_REQUIRED_VALUE
)
2304 FIXME( "read option %u not supported\n", option
);
2307 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2308 return read_type_uint8( reader
, mapping
, desc
, ptr
);
2310 case WS_UINT16_TYPE
:
2312 UINT16
*ptr
= value
;
2313 if (option
!= WS_READ_REQUIRED_VALUE
)
2315 FIXME( "read option %u not supported\n", option
);
2318 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2319 return read_type_uint16( reader
, mapping
, desc
, ptr
);
2321 case WS_UINT32_TYPE
:
2323 UINT32
*ptr
= value
;
2324 if (option
!= WS_READ_REQUIRED_VALUE
)
2326 FIXME( "read option %u not supported\n", option
);
2329 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2330 return read_type_uint32( reader
, mapping
, desc
, ptr
);
2332 case WS_UINT64_TYPE
:
2334 UINT64
*ptr
= value
;
2335 if (option
!= WS_READ_REQUIRED_VALUE
)
2337 FIXME( "read option %u not supported\n", option
);
2340 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2341 return read_type_uint64( reader
, mapping
, desc
, ptr
);
2345 WCHAR
**ptr
= value
;
2346 if (option
!= WS_READ_REQUIRED_POINTER
)
2348 FIXME( "read option %u not supported\n", option
);
2351 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2352 return read_type_wsz( reader
, mapping
, desc
, heap
, ptr
);
2355 FIXME( "type %u not supported\n", type
);
2360 /**************************************************************************
2361 * WsReadType [webservices.@]
2363 HRESULT WINAPI
WsReadType( WS_XML_READER
*handle
, WS_TYPE_MAPPING mapping
, WS_TYPE type
,
2364 const void *desc
, WS_READ_OPTION option
, WS_HEAP
*heap
, void *value
,
2365 ULONG size
, WS_ERROR
*error
)
2367 struct reader
*reader
= (struct reader
*)handle
;
2369 TRACE( "%p %u %u %p %u %p %p %u %p\n", handle
, mapping
, type
, desc
, option
, heap
, value
,
2371 if (error
) FIXME( "ignoring error parameter\n" );
2373 if (!reader
|| !value
) return E_INVALIDARG
;
2375 return read_type( reader
, mapping
, type
, desc
, option
, heap
, value
, size
);
2378 /**************************************************************************
2379 * WsSetErrorProperty [webservices.@]
2381 HRESULT WINAPI
WsSetErrorProperty( WS_ERROR
*handle
, WS_ERROR_PROPERTY_ID id
, const void *value
,
2384 struct error
*error
= (struct error
*)handle
;
2386 TRACE( "%p %u %p %u\n", handle
, id
, value
, size
);
2388 if (id
== WS_ERROR_PROPERTY_LANGID
) return WS_E_INVALID_OPERATION
;
2389 return set_error_prop( error
, id
, value
, size
);
2392 static inline BOOL
is_utf8( const unsigned char *data
, ULONG size
, ULONG
*offset
)
2394 static const char bom
[] = {0xef,0xbb,0xbf};
2395 const unsigned char *p
= data
;
2397 return (size
>= sizeof(bom
) && !memcmp( p
, bom
, sizeof(bom
) ) && (*offset
= sizeof(bom
))) ||
2398 (size
> 2 && !(*offset
= 0));
2401 static inline BOOL
is_utf16le( const unsigned char *data
, ULONG size
, ULONG
*offset
)
2403 static const char bom
[] = {0xff,0xfe};
2404 const unsigned char *p
= data
;
2406 return (size
>= sizeof(bom
) && !memcmp( p
, bom
, sizeof(bom
) ) && (*offset
= sizeof(bom
))) ||
2407 (size
>= 4 && p
[0] == '<' && !p
[1] && !(*offset
= 0));
2410 static WS_CHARSET
detect_charset( const unsigned char *data
, ULONG size
, ULONG
*offset
)
2414 /* FIXME: parse xml declaration */
2416 if (is_utf16le( data
, size
, offset
)) ret
= WS_CHARSET_UTF16LE
;
2417 else if (is_utf8( data
, size
, offset
)) ret
= WS_CHARSET_UTF8
;
2420 FIXME( "charset not recognized\n" );
2424 TRACE( "detected charset %u\n", ret
);
2428 static void set_input_buffer( struct reader
*reader
, const unsigned char *data
, ULONG size
)
2430 reader
->input_type
= WS_XML_READER_INPUT_TYPE_BUFFER
;
2431 reader
->input_data
= data
;
2432 reader
->input_size
= size
;
2434 reader
->read_size
= reader
->input_size
;
2435 reader
->read_pos
= 0;
2436 reader
->read_bufptr
= reader
->input_data
;
2439 /**************************************************************************
2440 * WsSetInput [webservices.@]
2442 HRESULT WINAPI
WsSetInput( WS_XML_READER
*handle
, const WS_XML_READER_ENCODING
*encoding
,
2443 const WS_XML_READER_INPUT
*input
, const WS_XML_READER_PROPERTY
*properties
,
2444 ULONG count
, WS_ERROR
*error
)
2446 struct reader
*reader
= (struct reader
*)handle
;
2449 ULONG i
, offset
= 0;
2451 TRACE( "%p %p %p %p %u %p\n", handle
, encoding
, input
, properties
, count
, error
);
2452 if (error
) FIXME( "ignoring error parameter\n" );
2454 if (!reader
) return E_INVALIDARG
;
2456 for (i
= 0; i
< count
; i
++)
2458 hr
= set_reader_prop( reader
, properties
[i
].id
, properties
[i
].value
, properties
[i
].valueSize
);
2459 if (hr
!= S_OK
) return hr
;
2462 if ((hr
= read_init_state( reader
)) != S_OK
) return hr
;
2464 switch (encoding
->encodingType
)
2466 case WS_XML_READER_ENCODING_TYPE_TEXT
:
2468 WS_XML_READER_TEXT_ENCODING
*text
= (WS_XML_READER_TEXT_ENCODING
*)encoding
;
2469 WS_XML_READER_BUFFER_INPUT
*buf
= (WS_XML_READER_BUFFER_INPUT
*)input
;
2470 WS_CHARSET charset
= text
->charSet
;
2472 if (input
->inputType
!= WS_XML_READER_INPUT_TYPE_BUFFER
)
2474 FIXME( "charset detection on input type %u not supported\n", input
->inputType
);
2478 if (charset
== WS_CHARSET_AUTO
)
2479 charset
= detect_charset( buf
->encodedData
, buf
->encodedDataSize
, &offset
);
2481 hr
= set_reader_prop( reader
, WS_XML_READER_PROPERTY_CHARSET
, &charset
, sizeof(charset
) );
2482 if (hr
!= S_OK
) return hr
;
2486 FIXME( "encoding type %u not supported\n", encoding
->encodingType
);
2489 switch (input
->inputType
)
2491 case WS_XML_READER_INPUT_TYPE_BUFFER
:
2493 WS_XML_READER_BUFFER_INPUT
*buf
= (WS_XML_READER_BUFFER_INPUT
*)input
;
2494 set_input_buffer( reader
, (const unsigned char *)buf
->encodedData
+ offset
, buf
->encodedDataSize
- offset
);
2498 FIXME( "input type %u not supported\n", input
->inputType
);
2502 if (!(node
= alloc_node( WS_XML_NODE_TYPE_BOF
))) return E_OUTOFMEMORY
;
2503 read_insert_bof( reader
, node
);
2507 /**************************************************************************
2508 * WsSetInputToBuffer [webservices.@]
2510 HRESULT WINAPI
WsSetInputToBuffer( WS_XML_READER
*handle
, WS_XML_BUFFER
*buffer
,
2511 const WS_XML_READER_PROPERTY
*properties
, ULONG count
,
2514 struct reader
*reader
= (struct reader
*)handle
;
2515 struct xmlbuf
*xmlbuf
= (struct xmlbuf
*)buffer
;
2519 ULONG i
, offset
= 0;
2521 TRACE( "%p %p %p %u %p\n", handle
, buffer
, properties
, count
, error
);
2522 if (error
) FIXME( "ignoring error parameter\n" );
2524 if (!reader
|| !xmlbuf
) return E_INVALIDARG
;
2526 for (i
= 0; i
< count
; i
++)
2528 hr
= set_reader_prop( reader
, properties
[i
].id
, properties
[i
].value
, properties
[i
].valueSize
);
2529 if (hr
!= S_OK
) return hr
;
2532 if ((hr
= read_init_state( reader
)) != S_OK
) return hr
;
2534 charset
= detect_charset( xmlbuf
->ptr
, xmlbuf
->size
, &offset
);
2535 hr
= set_reader_prop( reader
, WS_XML_READER_PROPERTY_CHARSET
, &charset
, sizeof(charset
) );
2536 if (hr
!= S_OK
) return hr
;
2538 set_input_buffer( reader
, (const unsigned char *)xmlbuf
->ptr
+ offset
, xmlbuf
->size
- offset
);
2539 if (!(node
= alloc_node( WS_XML_NODE_TYPE_BOF
))) return E_OUTOFMEMORY
;
2540 read_insert_bof( reader
, node
);
2544 /**************************************************************************
2545 * WsXmlStringEquals [webservices.@]
2547 HRESULT WINAPI
WsXmlStringEquals( const WS_XML_STRING
*str1
, const WS_XML_STRING
*str2
, WS_ERROR
*error
)
2549 TRACE( "%s %s %p\n", debugstr_xmlstr(str1
), debugstr_xmlstr(str2
), error
);
2550 if (error
) FIXME( "ignoring error parameter\n" );
2552 if (!str1
|| !str2
) return E_INVALIDARG
;
2554 if (str1
->length
!= str2
->length
) return S_FALSE
;
2555 if (!memcmp( str1
->bytes
, str2
->bytes
, str1
->length
)) return S_OK
;