42DEFINE_GUID(IID_IXmlReaderInput, 0x0b3ccc9b, 0x9214, 0x428b, 0xa2, 0xae, 0xef, 0x3a, 0xa8, 0x71, 0xaf, 0xda);
104 static const char *
const type_names[] =
113 "ProcessingInstruction",
129 return type_names[nodetype];
134 static const char *
const prop_names[] =
149 return prop_names[prop];
184 unsigned int allocated;
185 unsigned int written;
464 if (
reader->is_empty_element)
465 return &
reader->empty_element;
506 if (str1->
len != str2->
len)
return 0;
711 return reader->input->pending;
716 const int initial_len = 0x2000;
722 buffer->allocated = initial_len;
814 if (readerinput->
stream) {
815 ISequentialStream_Release(readerinput->
stream);
827 hr = IUnknown_QueryInterface(readerinput->
input, &IID_IStream, (
void**)&readerinput->
stream);
829 hr = IUnknown_QueryInterface(readerinput->
input, &IID_ISequentialStream, (
void**)&readerinput->
stream);
875 buffer->allocated = grown_size;
881 static const char startA[] = {
'<',
'?'};
882 static const char commentA[] = {
'<',
'!'};
884 unsigned char *
ptr = (
unsigned char*)
buffer->data;
891 (
ptr[1] && (
ptr[1] <= 0x7f)) ||
892 (
buffer->data[1] >> 5) == 0x6 ||
893 (
buffer->data[1] >> 4) == 0xe ||
894 (
buffer->data[1] >> 3) == 0x1e)
901 static const char utf8bom[] = {0xef,0xbb,0xbf};
902 static const char utf16lebom[] = {0xff,0xfe};
919 else if (*ptrW ==
'<')
926 else if (!
memcmp(
buffer->data, utf8bom,
sizeof(utf8bom)))
928 buffer->cur +=
sizeof(utf8bom);
931 else if (!
memcmp(
buffer->data, utf16lebom,
sizeof(utf16lebom)))
933 buffer->cur +=
sizeof(utf16lebom);
1006 if(prev_cr && *
src ==
'\n')
1014 buffer->prev_cr = prev_cr;
1034 TRACE(
"switching to cp %d\n",
cp);
1050 dest->written += dest_len*
sizeof(
WCHAR);
1079 int len, dest_len, prev_len;
1086 prev_len =
dest->written /
sizeof(
WCHAR);
1102 dest->written += dest_len*
sizeof(
WCHAR);
1113 return reader->input->buffer->utf16.cur;
1145 reader->position.line_position = 1;
1146 else if (ch ==
'\n')
1148 reader->position.line_number++;
1149 reader->position.line_position = 1;
1152 reader->position.line_position++;
1170 return ch ==
' ' || ch ==
'\t' || ch ==
'\r' || ch ==
'\n';
1191 static const WCHAR onedotW[] = {
'1',
'.',0};
1202 while (*
ptr >=
'0' && *
ptr <=
'9')
1217 static const WCHAR eqW[] = {
'=',0};
1229 static const WCHAR versionW[] = {
'v',
'e',
'r',
's',
'i',
'o',
'n',0};
1236 position =
reader->position;
1265 return ((ch >=
'A' && ch <=
'Z') ||
1266 (ch >=
'a' && ch <=
'z') ||
1267 (ch >=
'0' && ch <=
'9') ||
1268 (ch ==
'.') || (ch ==
'_') ||
1305 static const WCHAR encodingW[] = {
'e',
'n',
'c',
'o',
'd',
'i',
'n',
'g',0};
1312 position =
reader->position;
1343 static const WCHAR standaloneW[] = {
's',
't',
'a',
'n',
'd',
'a',
'l',
'o',
'n',
'e',0};
1344 static const WCHAR yesW[] = {
'y',
'e',
's',0};
1345 static const WCHAR noW[] = {
'n',
'o',0};
1353 position =
reader->position;
1387 static const WCHAR xmldeclW[] = {
'<',
'?',
'x',
'm',
'l',
' ',0};
1388 static const WCHAR declcloseW[] = {
'?',
'>',0};
1397 position =
reader->position;
1419 reader->empty_element.position = position;
1488 return (ch ==
'\t') || (ch ==
'\r') || (ch ==
'\n') ||
1489 (ch >= 0x20 && ch <= 0xd7ff) ||
1490 (ch >= 0xd800 && ch <= 0xdbff) ||
1491 (ch >= 0xdc00 && ch <= 0xdfff) ||
1492 (ch >= 0xe000 && ch <= 0xfffd);
1498 return (ch ==
' ') ||
1499 (ch >=
'a' && ch <=
'z') ||
1500 (ch >=
'A' && ch <=
'Z') ||
1501 (ch >=
'0' && ch <=
'9') ||
1502 (ch >=
'-' && ch <=
';') ||
1503 (ch ==
'=') || (ch ==
'?') ||
1504 (ch ==
'@') || (ch ==
'!') ||
1505 (ch >=
'#' && ch <=
'%') ||
1506 (ch ==
'_') || (ch ==
'\r') || (ch ==
'\n');
1511 return (ch ==
':') || (ch >=
'A' && ch <=
'Z') ||
1512 (ch ==
'_') || (ch >=
'a' && ch <=
'z') ||
1513 (ch >= 0xc0 && ch <= 0xd6) ||
1514 (ch >= 0xd8 && ch <= 0xf6) ||
1515 (ch >= 0xf8 && ch <= 0x2ff) ||
1516 (ch >= 0x370 && ch <= 0x37d) ||
1517 (ch >= 0x37f && ch <= 0x1fff) ||
1518 (ch >= 0x200c && ch <= 0x200d) ||
1519 (ch >= 0x2070 && ch <= 0x218f) ||
1520 (ch >= 0x2c00 && ch <= 0x2fef) ||
1521 (ch >= 0x3001 && ch <= 0xd7ff) ||
1522 (ch >= 0xd800 && ch <= 0xdbff) ||
1523 (ch >= 0xdc00 && ch <= 0xdfff) ||
1524 (ch >= 0xf900 && ch <= 0xfdcf) ||
1525 (ch >= 0xfdf0 && ch <= 0xfffd);
1531 return (ch >=
'A' && ch <=
'Z') ||
1532 (ch ==
'_') || (ch >=
'a' && ch <=
'z') ||
1533 (ch ==
'-') || (ch ==
'.') ||
1534 (ch >=
'0' && ch <=
'9') ||
1536 (ch >= 0xc0 && ch <= 0xd6) ||
1537 (ch >= 0xd8 && ch <= 0xf6) ||
1538 (ch >= 0xf8 && ch <= 0x2ff) ||
1539 (ch >= 0x300 && ch <= 0x36f) ||
1540 (ch >= 0x370 && ch <= 0x37d) ||
1541 (ch >= 0x37f && ch <= 0x1fff) ||
1542 (ch >= 0x200c && ch <= 0x200d) ||
1543 (ch >= 0x203f && ch <= 0x2040) ||
1544 (ch >= 0x2070 && ch <= 0x218f) ||
1545 (ch >= 0x2c00 && ch <= 0x2fef) ||
1546 (ch >= 0x3001 && ch <= 0xd7ff) ||
1547 (ch >= 0xd800 && ch <= 0xdbff) ||
1548 (ch >= 0xdc00 && ch <= 0xdfff) ||
1549 (ch >= 0xf900 && ch <= 0xfdcf) ||
1550 (ch >= 0xfdf0 && ch <= 0xfffd);
1611 static const WCHAR xmlW[] = {
'x',
'm',
'l'};
1627 for (
i = 0;
i <
name.len;
i++)
1644 switch (
reader->resumestate)
1705 switch (
reader->resumestate)
1748 switch (
reader->resumestate)
1758 ERR(
"unknown resume state %d\n",
reader->resumestate);
1888 static const WCHAR doctypeW[] = {
'<',
'!',
'D',
'O',
'C',
'T',
'Y',
'P',
'E',0};
1917 FIXME(
"internal subset parsing not implemented\n");
1954 if (check_for_separator && *
ptr ==
':')
2048 static const WCHAR entltW[] = {
'l',
't'};
2049 static const WCHAR entgtW[] = {
'g',
't'};
2050 static const WCHAR entampW[] = {
'a',
'm',
'p'};
2051 static const WCHAR entaposW[] = {
'a',
'p',
'o',
's'};
2052 static const WCHAR entquotW[] = {
'q',
'u',
'o',
't'};
2056 static const strval apos = { (
WCHAR*)entaposW, 4 };
2057 static const strval quot = { (
WCHAR*)entquotW, 4 };
2112 if ((*
ptr >=
'0' && *
ptr <=
'9'))
2113 ch = ch*16 + *
ptr -
'0';
2114 else if ((*
ptr >=
'a' && *
ptr <=
'f'))
2115 ch = ch*16 + *
ptr -
'a' + 10;
2116 else if ((*
ptr >=
'A' && *
ptr <=
'F'))
2117 ch = ch*16 + *
ptr -
'A' + 10;
2128 if ((*
ptr >=
'0' && *
ptr <=
'9'))
2130 ch = ch*10 + *
ptr -
'0';
2276 static const WCHAR endW[] = {
'/',
'>',0};
2319 switch (
reader->resumestate)
2426 if (*
ptr ==
']' && *(
ptr+1) ==
']' && *(
ptr+2) ==
'>')
2476 position =
reader->position;
2479 static const WCHAR ampW[] = {
'&',0};
2482 if (
ptr[0] ==
']' &&
ptr[1] ==
']' &&
ptr[2] ==
'>')
2490 reader->empty_element.position = position;
2515 static const WCHAR cdstartW[] = {
'<',
'!',
'[',
'C',
'D',
'A',
'T',
'A',
'[',0};
2516 static const WCHAR etagW[] = {
'<',
'/',0};
2520 switch (
reader->resumestate)
2532 ERR(
"unknown resume state %d\n",
reader->resumestate);
2565 reader->chunk_read_off = 0;
2576 if (
reader->is_empty_element)
2601 reader->position.line_number = 1;
2602 reader->position.line_position = 1;
2662 WARN(
"found garbage in the end of XML\n");
2673 FIXME(
"internal state %d not handled\n",
reader->instate);
2699 IXmlReader_AddRef(iface);
2714 struct ns *
ns, *ns2;
2732 reader->position.line_number = 0;
2733 reader->position.line_position = 0;
2758 if (
This->input) IUnknown_Release(&
This->input->IXmlReaderInput_iface);
2759 if (
This->resolver) IXmlResolver_Release(
This->resolver);
2760 if (
This->mlang) IUnknown_Release(
This->mlang);
2762 if (imalloc) IMalloc_Release(imalloc);
2779 IUnknown_Release(&
This->input->IXmlReaderInput_iface);
2793 hr = IUnknown_QueryInterface(
input, &IID_IXmlReaderInput, (
void**)&readerinput);
2800 ERR(
"got external IXmlReaderInput implementation: %p, vtbl=%p\n",
2801 readerinput, readerinput->lpVtbl);
2802 IUnknown_Release(readerinput);
2808 if (
hr !=
S_OK || !readerinput)
2840 IUnknown_AddRef(
This->mlang);
2845 IXmlResolver_AddRef(
This->resolver);
2874 IUnknown_Release(
This->mlang);
2877 IUnknown_AddRef(
This->mlang);
2879 FIXME(
"Ignoring MultiLanguage %p\n",
This->mlang);
2883 IXmlResolver_Release(
This->resolver);
2886 IXmlResolver_AddRef(
This->resolver);
2915 switch (
This->state)
2938 *nodetype =
This->nodetype;
2959 reader->chunk_read_off = 0;
3008 static const WCHAR xmlns_uriW[] = {
'h',
't',
't',
'p',
':',
'/',
'/',
'w',
'w',
'w',
'.',
'w',
'3',
'.',
'o',
'r',
'g',
'/',
3009 '2',
'0',
'0',
'0',
'/',
'x',
'm',
'l',
'n',
's',
'/',0};
3010 static const WCHAR xml_uriW[] = {
'h',
't',
't',
'p',
':',
'/',
'/',
'w',
'w',
'w',
'.',
'w',
'3',
'.',
'o',
'r',
'g',
'/',
3011 'X',
'M',
'L',
'/',
'1',
'9',
'9',
'8',
'/',
'n',
'a',
'm',
'e',
's',
'p',
'a',
'c',
'e',0};
3072 UINT target_name_len, target_uri_len;
3080 if (!
This->attr_count)
3087 target_uri_len =
lstrlenW(namespace_uri);
3091 UINT name_len, uri_len;
3097 if (name_len == target_name_len && uri_len == target_uri_len &&
3122 if (
This->is_empty_element) {
3133 This->chunk_read_off = 0;
3254 FIXME(
"Unhandled node type %d\n", nodetype);
3370 return &
reader->attr->value;
3376 if (!
val->str && ensure_allocated)
3403 hr = IXmlReader_Read(iface, &
type);
3418 reader->chunk_read_off = -off;
3433 if (
reader->chunk_read_off >= 0)
3451 UINT *baseUri_length)
3453 FIXME(
"(%p %p %p): stub\n", iface, baseUri, baseUri_length);
3459 FIXME(
"(%p): stub\n", iface);
3509 TRACE(
"(%p %p)\n",
This, line_position);
3522 *line_position =
This->attr->position.line_position;
3526 *line_position =
This->empty_element.position.line_position;
3529 *line_position =
This->position.line_position;
3559 TRACE(
"(%p)\n", iface);
3612 IUnknown_AddRef(iface);
3635 if (
This->input) IUnknown_Release(
This->input);
3636 if (
This->stream) ISequentialStream_Release(
This->stream);
3640 if (imalloc) IMalloc_Release(imalloc);
3675 reader->imalloc = imalloc;
3676 if (imalloc) IMalloc_AddRef(imalloc);
3684 reader->chunk_read_off = 0;
3689 IXmlReader_Release(&
reader->IXmlReader_iface);
3691 TRACE(
"returning iface %p, hr %#x\n", *
obj,
hr);
3712 readerinput = IMalloc_Alloc(imalloc,
sizeof(*readerinput));
3714 readerinput =
heap_alloc(
sizeof(*readerinput));
3718 readerinput->
ref = 1;
3719 readerinput->
imalloc = imalloc;
3721 if (imalloc) IMalloc_AddRef(imalloc);