ReactOS 0.4.17-dev-966-gf06eace
reader.c
Go to the documentation of this file.
1/*
2 * IXmlReader implementation
3 *
4 * Copyright 2010, 2012-2013, 2016-2017 Nikolay Sivov
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#define COBJMACROS
22
23#include <stdio.h>
24#include <stdarg.h>
25#include <assert.h>
26#include "windef.h"
27#include "winbase.h"
28#include "initguid.h"
29#include "objbase.h"
30#include "xmllite.h"
31#include "xmllite_private.h"
32#ifdef __REACTOS__
33#include <winnls.h>
34#endif
35
36#include "wine/debug.h"
37#include "wine/list.h"
38
40
41/* not defined in public headers */
42DEFINE_GUID(IID_IXmlReaderInput, 0x0b3ccc9b, 0x9214, 0x428b, 0xa2, 0xae, 0xef, 0x3a, 0xa8, 0x71, 0xaf, 0xda);
43
44typedef enum
45{
53 XmlReadInState_MiscEnd, /* optional Misc at the end of a document */
56
57/* This state denotes where parsing was interrupted by input problem.
58 Reader resumes parsing using this information. */
59typedef enum
60{
70
71/* saved pointer index to resume from particular input position */
72typedef enum
73{
74 XmlReadResume_Name, /* PITarget, name for NCName, prefix for QName */
75 XmlReadResume_Local, /* local for QName */
76 XmlReadResume_Body, /* PI body, comment text, CDATA text, CharData text */
79
80typedef enum
81{
88
90
91static const char *debugstr_nodetype(XmlNodeType nodetype)
92{
93 static const char * const type_names[] =
94 {
95 "None",
96 "Element",
97 "Attribute",
98 "Text",
99 "CDATA",
100 "",
101 "",
102 "ProcessingInstruction",
103 "Comment",
104 "",
105 "DocumentType",
106 "",
107 "",
108 "Whitespace",
109 "",
110 "EndElement",
111 "",
112 "XmlDeclaration"
113 };
114
115 if (nodetype > _XmlNodeType_Last)
116 return wine_dbg_sprintf("unknown type=%d", nodetype);
117
118 return type_names[nodetype];
119}
120
122{
123 static const char * const prop_names[] =
124 {
125 "MultiLanguage",
126 "ConformanceLevel",
127 "RandomAccess",
128 "XmlResolver",
129 "DtdProcessing",
130 "ReadState",
131 "MaxElementDepth",
132 "MaxEntityExpansion"
133 };
134
135 if (prop > _XmlReaderProperty_Last)
136 return wine_dbg_sprintf("unknown property=%d", prop);
137
138 return prop_names[prop];
139}
140
142{
143 const WCHAR *name;
145 UINT cp;
146};
147
148static const struct xml_encoding_data xml_encoding_map[] =
149{
150 { L"US-ASCII", XmlEncoding_USASCII, 20127 },
151 { L"UTF-16", XmlEncoding_UTF16, 1200 },
152 { L"UTF-8", XmlEncoding_UTF8, CP_UTF8 },
153};
154
156{
157 return xml_encoding_map[encoding].name;
158}
159
161{
162 int i;
163 for (i = 0; i < ARRAY_SIZE(xml_encoding_map); i++)
164 {
165 if (xml_encoding_map[i].cp == codepage) return xml_encoding_map[i].enc;
166 }
167 return XmlEncoding_Unknown;
168}
169
170typedef struct
171{
172 char *data;
174 unsigned int allocated;
175 unsigned int written;
178
180
181typedef struct
182{
185 /* reference passed on IXmlReaderInput creation, is kept when input is created */
191 /* stream reference set after SetInput() call from reader,
192 stored as sequential stream, cause currently
193 optimizations possible with IStream aren't implemented */
196 unsigned int pending : 1;
198
199static const struct IUnknownVtbl xmlreaderinputvtbl;
200
201/* Structure to hold parsed string of specific length.
202
203 Reader stores node value as 'start' pointer, on request
204 a null-terminated version of it is allocated.
205
206 To init a strval variable use reader_init_strval(),
207 to set strval as a reader value use reader_set_strval().
208 */
209typedef struct
210{
211 WCHAR *str; /* allocated null-terminated string */
212 UINT len; /* length in WCHARs, altered after ReadValueChunk */
213 UINT start; /* input position where value starts */
214} strval;
215
216static WCHAR emptyW[] = L"";
217static WCHAR xmlW[] = L"xml";
218static WCHAR xmlnsW[] = L"xmlns";
219static const strval strval_empty = { emptyW, 0 };
220static const strval strval_xml = { xmlW, 3 };
221static const strval strval_xmlns = { xmlnsW, 5 };
222
224{
227};
228
230{
233};
234
235struct attribute
236{
237 struct list entry;
243 unsigned int flags;
244};
245
247{
248 struct list entry;
253};
254
255struct ns
256{
257 struct list entry;
261};
262
263typedef struct
264{
270 HRESULT error; /* error set on XmlReadState_Error */
277 struct reader_position position;
278 struct list attrs; /* attributes list for current node */
279 struct attribute *attr; /* current attribute */
281 struct list nsdef;
282 struct list ns;
283 struct list elements;
289 struct element empty_element; /* used for empty elements without end tag <a />,
290 and to keep <?xml reader position */
291 UINT resume[XmlReadResume_Last]; /* offsets used to resume reader */
292} xmlreader;
293
295{
300};
301
303{
304 return CONTAINING_RECORD(iface, xmlreader, IXmlReader_iface);
305}
306
308{
309 return CONTAINING_RECORD(iface, xmlreaderinput, IXmlReaderInput_iface);
310}
311
312/* reader memory allocation functions */
313static inline void *reader_alloc(xmlreader *reader, size_t len)
314{
315 return m_alloc(reader->imalloc, len);
316}
317
318static inline void *reader_alloc_zero(xmlreader *reader, size_t len)
319{
320 void *ret = reader_alloc(reader, len);
321 if (ret)
322 memset(ret, 0, len);
323 return ret;
324}
325
326static inline void reader_free(xmlreader *reader, void *mem)
327{
328 m_free(reader->imalloc, mem);
329}
330
331/* Just return pointer from offset, no attempt to read more. */
333{
334 encoded_buffer *buffer = &reader->input->buffer->utf16;
335 return (WCHAR*)buffer->data + offset;
336}
337
338static inline WCHAR *reader_get_strptr(const xmlreader *reader, const strval *v)
339{
340 return v->str ? v->str : reader_get_ptr2(reader, v->start);
341}
342
344{
345 *dest = *src;
346
347 if (src->str != strval_empty.str)
348 {
349 dest->str = reader_alloc(reader, (dest->len+1)*sizeof(WCHAR));
350 if (!dest->str) return E_OUTOFMEMORY;
351 memcpy(dest->str, reader_get_strptr(reader, src), dest->len*sizeof(WCHAR));
352 dest->str[dest->len] = 0;
353 dest->start = 0;
354 }
355
356 return S_OK;
357}
358
359/* reader input memory allocation functions */
360static inline void *readerinput_alloc(xmlreaderinput *input, size_t len)
361{
362 return m_alloc(input->imalloc, len);
363}
364
365static inline void *readerinput_realloc(xmlreaderinput *input, void *mem, size_t len)
366{
367 return m_realloc(input->imalloc, mem, len);
368}
369
370static inline void readerinput_free(xmlreaderinput *input, void *mem)
371{
372 m_free(input->imalloc, mem);
373}
374
376{
377 LPWSTR ret = NULL;
378
379 if(str) {
380 DWORD size;
381
382 size = (lstrlenW(str)+1)*sizeof(WCHAR);
384 if (ret) memcpy(ret, str, size);
385 }
386
387 return ret;
388}
389
390/* This one frees stored string value if needed */
392{
393 if (v->str != strval_empty.str)
394 {
395 reader_free(reader, v->str);
396 *v = strval_empty;
397 }
398}
399
401{
402 struct attribute *attr, *attr2;
403 LIST_FOR_EACH_ENTRY_SAFE(attr, attr2, &reader->attrs, struct attribute, entry)
404 {
405 reader_free_strvalued(reader, &attr->localname);
408 }
409 list_init(&reader->attrs);
410 reader->attr_count = 0;
411 reader->attr = NULL;
412}
413
414/* attribute data holds pointers to buffer data, so buffer shrink is not possible
415 while we are on a node with attributes */
417 strval *value, const struct reader_position *position, unsigned int flags)
418{
419 struct attribute *attr;
420 HRESULT hr;
421
422 attr = reader_alloc(reader, sizeof(*attr));
423 if (!attr) return E_OUTOFMEMORY;
424
425 hr = reader_strvaldup(reader, localname, &attr->localname);
426 if (hr == S_OK)
427 {
429 if (hr != S_OK)
430 reader_free_strvalued(reader, &attr->localname);
431 }
432 if (hr != S_OK)
433 {
435 return hr;
436 }
437
438 if (prefix)
439 attr->prefix = *prefix;
440 else
441 memset(&attr->prefix, 0, sizeof(attr->prefix));
442 attr->qname = qname ? *qname : *localname;
443 attr->position = *position;
444 attr->flags = flags;
445 list_add_tail(&reader->attrs, &attr->entry);
446 reader->attr_count++;
447
448 return S_OK;
449}
450
451/* Returns current element, doesn't check if reader is actually positioned on it. */
453{
454 if (reader->is_empty_element)
455 return &reader->empty_element;
456
457 return LIST_ENTRY(list_head(&reader->elements), struct element, entry);
458}
459
461{
462 v->start = start;
463 v->len = len;
464 v->str = NULL;
465}
466
467static inline const char* debug_strval(const xmlreader *reader, const strval *v)
468{
469 return debugstr_wn(reader_get_strptr(reader, v), v->len);
470}
471
472/* used to initialize from constant string */
474{
475 v->start = 0;
476 v->len = len;
477 v->str = str;
478}
479
481{
483}
484
486{
487 int type;
488 for (type = 0; type < StringValue_Last; type++)
490}
491
492/* This helper should only be used to test if strings are the same,
493 it doesn't try to sort. */
494static inline int strval_eq(const xmlreader *reader, const strval *str1, const strval *str2)
495{
496 if (str1->len != str2->len) return 0;
498}
499
501{
502 struct element *elem, *elem2;
503 LIST_FOR_EACH_ENTRY_SAFE(elem, elem2, &reader->elements, struct element, entry)
504 {
506 reader_free_strvalued(reader, &elem->localname);
509 }
510 list_init(&reader->elements);
511 reader_free_strvalued(reader, &reader->empty_element.localname);
512 reader_free_strvalued(reader, &reader->empty_element.qname);
513 reader->is_empty_element = FALSE;
514}
515
517{
518 struct list *nslist = prefix ? &reader->ns : &reader->nsdef;
519 struct ns *ns;
520
521 LIST_FOR_EACH_ENTRY_REV(ns, nslist, struct ns, entry) {
523 return ns;
524 }
525
526 return NULL;
527}
528
530{
531 return (++reader->depth >= reader->max_depth && reader->max_depth) ? SC_E_MAXELEMENTDEPTH : S_OK;
532}
533
535{
536 if (reader->depth)
537 reader->depth--;
538}
539
541{
542 struct ns *ns;
543 HRESULT hr;
544
545 ns = reader_alloc(reader, sizeof(*ns));
546 if (!ns) return E_OUTOFMEMORY;
547
548 if (def)
549 memset(&ns->prefix, 0, sizeof(ns->prefix));
550 else {
552 if (FAILED(hr)) {
554 return hr;
555 }
556 }
557
559 if (FAILED(hr)) {
562 return hr;
563 }
564
565 ns->element = NULL;
566 list_add_head(def ? &reader->nsdef : &reader->ns, &ns->entry);
567 return hr;
568}
569
571{
576}
577
579{
580 struct ns *ns;
581
582 LIST_FOR_EACH_ENTRY(ns, &reader->ns, struct ns, entry) {
583 if (ns->element)
584 break;
585 ns->element = element;
586 }
587
588 LIST_FOR_EACH_ENTRY(ns, &reader->nsdef, struct ns, entry) {
589 if (ns->element)
590 break;
591 ns->element = element;
592 }
593}
594
596 strval *qname, const struct reader_position *position)
597{
598 struct element *element;
599 HRESULT hr;
600
602 if (!element)
603 return E_OUTOFMEMORY;
604
608 {
609 list_add_head(&reader->elements, &element->entry);
611 reader->is_empty_element = FALSE;
613 }
614 else
616
617 return hr;
618}
619
621{
622 struct ns *ns, *ns2;
623
624 LIST_FOR_EACH_ENTRY_SAFE_REV(ns, ns2, &reader->ns, struct ns, entry) {
625 if (ns->element != element)
626 break;
627
632 }
633
634 if (!list_empty(&reader->nsdef)) {
635 ns = LIST_ENTRY(list_head(&reader->nsdef), struct ns, entry);
636 if (ns->element == element) {
641 }
642 }
643}
644
646{
647 struct element *element;
648
649 if (list_empty(&reader->elements))
650 return;
651
652 element = LIST_ENTRY(list_head(&reader->elements), struct element, entry);
654
657
658 /* It was a root element, the rest is expected as Misc */
659 if (list_empty(&reader->elements))
661}
662
663/* Always make a copy, cause strings are supposed to be null terminated. Null pointer for 'value'
664 means node value is to be determined. */
666{
667 strval *v = &reader->strvalues[type];
668
670 if (!value)
671 {
672 v->str = NULL;
673 v->start = 0;
674 v->len = 0;
675 return;
676 }
677
678 if (value->str == strval_empty.str)
679 *v = *value;
680 else
681 {
682 if (type == StringValue_Value)
683 {
684 /* defer allocation for value string */
685 v->str = NULL;
686 v->start = value->start;
687 v->len = value->len;
688 }
689 else
690 {
691 v->str = reader_alloc(reader, (value->len + 1)*sizeof(WCHAR));
692 memcpy(v->str, reader_get_strptr(reader, value), value->len*sizeof(WCHAR));
693 v->str[value->len] = 0;
694 v->len = value->len;
695 }
696 }
697}
698
700{
701 return reader->input->pending;
702}
703
705{
706 const int initial_len = 0x2000;
707 buffer->data = readerinput_alloc(input, initial_len);
708 if (!buffer->data) return E_OUTOFMEMORY;
709
710 memset(buffer->data, 0, 4);
711 buffer->cur = 0;
712 buffer->allocated = initial_len;
713 buffer->written = 0;
714 buffer->prev_cr = FALSE;
715
716 return S_OK;
717}
718
720{
722}
723
725{
726 if (encoding == XmlEncoding_Unknown)
727 {
728 FIXME("unsupported encoding %d\n", encoding);
729 return E_NOTIMPL;
730 }
731
732 *cp = xml_encoding_map[encoding].cp;
733
734 return S_OK;
735}
736
738{
739 int min, max, n, c;
740
741 if (!name) return XmlEncoding_Unknown;
742
743 min = 0;
745
746 while (min <= max)
747 {
748 n = (min+max)/2;
749
750 if (len != -1)
752 else
754 if (!c)
755 return xml_encoding_map[n].enc;
756
757 if (c > 0)
758 max = n-1;
759 else
760 min = n+1;
761 }
762
763 return XmlEncoding_Unknown;
764}
765
767{
769 HRESULT hr;
770
771 input->buffer = NULL;
772
774 if (!buffer) return E_OUTOFMEMORY;
775
776 buffer->input = input;
777 buffer->code_page = ~0; /* code page is unknown at this point */
779 if (hr != S_OK) {
781 return hr;
782 }
783
784 hr = init_encoded_buffer(input, &buffer->encoded);
785 if (hr != S_OK) {
788 return hr;
789 }
790
791 input->buffer = buffer;
792 return S_OK;
793}
794
796{
797 free_encoded_buffer(buffer->input, &buffer->encoded);
798 free_encoded_buffer(buffer->input, &buffer->utf16);
800}
801
803{
804 if (readerinput->stream) {
805 ISequentialStream_Release(readerinput->stream);
806 readerinput->stream = NULL;
807 }
808}
809
810/* Queries already stored interface for IStream/ISequentialStream.
811 Interface supplied on creation will be overwritten */
813{
814 HRESULT hr;
815
816 readerinput_release_stream(readerinput);
817 hr = IUnknown_QueryInterface(readerinput->input, &IID_IStream, (void**)&readerinput->stream);
818 if (hr != S_OK)
819 hr = IUnknown_QueryInterface(readerinput->input, &IID_ISequentialStream, (void**)&readerinput->stream);
820
821 return hr;
822}
823
824/* reads a chunk to raw buffer */
826{
827 encoded_buffer *buffer = &readerinput->buffer->encoded;
828 /* to make sure aligned length won't exceed allocated length */
829 ULONG len = buffer->allocated - buffer->written - 4;
830 ULONG read;
831 HRESULT hr;
832
833 /* always try to get aligned to 4 bytes, so the only case we can get partially read characters is
834 variable width encodings like UTF-8 */
835 len = (len + 3) & ~3;
836 /* try to use allocated space or grow */
837 if (buffer->allocated - buffer->written < len)
838 {
839 buffer->allocated *= 2;
840 buffer->data = readerinput_realloc(readerinput, buffer->data, buffer->allocated);
841 len = buffer->allocated - buffer->written;
842 }
843
844 read = 0;
845 hr = ISequentialStream_Read(readerinput->stream, buffer->data + buffer->written, len, &read);
846 TRACE("written=%d, alloc=%d, requested=%ld, read=%ld, ret=%#lx\n", buffer->written, buffer->allocated, len, read, hr);
847 readerinput->pending = hr == E_PENDING;
848 if (FAILED(hr)) return hr;
849 buffer->written += read;
850 if (!buffer->written)
851 return MX_E_INPUTEND;
852
853 return hr;
854}
855
856/* grows UTF-16 buffer so it has at least 'length' WCHAR chars free on return */
857static void readerinput_grow(xmlreaderinput *readerinput, int length)
858{
859 encoded_buffer *buffer = &readerinput->buffer->utf16;
860
861 length *= sizeof(WCHAR);
862 /* grow if needed, plus 4 bytes to be sure null terminator will fit in */
863 if (buffer->allocated < buffer->written + length + 4)
864 {
865 int grown_size = max(2*buffer->allocated, buffer->allocated + length);
866 buffer->data = readerinput_realloc(readerinput, buffer->data, grown_size);
867 buffer->allocated = grown_size;
868 }
869}
870
871static inline BOOL readerinput_is_utf8(xmlreaderinput *readerinput)
872{
873 static const char startA[] = {'<','?'};
874 static const char commentA[] = {'<','!'};
875 encoded_buffer *buffer = &readerinput->buffer->encoded;
876 unsigned char *ptr = (unsigned char*)buffer->data;
877
878 return !memcmp(buffer->data, startA, sizeof(startA)) ||
879 !memcmp(buffer->data, commentA, sizeof(commentA)) ||
880 /* test start byte */
881 (ptr[0] == '<' &&
882 (
883 (ptr[1] && (ptr[1] <= 0x7f)) ||
884 (buffer->data[1] >> 5) == 0x6 || /* 2 bytes */
885 (buffer->data[1] >> 4) == 0xe || /* 3 bytes */
886 (buffer->data[1] >> 3) == 0x1e) /* 4 bytes */
887 );
888}
889
891{
892 encoded_buffer *buffer = &readerinput->buffer->encoded;
893 static const char utf8bom[] = {0xef,0xbb,0xbf};
894 static const char utf16lebom[] = {0xff,0xfe};
895 WCHAR *ptrW;
896
897 *enc = XmlEncoding_Unknown;
898
899 if (buffer->written <= 3)
900 {
901 HRESULT hr = readerinput_growraw(readerinput);
902 if (FAILED(hr)) return hr;
903 if (buffer->written < 3) return MX_E_INPUTEND;
904 }
905
906 ptrW = (WCHAR *)buffer->data;
907 /* try start symbols if we have enough data to do that, input buffer should contain
908 first chunk already */
909 if (readerinput_is_utf8(readerinput))
910 *enc = XmlEncoding_UTF8;
911 else if (*ptrW == '<')
912 {
913 ptrW++;
914 if (*ptrW == '?' || *ptrW == '!' || is_namestartchar(*ptrW))
915 *enc = XmlEncoding_UTF16;
916 }
917 /* try with BOM now */
918 else if (!memcmp(buffer->data, utf8bom, sizeof(utf8bom)))
919 {
920 buffer->cur += sizeof(utf8bom);
921 *enc = XmlEncoding_UTF8;
922 }
923 else if (!memcmp(buffer->data, utf16lebom, sizeof(utf16lebom)))
924 {
925 buffer->cur += sizeof(utf16lebom);
926 *enc = XmlEncoding_UTF16;
927 }
928
929 return S_OK;
930}
931
933{
934 encoded_buffer *buffer = &readerinput->buffer->encoded;
935 int len = buffer->written;
936
937 assert(len);
938
939 /* complete single byte char */
940 if (!(buffer->data[len-1] & 0x80)) return len;
941
942 /* find start byte of multibyte char */
943 while (--len && !(buffer->data[len] & 0xc0))
944 ;
945
946 return len;
947}
948
949/* Returns byte length of complete char sequence for buffer code page,
950 it's relative to current buffer position which is currently used for BOM handling
951 only. */
953{
954 encoded_buffer *buffer = &readerinput->buffer->encoded;
955 int len;
956
957 if (readerinput->buffer->code_page == CP_UTF8)
958 len = readerinput_get_utf8_convlen(readerinput);
959 else
960 len = buffer->written;
961
962 TRACE("%d\n", len - buffer->cur);
963 return len - buffer->cur;
964}
965
966/* It's possible that raw buffer has some leftovers from last conversion - some char
967 sequence that doesn't represent a full code point. Length argument should be calculated with
968 readerinput_get_convlen(), if it's -1 it will be calculated here. */
969static void readerinput_shrinkraw(xmlreaderinput *readerinput, int len)
970{
971 encoded_buffer *buffer = &readerinput->buffer->encoded;
972
973 if (len == -1)
974 len = readerinput_get_convlen(readerinput);
975
976 assert(len >= 0);
977 memmove(buffer->data, buffer->data + buffer->cur + (buffer->written - len), len);
978 /* everything below cur is lost too */
979 buffer->written -= len + buffer->cur;
980 /* after this point we don't need cur offset really,
981 it's used only to mark where actual data begins when first chunk is read */
982 buffer->cur = 0;
983}
984
986{
987 BOOL prev_cr = buffer->prev_cr;
988 const WCHAR *src;
989 WCHAR *dest;
990
991 src = dest = (WCHAR*)buffer->data + off;
992 while ((const char*)src < buffer->data + buffer->written)
993 {
994 if (*src == '\r')
995 {
996 *dest++ = '\n';
997 src++;
998 prev_cr = TRUE;
999 continue;
1000 }
1001 if(prev_cr && *src == '\n')
1002 src++;
1003 else
1004 *dest++ = *src++;
1005 prev_cr = FALSE;
1006 }
1007
1008 buffer->written = (char*)dest - buffer->data;
1009 buffer->prev_cr = prev_cr;
1010 *dest = 0;
1011}
1012
1013/* note that raw buffer content is kept */
1015{
1016 encoded_buffer *src = &readerinput->buffer->encoded;
1017 encoded_buffer *dest = &readerinput->buffer->utf16;
1018 int len, dest_len;
1019 UINT cp = ~0u;
1020 HRESULT hr;
1021 WCHAR *ptr;
1022
1023 hr = get_code_page(enc, &cp);
1024 if (FAILED(hr)) return;
1025
1026 readerinput->buffer->code_page = cp;
1027 len = readerinput_get_convlen(readerinput);
1028
1029 TRACE("switching to cp %d\n", cp);
1030
1031 /* just copy in this case */
1032 if (enc == XmlEncoding_UTF16)
1033 {
1034 readerinput_grow(readerinput, len);
1035 memcpy(dest->data, src->data + src->cur, len);
1036 dest->written += len;
1037 }
1038 else
1039 {
1040 dest_len = MultiByteToWideChar(cp, 0, src->data + src->cur, len, NULL, 0);
1041 readerinput_grow(readerinput, dest_len);
1042 ptr = (WCHAR*)dest->data;
1043 MultiByteToWideChar(cp, 0, src->data + src->cur, len, ptr, dest_len);
1044 ptr[dest_len] = 0;
1045 dest->written += dest_len*sizeof(WCHAR);
1046 }
1047
1049}
1050
1051/* shrinks parsed data a buffer begins with */
1053{
1054 encoded_buffer *buffer = &reader->input->buffer->utf16;
1055
1056 /* avoid to move too often using threshold shrink length */
1057 if (buffer->cur*sizeof(WCHAR) > buffer->written / 2)
1058 {
1059 buffer->written -= buffer->cur*sizeof(WCHAR);
1060 memmove(buffer->data, (WCHAR*)buffer->data + buffer->cur, buffer->written);
1061 buffer->cur = 0;
1062 *(WCHAR*)&buffer->data[buffer->written] = 0;
1063 }
1064}
1065
1066/* This is a normal way for reader to get new data converted from raw buffer to utf16 buffer.
1067 It won't attempt to shrink but will grow destination buffer if needed */
1069{
1070 xmlreaderinput *readerinput = reader->input;
1071 encoded_buffer *src = &readerinput->buffer->encoded;
1072 encoded_buffer *dest = &readerinput->buffer->utf16;
1073 UINT cp = readerinput->buffer->code_page;
1074 int len, dest_len, prev_len;
1075 HRESULT hr;
1076 WCHAR *ptr;
1077
1078 /* get some raw data from stream first */
1079 if (FAILED(hr = readerinput_growraw(readerinput)))
1080 return hr;
1081
1082 len = readerinput_get_convlen(readerinput);
1083 prev_len = dest->written / sizeof(WCHAR);
1084
1085 /* just copy for UTF-16 case */
1086 if (cp == 1200)
1087 {
1088 readerinput_grow(readerinput, len);
1089 memcpy(dest->data + dest->written, src->data + src->cur, len);
1090 dest->written += len;
1091 }
1092 else
1093 {
1094 dest_len = MultiByteToWideChar(cp, 0, src->data + src->cur, len, NULL, 0);
1095 readerinput_grow(readerinput, dest_len);
1096 ptr = (WCHAR*)(dest->data + dest->written);
1097 MultiByteToWideChar(cp, 0, src->data + src->cur, len, ptr, dest_len);
1098 ptr[dest_len] = 0;
1099 dest->written += dest_len*sizeof(WCHAR);
1100 /* get rid of processed data */
1101 readerinput_shrinkraw(readerinput, len);
1102 }
1103
1104 fixup_buffer_cr(dest, prev_len);
1105 return hr;
1106}
1107
1109{
1110 return reader->input->buffer->utf16.cur;
1111}
1112
1114{
1115 encoded_buffer *buffer = &reader->input->buffer->utf16;
1116 WCHAR *ptr = (WCHAR*)buffer->data + buffer->cur;
1117 if (!*ptr) reader_more(reader);
1118 return (WCHAR*)buffer->data + buffer->cur;
1119}
1120
1122{
1123 int i=0;
1124 const WCHAR *ptr = reader_get_ptr(reader);
1125 while (str[i])
1126 {
1127 if (!ptr[i])
1128 {
1131 }
1132 if (str[i] != ptr[i])
1133 return ptr[i] - str[i];
1134 i++;
1135 }
1136 return 0;
1137}
1138
1140{
1141 if (ch == '\r')
1142 reader->position.line_position = 1;
1143 else if (ch == '\n')
1144 {
1145 reader->position.line_number++;
1146 reader->position.line_position = 1;
1147 }
1148 else
1149 reader->position.line_position++;
1150}
1151
1152/* moves cursor n WCHARs forward */
1153static void reader_skipn(xmlreader *reader, int n)
1154{
1155 encoded_buffer *buffer = &reader->input->buffer->utf16;
1156 const WCHAR *ptr;
1157
1158 while (*(ptr = reader_get_ptr(reader)) && n--)
1159 {
1161 buffer->cur++;
1162 }
1163}
1164
1165/* [3] S ::= (#x20 | #x9 | #xD | #xA)+ */
1167{
1168 const WCHAR *ptr = reader_get_ptr(reader);
1170
1171 while (is_wchar_space(*ptr))
1172 {
1173 reader_skipn(reader, 1);
1175 }
1176
1177 return reader_get_cur(reader) - start;
1178}
1179
1180/* [26] VersionNum ::= '1.' [0-9]+ */
1182{
1183 WCHAR *ptr, *ptr2;
1184 UINT start;
1185
1186 if (reader_cmp(reader, L"1.")) return WC_E_XMLDECL;
1187
1189 /* skip "1." */
1190 reader_skipn(reader, 2);
1191
1192 ptr2 = ptr = reader_get_ptr(reader);
1193 while (*ptr >= '0' && *ptr <= '9')
1194 {
1195 reader_skipn(reader, 1);
1197 }
1198
1199 if (ptr2 == ptr) return WC_E_DIGIT;
1201 TRACE("version=%s\n", debug_strval(reader, val));
1202 return S_OK;
1203}
1204
1205/* [25] Eq ::= S? '=' S? */
1207{
1209 if (reader_cmp(reader, L"=")) return WC_E_EQUAL;
1210 /* skip '=' */
1211 reader_skipn(reader, 1);
1213 return S_OK;
1214}
1215
1217{
1218 return !reader_cmp(reader, L"\'") || !reader_cmp(reader, L"\"");
1219}
1220
1221/* [24] VersionInfo ::= S 'version' Eq ("'" VersionNum "'" | '"' VersionNum '"') */
1223{
1224 struct reader_position position;
1225 strval val, name;
1226 HRESULT hr;
1227
1229
1230 position = reader->position;
1231 if (reader_cmp(reader, L"version")) return WC_E_XMLDECL;
1233 /* skip 'version' */
1234 reader_skipn(reader, 7);
1235
1237 if (FAILED(hr)) return hr;
1238
1239 if (!reader_is_quote(reader))
1240 return WC_E_QUOTE;
1241 /* skip "'"|'"' */
1242 reader_skipn(reader, 1);
1243
1245 if (FAILED(hr)) return hr;
1246
1247 if (!reader_is_quote(reader))
1248 return WC_E_QUOTE;
1249
1250 /* skip "'"|'"' */
1251 reader_skipn(reader, 1);
1252
1253 return reader_add_attr(reader, NULL, &name, NULL, &val, &position, 0);
1254}
1255
1256/* ([A-Za-z0-9._] | '-') */
1258{
1259 return ((ch >= 'A' && ch <= 'Z') ||
1260 (ch >= 'a' && ch <= 'z') ||
1261 (ch >= '0' && ch <= '9') ||
1262 (ch == '.') || (ch == '_') ||
1263 (ch == '-'));
1264}
1265
1266/* [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')* */
1268{
1270 xml_encoding enc;
1271 int len;
1272
1273 if ((*start < 'A' || *start > 'Z') && (*start < 'a' || *start > 'z'))
1274 return WC_E_ENCNAME;
1275
1276 val->start = reader_get_cur(reader);
1277
1278 ptr = start;
1279 while (is_wchar_encname(*++ptr))
1280 ;
1281
1282 len = ptr - start;
1284 TRACE("encoding name %s\n", debugstr_wn(start, len));
1285 val->str = start;
1286 val->len = len;
1287
1288 if (enc == XmlEncoding_Unknown)
1289 return WC_E_ENCNAME;
1290
1291 /* skip encoding name */
1293 return S_OK;
1294}
1295
1296/* [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' | "'" EncName "'" ) */
1298{
1299 struct reader_position position;
1300 strval name, val;
1301 HRESULT hr;
1302
1303 if (!(*spaces = reader_skipspaces(reader))) return S_FALSE;
1304
1305 position = reader->position;
1306 if (reader_cmp(reader, L"encoding")) return S_FALSE;
1307 name.str = reader_get_ptr(reader);
1308 name.start = reader_get_cur(reader);
1309 name.len = 8;
1310 /* skip 'encoding' */
1311 reader_skipn(reader, 8);
1312
1314 if (FAILED(hr)) return hr;
1315
1316 if (!reader_is_quote(reader))
1317 return WC_E_QUOTE;
1318 /* skip "'"|'"' */
1319 reader_skipn(reader, 1);
1320
1322 if (FAILED(hr)) return hr;
1323
1324 if (!reader_is_quote(reader))
1325 return WC_E_QUOTE;
1326
1327 /* skip "'"|'"' */
1328 reader_skipn(reader, 1);
1329 *spaces = FALSE;
1330
1331 return reader_add_attr(reader, NULL, &name, NULL, &val, &position, 0);
1332}
1333
1334/* [32] SDDecl ::= S 'standalone' Eq (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no') '"')) */
1336{
1337 struct reader_position position;
1338 strval name, val;
1339 UINT start;
1340 HRESULT hr;
1341
1342 if (!spaces && !reader_skipspaces(reader)) return S_FALSE;
1343
1344 position = reader->position;
1345 if (reader_cmp(reader, L"standalone")) return S_FALSE;
1347 /* skip 'standalone' */
1348 reader_skipn(reader, 10);
1349
1351 if (FAILED(hr)) return hr;
1352
1353 if (!reader_is_quote(reader))
1354 return WC_E_QUOTE;
1355 /* skip "'"|'"' */
1356 reader_skipn(reader, 1);
1357
1358 if (reader_cmp(reader, L"yes") && reader_cmp(reader, L"no"))
1359 return WC_E_XMLDECL;
1360
1362 /* skip 'yes'|'no' */
1363 reader_skipn(reader, reader_cmp(reader, L"yes") ? 2 : 3);
1365 TRACE("standalone=%s\n", debug_strval(reader, &val));
1366
1367 if (!reader_is_quote(reader))
1368 return WC_E_QUOTE;
1369 /* skip "'"|'"' */
1370 reader_skipn(reader, 1);
1371
1372 return reader_add_attr(reader, NULL, &name, NULL, &val, &position, 0);
1373}
1374
1375/* [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>' */
1377{
1378 struct reader_position position;
1379 BOOL spaces;
1380 HRESULT hr;
1381
1382 if (reader_cmp(reader, L"<?xml "))
1383 return S_FALSE;
1384
1385 reader_skipn(reader, 2);
1386 position = reader->position;
1387 reader_skipn(reader, 3);
1389 if (FAILED(hr))
1390 return hr;
1391
1392 if (FAILED(hr = reader_parse_encdecl(reader, &spaces)))
1393 return hr;
1394
1395 if (FAILED(hr = reader_parse_sddecl(reader, spaces)))
1396 return hr;
1397
1399 if (reader_cmp(reader, L"?>"))
1400 return WC_E_XMLDECL;
1401
1402 /* skip '?>' */
1403 reader_skipn(reader, 2);
1404
1406 reader->empty_element.position = position;
1409
1410 return S_OK;
1411}
1412
1413/* [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->' */
1415{
1416 WCHAR *ptr;
1417 UINT start;
1418
1419 if (reader->resumestate == XmlReadResumeState_Comment)
1420 {
1421 start = reader->resume[XmlReadResume_Body];
1423 }
1424 else
1425 {
1426 /* skip '<!--' */
1427 reader_skipn(reader, 4);
1431 reader->nodetype = XmlNodeType_Comment;
1432 reader->resume[XmlReadResume_Body] = start;
1433 reader->resumestate = XmlReadResumeState_Comment;
1435 }
1436
1437 /* will exit when there's no more data, it won't attempt to
1438 read more from stream */
1439 while (*ptr)
1440 {
1441 if (ptr[0] == '-')
1442 {
1443 if (ptr[1] == '-')
1444 {
1445 if (ptr[2] == '>')
1446 {
1447 strval value;
1448
1450 TRACE("%s\n", debug_strval(reader, &value));
1451
1452 /* skip rest of markup '->' */
1453 reader_skipn(reader, 3);
1454
1456 reader->resume[XmlReadResume_Body] = 0;
1457 reader->resumestate = XmlReadResumeState_Initial;
1458 return S_OK;
1459 }
1460 else
1461 return WC_E_COMMENT;
1462 }
1463 }
1464
1465 reader_skipn(reader, 1);
1466 ptr++;
1467 }
1468
1469 return S_OK;
1470}
1471
1472/* [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%] */
1474{
1475 return (ch == ' ') ||
1476 (ch >= 'a' && ch <= 'z') ||
1477 (ch >= 'A' && ch <= 'Z') ||
1478 (ch >= '0' && ch <= '9') ||
1479 (ch >= '-' && ch <= ';') || /* '()*+,-./:; */
1480 (ch == '=') || (ch == '?') ||
1481 (ch == '@') || (ch == '!') ||
1482 (ch >= '#' && ch <= '%') || /* #$% */
1483 (ch == '_') || (ch == '\r') || (ch == '\n');
1484}
1485
1487{
1488 return (ch == ':') || (ch >= 'A' && ch <= 'Z') ||
1489 (ch == '_') || (ch >= 'a' && ch <= 'z') ||
1490 (ch >= 0xc0 && ch <= 0xd6) ||
1491 (ch >= 0xd8 && ch <= 0xf6) ||
1492 (ch >= 0xf8 && ch <= 0x2ff) ||
1493 (ch >= 0x370 && ch <= 0x37d) ||
1494 (ch >= 0x37f && ch <= 0x1fff) ||
1495 (ch >= 0x200c && ch <= 0x200d) ||
1496 (ch >= 0x2070 && ch <= 0x218f) ||
1497 (ch >= 0x2c00 && ch <= 0x2fef) ||
1498 (ch >= 0x3001 && ch <= 0xd7ff) ||
1499 (ch >= 0xd800 && ch <= 0xdbff) || /* high surrogate */
1500 (ch >= 0xdc00 && ch <= 0xdfff) || /* low surrogate */
1501 (ch >= 0xf900 && ch <= 0xfdcf) ||
1502 (ch >= 0xfdf0 && ch <= 0xfffd);
1503}
1504
1505/* [4 NS] NCName ::= Name - (Char* ':' Char*) */
1507{
1508 return (ch >= 'A' && ch <= 'Z') ||
1509 (ch == '_') || (ch >= 'a' && ch <= 'z') ||
1510 (ch == '-') || (ch == '.') ||
1511 (ch >= '0' && ch <= '9') ||
1512 (ch == 0xb7) ||
1513 (ch >= 0xc0 && ch <= 0xd6) ||
1514 (ch >= 0xd8 && ch <= 0xf6) ||
1515 (ch >= 0xf8 && ch <= 0x2ff) ||
1516 (ch >= 0x300 && ch <= 0x36f) ||
1517 (ch >= 0x370 && ch <= 0x37d) ||
1518 (ch >= 0x37f && ch <= 0x1fff) ||
1519 (ch >= 0x200c && ch <= 0x200d) ||
1520 (ch >= 0x203f && ch <= 0x2040) ||
1521 (ch >= 0x2070 && ch <= 0x218f) ||
1522 (ch >= 0x2c00 && ch <= 0x2fef) ||
1523 (ch >= 0x3001 && ch <= 0xd7ff) ||
1524 (ch >= 0xd800 && ch <= 0xdbff) || /* high surrogate */
1525 (ch >= 0xdc00 && ch <= 0xdfff) || /* low surrogate */
1526 (ch >= 0xf900 && ch <= 0xfdcf) ||
1527 (ch >= 0xfdf0 && ch <= 0xfffd);
1528}
1529
1531{
1532 return (ch == ':') || is_ncnamechar(ch);
1533}
1534
1536{
1537 /* When we're on attribute always return attribute type, container node type is kept.
1538 Note that container is not necessarily an element, and attribute doesn't mean it's
1539 an attribute in XML spec terms. */
1540 return reader->attr ? XmlNodeType_Attribute : reader->nodetype;
1541}
1542
1543/* [4] NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] |
1544 [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] |
1545 [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
1546 [4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
1547 [5] Name ::= NameStartChar (NameChar)* */
1549{
1550 WCHAR *ptr;
1551 UINT start;
1552
1553 if (reader->resume[XmlReadResume_Name])
1554 {
1555 start = reader->resume[XmlReadResume_Name];
1557 }
1558 else
1559 {
1563 }
1564
1565 while (is_namechar(*ptr))
1566 {
1567 reader_skipn(reader, 1);
1569 }
1570
1572 {
1573 reader->resume[XmlReadResume_Name] = start;
1574 return E_PENDING;
1575 }
1576 else
1577 reader->resume[XmlReadResume_Name] = 0;
1578
1580 TRACE("name %s:%d\n", debug_strval(reader, name), name->len);
1581
1582 return S_OK;
1583}
1584
1585/* [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l')) */
1587{
1588 static const strval xmlval = { (WCHAR *)L"xml", 3 };
1589 strval name;
1590 WCHAR *ptr;
1591 HRESULT hr;
1592 UINT i;
1593
1596
1597 /* now that we got name check for illegal content */
1598 if (strval_eq(reader, &name, &xmlval))
1599 return WC_E_LEADINGXML;
1600
1601 /* PITarget can't be a qualified name */
1603 for (i = 0; i < name.len; i++)
1604 if (ptr[i] == ':')
1605 return i ? NC_E_NAMECOLON : WC_E_PI;
1606
1607 TRACE("pitarget %s:%d\n", debug_strval(reader, &name), name.len);
1608 *target = name;
1609 return S_OK;
1610}
1611
1612/* [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>' */
1614{
1615 strval target;
1616 WCHAR *ptr;
1617 UINT start;
1618 HRESULT hr;
1619
1620 switch (reader->resumestate)
1621 {
1623 /* skip '<?' */
1624 reader_skipn(reader, 2);
1626 reader->resumestate = XmlReadResumeState_PITarget;
1629 if (FAILED(hr)) return hr;
1633 reader->resumestate = XmlReadResumeState_PIBody;
1635 default:
1636 ;
1637 }
1638
1639 start = reader->resume[XmlReadResume_Body];
1641 while (*ptr)
1642 {
1643 if (ptr[0] == '?')
1644 {
1645 if (ptr[1] == '>')
1646 {
1648 strval value;
1649
1650 /* strip all leading whitespace chars */
1651 while (start < cur)
1652 {
1654 if (!is_wchar_space(*ptr)) break;
1655 start++;
1656 }
1657
1659
1660 /* skip '?>' */
1661 reader_skipn(reader, 2);
1662 TRACE("%s\n", debug_strval(reader, &value));
1664 reader->resumestate = XmlReadResumeState_Initial;
1665 reader->resume[XmlReadResume_Body] = 0;
1667 return S_OK;
1668 }
1669 }
1670
1671 reader_skipn(reader, 1);
1673 }
1674
1675 return S_OK;
1676}
1677
1678/* This one is used to parse significant whitespace nodes, like in Misc production */
1680{
1681 switch (reader->resumestate)
1682 {
1687 reader->nodetype = XmlNodeType_Whitespace;
1691 /* fallthrough */
1693 {
1694 strval value;
1695 UINT start;
1696
1698 if (is_reader_pending(reader)) return S_OK;
1699
1700 start = reader->resume[XmlReadResume_Body];
1703 TRACE("%s\n", debug_strval(reader, &value));
1704 reader->resumestate = XmlReadResumeState_Initial;
1705 }
1706 default:
1707 ;
1708 }
1709
1710 return S_OK;
1711}
1712
1713/* [27] Misc ::= Comment | PI | S */
1715{
1716 HRESULT hr = S_FALSE;
1717
1718 if (reader->resumestate != XmlReadResumeState_Initial)
1719 {
1721 if (FAILED(hr)) return hr;
1722
1723 /* finish current node */
1724 switch (reader->resumestate)
1725 {
1728 return reader_parse_pi(reader);
1733 default:
1734 ERR("unknown resume state %d\n", reader->resumestate);
1735 }
1736 }
1737
1738 while (1)
1739 {
1740 const WCHAR *cur = reader_get_ptr(reader);
1741
1742 if (is_wchar_space(*cur))
1744 else if (!reader_cmp(reader, L"<!--"))
1746 else if (!reader_cmp(reader, L"<?"))
1748 else
1749 break;
1750
1751 if (hr != S_FALSE) return hr;
1752 }
1753
1754 return hr;
1755}
1756
1757/* [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'") */
1759{
1761 UINT start;
1762
1763 if (*cur != '"' && *cur != '\'') return WC_E_QUOTE;
1764
1765 quote = *cur;
1766 reader_skipn(reader, 1);
1767
1770 while (is_char(*cur) && *cur != quote)
1771 {
1772 reader_skipn(reader, 1);
1774 }
1776 if (*cur == quote) reader_skipn(reader, 1);
1777
1778 TRACE("%s\n", debug_strval(reader, literal));
1779 return S_OK;
1780}
1781
1782/* [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
1783 [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%] */
1785{
1787 UINT start;
1788
1789 if (*cur != '"' && *cur != '\'') return WC_E_QUOTE;
1790
1791 quote = *cur;
1792 reader_skipn(reader, 1);
1793
1796 while (is_pubchar(*cur) && *cur != quote)
1797 {
1798 reader_skipn(reader, 1);
1800 }
1802 if (*cur == quote) reader_skipn(reader, 1);
1803
1804 TRACE("%s\n", debug_strval(reader, literal));
1805 return S_OK;
1806}
1807
1808/* [75] ExternalID ::= 'SYSTEM' S SystemLiteral | 'PUBLIC' S PubidLiteral S SystemLiteral */
1810{
1811 static WCHAR systemW[] = L"SYSTEM";
1812 static WCHAR publicW[] = L"PUBLIC";
1813 struct reader_position position = reader->position;
1814 strval name, sys;
1815 HRESULT hr;
1816 int cnt;
1817
1818 if (!reader_cmp(reader, publicW)) {
1819 strval pub;
1820
1821 /* public id */
1822 reader_skipn(reader, 6);
1824 if (!cnt) return WC_E_WHITESPACE;
1825
1827 if (FAILED(hr)) return hr;
1828
1830 hr = reader_add_attr(reader, NULL, &name, NULL, &pub, &position, 0);
1831 if (FAILED(hr)) return hr;
1832
1834 if (!cnt) return S_OK;
1835
1836 /* optional system id */
1838 if (FAILED(hr)) return S_OK;
1839
1841 hr = reader_add_attr(reader, NULL, &name, NULL, &sys, &position, 0);
1842 if (FAILED(hr)) return hr;
1843
1844 return S_OK;
1845 } else if (!reader_cmp(reader, systemW)) {
1846 /* system id */
1847 reader_skipn(reader, 6);
1849 if (!cnt) return WC_E_WHITESPACE;
1850
1852 if (FAILED(hr)) return hr;
1853
1855 return reader_add_attr(reader, NULL, &name, NULL, &sys, &position, 0);
1856 }
1857
1858 return S_FALSE;
1859}
1860
1861/* [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S? ('[' intSubset ']' S?)? '>' */
1863{
1864 strval name;
1865 WCHAR *cur;
1866 HRESULT hr;
1867
1868 if (reader_cmp(reader, L"<!DOCTYPE")) return S_FALSE;
1870
1871 /* DTD processing is not allowed by default */
1872 if (reader->dtdmode == DtdProcessing_Prohibit) return WC_E_DTDPROHIBITED;
1873
1874 reader_skipn(reader, 9);
1876
1877 /* name */
1879 if (FAILED(hr)) return WC_E_DECLDOCTYPE;
1880
1882
1884 if (FAILED(hr)) return hr;
1885
1887
1889 if (*cur != '>')
1890 {
1891 FIXME("internal subset parsing not implemented\n");
1892 return E_NOTIMPL;
1893 }
1894
1895 /* skip '>' */
1896 reader_skipn(reader, 1);
1897
1898 reader->nodetype = XmlNodeType_DocumentType;
1901
1902 return S_OK;
1903}
1904
1905/* [11 NS] LocalPart ::= NCName */
1907{
1908 WCHAR *ptr;
1909 UINT start;
1910
1911 if (reader->resume[XmlReadResume_Local])
1912 {
1913 start = reader->resume[XmlReadResume_Local];
1915 }
1916 else
1917 {
1920 }
1921
1922 while (is_ncnamechar(*ptr))
1923 {
1924 reader_skipn(reader, 1);
1926 }
1927
1928 if (check_for_separator && *ptr == ':')
1929 return NC_E_QNAMECOLON;
1930
1932 {
1933 reader->resume[XmlReadResume_Local] = start;
1934 return E_PENDING;
1935 }
1936 else
1937 reader->resume[XmlReadResume_Local] = 0;
1938
1940
1941 return S_OK;
1942}
1943
1944/* [7 NS] QName ::= PrefixedName | UnprefixedName
1945 [8 NS] PrefixedName ::= Prefix ':' LocalPart
1946 [9 NS] UnprefixedName ::= LocalPart
1947 [10 NS] Prefix ::= NCName */
1949{
1950 WCHAR *ptr;
1951 UINT start;
1952 HRESULT hr;
1953
1954 if (reader->resume[XmlReadResume_Name])
1955 {
1956 start = reader->resume[XmlReadResume_Name];
1958 }
1959 else
1960 {
1963 reader->resume[XmlReadResume_Name] = start;
1964 if (!is_ncnamechar(*ptr)) return NC_E_QNAMECHARACTER;
1965 }
1966
1967 if (reader->resume[XmlReadResume_Local])
1968 {
1970 if (FAILED(hr)) return hr;
1971
1973 local->start - reader->resume[XmlReadResume_Name] - 1,
1974 prefix);
1975 }
1976 else
1977 {
1978 /* skip prefix part */
1979 while (is_ncnamechar(*ptr))
1980 {
1981 reader_skipn(reader, 1);
1983 }
1984
1985 if (is_reader_pending(reader)) return E_PENDING;
1986
1987 /* got a qualified name */
1988 if (*ptr == ':')
1989 {
1991
1992 /* skip ':' */
1993 reader_skipn(reader, 1);
1995 if (FAILED(hr)) return hr;
1996 }
1997 else
1998 {
2001 }
2002 }
2003
2004 if (prefix->len)
2005 TRACE("qname %s:%s\n", debug_strval(reader, prefix), debug_strval(reader, local));
2006 else
2007 TRACE("ncname %s\n", debug_strval(reader, local));
2008
2009 reader_init_strvalue(prefix->len ? prefix->start : local->start,
2010 /* count ':' too */
2011 (prefix->len ? prefix->len + 1 : 0) + local->len,
2012 qname);
2013
2014 reader->resume[XmlReadResume_Name] = 0;
2015 reader->resume[XmlReadResume_Local] = 0;
2016
2017 return S_OK;
2018}
2019
2021{
2022 static const strval lt = { (WCHAR *)L"lt", 2 };
2023 static const strval gt = { (WCHAR *)L"gt", 2 };
2024 static const strval amp = { (WCHAR *)L"amp", 3 };
2025 static const strval apos = { (WCHAR *)L"apos", 4 };
2026 static const strval quot = { (WCHAR *)L"quot", 4 };
2028
2029 switch (*str)
2030 {
2031 case 'l':
2032 if (strval_eq(reader, name, &lt)) return '<';
2033 break;
2034 case 'g':
2035 if (strval_eq(reader, name, &gt)) return '>';
2036 break;
2037 case 'a':
2038 if (strval_eq(reader, name, &amp))
2039 return '&';
2040 else if (strval_eq(reader, name, &apos))
2041 return '\'';
2042 break;
2043 case 'q':
2044 if (strval_eq(reader, name, &quot)) return '\"';
2045 break;
2046 default:
2047 ;
2048 }
2049
2050 return 0;
2051}
2052
2053/* [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'
2054 [67] Reference ::= EntityRef | CharRef
2055 [68] EntityRef ::= '&' Name ';' */
2057{
2058 encoded_buffer *buffer = &reader->input->buffer->utf16;
2061 WCHAR ch = 0;
2062 int len;
2063
2064 /* skip '&' */
2065 reader_skipn(reader, 1);
2067
2068 if (*ptr == '#')
2069 {
2070 reader_skipn(reader, 1);
2072
2073 /* hex char or decimal */
2074 if (*ptr == 'x')
2075 {
2076 reader_skipn(reader, 1);
2078
2079 while (*ptr != ';')
2080 {
2081 if ((*ptr >= '0' && *ptr <= '9'))
2082 ch = ch*16 + *ptr - '0';
2083 else if ((*ptr >= 'a' && *ptr <= 'f'))
2084 ch = ch*16 + *ptr - 'a' + 10;
2085 else if ((*ptr >= 'A' && *ptr <= 'F'))
2086 ch = ch*16 + *ptr - 'A' + 10;
2087 else
2088 return ch ? WC_E_SEMICOLON : WC_E_HEXDIGIT;
2089 reader_skipn(reader, 1);
2091 }
2092 }
2093 else
2094 {
2095 while (*ptr != ';')
2096 {
2097 if ((*ptr >= '0' && *ptr <= '9'))
2098 {
2099 ch = ch*10 + *ptr - '0';
2100 reader_skipn(reader, 1);
2102 }
2103 else
2104 return ch ? WC_E_SEMICOLON : WC_E_DIGIT;
2105 }
2106 }
2107
2108 if (!is_char(ch)) return WC_E_XMLCHARACTER;
2109
2110 /* normalize */
2111 if (is_wchar_space(ch)) ch = ' ';
2112
2115 len = buffer->written - ((char *)ptr - buffer->data);
2116 memmove(start + 1, ptr + 1, len);
2117
2118 buffer->written -= (reader_get_cur(reader) - cur) * sizeof(WCHAR);
2119 *(WCHAR*)(buffer->data + buffer->written) = 0;
2120 buffer->cur = cur + 1;
2121
2122 *start = ch;
2123 }
2124 else
2125 {
2126 strval name;
2127 HRESULT hr;
2128
2130 if (FAILED(hr)) return hr;
2131
2133 if (*ptr != ';') return WC_E_SEMICOLON;
2134
2135 /* predefined entities resolve to a single character */
2137 if (ch)
2138 {
2139 len = buffer->written - ((char*)ptr - buffer->data) - sizeof(WCHAR);
2140 memmove(start+1, ptr+1, len);
2141 buffer->cur = cur + 1;
2142 buffer->written -= (ptr - start) * sizeof(WCHAR);
2143 *(WCHAR*)(buffer->data + buffer->written) = 0;
2144
2145 *start = ch;
2146 }
2147 else
2148 {
2149 FIXME("undeclared entity %s\n", debug_strval(reader, &name));
2150 return WC_E_UNDECLAREDENTITY;
2151 }
2152
2153 }
2154
2155 return S_OK;
2156}
2157
2158/* [10 NS] AttValue ::= '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'" */
2160{
2161 WCHAR *ptr, quote;
2162 UINT start;
2163
2165
2166 /* skip opening quote */
2167 quote = *ptr;
2168 if (quote != '\"' && quote != '\'') return WC_E_QUOTE;
2169 reader_skipn(reader, 1);
2170
2173 while (*ptr)
2174 {
2175 if (*ptr == '<') return WC_E_LESSTHAN;
2176
2177 if (*ptr == quote)
2178 {
2180 /* skip closing quote */
2181 reader_skipn(reader, 1);
2182 return S_OK;
2183 }
2184
2185 if (*ptr == '&')
2186 {
2188 if (FAILED(hr)) return hr;
2189 }
2190 else
2191 {
2192 /* replace all whitespace chars with ' ' */
2193 if (is_wchar_space(*ptr)) *ptr = ' ';
2194 reader_skipn(reader, 1);
2195 }
2197 }
2198
2199 return WC_E_QUOTE;
2200}
2201
2202/* [1 NS] NSAttName ::= PrefixedAttName | DefaultAttName
2203 [2 NS] PrefixedAttName ::= 'xmlns:' NCName
2204 [3 NS] DefaultAttName ::= 'xmlns'
2205 [15 NS] Attribute ::= NSAttName Eq AttValue | QName Eq AttValue */
2207{
2208 struct reader_position position = reader->position;
2209 strval prefix, local, qname, value;
2210 enum attribute_flags flags = 0;
2211 HRESULT hr;
2212
2213 hr = reader_parse_qname(reader, &prefix, &local, &qname);
2214 if (FAILED(hr)) return hr;
2215
2218
2219 if (strval_eq(reader, &qname, &strval_xmlns))
2221
2223 if (FAILED(hr)) return hr;
2224
2226 if (FAILED(hr)) return hr;
2227
2230
2232 return reader_add_attr(reader, &prefix, &local, &qname, &value, &position, flags);
2233}
2234
2235/* [12 NS] STag ::= '<' QName (S Attribute)* S? '>'
2236 [14 NS] EmptyElemTag ::= '<' QName (S Attribute)* S? '/>' */
2238{
2239 struct reader_position position = reader->position;
2240 HRESULT hr;
2241
2243 if (FAILED(hr)) return hr;
2244
2245 for (;;)
2246 {
2248
2249 /* empty element */
2250 if ((reader->is_empty_element = !reader_cmp(reader, L"/>")))
2251 {
2252 struct element *element = &reader->empty_element;
2253
2254 /* skip '/>' */
2255 reader_skipn(reader, 2);
2256
2259
2260 element->prefix = *prefix;
2265 return S_OK;
2266 }
2267
2268 /* got a start tag */
2269 if (!reader_cmp(reader, L">"))
2270 {
2271 /* skip '>' */
2272 reader_skipn(reader, 1);
2274 }
2275
2277 if (FAILED(hr)) return hr;
2278 }
2279
2280 return S_OK;
2281}
2282
2283/* [39] element ::= EmptyElemTag | STag content ETag */
2285{
2286 HRESULT hr;
2287
2288 switch (reader->resumestate)
2289 {
2291 /* check if we are really on element */
2292 if (reader_cmp(reader, L"<")) return S_FALSE;
2293
2294 /* skip '<' */
2295 reader_skipn(reader, 1);
2296
2298 reader->resumestate = XmlReadResumeState_STag;
2300 {
2302
2303 /* this handles empty elements too */
2305 if (FAILED(hr)) return hr;
2306
2307 /* FIXME: need to check for defined namespace to reject invalid prefix */
2308
2309 /* if we got empty element and stack is empty go straight to Misc */
2310 if (reader->is_empty_element && list_empty(&reader->elements))
2311 reader->instate = XmlReadInState_MiscEnd;
2312 else
2313 reader->instate = XmlReadInState_Content;
2314
2315 reader->nodetype = XmlNodeType_Element;
2316 reader->resumestate = XmlReadResumeState_Initial;
2320 break;
2321 }
2322 default:
2323 hr = E_FAIL;
2324 }
2325
2326 return hr;
2327}
2328
2329/* [13 NS] ETag ::= '</' QName S? '>' */
2331{
2332 struct reader_position position;
2333 strval prefix, local, qname;
2334 struct element *element;
2335 HRESULT hr;
2336
2337 /* skip '</' */
2338 reader_skipn(reader, 2);
2339
2340 position = reader->position;
2342 if (FAILED(hr)) return hr;
2343
2345
2346 if (reader_cmp(reader, L">")) return WC_E_GREATERTHAN;
2347
2348 /* skip '>' */
2349 reader_skipn(reader, 1);
2350
2351 /* Element stack should never be empty at this point, cause we shouldn't get to
2352 content parsing if it's empty. */
2353 element = LIST_ENTRY(list_head(&reader->elements), struct element, entry);
2355
2356 /* update position stored for start tag, we won't be using it */
2358
2359 reader->nodetype = XmlNodeType_EndElement;
2360 reader->is_empty_element = FALSE;
2362
2363 return S_OK;
2364}
2365
2366/* [18] CDSect ::= CDStart CData CDEnd
2367 [19] CDStart ::= '<![CDATA['
2368 [20] CData ::= (Char* - (Char* ']]>' Char*))
2369 [21] CDEnd ::= ']]>' */
2371{
2372 WCHAR *ptr;
2373 UINT start;
2374
2375 if (reader->resumestate == XmlReadResumeState_CDATA)
2376 {
2377 start = reader->resume[XmlReadResume_Body];
2379 }
2380 else
2381 {
2382 /* skip markup '<![CDATA[' */
2383 reader_skipn(reader, 9);
2387 reader->nodetype = XmlNodeType_CDATA;
2388 reader->resume[XmlReadResume_Body] = start;
2389 reader->resumestate = XmlReadResumeState_CDATA;
2391 }
2392
2393 while (*ptr)
2394 {
2395 if (*ptr == ']' && *(ptr+1) == ']' && *(ptr+2) == '>')
2396 {
2397 strval value;
2398
2400
2401 /* skip ']]>' */
2402 reader_skipn(reader, 3);
2403 TRACE("%s\n", debug_strval(reader, &value));
2404
2406 reader->resume[XmlReadResume_Body] = 0;
2407 reader->resumestate = XmlReadResumeState_Initial;
2408 return S_OK;
2409 }
2410 else
2411 {
2412 reader_skipn(reader, 1);
2414 }
2415 }
2416
2417 return S_OK;
2418}
2419
2420/* [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*) */
2422{
2423 struct reader_position position;
2424 WCHAR *ptr;
2425 UINT start;
2426
2427 if (reader->resumestate == XmlReadResumeState_CharData)
2428 {
2429 start = reader->resume[XmlReadResume_Body];
2431 }
2432 else
2433 {
2437 /* There's no text */
2438 if (!*ptr || *ptr == '<') return S_OK;
2440 reader->resume[XmlReadResume_Body] = start;
2441 reader->resumestate = XmlReadResumeState_CharData;
2443 }
2444
2445 position = reader->position;
2446 while (*ptr)
2447 {
2448 /* CDATA closing sequence ']]>' is not allowed */
2449 if (ptr[0] == ']' && ptr[1] == ']' && ptr[2] == '>')
2450 return WC_E_CDSECTEND;
2451
2452 /* Found next markup part */
2453 if (ptr[0] == '<')
2454 {
2455 strval value;
2456
2457 reader->empty_element.position = position;
2460 reader->resume[XmlReadResume_Body] = 0;
2461 reader->resumestate = XmlReadResumeState_Initial;
2462 return S_OK;
2463 }
2464
2465 /* this covers a case when text has leading whitespace chars */
2466 if (!is_wchar_space(*ptr)) reader->nodetype = XmlNodeType_Text;
2467
2468 if (!reader_cmp(reader, L"&"))
2470 else
2471 reader_skipn(reader, 1);
2472
2474 }
2475
2476 return S_OK;
2477}
2478
2479/* [43] content ::= CharData? ((element | Reference | CDSect | PI | Comment) CharData?)* */
2481{
2482 if (reader->resumestate != XmlReadResumeState_Initial)
2483 {
2484 switch (reader->resumestate)
2485 {
2487 return reader_parse_cdata(reader);
2492 return reader_parse_pi(reader);
2495 default:
2496 ERR("unknown resume state %d\n", reader->resumestate);
2497 }
2498 }
2499
2501
2502 /* handle end tag here, it indicates end of content as well */
2503 if (!reader_cmp(reader, L"</"))
2505
2506 if (!reader_cmp(reader, L"<!--"))
2508
2509 if (!reader_cmp(reader, L"<?"))
2510 return reader_parse_pi(reader);
2511
2512 if (!reader_cmp(reader, L"<![CDATA["))
2513 return reader_parse_cdata(reader);
2514
2515 if (!reader_cmp(reader, L"<"))
2517
2518 /* what's left must be CharData */
2520}
2521
2523{
2525 HRESULT hr;
2526
2528 {
2529 reader->chunk_read_off = 0;
2531 }
2532
2533 /* When moving from EndElement or empty element, pop its own namespace definitions */
2534 switch (nodetype)
2535 {
2538 /* fallthrough */
2540 if (reader->is_empty_element)
2541 reader_pop_ns_nodes(reader, &reader->empty_element);
2542 else if (FAILED(hr = reader_inc_depth(reader)))
2543 return hr;
2544 break;
2548 break;
2549 default:
2550 ;
2551 }
2552
2553 for (;;)
2554 {
2555 switch (reader->instate)
2556 {
2557 /* if it's a first call for a new input we need to detect stream encoding */
2559 {
2560 xml_encoding enc;
2561
2562 hr = readerinput_growraw(reader->input);
2563 if (FAILED(hr)) return hr;
2564
2565 reader->position.line_number = 1;
2566 reader->position.line_position = 1;
2567
2568 /* try to detect encoding by BOM or data and set input code page */
2569 hr = readerinput_detectencoding(reader->input, &enc);
2570 TRACE("detected encoding %s, %#lx.\n", enc == XmlEncoding_Unknown ? "(unknown)" :
2572 if (FAILED(hr)) return hr;
2573
2574 /* always switch first time cause we have to put something in */
2576
2577 /* parse xml declaration */
2579 if (FAILED(hr)) return hr;
2580
2581 readerinput_shrinkraw(reader->input, -1);
2583 if (hr == S_OK) return hr;
2584 }
2585 break;
2588 if (FAILED(hr)) return hr;
2589
2590 if (hr == S_FALSE)
2591 reader->instate = XmlReadInState_DTD;
2592 else
2593 return hr;
2594 break;
2595 case XmlReadInState_DTD:
2597 if (FAILED(hr)) return hr;
2598
2599 if (hr == S_OK)
2600 {
2602 return hr;
2603 }
2604 else
2605 reader->instate = XmlReadInState_Element;
2606 break;
2609 if (FAILED(hr)) return hr;
2610
2611 if (hr == S_FALSE)
2612 reader->instate = XmlReadInState_Element;
2613 else
2614 return hr;
2615 break;
2622 if (hr != S_FALSE) return hr;
2623
2624 if (*reader_get_ptr(reader))
2625 {
2626 WARN("found garbage in the end of XML\n");
2627 return WC_E_SYNTAX;
2628 }
2629
2630 reader->instate = XmlReadInState_Eof;
2632 reader->nodetype = XmlNodeType_None;
2633 return hr;
2634 case XmlReadInState_Eof:
2635 return S_FALSE;
2636 default:
2637 FIXME("internal state %d not handled\n", reader->instate);
2638 return E_NOTIMPL;
2639 }
2640 }
2641
2642 return E_NOTIMPL;
2643}
2644
2646{
2647 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), ppvObject);
2648
2649 if (IsEqualGUID(riid, &IID_IUnknown) ||
2650 IsEqualGUID(riid, &IID_IXmlReader))
2651 {
2652 *ppvObject = iface;
2653 }
2654 else
2655 {
2656 FIXME("interface %s not implemented\n", debugstr_guid(riid));
2657 *ppvObject = NULL;
2658 return E_NOINTERFACE;
2659 }
2660
2661 IXmlReader_AddRef(iface);
2662
2663 return S_OK;
2664}
2665
2667{
2670 TRACE("%p, refcount %ld.\n", iface, ref);
2671 return ref;
2672}
2673
2675{
2676 struct ns *ns, *ns2;
2677
2678 LIST_FOR_EACH_ENTRY_SAFE(ns, ns2, &reader->ns, struct ns, entry) {
2679 list_remove(&ns->entry);
2683 }
2684
2685 LIST_FOR_EACH_ENTRY_SAFE(ns, ns2, &reader->nsdef, struct ns, entry) {
2686 list_remove(&ns->entry);
2689 }
2690}
2691
2693{
2694 reader->position.line_number = 0;
2695 reader->position.line_position = 0;
2696
2701
2702 reader->depth = 0;
2703 reader->nodetype = XmlNodeType_None;
2704 reader->resumestate = XmlReadResumeState_Initial;
2705 memset(reader->resume, 0, sizeof(reader->resume));
2706 reader->is_empty_element = FALSE;
2707}
2708
2710{
2713
2714 TRACE("%p, refcount %ld.\n", iface, ref);
2715
2716 if (ref == 0)
2717 {
2718 IMalloc *imalloc = This->imalloc;
2720 if (This->input) IUnknown_Release(&This->input->IXmlReaderInput_iface);
2721 if (This->resolver) IXmlResolver_Release(This->resolver);
2722 if (This->mlang) IUnknown_Release(This->mlang);
2724 if (imalloc) IMalloc_Release(imalloc);
2725 }
2726
2727 return ref;
2728}
2729
2731{
2733 IXmlReaderInput *readerinput;
2734 HRESULT hr;
2735
2736 TRACE("%p, %p.\n", iface, input);
2737
2738 if (This->input)
2739 {
2741 IUnknown_Release(&This->input->IXmlReaderInput_iface);
2742 This->input = NULL;
2743 }
2744
2746
2747 /* just reset current input */
2748 if (!input)
2749 {
2750 This->state = XmlReadState_Initial;
2751 return S_OK;
2752 }
2753
2754 /* now try IXmlReaderInput, ISequentialStream, IStream */
2755 hr = IUnknown_QueryInterface(input, &IID_IXmlReaderInput, (void**)&readerinput);
2756 if (hr == S_OK)
2757 {
2758 if (readerinput->lpVtbl == &xmlreaderinputvtbl)
2759 This->input = impl_from_IXmlReaderInput(readerinput);
2760 else
2761 {
2762 ERR("got external IXmlReaderInput implementation: %p, vtbl=%p\n",
2763 readerinput, readerinput->lpVtbl);
2764 IUnknown_Release(readerinput);
2765 return E_FAIL;
2766
2767 }
2768 }
2769
2770 if (hr != S_OK || !readerinput)
2771 {
2772 /* create IXmlReaderInput basing on supplied interface */
2774 This->imalloc, NULL, FALSE, NULL, &readerinput);
2775 if (hr != S_OK) return hr;
2776 This->input = impl_from_IXmlReaderInput(readerinput);
2777 }
2778
2779 /* set stream for supplied IXmlReaderInput */
2781 if (hr == S_OK)
2782 {
2783 This->state = XmlReadState_Initial;
2784 This->instate = XmlReadInState_Initial;
2785 }
2786 return hr;
2787}
2788
2790{
2792
2793 TRACE("%p, %s, %p.\n", iface, debugstr_reader_prop(property), value);
2794
2795 if (!value) return E_INVALIDARG;
2796
2797 switch (property)
2798 {
2800 *value = (LONG_PTR)This->mlang;
2801 if (This->mlang)
2802 IUnknown_AddRef(This->mlang);
2803 break;
2805 *value = (LONG_PTR)This->resolver;
2806 if (This->resolver)
2807 IXmlResolver_AddRef(This->resolver);
2808 break;
2810 *value = This->dtdmode;
2811 break;
2813 *value = This->state;
2814 break;
2816 *value = This->max_depth;
2817 break;
2818 default:
2819 FIXME("Unimplemented property (%u)\n", property);
2820 return E_NOTIMPL;
2821 }
2822
2823 return S_OK;
2824}
2825
2827{
2829
2830 TRACE("%p, %s, %Ix.\n", iface, debugstr_reader_prop(property), value);
2831
2832 switch (property)
2833 {
2835 if (This->mlang)
2836 IUnknown_Release(This->mlang);
2837 This->mlang = (IUnknown*)value;
2838 if (This->mlang)
2839 IUnknown_AddRef(This->mlang);
2840 if (This->mlang)
2841 FIXME("Ignoring MultiLanguage %p\n", This->mlang);
2842 break;
2844 if (This->resolver)
2845 IXmlResolver_Release(This->resolver);
2846 This->resolver = (IXmlResolver*)value;
2847 if (This->resolver)
2848 IXmlResolver_AddRef(This->resolver);
2849 break;
2851 if (value < 0 || value > _DtdProcessing_Last) return E_INVALIDARG;
2852 This->dtdmode = value;
2853 break;
2855 This->max_depth = value;
2856 break;
2857 default:
2858 FIXME("Unimplemented property (%u)\n", property);
2859 return E_NOTIMPL;
2860 }
2861
2862 return S_OK;
2863}
2864
2866{
2868 XmlNodeType oldtype = This->nodetype;
2870 HRESULT hr;
2871
2872 TRACE("%p, %p.\n", iface, nodetype);
2873
2874 if (!nodetype)
2875 nodetype = &type;
2876
2877 switch (This->state)
2878 {
2880 hr = S_FALSE;
2881 break;
2882 case XmlReadState_Error:
2883 hr = This->error;
2884 break;
2885 default:
2887 if (SUCCEEDED(hr) && oldtype == XmlNodeType_None && This->nodetype != oldtype)
2889
2890 if (FAILED(hr))
2891 {
2892 This->state = XmlReadState_Error;
2893 This->nodetype = XmlNodeType_None;
2894 This->depth = 0;
2895 This->error = hr;
2896 }
2897 }
2898
2899 TRACE("node type %s\n", debugstr_nodetype(This->nodetype));
2900 *nodetype = This->nodetype;
2901
2902 return hr;
2903}
2904
2906{
2908
2909 TRACE("%p, %p.\n", iface, node_type);
2910
2911 if (!node_type)
2912 return E_INVALIDARG;
2913
2914 *node_type = reader_get_nodetype(This);
2915 return This->state == XmlReadState_Closed ? S_FALSE : S_OK;
2916}
2917
2919{
2920 if (!reader->attr)
2922 reader->attr = attr;
2923 reader->chunk_read_off = 0;
2927}
2928
2930{
2931 if (!reader->attr_count)
2932 return S_FALSE;
2933
2935
2936 return S_OK;
2937}
2938
2940{
2942
2943 TRACE("%p.\n", iface);
2944
2946}
2947
2949{
2951 const struct list *next;
2952
2953 TRACE("%p.\n", iface);
2954
2955 if (!This->attr_count) return S_FALSE;
2956
2957 if (!This->attr)
2959
2960 next = list_next(&This->attrs, &This->attr->entry);
2961 if (next)
2963
2964 return next ? S_OK : S_FALSE;
2965}
2966
2968{
2969 static const WCHAR xmlns_uriW[] = L"http://www.w3.org/2000/xmlns/";
2970 static const WCHAR xml_uriW[] = L"http://www.w3.org/XML/1998/namespace";
2971
2972 /* Check for reserved prefixes first */
2973 if ((strval_eq(reader, &attr->prefix, &strval_empty) && strval_eq(reader, &attr->localname, &strval_xmlns)) ||
2974 strval_eq(reader, &attr->prefix, &strval_xmlns))
2975 {
2976 *uri = xmlns_uriW;
2977 *len = ARRAY_SIZE(xmlns_uriW) - 1;
2978 }
2979 else if (strval_eq(reader, &attr->prefix, &strval_xml))
2980 {
2981 *uri = xml_uriW;
2982 *len = ARRAY_SIZE(xml_uriW) - 1;
2983 }
2984 else
2985 {
2986 *uri = NULL;
2987 *len = 0;
2988 }
2989
2990 if (!*uri)
2991 {
2992 struct ns *ns;
2993
2994 if ((ns = reader_lookup_ns(reader, &attr->prefix)))
2995 {
2996 *uri = ns->uri.str;
2997 *len = ns->uri.len;
2998 }
2999 else
3000 {
3001 *uri = emptyW;
3002 *len = 0;
3003 }
3004 }
3005}
3006
3008{
3010 {
3011 *name = xmlnsW;
3012 *len = 5;
3013 }
3014 else if (attr->flags & ATTRIBUTE_NS_DEFINITION)
3015 {
3016 const struct ns *ns = reader_lookup_ns(reader, &attr->localname);
3017 *name = ns->prefix.str;
3018 *len = ns->prefix.len;
3019 }
3020 else
3021 {
3022 *name = attr->localname.str;
3023 *len = attr->localname.len;
3024 }
3025}
3026
3028 const WCHAR *local_name, const WCHAR *namespace_uri)
3029{
3031 UINT target_name_len, target_uri_len;
3032 struct attribute *attr;
3033
3034 TRACE("%p, %s, %s.\n", iface, debugstr_w(local_name), debugstr_w(namespace_uri));
3035
3036 if (!local_name)
3037 return E_INVALIDARG;
3038
3039 if (!This->attr_count)
3040 return S_FALSE;
3041
3042 if (!namespace_uri)
3043 namespace_uri = emptyW;
3044
3045 target_name_len = lstrlenW(local_name);
3046 target_uri_len = lstrlenW(namespace_uri);
3047
3048 LIST_FOR_EACH_ENTRY(attr, &This->attrs, struct attribute, entry)
3049 {
3050 UINT name_len, uri_len;
3051 const WCHAR *name, *uri;
3052
3055
3056 if (name_len == target_name_len && uri_len == target_uri_len &&
3057 !wcscmp(name, local_name) && !wcscmp(uri, namespace_uri))
3058 {
3060 return S_OK;
3061 }
3062 }
3063
3064 return S_FALSE;
3065}
3066
3068{
3070
3071 TRACE("%p.\n", iface);
3072
3073 if (!This->attr_count) return S_FALSE;
3074
3075 if (This->attr)
3077
3078 This->attr = NULL;
3079
3080 /* FIXME: support other node types with 'attributes' like DTD */
3081 if (This->is_empty_element) {
3082 reader_set_strvalue(This, StringValue_Prefix, &This->empty_element.prefix);
3083 reader_set_strvalue(This, StringValue_QualifiedName, &This->empty_element.qname);
3084 }
3085 else {
3086 struct element *element = LIST_ENTRY(list_head(&This->elements), struct element, entry);
3087 if (element) {
3090 }
3091 }
3092 This->chunk_read_off = 0;
3094
3095 return S_OK;
3096}
3097
3099{
3101 struct attribute *attribute = This->attr;
3102 struct element *element;
3103 UINT length;
3104
3105 TRACE("%p, %p, %p.\n", iface, name, len);
3106
3107 if (!len)
3108 len = &length;
3109
3110 switch (reader_get_nodetype(This))
3111 {
3112 case XmlNodeType_Text:
3113 case XmlNodeType_CDATA:
3116 *name = emptyW;
3117 *len = 0;
3118 break;
3122 if (element->prefix.len)
3123 {
3124 *name = element->qname.str;
3125 *len = element->qname.len;
3126 }
3127 else
3128 {
3131 }
3132 break;
3135 {
3136 *name = xmlnsW;
3137 *len = 5;
3138 } else if (attribute->prefix.len)
3139 {
3140 *name = This->strvalues[StringValue_QualifiedName].str;
3141 *len = This->strvalues[StringValue_QualifiedName].len;
3142 }
3143 else
3144 {
3147 }
3148 break;
3149 default:
3150 *name = This->strvalues[StringValue_QualifiedName].str;
3151 *len = This->strvalues[StringValue_QualifiedName].len;
3152 break;
3153 }
3154
3155 return S_OK;
3156}
3157
3159{
3160 if (list_empty(&reader->nsdef))
3161 return NULL;
3162
3163 return LIST_ENTRY(list_head(&reader->nsdef), struct ns, entry);
3164}
3165
3167{
3169 const strval *prefix = &This->strvalues[StringValue_Prefix];
3170 XmlNodeType nodetype;
3171 struct ns *ns;
3172 UINT length;
3173
3174 TRACE("%p, %p, %p.\n", iface, uri, len);
3175
3176 if (!len)
3177 len = &length;
3178
3179 switch ((nodetype = reader_get_nodetype(This)))
3180 {
3183 break;
3186 {
3188
3189 /* pick top default ns if any */
3190 if (!ns)
3192
3193 if (ns) {
3194 *uri = ns->uri.str;
3195 *len = ns->uri.len;
3196 }
3197 else {
3198 *uri = emptyW;
3199 *len = 0;
3200 }
3201 }
3202 break;
3203 case XmlNodeType_Text:
3204 case XmlNodeType_CDATA:
3209 *uri = emptyW;
3210 *len = 0;
3211 break;
3212 default:
3213 FIXME("Unhandled node type %d\n", nodetype);
3214 *uri = NULL;
3215 *len = 0;
3216 return E_NOTIMPL;
3217 }
3218
3219 return S_OK;
3220}
3221
3223{
3225 struct element *element;
3226 UINT length;
3227
3228 TRACE("%p, %p, %p.\n", iface, name, len);
3229
3230 if (!len)
3231 len = &length;
3232
3233 switch (reader_get_nodetype(This))
3234 {
3235 case XmlNodeType_Text:
3236 case XmlNodeType_CDATA:
3239 *name = emptyW;
3240 *len = 0;
3241 break;
3247 break;
3250 break;
3251 default:
3252 *name = This->strvalues[StringValue_LocalName].str;
3253 *len = This->strvalues[StringValue_LocalName].len;
3254 break;
3255 }
3256
3257 return S_OK;
3258}
3259
3261{
3263 XmlNodeType nodetype;
3264 UINT length;
3265
3266 TRACE("%p, %p, %p.\n", iface, ret, len);
3267
3268 if (!len)
3269 len = &length;
3270
3271 *ret = emptyW;
3272 *len = 0;
3273
3274 switch ((nodetype = reader_get_nodetype(This)))
3275 {
3279 {
3280 const strval *prefix = &This->strvalues[StringValue_Prefix];
3281 struct ns *ns;
3282
3284 {
3285 *ret = xmlW;
3286 *len = 3;
3287 }
3288 else if (strval_eq(This, prefix, &strval_xmlns))
3289 {
3290 *ret = xmlnsW;
3291 *len = 5;
3292 }
3293 else if ((ns = reader_lookup_ns(This, prefix)))
3294 {
3295 *ret = ns->prefix.str;
3296 *len = ns->prefix.len;
3297 }
3298
3299 break;
3300 }
3301 default:
3302 ;
3303 }
3304
3305 return S_OK;
3306}
3307
3308static const strval *reader_get_value(xmlreader *reader, BOOL ensure_allocated)
3309{
3310 strval *val;
3311
3312 switch (reader_get_nodetype(reader))
3313 {
3316 case XmlNodeType_None:
3317 return &strval_empty;
3319 /* For namespace definition attributes return values from namespace list */
3321 {
3322 struct ns *ns;
3323
3324 if (!(ns = reader_lookup_ns(reader, &reader->attr->localname)))
3326
3327 return &ns->uri;
3328 }
3329 return &reader->attr->value;
3330 default:
3331 break;
3332 }
3333
3334 val = &reader->strvalues[StringValue_Value];
3335 if (!val->str && ensure_allocated)
3336 {
3337 WCHAR *ptr = reader_alloc(reader, (val->len+1)*sizeof(WCHAR));
3338 if (!ptr) return NULL;
3339 memcpy(ptr, reader_get_strptr(reader, val), val->len*sizeof(WCHAR));
3340 ptr[val->len] = 0;
3341 val->str = ptr;
3342 }
3343
3344 return val;
3345}
3346
3348{
3350 const strval *val = &reader->strvalues[StringValue_Value];
3351 UINT off;
3352
3353 TRACE("%p, %p, %p.\n", iface, value, len);
3354
3355 *value = NULL;
3356
3357 if ((reader->nodetype == XmlNodeType_Comment && !val->str && !val->len) || is_reader_pending(reader))
3358 {
3360 HRESULT hr;
3361
3362 hr = IXmlReader_Read(iface, &type);
3363 if (FAILED(hr)) return hr;
3364
3365 /* return if still pending, partially read values are not reported */
3366 if (is_reader_pending(reader)) return E_PENDING;
3367 }
3368
3370 if (!val)
3371 return E_OUTOFMEMORY;
3372
3373 off = abs(reader->chunk_read_off);
3374 assert(off <= val->len);
3375 *value = val->str + off;
3376 if (len) *len = val->len - off;
3377 reader->chunk_read_off = -off;
3378 return S_OK;
3379}
3380
3382{
3384 const strval *val;
3385 UINT len = 0;
3386
3387 TRACE("%p, %p, %u, %p.\n", iface, buffer, chunk_size, read);
3388
3390
3391 /* If value is already read by GetValue, chunk_read_off is negative and chunked reads are not possible. */
3392 if (reader->chunk_read_off >= 0)
3393 {
3394 assert(reader->chunk_read_off <= val->len);
3395 len = min(val->len - reader->chunk_read_off, chunk_size);
3396 }
3397 if (read) *read = len;
3398
3399 if (len)
3400 {
3401 memcpy(buffer, reader_get_strptr(reader, val) + reader->chunk_read_off, len*sizeof(WCHAR));
3402 reader->chunk_read_off += len;
3403 }
3404
3405 return len || !chunk_size ? S_OK : S_FALSE;
3406}
3407
3409 LPCWSTR *baseUri,
3410 UINT *baseUri_length)
3411{
3412 FIXME("%p, %p, %p: stub\n", iface, baseUri, baseUri_length);
3413 return E_NOTIMPL;
3414}
3415
3417{
3418 FIXME("%p: stub\n", iface);
3419 return FALSE;
3420}
3421
3423{
3425
3426 TRACE("%p.\n", iface);
3427
3428 /* Empty elements are not placed in stack, it's stored as a global reader flag that makes sense
3429 when current node is start tag of an element */
3430 return (reader_get_nodetype(This) == XmlNodeType_Element) ? This->is_empty_element : FALSE;
3431}
3432
3434{
3436 const struct element *element;
3437
3438 TRACE("%p, %p.\n", iface, line_number);
3439
3440 if (!line_number)
3441 return E_INVALIDARG;
3442
3443 switch (reader_get_nodetype(This))
3444 {
3448 *line_number = element->position.line_number;
3449 break;
3451 *line_number = This->attr->position.line_number;
3452 break;
3455 *line_number = This->empty_element.position.line_number;
3456 break;
3457 default:
3458 *line_number = This->position.line_number;
3459 break;
3460 }
3461
3462 return This->state == XmlReadState_Closed ? S_FALSE : S_OK;
3463}
3464
3466{
3468 const struct element *element;
3469
3470 TRACE("%p, %p.\n", iface, line_position);
3471
3472 if (!line_position)
3473 return E_INVALIDARG;
3474
3475 switch (reader_get_nodetype(This))
3476 {
3480 *line_position = element->position.line_position;
3481 break;
3483 *line_position = This->attr->position.line_position;
3484 break;
3487 *line_position = This->empty_element.position.line_position;
3488 break;
3489 default:
3490 *line_position = This->position.line_position;
3491 break;
3492 }
3493
3494 return This->state == XmlReadState_Closed ? S_FALSE : S_OK;
3495}
3496
3498{
3500
3501 TRACE("%p, %p.\n", iface, count);
3502
3503 if (!count) return E_INVALIDARG;
3504
3505 *count = This->attr_count;
3506 return S_OK;
3507}
3508
3510{
3512
3513 TRACE("%p, %p.\n", iface, depth);
3514
3515 *depth = This->depth;
3516 return S_OK;
3517}
3518
3520{
3522
3523 TRACE("%p.\n", iface);
3524
3525 return This->state == XmlReadState_EndOfFile;
3526}
3527
3528static const struct IXmlReaderVtbl xmlreader_vtbl =
3529{
3556};
3557
3560{
3561 TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), ppvObject);
3562
3563 if (IsEqualGUID(riid, &IID_IXmlReaderInput) ||
3565 {
3566 *ppvObject = iface;
3567 }
3568 else
3569 {
3570 WARN("interface %s not implemented\n", debugstr_guid(riid));
3571 *ppvObject = NULL;
3572 return E_NOINTERFACE;
3573 }
3574
3575 IUnknown_AddRef(iface);
3576
3577 return S_OK;
3578}
3579
3581{
3584 TRACE("%p, refcount %ld.\n", iface, ref);
3585 return ref;
3586}
3587
3589{
3592
3593 TRACE("%p, refcount %ld.\n", iface, ref);
3594
3595 if (ref == 0)
3596 {
3597 IMalloc *imalloc = This->imalloc;
3598 if (This->input) IUnknown_Release(This->input);
3599 if (This->stream) ISequentialStream_Release(This->stream);
3600 if (This->buffer) free_input_buffer(This->buffer);
3601 readerinput_free(This, This->baseuri);
3603 if (imalloc) IMalloc_Release(imalloc);
3604 }
3605
3606 return ref;
3607}
3608
3609static const struct IUnknownVtbl xmlreaderinputvtbl =
3610{
3614};
3615
3617{
3619 HRESULT hr;
3620 int i;
3621
3622 TRACE("%s, %p, %p.\n", wine_dbgstr_guid(riid), obj, imalloc);
3623
3624 if (!(reader = m_alloc(imalloc, sizeof(*reader))))
3625 return E_OUTOFMEMORY;
3626
3627 memset(reader, 0, sizeof(*reader));
3628 reader->IXmlReader_iface.lpVtbl = &xmlreader_vtbl;
3629 reader->ref = 1;
3630 reader->state = XmlReadState_Closed;
3631 reader->instate = XmlReadInState_Initial;
3632 reader->resumestate = XmlReadResumeState_Initial;
3633 reader->dtdmode = DtdProcessing_Prohibit;
3634 reader->imalloc = imalloc;
3635 if (imalloc) IMalloc_AddRef(imalloc);
3636 reader->nodetype = XmlNodeType_None;
3637 list_init(&reader->attrs);
3638 list_init(&reader->nsdef);
3639 list_init(&reader->ns);
3640 list_init(&reader->elements);
3641 reader->max_depth = 256;
3642
3643 reader->chunk_read_off = 0;
3644 for (i = 0; i < StringValue_Last; i++)
3645 reader->strvalues[i] = strval_empty;
3646
3647 hr = IXmlReader_QueryInterface(&reader->IXmlReader_iface, riid, obj);
3648 IXmlReader_Release(&reader->IXmlReader_iface);
3649
3650 TRACE("returning iface %p, hr %#lx.\n", *obj, hr);
3651
3652 return hr;
3653}
3654
3656 BOOL hint, const WCHAR *base_uri, IXmlReaderInput **ppInput)
3657{
3658 xmlreaderinput *readerinput;
3659 HRESULT hr;
3660
3661 if (!stream || !ppInput) return E_INVALIDARG;
3662
3663 if (!(readerinput = m_alloc(imalloc, sizeof(*readerinput))))
3664 return E_OUTOFMEMORY;
3665 memset(readerinput, 0, sizeof(*readerinput));
3666
3667 readerinput->IXmlReaderInput_iface.lpVtbl = &xmlreaderinputvtbl;
3668 readerinput->ref = 1;
3669 readerinput->imalloc = imalloc;
3670 if (imalloc) IMalloc_AddRef(imalloc);
3671 readerinput->encoding = encoding;
3672 readerinput->hint = hint;
3673 readerinput->baseuri = readerinput_strdupW(readerinput, base_uri);
3674
3675 hr = alloc_input_buffer(readerinput);
3676 if (hr != S_OK)
3677 {
3678 readerinput_free(readerinput, readerinput->baseuri);
3679 readerinput_free(readerinput, readerinput);
3680 if (imalloc) IMalloc_Release(imalloc);
3681 return hr;
3682 }
3683 IUnknown_QueryInterface(stream, &IID_IUnknown, (void**)&readerinput->input);
3684
3685 *ppInput = &readerinput->IXmlReaderInput_iface;
3686
3687 TRACE("returning iface %p\n", *ppInput);
3688
3689 return S_OK;
3690}
3691
3692/***********************************************************************
3693 * CreateXmlReaderInputWithEncodingName (xmllite.@)
3694 */
3696 const WCHAR *encoding, BOOL hint, const WCHAR *base_uri, IXmlReaderInput **input)
3697{
3698 TRACE("%p, %p, %s, %d, %s, %p.\n", stream, imalloc, wine_dbgstr_w(encoding),
3699 hint, wine_dbgstr_w(base_uri), input);
3700
3701 return create_reader_input(stream, imalloc, parse_encoding_name(encoding, -1), hint, base_uri, input);
3702}
3703
3704/***********************************************************************
3705 * CreateXmlReaderInputWithEncodingCodePage (xmllite.@)
3706 */
3708 UINT codepage, BOOL hint, const WCHAR *base_uri, IXmlReaderInput **input)
3709{
3710 TRACE("%p, %p, %u, %d, %s, %p.\n", stream, imalloc, codepage, hint, wine_dbgstr_w(base_uri), input);
3711
3713}
#define read
Definition: acwin.h:97
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
BOOL is_char(const WCHAR s, const WCHAR c)
Definition: reg.c:267
void quote(int argc, const char *argv[])
Definition: cmds.c:1480
#define ARRAY_SIZE(A)
Definition: main.h:20
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static int list_empty(struct list_entry *head)
Definition: list.h:58
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
static void list_init(struct list_entry *head)
Definition: list.h:51
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
const GUID IID_IUnknown
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
Definition: list.h:39
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
int const char const *const int const line_number
Definition: debug_heap.cpp:499
HRESULT hr
Definition: delayimp.cpp:582
#define E_PENDING
Definition: dinput.h:172
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
const char * wine_dbg_sprintf(const char *format,...)
Definition: compat.c:296
#define wcsnicmp
Definition: compat.h:14
#define MultiByteToWideChar
Definition: compat.h:110
#define wcsicmp
Definition: compat.h:15
#define lstrlenW
Definition: compat.h:750
unsigned char ch[4][2]
Definition: console.c:118
#define assert(_expr)
Definition: assert.h:32
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1977
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
static HRESULT create_reader_input(IUnknown *stream, IMalloc *imalloc, xml_encoding encoding, BOOL hint, const WCHAR *base_uri, IXmlReaderInput **ppInput)
Definition: reader.c:3655
static const strval strval_empty
Definition: reader.c:219
static int readerinput_get_utf8_convlen(xmlreaderinput *readerinput)
Definition: reader.c:932
static void reader_shrink(xmlreader *reader)
Definition: reader.c:1052
static HRESULT WINAPI xmlreader_ReadValueChunk(IXmlReader *iface, WCHAR *buffer, UINT chunk_size, UINT *read)
Definition: reader.c:3381
static BOOL reader_is_quote(xmlreader *reader)
Definition: reader.c:1216
static ULONG WINAPI xmlreaderinput_Release(IXmlReaderInput *iface)
Definition: reader.c:3588
static HRESULT alloc_input_buffer(xmlreaderinput *input)
Definition: reader.c:766
HRESULT WINAPI CreateXmlReader(REFIID riid, void **obj, IMalloc *imalloc)
Definition: reader.c:3616
static HRESULT WINAPI xmlreader_GetDepth(IXmlReader *iface, UINT *depth)
Definition: reader.c:3509
static HRESULT reader_parse_attvalue(xmlreader *reader, strval *value)
Definition: reader.c:2159
static const char * debugstr_reader_prop(XmlReaderProperty prop)
Definition: reader.c:121
static HRESULT reader_parse_pi(xmlreader *reader)
Definition: reader.c:1613
static HRESULT reader_parse_local(xmlreader *reader, strval *local, BOOL check_for_separator)
Definition: reader.c:1906
static void * readerinput_alloc(xmlreaderinput *input, size_t len)
Definition: reader.c:360
static WCHAR * reader_get_ptr2(const xmlreader *reader, UINT offset)
Definition: reader.c:332
static const struct IUnknownVtbl xmlreaderinputvtbl
Definition: reader.c:199
static void reader_set_current_attribute(xmlreader *reader, struct attribute *attr)
Definition: reader.c:2918
static void free_encoded_buffer(xmlreaderinput *input, encoded_buffer *buffer)
Definition: reader.c:719
static struct ns * reader_lookup_ns(xmlreader *reader, const strval *prefix)
Definition: reader.c:516
BOOL is_namechar(WCHAR ch)
Definition: reader.c:1530
static HRESULT reader_parse_cdata(xmlreader *reader)
Definition: reader.c:2370
static HRESULT reader_parse_xmldecl(xmlreader *reader)
Definition: reader.c:1376
static WCHAR * reader_get_ptr(xmlreader *reader)
Definition: reader.c:1113
static HRESULT WINAPI xmlreaderinput_QueryInterface(IXmlReaderInput *iface, REFIID riid, void **ppvObject)
Definition: reader.c:3559
static HRESULT reader_parse_chardata(xmlreader *reader)
Definition: reader.c:2421
static HRESULT reader_parse_qname(xmlreader *reader, strval *prefix, strval *local, strval *qname)
Definition: reader.c:1948
static const struct IXmlReaderVtbl xmlreader_vtbl
Definition: reader.c:3528
static HRESULT WINAPI xmlreader_MoveToAttributeByName(IXmlReader *iface, const WCHAR *local_name, const WCHAR *namespace_uri)
Definition: reader.c:3027
static HRESULT WINAPI xmlreader_GetNamespaceUri(IXmlReader *iface, const WCHAR **uri, UINT *len)
Definition: reader.c:3166
static void reader_set_strvalue(xmlreader *reader, XmlReaderStringValue type, const strval *value)
Definition: reader.c:665
static HRESULT reader_parse_stag(xmlreader *reader, strval *prefix, strval *local, strval *qname)
Definition: reader.c:2237
static HRESULT WINAPI xmlreader_SetInput(IXmlReader *iface, IUnknown *input)
Definition: reader.c:2730
static HRESULT reader_parse_versionnum(xmlreader *reader, strval *val)
Definition: reader.c:1181
static HRESULT WINAPI xmlreader_MoveToFirstAttribute(IXmlReader *iface)
Definition: reader.c:2939
static HRESULT reader_parse_attribute(xmlreader *reader)
Definition: reader.c:2206
static HRESULT WINAPI xmlreader_GetValue(IXmlReader *iface, const WCHAR **value, UINT *len)
Definition: reader.c:3347
static WCHAR * reader_get_strptr(const xmlreader *reader, const strval *v)
Definition: reader.c:338
static void reader_get_attribute_local_name(xmlreader *reader, struct attribute *attr, const WCHAR **name, UINT *len)
Definition: reader.c:3007
static void readerinput_free(xmlreaderinput *input, void *mem)
Definition: reader.c:370
static HRESULT reader_parse_content(xmlreader *reader)
Definition: reader.c:2480
static struct element * reader_get_element(xmlreader *reader)
Definition: reader.c:452
static int reader_skipspaces(xmlreader *reader)
Definition: reader.c:1166
static int readerinput_get_convlen(xmlreaderinput *readerinput)
Definition: reader.c:952
static BOOL WINAPI xmlreader_IsEOF(IXmlReader *iface)
Definition: reader.c:3519
static HRESULT WINAPI xmlreader_GetBaseUri(IXmlReader *iface, LPCWSTR *baseUri, UINT *baseUri_length)
Definition: reader.c:3408
static HRESULT reader_parse_endtag(xmlreader *reader)
Definition: reader.c:2330
static void reader_free_element(xmlreader *reader, struct element *element)
Definition: reader.c:570
static HRESULT reader_parse_comment(xmlreader *reader)
Definition: reader.c:1414
XmlReaderResume
Definition: reader.c:73
@ XmlReadResume_Name
Definition: reader.c:74
@ XmlReadResume_Local
Definition: reader.c:75
@ XmlReadResume_Body
Definition: reader.c:76
@ XmlReadResume_Last
Definition: reader.c:77
static int is_reader_pending(xmlreader *reader)
Definition: reader.c:699
static HRESULT reader_parse_sys_literal(xmlreader *reader, strval *literal)
Definition: reader.c:1758
static HRESULT readerinput_growraw(xmlreaderinput *readerinput)
Definition: reader.c:825
static WCHAR xmlW[]
Definition: reader.c:217
static void * reader_alloc_zero(xmlreader *reader, size_t len)
Definition: reader.c:318
static HRESULT WINAPI xmlreader_GetLineNumber(IXmlReader *iface, UINT *line_number)
Definition: reader.c:3433
static void reader_mark_ns_nodes(xmlreader *reader, struct element *element)
Definition: reader.c:578
BOOL is_namestartchar(WCHAR ch)
Definition: reader.c:1486
static HRESULT WINAPI xmlreader_MoveToNextAttribute(IXmlReader *iface)
Definition: reader.c:2948
static int strval_eq(const xmlreader *reader, const strval *str1, const strval *str2)
Definition: reader.c:494
static void reader_pop_element(xmlreader *reader)
Definition: reader.c:645
const WCHAR * get_encoding_name(xml_encoding encoding)
Definition: reader.c:155
static HRESULT WINAPI xmlreader_MoveToElement(IXmlReader *iface)
Definition: reader.c:3067
static HRESULT reader_inc_depth(xmlreader *reader)
Definition: reader.c:529
HRESULT get_code_page(xml_encoding encoding, UINT *cp)
Definition: reader.c:724
static void readerinput_shrinkraw(xmlreaderinput *readerinput, int len)
Definition: reader.c:969
static HRESULT WINAPI xmlreader_Read(IXmlReader *iface, XmlNodeType *nodetype)
Definition: reader.c:2865
static WCHAR get_predefined_entity(const xmlreader *reader, const strval *name)
Definition: reader.c:2020
static void reader_clear_elements(xmlreader *reader)
Definition: reader.c:500
static HRESULT WINAPI xmlreader_QueryInterface(IXmlReader *iface, REFIID riid, void **ppvObject)
Definition: reader.c:2645
static HRESULT reader_parse_misc(xmlreader *reader)
Definition: reader.c:1714
static void readerinput_release_stream(xmlreaderinput *readerinput)
Definition: reader.c:802
static HRESULT reader_parse_externalid(xmlreader *reader)
Definition: reader.c:1809
static BOOL is_wchar_encname(WCHAR ch)
Definition: reader.c:1257
static void reader_get_attribute_ns_uri(xmlreader *reader, struct attribute *attr, const WCHAR **uri, UINT *len)
Definition: reader.c:2967
static void reader_reset_parser(xmlreader *reader)
Definition: reader.c:2692
static void reader_update_position(xmlreader *reader, WCHAR ch)
Definition: reader.c:1139
static WCHAR xmlnsW[]
Definition: reader.c:218
static HRESULT WINAPI xmlreader_GetPrefix(IXmlReader *iface, const WCHAR **ret, UINT *len)
Definition: reader.c:3260
static HRESULT reader_more(xmlreader *reader)
Definition: reader.c:1068
static const strval strval_xml
Definition: reader.c:220
static void * reader_alloc(xmlreader *reader, size_t len)
Definition: reader.c:313
static HRESULT WINAPI xmlreader_GetLinePosition(IXmlReader *iface, UINT *line_position)
Definition: reader.c:3465
attribute_flags
Definition: reader.c:230
@ ATTRIBUTE_DEFAULT_NS_DEFINITION
Definition: reader.c:232
@ ATTRIBUTE_NS_DEFINITION
Definition: reader.c:231
static HRESULT WINAPI xmlreader_GetNodeType(IXmlReader *iface, XmlNodeType *node_type)
Definition: reader.c:2905
static const struct xml_encoding_data xml_encoding_map[]
Definition: reader.c:148
static void reader_pop_ns_nodes(xmlreader *reader, struct element *element)
Definition: reader.c:620
static xmlreader * impl_from_IXmlReader(IXmlReader *iface)
Definition: reader.c:302
static HRESULT reader_parse_name(xmlreader *reader, strval *name)
Definition: reader.c:1548
static HRESULT WINAPI xmlreader_GetQualifiedName(IXmlReader *iface, LPCWSTR *name, UINT *len)
Definition: reader.c:3098
static HRESULT reader_push_element(xmlreader *reader, strval *prefix, strval *localname, strval *qname, const struct reader_position *position)
Definition: reader.c:595
HRESULT WINAPI CreateXmlReaderInputWithEncodingCodePage(IUnknown *stream, IMalloc *imalloc, UINT codepage, BOOL hint, const WCHAR *base_uri, IXmlReaderInput **input)
Definition: reader.c:3707
static HRESULT readerinput_detectencoding(xmlreaderinput *readerinput, xml_encoding *enc)
Definition: reader.c:890
static int reader_cmp(xmlreader *reader, const WCHAR *str)
Definition: reader.c:1121
static struct ns * reader_lookup_nsdef(xmlreader *reader)
Definition: reader.c:3158
static const strval strval_xmlns
Definition: reader.c:221
static HRESULT WINAPI xmlreader_GetAttributeCount(IXmlReader *iface, UINT *count)
Definition: reader.c:3497
static void reader_free_strvalued(xmlreader *reader, strval *v)
Definition: reader.c:391
static WCHAR emptyW[]
Definition: reader.c:216
static ULONG WINAPI xmlreader_AddRef(IXmlReader *iface)
Definition: reader.c:2666
static HRESULT reader_parse_versioninfo(xmlreader *reader)
Definition: reader.c:1222
static ULONG WINAPI xmlreaderinput_AddRef(IXmlReaderInput *iface)
Definition: reader.c:3580
static void reader_dec_depth(xmlreader *reader)
Definition: reader.c:534
static void reader_free(xmlreader *reader, void *mem)
Definition: reader.c:326
xml_encoding get_encoding_from_codepage(UINT codepage)
Definition: reader.c:160
static void reader_free_strvalue(xmlreader *reader, XmlReaderStringValue type)
Definition: reader.c:480
static WCHAR * readerinput_strdupW(xmlreaderinput *input, const WCHAR *str)
Definition: reader.c:375
static void readerinput_switchencoding(xmlreaderinput *readerinput, xml_encoding enc)
Definition: reader.c:1014
static HRESULT reader_parse_eq(xmlreader *reader)
Definition: reader.c:1206
static HRESULT reader_parse_pitarget(xmlreader *reader, strval *target)
Definition: reader.c:1586
static HRESULT reader_move_to_first_attribute(xmlreader *reader)
Definition: reader.c:2929
static HRESULT reader_parse_encname(xmlreader *reader, strval *val)
Definition: reader.c:1267
static xmlreaderinput * impl_from_IXmlReaderInput(IXmlReaderInput *iface)
Definition: reader.c:307
static void reader_clear_ns(xmlreader *reader)
Definition: reader.c:2674
static HRESULT reader_parse_encdecl(xmlreader *reader, BOOL *spaces)
Definition: reader.c:1297
static void free_input_buffer(input_buffer *buffer)
Definition: reader.c:795
static HRESULT WINAPI xmlreader_SetProperty(IXmlReader *iface, UINT property, LONG_PTR value)
Definition: reader.c:2826
XmlReaderStringValue
Definition: reader.c:81
@ StringValue_LocalName
Definition: reader.c:82
@ StringValue_Value
Definition: reader.c:85
@ StringValue_Last
Definition: reader.c:86
@ StringValue_QualifiedName
Definition: reader.c:84
@ StringValue_Prefix
Definition: reader.c:83
xml_encoding parse_encoding_name(const WCHAR *name, int len)
Definition: reader.c:737
static HRESULT reader_parse_pub_literal(xmlreader *reader, strval *literal)
Definition: reader.c:1784
static void * readerinput_realloc(xmlreaderinput *input, void *mem, size_t len)
Definition: reader.c:365
static void reader_clear_attrs(xmlreader *reader)
Definition: reader.c:400
static void readerinput_grow(xmlreaderinput *readerinput, int length)
Definition: reader.c:857
static BOOL WINAPI xmlreader_IsEmptyElement(IXmlReader *iface)
Definition: reader.c:3422
static const strval * reader_get_value(xmlreader *reader, BOOL ensure_allocated)
Definition: reader.c:3308
static HRESULT WINAPI xmlreader_GetLocalName(IXmlReader *iface, LPCWSTR *name, UINT *len)
Definition: reader.c:3222
static void reader_free_strvalues(xmlreader *reader)
Definition: reader.c:485
static UINT reader_get_cur(xmlreader *reader)
Definition: reader.c:1108
BOOL is_pubchar(WCHAR ch)
Definition: reader.c:1473
static HRESULT WINAPI xmlreader_GetProperty(IXmlReader *iface, UINT property, LONG_PTR *value)
Definition: reader.c:2789
static BOOL readerinput_is_utf8(xmlreaderinput *readerinput)
Definition: reader.c:871
static ULONG WINAPI xmlreader_Release(IXmlReader *iface)
Definition: reader.c:2709
static HRESULT reader_parse_nextnode(xmlreader *reader)
Definition: reader.c:2522
static HRESULT reader_add_attr(xmlreader *reader, strval *prefix, strval *localname, strval *qname, strval *value, const struct reader_position *position, unsigned int flags)
Definition: reader.c:416
static HRESULT readerinput_query_for_stream(xmlreaderinput *readerinput)
Definition: reader.c:812
XmlReaderResumeState
Definition: reader.c:60
@ XmlReadResumeState_PITarget
Definition: reader.c:62
@ XmlReadResumeState_PIBody
Definition: reader.c:63
@ XmlReadResumeState_Initial
Definition: reader.c:61
@ XmlReadResumeState_CharData
Definition: reader.c:67
@ XmlReadResumeState_Comment
Definition: reader.c:65
@ XmlReadResumeState_Whitespace
Definition: reader.c:68
@ XmlReadResumeState_STag
Definition: reader.c:66
@ XmlReadResumeState_CDATA
Definition: reader.c:64
static void fixup_buffer_cr(encoded_buffer *buffer, int off)
Definition: reader.c:985
static HRESULT reader_parse_reference(xmlreader *reader)
Definition: reader.c:2056
static BOOL WINAPI xmlreader_IsDefault(IXmlReader *iface)
Definition: reader.c:3416
XmlReaderInternalState
Definition: reader.c:45
@ XmlReadInState_Element
Definition: reader.c:51
@ XmlReadInState_DTD
Definition: reader.c:49
@ XmlReadInState_Eof
Definition: reader.c:54
@ XmlReadInState_Misc_DTD
Definition: reader.c:48
@ XmlReadInState_Content
Definition: reader.c:52
@ XmlReadInState_DTD_Misc
Definition: reader.c:50
@ XmlReadInState_MiscEnd
Definition: reader.c:53
@ XmlReadInState_XmlDecl
Definition: reader.c:47
@ XmlReadInState_Initial
Definition: reader.c:46
BOOL is_ncnamechar(WCHAR ch)
Definition: reader.c:1506
static HRESULT reader_push_ns(xmlreader *reader, const strval *prefix, const strval *uri, BOOL def)
Definition: reader.c:540
static void reader_init_cstrvalue(WCHAR *str, UINT len, strval *v)
Definition: reader.c:473
static HRESULT reader_strvaldup(xmlreader *reader, const strval *src, strval *dest)
Definition: reader.c:343
static XmlNodeType reader_get_nodetype(const xmlreader *reader)
Definition: reader.c:1535
static const char * debugstr_nodetype(XmlNodeType nodetype)
Definition: reader.c:91
static HRESULT init_encoded_buffer(xmlreaderinput *input, encoded_buffer *buffer)
Definition: reader.c:704
static HRESULT reader_parse_sddecl(xmlreader *reader, BOOL spaces)
Definition: reader.c:1335
static HRESULT reader_parse_element(xmlreader *reader)
Definition: reader.c:2284
static void reader_skipn(xmlreader *reader, int n)
Definition: reader.c:1153
static void reader_init_strvalue(UINT start, UINT len, strval *v)
Definition: reader.c:460
static HRESULT reader_parse_dtd(xmlreader *reader)
Definition: reader.c:1862
static const char * debug_strval(const xmlreader *reader, const strval *v)
Definition: reader.c:467
static HRESULT reader_parse_whitespace(xmlreader *reader)
Definition: reader.c:1679
HRESULT WINAPI CreateXmlReaderInputWithEncodingName(IUnknown *stream, IMalloc *imalloc, const WCHAR *encoding, BOOL hint, const WCHAR *base_uri, IXmlReaderInput **input)
Definition: reader.c:3695
return ret
Definition: mutex.c:147
#define L(x)
Definition: resources.c:13
static BSTR local_name(call_frame_t *frame, int ref)
Definition: engine.c:164
#define abs(i)
Definition: fconv.c:206
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define local
Definition: zutil.h:30
FxCollectionEntry * cur
GLuint start
Definition: gl.h:1545
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
const GLdouble * v
Definition: gl.h:2040
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble n
Definition: glext.h:7729
GLenum src
Definition: glext.h:6340
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
const GLubyte * c
Definition: glext.h:8905
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLuint GLfloat * val
Definition: glext.h:7180
GLenum GLsizei len
Definition: glext.h:6722
GLenum GLenum GLenum input
Definition: glext.h:9031
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
unsigned int UINT
Definition: sysinfo.c:13
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
#define c
Definition: ke_i.h:80
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_wn
Definition: kernel32.h:33
#define debugstr_w
Definition: kernel32.h:32
#define wine_dbgstr_w
Definition: kernel32.h:34
if(dx< 0)
Definition: linetemp.h:194
POINT cp
Definition: magnifier.c:59
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
static PVOID ptr
Definition: dispmode.c:27
static size_t elem
Definition: string.c:71
static char * dest
Definition: rtl.c:149
const WCHAR * uri
Definition: sec_mgr.c:1564
#define min(a, b)
Definition: monoChain.cc:55
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
static const WCHAR publicW[]
Definition: mxwriter.c:44
static const WCHAR systemW[]
Definition: mxwriter.c:45
xml_encoding
Definition: mxwriter.c:49
@ XmlEncoding_UTF8
Definition: mxwriter.c:60
@ XmlEncoding_Unknown
Definition: mxwriter.c:70
@ XmlEncoding_UTF16
Definition: mxwriter.c:59
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)
Definition: guiddef.h:68
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
static unsigned __int64 next
Definition: rand_nt.c:6
const WCHAR * str
#define CP_UTF8
Definition: nls.h:20
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:181
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:236
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:242
__WINE_SERVER_LIST_INLINE struct list * list_next(const struct list *list, const struct list *elem)
Definition: list.h:117
#define LIST_FOR_EACH_ENTRY_REV(elem, list, type, field)
Definition: list.h:260
#define LIST_FOR_EACH_ENTRY_SAFE_REV(cursor, cursor2, list, type, field)
Definition: list.h:266
XML_HIDDEN void xmlParserErrors const char const xmlChar const xmlChar * str2
Definition: parser.h:35
XML_HIDDEN void xmlParserErrors const char const xmlChar * str1
Definition: parser.h:35
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
Definition: cookie.c:202
WCHAR * value
Definition: cookie.c:204
unsigned int flags
Definition: reader.c:243
strval localname
Definition: reader.c:239
strval qname
Definition: reader.c:240
strval prefix
Definition: reader.c:238
struct reader_position position
Definition: reader.c:242
struct list entry
Definition: reader.c:237
strval value
Definition: reader.c:241
strval localname
Definition: reader.c:250
strval prefix
Definition: reader.c:249
strval qname
Definition: reader.c:251
struct list entry
Definition: reader.c:248
struct reader_position position
Definition: reader.c:252
unsigned int written
Definition: mxwriter.c:145
BOOL prev_cr
Definition: reader.c:176
unsigned int allocated
Definition: mxwriter.c:144
encoded_buffer utf16
Definition: reader.c:296
xmlreaderinput * input
Definition: reader.c:299
encoded_buffer encoded
Definition: reader.c:297
UINT code_page
Definition: reader.c:298
Definition: list.h:15
Definition: mem.c:349
Definition: name.c:39
Definition: mxnamespace.c:38
struct element * element
Definition: reader.c:260
strval prefix
Definition: reader.c:258
struct list entry
Definition: reader.c:257
strval uri
Definition: reader.c:259
BSTR prefix
Definition: mxnamespace.c:39
BSTR uri
Definition: mxnamespace.c:40
UINT line_position
Definition: reader.c:226
UINT line_number
Definition: reader.c:225
Definition: reader.h:84
Definition: send.c:48
Definition: parse.h:23
Definition: reader.c:210
UINT start
Definition: reader.c:213
WCHAR * str
Definition: reader.c:211
UINT len
Definition: reader.c:212
Definition: tools.h:99
const WCHAR * encoding
Definition: mxwriter.c:75
const WCHAR * name
Definition: reader.c:143
xml_encoding enc
Definition: mxwriter.c:76
XmlNodeType nodetype
Definition: reader.c:273
HRESULT error
Definition: reader.c:270
XmlReadState state
Definition: reader.c:269
XmlReaderResumeState resumestate
Definition: reader.c:272
IMalloc * imalloc
Definition: reader.c:268
DtdProcessing dtdmode
Definition: reader.c:274
IXmlReader IXmlReader_iface
Definition: reader.c:265
xmlreaderinput * input
Definition: reader.c:267
BOOL is_empty_element
Definition: reader.c:288
struct attribute * attr
Definition: reader.c:279
UINT attr_count
Definition: reader.c:280
IUnknown * mlang
Definition: reader.c:276
LONG ref
Definition: reader.c:266
XmlReaderInternalState instate
Definition: reader.c:271
IXmlResolver * resolver
Definition: reader.c:275
UINT max_depth
Definition: reader.c:287
UINT depth
Definition: reader.c:286
int chunk_read_off
Definition: reader.c:284
input_buffer * buffer
Definition: reader.c:195
ISequentialStream * stream
Definition: reader.c:194
WCHAR * baseuri
Definition: reader.c:190
IUnknown * input
Definition: reader.c:186
xml_encoding encoding
Definition: reader.c:188
IXmlReaderInput IXmlReaderInput_iface
Definition: reader.c:183
unsigned int pending
Definition: reader.c:196
IMalloc * imalloc
Definition: reader.c:187
#define max(a, b)
Definition: svc.c:63
#define LIST_ENTRY(type)
Definition: queue.h:175
Character const *const prefix
Definition: tempnam.cpp:195
#define LONG_PTR
Definition: treelist.c:79
const uint16_t * LPCWSTR
Definition: typedefs.h:57
uint16_t * LPWSTR
Definition: typedefs.h:56
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
Definition: pdh_main.c:64
DWORD hint
Definition: vfdcmd.c:88
_In_ size_t cnt
Definition: wcstombs.cpp:43
int codepage
Definition: win_iconv.c:156
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:3451
#define E_NOINTERFACE
Definition: winerror.h:3479
XmlReadState
Definition: xmllite.idl:98
@ XmlReadState_Closed
Definition: xmllite.idl:103
@ XmlReadState_Error
Definition: xmllite.idl:101
@ XmlReadState_EndOfFile
Definition: xmllite.idl:102
@ XmlReadState_Initial
Definition: xmllite.idl:99
@ XmlReadState_Interactive
Definition: xmllite.idl:100
DtdProcessing
Definition: xmllite.idl:117
@ _DtdProcessing_Last
Definition: xmllite.idl:120
@ DtdProcessing_Prohibit
Definition: xmllite.idl:118
@ WC_E_WHITESPACE
Definition: xmllite.idl:146
@ WC_E_LESSTHAN
Definition: xmllite.idl:151
@ WC_E_PI
Definition: xmllite.idl:187
@ WC_E_XMLDECL
Definition: xmllite.idl:177
@ WC_E_EQUAL
Definition: xmllite.idl:150
@ WC_E_DIGIT
Definition: xmllite.idl:153
@ NC_E_QNAMECOLON
Definition: xmllite.idl:196
@ WC_E_DECLDOCTYPE
Definition: xmllite.idl:163
@ WC_E_SYNTAX
Definition: xmllite.idl:158
@ WC_E_UNDECLAREDENTITY
Definition: xmllite.idl:184
@ SC_E_MAXELEMENTDEPTH
Definition: xmllite.idl:206
@ WC_E_GREATERTHAN
Definition: xmllite.idl:148
@ WC_E_LEADINGXML
Definition: xmllite.idl:175
@ WC_E_CDSECTEND
Definition: xmllite.idl:190
@ WC_E_NAMECHARACTER
Definition: xmllite.idl:157
@ WC_E_ENCNAME
Definition: xmllite.idl:178
@ WC_E_SEMICOLON
Definition: xmllite.idl:147
@ WC_E_ELEMENTMATCH
Definition: xmllite.idl:172
@ NC_E_NAMECOLON
Definition: xmllite.idl:197
@ WC_E_XMLCHARACTER
Definition: xmllite.idl:156
@ NC_E_QNAMECHARACTER
Definition: xmllite.idl:195
@ WC_E_QUOTE
Definition: xmllite.idl:149
@ WC_E_DTDPROHIBITED
Definition: xmllite.idl:192
@ MX_E_INPUTEND
Definition: xmllite.idl:141
@ WC_E_HEXDIGIT
Definition: xmllite.idl:152
@ WC_E_COMMENT
Definition: xmllite.idl:160
XmlReaderProperty
Definition: xmllite.idl:125
@ _XmlReaderProperty_Last
Definition: xmllite.idl:134
@ XmlReaderProperty_MultiLanguage
Definition: xmllite.idl:126
@ XmlReaderProperty_DtdProcessing
Definition: xmllite.idl:130
@ XmlReaderProperty_XmlResolver
Definition: xmllite.idl:129
@ XmlReaderProperty_MaxElementDepth
Definition: xmllite.idl:132
@ XmlReaderProperty_ReadState
Definition: xmllite.idl:131
XmlNodeType
Definition: xmllite.idl:23
@ XmlNodeType_Whitespace
Definition: xmllite.idl:32
@ XmlNodeType_EndElement
Definition: xmllite.idl:33
@ XmlNodeType_ProcessingInstruction
Definition: xmllite.idl:29
@ XmlNodeType_Attribute
Definition: xmllite.idl:26
@ XmlNodeType_CDATA
Definition: xmllite.idl:28
@ XmlNodeType_XmlDeclaration
Definition: xmllite.idl:34
@ _XmlNodeType_Last
Definition: xmllite.idl:35
@ XmlNodeType_Comment
Definition: xmllite.idl:30
@ XmlNodeType_DocumentType
Definition: xmllite.idl:31
@ XmlNodeType_None
Definition: xmllite.idl:24
@ XmlNodeType_Element
Definition: xmllite.idl:25
@ XmlNodeType_Text
Definition: xmllite.idl:27
static void * m_alloc(IMalloc *imalloc, size_t len)
static BOOL is_wchar_space(WCHAR ch)
static void m_free(IMalloc *imalloc, void *mem)
static void * m_realloc(IMalloc *imalloc, void *mem, size_t len)
@ XmlEncoding_USASCII