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