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 HRESULT
read_move_to( struct reader
*reader
, WS_MOVE_TO move
, BOOL
*found
)
1350 BOOL success
= FALSE
;
1353 if (!read_end_of_data( reader
))
1355 while (reader
->state
!= READER_STATE_EOF
&& (hr
= read_node( reader
)) == S_OK
) { /* nothing */ };
1356 if (hr
!= S_OK
) return hr
;
1360 case WS_MOVE_TO_ROOT_ELEMENT
:
1361 success
= move_to_root_element( reader
);
1364 case WS_MOVE_TO_FIRST_NODE
:
1365 if ((ptr
= list_head( &reader
->current
->parent
->children
)))
1367 reader
->current
= LIST_ENTRY( ptr
, struct node
, entry
);
1372 case WS_MOVE_TO_NEXT_NODE
:
1373 if ((ptr
= list_next( &reader
->current
->parent
->children
, &reader
->current
->entry
)))
1375 reader
->current
= LIST_ENTRY( ptr
, struct node
, entry
);
1380 case WS_MOVE_TO_PREVIOUS_NODE
:
1381 if ((ptr
= list_prev( &reader
->current
->parent
->children
, &reader
->current
->entry
)))
1383 reader
->current
= LIST_ENTRY( ptr
, struct node
, entry
);
1388 case WS_MOVE_TO_CHILD_NODE
:
1389 if ((ptr
= list_head( &reader
->current
->children
)))
1391 reader
->current
= LIST_ENTRY( ptr
, struct node
, entry
);
1396 case WS_MOVE_TO_BOF
:
1397 reader
->current
= reader
->root
;
1401 case WS_MOVE_TO_EOF
:
1402 if ((ptr
= list_tail( &reader
->root
->children
)))
1404 reader
->current
= LIST_ENTRY( ptr
, struct node
, entry
);
1410 FIXME( "unhandled move %u\n", move
);
1419 return success
? S_OK
: WS_E_INVALID_FORMAT
;
1422 /**************************************************************************
1423 * WsMoveReader [webservices.@]
1425 HRESULT WINAPI
WsMoveReader( WS_XML_READER
*handle
, WS_MOVE_TO move
, BOOL
*found
, WS_ERROR
*error
)
1427 struct reader
*reader
= (struct reader
*)handle
;
1429 TRACE( "%p %u %p %p\n", handle
, move
, found
, error
);
1430 if (error
) FIXME( "ignoring error parameter\n" );
1432 if (!reader
) return E_INVALIDARG
;
1433 if (!reader
->input_type
) return WS_E_INVALID_OPERATION
;
1435 return read_move_to( reader
, move
, found
);
1438 /**************************************************************************
1439 * WsReadStartAttribute [webservices.@]
1441 HRESULT WINAPI
WsReadStartAttribute( WS_XML_READER
*handle
, ULONG index
, WS_ERROR
*error
)
1443 struct reader
*reader
= (struct reader
*)handle
;
1444 WS_XML_ELEMENT_NODE
*elem
;
1446 TRACE( "%p %u %p\n", handle
, index
, error
);
1447 if (error
) FIXME( "ignoring error parameter\n" );
1449 if (!reader
) return E_INVALIDARG
;
1451 elem
= &reader
->current
->hdr
;
1452 if (reader
->state
!= READER_STATE_STARTELEMENT
|| index
>= elem
->attributeCount
)
1453 return WS_E_INVALID_FORMAT
;
1455 reader
->current_attr
= index
;
1456 reader
->state
= READER_STATE_STARTATTRIBUTE
;
1460 /**************************************************************************
1461 * WsReadEndAttribute [webservices.@]
1463 HRESULT WINAPI
WsReadEndAttribute( WS_XML_READER
*handle
, WS_ERROR
*error
)
1465 struct reader
*reader
= (struct reader
*)handle
;
1467 TRACE( "%p %p\n", handle
, error
);
1468 if (error
) FIXME( "ignoring error parameter\n" );
1470 if (!reader
) return E_INVALIDARG
;
1472 if (reader
->state
!= READER_STATE_STARTATTRIBUTE
)
1473 return WS_E_INVALID_FORMAT
;
1475 reader
->state
= READER_STATE_STARTELEMENT
;
1479 static WCHAR
*xmltext_to_widechar( WS_HEAP
*heap
, const WS_XML_TEXT
*text
)
1483 switch (text
->textType
)
1485 case WS_XML_TEXT_TYPE_UTF8
:
1487 const WS_XML_UTF8_TEXT
*utf8
= (const WS_XML_UTF8_TEXT
*)text
;
1488 int len
= MultiByteToWideChar( CP_UTF8
, 0, (char *)utf8
->value
.bytes
, utf8
->value
.length
, NULL
, 0 );
1489 if (!(ret
= ws_alloc( heap
, (len
+ 1) * sizeof(WCHAR
) ))) return NULL
;
1490 MultiByteToWideChar( CP_UTF8
, 0, (char *)utf8
->value
.bytes
, utf8
->value
.length
, ret
, len
);
1495 FIXME( "unhandled type %u\n", text
->textType
);
1502 #define MAX_INT8 0x7f
1503 #define MIN_INT8 (-MAX_INT8 - 1)
1504 #define MAX_INT16 0x7fff
1505 #define MIN_INT16 (-MAX_INT16 - 1)
1506 #define MAX_INT32 0x7fffffff
1507 #define MIN_INT32 (-MAX_INT32 - 1)
1508 #define MAX_INT64 (((INT64)0x7fffffff << 32) | 0xffffffff)
1509 #define MIN_INT64 (-MAX_INT64 - 1)
1510 #define MAX_UINT8 0xff
1511 #define MAX_UINT16 0xffff
1512 #define MAX_UINT32 0xffffffff
1513 #define MAX_UINT64 (((UINT64)0xffffffff << 32) | 0xffffffff)
1515 static HRESULT
str_to_int64( const unsigned char *str
, ULONG len
, INT64 min
, INT64 max
, INT64
*ret
)
1517 BOOL negative
= FALSE
;
1518 const unsigned char *ptr
= str
;
1521 while (len
&& read_isspace( *ptr
)) { ptr
++; len
--; }
1522 while (len
&& read_isspace( ptr
[len
- 1] )) { len
--; }
1523 if (!len
) return WS_E_INVALID_FORMAT
;
1531 if (!len
) return WS_E_INVALID_FORMAT
;
1537 if (!isdigit( *ptr
)) return WS_E_INVALID_FORMAT
;
1539 if (negative
) val
= -val
;
1541 if ((!negative
&& (*ret
> max
/ 10 || *ret
* 10 > max
- val
)) ||
1542 (negative
&& (*ret
< min
/ 10 || *ret
* 10 < min
- val
)))
1544 return WS_E_NUMERIC_OVERFLOW
;
1546 *ret
= *ret
* 10 + val
;
1553 static HRESULT
str_to_uint64( const unsigned char *str
, ULONG len
, UINT64 max
, UINT64
*ret
)
1555 const unsigned char *ptr
= str
;
1558 while (len
&& read_isspace( *ptr
)) { ptr
++; len
--; }
1559 while (len
&& read_isspace( ptr
[len
- 1] )) { len
--; }
1560 if (!len
) return WS_E_INVALID_FORMAT
;
1566 if (!isdigit( *ptr
)) return WS_E_INVALID_FORMAT
;
1569 if ((*ret
> max
/ 10 || *ret
* 10 > max
- val
)) return WS_E_NUMERIC_OVERFLOW
;
1570 *ret
= *ret
* 10 + val
;
1577 static HRESULT
read_get_node_text( struct reader
*reader
, WS_XML_UTF8_TEXT
**ret
)
1579 WS_XML_TEXT_NODE
*text
;
1581 if (reader
->current
->hdr
.node
.nodeType
!= WS_XML_NODE_TYPE_TEXT
)
1582 return WS_E_INVALID_FORMAT
;
1584 text
= (WS_XML_TEXT_NODE
*)&reader
->current
->hdr
.node
;
1585 if (text
->text
->textType
!= WS_XML_TEXT_TYPE_UTF8
)
1587 FIXME( "text type %u not supported\n", text
->text
->textType
);
1590 *ret
= (WS_XML_UTF8_TEXT
*)text
->text
;
1594 static HRESULT
read_get_attribute_text( struct reader
*reader
, WS_XML_UTF8_TEXT
**ret
)
1596 WS_XML_ELEMENT_NODE
*elem
= &reader
->current
->hdr
;
1597 WS_XML_ATTRIBUTE
*attr
;
1599 if (reader
->current
->hdr
.node
.nodeType
!= WS_XML_NODE_TYPE_ELEMENT
||
1600 reader
->current_attr
>= elem
->attributeCount
) return WS_E_INVALID_FORMAT
;
1602 attr
= elem
->attributes
[reader
->current_attr
];
1603 if (attr
->value
->textType
!= WS_XML_TEXT_TYPE_UTF8
)
1605 FIXME( "text type %u not supported\n", attr
->value
->textType
);
1608 *ret
= (WS_XML_UTF8_TEXT
*)attr
->value
;
1609 reader
->current_attr
++;
1613 static BOOL
find_attribute( struct reader
*reader
, const WS_XML_STRING
*localname
,
1614 const WS_XML_STRING
*ns
, ULONG
*index
)
1617 WS_XML_ELEMENT_NODE
*elem
= &reader
->current
->hdr
;
1621 *index
= reader
->current_attr
;
1624 for (i
= 0; i
< elem
->attributeCount
; i
++)
1626 const WS_XML_STRING
*localname2
= elem
->attributes
[i
]->localName
;
1627 const WS_XML_STRING
*ns2
= elem
->attributes
[i
]->ns
;
1629 if (!cmp_name( localname
->bytes
, localname
->length
, localname2
->bytes
, localname2
->length
) &&
1630 !cmp_name( ns
->bytes
, ns
->length
, ns2
->bytes
, ns2
->length
))
1639 /**************************************************************************
1640 * WsFindAttribute [webservices.@]
1642 HRESULT WINAPI
WsFindAttribute( WS_XML_READER
*handle
, const WS_XML_STRING
*localname
,
1643 const WS_XML_STRING
*ns
, BOOL required
, ULONG
*index
,
1646 struct reader
*reader
= (struct reader
*)handle
;
1648 TRACE( "%p %s %s %d %p %p\n", handle
, debugstr_xmlstr(localname
), debugstr_xmlstr(ns
),
1649 required
, index
, error
);
1650 if (error
) FIXME( "ignoring error parameter\n" );
1652 if (!reader
|| !localname
|| !ns
|| !index
) return E_INVALIDARG
;
1654 if (reader
->current
->hdr
.node
.nodeType
!= WS_XML_NODE_TYPE_ELEMENT
)
1655 return WS_E_INVALID_OPERATION
;
1657 if (!find_attribute( reader
, localname
, ns
, index
))
1659 if (required
) return WS_E_INVALID_FORMAT
;
1666 static HRESULT
read_type_bool( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
1667 const WS_BOOL_DESCRIPTION
*desc
, BOOL
*ret
)
1669 WS_XML_UTF8_TEXT
*utf8
;
1675 FIXME( "description not supported\n" );
1680 case WS_ATTRIBUTE_TYPE_MAPPING
:
1681 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
1682 len
= utf8
->value
.length
;
1685 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
1686 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
1687 len
= utf8
->value
.length
;
1691 FIXME( "mapping %u not supported\n", mapping
);
1695 if (len
== 4 && !memcmp( utf8
->value
.bytes
, "true", 4 )) *ret
= TRUE
;
1696 else if (len
== 1 && !memcmp( utf8
->value
.bytes
, "1", 1 )) *ret
= TRUE
;
1697 else if (len
== 5 && !memcmp( utf8
->value
.bytes
, "false", 5 )) *ret
= FALSE
;
1698 else if (len
== 1 && !memcmp( utf8
->value
.bytes
, "0", 1 )) *ret
= FALSE
;
1699 else return WS_E_INVALID_FORMAT
;
1704 static HRESULT
read_type_int8( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
1705 const WS_INT8_DESCRIPTION
*desc
, INT8
*ret
)
1707 WS_XML_UTF8_TEXT
*utf8
;
1713 FIXME( "description not supported\n" );
1718 case WS_ATTRIBUTE_TYPE_MAPPING
:
1719 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
1722 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
1723 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
1727 FIXME( "mapping %u not supported\n", mapping
);
1731 if ((hr
= str_to_int64( utf8
->value
.bytes
, utf8
->value
.length
, MIN_INT8
, MAX_INT8
, &val
)) != S_OK
)
1738 static HRESULT
read_type_int16( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
1739 const WS_INT16_DESCRIPTION
*desc
, INT16
*ret
)
1741 WS_XML_UTF8_TEXT
*utf8
;
1747 FIXME( "description not supported\n" );
1752 case WS_ATTRIBUTE_TYPE_MAPPING
:
1753 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
1756 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
1757 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
1761 FIXME( "mapping %u not supported\n", mapping
);
1765 if ((hr
= str_to_int64( utf8
->value
.bytes
, utf8
->value
.length
, MIN_INT16
, MAX_INT16
, &val
)) != S_OK
)
1772 static HRESULT
read_type_int32( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
1773 const WS_INT32_DESCRIPTION
*desc
, INT32
*ret
)
1775 WS_XML_UTF8_TEXT
*utf8
;
1781 FIXME( "description not supported\n" );
1786 case WS_ATTRIBUTE_TYPE_MAPPING
:
1787 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
1790 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
1791 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
1795 FIXME( "mapping %u not supported\n", mapping
);
1799 if ((hr
= str_to_int64( utf8
->value
.bytes
, utf8
->value
.length
, MIN_INT32
, MAX_INT32
, &val
)) != S_OK
)
1806 static HRESULT
read_type_int64( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
1807 const WS_INT64_DESCRIPTION
*desc
, INT64
*ret
)
1809 WS_XML_UTF8_TEXT
*utf8
;
1815 FIXME( "description not supported\n" );
1820 case WS_ATTRIBUTE_TYPE_MAPPING
:
1821 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
1824 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
1825 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
1829 FIXME( "mapping %u not supported\n", mapping
);
1833 if ((hr
= str_to_int64( utf8
->value
.bytes
, utf8
->value
.length
, MIN_INT64
, MAX_INT64
, &val
)) != S_OK
)
1840 static HRESULT
read_type_uint8( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
1841 const WS_UINT8_DESCRIPTION
*desc
, UINT8
*ret
)
1843 WS_XML_UTF8_TEXT
*utf8
;
1849 FIXME( "description not supported\n" );
1854 case WS_ATTRIBUTE_TYPE_MAPPING
:
1855 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
1858 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
1859 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
1863 FIXME( "mapping %u not supported\n", mapping
);
1867 if ((hr
= str_to_uint64( utf8
->value
.bytes
, utf8
->value
.length
, MAX_UINT8
, &val
)) != S_OK
)
1874 static HRESULT
read_type_uint16( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
1875 const WS_UINT16_DESCRIPTION
*desc
, UINT16
*ret
)
1877 WS_XML_UTF8_TEXT
*utf8
;
1883 FIXME( "description not supported\n" );
1888 case WS_ATTRIBUTE_TYPE_MAPPING
:
1889 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
1892 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
1893 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
1897 FIXME( "mapping %u not supported\n", mapping
);
1901 if ((hr
= str_to_uint64( utf8
->value
.bytes
, utf8
->value
.length
, MAX_UINT16
, &val
)) != S_OK
)
1908 static HRESULT
read_type_uint32( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
1909 const WS_UINT32_DESCRIPTION
*desc
, UINT32
*ret
)
1911 WS_XML_UTF8_TEXT
*utf8
;
1917 FIXME( "description not supported\n" );
1922 case WS_ATTRIBUTE_TYPE_MAPPING
:
1923 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
1926 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
1927 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
1931 FIXME( "mapping %u not supported\n", mapping
);
1935 if ((hr
= str_to_uint64( utf8
->value
.bytes
, utf8
->value
.length
, MAX_UINT32
, &val
)) != S_OK
)
1942 static HRESULT
read_type_uint64( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
1943 const WS_UINT64_DESCRIPTION
*desc
, UINT64
*ret
)
1945 WS_XML_UTF8_TEXT
*utf8
;
1951 FIXME( "description not supported\n" );
1956 case WS_ATTRIBUTE_TYPE_MAPPING
:
1957 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
1960 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
1961 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
1965 FIXME( "mapping %u not supported\n", mapping
);
1969 if ((hr
= str_to_uint64( utf8
->value
.bytes
, utf8
->value
.length
, MAX_UINT64
, &val
)) != S_OK
)
1976 static HRESULT
read_type_wsz( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
1977 const WS_WSZ_DESCRIPTION
*desc
, WS_HEAP
*heap
, WCHAR
**ret
)
1979 WS_XML_UTF8_TEXT
*utf8
;
1985 FIXME( "description not supported\n" );
1990 case WS_ATTRIBUTE_TYPE_MAPPING
:
1991 if ((hr
= read_get_attribute_text( reader
, &utf8
)) != S_OK
) return hr
;
1994 case WS_ELEMENT_TYPE_MAPPING
:
1995 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
1996 if ((hr
= read_get_node_text( reader
, &utf8
)) != S_OK
) return hr
;
2000 FIXME( "mapping %u not supported\n", mapping
);
2004 if (!(str
= xmltext_to_widechar( heap
, &utf8
->text
))) return WS_E_QUOTA_EXCEEDED
;
2009 static HRESULT
read_type_struct( struct reader
*, WS_TYPE_MAPPING
, const WS_STRUCT_DESCRIPTION
*,
2010 WS_HEAP
*, void ** );
2012 static HRESULT
read_type_struct_field( struct reader
*reader
, const WS_FIELD_DESCRIPTION
*desc
,
2013 WS_HEAP
*heap
, char *buf
)
2015 char *ptr
= buf
+ desc
->offset
;
2016 WS_TYPE_MAPPING mapping
;
2019 if (desc
->options
&& desc
->options
!= WS_FIELD_POINTER
&&
2020 desc
->options
!= WS_FIELD_OPTIONAL
&&
2021 desc
->options
!= (WS_FIELD_POINTER
| WS_FIELD_OPTIONAL
))
2023 FIXME( "options 0x%x not supported\n", desc
->options
);
2027 switch (desc
->mapping
)
2029 case WS_ATTRIBUTE_FIELD_MAPPING
:
2030 mapping
= WS_ATTRIBUTE_TYPE_MAPPING
;
2033 case WS_ELEMENT_FIELD_MAPPING
:
2034 mapping
= WS_ELEMENT_TYPE_MAPPING
;
2038 FIXME( "unhandled field mapping %u\n", desc
->mapping
);
2044 case WS_STRUCT_TYPE
:
2045 hr
= read_type_struct( reader
, mapping
, desc
->typeDescription
, heap
, (void **)ptr
);
2049 hr
= read_type_bool( reader
, mapping
, desc
->typeDescription
, (BOOL
*)ptr
);
2053 hr
= read_type_int8( reader
, mapping
, desc
->typeDescription
, (INT8
*)ptr
);
2057 hr
= read_type_int16( reader
, mapping
, desc
->typeDescription
, (INT16
*)ptr
);
2061 hr
= read_type_int32( reader
, mapping
, desc
->typeDescription
, (INT32
*)ptr
);
2065 hr
= read_type_int64( reader
, mapping
, desc
->typeDescription
, (INT64
*)ptr
);
2069 hr
= read_type_uint8( reader
, mapping
, desc
->typeDescription
, (UINT8
*)ptr
);
2072 case WS_UINT16_TYPE
:
2073 hr
= read_type_uint16( reader
, mapping
, desc
->typeDescription
, (UINT16
*)ptr
);
2076 case WS_UINT32_TYPE
:
2077 hr
= read_type_uint32( reader
, mapping
, desc
->typeDescription
, (UINT32
*)ptr
);
2080 case WS_UINT64_TYPE
:
2081 hr
= read_type_uint64( reader
, mapping
, desc
->typeDescription
, (UINT64
*)ptr
);
2085 hr
= read_type_wsz( reader
, mapping
, desc
->typeDescription
, heap
, (WCHAR
**)ptr
);
2089 FIXME( "type %u not implemented\n", desc
->type
);
2096 static HRESULT
read_type_struct( struct reader
*reader
, WS_TYPE_MAPPING mapping
,
2097 const WS_STRUCT_DESCRIPTION
*desc
, WS_HEAP
*heap
, void **ret
)
2103 if (!desc
) return E_INVALIDARG
;
2105 if (desc
->structOptions
)
2107 FIXME( "struct options 0x%x not supported\n", desc
->structOptions
);
2113 case WS_ELEMENT_TYPE_MAPPING
:
2114 if ((hr
= read_to_startelement( reader
, NULL
)) != S_OK
) return hr
;
2117 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
2118 if ((hr
= read_to_startelement( reader
, NULL
)) != S_OK
) return hr
;
2119 if ((hr
= read_startelement( reader
)) != S_OK
) return hr
;
2123 FIXME( "unhandled mapping %u\n", mapping
);
2127 if (!(buf
= ws_alloc_zero( heap
, desc
->size
))) return WS_E_QUOTA_EXCEEDED
;
2129 for (i
= 0; i
< desc
->fieldCount
; i
++)
2131 if ((hr
= read_type_struct_field( reader
, desc
->fields
[i
], heap
, buf
)) != S_OK
)
2133 ws_free( heap
, buf
);
2140 case WS_ELEMENT_TYPE_MAPPING
:
2141 if ((hr
= read_endelement( reader
)) != S_OK
) return hr
;
2144 case WS_ELEMENT_CONTENT_TYPE_MAPPING
:
2145 if ((hr
= read_endelement( reader
)) != S_OK
) return hr
;
2146 if ((hr
= read_node( reader
)) != S_OK
) return hr
;
2147 if (reader
->state
!= READER_STATE_EOF
) return WS_E_INVALID_FORMAT
;
2157 static HRESULT
read_type( struct reader
*reader
, WS_TYPE_MAPPING mapping
, WS_TYPE type
,
2158 const void *desc
, WS_READ_OPTION option
, WS_HEAP
*heap
,
2159 void *value
, ULONG size
)
2163 case WS_STRUCT_TYPE
:
2166 if (option
!= WS_READ_REQUIRED_POINTER
|| size
!= sizeof(*ptr
))
2167 return E_INVALIDARG
;
2169 return read_type_struct( reader
, mapping
, desc
, heap
, ptr
);
2174 if (option
!= WS_READ_REQUIRED_VALUE
)
2176 FIXME( "read option %u not supported\n", option
);
2179 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2180 return read_type_bool( reader
, mapping
, desc
, ptr
);
2185 if (option
!= WS_READ_REQUIRED_VALUE
)
2187 FIXME( "read option %u not supported\n", option
);
2190 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2191 return read_type_int8( reader
, mapping
, desc
, ptr
);
2196 if (option
!= WS_READ_REQUIRED_VALUE
)
2198 FIXME( "read option %u not supported\n", option
);
2201 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2202 return read_type_int16( reader
, mapping
, desc
, ptr
);
2207 if (option
!= WS_READ_REQUIRED_VALUE
)
2209 FIXME( "read option %u not supported\n", option
);
2212 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2213 return read_type_int32( reader
, mapping
, desc
, ptr
);
2218 if (option
!= WS_READ_REQUIRED_VALUE
)
2220 FIXME( "read option %u not supported\n", option
);
2223 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2224 return read_type_int64( reader
, mapping
, desc
, ptr
);
2229 if (option
!= WS_READ_REQUIRED_VALUE
)
2231 FIXME( "read option %u not supported\n", option
);
2234 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2235 return read_type_uint8( reader
, mapping
, desc
, ptr
);
2237 case WS_UINT16_TYPE
:
2239 UINT16
*ptr
= value
;
2240 if (option
!= WS_READ_REQUIRED_VALUE
)
2242 FIXME( "read option %u not supported\n", option
);
2245 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2246 return read_type_uint16( reader
, mapping
, desc
, ptr
);
2248 case WS_UINT32_TYPE
:
2250 UINT32
*ptr
= value
;
2251 if (option
!= WS_READ_REQUIRED_VALUE
)
2253 FIXME( "read option %u not supported\n", option
);
2256 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2257 return read_type_uint32( reader
, mapping
, desc
, ptr
);
2259 case WS_UINT64_TYPE
:
2261 UINT64
*ptr
= value
;
2262 if (option
!= WS_READ_REQUIRED_VALUE
)
2264 FIXME( "read option %u not supported\n", option
);
2267 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2268 return read_type_uint64( reader
, mapping
, desc
, ptr
);
2272 WCHAR
**ptr
= value
;
2273 if (option
!= WS_READ_REQUIRED_POINTER
)
2275 FIXME( "read option %u not supported\n", option
);
2278 if (size
!= sizeof(*ptr
)) return E_INVALIDARG
;
2279 return read_type_wsz( reader
, mapping
, desc
, heap
, ptr
);
2282 FIXME( "type %u not supported\n", type
);
2287 /**************************************************************************
2288 * WsReadType [webservices.@]
2290 HRESULT WINAPI
WsReadType( WS_XML_READER
*handle
, WS_TYPE_MAPPING mapping
, WS_TYPE type
,
2291 const void *desc
, WS_READ_OPTION option
, WS_HEAP
*heap
, void *value
,
2292 ULONG size
, WS_ERROR
*error
)
2294 struct reader
*reader
= (struct reader
*)handle
;
2296 TRACE( "%p %u %u %p %u %p %p %u %p\n", handle
, mapping
, type
, desc
, option
, heap
, value
,
2298 if (error
) FIXME( "ignoring error parameter\n" );
2300 if (!reader
|| !value
) return E_INVALIDARG
;
2302 return read_type( reader
, mapping
, type
, desc
, option
, heap
, value
, size
);
2305 /**************************************************************************
2306 * WsSetErrorProperty [webservices.@]
2308 HRESULT WINAPI
WsSetErrorProperty( WS_ERROR
*handle
, WS_ERROR_PROPERTY_ID id
, const void *value
,
2311 struct error
*error
= (struct error
*)handle
;
2313 TRACE( "%p %u %p %u\n", handle
, id
, value
, size
);
2315 if (id
== WS_ERROR_PROPERTY_LANGID
) return WS_E_INVALID_OPERATION
;
2316 return set_error_prop( error
, id
, value
, size
);
2319 static inline BOOL
is_utf8( const unsigned char *data
, ULONG size
, ULONG
*offset
)
2321 static const char bom
[] = {0xef,0xbb,0xbf};
2322 const unsigned char *p
= data
;
2324 return (size
>= sizeof(bom
) && !memcmp( p
, bom
, sizeof(bom
) ) && (*offset
= sizeof(bom
))) ||
2325 (size
> 2 && !(*offset
= 0));
2328 static inline BOOL
is_utf16le( const unsigned char *data
, ULONG size
, ULONG
*offset
)
2330 static const char bom
[] = {0xff,0xfe};
2331 const unsigned char *p
= data
;
2333 return (size
>= sizeof(bom
) && !memcmp( p
, bom
, sizeof(bom
) ) && (*offset
= sizeof(bom
))) ||
2334 (size
>= 4 && p
[0] == '<' && !p
[1] && !(*offset
= 0));
2337 static WS_CHARSET
detect_charset( const unsigned char *data
, ULONG size
, ULONG
*offset
)
2341 /* FIXME: parse xml declaration */
2343 if (is_utf16le( data
, size
, offset
)) ret
= WS_CHARSET_UTF16LE
;
2344 else if (is_utf8( data
, size
, offset
)) ret
= WS_CHARSET_UTF8
;
2347 FIXME( "charset not recognized\n" );
2351 TRACE( "detected charset %u\n", ret
);
2355 static void set_input_buffer( struct reader
*reader
, const unsigned char *data
, ULONG size
)
2357 reader
->input_type
= WS_XML_READER_INPUT_TYPE_BUFFER
;
2358 reader
->input_data
= data
;
2359 reader
->input_size
= size
;
2361 reader
->read_size
= reader
->input_size
;
2362 reader
->read_pos
= 0;
2363 reader
->read_bufptr
= reader
->input_data
;
2366 /**************************************************************************
2367 * WsSetInput [webservices.@]
2369 HRESULT WINAPI
WsSetInput( WS_XML_READER
*handle
, const WS_XML_READER_ENCODING
*encoding
,
2370 const WS_XML_READER_INPUT
*input
, const WS_XML_READER_PROPERTY
*properties
,
2371 ULONG count
, WS_ERROR
*error
)
2373 struct reader
*reader
= (struct reader
*)handle
;
2376 ULONG i
, offset
= 0;
2378 TRACE( "%p %p %p %p %u %p\n", handle
, encoding
, input
, properties
, count
, error
);
2379 if (error
) FIXME( "ignoring error parameter\n" );
2381 if (!reader
) return E_INVALIDARG
;
2383 for (i
= 0; i
< count
; i
++)
2385 hr
= set_reader_prop( reader
, properties
[i
].id
, properties
[i
].value
, properties
[i
].valueSize
);
2386 if (hr
!= S_OK
) return hr
;
2389 if ((hr
= read_init_state( reader
)) != S_OK
) return hr
;
2391 switch (encoding
->encodingType
)
2393 case WS_XML_READER_ENCODING_TYPE_TEXT
:
2395 WS_XML_READER_TEXT_ENCODING
*text
= (WS_XML_READER_TEXT_ENCODING
*)encoding
;
2396 WS_XML_READER_BUFFER_INPUT
*buf
= (WS_XML_READER_BUFFER_INPUT
*)input
;
2397 WS_CHARSET charset
= text
->charSet
;
2399 if (input
->inputType
!= WS_XML_READER_INPUT_TYPE_BUFFER
)
2401 FIXME( "charset detection on input type %u not supported\n", input
->inputType
);
2405 if (charset
== WS_CHARSET_AUTO
)
2406 charset
= detect_charset( buf
->encodedData
, buf
->encodedDataSize
, &offset
);
2408 hr
= set_reader_prop( reader
, WS_XML_READER_PROPERTY_CHARSET
, &charset
, sizeof(charset
) );
2409 if (hr
!= S_OK
) return hr
;
2413 FIXME( "encoding type %u not supported\n", encoding
->encodingType
);
2416 switch (input
->inputType
)
2418 case WS_XML_READER_INPUT_TYPE_BUFFER
:
2420 WS_XML_READER_BUFFER_INPUT
*buf
= (WS_XML_READER_BUFFER_INPUT
*)input
;
2421 set_input_buffer( reader
, (const unsigned char *)buf
->encodedData
+ offset
, buf
->encodedDataSize
- offset
);
2425 FIXME( "input type %u not supported\n", input
->inputType
);
2429 if (!(node
= alloc_node( WS_XML_NODE_TYPE_BOF
))) return E_OUTOFMEMORY
;
2430 read_insert_bof( reader
, node
);
2434 /**************************************************************************
2435 * WsSetInputToBuffer [webservices.@]
2437 HRESULT WINAPI
WsSetInputToBuffer( WS_XML_READER
*handle
, WS_XML_BUFFER
*buffer
,
2438 const WS_XML_READER_PROPERTY
*properties
, ULONG count
,
2441 struct reader
*reader
= (struct reader
*)handle
;
2442 struct xmlbuf
*xmlbuf
= (struct xmlbuf
*)buffer
;
2446 ULONG i
, offset
= 0;
2448 TRACE( "%p %p %p %u %p\n", handle
, buffer
, properties
, count
, error
);
2449 if (error
) FIXME( "ignoring error parameter\n" );
2451 if (!reader
|| !xmlbuf
) return E_INVALIDARG
;
2453 for (i
= 0; i
< count
; i
++)
2455 hr
= set_reader_prop( reader
, properties
[i
].id
, properties
[i
].value
, properties
[i
].valueSize
);
2456 if (hr
!= S_OK
) return hr
;
2459 if ((hr
= read_init_state( reader
)) != S_OK
) return hr
;
2461 charset
= detect_charset( xmlbuf
->ptr
, xmlbuf
->size
, &offset
);
2462 hr
= set_reader_prop( reader
, WS_XML_READER_PROPERTY_CHARSET
, &charset
, sizeof(charset
) );
2463 if (hr
!= S_OK
) return hr
;
2465 set_input_buffer( reader
, (const unsigned char *)xmlbuf
->ptr
+ offset
, xmlbuf
->size
- offset
);
2466 if (!(node
= alloc_node( WS_XML_NODE_TYPE_BOF
))) return E_OUTOFMEMORY
;
2467 read_insert_bof( reader
, node
);
2471 /**************************************************************************
2472 * WsXmlStringEquals [webservices.@]
2474 HRESULT WINAPI
WsXmlStringEquals( const WS_XML_STRING
*str1
, const WS_XML_STRING
*str2
, WS_ERROR
*error
)
2476 TRACE( "%s %s %p\n", debugstr_xmlstr(str1
), debugstr_xmlstr(str2
), error
);
2477 if (error
) FIXME( "ignoring error parameter\n" );
2479 if (!str1
|| !str2
) return E_INVALIDARG
;
2481 if (str1
->length
!= str2
->length
) return S_FALSE
;
2482 if (!memcmp( str1
->bytes
, str2
->bytes
, str1
->length
)) return S_OK
;