1 /* 2 * SAX Reader implementation 3 * 4 * Copyright 2008 Alistair Leslie-Hughes 5 * Copyright 2008 Piotr Caban 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 #define COBJMACROS 22 23 #include "config.h" 24 25 #include <stdarg.h> 26 #ifdef HAVE_LIBXML2 27 # include <libxml/parser.h> 28 # include <libxml/xmlerror.h> 29 # include <libxml/SAX2.h> 30 # include <libxml/parserInternals.h> 31 #endif 32 33 #include "windef.h" 34 #include "winbase.h" 35 #include "winuser.h" 36 #include "winnls.h" 37 #include "ole2.h" 38 #include "msxml6.h" 39 #include "wininet.h" 40 #include "urlmon.h" 41 #include "winreg.h" 42 #include "shlwapi.h" 43 44 #include "wine/debug.h" 45 46 #include "msxml_private.h" 47 48 #ifdef HAVE_LIBXML2 49 50 WINE_DEFAULT_DEBUG_CHANNEL(msxml); 51 52 typedef enum 53 { 54 FeatureUnknown = 0, 55 ExhaustiveErrors = 1 << 1, 56 ExternalGeneralEntities = 1 << 2, 57 ExternalParameterEntities = 1 << 3, 58 ForcedResync = 1 << 4, 59 NamespacePrefixes = 1 << 5, 60 Namespaces = 1 << 6, 61 ParameterEntities = 1 << 7, 62 PreserveSystemIndentifiers = 1 << 8, 63 ProhibitDTD = 1 << 9, 64 SchemaValidation = 1 << 10, 65 ServerHttpRequest = 1 << 11, 66 SuppressValidationfatalError = 1 << 12, 67 UseInlineSchema = 1 << 13, 68 UseSchemaLocation = 1 << 14, 69 LexicalHandlerParEntities = 1 << 15 70 } saxreader_feature; 71 72 /* feature names */ 73 static const WCHAR FeatureExternalGeneralEntitiesW[] = { 74 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/', 75 'f','e','a','t','u','r','e','s','/','e','x','t','e','r','n','a','l','-','g','e','n','e','r','a','l', 76 '-','e','n','t','i','t','i','e','s',0 77 }; 78 79 static const WCHAR FeatureExternalParameterEntitiesW[] = { 80 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s', 81 '/','e','x','t','e','r','n','a','l','-','p','a','r','a','m','e','t','e','r','-','e','n','t','i','t','i','e','s',0 82 }; 83 84 static const WCHAR FeatureLexicalHandlerParEntitiesW[] = { 85 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s', 86 '/','l','e','x','i','c','a','l','-','h','a','n','d','l','e','r','/','p','a','r','a','m','e','t','e','r','-','e','n','t','i','t','i','e','s',0 87 }; 88 89 static const WCHAR FeatureProhibitDTDW[] = { 90 'p','r','o','h','i','b','i','t','-','d','t','d',0 91 }; 92 93 static const WCHAR FeatureNamespacesW[] = { 94 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s', 95 '/','n','a','m','e','s','p','a','c','e','s',0 96 }; 97 98 static const WCHAR FeatureNamespacePrefixesW[] = { 99 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s', 100 '/','n','a','m','e','s','p','a','c','e','-','p','r','e','f','i','x','e','s',0 101 }; 102 103 static const WCHAR ExhaustiveErrorsW[] = { 104 'e','x','h','a','u','s','t','i','v','e','-','e','r','r','o','r','s',0 105 }; 106 107 static const WCHAR SchemaValidationW[] = { 108 's','c','h','e','m','a','-','v','a','l','i','d','a','t','i','o','n',0 109 }; 110 111 struct saxreader_feature_pair 112 { 113 saxreader_feature feature; 114 const WCHAR *name; 115 }; 116 117 static const struct saxreader_feature_pair saxreader_feature_map[] = { 118 { ExhaustiveErrors, ExhaustiveErrorsW }, 119 { ExternalGeneralEntities, FeatureExternalGeneralEntitiesW }, 120 { ExternalParameterEntities, FeatureExternalParameterEntitiesW }, 121 { LexicalHandlerParEntities, FeatureLexicalHandlerParEntitiesW }, 122 { NamespacePrefixes, FeatureNamespacePrefixesW }, 123 { Namespaces, FeatureNamespacesW }, 124 { ProhibitDTD, FeatureProhibitDTDW }, 125 { SchemaValidation, SchemaValidationW }, 126 }; 127 128 static saxreader_feature get_saxreader_feature(const WCHAR *name) 129 { 130 int min, max, n, c; 131 132 min = 0; 133 max = ARRAY_SIZE(saxreader_feature_map) - 1; 134 135 while (min <= max) 136 { 137 n = (min+max)/2; 138 139 c = strcmpW(saxreader_feature_map[n].name, name); 140 if (!c) 141 return saxreader_feature_map[n].feature; 142 143 if (c > 0) 144 max = n-1; 145 else 146 min = n+1; 147 } 148 149 return FeatureUnknown; 150 } 151 152 struct bstrpool 153 { 154 BSTR *pool; 155 unsigned int index; 156 unsigned int len; 157 }; 158 159 typedef struct 160 { 161 BSTR prefix; 162 BSTR uri; 163 } ns; 164 165 typedef struct 166 { 167 struct list entry; 168 BSTR prefix; 169 BSTR local; 170 BSTR qname; 171 ns *ns; /* namespaces defined in this particular element */ 172 int ns_count; 173 } element_entry; 174 175 enum saxhandler_type 176 { 177 SAXContentHandler = 0, 178 SAXDeclHandler, 179 SAXDTDHandler, 180 SAXEntityResolver, 181 SAXErrorHandler, 182 SAXLexicalHandler, 183 SAXHandler_Last 184 }; 185 186 struct saxanyhandler_iface 187 { 188 IUnknown *handler; 189 IUnknown *vbhandler; 190 }; 191 192 struct saxcontenthandler_iface 193 { 194 ISAXContentHandler *handler; 195 IVBSAXContentHandler *vbhandler; 196 }; 197 198 struct saxerrorhandler_iface 199 { 200 ISAXErrorHandler *handler; 201 IVBSAXErrorHandler *vbhandler; 202 }; 203 204 struct saxlexicalhandler_iface 205 { 206 ISAXLexicalHandler *handler; 207 IVBSAXLexicalHandler *vbhandler; 208 }; 209 210 struct saxentityresolver_iface 211 { 212 ISAXEntityResolver *handler; 213 IVBSAXEntityResolver *vbhandler; 214 }; 215 216 struct saxhandler_iface 217 { 218 union { 219 struct saxcontenthandler_iface content; 220 struct saxentityresolver_iface entityresolver; 221 struct saxerrorhandler_iface error; 222 struct saxlexicalhandler_iface lexical; 223 struct saxanyhandler_iface anyhandler; 224 } u; 225 }; 226 227 typedef struct 228 { 229 DispatchEx dispex; 230 IVBSAXXMLReader IVBSAXXMLReader_iface; 231 ISAXXMLReader ISAXXMLReader_iface; 232 LONG ref; 233 234 struct saxhandler_iface saxhandlers[SAXHandler_Last]; 235 xmlSAXHandler sax; 236 BOOL isParsing; 237 struct bstrpool pool; 238 saxreader_feature features; 239 BSTR xmldecl_version; 240 MSXML_VERSION version; 241 } saxreader; 242 243 static HRESULT saxreader_put_handler(saxreader *reader, enum saxhandler_type type, void *ptr, BOOL vb) 244 { 245 struct saxanyhandler_iface *iface = &reader->saxhandlers[type].u.anyhandler; 246 IUnknown *unk = (IUnknown*)ptr; 247 248 if (unk) 249 IUnknown_AddRef(unk); 250 251 if ((vb && iface->vbhandler) || (!vb && iface->handler)) 252 IUnknown_Release(vb ? iface->vbhandler : iface->handler); 253 254 if (vb) 255 iface->vbhandler = unk; 256 else 257 iface->handler = unk; 258 259 return S_OK; 260 } 261 262 static HRESULT saxreader_get_handler(const saxreader *reader, enum saxhandler_type type, BOOL vb, void **ret) 263 { 264 const struct saxanyhandler_iface *iface = &reader->saxhandlers[type].u.anyhandler; 265 266 if (!ret) return E_POINTER; 267 268 if ((vb && iface->vbhandler) || (!vb && iface->handler)) 269 { 270 if (vb) 271 IUnknown_AddRef(iface->vbhandler); 272 else 273 IUnknown_AddRef(iface->handler); 274 } 275 276 *ret = vb ? iface->vbhandler : iface->handler; 277 278 return S_OK; 279 } 280 281 static struct saxcontenthandler_iface *saxreader_get_contenthandler(saxreader *reader) 282 { 283 return &reader->saxhandlers[SAXContentHandler].u.content; 284 } 285 286 static struct saxerrorhandler_iface *saxreader_get_errorhandler(saxreader *reader) 287 { 288 return &reader->saxhandlers[SAXErrorHandler].u.error; 289 } 290 291 static struct saxlexicalhandler_iface *saxreader_get_lexicalhandler(saxreader *reader) 292 { 293 return &reader->saxhandlers[SAXLexicalHandler].u.lexical; 294 } 295 296 typedef struct 297 { 298 IVBSAXLocator IVBSAXLocator_iface; 299 ISAXLocator ISAXLocator_iface; 300 IVBSAXAttributes IVBSAXAttributes_iface; 301 ISAXAttributes ISAXAttributes_iface; 302 LONG ref; 303 saxreader *saxreader; 304 HRESULT ret; 305 xmlParserCtxtPtr pParserCtxt; 306 BSTR publicId; 307 BSTR systemId; 308 int line; 309 int column; 310 BOOL vbInterface; 311 struct list elements; 312 313 BSTR namespaceUri; 314 int attr_alloc_count; 315 int attr_count; 316 struct _attributes 317 { 318 BSTR szLocalname; 319 BSTR szURI; 320 BSTR szValue; 321 BSTR szQName; 322 } *attributes; 323 } saxlocator; 324 325 static inline saxreader *impl_from_IVBSAXXMLReader( IVBSAXXMLReader *iface ) 326 { 327 return CONTAINING_RECORD(iface, saxreader, IVBSAXXMLReader_iface); 328 } 329 330 static inline saxreader *impl_from_ISAXXMLReader( ISAXXMLReader *iface ) 331 { 332 return CONTAINING_RECORD(iface, saxreader, ISAXXMLReader_iface); 333 } 334 335 static inline saxlocator *impl_from_IVBSAXLocator( IVBSAXLocator *iface ) 336 { 337 return CONTAINING_RECORD(iface, saxlocator, IVBSAXLocator_iface); 338 } 339 340 static inline saxlocator *impl_from_ISAXLocator( ISAXLocator *iface ) 341 { 342 return CONTAINING_RECORD(iface, saxlocator, ISAXLocator_iface); 343 } 344 345 static inline saxlocator *impl_from_IVBSAXAttributes( IVBSAXAttributes *iface ) 346 { 347 return CONTAINING_RECORD(iface, saxlocator, IVBSAXAttributes_iface); 348 } 349 350 static inline saxlocator *impl_from_ISAXAttributes( ISAXAttributes *iface ) 351 { 352 return CONTAINING_RECORD(iface, saxlocator, ISAXAttributes_iface); 353 } 354 355 static inline BOOL saxreader_has_handler(const saxlocator *locator, enum saxhandler_type type) 356 { 357 struct saxanyhandler_iface *iface = &locator->saxreader->saxhandlers[type].u.anyhandler; 358 return (locator->vbInterface && iface->vbhandler) || (!locator->vbInterface && iface->handler); 359 } 360 361 static HRESULT saxreader_saxcharacters(saxlocator *locator, BSTR chars) 362 { 363 struct saxcontenthandler_iface *content = saxreader_get_contenthandler(locator->saxreader); 364 HRESULT hr; 365 366 if (!saxreader_has_handler(locator, SAXContentHandler)) return S_OK; 367 368 if (locator->vbInterface) 369 hr = IVBSAXContentHandler_characters(content->vbhandler, &chars); 370 else 371 hr = ISAXContentHandler_characters(content->handler, chars, SysStringLen(chars)); 372 373 return hr; 374 } 375 376 /* property names */ 377 static const WCHAR PropertyCharsetW[] = { 378 'c','h','a','r','s','e','t',0 379 }; 380 static const WCHAR PropertyXmlDeclVersionW[] = { 381 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0 382 }; 383 static const WCHAR PropertyDeclHandlerW[] = { 384 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/', 385 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/', 386 'd','e','c','l','a','r','a','t','i','o','n', 387 '-','h','a','n','d','l','e','r',0 388 }; 389 static const WCHAR PropertyDomNodeW[] = { 390 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/', 391 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/', 392 'd','o','m','-','n','o','d','e',0 393 }; 394 static const WCHAR PropertyInputSourceW[] = { 395 'i','n','p','u','t','-','s','o','u','r','c','e',0 396 }; 397 static const WCHAR PropertyLexicalHandlerW[] = { 398 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/', 399 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/', 400 'l','e','x','i','c','a','l','-','h','a','n','d','l','e','r',0 401 }; 402 static const WCHAR PropertyMaxElementDepthW[] = { 403 'm','a','x','-','e','l','e','m','e','n','t','-','d','e','p','t','h',0 404 }; 405 static const WCHAR PropertyMaxXMLSizeW[] = { 406 'm','a','x','-','x','m','l','-','s','i','z','e',0 407 }; 408 static const WCHAR PropertySchemaDeclHandlerW[] = { 409 's','c','h','e','m','a','-','d','e','c','l','a','r','a','t','i','o','n','-', 410 'h','a','n','d','l','e','r',0 411 }; 412 static const WCHAR PropertyXMLDeclEncodingW[] = { 413 'x','m','l','d','e','c','l','-','e','n','c','o','d','i','n','g',0 414 }; 415 static const WCHAR PropertyXMLDeclStandaloneW[] = { 416 'x','m','l','d','e','c','l','-','s','t','a','n','d','a','l','o','n','e',0 417 }; 418 static const WCHAR PropertyXMLDeclVersionW[] = { 419 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0 420 }; 421 422 static inline HRESULT set_feature_value(saxreader *reader, saxreader_feature feature, VARIANT_BOOL value) 423 { 424 /* handling of non-VARIANT_* values is version dependent */ 425 if ((reader->version < MSXML4) && (value != VARIANT_TRUE)) 426 value = VARIANT_FALSE; 427 if ((reader->version >= MSXML4) && (value != VARIANT_FALSE)) 428 value = VARIANT_TRUE; 429 430 if (value == VARIANT_TRUE) 431 reader->features |= feature; 432 else 433 reader->features &= ~feature; 434 435 return S_OK; 436 } 437 438 static inline HRESULT get_feature_value(const saxreader *reader, saxreader_feature feature, VARIANT_BOOL *value) 439 { 440 *value = reader->features & feature ? VARIANT_TRUE : VARIANT_FALSE; 441 return S_OK; 442 } 443 444 static BOOL is_namespaces_enabled(const saxreader *reader) 445 { 446 return (reader->version < MSXML4) || (reader->features & Namespaces); 447 } 448 449 static BSTR build_qname(BSTR prefix, BSTR local) 450 { 451 if (prefix && *prefix) 452 { 453 BSTR qname = SysAllocStringLen(NULL, SysStringLen(prefix) + SysStringLen(local) + 1); 454 WCHAR *ptr; 455 456 ptr = qname; 457 strcpyW(ptr, prefix); 458 ptr += SysStringLen(prefix); 459 *ptr++ = ':'; 460 strcpyW(ptr, local); 461 return qname; 462 } 463 else 464 return SysAllocString(local); 465 } 466 467 static element_entry* alloc_element_entry(const xmlChar *local, const xmlChar *prefix, int nb_ns, 468 const xmlChar **namespaces) 469 { 470 element_entry *ret; 471 int i; 472 473 ret = heap_alloc(sizeof(*ret)); 474 if (!ret) return ret; 475 476 ret->local = bstr_from_xmlChar(local); 477 ret->prefix = bstr_from_xmlChar(prefix); 478 ret->qname = build_qname(ret->prefix, ret->local); 479 ret->ns = nb_ns ? heap_alloc(nb_ns*sizeof(ns)) : NULL; 480 ret->ns_count = nb_ns; 481 482 for (i=0; i < nb_ns; i++) 483 { 484 ret->ns[i].prefix = bstr_from_xmlChar(namespaces[2*i]); 485 ret->ns[i].uri = bstr_from_xmlChar(namespaces[2*i+1]); 486 } 487 488 return ret; 489 } 490 491 static void free_element_entry(element_entry *element) 492 { 493 int i; 494 495 for (i=0; i<element->ns_count;i++) 496 { 497 SysFreeString(element->ns[i].prefix); 498 SysFreeString(element->ns[i].uri); 499 } 500 501 SysFreeString(element->prefix); 502 SysFreeString(element->local); 503 SysFreeString(element->qname); 504 505 heap_free(element->ns); 506 heap_free(element); 507 } 508 509 static void push_element_ns(saxlocator *locator, element_entry *element) 510 { 511 list_add_head(&locator->elements, &element->entry); 512 } 513 514 static element_entry * pop_element_ns(saxlocator *locator) 515 { 516 element_entry *element = LIST_ENTRY(list_head(&locator->elements), element_entry, entry); 517 518 if (element) 519 list_remove(&element->entry); 520 521 return element; 522 } 523 524 static BSTR find_element_uri(saxlocator *locator, const xmlChar *uri) 525 { 526 element_entry *element; 527 BSTR uriW; 528 int i; 529 530 if (!uri) return NULL; 531 532 uriW = bstr_from_xmlChar(uri); 533 534 LIST_FOR_EACH_ENTRY(element, &locator->elements, element_entry, entry) 535 { 536 for (i=0; i < element->ns_count; i++) 537 if (!strcmpW(uriW, element->ns[i].uri)) 538 { 539 SysFreeString(uriW); 540 return element->ns[i].uri; 541 } 542 } 543 544 SysFreeString(uriW); 545 ERR("namespace uri not found, %s\n", debugstr_a((char*)uri)); 546 return NULL; 547 } 548 549 /* used to localize version dependent error check behaviour */ 550 static inline BOOL sax_callback_failed(saxlocator *This, HRESULT hr) 551 { 552 return This->saxreader->version >= MSXML4 ? FAILED(hr) : hr != S_OK; 553 } 554 555 /* index value -1 means it tries to loop for a first time */ 556 static inline BOOL iterate_endprefix_index(saxlocator *This, const element_entry *element, int *i) 557 { 558 if (This->saxreader->version >= MSXML4) 559 { 560 if (*i == -1) *i = 0; else ++*i; 561 return *i < element->ns_count; 562 } 563 else 564 { 565 if (*i == -1) *i = element->ns_count-1; else --*i; 566 return *i >= 0; 567 } 568 } 569 570 static BOOL bstr_pool_insert(struct bstrpool *pool, BSTR pool_entry) 571 { 572 if (!pool->pool) 573 { 574 pool->pool = heap_alloc(16 * sizeof(*pool->pool)); 575 if (!pool->pool) 576 return FALSE; 577 578 pool->index = 0; 579 pool->len = 16; 580 } 581 else if (pool->index == pool->len) 582 { 583 BSTR *realloc = heap_realloc(pool->pool, pool->len * 2 * sizeof(*realloc)); 584 585 if (!realloc) 586 return FALSE; 587 588 pool->pool = realloc; 589 pool->len *= 2; 590 } 591 592 pool->pool[pool->index++] = pool_entry; 593 return TRUE; 594 } 595 596 static void free_bstr_pool(struct bstrpool *pool) 597 { 598 unsigned int i; 599 600 for (i = 0; i < pool->index; i++) 601 SysFreeString(pool->pool[i]); 602 603 heap_free(pool->pool); 604 605 pool->pool = NULL; 606 pool->index = pool->len = 0; 607 } 608 609 static BSTR bstr_from_xmlCharN(const xmlChar *buf, int len) 610 { 611 DWORD dLen; 612 BSTR bstr; 613 614 if (!buf) 615 return NULL; 616 617 dLen = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, NULL, 0); 618 if(len != -1) dLen++; 619 bstr = SysAllocStringLen(NULL, dLen-1); 620 if (!bstr) 621 return NULL; 622 MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, bstr, dLen); 623 if(len != -1) bstr[dLen-1] = '\0'; 624 625 return bstr; 626 } 627 628 static BSTR QName_from_xmlChar(const xmlChar *prefix, const xmlChar *name) 629 { 630 xmlChar *qname; 631 BSTR bstr; 632 633 if(!name) return NULL; 634 635 if(!prefix || !*prefix) 636 return bstr_from_xmlChar(name); 637 638 qname = xmlBuildQName(name, prefix, NULL, 0); 639 bstr = bstr_from_xmlChar(qname); 640 xmlFree(qname); 641 642 return bstr; 643 } 644 645 static BSTR pooled_bstr_from_xmlChar(struct bstrpool *pool, const xmlChar *buf) 646 { 647 BSTR pool_entry = bstr_from_xmlChar(buf); 648 649 if (pool_entry && !bstr_pool_insert(pool, pool_entry)) 650 { 651 SysFreeString(pool_entry); 652 return NULL; 653 } 654 655 return pool_entry; 656 } 657 658 static BSTR pooled_bstr_from_xmlCharN(struct bstrpool *pool, const xmlChar *buf, int len) 659 { 660 BSTR pool_entry = bstr_from_xmlCharN(buf, len); 661 662 if (pool_entry && !bstr_pool_insert(pool, pool_entry)) 663 { 664 SysFreeString(pool_entry); 665 return NULL; 666 } 667 668 return pool_entry; 669 } 670 671 static void format_error_message_from_id(saxlocator *This, HRESULT hr) 672 { 673 struct saxerrorhandler_iface *handler = saxreader_get_errorhandler(This->saxreader); 674 xmlStopParser(This->pParserCtxt); 675 This->ret = hr; 676 677 if (saxreader_has_handler(This, SAXErrorHandler)) 678 { 679 WCHAR msg[1024]; 680 if(!FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, 681 NULL, hr, 0, msg, ARRAY_SIZE(msg), NULL)) 682 { 683 FIXME("MSXML errors not yet supported.\n"); 684 msg[0] = '\0'; 685 } 686 687 if(This->vbInterface) 688 { 689 BSTR bstrMsg = SysAllocString(msg); 690 IVBSAXErrorHandler_fatalError(handler->vbhandler, 691 &This->IVBSAXLocator_iface, &bstrMsg, hr); 692 SysFreeString(bstrMsg); 693 } 694 else 695 ISAXErrorHandler_fatalError(handler->handler, 696 &This->ISAXLocator_iface, msg, hr); 697 } 698 } 699 700 static void update_position(saxlocator *This, BOOL fix_column) 701 { 702 const xmlChar *p = This->pParserCtxt->input->cur-1; 703 const xmlChar *baseP = This->pParserCtxt->input->base; 704 705 This->line = xmlSAX2GetLineNumber(This->pParserCtxt); 706 if(fix_column) 707 { 708 This->column = 1; 709 for(;p>=baseP && *p!='\n' && *p!='\r'; p--) 710 This->column++; 711 } 712 else 713 { 714 This->column = xmlSAX2GetColumnNumber(This->pParserCtxt); 715 } 716 } 717 718 /*** IVBSAXAttributes interface ***/ 719 static HRESULT WINAPI ivbsaxattributes_QueryInterface( 720 IVBSAXAttributes* iface, 721 REFIID riid, 722 void **ppvObject) 723 { 724 saxlocator *This = impl_from_IVBSAXAttributes(iface); 725 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject); 726 return IVBSAXLocator_QueryInterface(&This->IVBSAXLocator_iface, riid, ppvObject); 727 } 728 729 static ULONG WINAPI ivbsaxattributes_AddRef(IVBSAXAttributes* iface) 730 { 731 saxlocator *This = impl_from_IVBSAXAttributes(iface); 732 return IVBSAXLocator_AddRef(&This->IVBSAXLocator_iface); 733 } 734 735 static ULONG WINAPI ivbsaxattributes_Release(IVBSAXAttributes* iface) 736 { 737 saxlocator *This = impl_from_IVBSAXAttributes(iface); 738 return IVBSAXLocator_Release(&This->IVBSAXLocator_iface); 739 } 740 741 static HRESULT WINAPI ivbsaxattributes_GetTypeInfoCount( IVBSAXAttributes *iface, UINT* pctinfo ) 742 { 743 saxlocator *This = impl_from_IVBSAXAttributes( iface ); 744 745 TRACE("(%p)->(%p)\n", This, pctinfo); 746 747 *pctinfo = 1; 748 749 return S_OK; 750 } 751 752 static HRESULT WINAPI ivbsaxattributes_GetTypeInfo( 753 IVBSAXAttributes *iface, 754 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo ) 755 { 756 saxlocator *This = impl_from_IVBSAXAttributes( iface ); 757 758 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); 759 760 return get_typeinfo(IVBSAXAttributes_tid, ppTInfo); 761 } 762 763 static HRESULT WINAPI ivbsaxattributes_GetIDsOfNames( 764 IVBSAXAttributes *iface, 765 REFIID riid, 766 LPOLESTR* rgszNames, 767 UINT cNames, 768 LCID lcid, 769 DISPID* rgDispId) 770 { 771 saxlocator *This = impl_from_IVBSAXAttributes( iface ); 772 ITypeInfo *typeinfo; 773 HRESULT hr; 774 775 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, 776 lcid, rgDispId); 777 778 if(!rgszNames || cNames == 0 || !rgDispId) 779 return E_INVALIDARG; 780 781 hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo); 782 if(SUCCEEDED(hr)) 783 { 784 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId); 785 ITypeInfo_Release(typeinfo); 786 } 787 788 return hr; 789 } 790 791 static HRESULT WINAPI ivbsaxattributes_Invoke( 792 IVBSAXAttributes *iface, 793 DISPID dispIdMember, 794 REFIID riid, 795 LCID lcid, 796 WORD wFlags, 797 DISPPARAMS* pDispParams, 798 VARIANT* pVarResult, 799 EXCEPINFO* pExcepInfo, 800 UINT* puArgErr) 801 { 802 saxlocator *This = impl_from_IVBSAXAttributes( iface ); 803 ITypeInfo *typeinfo; 804 HRESULT hr; 805 806 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), 807 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 808 809 hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo); 810 if(SUCCEEDED(hr)) 811 { 812 hr = ITypeInfo_Invoke(typeinfo, &This->IVBSAXAttributes_iface, dispIdMember, wFlags, 813 pDispParams, pVarResult, pExcepInfo, puArgErr); 814 ITypeInfo_Release(typeinfo); 815 } 816 817 return hr; 818 } 819 820 /*** IVBSAXAttributes methods ***/ 821 static HRESULT WINAPI ivbsaxattributes_get_length( 822 IVBSAXAttributes* iface, 823 int *nLength) 824 { 825 saxlocator *This = impl_from_IVBSAXAttributes( iface ); 826 return ISAXAttributes_getLength(&This->ISAXAttributes_iface, nLength); 827 } 828 829 static HRESULT WINAPI ivbsaxattributes_getURI( 830 IVBSAXAttributes* iface, 831 int nIndex, 832 BSTR *uri) 833 { 834 saxlocator *This = impl_from_IVBSAXAttributes( iface ); 835 const WCHAR *uriW; 836 HRESULT hr; 837 int len; 838 839 TRACE("(%p)->(%d %p)\n", This, nIndex, uri); 840 841 if (!uri) 842 return E_POINTER; 843 844 *uri = NULL; 845 hr = ISAXAttributes_getURI(&This->ISAXAttributes_iface, nIndex, &uriW, &len); 846 if (FAILED(hr)) 847 return hr; 848 849 return return_bstrn(uriW, len, uri); 850 } 851 852 static HRESULT WINAPI ivbsaxattributes_getLocalName( 853 IVBSAXAttributes* iface, 854 int nIndex, 855 BSTR *name) 856 { 857 saxlocator *This = impl_from_IVBSAXAttributes( iface ); 858 const WCHAR *nameW; 859 HRESULT hr; 860 int len; 861 862 TRACE("(%p)->(%d %p)\n", This, nIndex, name); 863 864 if (!name) 865 return E_POINTER; 866 867 *name = NULL; 868 hr = ISAXAttributes_getLocalName(&This->ISAXAttributes_iface, nIndex, &nameW, &len); 869 if (FAILED(hr)) 870 return hr; 871 872 return return_bstrn(nameW, len, name); 873 } 874 875 static HRESULT WINAPI ivbsaxattributes_getQName( 876 IVBSAXAttributes* iface, 877 int nIndex, 878 BSTR *QName) 879 { 880 saxlocator *This = impl_from_IVBSAXAttributes( iface ); 881 const WCHAR *nameW; 882 HRESULT hr; 883 int len; 884 885 TRACE("(%p)->(%d %p)\n", This, nIndex, QName); 886 887 if (!QName) 888 return E_POINTER; 889 890 *QName = NULL; 891 hr = ISAXAttributes_getQName(&This->ISAXAttributes_iface, nIndex, &nameW, &len); 892 if (FAILED(hr)) 893 return hr; 894 895 return return_bstrn(nameW, len, QName); 896 } 897 898 static HRESULT WINAPI ivbsaxattributes_getIndexFromName( 899 IVBSAXAttributes* iface, 900 BSTR uri, 901 BSTR localName, 902 int *index) 903 { 904 saxlocator *This = impl_from_IVBSAXAttributes( iface ); 905 return ISAXAttributes_getIndexFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri), 906 localName, SysStringLen(localName), index); 907 } 908 909 static HRESULT WINAPI ivbsaxattributes_getIndexFromQName( 910 IVBSAXAttributes* iface, 911 BSTR QName, 912 int *index) 913 { 914 saxlocator *This = impl_from_IVBSAXAttributes( iface ); 915 return ISAXAttributes_getIndexFromQName(&This->ISAXAttributes_iface, QName, 916 SysStringLen(QName), index); 917 } 918 919 static HRESULT WINAPI ivbsaxattributes_getType( 920 IVBSAXAttributes* iface, 921 int nIndex, 922 BSTR *type) 923 { 924 saxlocator *This = impl_from_IVBSAXAttributes( iface ); 925 const WCHAR *typeW; 926 HRESULT hr; 927 int len; 928 929 TRACE("(%p)->(%d %p)\n", This, nIndex, type); 930 931 if (!type) 932 return E_POINTER; 933 934 *type = NULL; 935 hr = ISAXAttributes_getType(&This->ISAXAttributes_iface, nIndex, &typeW, &len); 936 if (FAILED(hr)) 937 return hr; 938 939 return return_bstrn(typeW, len, type); 940 } 941 942 static HRESULT WINAPI ivbsaxattributes_getTypeFromName( 943 IVBSAXAttributes* iface, 944 BSTR uri, 945 BSTR localName, 946 BSTR *type) 947 { 948 saxlocator *This = impl_from_IVBSAXAttributes( iface ); 949 const WCHAR *typeW; 950 HRESULT hr; 951 int len; 952 953 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(uri), debugstr_w(localName), type); 954 955 if (!type) 956 return E_POINTER; 957 958 *type = NULL; 959 hr = ISAXAttributes_getTypeFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri), 960 localName, SysStringLen(localName), &typeW, &len); 961 if (FAILED(hr)) 962 return hr; 963 964 return return_bstrn(typeW, len, type); 965 } 966 967 static HRESULT WINAPI ivbsaxattributes_getTypeFromQName( 968 IVBSAXAttributes* iface, 969 BSTR QName, 970 BSTR *type) 971 { 972 saxlocator *This = impl_from_IVBSAXAttributes( iface ); 973 const WCHAR *typeW; 974 HRESULT hr; 975 int len; 976 977 TRACE("(%p)->(%s %p)\n", This, debugstr_w(QName), type); 978 979 if (!type) 980 return E_POINTER; 981 982 *type = NULL; 983 hr = ISAXAttributes_getTypeFromQName(&This->ISAXAttributes_iface, QName, SysStringLen(QName), 984 &typeW, &len); 985 if (FAILED(hr)) 986 return hr; 987 988 return return_bstrn(typeW, len, type); 989 } 990 991 static HRESULT WINAPI ivbsaxattributes_getValue( 992 IVBSAXAttributes* iface, 993 int nIndex, 994 BSTR *value) 995 { 996 saxlocator *This = impl_from_IVBSAXAttributes( iface ); 997 const WCHAR *valueW; 998 HRESULT hr; 999 int len; 1000 1001 TRACE("(%p)->(%d %p)\n", This, nIndex, value); 1002 1003 if (!value) 1004 return E_POINTER; 1005 1006 *value = NULL; 1007 hr = ISAXAttributes_getValue(&This->ISAXAttributes_iface, nIndex, &valueW, &len); 1008 if (FAILED(hr)) 1009 return hr; 1010 1011 return return_bstrn(valueW, len, value); 1012 } 1013 1014 static HRESULT WINAPI ivbsaxattributes_getValueFromName( 1015 IVBSAXAttributes* iface, 1016 BSTR uri, 1017 BSTR localName, 1018 BSTR *value) 1019 { 1020 saxlocator *This = impl_from_IVBSAXAttributes( iface ); 1021 const WCHAR *valueW; 1022 HRESULT hr; 1023 int len; 1024 1025 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(uri), debugstr_w(localName), value); 1026 1027 if (!value) 1028 return E_POINTER; 1029 1030 *value = NULL; 1031 hr = ISAXAttributes_getValueFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri), 1032 localName, SysStringLen(localName), &valueW, &len); 1033 if (FAILED(hr)) 1034 return hr; 1035 1036 return return_bstrn(valueW, len, value); 1037 } 1038 1039 static HRESULT WINAPI ivbsaxattributes_getValueFromQName( 1040 IVBSAXAttributes* iface, 1041 BSTR QName, 1042 BSTR *value) 1043 { 1044 saxlocator *This = impl_from_IVBSAXAttributes( iface ); 1045 const WCHAR *valueW; 1046 HRESULT hr; 1047 int len; 1048 1049 TRACE("(%p)->(%s %p)\n", This, debugstr_w(QName), value); 1050 1051 if (!value) 1052 return E_POINTER; 1053 1054 *value = NULL; 1055 hr = ISAXAttributes_getValueFromQName(&This->ISAXAttributes_iface, QName, 1056 SysStringLen(QName), &valueW, &len); 1057 if (FAILED(hr)) 1058 return hr; 1059 1060 return return_bstrn(valueW, len, value); 1061 } 1062 1063 static const struct IVBSAXAttributesVtbl ivbsaxattributes_vtbl = 1064 { 1065 ivbsaxattributes_QueryInterface, 1066 ivbsaxattributes_AddRef, 1067 ivbsaxattributes_Release, 1068 ivbsaxattributes_GetTypeInfoCount, 1069 ivbsaxattributes_GetTypeInfo, 1070 ivbsaxattributes_GetIDsOfNames, 1071 ivbsaxattributes_Invoke, 1072 ivbsaxattributes_get_length, 1073 ivbsaxattributes_getURI, 1074 ivbsaxattributes_getLocalName, 1075 ivbsaxattributes_getQName, 1076 ivbsaxattributes_getIndexFromName, 1077 ivbsaxattributes_getIndexFromQName, 1078 ivbsaxattributes_getType, 1079 ivbsaxattributes_getTypeFromName, 1080 ivbsaxattributes_getTypeFromQName, 1081 ivbsaxattributes_getValue, 1082 ivbsaxattributes_getValueFromName, 1083 ivbsaxattributes_getValueFromQName 1084 }; 1085 1086 /*** ISAXAttributes interface ***/ 1087 /*** IUnknown methods ***/ 1088 static HRESULT WINAPI isaxattributes_QueryInterface( 1089 ISAXAttributes* iface, 1090 REFIID riid, 1091 void **ppvObject) 1092 { 1093 saxlocator *This = impl_from_ISAXAttributes(iface); 1094 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject); 1095 return ISAXLocator_QueryInterface(&This->ISAXLocator_iface, riid, ppvObject); 1096 } 1097 1098 static ULONG WINAPI isaxattributes_AddRef(ISAXAttributes* iface) 1099 { 1100 saxlocator *This = impl_from_ISAXAttributes(iface); 1101 TRACE("%p\n", This); 1102 return ISAXLocator_AddRef(&This->ISAXLocator_iface); 1103 } 1104 1105 static ULONG WINAPI isaxattributes_Release(ISAXAttributes* iface) 1106 { 1107 saxlocator *This = impl_from_ISAXAttributes(iface); 1108 1109 TRACE("%p\n", This); 1110 return ISAXLocator_Release(&This->ISAXLocator_iface); 1111 } 1112 1113 /*** ISAXAttributes methods ***/ 1114 static HRESULT WINAPI isaxattributes_getLength( 1115 ISAXAttributes* iface, 1116 int *length) 1117 { 1118 saxlocator *This = impl_from_ISAXAttributes( iface ); 1119 1120 *length = This->attr_count; 1121 TRACE("Length set to %d\n", *length); 1122 return S_OK; 1123 } 1124 1125 static inline BOOL is_valid_attr_index(const saxlocator *locator, int index) 1126 { 1127 return index < locator->attr_count && index >= 0; 1128 } 1129 1130 static HRESULT WINAPI isaxattributes_getURI( 1131 ISAXAttributes* iface, 1132 int index, 1133 const WCHAR **url, 1134 int *size) 1135 { 1136 saxlocator *This = impl_from_ISAXAttributes( iface ); 1137 TRACE("(%p)->(%d)\n", This, index); 1138 1139 if(!is_valid_attr_index(This, index)) return E_INVALIDARG; 1140 if(!url || !size) return E_POINTER; 1141 1142 *size = SysStringLen(This->attributes[index].szURI); 1143 *url = This->attributes[index].szURI; 1144 1145 TRACE("(%s:%d)\n", debugstr_w(This->attributes[index].szURI), *size); 1146 1147 return S_OK; 1148 } 1149 1150 static HRESULT WINAPI isaxattributes_getLocalName( 1151 ISAXAttributes* iface, 1152 int index, 1153 const WCHAR **pLocalName, 1154 int *pLocalNameLength) 1155 { 1156 saxlocator *This = impl_from_ISAXAttributes( iface ); 1157 TRACE("(%p)->(%d)\n", This, index); 1158 1159 if(!is_valid_attr_index(This, index)) return E_INVALIDARG; 1160 if(!pLocalName || !pLocalNameLength) return E_POINTER; 1161 1162 *pLocalNameLength = SysStringLen(This->attributes[index].szLocalname); 1163 *pLocalName = This->attributes[index].szLocalname; 1164 1165 return S_OK; 1166 } 1167 1168 static HRESULT WINAPI isaxattributes_getQName( 1169 ISAXAttributes* iface, 1170 int index, 1171 const WCHAR **pQName, 1172 int *pQNameLength) 1173 { 1174 saxlocator *This = impl_from_ISAXAttributes( iface ); 1175 TRACE("(%p)->(%d)\n", This, index); 1176 1177 if(!is_valid_attr_index(This, index)) return E_INVALIDARG; 1178 if(!pQName || !pQNameLength) return E_POINTER; 1179 1180 *pQNameLength = SysStringLen(This->attributes[index].szQName); 1181 *pQName = This->attributes[index].szQName; 1182 1183 return S_OK; 1184 } 1185 1186 static HRESULT WINAPI isaxattributes_getName( 1187 ISAXAttributes* iface, 1188 int index, 1189 const WCHAR **uri, 1190 int *pUriLength, 1191 const WCHAR **localName, 1192 int *pLocalNameSize, 1193 const WCHAR **QName, 1194 int *pQNameLength) 1195 { 1196 saxlocator *This = impl_from_ISAXAttributes( iface ); 1197 TRACE("(%p)->(%d)\n", This, index); 1198 1199 if(!is_valid_attr_index(This, index)) return E_INVALIDARG; 1200 if(!uri || !pUriLength || !localName || !pLocalNameSize 1201 || !QName || !pQNameLength) return E_POINTER; 1202 1203 *pUriLength = SysStringLen(This->attributes[index].szURI); 1204 *uri = This->attributes[index].szURI; 1205 *pLocalNameSize = SysStringLen(This->attributes[index].szLocalname); 1206 *localName = This->attributes[index].szLocalname; 1207 *pQNameLength = SysStringLen(This->attributes[index].szQName); 1208 *QName = This->attributes[index].szQName; 1209 1210 TRACE("(%s, %s, %s)\n", debugstr_w(*uri), debugstr_w(*localName), debugstr_w(*QName)); 1211 1212 return S_OK; 1213 } 1214 1215 static HRESULT WINAPI isaxattributes_getIndexFromName( 1216 ISAXAttributes* iface, 1217 const WCHAR *pUri, 1218 int cUriLength, 1219 const WCHAR *pLocalName, 1220 int cocalNameLength, 1221 int *index) 1222 { 1223 saxlocator *This = impl_from_ISAXAttributes( iface ); 1224 int i; 1225 TRACE("(%p)->(%s, %d, %s, %d)\n", This, debugstr_w(pUri), cUriLength, 1226 debugstr_w(pLocalName), cocalNameLength); 1227 1228 if(!pUri || !pLocalName || !index) return E_POINTER; 1229 1230 for(i=0; i<This->attr_count; i++) 1231 { 1232 if(cUriLength!=SysStringLen(This->attributes[i].szURI) 1233 || cocalNameLength!=SysStringLen(This->attributes[i].szLocalname)) 1234 continue; 1235 if(cUriLength && memcmp(pUri, This->attributes[i].szURI, 1236 sizeof(WCHAR)*cUriLength)) 1237 continue; 1238 if(cocalNameLength && memcmp(pLocalName, This->attributes[i].szLocalname, 1239 sizeof(WCHAR)*cocalNameLength)) 1240 continue; 1241 1242 *index = i; 1243 return S_OK; 1244 } 1245 1246 return E_INVALIDARG; 1247 } 1248 1249 static HRESULT WINAPI isaxattributes_getIndexFromQName( 1250 ISAXAttributes* iface, 1251 const WCHAR *pQName, 1252 int nQNameLength, 1253 int *index) 1254 { 1255 saxlocator *This = impl_from_ISAXAttributes( iface ); 1256 int i; 1257 TRACE("(%p)->(%s, %d)\n", This, debugstr_w(pQName), nQNameLength); 1258 1259 if(!pQName || !index) return E_POINTER; 1260 if(!nQNameLength) return E_INVALIDARG; 1261 1262 for(i=0; i<This->attr_count; i++) 1263 { 1264 if(nQNameLength!=SysStringLen(This->attributes[i].szQName)) continue; 1265 if(memcmp(pQName, This->attributes[i].szQName, sizeof(WCHAR)*nQNameLength)) continue; 1266 1267 *index = i; 1268 return S_OK; 1269 } 1270 1271 return E_INVALIDARG; 1272 } 1273 1274 static HRESULT WINAPI isaxattributes_getType( 1275 ISAXAttributes* iface, 1276 int nIndex, 1277 const WCHAR **pType, 1278 int *pTypeLength) 1279 { 1280 saxlocator *This = impl_from_ISAXAttributes( iface ); 1281 1282 FIXME("(%p)->(%d) stub\n", This, nIndex); 1283 return E_NOTIMPL; 1284 } 1285 1286 static HRESULT WINAPI isaxattributes_getTypeFromName( 1287 ISAXAttributes* iface, 1288 const WCHAR *pUri, 1289 int nUri, 1290 const WCHAR *pLocalName, 1291 int nLocalName, 1292 const WCHAR **pType, 1293 int *nType) 1294 { 1295 saxlocator *This = impl_from_ISAXAttributes( iface ); 1296 1297 FIXME("(%p)->(%s, %d, %s, %d) stub\n", This, debugstr_w(pUri), nUri, 1298 debugstr_w(pLocalName), nLocalName); 1299 return E_NOTIMPL; 1300 } 1301 1302 static HRESULT WINAPI isaxattributes_getTypeFromQName( 1303 ISAXAttributes* iface, 1304 const WCHAR *pQName, 1305 int nQName, 1306 const WCHAR **pType, 1307 int *nType) 1308 { 1309 saxlocator *This = impl_from_ISAXAttributes( iface ); 1310 1311 FIXME("(%p)->(%s, %d) stub\n", This, debugstr_w(pQName), nQName); 1312 return E_NOTIMPL; 1313 } 1314 1315 static HRESULT WINAPI isaxattributes_getValue( 1316 ISAXAttributes* iface, 1317 int index, 1318 const WCHAR **value, 1319 int *nValue) 1320 { 1321 saxlocator *This = impl_from_ISAXAttributes( iface ); 1322 TRACE("(%p)->(%d)\n", This, index); 1323 1324 if(!is_valid_attr_index(This, index)) return E_INVALIDARG; 1325 if(!value || !nValue) return E_POINTER; 1326 1327 *nValue = SysStringLen(This->attributes[index].szValue); 1328 *value = This->attributes[index].szValue; 1329 1330 TRACE("(%s:%d)\n", debugstr_w(*value), *nValue); 1331 1332 return S_OK; 1333 } 1334 1335 static HRESULT WINAPI isaxattributes_getValueFromName( 1336 ISAXAttributes* iface, 1337 const WCHAR *pUri, 1338 int nUri, 1339 const WCHAR *pLocalName, 1340 int nLocalName, 1341 const WCHAR **pValue, 1342 int *nValue) 1343 { 1344 HRESULT hr; 1345 int index; 1346 saxlocator *This = impl_from_ISAXAttributes( iface ); 1347 TRACE("(%p)->(%s, %d, %s, %d)\n", This, debugstr_w(pUri), nUri, 1348 debugstr_w(pLocalName), nLocalName); 1349 1350 hr = ISAXAttributes_getIndexFromName(iface, 1351 pUri, nUri, pLocalName, nLocalName, &index); 1352 if(hr==S_OK) hr = ISAXAttributes_getValue(iface, index, pValue, nValue); 1353 1354 return hr; 1355 } 1356 1357 static HRESULT WINAPI isaxattributes_getValueFromQName( 1358 ISAXAttributes* iface, 1359 const WCHAR *pQName, 1360 int nQName, 1361 const WCHAR **pValue, 1362 int *nValue) 1363 { 1364 HRESULT hr; 1365 int index; 1366 saxlocator *This = impl_from_ISAXAttributes( iface ); 1367 TRACE("(%p)->(%s, %d)\n", This, debugstr_w(pQName), nQName); 1368 1369 hr = ISAXAttributes_getIndexFromQName(iface, pQName, nQName, &index); 1370 if(hr==S_OK) hr = ISAXAttributes_getValue(iface, index, pValue, nValue); 1371 1372 return hr; 1373 } 1374 1375 static const struct ISAXAttributesVtbl isaxattributes_vtbl = 1376 { 1377 isaxattributes_QueryInterface, 1378 isaxattributes_AddRef, 1379 isaxattributes_Release, 1380 isaxattributes_getLength, 1381 isaxattributes_getURI, 1382 isaxattributes_getLocalName, 1383 isaxattributes_getQName, 1384 isaxattributes_getName, 1385 isaxattributes_getIndexFromName, 1386 isaxattributes_getIndexFromQName, 1387 isaxattributes_getType, 1388 isaxattributes_getTypeFromName, 1389 isaxattributes_getTypeFromQName, 1390 isaxattributes_getValue, 1391 isaxattributes_getValueFromName, 1392 isaxattributes_getValueFromQName 1393 }; 1394 1395 /* Libxml2 escapes '&' back to char reference '&' in attribute value, 1396 so when document has escaped value with '&' it's parsed to '&' and then 1397 escaped to '&'. This function takes care of ampersands only. */ 1398 static BSTR saxreader_get_unescaped_value(const xmlChar *buf, int len) 1399 { 1400 static const WCHAR ampescW[] = {'&','#','3','8',';',0}; 1401 WCHAR *dest, *ptrW, *str; 1402 DWORD str_len; 1403 BSTR bstr; 1404 1405 if (!buf) 1406 return NULL; 1407 1408 str_len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, NULL, 0); 1409 if (len != -1) str_len++; 1410 1411 str = heap_alloc(str_len*sizeof(WCHAR)); 1412 if (!str) return NULL; 1413 1414 MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, str, str_len); 1415 if (len != -1) str[str_len-1] = 0; 1416 1417 ptrW = str; 1418 while ((dest = strstrW(ptrW, ampescW))) 1419 { 1420 WCHAR *src; 1421 1422 /* leave first '&' from a reference as a value */ 1423 src = dest + ARRAY_SIZE(ampescW) - 1; 1424 dest++; 1425 1426 /* move together with null terminator */ 1427 memmove(dest, src, (strlenW(src) + 1)*sizeof(WCHAR)); 1428 1429 ptrW++; 1430 } 1431 1432 bstr = SysAllocString(str); 1433 heap_free(str); 1434 1435 return bstr; 1436 } 1437 1438 static void free_attribute_values(saxlocator *locator) 1439 { 1440 int i; 1441 1442 for (i = 0; i < locator->attr_count; i++) 1443 { 1444 SysFreeString(locator->attributes[i].szLocalname); 1445 locator->attributes[i].szLocalname = NULL; 1446 1447 SysFreeString(locator->attributes[i].szValue); 1448 locator->attributes[i].szValue = NULL; 1449 1450 SysFreeString(locator->attributes[i].szQName); 1451 locator->attributes[i].szQName = NULL; 1452 } 1453 } 1454 1455 static HRESULT SAXAttributes_populate(saxlocator *locator, 1456 int nb_namespaces, const xmlChar **xmlNamespaces, 1457 int nb_attributes, const xmlChar **xmlAttributes) 1458 { 1459 static const xmlChar xmlns[] = "xmlns"; 1460 static const WCHAR xmlnsW[] = { 'x','m','l','n','s',0 }; 1461 1462 struct _attributes *attrs; 1463 int i; 1464 1465 /* skip namespace definitions */ 1466 if ((locator->saxreader->features & NamespacePrefixes) == 0) 1467 nb_namespaces = 0; 1468 1469 locator->attr_count = nb_namespaces + nb_attributes; 1470 if(locator->attr_count > locator->attr_alloc_count) 1471 { 1472 int new_size = locator->attr_count * 2; 1473 attrs = heap_realloc_zero(locator->attributes, new_size * sizeof(struct _attributes)); 1474 if(!attrs) 1475 { 1476 free_attribute_values(locator); 1477 locator->attr_count = 0; 1478 return E_OUTOFMEMORY; 1479 } 1480 locator->attributes = attrs; 1481 locator->attr_alloc_count = new_size; 1482 } 1483 else 1484 { 1485 attrs = locator->attributes; 1486 } 1487 1488 for (i = 0; i < nb_namespaces; i++) 1489 { 1490 SysFreeString(attrs[nb_attributes+i].szLocalname); 1491 attrs[nb_attributes+i].szLocalname = SysAllocStringLen(NULL, 0); 1492 1493 attrs[nb_attributes+i].szURI = locator->namespaceUri; 1494 1495 SysFreeString(attrs[nb_attributes+i].szValue); 1496 attrs[nb_attributes+i].szValue = bstr_from_xmlChar(xmlNamespaces[2*i+1]); 1497 1498 SysFreeString(attrs[nb_attributes+i].szQName); 1499 if(!xmlNamespaces[2*i]) 1500 attrs[nb_attributes+i].szQName = SysAllocString(xmlnsW); 1501 else 1502 attrs[nb_attributes+i].szQName = QName_from_xmlChar(xmlns, xmlNamespaces[2*i]); 1503 } 1504 1505 for (i = 0; i < nb_attributes; i++) 1506 { 1507 static const xmlChar xmlA[] = "xml"; 1508 1509 if (xmlStrEqual(xmlAttributes[i*5+1], xmlA)) 1510 attrs[i].szURI = bstr_from_xmlChar(xmlAttributes[i*5+2]); 1511 else 1512 /* that's an important feature to keep same uri pointer for every reported attribute */ 1513 attrs[i].szURI = find_element_uri(locator, xmlAttributes[i*5+2]); 1514 1515 SysFreeString(attrs[i].szLocalname); 1516 attrs[i].szLocalname = bstr_from_xmlChar(xmlAttributes[i*5]); 1517 1518 SysFreeString(attrs[i].szValue); 1519 attrs[i].szValue = saxreader_get_unescaped_value(xmlAttributes[i*5+3], xmlAttributes[i*5+4]-xmlAttributes[i*5+3]); 1520 1521 SysFreeString(attrs[i].szQName); 1522 attrs[i].szQName = QName_from_xmlChar(xmlAttributes[i*5+1], xmlAttributes[i*5]); 1523 } 1524 1525 return S_OK; 1526 } 1527 1528 /*** LibXML callbacks ***/ 1529 static void libxmlStartDocument(void *ctx) 1530 { 1531 saxlocator *This = ctx; 1532 struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader); 1533 HRESULT hr; 1534 1535 if (This->saxreader->version >= MSXML4) 1536 { 1537 const xmlChar *p = This->pParserCtxt->input->cur-1; 1538 update_position(This, FALSE); 1539 while(p>This->pParserCtxt->input->base && *p!='>') 1540 { 1541 if(*p=='\n' || (*p=='\r' && *(p+1)!='\n')) 1542 This->line--; 1543 p--; 1544 } 1545 This->column = 0; 1546 for(; p>=This->pParserCtxt->input->base && *p!='\n' && *p!='\r'; p--) 1547 This->column++; 1548 } 1549 1550 /* store version value, declaration has to contain version attribute */ 1551 if (This->pParserCtxt->standalone != -1) 1552 { 1553 SysFreeString(This->saxreader->xmldecl_version); 1554 This->saxreader->xmldecl_version = bstr_from_xmlChar(This->pParserCtxt->version); 1555 } 1556 1557 if (saxreader_has_handler(This, SAXContentHandler)) 1558 { 1559 if(This->vbInterface) 1560 hr = IVBSAXContentHandler_startDocument(handler->vbhandler); 1561 else 1562 hr = ISAXContentHandler_startDocument(handler->handler); 1563 1564 if (sax_callback_failed(This, hr)) 1565 format_error_message_from_id(This, hr); 1566 } 1567 } 1568 1569 static void libxmlEndDocument(void *ctx) 1570 { 1571 saxlocator *This = ctx; 1572 struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader); 1573 HRESULT hr; 1574 1575 if (This->saxreader->version >= MSXML4) { 1576 update_position(This, FALSE); 1577 if(This->column > 1) 1578 This->line++; 1579 This->column = 0; 1580 } else { 1581 This->column = 0; 1582 This->line = 0; 1583 } 1584 1585 if(This->ret != S_OK) return; 1586 1587 if (saxreader_has_handler(This, SAXContentHandler)) 1588 { 1589 if(This->vbInterface) 1590 hr = IVBSAXContentHandler_endDocument(handler->vbhandler); 1591 else 1592 hr = ISAXContentHandler_endDocument(handler->handler); 1593 1594 if (sax_callback_failed(This, hr)) 1595 format_error_message_from_id(This, hr); 1596 } 1597 } 1598 1599 static void libxmlStartElementNS( 1600 void *ctx, 1601 const xmlChar *localname, 1602 const xmlChar *prefix, 1603 const xmlChar *URI, 1604 int nb_namespaces, 1605 const xmlChar **namespaces, 1606 int nb_attributes, 1607 int nb_defaulted, 1608 const xmlChar **attributes) 1609 { 1610 saxlocator *This = ctx; 1611 struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader); 1612 element_entry *element; 1613 HRESULT hr = S_OK; 1614 BSTR uri; 1615 1616 update_position(This, TRUE); 1617 if(*(This->pParserCtxt->input->cur) == '/') 1618 This->column++; 1619 if(This->saxreader->version < MSXML4) 1620 This->column++; 1621 1622 element = alloc_element_entry(localname, prefix, nb_namespaces, namespaces); 1623 push_element_ns(This, element); 1624 1625 if (is_namespaces_enabled(This->saxreader)) 1626 { 1627 int i; 1628 1629 for (i = 0; i < nb_namespaces && saxreader_has_handler(This, SAXContentHandler); i++) 1630 { 1631 if (This->vbInterface) 1632 hr = IVBSAXContentHandler_startPrefixMapping( 1633 handler->vbhandler, 1634 &element->ns[i].prefix, 1635 &element->ns[i].uri); 1636 else 1637 hr = ISAXContentHandler_startPrefixMapping( 1638 handler->handler, 1639 element->ns[i].prefix, 1640 SysStringLen(element->ns[i].prefix), 1641 element->ns[i].uri, 1642 SysStringLen(element->ns[i].uri)); 1643 1644 if (sax_callback_failed(This, hr)) 1645 { 1646 format_error_message_from_id(This, hr); 1647 return; 1648 } 1649 } 1650 } 1651 1652 uri = find_element_uri(This, URI); 1653 hr = SAXAttributes_populate(This, nb_namespaces, namespaces, nb_attributes, attributes); 1654 if (hr == S_OK && saxreader_has_handler(This, SAXContentHandler)) 1655 { 1656 BSTR local; 1657 1658 if (is_namespaces_enabled(This->saxreader)) 1659 local = element->local; 1660 else 1661 uri = local = NULL; 1662 1663 if (This->vbInterface) 1664 hr = IVBSAXContentHandler_startElement(handler->vbhandler, 1665 &uri, &local, &element->qname, &This->IVBSAXAttributes_iface); 1666 else 1667 hr = ISAXContentHandler_startElement(handler->handler, 1668 uri, SysStringLen(uri), 1669 local, SysStringLen(local), 1670 element->qname, SysStringLen(element->qname), 1671 &This->ISAXAttributes_iface); 1672 1673 if (sax_callback_failed(This, hr)) 1674 format_error_message_from_id(This, hr); 1675 } 1676 } 1677 1678 static void libxmlEndElementNS( 1679 void *ctx, 1680 const xmlChar *localname, 1681 const xmlChar *prefix, 1682 const xmlChar *URI) 1683 { 1684 saxlocator *This = ctx; 1685 struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader); 1686 element_entry *element; 1687 const xmlChar *p; 1688 BSTR uri, local; 1689 HRESULT hr; 1690 1691 update_position(This, FALSE); 1692 p = This->pParserCtxt->input->cur; 1693 1694 if (This->saxreader->version >= MSXML4) 1695 { 1696 p--; 1697 while(p>This->pParserCtxt->input->base && *p!='>') 1698 { 1699 if(*p=='\n' || (*p=='\r' && *(p+1)!='\n')) 1700 This->line--; 1701 p--; 1702 } 1703 } 1704 else if(*(p-1)!='>' || *(p-2)!='/') 1705 { 1706 p--; 1707 while(p-2>=This->pParserCtxt->input->base 1708 && *(p-2)!='<' && *(p-1)!='/') 1709 { 1710 if(*p=='\n' || (*p=='\r' && *(p+1)!='\n')) 1711 This->line--; 1712 p--; 1713 } 1714 } 1715 This->column = 0; 1716 for(; p>=This->pParserCtxt->input->base && *p!='\n' && *p!='\r'; p--) 1717 This->column++; 1718 1719 uri = find_element_uri(This, URI); 1720 element = pop_element_ns(This); 1721 1722 if (!saxreader_has_handler(This, SAXContentHandler)) 1723 { 1724 free_attribute_values(This); 1725 This->attr_count = 0; 1726 free_element_entry(element); 1727 return; 1728 } 1729 1730 if (is_namespaces_enabled(This->saxreader)) 1731 local = element->local; 1732 else 1733 uri = local = NULL; 1734 1735 if (This->vbInterface) 1736 hr = IVBSAXContentHandler_endElement( 1737 handler->vbhandler, 1738 &uri, &local, &element->qname); 1739 else 1740 hr = ISAXContentHandler_endElement( 1741 handler->handler, 1742 uri, SysStringLen(uri), 1743 local, SysStringLen(local), 1744 element->qname, SysStringLen(element->qname)); 1745 1746 free_attribute_values(This); 1747 This->attr_count = 0; 1748 1749 if (sax_callback_failed(This, hr)) 1750 { 1751 format_error_message_from_id(This, hr); 1752 free_element_entry(element); 1753 return; 1754 } 1755 1756 if (is_namespaces_enabled(This->saxreader)) 1757 { 1758 int i = -1; 1759 while (iterate_endprefix_index(This, element, &i) && saxreader_has_handler(This, SAXContentHandler)) 1760 { 1761 if (This->vbInterface) 1762 hr = IVBSAXContentHandler_endPrefixMapping( 1763 handler->vbhandler, &element->ns[i].prefix); 1764 else 1765 hr = ISAXContentHandler_endPrefixMapping( 1766 handler->handler, element->ns[i].prefix, SysStringLen(element->ns[i].prefix)); 1767 1768 if (sax_callback_failed(This, hr)) break; 1769 } 1770 1771 if (sax_callback_failed(This, hr)) 1772 format_error_message_from_id(This, hr); 1773 } 1774 1775 free_element_entry(element); 1776 } 1777 1778 static void libxmlCharacters( 1779 void *ctx, 1780 const xmlChar *ch, 1781 int len) 1782 { 1783 saxlocator *This = ctx; 1784 BSTR Chars; 1785 HRESULT hr; 1786 xmlChar *cur, *end; 1787 BOOL lastEvent = FALSE; 1788 1789 if (!saxreader_has_handler(This, SAXContentHandler)) return; 1790 1791 update_position(This, FALSE); 1792 cur = (xmlChar*)This->pParserCtxt->input->cur; 1793 while(cur>=This->pParserCtxt->input->base && *cur!='>') 1794 { 1795 if(*cur=='\n' || (*cur=='\r' && *(cur+1)!='\n')) 1796 This->line--; 1797 cur--; 1798 } 1799 This->column = 1; 1800 for(; cur>=This->pParserCtxt->input->base && *cur!='\n' && *cur!='\r'; cur--) 1801 This->column++; 1802 1803 cur = (xmlChar*)ch; 1804 if(*(ch-1)=='\r') cur--; 1805 end = cur; 1806 1807 while(1) 1808 { 1809 while(end-ch<len && *end!='\r') end++; 1810 if(end-ch==len) 1811 { 1812 lastEvent = TRUE; 1813 } 1814 else 1815 { 1816 *end = '\n'; 1817 end++; 1818 } 1819 1820 if (This->saxreader->version >= MSXML4) 1821 { 1822 xmlChar *p; 1823 1824 for(p=cur; p!=end; p++) 1825 { 1826 if(*p=='\n') 1827 { 1828 This->line++; 1829 This->column = 1; 1830 } 1831 else 1832 { 1833 This->column++; 1834 } 1835 } 1836 1837 if(!lastEvent) 1838 This->column = 0; 1839 } 1840 1841 Chars = pooled_bstr_from_xmlCharN(&This->saxreader->pool, cur, end-cur); 1842 hr = saxreader_saxcharacters(This, Chars); 1843 1844 if (sax_callback_failed(This, hr)) 1845 { 1846 format_error_message_from_id(This, hr); 1847 return; 1848 } 1849 1850 if (This->saxreader->version < MSXML4) 1851 This->column += end-cur; 1852 1853 if(lastEvent) 1854 break; 1855 1856 *(end-1) = '\r'; 1857 if(*end == '\n') 1858 { 1859 end++; 1860 This->column++; 1861 } 1862 cur = end; 1863 1864 if(end-ch == len) break; 1865 } 1866 } 1867 1868 static void libxmlSetDocumentLocator( 1869 void *ctx, 1870 xmlSAXLocatorPtr loc) 1871 { 1872 saxlocator *This = ctx; 1873 struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader); 1874 HRESULT hr = S_OK; 1875 1876 if (saxreader_has_handler(This, SAXContentHandler)) 1877 { 1878 if(This->vbInterface) 1879 hr = IVBSAXContentHandler_putref_documentLocator(handler->vbhandler, 1880 &This->IVBSAXLocator_iface); 1881 else 1882 hr = ISAXContentHandler_putDocumentLocator(handler->handler, &This->ISAXLocator_iface); 1883 } 1884 1885 if(FAILED(hr)) 1886 format_error_message_from_id(This, hr); 1887 } 1888 1889 static void libxmlComment(void *ctx, const xmlChar *value) 1890 { 1891 saxlocator *This = ctx; 1892 struct saxlexicalhandler_iface *handler = saxreader_get_lexicalhandler(This->saxreader); 1893 BSTR bValue; 1894 HRESULT hr; 1895 const xmlChar *p = This->pParserCtxt->input->cur; 1896 1897 update_position(This, FALSE); 1898 while(p-4>=This->pParserCtxt->input->base 1899 && memcmp(p-4, "<!--", sizeof(char[4]))) 1900 { 1901 if(*p=='\n' || (*p=='\r' && *(p+1)!='\n')) 1902 This->line--; 1903 p--; 1904 } 1905 1906 This->column = 0; 1907 for(; p>=This->pParserCtxt->input->base && *p!='\n' && *p!='\r'; p--) 1908 This->column++; 1909 1910 if (!saxreader_has_handler(This, SAXLexicalHandler)) return; 1911 1912 bValue = pooled_bstr_from_xmlChar(&This->saxreader->pool, value); 1913 1914 if (This->vbInterface) 1915 hr = IVBSAXLexicalHandler_comment(handler->vbhandler, &bValue); 1916 else 1917 hr = ISAXLexicalHandler_comment(handler->handler, bValue, SysStringLen(bValue)); 1918 1919 if(FAILED(hr)) 1920 format_error_message_from_id(This, hr); 1921 } 1922 1923 static void libxmlFatalError(void *ctx, const char *msg, ...) 1924 { 1925 saxlocator *This = ctx; 1926 struct saxerrorhandler_iface *handler = saxreader_get_errorhandler(This->saxreader); 1927 char message[1024]; 1928 WCHAR *error; 1929 DWORD len; 1930 va_list args; 1931 1932 if(This->ret != S_OK) { 1933 xmlStopParser(This->pParserCtxt); 1934 return; 1935 } 1936 1937 va_start(args, msg); 1938 vsprintf(message, msg, args); 1939 va_end(args); 1940 1941 len = MultiByteToWideChar(CP_UNIXCP, 0, message, -1, NULL, 0); 1942 error = heap_alloc(sizeof(WCHAR)*len); 1943 if(error) 1944 { 1945 MultiByteToWideChar(CP_UNIXCP, 0, message, -1, error, len); 1946 TRACE("fatal error for %p: %s\n", This, debugstr_w(error)); 1947 } 1948 1949 if (!saxreader_has_handler(This, SAXErrorHandler)) 1950 { 1951 xmlStopParser(This->pParserCtxt); 1952 This->ret = E_FAIL; 1953 heap_free(error); 1954 return; 1955 } 1956 1957 FIXME("Error handling is not compatible.\n"); 1958 1959 if(This->vbInterface) 1960 { 1961 BSTR bstrError = SysAllocString(error); 1962 IVBSAXErrorHandler_fatalError(handler->vbhandler, &This->IVBSAXLocator_iface, 1963 &bstrError, E_FAIL); 1964 SysFreeString(bstrError); 1965 } 1966 else 1967 ISAXErrorHandler_fatalError(handler->handler, &This->ISAXLocator_iface, error, E_FAIL); 1968 1969 heap_free(error); 1970 1971 xmlStopParser(This->pParserCtxt); 1972 This->ret = E_FAIL; 1973 } 1974 1975 /* The only reason this helper exists is that CDATA section are reported by chunks, 1976 newlines are used as delimiter. More than that, reader even alters input data before reporting. 1977 1978 This helper should be called for substring with trailing newlines. 1979 */ 1980 static BSTR saxreader_get_cdata_chunk(const xmlChar *str, int len) 1981 { 1982 BSTR bstr = bstr_from_xmlCharN(str, len), ret; 1983 WCHAR *ptr; 1984 1985 len = SysStringLen(bstr); 1986 ptr = bstr + len - 1; 1987 while ((*ptr == '\r' || *ptr == '\n') && ptr >= bstr) 1988 ptr--; 1989 1990 while (*++ptr) 1991 { 1992 /* replace returns as: 1993 1994 - "\r<char>" -> "\n<char>" 1995 - "\r\r" -> "\r" 1996 - "\r\n" -> "\n" 1997 */ 1998 if (*ptr == '\r') 1999 { 2000 if (*(ptr+1) == '\r' || *(ptr+1) == '\n') 2001 { 2002 /* shift tail */ 2003 memmove(ptr, ptr+1, len-- - (ptr-bstr)); 2004 } 2005 else 2006 *ptr = '\n'; 2007 } 2008 } 2009 2010 ret = SysAllocStringLen(bstr, len); 2011 SysFreeString(bstr); 2012 return ret; 2013 } 2014 2015 static void libxml_cdatablock(void *ctx, const xmlChar *value, int len) 2016 { 2017 const xmlChar *start, *end; 2018 saxlocator *locator = ctx; 2019 struct saxlexicalhandler_iface *lexical = saxreader_get_lexicalhandler(locator->saxreader); 2020 HRESULT hr = S_OK; 2021 BSTR chars; 2022 int i; 2023 2024 update_position(locator, FALSE); 2025 if (saxreader_has_handler(locator, SAXLexicalHandler)) 2026 { 2027 if (locator->vbInterface) 2028 hr = IVBSAXLexicalHandler_startCDATA(lexical->vbhandler); 2029 else 2030 hr = ISAXLexicalHandler_startCDATA(lexical->handler); 2031 } 2032 2033 if(FAILED(hr)) 2034 { 2035 format_error_message_from_id(locator, hr); 2036 return; 2037 } 2038 2039 start = value; 2040 end = NULL; 2041 i = 0; 2042 2043 while (i < len) 2044 { 2045 /* scan for newlines */ 2046 if (value[i] == '\r' || value[i] == '\n') 2047 { 2048 /* skip newlines/linefeeds */ 2049 while (i < len) 2050 { 2051 if (value[i] != '\r' && value[i] != '\n') break; 2052 i++; 2053 } 2054 end = &value[i]; 2055 2056 /* report */ 2057 chars = saxreader_get_cdata_chunk(start, end-start); 2058 TRACE("(chunk %s)\n", debugstr_w(chars)); 2059 hr = saxreader_saxcharacters(locator, chars); 2060 SysFreeString(chars); 2061 2062 start = &value[i]; 2063 end = NULL; 2064 } 2065 i++; 2066 locator->column++; 2067 } 2068 2069 /* no newline chars (or last chunk) report as a whole */ 2070 if (!end && start == value) 2071 { 2072 /* report */ 2073 chars = bstr_from_xmlCharN(start, len-(start-value)); 2074 TRACE("(%s)\n", debugstr_w(chars)); 2075 hr = saxreader_saxcharacters(locator, chars); 2076 SysFreeString(chars); 2077 } 2078 2079 if (saxreader_has_handler(locator, SAXLexicalHandler)) 2080 { 2081 if (locator->vbInterface) 2082 hr = IVBSAXLexicalHandler_endCDATA(lexical->vbhandler); 2083 else 2084 hr = ISAXLexicalHandler_endCDATA(lexical->handler); 2085 } 2086 2087 if(FAILED(hr)) 2088 format_error_message_from_id(locator, hr); 2089 } 2090 2091 static xmlParserInputPtr libxmlresolveentity(void *ctx, const xmlChar *publicid, const xmlChar *systemid) 2092 { 2093 FIXME("entity resolving not implemented, %s, %s\n", publicid, systemid); 2094 return xmlSAX2ResolveEntity(ctx, publicid, systemid); 2095 } 2096 2097 /*** IVBSAXLocator interface ***/ 2098 /*** IUnknown methods ***/ 2099 static HRESULT WINAPI ivbsaxlocator_QueryInterface(IVBSAXLocator* iface, REFIID riid, void **ppvObject) 2100 { 2101 saxlocator *This = impl_from_IVBSAXLocator( iface ); 2102 2103 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject); 2104 2105 *ppvObject = NULL; 2106 2107 if ( IsEqualGUID( riid, &IID_IUnknown ) || 2108 IsEqualGUID( riid, &IID_IDispatch) || 2109 IsEqualGUID( riid, &IID_IVBSAXLocator )) 2110 { 2111 *ppvObject = iface; 2112 } 2113 else if ( IsEqualGUID( riid, &IID_IVBSAXAttributes )) 2114 { 2115 *ppvObject = &This->IVBSAXAttributes_iface; 2116 } 2117 else 2118 { 2119 FIXME("interface %s not implemented\n", debugstr_guid(riid)); 2120 return E_NOINTERFACE; 2121 } 2122 2123 IVBSAXLocator_AddRef( iface ); 2124 2125 return S_OK; 2126 } 2127 2128 static ULONG WINAPI ivbsaxlocator_AddRef(IVBSAXLocator* iface) 2129 { 2130 saxlocator *This = impl_from_IVBSAXLocator( iface ); 2131 TRACE("%p\n", This ); 2132 return ISAXLocator_AddRef(&This->ISAXLocator_iface); 2133 } 2134 2135 static ULONG WINAPI ivbsaxlocator_Release(IVBSAXLocator* iface) 2136 { 2137 saxlocator *This = impl_from_IVBSAXLocator( iface ); 2138 return ISAXLocator_Release(&This->ISAXLocator_iface); 2139 } 2140 2141 /*** IDispatch methods ***/ 2142 static HRESULT WINAPI ivbsaxlocator_GetTypeInfoCount( IVBSAXLocator *iface, UINT* pctinfo ) 2143 { 2144 saxlocator *This = impl_from_IVBSAXLocator( iface ); 2145 2146 TRACE("(%p)->(%p)\n", This, pctinfo); 2147 2148 *pctinfo = 1; 2149 2150 return S_OK; 2151 } 2152 2153 static HRESULT WINAPI ivbsaxlocator_GetTypeInfo( 2154 IVBSAXLocator *iface, 2155 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo ) 2156 { 2157 saxlocator *This = impl_from_IVBSAXLocator( iface ); 2158 2159 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); 2160 2161 return get_typeinfo(IVBSAXLocator_tid, ppTInfo); 2162 } 2163 2164 static HRESULT WINAPI ivbsaxlocator_GetIDsOfNames( 2165 IVBSAXLocator *iface, 2166 REFIID riid, 2167 LPOLESTR* rgszNames, 2168 UINT cNames, 2169 LCID lcid, 2170 DISPID* rgDispId) 2171 { 2172 saxlocator *This = impl_from_IVBSAXLocator( iface ); 2173 ITypeInfo *typeinfo; 2174 HRESULT hr; 2175 2176 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, 2177 lcid, rgDispId); 2178 2179 if(!rgszNames || cNames == 0 || !rgDispId) 2180 return E_INVALIDARG; 2181 2182 hr = get_typeinfo(IVBSAXLocator_tid, &typeinfo); 2183 if(SUCCEEDED(hr)) 2184 { 2185 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId); 2186 ITypeInfo_Release(typeinfo); 2187 } 2188 2189 return hr; 2190 } 2191 2192 static HRESULT WINAPI ivbsaxlocator_Invoke( 2193 IVBSAXLocator *iface, 2194 DISPID dispIdMember, 2195 REFIID riid, 2196 LCID lcid, 2197 WORD wFlags, 2198 DISPPARAMS* pDispParams, 2199 VARIANT* pVarResult, 2200 EXCEPINFO* pExcepInfo, 2201 UINT* puArgErr) 2202 { 2203 saxlocator *This = impl_from_IVBSAXLocator( iface ); 2204 ITypeInfo *typeinfo; 2205 HRESULT hr; 2206 2207 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), 2208 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 2209 2210 hr = get_typeinfo(IVBSAXLocator_tid, &typeinfo); 2211 if(SUCCEEDED(hr)) 2212 { 2213 hr = ITypeInfo_Invoke(typeinfo, &This->IVBSAXLocator_iface, dispIdMember, wFlags, 2214 pDispParams, pVarResult, pExcepInfo, puArgErr); 2215 ITypeInfo_Release(typeinfo); 2216 } 2217 2218 return hr; 2219 } 2220 2221 /*** IVBSAXLocator methods ***/ 2222 static HRESULT WINAPI ivbsaxlocator_get_columnNumber( 2223 IVBSAXLocator* iface, 2224 int *pnColumn) 2225 { 2226 saxlocator *This = impl_from_IVBSAXLocator( iface ); 2227 return ISAXLocator_getColumnNumber(&This->ISAXLocator_iface, pnColumn); 2228 } 2229 2230 static HRESULT WINAPI ivbsaxlocator_get_lineNumber( 2231 IVBSAXLocator* iface, 2232 int *pnLine) 2233 { 2234 saxlocator *This = impl_from_IVBSAXLocator( iface ); 2235 return ISAXLocator_getLineNumber(&This->ISAXLocator_iface, pnLine); 2236 } 2237 2238 static HRESULT WINAPI ivbsaxlocator_get_publicId(IVBSAXLocator* iface, BSTR *ret) 2239 { 2240 saxlocator *This = impl_from_IVBSAXLocator( iface ); 2241 const WCHAR *publicidW; 2242 HRESULT hr; 2243 2244 TRACE("(%p)->(%p)\n", This, ret); 2245 2246 if (!ret) 2247 return E_POINTER; 2248 2249 *ret = NULL; 2250 hr = ISAXLocator_getPublicId(&This->ISAXLocator_iface, &publicidW); 2251 if (FAILED(hr)) 2252 return hr; 2253 2254 return return_bstr(publicidW, ret); 2255 } 2256 2257 static HRESULT WINAPI ivbsaxlocator_get_systemId(IVBSAXLocator* iface, BSTR *ret) 2258 { 2259 saxlocator *This = impl_from_IVBSAXLocator( iface ); 2260 const WCHAR *systemidW; 2261 HRESULT hr; 2262 2263 TRACE("(%p)->(%p)\n", This, ret); 2264 2265 if (!ret) 2266 return E_POINTER; 2267 2268 *ret = NULL; 2269 hr = ISAXLocator_getSystemId(&This->ISAXLocator_iface, &systemidW); 2270 if (FAILED(hr)) 2271 return hr; 2272 2273 return return_bstr(systemidW, ret); 2274 } 2275 2276 static const struct IVBSAXLocatorVtbl VBSAXLocatorVtbl = 2277 { 2278 ivbsaxlocator_QueryInterface, 2279 ivbsaxlocator_AddRef, 2280 ivbsaxlocator_Release, 2281 ivbsaxlocator_GetTypeInfoCount, 2282 ivbsaxlocator_GetTypeInfo, 2283 ivbsaxlocator_GetIDsOfNames, 2284 ivbsaxlocator_Invoke, 2285 ivbsaxlocator_get_columnNumber, 2286 ivbsaxlocator_get_lineNumber, 2287 ivbsaxlocator_get_publicId, 2288 ivbsaxlocator_get_systemId 2289 }; 2290 2291 /*** ISAXLocator interface ***/ 2292 /*** IUnknown methods ***/ 2293 static HRESULT WINAPI isaxlocator_QueryInterface(ISAXLocator* iface, REFIID riid, void **ppvObject) 2294 { 2295 saxlocator *This = impl_from_ISAXLocator( iface ); 2296 2297 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject ); 2298 2299 *ppvObject = NULL; 2300 2301 if ( IsEqualGUID( riid, &IID_IUnknown ) || 2302 IsEqualGUID( riid, &IID_ISAXLocator )) 2303 { 2304 *ppvObject = iface; 2305 } 2306 else if ( IsEqualGUID( riid, &IID_ISAXAttributes )) 2307 { 2308 *ppvObject = &This->ISAXAttributes_iface; 2309 } 2310 else 2311 { 2312 WARN("interface %s not implemented\n", debugstr_guid(riid)); 2313 return E_NOINTERFACE; 2314 } 2315 2316 ISAXLocator_AddRef( iface ); 2317 2318 return S_OK; 2319 } 2320 2321 static ULONG WINAPI isaxlocator_AddRef(ISAXLocator* iface) 2322 { 2323 saxlocator *This = impl_from_ISAXLocator( iface ); 2324 ULONG ref = InterlockedIncrement( &This->ref ); 2325 TRACE("(%p)->(%d)\n", This, ref); 2326 return ref; 2327 } 2328 2329 static ULONG WINAPI isaxlocator_Release( 2330 ISAXLocator* iface) 2331 { 2332 saxlocator *This = impl_from_ISAXLocator( iface ); 2333 LONG ref = InterlockedDecrement( &This->ref ); 2334 2335 TRACE("(%p)->(%d)\n", This, ref ); 2336 2337 if (ref == 0) 2338 { 2339 element_entry *element, *element2; 2340 int index; 2341 2342 SysFreeString(This->publicId); 2343 SysFreeString(This->systemId); 2344 SysFreeString(This->namespaceUri); 2345 2346 for(index = 0; index < This->attr_alloc_count; index++) 2347 { 2348 SysFreeString(This->attributes[index].szLocalname); 2349 SysFreeString(This->attributes[index].szValue); 2350 SysFreeString(This->attributes[index].szQName); 2351 } 2352 heap_free(This->attributes); 2353 2354 /* element stack */ 2355 LIST_FOR_EACH_ENTRY_SAFE(element, element2, &This->elements, element_entry, entry) 2356 { 2357 list_remove(&element->entry); 2358 free_element_entry(element); 2359 } 2360 2361 ISAXXMLReader_Release(&This->saxreader->ISAXXMLReader_iface); 2362 heap_free( This ); 2363 } 2364 2365 return ref; 2366 } 2367 2368 /*** ISAXLocator methods ***/ 2369 static HRESULT WINAPI isaxlocator_getColumnNumber( 2370 ISAXLocator* iface, 2371 int *pnColumn) 2372 { 2373 saxlocator *This = impl_from_ISAXLocator( iface ); 2374 2375 *pnColumn = This->column; 2376 return S_OK; 2377 } 2378 2379 static HRESULT WINAPI isaxlocator_getLineNumber( 2380 ISAXLocator* iface, 2381 int *pnLine) 2382 { 2383 saxlocator *This = impl_from_ISAXLocator( iface ); 2384 2385 *pnLine = This->line; 2386 return S_OK; 2387 } 2388 2389 static HRESULT WINAPI isaxlocator_getPublicId( 2390 ISAXLocator* iface, 2391 const WCHAR ** ppwchPublicId) 2392 { 2393 BSTR publicId; 2394 saxlocator *This = impl_from_ISAXLocator( iface ); 2395 2396 SysFreeString(This->publicId); 2397 2398 publicId = bstr_from_xmlChar(xmlSAX2GetPublicId(This->pParserCtxt)); 2399 if(SysStringLen(publicId)) 2400 This->publicId = publicId; 2401 else 2402 { 2403 SysFreeString(publicId); 2404 This->publicId = NULL; 2405 } 2406 2407 *ppwchPublicId = This->publicId; 2408 return S_OK; 2409 } 2410 2411 static HRESULT WINAPI isaxlocator_getSystemId( 2412 ISAXLocator* iface, 2413 const WCHAR ** ppwchSystemId) 2414 { 2415 BSTR systemId; 2416 saxlocator *This = impl_from_ISAXLocator( iface ); 2417 2418 SysFreeString(This->systemId); 2419 2420 systemId = bstr_from_xmlChar(xmlSAX2GetSystemId(This->pParserCtxt)); 2421 if(SysStringLen(systemId)) 2422 This->systemId = systemId; 2423 else 2424 { 2425 SysFreeString(systemId); 2426 This->systemId = NULL; 2427 } 2428 2429 *ppwchSystemId = This->systemId; 2430 return S_OK; 2431 } 2432 2433 static const struct ISAXLocatorVtbl SAXLocatorVtbl = 2434 { 2435 isaxlocator_QueryInterface, 2436 isaxlocator_AddRef, 2437 isaxlocator_Release, 2438 isaxlocator_getColumnNumber, 2439 isaxlocator_getLineNumber, 2440 isaxlocator_getPublicId, 2441 isaxlocator_getSystemId 2442 }; 2443 2444 static HRESULT SAXLocator_create(saxreader *reader, saxlocator **ppsaxlocator, BOOL vbInterface) 2445 { 2446 static const WCHAR w3xmlns[] = { 'h','t','t','p',':','/','/', 'w','w','w','.','w','3','.', 2447 'o','r','g','/','2','0','0','0','/','x','m','l','n','s','/',0 }; 2448 2449 saxlocator *locator; 2450 2451 locator = heap_alloc( sizeof (*locator) ); 2452 if( !locator ) 2453 return E_OUTOFMEMORY; 2454 2455 locator->IVBSAXLocator_iface.lpVtbl = &VBSAXLocatorVtbl; 2456 locator->ISAXLocator_iface.lpVtbl = &SAXLocatorVtbl; 2457 locator->IVBSAXAttributes_iface.lpVtbl = &ivbsaxattributes_vtbl; 2458 locator->ISAXAttributes_iface.lpVtbl = &isaxattributes_vtbl; 2459 locator->ref = 1; 2460 locator->vbInterface = vbInterface; 2461 2462 locator->saxreader = reader; 2463 ISAXXMLReader_AddRef(&reader->ISAXXMLReader_iface); 2464 2465 locator->pParserCtxt = NULL; 2466 locator->publicId = NULL; 2467 locator->systemId = NULL; 2468 locator->line = reader->version < MSXML4 ? 0 : 1; 2469 locator->column = 0; 2470 locator->ret = S_OK; 2471 if (locator->saxreader->version >= MSXML6) 2472 locator->namespaceUri = SysAllocString(w3xmlns); 2473 else 2474 locator->namespaceUri = SysAllocStringLen(NULL, 0); 2475 if(!locator->namespaceUri) 2476 { 2477 ISAXXMLReader_Release(&reader->ISAXXMLReader_iface); 2478 heap_free(locator); 2479 return E_OUTOFMEMORY; 2480 } 2481 2482 locator->attr_alloc_count = 8; 2483 locator->attr_count = 0; 2484 locator->attributes = heap_alloc_zero(sizeof(struct _attributes)*locator->attr_alloc_count); 2485 if(!locator->attributes) 2486 { 2487 ISAXXMLReader_Release(&reader->ISAXXMLReader_iface); 2488 SysFreeString(locator->namespaceUri); 2489 heap_free(locator); 2490 return E_OUTOFMEMORY; 2491 } 2492 2493 list_init(&locator->elements); 2494 2495 *ppsaxlocator = locator; 2496 2497 TRACE("returning %p\n", *ppsaxlocator); 2498 2499 return S_OK; 2500 } 2501 2502 /*** SAXXMLReader internal functions ***/ 2503 static HRESULT internal_parseBuffer(saxreader *This, const char *buffer, int size, BOOL vbInterface) 2504 { 2505 xmlCharEncoding encoding = XML_CHAR_ENCODING_NONE; 2506 xmlChar *enc_name = NULL; 2507 saxlocator *locator; 2508 HRESULT hr; 2509 2510 TRACE("(%p)->(%p %d)\n", This, buffer, size); 2511 2512 hr = SAXLocator_create(This, &locator, vbInterface); 2513 if (FAILED(hr)) 2514 return hr; 2515 2516 if (size >= 4) 2517 { 2518 const unsigned char *buff = (unsigned char*)buffer; 2519 2520 encoding = xmlDetectCharEncoding((xmlChar*)buffer, 4); 2521 enc_name = (xmlChar*)xmlGetCharEncodingName(encoding); 2522 TRACE("detected encoding: %s\n", enc_name); 2523 /* skip BOM, parser won't switch encodings and so won't skip it on its own */ 2524 if ((encoding == XML_CHAR_ENCODING_UTF8) && 2525 buff[0] == 0xEF && buff[1] == 0xBB && buff[2] == 0xBF) 2526 { 2527 buffer += 3; 2528 size -= 3; 2529 } 2530 } 2531 2532 /* if libxml2 detection failed try to guess */ 2533 if (encoding == XML_CHAR_ENCODING_NONE) 2534 { 2535 const WCHAR *ptr = (WCHAR*)buffer; 2536 /* an xml declaration with optional encoding will still be handled by the parser */ 2537 if ((size >= 2) && *ptr == '<' && ptr[1] != '?') 2538 { 2539 enc_name = (xmlChar*)xmlGetCharEncodingName(XML_CHAR_ENCODING_UTF16LE); 2540 encoding = XML_CHAR_ENCODING_UTF16LE; 2541 } 2542 } 2543 else if (encoding == XML_CHAR_ENCODING_UTF8) 2544 enc_name = (xmlChar*)xmlGetCharEncodingName(encoding); 2545 else 2546 enc_name = NULL; 2547 2548 locator->pParserCtxt = xmlCreateMemoryParserCtxt(buffer, size); 2549 if (!locator->pParserCtxt) 2550 { 2551 ISAXLocator_Release(&locator->ISAXLocator_iface); 2552 return E_FAIL; 2553 } 2554 2555 if (enc_name) 2556 { 2557 locator->pParserCtxt->encoding = xmlStrdup(enc_name); 2558 if (encoding == XML_CHAR_ENCODING_UTF16LE) { 2559 TRACE("switching to %s\n", enc_name); 2560 xmlSwitchEncoding(locator->pParserCtxt, encoding); 2561 } 2562 } 2563 2564 xmlFree(locator->pParserCtxt->sax); 2565 locator->pParserCtxt->sax = &locator->saxreader->sax; 2566 locator->pParserCtxt->userData = locator; 2567 2568 This->isParsing = TRUE; 2569 if(xmlParseDocument(locator->pParserCtxt) == -1 && locator->ret == S_OK) 2570 hr = E_FAIL; 2571 else 2572 hr = locator->ret; 2573 This->isParsing = FALSE; 2574 2575 if(locator->pParserCtxt) 2576 { 2577 locator->pParserCtxt->sax = NULL; 2578 xmlFreeParserCtxt(locator->pParserCtxt); 2579 locator->pParserCtxt = NULL; 2580 } 2581 2582 ISAXLocator_Release(&locator->ISAXLocator_iface); 2583 return hr; 2584 } 2585 2586 static HRESULT internal_parseStream(saxreader *This, ISequentialStream *stream, BOOL vbInterface) 2587 { 2588 saxlocator *locator; 2589 HRESULT hr; 2590 ULONG dataRead; 2591 char data[2048]; 2592 int ret; 2593 2594 dataRead = 0; 2595 hr = ISequentialStream_Read(stream, data, sizeof(data), &dataRead); 2596 if(FAILED(hr)) return hr; 2597 2598 hr = SAXLocator_create(This, &locator, vbInterface); 2599 if(FAILED(hr)) return hr; 2600 2601 locator->pParserCtxt = xmlCreatePushParserCtxt( 2602 &locator->saxreader->sax, locator, 2603 data, dataRead, NULL); 2604 if(!locator->pParserCtxt) 2605 { 2606 ISAXLocator_Release(&locator->ISAXLocator_iface); 2607 return E_FAIL; 2608 } 2609 2610 This->isParsing = TRUE; 2611 2612 do { 2613 dataRead = 0; 2614 hr = ISequentialStream_Read(stream, data, sizeof(data), &dataRead); 2615 if (FAILED(hr) || !dataRead) break; 2616 2617 ret = xmlParseChunk(locator->pParserCtxt, data, dataRead, 0); 2618 hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret; 2619 }while(hr == S_OK); 2620 2621 if(SUCCEEDED(hr)) 2622 { 2623 ret = xmlParseChunk(locator->pParserCtxt, data, 0, 1); 2624 hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret; 2625 } 2626 2627 2628 This->isParsing = FALSE; 2629 2630 xmlFreeParserCtxt(locator->pParserCtxt); 2631 locator->pParserCtxt = NULL; 2632 ISAXLocator_Release(&locator->ISAXLocator_iface); 2633 return hr; 2634 } 2635 2636 static HRESULT internal_parse( 2637 saxreader* This, 2638 VARIANT varInput, 2639 BOOL vbInterface) 2640 { 2641 HRESULT hr; 2642 2643 TRACE("(%p)->(%s)\n", This, debugstr_variant(&varInput)); 2644 2645 /* Dispose of the BSTRs in the pool from a prior run, if any. */ 2646 free_bstr_pool(&This->pool); 2647 2648 switch(V_VT(&varInput)) 2649 { 2650 case VT_BSTR: 2651 case VT_BSTR|VT_BYREF: 2652 { 2653 BSTR str = V_ISBYREF(&varInput) ? *V_BSTRREF(&varInput) : V_BSTR(&varInput); 2654 hr = internal_parseBuffer(This, (const char*)str, strlenW(str)*sizeof(WCHAR), vbInterface); 2655 break; 2656 } 2657 case VT_ARRAY|VT_UI1: { 2658 void *pSAData; 2659 LONG lBound, uBound; 2660 ULONG dataRead; 2661 2662 hr = SafeArrayGetLBound(V_ARRAY(&varInput), 1, &lBound); 2663 if(hr != S_OK) break; 2664 hr = SafeArrayGetUBound(V_ARRAY(&varInput), 1, &uBound); 2665 if(hr != S_OK) break; 2666 dataRead = (uBound-lBound)*SafeArrayGetElemsize(V_ARRAY(&varInput)); 2667 hr = SafeArrayAccessData(V_ARRAY(&varInput), &pSAData); 2668 if(hr != S_OK) break; 2669 hr = internal_parseBuffer(This, pSAData, dataRead, vbInterface); 2670 SafeArrayUnaccessData(V_ARRAY(&varInput)); 2671 break; 2672 } 2673 case VT_UNKNOWN: 2674 case VT_DISPATCH: { 2675 ISequentialStream *stream = NULL; 2676 IXMLDOMDocument *xmlDoc; 2677 2678 if (!V_UNKNOWN(&varInput)) 2679 return E_INVALIDARG; 2680 2681 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput), 2682 &IID_IXMLDOMDocument, (void**)&xmlDoc) == S_OK) 2683 { 2684 BSTR bstrData; 2685 2686 IXMLDOMDocument_get_xml(xmlDoc, &bstrData); 2687 hr = internal_parseBuffer(This, (const char*)bstrData, 2688 SysStringByteLen(bstrData), vbInterface); 2689 IXMLDOMDocument_Release(xmlDoc); 2690 SysFreeString(bstrData); 2691 break; 2692 } 2693 2694 /* try base interface first */ 2695 IUnknown_QueryInterface(V_UNKNOWN(&varInput), &IID_ISequentialStream, (void**)&stream); 2696 if (!stream) 2697 /* this should never happen if IStream is implemented properly, but just in case */ 2698 IUnknown_QueryInterface(V_UNKNOWN(&varInput), &IID_IStream, (void**)&stream); 2699 2700 if(stream) 2701 { 2702 hr = internal_parseStream(This, stream, vbInterface); 2703 ISequentialStream_Release(stream); 2704 } 2705 else 2706 { 2707 WARN("IUnknown* input doesn't support any of expected interfaces\n"); 2708 hr = E_INVALIDARG; 2709 } 2710 2711 break; 2712 } 2713 default: 2714 WARN("vt %d not implemented\n", V_VT(&varInput)); 2715 hr = E_INVALIDARG; 2716 } 2717 2718 return hr; 2719 } 2720 2721 static HRESULT internal_vbonDataAvailable(void *obj, char *ptr, DWORD len) 2722 { 2723 saxreader *This = obj; 2724 2725 return internal_parseBuffer(This, ptr, len, TRUE); 2726 } 2727 2728 static HRESULT internal_onDataAvailable(void *obj, char *ptr, DWORD len) 2729 { 2730 saxreader *This = obj; 2731 2732 return internal_parseBuffer(This, ptr, len, FALSE); 2733 } 2734 2735 static HRESULT internal_parseURL( 2736 saxreader* This, 2737 const WCHAR *url, 2738 BOOL vbInterface) 2739 { 2740 IMoniker *mon; 2741 bsc_t *bsc; 2742 HRESULT hr; 2743 2744 TRACE("(%p)->(%s)\n", This, debugstr_w(url)); 2745 2746 hr = create_moniker_from_url(url, &mon); 2747 if(FAILED(hr)) 2748 return hr; 2749 2750 if(vbInterface) hr = bind_url(mon, internal_vbonDataAvailable, This, &bsc); 2751 else hr = bind_url(mon, internal_onDataAvailable, This, &bsc); 2752 IMoniker_Release(mon); 2753 2754 if(FAILED(hr)) 2755 return hr; 2756 2757 return detach_bsc(bsc); 2758 } 2759 2760 static HRESULT saxreader_put_handler_from_variant(saxreader *This, enum saxhandler_type type, const VARIANT *v, BOOL vb) 2761 { 2762 const IID *riid; 2763 2764 if (V_VT(v) == VT_EMPTY) 2765 return saxreader_put_handler(This, type, NULL, vb); 2766 2767 switch (type) 2768 { 2769 case SAXDeclHandler: 2770 riid = vb ? &IID_IVBSAXDeclHandler : &IID_ISAXDeclHandler; 2771 break; 2772 case SAXLexicalHandler: 2773 riid = vb ? &IID_IVBSAXLexicalHandler : &IID_ISAXLexicalHandler; 2774 break; 2775 default: 2776 ERR("wrong handler type %d\n", type); 2777 return E_FAIL; 2778 } 2779 2780 switch (V_VT(v)) 2781 { 2782 case VT_DISPATCH: 2783 case VT_UNKNOWN: 2784 { 2785 IUnknown *handler = NULL; 2786 2787 if (V_UNKNOWN(v)) 2788 { 2789 HRESULT hr = IUnknown_QueryInterface(V_UNKNOWN(v), riid, (void**)&handler); 2790 if (FAILED(hr)) return hr; 2791 } 2792 2793 saxreader_put_handler(This, type, handler, vb); 2794 if (handler) IUnknown_Release(handler); 2795 break; 2796 } 2797 default: 2798 ERR("value type %d not supported\n", V_VT(v)); 2799 return E_INVALIDARG; 2800 } 2801 2802 return S_OK; 2803 } 2804 2805 static HRESULT internal_putProperty( 2806 saxreader* This, 2807 const WCHAR *prop, 2808 VARIANT value, 2809 BOOL vbInterface) 2810 { 2811 VARIANT *v; 2812 2813 TRACE("(%p)->(%s %s)\n", This, debugstr_w(prop), debugstr_variant(&value)); 2814 2815 if (This->isParsing) return E_FAIL; 2816 2817 v = V_VT(&value) == (VT_VARIANT|VT_BYREF) ? V_VARIANTREF(&value) : &value; 2818 if(!memcmp(prop, PropertyDeclHandlerW, sizeof(PropertyDeclHandlerW))) 2819 return saxreader_put_handler_from_variant(This, SAXDeclHandler, v, vbInterface); 2820 2821 if(!memcmp(prop, PropertyLexicalHandlerW, sizeof(PropertyLexicalHandlerW))) 2822 return saxreader_put_handler_from_variant(This, SAXLexicalHandler, v, vbInterface); 2823 2824 if(!memcmp(prop, PropertyMaxXMLSizeW, sizeof(PropertyMaxXMLSizeW))) 2825 { 2826 if (V_VT(v) == VT_I4 && V_I4(v) == 0) return S_OK; 2827 FIXME("(%p)->(%s): max-xml-size unsupported\n", This, debugstr_variant(v)); 2828 return E_NOTIMPL; 2829 } 2830 2831 if(!memcmp(prop, PropertyMaxElementDepthW, sizeof(PropertyMaxElementDepthW))) 2832 { 2833 if (V_VT(v) == VT_I4 && V_I4(v) == 0) return S_OK; 2834 FIXME("(%p)->(%s): max-element-depth unsupported\n", This, debugstr_variant(v)); 2835 return E_NOTIMPL; 2836 } 2837 2838 FIXME("(%p)->(%s:%s): unsupported property\n", This, debugstr_w(prop), debugstr_variant(v)); 2839 2840 if(!memcmp(prop, PropertyCharsetW, sizeof(PropertyCharsetW))) 2841 return E_NOTIMPL; 2842 2843 if(!memcmp(prop, PropertyDomNodeW, sizeof(PropertyDomNodeW))) 2844 return E_FAIL; 2845 2846 if(!memcmp(prop, PropertyInputSourceW, sizeof(PropertyInputSourceW))) 2847 return E_NOTIMPL; 2848 2849 if(!memcmp(prop, PropertySchemaDeclHandlerW, sizeof(PropertySchemaDeclHandlerW))) 2850 return E_NOTIMPL; 2851 2852 if(!memcmp(prop, PropertyXMLDeclEncodingW, sizeof(PropertyXMLDeclEncodingW))) 2853 return E_FAIL; 2854 2855 if(!memcmp(prop, PropertyXMLDeclStandaloneW, sizeof(PropertyXMLDeclStandaloneW))) 2856 return E_FAIL; 2857 2858 if(!memcmp(prop, PropertyXMLDeclVersionW, sizeof(PropertyXMLDeclVersionW))) 2859 return E_FAIL; 2860 2861 return E_INVALIDARG; 2862 } 2863 2864 static HRESULT internal_getProperty(const saxreader* This, const WCHAR *prop, VARIANT *value, BOOL vb) 2865 { 2866 TRACE("(%p)->(%s)\n", This, debugstr_w(prop)); 2867 2868 if (!value) return E_POINTER; 2869 2870 if (!memcmp(PropertyLexicalHandlerW, prop, sizeof(PropertyLexicalHandlerW))) 2871 { 2872 V_VT(value) = VT_UNKNOWN; 2873 saxreader_get_handler(This, SAXLexicalHandler, vb, (void**)&V_UNKNOWN(value)); 2874 return S_OK; 2875 } 2876 2877 if (!memcmp(PropertyDeclHandlerW, prop, sizeof(PropertyDeclHandlerW))) 2878 { 2879 V_VT(value) = VT_UNKNOWN; 2880 saxreader_get_handler(This, SAXDeclHandler, vb, (void**)&V_UNKNOWN(value)); 2881 return S_OK; 2882 } 2883 2884 if (!memcmp(PropertyXmlDeclVersionW, prop, sizeof(PropertyXmlDeclVersionW))) 2885 { 2886 V_VT(value) = VT_BSTR; 2887 V_BSTR(value) = SysAllocString(This->xmldecl_version); 2888 return S_OK; 2889 } 2890 2891 FIXME("(%p)->(%s) unsupported property\n", This, debugstr_w(prop)); 2892 2893 return E_NOTIMPL; 2894 } 2895 2896 /*** IVBSAXXMLReader interface ***/ 2897 /*** IUnknown methods ***/ 2898 static HRESULT WINAPI saxxmlreader_QueryInterface(IVBSAXXMLReader* iface, REFIID riid, void **ppvObject) 2899 { 2900 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 2901 2902 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject ); 2903 2904 *ppvObject = NULL; 2905 2906 if ( IsEqualGUID( riid, &IID_IUnknown ) || 2907 IsEqualGUID( riid, &IID_IDispatch ) || 2908 IsEqualGUID( riid, &IID_IVBSAXXMLReader )) 2909 { 2910 *ppvObject = iface; 2911 } 2912 else if( IsEqualGUID( riid, &IID_ISAXXMLReader )) 2913 { 2914 *ppvObject = &This->ISAXXMLReader_iface; 2915 } 2916 else if (dispex_query_interface(&This->dispex, riid, ppvObject)) 2917 { 2918 return *ppvObject ? S_OK : E_NOINTERFACE; 2919 } 2920 else 2921 { 2922 FIXME("interface %s not implemented\n", debugstr_guid(riid)); 2923 return E_NOINTERFACE; 2924 } 2925 2926 IVBSAXXMLReader_AddRef( iface ); 2927 2928 return S_OK; 2929 } 2930 2931 static ULONG WINAPI saxxmlreader_AddRef(IVBSAXXMLReader* iface) 2932 { 2933 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 2934 TRACE("%p\n", This ); 2935 return InterlockedIncrement( &This->ref ); 2936 } 2937 2938 static ULONG WINAPI saxxmlreader_Release( 2939 IVBSAXXMLReader* iface) 2940 { 2941 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 2942 LONG ref; 2943 2944 TRACE("%p\n", This ); 2945 2946 ref = InterlockedDecrement( &This->ref ); 2947 if ( ref == 0 ) 2948 { 2949 int i; 2950 2951 for (i = 0; i < SAXHandler_Last; i++) 2952 { 2953 struct saxanyhandler_iface *saxiface = &This->saxhandlers[i].u.anyhandler; 2954 2955 if (saxiface->handler) 2956 IUnknown_Release(saxiface->handler); 2957 2958 if (saxiface->vbhandler) 2959 IUnknown_Release(saxiface->vbhandler); 2960 } 2961 2962 SysFreeString(This->xmldecl_version); 2963 free_bstr_pool(&This->pool); 2964 2965 heap_free( This ); 2966 } 2967 2968 return ref; 2969 } 2970 /*** IDispatch ***/ 2971 static HRESULT WINAPI saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader *iface, UINT* pctinfo ) 2972 { 2973 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 2974 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo); 2975 } 2976 2977 static HRESULT WINAPI saxxmlreader_GetTypeInfo( 2978 IVBSAXXMLReader *iface, 2979 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo ) 2980 { 2981 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 2982 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, 2983 iTInfo, lcid, ppTInfo); 2984 } 2985 2986 static HRESULT WINAPI saxxmlreader_GetIDsOfNames( 2987 IVBSAXXMLReader *iface, 2988 REFIID riid, 2989 LPOLESTR* rgszNames, 2990 UINT cNames, 2991 LCID lcid, 2992 DISPID* rgDispId) 2993 { 2994 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 2995 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, 2996 riid, rgszNames, cNames, lcid, rgDispId); 2997 } 2998 2999 static HRESULT WINAPI saxxmlreader_Invoke( 3000 IVBSAXXMLReader *iface, 3001 DISPID dispIdMember, 3002 REFIID riid, 3003 LCID lcid, 3004 WORD wFlags, 3005 DISPPARAMS* pDispParams, 3006 VARIANT* pVarResult, 3007 EXCEPINFO* pExcepInfo, 3008 UINT* puArgErr) 3009 { 3010 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3011 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, 3012 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 3013 } 3014 3015 /*** IVBSAXXMLReader methods ***/ 3016 static HRESULT WINAPI saxxmlreader_getFeature( 3017 IVBSAXXMLReader* iface, 3018 BSTR feature_name, 3019 VARIANT_BOOL *value) 3020 { 3021 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3022 return ISAXXMLReader_getFeature(&This->ISAXXMLReader_iface, feature_name, value); 3023 } 3024 3025 static HRESULT WINAPI saxxmlreader_putFeature( 3026 IVBSAXXMLReader* iface, 3027 BSTR feature_name, 3028 VARIANT_BOOL value) 3029 { 3030 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3031 return ISAXXMLReader_putFeature(&This->ISAXXMLReader_iface, feature_name, value); 3032 } 3033 3034 static HRESULT WINAPI saxxmlreader_getProperty( 3035 IVBSAXXMLReader* iface, 3036 BSTR prop, 3037 VARIANT *value) 3038 { 3039 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3040 return internal_getProperty(This, prop, value, TRUE); 3041 } 3042 3043 static HRESULT WINAPI saxxmlreader_putProperty( 3044 IVBSAXXMLReader* iface, 3045 BSTR pProp, 3046 VARIANT value) 3047 { 3048 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3049 return internal_putProperty(This, pProp, value, TRUE); 3050 } 3051 3052 static HRESULT WINAPI saxxmlreader_get_entityResolver( 3053 IVBSAXXMLReader* iface, 3054 IVBSAXEntityResolver **resolver) 3055 { 3056 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3057 return saxreader_get_handler(This, SAXEntityResolver, TRUE, (void**)resolver); 3058 } 3059 3060 static HRESULT WINAPI saxxmlreader_put_entityResolver( 3061 IVBSAXXMLReader* iface, 3062 IVBSAXEntityResolver *resolver) 3063 { 3064 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3065 return saxreader_put_handler(This, SAXEntityResolver, resolver, TRUE); 3066 } 3067 3068 static HRESULT WINAPI saxxmlreader_get_contentHandler( 3069 IVBSAXXMLReader* iface, 3070 IVBSAXContentHandler **handler) 3071 { 3072 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3073 return saxreader_get_handler(This, SAXContentHandler, TRUE, (void**)handler); 3074 } 3075 3076 static HRESULT WINAPI saxxmlreader_put_contentHandler( 3077 IVBSAXXMLReader* iface, 3078 IVBSAXContentHandler *handler) 3079 { 3080 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3081 return saxreader_put_handler(This, SAXContentHandler, handler, TRUE); 3082 } 3083 3084 static HRESULT WINAPI saxxmlreader_get_dtdHandler( 3085 IVBSAXXMLReader* iface, 3086 IVBSAXDTDHandler **handler) 3087 { 3088 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3089 return saxreader_get_handler(This, SAXDTDHandler, TRUE, (void**)handler); 3090 } 3091 3092 static HRESULT WINAPI saxxmlreader_put_dtdHandler( 3093 IVBSAXXMLReader* iface, 3094 IVBSAXDTDHandler *handler) 3095 { 3096 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3097 return saxreader_put_handler(This, SAXDTDHandler, handler, TRUE); 3098 } 3099 3100 static HRESULT WINAPI saxxmlreader_get_errorHandler( 3101 IVBSAXXMLReader* iface, 3102 IVBSAXErrorHandler **handler) 3103 { 3104 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3105 return saxreader_get_handler(This, SAXErrorHandler, TRUE, (void**)handler); 3106 } 3107 3108 static HRESULT WINAPI saxxmlreader_put_errorHandler( 3109 IVBSAXXMLReader* iface, 3110 IVBSAXErrorHandler *handler) 3111 { 3112 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3113 return saxreader_put_handler(This, SAXErrorHandler, handler, TRUE); 3114 } 3115 3116 static HRESULT WINAPI saxxmlreader_get_baseURL( 3117 IVBSAXXMLReader* iface, 3118 BSTR *pBaseUrl) 3119 { 3120 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3121 3122 FIXME("(%p)->(%p) stub\n", This, pBaseUrl); 3123 return E_NOTIMPL; 3124 } 3125 3126 static HRESULT WINAPI saxxmlreader_put_baseURL( 3127 IVBSAXXMLReader* iface, 3128 BSTR pBaseUrl) 3129 { 3130 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3131 return ISAXXMLReader_putBaseURL(&This->ISAXXMLReader_iface, pBaseUrl); 3132 } 3133 3134 static HRESULT WINAPI saxxmlreader_get_secureBaseURL( 3135 IVBSAXXMLReader* iface, 3136 BSTR *pSecureBaseUrl) 3137 { 3138 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3139 3140 FIXME("(%p)->(%p) stub\n", This, pSecureBaseUrl); 3141 return E_NOTIMPL; 3142 } 3143 3144 static HRESULT WINAPI saxxmlreader_put_secureBaseURL( 3145 IVBSAXXMLReader* iface, 3146 BSTR secureBaseUrl) 3147 { 3148 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3149 return ISAXXMLReader_putSecureBaseURL(&This->ISAXXMLReader_iface, secureBaseUrl); 3150 } 3151 3152 static HRESULT WINAPI saxxmlreader_parse( 3153 IVBSAXXMLReader* iface, 3154 VARIANT varInput) 3155 { 3156 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3157 return internal_parse(This, varInput, TRUE); 3158 } 3159 3160 static HRESULT WINAPI saxxmlreader_parseURL( 3161 IVBSAXXMLReader* iface, 3162 BSTR url) 3163 { 3164 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3165 return internal_parseURL(This, url, TRUE); 3166 } 3167 3168 static const struct IVBSAXXMLReaderVtbl VBSAXXMLReaderVtbl = 3169 { 3170 saxxmlreader_QueryInterface, 3171 saxxmlreader_AddRef, 3172 saxxmlreader_Release, 3173 saxxmlreader_GetTypeInfoCount, 3174 saxxmlreader_GetTypeInfo, 3175 saxxmlreader_GetIDsOfNames, 3176 saxxmlreader_Invoke, 3177 saxxmlreader_getFeature, 3178 saxxmlreader_putFeature, 3179 saxxmlreader_getProperty, 3180 saxxmlreader_putProperty, 3181 saxxmlreader_get_entityResolver, 3182 saxxmlreader_put_entityResolver, 3183 saxxmlreader_get_contentHandler, 3184 saxxmlreader_put_contentHandler, 3185 saxxmlreader_get_dtdHandler, 3186 saxxmlreader_put_dtdHandler, 3187 saxxmlreader_get_errorHandler, 3188 saxxmlreader_put_errorHandler, 3189 saxxmlreader_get_baseURL, 3190 saxxmlreader_put_baseURL, 3191 saxxmlreader_get_secureBaseURL, 3192 saxxmlreader_put_secureBaseURL, 3193 saxxmlreader_parse, 3194 saxxmlreader_parseURL 3195 }; 3196 3197 /*** ISAXXMLReader interface ***/ 3198 /*** IUnknown methods ***/ 3199 static HRESULT WINAPI isaxxmlreader_QueryInterface(ISAXXMLReader* iface, REFIID riid, void **ppvObject) 3200 { 3201 saxreader *This = impl_from_ISAXXMLReader( iface ); 3202 return IVBSAXXMLReader_QueryInterface(&This->IVBSAXXMLReader_iface, riid, ppvObject); 3203 } 3204 3205 static ULONG WINAPI isaxxmlreader_AddRef(ISAXXMLReader* iface) 3206 { 3207 saxreader *This = impl_from_ISAXXMLReader( iface ); 3208 return IVBSAXXMLReader_AddRef(&This->IVBSAXXMLReader_iface); 3209 } 3210 3211 static ULONG WINAPI isaxxmlreader_Release(ISAXXMLReader* iface) 3212 { 3213 saxreader *This = impl_from_ISAXXMLReader( iface ); 3214 return IVBSAXXMLReader_Release(&This->IVBSAXXMLReader_iface); 3215 } 3216 3217 /*** ISAXXMLReader methods ***/ 3218 static HRESULT WINAPI isaxxmlreader_getFeature( 3219 ISAXXMLReader* iface, 3220 const WCHAR *feature_name, 3221 VARIANT_BOOL *value) 3222 { 3223 saxreader *This = impl_from_ISAXXMLReader( iface ); 3224 saxreader_feature feature; 3225 3226 TRACE("(%p)->(%s %p)\n", This, debugstr_w(feature_name), value); 3227 3228 feature = get_saxreader_feature(feature_name); 3229 3230 if (This->version < MSXML4 && (feature == ExhaustiveErrors || feature == SchemaValidation)) 3231 return E_INVALIDARG; 3232 3233 if (feature == Namespaces || 3234 feature == NamespacePrefixes || 3235 feature == ExhaustiveErrors || 3236 feature == SchemaValidation) 3237 return get_feature_value(This, feature, value); 3238 3239 FIXME("(%p)->(%s %p) stub\n", This, debugstr_w(feature_name), value); 3240 return E_NOTIMPL; 3241 } 3242 3243 static HRESULT WINAPI isaxxmlreader_putFeature( 3244 ISAXXMLReader* iface, 3245 const WCHAR *feature_name, 3246 VARIANT_BOOL value) 3247 { 3248 saxreader *This = impl_from_ISAXXMLReader( iface ); 3249 saxreader_feature feature; 3250 3251 TRACE("(%p)->(%s %x)\n", This, debugstr_w(feature_name), value); 3252 3253 feature = get_saxreader_feature(feature_name); 3254 3255 /* accepted cases */ 3256 if ((feature == ExhaustiveErrors && value == VARIANT_FALSE) || 3257 (feature == SchemaValidation && value == VARIANT_FALSE) || 3258 feature == Namespaces || 3259 feature == NamespacePrefixes) 3260 { 3261 return set_feature_value(This, feature, value); 3262 } 3263 3264 if (feature == LexicalHandlerParEntities || 3265 feature == ProhibitDTD || 3266 feature == ExternalGeneralEntities || 3267 feature == ExternalParameterEntities) 3268 { 3269 FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(feature_name), value); 3270 return set_feature_value(This, feature, value); 3271 } 3272 3273 FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(feature_name), value); 3274 return E_NOTIMPL; 3275 } 3276 3277 static HRESULT WINAPI isaxxmlreader_getProperty( 3278 ISAXXMLReader* iface, 3279 const WCHAR *prop, 3280 VARIANT *value) 3281 { 3282 saxreader *This = impl_from_ISAXXMLReader( iface ); 3283 return internal_getProperty(This, prop, value, FALSE); 3284 } 3285 3286 static HRESULT WINAPI isaxxmlreader_putProperty( 3287 ISAXXMLReader* iface, 3288 const WCHAR *pProp, 3289 VARIANT value) 3290 { 3291 saxreader *This = impl_from_ISAXXMLReader( iface ); 3292 return internal_putProperty(This, pProp, value, FALSE); 3293 } 3294 3295 static HRESULT WINAPI isaxxmlreader_getEntityResolver( 3296 ISAXXMLReader* iface, 3297 ISAXEntityResolver **resolver) 3298 { 3299 saxreader *This = impl_from_ISAXXMLReader( iface ); 3300 return saxreader_get_handler(This, SAXEntityResolver, FALSE, (void**)resolver); 3301 } 3302 3303 static HRESULT WINAPI isaxxmlreader_putEntityResolver( 3304 ISAXXMLReader* iface, 3305 ISAXEntityResolver *resolver) 3306 { 3307 saxreader *This = impl_from_ISAXXMLReader( iface ); 3308 return saxreader_put_handler(This, SAXEntityResolver, resolver, FALSE); 3309 } 3310 3311 static HRESULT WINAPI isaxxmlreader_getContentHandler( 3312 ISAXXMLReader* iface, 3313 ISAXContentHandler **handler) 3314 { 3315 saxreader *This = impl_from_ISAXXMLReader( iface ); 3316 return saxreader_get_handler(This, SAXContentHandler, FALSE, (void**)handler); 3317 } 3318 3319 static HRESULT WINAPI isaxxmlreader_putContentHandler( 3320 ISAXXMLReader* iface, 3321 ISAXContentHandler *handler) 3322 { 3323 saxreader *This = impl_from_ISAXXMLReader( iface ); 3324 return saxreader_put_handler(This, SAXContentHandler, handler, FALSE); 3325 } 3326 3327 static HRESULT WINAPI isaxxmlreader_getDTDHandler( 3328 ISAXXMLReader* iface, 3329 ISAXDTDHandler **handler) 3330 { 3331 saxreader *This = impl_from_ISAXXMLReader( iface ); 3332 return saxreader_get_handler(This, SAXDTDHandler, FALSE, (void**)handler); 3333 } 3334 3335 static HRESULT WINAPI isaxxmlreader_putDTDHandler( 3336 ISAXXMLReader* iface, 3337 ISAXDTDHandler *handler) 3338 { 3339 saxreader *This = impl_from_ISAXXMLReader( iface ); 3340 return saxreader_put_handler(This, SAXDTDHandler, handler, FALSE); 3341 } 3342 3343 static HRESULT WINAPI isaxxmlreader_getErrorHandler( 3344 ISAXXMLReader* iface, 3345 ISAXErrorHandler **handler) 3346 { 3347 saxreader *This = impl_from_ISAXXMLReader( iface ); 3348 return saxreader_get_handler(This, SAXErrorHandler, FALSE, (void**)handler); 3349 } 3350 3351 static HRESULT WINAPI isaxxmlreader_putErrorHandler(ISAXXMLReader* iface, ISAXErrorHandler *handler) 3352 { 3353 saxreader *This = impl_from_ISAXXMLReader( iface ); 3354 return saxreader_put_handler(This, SAXErrorHandler, handler, FALSE); 3355 } 3356 3357 static HRESULT WINAPI isaxxmlreader_getBaseURL( 3358 ISAXXMLReader* iface, 3359 const WCHAR **base_url) 3360 { 3361 saxreader *This = impl_from_ISAXXMLReader( iface ); 3362 3363 FIXME("(%p)->(%p) stub\n", This, base_url); 3364 return E_NOTIMPL; 3365 } 3366 3367 static HRESULT WINAPI isaxxmlreader_putBaseURL( 3368 ISAXXMLReader* iface, 3369 const WCHAR *pBaseUrl) 3370 { 3371 saxreader *This = impl_from_ISAXXMLReader( iface ); 3372 3373 FIXME("(%p)->(%s) stub\n", This, debugstr_w(pBaseUrl)); 3374 return E_NOTIMPL; 3375 } 3376 3377 static HRESULT WINAPI isaxxmlreader_getSecureBaseURL( 3378 ISAXXMLReader* iface, 3379 const WCHAR **pSecureBaseUrl) 3380 { 3381 saxreader *This = impl_from_ISAXXMLReader( iface ); 3382 FIXME("(%p)->(%p) stub\n", This, pSecureBaseUrl); 3383 return E_NOTIMPL; 3384 } 3385 3386 static HRESULT WINAPI isaxxmlreader_putSecureBaseURL( 3387 ISAXXMLReader* iface, 3388 const WCHAR *secureBaseUrl) 3389 { 3390 saxreader *This = impl_from_ISAXXMLReader( iface ); 3391 3392 FIXME("(%p)->(%s) stub\n", This, debugstr_w(secureBaseUrl)); 3393 return E_NOTIMPL; 3394 } 3395 3396 static HRESULT WINAPI isaxxmlreader_parse( 3397 ISAXXMLReader* iface, 3398 VARIANT varInput) 3399 { 3400 saxreader *This = impl_from_ISAXXMLReader( iface ); 3401 return internal_parse(This, varInput, FALSE); 3402 } 3403 3404 static HRESULT WINAPI isaxxmlreader_parseURL( 3405 ISAXXMLReader* iface, 3406 const WCHAR *url) 3407 { 3408 saxreader *This = impl_from_ISAXXMLReader( iface ); 3409 return internal_parseURL(This, url, FALSE); 3410 } 3411 3412 static const struct ISAXXMLReaderVtbl SAXXMLReaderVtbl = 3413 { 3414 isaxxmlreader_QueryInterface, 3415 isaxxmlreader_AddRef, 3416 isaxxmlreader_Release, 3417 isaxxmlreader_getFeature, 3418 isaxxmlreader_putFeature, 3419 isaxxmlreader_getProperty, 3420 isaxxmlreader_putProperty, 3421 isaxxmlreader_getEntityResolver, 3422 isaxxmlreader_putEntityResolver, 3423 isaxxmlreader_getContentHandler, 3424 isaxxmlreader_putContentHandler, 3425 isaxxmlreader_getDTDHandler, 3426 isaxxmlreader_putDTDHandler, 3427 isaxxmlreader_getErrorHandler, 3428 isaxxmlreader_putErrorHandler, 3429 isaxxmlreader_getBaseURL, 3430 isaxxmlreader_putBaseURL, 3431 isaxxmlreader_getSecureBaseURL, 3432 isaxxmlreader_putSecureBaseURL, 3433 isaxxmlreader_parse, 3434 isaxxmlreader_parseURL 3435 }; 3436 3437 static const tid_t saxreader_iface_tids[] = { 3438 IVBSAXXMLReader_tid, 3439 0 3440 }; 3441 static dispex_static_data_t saxreader_dispex = { 3442 NULL, 3443 IVBSAXXMLReader_tid, 3444 NULL, 3445 saxreader_iface_tids 3446 }; 3447 3448 HRESULT SAXXMLReader_create(MSXML_VERSION version, LPVOID *ppObj) 3449 { 3450 saxreader *reader; 3451 3452 TRACE("(%p)\n", ppObj); 3453 3454 reader = heap_alloc( sizeof (*reader) ); 3455 if( !reader ) 3456 return E_OUTOFMEMORY; 3457 3458 reader->IVBSAXXMLReader_iface.lpVtbl = &VBSAXXMLReaderVtbl; 3459 reader->ISAXXMLReader_iface.lpVtbl = &SAXXMLReaderVtbl; 3460 reader->ref = 1; 3461 memset(reader->saxhandlers, 0, sizeof(reader->saxhandlers)); 3462 reader->isParsing = FALSE; 3463 reader->xmldecl_version = NULL; 3464 reader->pool.pool = NULL; 3465 reader->pool.index = 0; 3466 reader->pool.len = 0; 3467 reader->features = Namespaces | NamespacePrefixes; 3468 reader->version = version; 3469 3470 init_dispex(&reader->dispex, (IUnknown*)&reader->IVBSAXXMLReader_iface, &saxreader_dispex); 3471 3472 memset(&reader->sax, 0, sizeof(xmlSAXHandler)); 3473 reader->sax.initialized = XML_SAX2_MAGIC; 3474 reader->sax.startDocument = libxmlStartDocument; 3475 reader->sax.endDocument = libxmlEndDocument; 3476 reader->sax.startElementNs = libxmlStartElementNS; 3477 reader->sax.endElementNs = libxmlEndElementNS; 3478 reader->sax.characters = libxmlCharacters; 3479 reader->sax.setDocumentLocator = libxmlSetDocumentLocator; 3480 reader->sax.comment = libxmlComment; 3481 reader->sax.error = libxmlFatalError; 3482 reader->sax.fatalError = libxmlFatalError; 3483 reader->sax.cdataBlock = libxml_cdatablock; 3484 reader->sax.resolveEntity = libxmlresolveentity; 3485 3486 *ppObj = &reader->IVBSAXXMLReader_iface; 3487 3488 TRACE("returning iface %p\n", *ppObj); 3489 3490 return S_OK; 3491 } 3492 3493 #else 3494 3495 HRESULT SAXXMLReader_create(MSXML_VERSION version, LPVOID *ppObj) 3496 { 3497 MESSAGE("This program tried to use a SAX XML Reader object, but\n" 3498 "libxml2 support was not present at compile time.\n"); 3499 return E_NOTIMPL; 3500 } 3501 3502 #endif 3503