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 len = SysStringLen(bstr); 1954 ptr = bstr + len - 1; 1955 while ((*ptr == '\r' || *ptr == '\n') && ptr >= bstr) 1956 ptr--; 1957 1958 while (*++ptr) 1959 { 1960 /* replace returns as: 1961 1962 - "\r<char>" -> "\n<char>" 1963 - "\r\r" -> "\r" 1964 - "\r\n" -> "\n" 1965 */ 1966 if (*ptr == '\r') 1967 { 1968 if (*(ptr+1) == '\r' || *(ptr+1) == '\n') 1969 { 1970 /* shift tail */ 1971 memmove(ptr, ptr+1, len-- - (ptr-bstr)); 1972 } 1973 else 1974 *ptr = '\n'; 1975 } 1976 } 1977 1978 ret = SysAllocStringLen(bstr, len); 1979 SysFreeString(bstr); 1980 return ret; 1981 } 1982 1983 static void libxml_cdatablock(void *ctx, const xmlChar *value, int len) 1984 { 1985 const xmlChar *start, *end; 1986 saxlocator *locator = ctx; 1987 struct saxlexicalhandler_iface *lexical = saxreader_get_lexicalhandler(locator->saxreader); 1988 HRESULT hr = S_OK; 1989 BSTR chars; 1990 int i; 1991 1992 update_position(locator, FALSE); 1993 if (saxreader_has_handler(locator, SAXLexicalHandler)) 1994 { 1995 if (locator->vbInterface) 1996 hr = IVBSAXLexicalHandler_startCDATA(lexical->vbhandler); 1997 else 1998 hr = ISAXLexicalHandler_startCDATA(lexical->handler); 1999 } 2000 2001 if(FAILED(hr)) 2002 { 2003 format_error_message_from_id(locator, hr); 2004 return; 2005 } 2006 2007 start = value; 2008 end = NULL; 2009 i = 0; 2010 2011 while (i < len) 2012 { 2013 /* scan for newlines */ 2014 if (value[i] == '\r' || value[i] == '\n') 2015 { 2016 /* skip newlines/linefeeds */ 2017 while (i < len) 2018 { 2019 if (value[i] != '\r' && value[i] != '\n') break; 2020 i++; 2021 } 2022 end = &value[i]; 2023 2024 /* report */ 2025 chars = saxreader_get_cdata_chunk(start, end-start); 2026 TRACE("(chunk %s)\n", debugstr_w(chars)); 2027 hr = saxreader_saxcharacters(locator, chars); 2028 SysFreeString(chars); 2029 2030 start = &value[i]; 2031 end = NULL; 2032 } 2033 i++; 2034 locator->column++; 2035 } 2036 2037 /* no newline chars (or last chunk) report as a whole */ 2038 if (!end && start == value) 2039 { 2040 /* report */ 2041 chars = bstr_from_xmlCharN(start, len-(start-value)); 2042 TRACE("(%s)\n", debugstr_w(chars)); 2043 hr = saxreader_saxcharacters(locator, chars); 2044 SysFreeString(chars); 2045 } 2046 2047 if (saxreader_has_handler(locator, SAXLexicalHandler)) 2048 { 2049 if (locator->vbInterface) 2050 hr = IVBSAXLexicalHandler_endCDATA(lexical->vbhandler); 2051 else 2052 hr = ISAXLexicalHandler_endCDATA(lexical->handler); 2053 } 2054 2055 if(FAILED(hr)) 2056 format_error_message_from_id(locator, hr); 2057 } 2058 2059 static xmlParserInputPtr libxmlresolveentity(void *ctx, const xmlChar *publicid, const xmlChar *systemid) 2060 { 2061 FIXME("entity resolving not implemented, %s, %s\n", publicid, systemid); 2062 return xmlSAX2ResolveEntity(ctx, publicid, systemid); 2063 } 2064 2065 /*** IVBSAXLocator interface ***/ 2066 /*** IUnknown methods ***/ 2067 static HRESULT WINAPI ivbsaxlocator_QueryInterface(IVBSAXLocator* iface, REFIID riid, void **ppvObject) 2068 { 2069 saxlocator *This = impl_from_IVBSAXLocator( iface ); 2070 2071 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject); 2072 2073 *ppvObject = NULL; 2074 2075 if ( IsEqualGUID( riid, &IID_IUnknown ) || 2076 IsEqualGUID( riid, &IID_IDispatch) || 2077 IsEqualGUID( riid, &IID_IVBSAXLocator )) 2078 { 2079 *ppvObject = iface; 2080 } 2081 else if ( IsEqualGUID( riid, &IID_IVBSAXAttributes )) 2082 { 2083 *ppvObject = &This->IVBSAXAttributes_iface; 2084 } 2085 else 2086 { 2087 FIXME("interface %s not implemented\n", debugstr_guid(riid)); 2088 return E_NOINTERFACE; 2089 } 2090 2091 IVBSAXLocator_AddRef( iface ); 2092 2093 return S_OK; 2094 } 2095 2096 static ULONG WINAPI ivbsaxlocator_AddRef(IVBSAXLocator* iface) 2097 { 2098 saxlocator *This = impl_from_IVBSAXLocator( iface ); 2099 TRACE("%p\n", This ); 2100 return ISAXLocator_AddRef(&This->ISAXLocator_iface); 2101 } 2102 2103 static ULONG WINAPI ivbsaxlocator_Release(IVBSAXLocator* iface) 2104 { 2105 saxlocator *This = impl_from_IVBSAXLocator( iface ); 2106 return ISAXLocator_Release(&This->ISAXLocator_iface); 2107 } 2108 2109 /*** IDispatch methods ***/ 2110 static HRESULT WINAPI ivbsaxlocator_GetTypeInfoCount( IVBSAXLocator *iface, UINT* pctinfo ) 2111 { 2112 saxlocator *This = impl_from_IVBSAXLocator( iface ); 2113 2114 TRACE("(%p)->(%p)\n", This, pctinfo); 2115 2116 *pctinfo = 1; 2117 2118 return S_OK; 2119 } 2120 2121 static HRESULT WINAPI ivbsaxlocator_GetTypeInfo( 2122 IVBSAXLocator *iface, 2123 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo ) 2124 { 2125 saxlocator *This = impl_from_IVBSAXLocator( iface ); 2126 2127 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); 2128 2129 return get_typeinfo(IVBSAXLocator_tid, ppTInfo); 2130 } 2131 2132 static HRESULT WINAPI ivbsaxlocator_GetIDsOfNames( 2133 IVBSAXLocator *iface, 2134 REFIID riid, 2135 LPOLESTR* rgszNames, 2136 UINT cNames, 2137 LCID lcid, 2138 DISPID* rgDispId) 2139 { 2140 saxlocator *This = impl_from_IVBSAXLocator( iface ); 2141 ITypeInfo *typeinfo; 2142 HRESULT hr; 2143 2144 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, 2145 lcid, rgDispId); 2146 2147 if(!rgszNames || cNames == 0 || !rgDispId) 2148 return E_INVALIDARG; 2149 2150 hr = get_typeinfo(IVBSAXLocator_tid, &typeinfo); 2151 if(SUCCEEDED(hr)) 2152 { 2153 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId); 2154 ITypeInfo_Release(typeinfo); 2155 } 2156 2157 return hr; 2158 } 2159 2160 static HRESULT WINAPI ivbsaxlocator_Invoke( 2161 IVBSAXLocator *iface, 2162 DISPID dispIdMember, 2163 REFIID riid, 2164 LCID lcid, 2165 WORD wFlags, 2166 DISPPARAMS* pDispParams, 2167 VARIANT* pVarResult, 2168 EXCEPINFO* pExcepInfo, 2169 UINT* puArgErr) 2170 { 2171 saxlocator *This = impl_from_IVBSAXLocator( iface ); 2172 ITypeInfo *typeinfo; 2173 HRESULT hr; 2174 2175 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), 2176 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 2177 2178 hr = get_typeinfo(IVBSAXLocator_tid, &typeinfo); 2179 if(SUCCEEDED(hr)) 2180 { 2181 hr = ITypeInfo_Invoke(typeinfo, &This->IVBSAXLocator_iface, dispIdMember, wFlags, 2182 pDispParams, pVarResult, pExcepInfo, puArgErr); 2183 ITypeInfo_Release(typeinfo); 2184 } 2185 2186 return hr; 2187 } 2188 2189 /*** IVBSAXLocator methods ***/ 2190 static HRESULT WINAPI ivbsaxlocator_get_columnNumber( 2191 IVBSAXLocator* iface, 2192 int *pnColumn) 2193 { 2194 saxlocator *This = impl_from_IVBSAXLocator( iface ); 2195 return ISAXLocator_getColumnNumber(&This->ISAXLocator_iface, pnColumn); 2196 } 2197 2198 static HRESULT WINAPI ivbsaxlocator_get_lineNumber( 2199 IVBSAXLocator* iface, 2200 int *pnLine) 2201 { 2202 saxlocator *This = impl_from_IVBSAXLocator( iface ); 2203 return ISAXLocator_getLineNumber(&This->ISAXLocator_iface, pnLine); 2204 } 2205 2206 static HRESULT WINAPI ivbsaxlocator_get_publicId(IVBSAXLocator* iface, BSTR *ret) 2207 { 2208 saxlocator *This = impl_from_IVBSAXLocator( iface ); 2209 const WCHAR *publicidW; 2210 HRESULT hr; 2211 2212 TRACE("(%p)->(%p)\n", This, ret); 2213 2214 if (!ret) 2215 return E_POINTER; 2216 2217 *ret = NULL; 2218 hr = ISAXLocator_getPublicId(&This->ISAXLocator_iface, &publicidW); 2219 if (FAILED(hr)) 2220 return hr; 2221 2222 return return_bstr(publicidW, ret); 2223 } 2224 2225 static HRESULT WINAPI ivbsaxlocator_get_systemId(IVBSAXLocator* iface, BSTR *ret) 2226 { 2227 saxlocator *This = impl_from_IVBSAXLocator( iface ); 2228 const WCHAR *systemidW; 2229 HRESULT hr; 2230 2231 TRACE("(%p)->(%p)\n", This, ret); 2232 2233 if (!ret) 2234 return E_POINTER; 2235 2236 *ret = NULL; 2237 hr = ISAXLocator_getSystemId(&This->ISAXLocator_iface, &systemidW); 2238 if (FAILED(hr)) 2239 return hr; 2240 2241 return return_bstr(systemidW, ret); 2242 } 2243 2244 static const struct IVBSAXLocatorVtbl VBSAXLocatorVtbl = 2245 { 2246 ivbsaxlocator_QueryInterface, 2247 ivbsaxlocator_AddRef, 2248 ivbsaxlocator_Release, 2249 ivbsaxlocator_GetTypeInfoCount, 2250 ivbsaxlocator_GetTypeInfo, 2251 ivbsaxlocator_GetIDsOfNames, 2252 ivbsaxlocator_Invoke, 2253 ivbsaxlocator_get_columnNumber, 2254 ivbsaxlocator_get_lineNumber, 2255 ivbsaxlocator_get_publicId, 2256 ivbsaxlocator_get_systemId 2257 }; 2258 2259 /*** ISAXLocator interface ***/ 2260 /*** IUnknown methods ***/ 2261 static HRESULT WINAPI isaxlocator_QueryInterface(ISAXLocator* iface, REFIID riid, void **ppvObject) 2262 { 2263 saxlocator *This = impl_from_ISAXLocator( iface ); 2264 2265 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject ); 2266 2267 *ppvObject = NULL; 2268 2269 if ( IsEqualGUID( riid, &IID_IUnknown ) || 2270 IsEqualGUID( riid, &IID_ISAXLocator )) 2271 { 2272 *ppvObject = iface; 2273 } 2274 else if ( IsEqualGUID( riid, &IID_ISAXAttributes )) 2275 { 2276 *ppvObject = &This->ISAXAttributes_iface; 2277 } 2278 else 2279 { 2280 WARN("interface %s not implemented\n", debugstr_guid(riid)); 2281 return E_NOINTERFACE; 2282 } 2283 2284 ISAXLocator_AddRef( iface ); 2285 2286 return S_OK; 2287 } 2288 2289 static ULONG WINAPI isaxlocator_AddRef(ISAXLocator* iface) 2290 { 2291 saxlocator *This = impl_from_ISAXLocator( iface ); 2292 ULONG ref = InterlockedIncrement( &This->ref ); 2293 TRACE("(%p)->(%d)\n", This, ref); 2294 return ref; 2295 } 2296 2297 static ULONG WINAPI isaxlocator_Release( 2298 ISAXLocator* iface) 2299 { 2300 saxlocator *This = impl_from_ISAXLocator( iface ); 2301 LONG ref = InterlockedDecrement( &This->ref ); 2302 2303 TRACE("(%p)->(%d)\n", This, ref ); 2304 2305 if (ref == 0) 2306 { 2307 element_entry *element, *element2; 2308 int index; 2309 2310 SysFreeString(This->publicId); 2311 SysFreeString(This->systemId); 2312 SysFreeString(This->namespaceUri); 2313 2314 for(index = 0; index < This->attr_alloc_count; index++) 2315 { 2316 SysFreeString(This->attributes[index].szLocalname); 2317 SysFreeString(This->attributes[index].szValue); 2318 SysFreeString(This->attributes[index].szQName); 2319 } 2320 heap_free(This->attributes); 2321 2322 /* element stack */ 2323 LIST_FOR_EACH_ENTRY_SAFE(element, element2, &This->elements, element_entry, entry) 2324 { 2325 list_remove(&element->entry); 2326 free_element_entry(element); 2327 } 2328 2329 ISAXXMLReader_Release(&This->saxreader->ISAXXMLReader_iface); 2330 heap_free( This ); 2331 } 2332 2333 return ref; 2334 } 2335 2336 /*** ISAXLocator methods ***/ 2337 static HRESULT WINAPI isaxlocator_getColumnNumber( 2338 ISAXLocator* iface, 2339 int *pnColumn) 2340 { 2341 saxlocator *This = impl_from_ISAXLocator( iface ); 2342 2343 *pnColumn = This->column; 2344 return S_OK; 2345 } 2346 2347 static HRESULT WINAPI isaxlocator_getLineNumber( 2348 ISAXLocator* iface, 2349 int *pnLine) 2350 { 2351 saxlocator *This = impl_from_ISAXLocator( iface ); 2352 2353 *pnLine = This->line; 2354 return S_OK; 2355 } 2356 2357 static HRESULT WINAPI isaxlocator_getPublicId( 2358 ISAXLocator* iface, 2359 const WCHAR ** ppwchPublicId) 2360 { 2361 BSTR publicId; 2362 saxlocator *This = impl_from_ISAXLocator( iface ); 2363 2364 SysFreeString(This->publicId); 2365 2366 publicId = bstr_from_xmlChar(xmlSAX2GetPublicId(This->pParserCtxt)); 2367 if(SysStringLen(publicId)) 2368 This->publicId = publicId; 2369 else 2370 { 2371 SysFreeString(publicId); 2372 This->publicId = NULL; 2373 } 2374 2375 *ppwchPublicId = This->publicId; 2376 return S_OK; 2377 } 2378 2379 static HRESULT WINAPI isaxlocator_getSystemId( 2380 ISAXLocator* iface, 2381 const WCHAR ** ppwchSystemId) 2382 { 2383 BSTR systemId; 2384 saxlocator *This = impl_from_ISAXLocator( iface ); 2385 2386 SysFreeString(This->systemId); 2387 2388 systemId = bstr_from_xmlChar(xmlSAX2GetSystemId(This->pParserCtxt)); 2389 if(SysStringLen(systemId)) 2390 This->systemId = systemId; 2391 else 2392 { 2393 SysFreeString(systemId); 2394 This->systemId = NULL; 2395 } 2396 2397 *ppwchSystemId = This->systemId; 2398 return S_OK; 2399 } 2400 2401 static const struct ISAXLocatorVtbl SAXLocatorVtbl = 2402 { 2403 isaxlocator_QueryInterface, 2404 isaxlocator_AddRef, 2405 isaxlocator_Release, 2406 isaxlocator_getColumnNumber, 2407 isaxlocator_getLineNumber, 2408 isaxlocator_getPublicId, 2409 isaxlocator_getSystemId 2410 }; 2411 2412 static HRESULT SAXLocator_create(saxreader *reader, saxlocator **ppsaxlocator, BOOL vbInterface) 2413 { 2414 static const WCHAR w3xmlns[] = { 'h','t','t','p',':','/','/', 'w','w','w','.','w','3','.', 2415 'o','r','g','/','2','0','0','0','/','x','m','l','n','s','/',0 }; 2416 2417 saxlocator *locator; 2418 2419 locator = heap_alloc( sizeof (*locator) ); 2420 if( !locator ) 2421 return E_OUTOFMEMORY; 2422 2423 locator->IVBSAXLocator_iface.lpVtbl = &VBSAXLocatorVtbl; 2424 locator->ISAXLocator_iface.lpVtbl = &SAXLocatorVtbl; 2425 locator->IVBSAXAttributes_iface.lpVtbl = &ivbsaxattributes_vtbl; 2426 locator->ISAXAttributes_iface.lpVtbl = &isaxattributes_vtbl; 2427 locator->ref = 1; 2428 locator->vbInterface = vbInterface; 2429 2430 locator->saxreader = reader; 2431 ISAXXMLReader_AddRef(&reader->ISAXXMLReader_iface); 2432 2433 locator->pParserCtxt = NULL; 2434 locator->publicId = NULL; 2435 locator->systemId = NULL; 2436 locator->line = reader->version < MSXML4 ? 0 : 1; 2437 locator->column = 0; 2438 locator->ret = S_OK; 2439 if (locator->saxreader->version >= MSXML6) 2440 locator->namespaceUri = SysAllocString(w3xmlns); 2441 else 2442 locator->namespaceUri = SysAllocStringLen(NULL, 0); 2443 if(!locator->namespaceUri) 2444 { 2445 ISAXXMLReader_Release(&reader->ISAXXMLReader_iface); 2446 heap_free(locator); 2447 return E_OUTOFMEMORY; 2448 } 2449 2450 locator->attr_alloc_count = 8; 2451 locator->attr_count = 0; 2452 locator->attributes = heap_alloc_zero(sizeof(struct _attributes)*locator->attr_alloc_count); 2453 if(!locator->attributes) 2454 { 2455 ISAXXMLReader_Release(&reader->ISAXXMLReader_iface); 2456 SysFreeString(locator->namespaceUri); 2457 heap_free(locator); 2458 return E_OUTOFMEMORY; 2459 } 2460 2461 list_init(&locator->elements); 2462 2463 *ppsaxlocator = locator; 2464 2465 TRACE("returning %p\n", *ppsaxlocator); 2466 2467 return S_OK; 2468 } 2469 2470 /*** SAXXMLReader internal functions ***/ 2471 static HRESULT internal_parseBuffer(saxreader *This, const char *buffer, int size, BOOL vbInterface) 2472 { 2473 xmlCharEncoding encoding = XML_CHAR_ENCODING_NONE; 2474 xmlChar *enc_name = NULL; 2475 saxlocator *locator; 2476 HRESULT hr; 2477 2478 TRACE("(%p)->(%p %d)\n", This, buffer, size); 2479 2480 hr = SAXLocator_create(This, &locator, vbInterface); 2481 if (FAILED(hr)) 2482 return hr; 2483 2484 if (size >= 4) 2485 { 2486 const unsigned char *buff = (unsigned char*)buffer; 2487 2488 encoding = xmlDetectCharEncoding((xmlChar*)buffer, 4); 2489 enc_name = (xmlChar*)xmlGetCharEncodingName(encoding); 2490 TRACE("detected encoding: %s\n", enc_name); 2491 /* skip BOM, parser won't switch encodings and so won't skip it on its own */ 2492 if ((encoding == XML_CHAR_ENCODING_UTF8) && 2493 buff[0] == 0xEF && buff[1] == 0xBB && buff[2] == 0xBF) 2494 { 2495 buffer += 3; 2496 size -= 3; 2497 } 2498 } 2499 2500 /* if libxml2 detection failed try to guess */ 2501 if (encoding == XML_CHAR_ENCODING_NONE) 2502 { 2503 const WCHAR *ptr = (WCHAR*)buffer; 2504 /* an xml declaration with optional encoding will still be handled by the parser */ 2505 if ((size >= 2) && *ptr == '<' && ptr[1] != '?') 2506 { 2507 enc_name = (xmlChar*)xmlGetCharEncodingName(XML_CHAR_ENCODING_UTF16LE); 2508 encoding = XML_CHAR_ENCODING_UTF16LE; 2509 } 2510 } 2511 else if (encoding == XML_CHAR_ENCODING_UTF8) 2512 enc_name = (xmlChar*)xmlGetCharEncodingName(encoding); 2513 else 2514 enc_name = NULL; 2515 2516 locator->pParserCtxt = xmlCreateMemoryParserCtxt(buffer, size); 2517 if (!locator->pParserCtxt) 2518 { 2519 ISAXLocator_Release(&locator->ISAXLocator_iface); 2520 return E_FAIL; 2521 } 2522 2523 if (enc_name) 2524 { 2525 locator->pParserCtxt->encoding = xmlStrdup(enc_name); 2526 if (encoding == XML_CHAR_ENCODING_UTF16LE) { 2527 TRACE("switching to %s\n", enc_name); 2528 xmlSwitchEncoding(locator->pParserCtxt, encoding); 2529 } 2530 } 2531 2532 xmlFree(locator->pParserCtxt->sax); 2533 locator->pParserCtxt->sax = &locator->saxreader->sax; 2534 locator->pParserCtxt->userData = locator; 2535 2536 This->isParsing = TRUE; 2537 if(xmlParseDocument(locator->pParserCtxt) == -1 && locator->ret == S_OK) 2538 hr = E_FAIL; 2539 else 2540 hr = locator->ret; 2541 This->isParsing = FALSE; 2542 2543 if(locator->pParserCtxt) 2544 { 2545 locator->pParserCtxt->sax = NULL; 2546 xmlFreeParserCtxt(locator->pParserCtxt); 2547 locator->pParserCtxt = NULL; 2548 } 2549 2550 ISAXLocator_Release(&locator->ISAXLocator_iface); 2551 return hr; 2552 } 2553 2554 static HRESULT internal_parseStream(saxreader *This, ISequentialStream *stream, BOOL vbInterface) 2555 { 2556 saxlocator *locator; 2557 HRESULT hr; 2558 ULONG dataRead; 2559 char data[2048]; 2560 int ret; 2561 2562 dataRead = 0; 2563 hr = ISequentialStream_Read(stream, data, sizeof(data), &dataRead); 2564 if(FAILED(hr)) return hr; 2565 2566 hr = SAXLocator_create(This, &locator, vbInterface); 2567 if(FAILED(hr)) return hr; 2568 2569 locator->pParserCtxt = xmlCreatePushParserCtxt( 2570 &locator->saxreader->sax, locator, 2571 data, dataRead, NULL); 2572 if(!locator->pParserCtxt) 2573 { 2574 ISAXLocator_Release(&locator->ISAXLocator_iface); 2575 return E_FAIL; 2576 } 2577 2578 This->isParsing = TRUE; 2579 2580 do { 2581 dataRead = 0; 2582 hr = ISequentialStream_Read(stream, data, sizeof(data), &dataRead); 2583 if (FAILED(hr) || !dataRead) break; 2584 2585 ret = xmlParseChunk(locator->pParserCtxt, data, dataRead, 0); 2586 hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret; 2587 }while(hr == S_OK); 2588 2589 if(SUCCEEDED(hr)) 2590 { 2591 ret = xmlParseChunk(locator->pParserCtxt, data, 0, 1); 2592 hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret; 2593 } 2594 2595 2596 This->isParsing = FALSE; 2597 2598 xmlFreeParserCtxt(locator->pParserCtxt); 2599 locator->pParserCtxt = NULL; 2600 ISAXLocator_Release(&locator->ISAXLocator_iface); 2601 return hr; 2602 } 2603 2604 static HRESULT internal_parse( 2605 saxreader* This, 2606 VARIANT varInput, 2607 BOOL vbInterface) 2608 { 2609 HRESULT hr; 2610 2611 TRACE("(%p)->(%s)\n", This, debugstr_variant(&varInput)); 2612 2613 /* Dispose of the BSTRs in the pool from a prior run, if any. */ 2614 free_bstr_pool(&This->pool); 2615 2616 switch(V_VT(&varInput)) 2617 { 2618 case VT_BSTR: 2619 case VT_BSTR|VT_BYREF: 2620 { 2621 BSTR str = V_ISBYREF(&varInput) ? *V_BSTRREF(&varInput) : V_BSTR(&varInput); 2622 hr = internal_parseBuffer(This, (const char*)str, strlenW(str)*sizeof(WCHAR), vbInterface); 2623 break; 2624 } 2625 case VT_ARRAY|VT_UI1: { 2626 void *pSAData; 2627 LONG lBound, uBound; 2628 ULONG dataRead; 2629 2630 hr = SafeArrayGetLBound(V_ARRAY(&varInput), 1, &lBound); 2631 if(hr != S_OK) break; 2632 hr = SafeArrayGetUBound(V_ARRAY(&varInput), 1, &uBound); 2633 if(hr != S_OK) break; 2634 dataRead = (uBound-lBound)*SafeArrayGetElemsize(V_ARRAY(&varInput)); 2635 hr = SafeArrayAccessData(V_ARRAY(&varInput), &pSAData); 2636 if(hr != S_OK) break; 2637 hr = internal_parseBuffer(This, pSAData, dataRead, vbInterface); 2638 SafeArrayUnaccessData(V_ARRAY(&varInput)); 2639 break; 2640 } 2641 case VT_UNKNOWN: 2642 case VT_DISPATCH: { 2643 ISequentialStream *stream = NULL; 2644 IXMLDOMDocument *xmlDoc; 2645 2646 if (!V_UNKNOWN(&varInput)) 2647 return E_INVALIDARG; 2648 2649 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput), 2650 &IID_IXMLDOMDocument, (void**)&xmlDoc) == S_OK) 2651 { 2652 BSTR bstrData; 2653 2654 IXMLDOMDocument_get_xml(xmlDoc, &bstrData); 2655 hr = internal_parseBuffer(This, (const char*)bstrData, 2656 SysStringByteLen(bstrData), vbInterface); 2657 IXMLDOMDocument_Release(xmlDoc); 2658 SysFreeString(bstrData); 2659 break; 2660 } 2661 2662 /* try base interface first */ 2663 IUnknown_QueryInterface(V_UNKNOWN(&varInput), &IID_ISequentialStream, (void**)&stream); 2664 if (!stream) 2665 /* this should never happen if IStream is implemented properly, but just in case */ 2666 IUnknown_QueryInterface(V_UNKNOWN(&varInput), &IID_IStream, (void**)&stream); 2667 2668 if(stream) 2669 { 2670 hr = internal_parseStream(This, stream, vbInterface); 2671 ISequentialStream_Release(stream); 2672 } 2673 else 2674 { 2675 WARN("IUnknown* input doesn't support any of expected interfaces\n"); 2676 hr = E_INVALIDARG; 2677 } 2678 2679 break; 2680 } 2681 default: 2682 WARN("vt %d not implemented\n", V_VT(&varInput)); 2683 hr = E_INVALIDARG; 2684 } 2685 2686 return hr; 2687 } 2688 2689 static HRESULT internal_vbonDataAvailable(void *obj, char *ptr, DWORD len) 2690 { 2691 saxreader *This = obj; 2692 2693 return internal_parseBuffer(This, ptr, len, TRUE); 2694 } 2695 2696 static HRESULT internal_onDataAvailable(void *obj, char *ptr, DWORD len) 2697 { 2698 saxreader *This = obj; 2699 2700 return internal_parseBuffer(This, ptr, len, FALSE); 2701 } 2702 2703 static HRESULT internal_parseURL( 2704 saxreader* This, 2705 const WCHAR *url, 2706 BOOL vbInterface) 2707 { 2708 IMoniker *mon; 2709 bsc_t *bsc; 2710 HRESULT hr; 2711 2712 TRACE("(%p)->(%s)\n", This, debugstr_w(url)); 2713 2714 hr = create_moniker_from_url(url, &mon); 2715 if(FAILED(hr)) 2716 return hr; 2717 2718 if(vbInterface) hr = bind_url(mon, internal_vbonDataAvailable, This, &bsc); 2719 else hr = bind_url(mon, internal_onDataAvailable, This, &bsc); 2720 IMoniker_Release(mon); 2721 2722 if(FAILED(hr)) 2723 return hr; 2724 2725 return detach_bsc(bsc); 2726 } 2727 2728 static HRESULT saxreader_put_handler_from_variant(saxreader *This, enum saxhandler_type type, const VARIANT *v, BOOL vb) 2729 { 2730 const IID *riid; 2731 2732 if (V_VT(v) == VT_EMPTY) 2733 return saxreader_put_handler(This, type, NULL, vb); 2734 2735 switch (type) 2736 { 2737 case SAXDeclHandler: 2738 riid = vb ? &IID_IVBSAXDeclHandler : &IID_ISAXDeclHandler; 2739 break; 2740 case SAXLexicalHandler: 2741 riid = vb ? &IID_IVBSAXLexicalHandler : &IID_ISAXLexicalHandler; 2742 break; 2743 default: 2744 ERR("wrong handler type %d\n", type); 2745 return E_FAIL; 2746 } 2747 2748 switch (V_VT(v)) 2749 { 2750 case VT_DISPATCH: 2751 case VT_UNKNOWN: 2752 { 2753 IUnknown *handler = NULL; 2754 2755 if (V_UNKNOWN(v)) 2756 { 2757 HRESULT hr = IUnknown_QueryInterface(V_UNKNOWN(v), riid, (void**)&handler); 2758 if (FAILED(hr)) return hr; 2759 } 2760 2761 saxreader_put_handler(This, type, handler, vb); 2762 if (handler) IUnknown_Release(handler); 2763 break; 2764 } 2765 default: 2766 ERR("value type %d not supported\n", V_VT(v)); 2767 return E_INVALIDARG; 2768 } 2769 2770 return S_OK; 2771 } 2772 2773 static HRESULT internal_putProperty( 2774 saxreader* This, 2775 const WCHAR *prop, 2776 VARIANT value, 2777 BOOL vbInterface) 2778 { 2779 VARIANT *v; 2780 2781 TRACE("(%p)->(%s %s)\n", This, debugstr_w(prop), debugstr_variant(&value)); 2782 2783 if (This->isParsing) return E_FAIL; 2784 2785 v = V_VT(&value) == (VT_VARIANT|VT_BYREF) ? V_VARIANTREF(&value) : &value; 2786 if(!memcmp(prop, PropertyDeclHandlerW, sizeof(PropertyDeclHandlerW))) 2787 return saxreader_put_handler_from_variant(This, SAXDeclHandler, v, vbInterface); 2788 2789 if(!memcmp(prop, PropertyLexicalHandlerW, sizeof(PropertyLexicalHandlerW))) 2790 return saxreader_put_handler_from_variant(This, SAXLexicalHandler, v, vbInterface); 2791 2792 if(!memcmp(prop, PropertyMaxXMLSizeW, sizeof(PropertyMaxXMLSizeW))) 2793 { 2794 if (V_VT(v) == VT_I4 && V_I4(v) == 0) return S_OK; 2795 FIXME("(%p)->(%s): max-xml-size unsupported\n", This, debugstr_variant(v)); 2796 return E_NOTIMPL; 2797 } 2798 2799 if(!memcmp(prop, PropertyMaxElementDepthW, sizeof(PropertyMaxElementDepthW))) 2800 { 2801 if (V_VT(v) == VT_I4 && V_I4(v) == 0) return S_OK; 2802 FIXME("(%p)->(%s): max-element-depth unsupported\n", This, debugstr_variant(v)); 2803 return E_NOTIMPL; 2804 } 2805 2806 FIXME("(%p)->(%s:%s): unsupported property\n", This, debugstr_w(prop), debugstr_variant(v)); 2807 2808 if(!memcmp(prop, PropertyCharsetW, sizeof(PropertyCharsetW))) 2809 return E_NOTIMPL; 2810 2811 if(!memcmp(prop, PropertyDomNodeW, sizeof(PropertyDomNodeW))) 2812 return E_FAIL; 2813 2814 if(!memcmp(prop, PropertyInputSourceW, sizeof(PropertyInputSourceW))) 2815 return E_NOTIMPL; 2816 2817 if(!memcmp(prop, PropertySchemaDeclHandlerW, sizeof(PropertySchemaDeclHandlerW))) 2818 return E_NOTIMPL; 2819 2820 if(!memcmp(prop, PropertyXMLDeclEncodingW, sizeof(PropertyXMLDeclEncodingW))) 2821 return E_FAIL; 2822 2823 if(!memcmp(prop, PropertyXMLDeclStandaloneW, sizeof(PropertyXMLDeclStandaloneW))) 2824 return E_FAIL; 2825 2826 if(!memcmp(prop, PropertyXMLDeclVersionW, sizeof(PropertyXMLDeclVersionW))) 2827 return E_FAIL; 2828 2829 return E_INVALIDARG; 2830 } 2831 2832 static HRESULT internal_getProperty(const saxreader* This, const WCHAR *prop, VARIANT *value, BOOL vb) 2833 { 2834 TRACE("(%p)->(%s)\n", This, debugstr_w(prop)); 2835 2836 if (!value) return E_POINTER; 2837 2838 if (!memcmp(PropertyLexicalHandlerW, prop, sizeof(PropertyLexicalHandlerW))) 2839 { 2840 V_VT(value) = VT_UNKNOWN; 2841 saxreader_get_handler(This, SAXLexicalHandler, vb, (void**)&V_UNKNOWN(value)); 2842 return S_OK; 2843 } 2844 2845 if (!memcmp(PropertyDeclHandlerW, prop, sizeof(PropertyDeclHandlerW))) 2846 { 2847 V_VT(value) = VT_UNKNOWN; 2848 saxreader_get_handler(This, SAXDeclHandler, vb, (void**)&V_UNKNOWN(value)); 2849 return S_OK; 2850 } 2851 2852 if (!memcmp(PropertyXmlDeclVersionW, prop, sizeof(PropertyXmlDeclVersionW))) 2853 { 2854 V_VT(value) = VT_BSTR; 2855 V_BSTR(value) = SysAllocString(This->xmldecl_version); 2856 return S_OK; 2857 } 2858 2859 FIXME("(%p)->(%s) unsupported property\n", This, debugstr_w(prop)); 2860 2861 return E_NOTIMPL; 2862 } 2863 2864 /*** IVBSAXXMLReader interface ***/ 2865 /*** IUnknown methods ***/ 2866 static HRESULT WINAPI saxxmlreader_QueryInterface(IVBSAXXMLReader* iface, REFIID riid, void **ppvObject) 2867 { 2868 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 2869 2870 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject ); 2871 2872 *ppvObject = NULL; 2873 2874 if ( IsEqualGUID( riid, &IID_IUnknown ) || 2875 IsEqualGUID( riid, &IID_IDispatch ) || 2876 IsEqualGUID( riid, &IID_IVBSAXXMLReader )) 2877 { 2878 *ppvObject = iface; 2879 } 2880 else if( IsEqualGUID( riid, &IID_ISAXXMLReader )) 2881 { 2882 *ppvObject = &This->ISAXXMLReader_iface; 2883 } 2884 else if (dispex_query_interface(&This->dispex, riid, ppvObject)) 2885 { 2886 return *ppvObject ? S_OK : E_NOINTERFACE; 2887 } 2888 else 2889 { 2890 FIXME("interface %s not implemented\n", debugstr_guid(riid)); 2891 return E_NOINTERFACE; 2892 } 2893 2894 IVBSAXXMLReader_AddRef( iface ); 2895 2896 return S_OK; 2897 } 2898 2899 static ULONG WINAPI saxxmlreader_AddRef(IVBSAXXMLReader* iface) 2900 { 2901 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 2902 TRACE("%p\n", This ); 2903 return InterlockedIncrement( &This->ref ); 2904 } 2905 2906 static ULONG WINAPI saxxmlreader_Release( 2907 IVBSAXXMLReader* iface) 2908 { 2909 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 2910 LONG ref; 2911 2912 TRACE("%p\n", This ); 2913 2914 ref = InterlockedDecrement( &This->ref ); 2915 if ( ref == 0 ) 2916 { 2917 int i; 2918 2919 for (i = 0; i < SAXHandler_Last; i++) 2920 { 2921 struct saxanyhandler_iface *saxiface = &This->saxhandlers[i].u.anyhandler; 2922 2923 if (saxiface->handler) 2924 IUnknown_Release(saxiface->handler); 2925 2926 if (saxiface->vbhandler) 2927 IUnknown_Release(saxiface->vbhandler); 2928 } 2929 2930 SysFreeString(This->xmldecl_version); 2931 free_bstr_pool(&This->pool); 2932 2933 heap_free( This ); 2934 } 2935 2936 return ref; 2937 } 2938 /*** IDispatch ***/ 2939 static HRESULT WINAPI saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader *iface, UINT* pctinfo ) 2940 { 2941 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 2942 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo); 2943 } 2944 2945 static HRESULT WINAPI saxxmlreader_GetTypeInfo( 2946 IVBSAXXMLReader *iface, 2947 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo ) 2948 { 2949 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 2950 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, 2951 iTInfo, lcid, ppTInfo); 2952 } 2953 2954 static HRESULT WINAPI saxxmlreader_GetIDsOfNames( 2955 IVBSAXXMLReader *iface, 2956 REFIID riid, 2957 LPOLESTR* rgszNames, 2958 UINT cNames, 2959 LCID lcid, 2960 DISPID* rgDispId) 2961 { 2962 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 2963 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, 2964 riid, rgszNames, cNames, lcid, rgDispId); 2965 } 2966 2967 static HRESULT WINAPI saxxmlreader_Invoke( 2968 IVBSAXXMLReader *iface, 2969 DISPID dispIdMember, 2970 REFIID riid, 2971 LCID lcid, 2972 WORD wFlags, 2973 DISPPARAMS* pDispParams, 2974 VARIANT* pVarResult, 2975 EXCEPINFO* pExcepInfo, 2976 UINT* puArgErr) 2977 { 2978 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 2979 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, 2980 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 2981 } 2982 2983 /*** IVBSAXXMLReader methods ***/ 2984 static HRESULT WINAPI saxxmlreader_getFeature( 2985 IVBSAXXMLReader* iface, 2986 BSTR feature_name, 2987 VARIANT_BOOL *value) 2988 { 2989 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 2990 return ISAXXMLReader_getFeature(&This->ISAXXMLReader_iface, feature_name, value); 2991 } 2992 2993 static HRESULT WINAPI saxxmlreader_putFeature( 2994 IVBSAXXMLReader* iface, 2995 BSTR feature_name, 2996 VARIANT_BOOL value) 2997 { 2998 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 2999 return ISAXXMLReader_putFeature(&This->ISAXXMLReader_iface, feature_name, value); 3000 } 3001 3002 static HRESULT WINAPI saxxmlreader_getProperty( 3003 IVBSAXXMLReader* iface, 3004 BSTR prop, 3005 VARIANT *value) 3006 { 3007 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3008 return internal_getProperty(This, prop, value, TRUE); 3009 } 3010 3011 static HRESULT WINAPI saxxmlreader_putProperty( 3012 IVBSAXXMLReader* iface, 3013 BSTR pProp, 3014 VARIANT value) 3015 { 3016 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3017 return internal_putProperty(This, pProp, value, TRUE); 3018 } 3019 3020 static HRESULT WINAPI saxxmlreader_get_entityResolver( 3021 IVBSAXXMLReader* iface, 3022 IVBSAXEntityResolver **resolver) 3023 { 3024 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3025 return saxreader_get_handler(This, SAXEntityResolver, TRUE, (void**)resolver); 3026 } 3027 3028 static HRESULT WINAPI saxxmlreader_put_entityResolver( 3029 IVBSAXXMLReader* iface, 3030 IVBSAXEntityResolver *resolver) 3031 { 3032 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3033 return saxreader_put_handler(This, SAXEntityResolver, resolver, TRUE); 3034 } 3035 3036 static HRESULT WINAPI saxxmlreader_get_contentHandler( 3037 IVBSAXXMLReader* iface, 3038 IVBSAXContentHandler **handler) 3039 { 3040 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3041 return saxreader_get_handler(This, SAXContentHandler, TRUE, (void**)handler); 3042 } 3043 3044 static HRESULT WINAPI saxxmlreader_put_contentHandler( 3045 IVBSAXXMLReader* iface, 3046 IVBSAXContentHandler *handler) 3047 { 3048 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3049 return saxreader_put_handler(This, SAXContentHandler, handler, TRUE); 3050 } 3051 3052 static HRESULT WINAPI saxxmlreader_get_dtdHandler( 3053 IVBSAXXMLReader* iface, 3054 IVBSAXDTDHandler **handler) 3055 { 3056 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3057 return saxreader_get_handler(This, SAXDTDHandler, TRUE, (void**)handler); 3058 } 3059 3060 static HRESULT WINAPI saxxmlreader_put_dtdHandler( 3061 IVBSAXXMLReader* iface, 3062 IVBSAXDTDHandler *handler) 3063 { 3064 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3065 return saxreader_put_handler(This, SAXDTDHandler, handler, TRUE); 3066 } 3067 3068 static HRESULT WINAPI saxxmlreader_get_errorHandler( 3069 IVBSAXXMLReader* iface, 3070 IVBSAXErrorHandler **handler) 3071 { 3072 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3073 return saxreader_get_handler(This, SAXErrorHandler, TRUE, (void**)handler); 3074 } 3075 3076 static HRESULT WINAPI saxxmlreader_put_errorHandler( 3077 IVBSAXXMLReader* iface, 3078 IVBSAXErrorHandler *handler) 3079 { 3080 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3081 return saxreader_put_handler(This, SAXErrorHandler, handler, TRUE); 3082 } 3083 3084 static HRESULT WINAPI saxxmlreader_get_baseURL( 3085 IVBSAXXMLReader* iface, 3086 BSTR *pBaseUrl) 3087 { 3088 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3089 3090 FIXME("(%p)->(%p) stub\n", This, pBaseUrl); 3091 return E_NOTIMPL; 3092 } 3093 3094 static HRESULT WINAPI saxxmlreader_put_baseURL( 3095 IVBSAXXMLReader* iface, 3096 BSTR pBaseUrl) 3097 { 3098 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3099 return ISAXXMLReader_putBaseURL(&This->ISAXXMLReader_iface, pBaseUrl); 3100 } 3101 3102 static HRESULT WINAPI saxxmlreader_get_secureBaseURL( 3103 IVBSAXXMLReader* iface, 3104 BSTR *pSecureBaseUrl) 3105 { 3106 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3107 3108 FIXME("(%p)->(%p) stub\n", This, pSecureBaseUrl); 3109 return E_NOTIMPL; 3110 } 3111 3112 static HRESULT WINAPI saxxmlreader_put_secureBaseURL( 3113 IVBSAXXMLReader* iface, 3114 BSTR secureBaseUrl) 3115 { 3116 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3117 return ISAXXMLReader_putSecureBaseURL(&This->ISAXXMLReader_iface, secureBaseUrl); 3118 } 3119 3120 static HRESULT WINAPI saxxmlreader_parse( 3121 IVBSAXXMLReader* iface, 3122 VARIANT varInput) 3123 { 3124 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3125 return internal_parse(This, varInput, TRUE); 3126 } 3127 3128 static HRESULT WINAPI saxxmlreader_parseURL( 3129 IVBSAXXMLReader* iface, 3130 BSTR url) 3131 { 3132 saxreader *This = impl_from_IVBSAXXMLReader( iface ); 3133 return internal_parseURL(This, url, TRUE); 3134 } 3135 3136 static const struct IVBSAXXMLReaderVtbl VBSAXXMLReaderVtbl = 3137 { 3138 saxxmlreader_QueryInterface, 3139 saxxmlreader_AddRef, 3140 saxxmlreader_Release, 3141 saxxmlreader_GetTypeInfoCount, 3142 saxxmlreader_GetTypeInfo, 3143 saxxmlreader_GetIDsOfNames, 3144 saxxmlreader_Invoke, 3145 saxxmlreader_getFeature, 3146 saxxmlreader_putFeature, 3147 saxxmlreader_getProperty, 3148 saxxmlreader_putProperty, 3149 saxxmlreader_get_entityResolver, 3150 saxxmlreader_put_entityResolver, 3151 saxxmlreader_get_contentHandler, 3152 saxxmlreader_put_contentHandler, 3153 saxxmlreader_get_dtdHandler, 3154 saxxmlreader_put_dtdHandler, 3155 saxxmlreader_get_errorHandler, 3156 saxxmlreader_put_errorHandler, 3157 saxxmlreader_get_baseURL, 3158 saxxmlreader_put_baseURL, 3159 saxxmlreader_get_secureBaseURL, 3160 saxxmlreader_put_secureBaseURL, 3161 saxxmlreader_parse, 3162 saxxmlreader_parseURL 3163 }; 3164 3165 /*** ISAXXMLReader interface ***/ 3166 /*** IUnknown methods ***/ 3167 static HRESULT WINAPI isaxxmlreader_QueryInterface(ISAXXMLReader* iface, REFIID riid, void **ppvObject) 3168 { 3169 saxreader *This = impl_from_ISAXXMLReader( iface ); 3170 return IVBSAXXMLReader_QueryInterface(&This->IVBSAXXMLReader_iface, riid, ppvObject); 3171 } 3172 3173 static ULONG WINAPI isaxxmlreader_AddRef(ISAXXMLReader* iface) 3174 { 3175 saxreader *This = impl_from_ISAXXMLReader( iface ); 3176 return IVBSAXXMLReader_AddRef(&This->IVBSAXXMLReader_iface); 3177 } 3178 3179 static ULONG WINAPI isaxxmlreader_Release(ISAXXMLReader* iface) 3180 { 3181 saxreader *This = impl_from_ISAXXMLReader( iface ); 3182 return IVBSAXXMLReader_Release(&This->IVBSAXXMLReader_iface); 3183 } 3184 3185 /*** ISAXXMLReader methods ***/ 3186 static HRESULT WINAPI isaxxmlreader_getFeature( 3187 ISAXXMLReader* iface, 3188 const WCHAR *feature_name, 3189 VARIANT_BOOL *value) 3190 { 3191 saxreader *This = impl_from_ISAXXMLReader( iface ); 3192 saxreader_feature feature; 3193 3194 TRACE("(%p)->(%s %p)\n", This, debugstr_w(feature_name), value); 3195 3196 feature = get_saxreader_feature(feature_name); 3197 if (feature == Namespaces || feature == NamespacePrefixes) 3198 return get_feature_value(This, feature, value); 3199 3200 FIXME("(%p)->(%s %p) stub\n", This, debugstr_w(feature_name), value); 3201 return E_NOTIMPL; 3202 } 3203 3204 static HRESULT WINAPI isaxxmlreader_putFeature( 3205 ISAXXMLReader* iface, 3206 const WCHAR *feature_name, 3207 VARIANT_BOOL value) 3208 { 3209 saxreader *This = impl_from_ISAXXMLReader( iface ); 3210 saxreader_feature feature; 3211 3212 TRACE("(%p)->(%s %x)\n", This, debugstr_w(feature_name), value); 3213 3214 feature = get_saxreader_feature(feature_name); 3215 3216 /* accepted cases */ 3217 if ((feature == ExternalGeneralEntities && value == VARIANT_FALSE) || 3218 (feature == ExternalParameterEntities && value == VARIANT_FALSE) || 3219 feature == Namespaces || 3220 feature == NamespacePrefixes) 3221 { 3222 return set_feature_value(This, feature, value); 3223 } 3224 3225 if (feature == LexicalHandlerParEntities || feature == ProhibitDTD) 3226 { 3227 FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(feature_name), value); 3228 return set_feature_value(This, feature, value); 3229 } 3230 3231 FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(feature_name), value); 3232 return E_NOTIMPL; 3233 } 3234 3235 static HRESULT WINAPI isaxxmlreader_getProperty( 3236 ISAXXMLReader* iface, 3237 const WCHAR *prop, 3238 VARIANT *value) 3239 { 3240 saxreader *This = impl_from_ISAXXMLReader( iface ); 3241 return internal_getProperty(This, prop, value, FALSE); 3242 } 3243 3244 static HRESULT WINAPI isaxxmlreader_putProperty( 3245 ISAXXMLReader* iface, 3246 const WCHAR *pProp, 3247 VARIANT value) 3248 { 3249 saxreader *This = impl_from_ISAXXMLReader( iface ); 3250 return internal_putProperty(This, pProp, value, FALSE); 3251 } 3252 3253 static HRESULT WINAPI isaxxmlreader_getEntityResolver( 3254 ISAXXMLReader* iface, 3255 ISAXEntityResolver **resolver) 3256 { 3257 saxreader *This = impl_from_ISAXXMLReader( iface ); 3258 return saxreader_get_handler(This, SAXEntityResolver, FALSE, (void**)resolver); 3259 } 3260 3261 static HRESULT WINAPI isaxxmlreader_putEntityResolver( 3262 ISAXXMLReader* iface, 3263 ISAXEntityResolver *resolver) 3264 { 3265 saxreader *This = impl_from_ISAXXMLReader( iface ); 3266 return saxreader_put_handler(This, SAXEntityResolver, resolver, FALSE); 3267 } 3268 3269 static HRESULT WINAPI isaxxmlreader_getContentHandler( 3270 ISAXXMLReader* iface, 3271 ISAXContentHandler **handler) 3272 { 3273 saxreader *This = impl_from_ISAXXMLReader( iface ); 3274 return saxreader_get_handler(This, SAXContentHandler, FALSE, (void**)handler); 3275 } 3276 3277 static HRESULT WINAPI isaxxmlreader_putContentHandler( 3278 ISAXXMLReader* iface, 3279 ISAXContentHandler *handler) 3280 { 3281 saxreader *This = impl_from_ISAXXMLReader( iface ); 3282 return saxreader_put_handler(This, SAXContentHandler, handler, FALSE); 3283 } 3284 3285 static HRESULT WINAPI isaxxmlreader_getDTDHandler( 3286 ISAXXMLReader* iface, 3287 ISAXDTDHandler **handler) 3288 { 3289 saxreader *This = impl_from_ISAXXMLReader( iface ); 3290 return saxreader_get_handler(This, SAXDTDHandler, FALSE, (void**)handler); 3291 } 3292 3293 static HRESULT WINAPI isaxxmlreader_putDTDHandler( 3294 ISAXXMLReader* iface, 3295 ISAXDTDHandler *handler) 3296 { 3297 saxreader *This = impl_from_ISAXXMLReader( iface ); 3298 return saxreader_put_handler(This, SAXDTDHandler, handler, FALSE); 3299 } 3300 3301 static HRESULT WINAPI isaxxmlreader_getErrorHandler( 3302 ISAXXMLReader* iface, 3303 ISAXErrorHandler **handler) 3304 { 3305 saxreader *This = impl_from_ISAXXMLReader( iface ); 3306 return saxreader_get_handler(This, SAXErrorHandler, FALSE, (void**)handler); 3307 } 3308 3309 static HRESULT WINAPI isaxxmlreader_putErrorHandler(ISAXXMLReader* iface, ISAXErrorHandler *handler) 3310 { 3311 saxreader *This = impl_from_ISAXXMLReader( iface ); 3312 return saxreader_put_handler(This, SAXErrorHandler, handler, FALSE); 3313 } 3314 3315 static HRESULT WINAPI isaxxmlreader_getBaseURL( 3316 ISAXXMLReader* iface, 3317 const WCHAR **base_url) 3318 { 3319 saxreader *This = impl_from_ISAXXMLReader( iface ); 3320 3321 FIXME("(%p)->(%p) stub\n", This, base_url); 3322 return E_NOTIMPL; 3323 } 3324 3325 static HRESULT WINAPI isaxxmlreader_putBaseURL( 3326 ISAXXMLReader* iface, 3327 const WCHAR *pBaseUrl) 3328 { 3329 saxreader *This = impl_from_ISAXXMLReader( iface ); 3330 3331 FIXME("(%p)->(%s) stub\n", This, debugstr_w(pBaseUrl)); 3332 return E_NOTIMPL; 3333 } 3334 3335 static HRESULT WINAPI isaxxmlreader_getSecureBaseURL( 3336 ISAXXMLReader* iface, 3337 const WCHAR **pSecureBaseUrl) 3338 { 3339 saxreader *This = impl_from_ISAXXMLReader( iface ); 3340 FIXME("(%p)->(%p) stub\n", This, pSecureBaseUrl); 3341 return E_NOTIMPL; 3342 } 3343 3344 static HRESULT WINAPI isaxxmlreader_putSecureBaseURL( 3345 ISAXXMLReader* iface, 3346 const WCHAR *secureBaseUrl) 3347 { 3348 saxreader *This = impl_from_ISAXXMLReader( iface ); 3349 3350 FIXME("(%p)->(%s) stub\n", This, debugstr_w(secureBaseUrl)); 3351 return E_NOTIMPL; 3352 } 3353 3354 static HRESULT WINAPI isaxxmlreader_parse( 3355 ISAXXMLReader* iface, 3356 VARIANT varInput) 3357 { 3358 saxreader *This = impl_from_ISAXXMLReader( iface ); 3359 return internal_parse(This, varInput, FALSE); 3360 } 3361 3362 static HRESULT WINAPI isaxxmlreader_parseURL( 3363 ISAXXMLReader* iface, 3364 const WCHAR *url) 3365 { 3366 saxreader *This = impl_from_ISAXXMLReader( iface ); 3367 return internal_parseURL(This, url, FALSE); 3368 } 3369 3370 static const struct ISAXXMLReaderVtbl SAXXMLReaderVtbl = 3371 { 3372 isaxxmlreader_QueryInterface, 3373 isaxxmlreader_AddRef, 3374 isaxxmlreader_Release, 3375 isaxxmlreader_getFeature, 3376 isaxxmlreader_putFeature, 3377 isaxxmlreader_getProperty, 3378 isaxxmlreader_putProperty, 3379 isaxxmlreader_getEntityResolver, 3380 isaxxmlreader_putEntityResolver, 3381 isaxxmlreader_getContentHandler, 3382 isaxxmlreader_putContentHandler, 3383 isaxxmlreader_getDTDHandler, 3384 isaxxmlreader_putDTDHandler, 3385 isaxxmlreader_getErrorHandler, 3386 isaxxmlreader_putErrorHandler, 3387 isaxxmlreader_getBaseURL, 3388 isaxxmlreader_putBaseURL, 3389 isaxxmlreader_getSecureBaseURL, 3390 isaxxmlreader_putSecureBaseURL, 3391 isaxxmlreader_parse, 3392 isaxxmlreader_parseURL 3393 }; 3394 3395 static const tid_t saxreader_iface_tids[] = { 3396 IVBSAXXMLReader_tid, 3397 0 3398 }; 3399 static dispex_static_data_t saxreader_dispex = { 3400 NULL, 3401 IVBSAXXMLReader_tid, 3402 NULL, 3403 saxreader_iface_tids 3404 }; 3405 3406 HRESULT SAXXMLReader_create(MSXML_VERSION version, LPVOID *ppObj) 3407 { 3408 saxreader *reader; 3409 3410 TRACE("(%p)\n", ppObj); 3411 3412 reader = heap_alloc( sizeof (*reader) ); 3413 if( !reader ) 3414 return E_OUTOFMEMORY; 3415 3416 reader->IVBSAXXMLReader_iface.lpVtbl = &VBSAXXMLReaderVtbl; 3417 reader->ISAXXMLReader_iface.lpVtbl = &SAXXMLReaderVtbl; 3418 reader->ref = 1; 3419 memset(reader->saxhandlers, 0, sizeof(reader->saxhandlers)); 3420 reader->isParsing = FALSE; 3421 reader->xmldecl_version = NULL; 3422 reader->pool.pool = NULL; 3423 reader->pool.index = 0; 3424 reader->pool.len = 0; 3425 reader->features = Namespaces | NamespacePrefixes; 3426 reader->version = version; 3427 3428 init_dispex(&reader->dispex, (IUnknown*)&reader->IVBSAXXMLReader_iface, &saxreader_dispex); 3429 3430 memset(&reader->sax, 0, sizeof(xmlSAXHandler)); 3431 reader->sax.initialized = XML_SAX2_MAGIC; 3432 reader->sax.startDocument = libxmlStartDocument; 3433 reader->sax.endDocument = libxmlEndDocument; 3434 reader->sax.startElementNs = libxmlStartElementNS; 3435 reader->sax.endElementNs = libxmlEndElementNS; 3436 reader->sax.characters = libxmlCharacters; 3437 reader->sax.setDocumentLocator = libxmlSetDocumentLocator; 3438 reader->sax.comment = libxmlComment; 3439 reader->sax.error = libxmlFatalError; 3440 reader->sax.fatalError = libxmlFatalError; 3441 reader->sax.cdataBlock = libxml_cdatablock; 3442 reader->sax.resolveEntity = libxmlresolveentity; 3443 3444 *ppObj = &reader->IVBSAXXMLReader_iface; 3445 3446 TRACE("returning iface %p\n", *ppObj); 3447 3448 return S_OK; 3449 } 3450 3451 #else 3452 3453 HRESULT SAXXMLReader_create(MSXML_VERSION version, LPVOID *ppObj) 3454 { 3455 MESSAGE("This program tried to use a SAX XML Reader object, but\n" 3456 "libxml2 support was not present at compile time.\n"); 3457 return E_NOTIMPL; 3458 } 3459 3460 #endif 3461