1 /* 2 * DOM comment node implementation 3 * 4 * Copyright 2006 Huw Davies 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #define COBJMACROS 22 23 #include "config.h" 24 25 #include <stdarg.h> 26 #ifdef HAVE_LIBXML2 27 # include <libxml/parser.h> 28 # include <libxml/xmlerror.h> 29 #endif 30 31 #include "windef.h" 32 #include "winbase.h" 33 #include "winuser.h" 34 #include "ole2.h" 35 #include "msxml6.h" 36 37 #include "msxml_private.h" 38 39 #include "wine/debug.h" 40 41 #ifdef HAVE_LIBXML2 42 43 WINE_DEFAULT_DEBUG_CHANNEL(msxml); 44 45 typedef struct _domcomment 46 { 47 xmlnode node; 48 IXMLDOMComment IXMLDOMComment_iface; 49 LONG ref; 50 } domcomment; 51 52 static const tid_t domcomment_se_tids[] = { 53 IXMLDOMNode_tid, 54 IXMLDOMComment_tid, 55 NULL_tid 56 }; 57 58 static inline domcomment *impl_from_IXMLDOMComment( IXMLDOMComment *iface ) 59 { 60 return CONTAINING_RECORD(iface, domcomment, IXMLDOMComment_iface); 61 } 62 63 static HRESULT WINAPI domcomment_QueryInterface( 64 IXMLDOMComment *iface, 65 REFIID riid, 66 void** ppvObject ) 67 { 68 domcomment *This = impl_from_IXMLDOMComment( iface ); 69 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject); 70 71 if ( IsEqualGUID( riid, &IID_IXMLDOMComment ) || 72 IsEqualGUID( riid, &IID_IXMLDOMCharacterData) || 73 IsEqualGUID( riid, &IID_IXMLDOMNode ) || 74 IsEqualGUID( riid, &IID_IDispatch ) || 75 IsEqualGUID( riid, &IID_IUnknown ) ) 76 { 77 *ppvObject = iface; 78 } 79 else if(node_query_interface(&This->node, riid, ppvObject)) 80 { 81 return *ppvObject ? S_OK : E_NOINTERFACE; 82 } 83 else if(IsEqualGUID( riid, &IID_ISupportErrorInfo )) 84 { 85 return node_create_supporterrorinfo(domcomment_se_tids, ppvObject); 86 } 87 else 88 { 89 TRACE("Unsupported interface %s\n", debugstr_guid(riid)); 90 *ppvObject = NULL; 91 return E_NOINTERFACE; 92 } 93 94 IXMLDOMComment_AddRef(iface); 95 return S_OK; 96 } 97 98 static ULONG WINAPI domcomment_AddRef( 99 IXMLDOMComment *iface ) 100 { 101 domcomment *This = impl_from_IXMLDOMComment( iface ); 102 ULONG ref = InterlockedIncrement( &This->ref ); 103 TRACE("(%p)->(%d)\n", This, ref); 104 return ref; 105 } 106 107 static ULONG WINAPI domcomment_Release( 108 IXMLDOMComment *iface ) 109 { 110 domcomment *This = impl_from_IXMLDOMComment( iface ); 111 ULONG ref = InterlockedDecrement( &This->ref ); 112 113 TRACE("(%p)->(%d)\n", This, ref); 114 if ( ref == 0 ) 115 { 116 destroy_xmlnode(&This->node); 117 heap_free( This ); 118 } 119 120 return ref; 121 } 122 123 static HRESULT WINAPI domcomment_GetTypeInfoCount( 124 IXMLDOMComment *iface, 125 UINT* pctinfo ) 126 { 127 domcomment *This = impl_from_IXMLDOMComment( iface ); 128 return IDispatchEx_GetTypeInfoCount(&This->node.dispex.IDispatchEx_iface, pctinfo); 129 } 130 131 static HRESULT WINAPI domcomment_GetTypeInfo( 132 IXMLDOMComment *iface, 133 UINT iTInfo, LCID lcid, 134 ITypeInfo** ppTInfo ) 135 { 136 domcomment *This = impl_from_IXMLDOMComment( iface ); 137 return IDispatchEx_GetTypeInfo(&This->node.dispex.IDispatchEx_iface, 138 iTInfo, lcid, ppTInfo); 139 } 140 141 static HRESULT WINAPI domcomment_GetIDsOfNames( 142 IXMLDOMComment *iface, 143 REFIID riid, LPOLESTR* rgszNames, 144 UINT cNames, LCID lcid, DISPID* rgDispId ) 145 { 146 domcomment *This = impl_from_IXMLDOMComment( iface ); 147 return IDispatchEx_GetIDsOfNames(&This->node.dispex.IDispatchEx_iface, 148 riid, rgszNames, cNames, lcid, rgDispId); 149 } 150 151 static HRESULT WINAPI domcomment_Invoke( 152 IXMLDOMComment *iface, 153 DISPID dispIdMember, REFIID riid, LCID lcid, 154 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, 155 EXCEPINFO* pExcepInfo, UINT* puArgErr ) 156 { 157 domcomment *This = impl_from_IXMLDOMComment( iface ); 158 return IDispatchEx_Invoke(&This->node.dispex.IDispatchEx_iface, 159 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 160 } 161 162 static HRESULT WINAPI domcomment_get_nodeName( 163 IXMLDOMComment *iface, 164 BSTR* p ) 165 { 166 domcomment *This = impl_from_IXMLDOMComment( iface ); 167 168 static const WCHAR commentW[] = {'#','c','o','m','m','e','n','t',0}; 169 170 TRACE("(%p)->(%p)\n", This, p); 171 172 return return_bstr(commentW, p); 173 } 174 175 static HRESULT WINAPI domcomment_get_nodeValue( 176 IXMLDOMComment *iface, 177 VARIANT* value) 178 { 179 domcomment *This = impl_from_IXMLDOMComment( iface ); 180 181 TRACE("(%p)->(%p)\n", This, value); 182 183 return node_get_content(&This->node, value); 184 } 185 186 static HRESULT WINAPI domcomment_put_nodeValue( 187 IXMLDOMComment *iface, 188 VARIANT value) 189 { 190 domcomment *This = impl_from_IXMLDOMComment( iface ); 191 192 TRACE("(%p)->(%s)\n", This, debugstr_variant(&value)); 193 194 return node_put_value(&This->node, &value); 195 } 196 197 static HRESULT WINAPI domcomment_get_nodeType( 198 IXMLDOMComment *iface, 199 DOMNodeType* domNodeType ) 200 { 201 domcomment *This = impl_from_IXMLDOMComment( iface ); 202 203 TRACE("(%p)->(%p)\n", This, domNodeType); 204 205 *domNodeType = NODE_COMMENT; 206 return S_OK; 207 } 208 209 static HRESULT WINAPI domcomment_get_parentNode( 210 IXMLDOMComment *iface, 211 IXMLDOMNode** parent ) 212 { 213 domcomment *This = impl_from_IXMLDOMComment( iface ); 214 215 TRACE("(%p)->(%p)\n", This, parent); 216 217 return node_get_parent(&This->node, parent); 218 } 219 220 static HRESULT WINAPI domcomment_get_childNodes( 221 IXMLDOMComment *iface, 222 IXMLDOMNodeList** outList) 223 { 224 domcomment *This = impl_from_IXMLDOMComment( iface ); 225 226 TRACE("(%p)->(%p)\n", This, outList); 227 228 return node_get_child_nodes(&This->node, outList); 229 } 230 231 static HRESULT WINAPI domcomment_get_firstChild( 232 IXMLDOMComment *iface, 233 IXMLDOMNode** domNode) 234 { 235 domcomment *This = impl_from_IXMLDOMComment( iface ); 236 237 TRACE("(%p)->(%p)\n", This, domNode); 238 239 return return_null_node(domNode); 240 } 241 242 static HRESULT WINAPI domcomment_get_lastChild( 243 IXMLDOMComment *iface, 244 IXMLDOMNode** domNode) 245 { 246 domcomment *This = impl_from_IXMLDOMComment( iface ); 247 248 TRACE("(%p)->(%p)\n", This, domNode); 249 250 return return_null_node(domNode); 251 } 252 253 static HRESULT WINAPI domcomment_get_previousSibling( 254 IXMLDOMComment *iface, 255 IXMLDOMNode** domNode) 256 { 257 domcomment *This = impl_from_IXMLDOMComment( iface ); 258 259 TRACE("(%p)->(%p)\n", This, domNode); 260 261 return node_get_previous_sibling(&This->node, domNode); 262 } 263 264 static HRESULT WINAPI domcomment_get_nextSibling( 265 IXMLDOMComment *iface, 266 IXMLDOMNode** domNode) 267 { 268 domcomment *This = impl_from_IXMLDOMComment( iface ); 269 270 TRACE("(%p)->(%p)\n", This, domNode); 271 272 return node_get_next_sibling(&This->node, domNode); 273 } 274 275 static HRESULT WINAPI domcomment_get_attributes( 276 IXMLDOMComment *iface, 277 IXMLDOMNamedNodeMap** attributeMap) 278 { 279 domcomment *This = impl_from_IXMLDOMComment( iface ); 280 281 TRACE("(%p)->(%p)\n", This, attributeMap); 282 283 return return_null_ptr((void**)attributeMap); 284 } 285 286 static HRESULT WINAPI domcomment_insertBefore( 287 IXMLDOMComment *iface, 288 IXMLDOMNode* newNode, VARIANT refChild, 289 IXMLDOMNode** outOldNode) 290 { 291 domcomment *This = impl_from_IXMLDOMComment( iface ); 292 293 FIXME("(%p)->(%p %s %p) needs test\n", This, newNode, debugstr_variant(&refChild), outOldNode); 294 295 return node_insert_before(&This->node, newNode, &refChild, outOldNode); 296 } 297 298 static HRESULT WINAPI domcomment_replaceChild( 299 IXMLDOMComment *iface, 300 IXMLDOMNode* newNode, 301 IXMLDOMNode* oldNode, 302 IXMLDOMNode** outOldNode) 303 { 304 domcomment *This = impl_from_IXMLDOMComment( iface ); 305 306 FIXME("(%p)->(%p %p %p) needs tests\n", This, newNode, oldNode, outOldNode); 307 308 return node_replace_child(&This->node, newNode, oldNode, outOldNode); 309 } 310 311 static HRESULT WINAPI domcomment_removeChild( 312 IXMLDOMComment *iface, 313 IXMLDOMNode *child, IXMLDOMNode **oldChild) 314 { 315 domcomment *This = impl_from_IXMLDOMComment( iface ); 316 TRACE("(%p)->(%p %p)\n", This, child, oldChild); 317 return node_remove_child(&This->node, child, oldChild); 318 } 319 320 static HRESULT WINAPI domcomment_appendChild( 321 IXMLDOMComment *iface, 322 IXMLDOMNode *child, IXMLDOMNode **outChild) 323 { 324 domcomment *This = impl_from_IXMLDOMComment( iface ); 325 TRACE("(%p)->(%p %p)\n", This, child, outChild); 326 return node_append_child(&This->node, child, outChild); 327 } 328 329 static HRESULT WINAPI domcomment_hasChildNodes( 330 IXMLDOMComment *iface, 331 VARIANT_BOOL *ret) 332 { 333 domcomment *This = impl_from_IXMLDOMComment( iface ); 334 TRACE("(%p)->(%p)\n", This, ret); 335 return return_var_false(ret); 336 } 337 338 static HRESULT WINAPI domcomment_get_ownerDocument( 339 IXMLDOMComment *iface, 340 IXMLDOMDocument **doc) 341 { 342 domcomment *This = impl_from_IXMLDOMComment( iface ); 343 TRACE("(%p)->(%p)\n", This, doc); 344 return node_get_owner_doc(&This->node, doc); 345 } 346 347 static HRESULT WINAPI domcomment_cloneNode( 348 IXMLDOMComment *iface, 349 VARIANT_BOOL deep, IXMLDOMNode** outNode) 350 { 351 domcomment *This = impl_from_IXMLDOMComment( iface ); 352 TRACE("(%p)->(%d %p)\n", This, deep, outNode); 353 return node_clone( &This->node, deep, outNode ); 354 } 355 356 static HRESULT WINAPI domcomment_get_nodeTypeString( 357 IXMLDOMComment *iface, 358 BSTR* p) 359 { 360 domcomment *This = impl_from_IXMLDOMComment( iface ); 361 static const WCHAR commentW[] = {'c','o','m','m','e','n','t',0}; 362 363 TRACE("(%p)->(%p)\n", This, p); 364 365 return return_bstr(commentW, p); 366 } 367 368 static HRESULT WINAPI domcomment_get_text( 369 IXMLDOMComment *iface, 370 BSTR* p) 371 { 372 domcomment *This = impl_from_IXMLDOMComment( iface ); 373 TRACE("(%p)->(%p)\n", This, p); 374 return node_get_text(&This->node, p); 375 } 376 377 static HRESULT WINAPI domcomment_put_text( 378 IXMLDOMComment *iface, 379 BSTR p) 380 { 381 domcomment *This = impl_from_IXMLDOMComment( iface ); 382 TRACE("(%p)->(%s)\n", This, debugstr_w(p)); 383 return node_put_text( &This->node, p ); 384 } 385 386 static HRESULT WINAPI domcomment_get_specified( 387 IXMLDOMComment *iface, 388 VARIANT_BOOL* isSpecified) 389 { 390 domcomment *This = impl_from_IXMLDOMComment( iface ); 391 FIXME("(%p)->(%p) stub!\n", This, isSpecified); 392 *isSpecified = VARIANT_TRUE; 393 return S_OK; 394 } 395 396 static HRESULT WINAPI domcomment_get_definition( 397 IXMLDOMComment *iface, 398 IXMLDOMNode** definitionNode) 399 { 400 domcomment *This = impl_from_IXMLDOMComment( iface ); 401 FIXME("(%p)->(%p)\n", This, definitionNode); 402 return E_NOTIMPL; 403 } 404 405 static HRESULT WINAPI domcomment_get_nodeTypedValue( 406 IXMLDOMComment *iface, 407 VARIANT* v) 408 { 409 domcomment *This = impl_from_IXMLDOMComment( iface ); 410 TRACE("(%p)->(%p)\n", This, v); 411 return node_get_content(&This->node, v); 412 } 413 414 static HRESULT WINAPI domcomment_put_nodeTypedValue( 415 IXMLDOMComment *iface, 416 VARIANT typedValue) 417 { 418 domcomment *This = impl_from_IXMLDOMComment( iface ); 419 FIXME("(%p)->(%s)\n", This, debugstr_variant(&typedValue)); 420 return E_NOTIMPL; 421 } 422 423 static HRESULT WINAPI domcomment_get_dataType( 424 IXMLDOMComment *iface, 425 VARIANT* typename) 426 { 427 domcomment *This = impl_from_IXMLDOMComment( iface ); 428 TRACE("(%p)->(%p)\n", This, typename); 429 return return_null_var( typename ); 430 } 431 432 static HRESULT WINAPI domcomment_put_dataType( 433 IXMLDOMComment *iface, 434 BSTR p) 435 { 436 domcomment *This = impl_from_IXMLDOMComment( iface ); 437 438 TRACE("(%p)->(%s)\n", This, debugstr_w(p)); 439 440 if(!p) 441 return E_INVALIDARG; 442 443 return E_FAIL; 444 } 445 446 static HRESULT WINAPI domcomment_get_xml( 447 IXMLDOMComment *iface, 448 BSTR* p) 449 { 450 domcomment *This = impl_from_IXMLDOMComment( iface ); 451 452 TRACE("(%p)->(%p)\n", This, p); 453 454 return node_get_xml(&This->node, FALSE, p); 455 } 456 457 static HRESULT WINAPI domcomment_transformNode( 458 IXMLDOMComment *iface, 459 IXMLDOMNode *node, BSTR *p) 460 { 461 domcomment *This = impl_from_IXMLDOMComment( iface ); 462 TRACE("(%p)->(%p %p)\n", This, node, p); 463 return node_transform_node(&This->node, node, p); 464 } 465 466 static HRESULT WINAPI domcomment_selectNodes( 467 IXMLDOMComment *iface, 468 BSTR p, IXMLDOMNodeList** outList) 469 { 470 domcomment *This = impl_from_IXMLDOMComment( iface ); 471 TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outList); 472 return node_select_nodes(&This->node, p, outList); 473 } 474 475 static HRESULT WINAPI domcomment_selectSingleNode( 476 IXMLDOMComment *iface, 477 BSTR p, IXMLDOMNode** outNode) 478 { 479 domcomment *This = impl_from_IXMLDOMComment( iface ); 480 TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outNode); 481 return node_select_singlenode(&This->node, p, outNode); 482 } 483 484 static HRESULT WINAPI domcomment_get_parsed( 485 IXMLDOMComment *iface, 486 VARIANT_BOOL* isParsed) 487 { 488 domcomment *This = impl_from_IXMLDOMComment( iface ); 489 FIXME("(%p)->(%p) stub!\n", This, isParsed); 490 *isParsed = VARIANT_TRUE; 491 return S_OK; 492 } 493 494 static HRESULT WINAPI domcomment_get_namespaceURI( 495 IXMLDOMComment *iface, 496 BSTR* p) 497 { 498 domcomment *This = impl_from_IXMLDOMComment( iface ); 499 TRACE("(%p)->(%p)\n", This, p); 500 return node_get_namespaceURI(&This->node, p); 501 } 502 503 static HRESULT WINAPI domcomment_get_prefix( 504 IXMLDOMComment *iface, 505 BSTR* prefix) 506 { 507 domcomment *This = impl_from_IXMLDOMComment( iface ); 508 TRACE("(%p)->(%p)\n", This, prefix); 509 return return_null_bstr( prefix ); 510 } 511 512 static HRESULT WINAPI domcomment_get_baseName( 513 IXMLDOMComment *iface, 514 BSTR* name) 515 { 516 domcomment *This = impl_from_IXMLDOMComment( iface ); 517 TRACE("(%p)->(%p)\n", This, name); 518 return return_null_bstr( name ); 519 } 520 521 static HRESULT WINAPI domcomment_transformNodeToObject( 522 IXMLDOMComment *iface, 523 IXMLDOMNode* domNode, VARIANT var1) 524 { 525 domcomment *This = impl_from_IXMLDOMComment( iface ); 526 FIXME("(%p)->(%p %s)\n", This, domNode, debugstr_variant(&var1)); 527 return E_NOTIMPL; 528 } 529 530 static HRESULT WINAPI domcomment_get_data( 531 IXMLDOMComment *iface, 532 BSTR *p) 533 { 534 domcomment *This = impl_from_IXMLDOMComment( iface ); 535 HRESULT hr; 536 VARIANT vRet; 537 538 TRACE("(%p)->(%p)\n", This, p); 539 540 if(!p) 541 return E_INVALIDARG; 542 543 hr = IXMLDOMComment_get_nodeValue( iface, &vRet ); 544 if(hr == S_OK) 545 { 546 *p = V_BSTR(&vRet); 547 } 548 549 return hr; 550 } 551 552 static HRESULT WINAPI domcomment_put_data( 553 IXMLDOMComment *iface, 554 BSTR data) 555 { 556 domcomment *This = impl_from_IXMLDOMComment( iface ); 557 TRACE("(%p)->(%s)\n", This, debugstr_w(data)); 558 return node_set_content(&This->node, data); 559 } 560 561 static HRESULT WINAPI domcomment_get_length( 562 IXMLDOMComment *iface, 563 LONG *len) 564 { 565 domcomment *This = impl_from_IXMLDOMComment( iface ); 566 HRESULT hr; 567 BSTR data; 568 569 TRACE("(%p)->(%p)\n", This, len); 570 571 if(!len) 572 return E_INVALIDARG; 573 574 hr = IXMLDOMComment_get_data(iface, &data); 575 if(hr == S_OK) 576 { 577 *len = SysStringLen(data); 578 SysFreeString(data); 579 } 580 581 return hr; 582 } 583 584 static HRESULT WINAPI domcomment_substringData( 585 IXMLDOMComment *iface, 586 LONG offset, LONG count, BSTR *p) 587 { 588 domcomment *This = impl_from_IXMLDOMComment( iface ); 589 HRESULT hr; 590 BSTR data; 591 592 TRACE("(%p)->(%d %d %p)\n", This, offset, count, p); 593 594 if(!p) 595 return E_INVALIDARG; 596 597 *p = NULL; 598 if(offset < 0 || count < 0) 599 return E_INVALIDARG; 600 601 if(count == 0) 602 return S_FALSE; 603 604 hr = IXMLDOMComment_get_data(iface, &data); 605 if(hr == S_OK) 606 { 607 LONG len = SysStringLen(data); 608 609 if(offset < len) 610 { 611 if(offset + count > len) 612 *p = SysAllocString(&data[offset]); 613 else 614 *p = SysAllocStringLen(&data[offset], count); 615 } 616 else 617 hr = S_FALSE; 618 619 SysFreeString(data); 620 } 621 622 return hr; 623 } 624 625 static HRESULT WINAPI domcomment_appendData( 626 IXMLDOMComment *iface, 627 BSTR p) 628 { 629 domcomment *This = impl_from_IXMLDOMComment( iface ); 630 HRESULT hr; 631 BSTR data; 632 LONG p_len; 633 634 TRACE("(%p)->(%s)\n", This, debugstr_w(p)); 635 636 /* Nothing to do if NULL or an Empty string passed in. */ 637 if((p_len = SysStringLen(p)) == 0) return S_OK; 638 639 hr = IXMLDOMComment_get_data(iface, &data); 640 if(hr == S_OK) 641 { 642 LONG len = SysStringLen(data); 643 BSTR str = SysAllocStringLen(NULL, p_len + len); 644 645 memcpy(str, data, len*sizeof(WCHAR)); 646 memcpy(&str[len], p, p_len*sizeof(WCHAR)); 647 str[len+p_len] = 0; 648 649 hr = IXMLDOMComment_put_data(iface, str); 650 651 SysFreeString(str); 652 SysFreeString(data); 653 } 654 655 return hr; 656 } 657 658 static HRESULT WINAPI domcomment_insertData( 659 IXMLDOMComment *iface, 660 LONG offset, BSTR p) 661 { 662 domcomment *This = impl_from_IXMLDOMComment( iface ); 663 HRESULT hr; 664 BSTR data; 665 LONG p_len; 666 667 TRACE("(%p)->(%d %s)\n", This, offset, debugstr_w(p)); 668 669 /* If have a NULL or empty string, don't do anything. */ 670 if((p_len = SysStringLen(p)) == 0) 671 return S_OK; 672 673 if(offset < 0) 674 { 675 return E_INVALIDARG; 676 } 677 678 hr = IXMLDOMComment_get_data(iface, &data); 679 if(hr == S_OK) 680 { 681 LONG len = SysStringLen(data); 682 BSTR str; 683 684 if(len < offset) 685 { 686 SysFreeString(data); 687 return E_INVALIDARG; 688 } 689 690 str = SysAllocStringLen(NULL, len + p_len); 691 /* start part, supplied string and end part */ 692 memcpy(str, data, offset*sizeof(WCHAR)); 693 memcpy(&str[offset], p, p_len*sizeof(WCHAR)); 694 memcpy(&str[offset+p_len], &data[offset], (len-offset)*sizeof(WCHAR)); 695 str[len+p_len] = 0; 696 697 hr = IXMLDOMComment_put_data(iface, str); 698 699 SysFreeString(str); 700 SysFreeString(data); 701 } 702 703 return hr; 704 } 705 706 static HRESULT WINAPI domcomment_deleteData( 707 IXMLDOMComment *iface, 708 LONG offset, LONG count) 709 { 710 HRESULT hr; 711 LONG len = -1; 712 BSTR str; 713 714 TRACE("(%p)->(%d %d)\n", iface, offset, count); 715 716 hr = IXMLDOMComment_get_length(iface, &len); 717 if(hr != S_OK) return hr; 718 719 if((offset < 0) || (offset > len) || (count < 0)) 720 return E_INVALIDARG; 721 722 if(len == 0) return S_OK; 723 724 /* cutting start or end */ 725 if((offset == 0) || ((count + offset) >= len)) 726 { 727 if(offset == 0) 728 IXMLDOMComment_substringData(iface, count, len - count, &str); 729 else 730 IXMLDOMComment_substringData(iface, 0, offset, &str); 731 hr = IXMLDOMComment_put_data(iface, str); 732 } 733 else 734 /* cutting from the inside */ 735 { 736 BSTR str_end; 737 738 IXMLDOMComment_substringData(iface, 0, offset, &str); 739 IXMLDOMComment_substringData(iface, offset + count, len - count, &str_end); 740 741 hr = IXMLDOMComment_put_data(iface, str); 742 if(hr == S_OK) 743 hr = IXMLDOMComment_appendData(iface, str_end); 744 745 SysFreeString(str_end); 746 } 747 748 SysFreeString(str); 749 750 return hr; 751 } 752 753 static HRESULT WINAPI domcomment_replaceData( 754 IXMLDOMComment *iface, 755 LONG offset, LONG count, BSTR p) 756 { 757 domcomment *This = impl_from_IXMLDOMComment( iface ); 758 HRESULT hr; 759 760 TRACE("(%p)->(%d %d %s)\n", This, offset, count, debugstr_w(p)); 761 762 hr = IXMLDOMComment_deleteData(iface, offset, count); 763 764 if (hr == S_OK) 765 hr = IXMLDOMComment_insertData(iface, offset, p); 766 767 return hr; 768 } 769 770 static const struct IXMLDOMCommentVtbl domcomment_vtbl = 771 { 772 domcomment_QueryInterface, 773 domcomment_AddRef, 774 domcomment_Release, 775 domcomment_GetTypeInfoCount, 776 domcomment_GetTypeInfo, 777 domcomment_GetIDsOfNames, 778 domcomment_Invoke, 779 domcomment_get_nodeName, 780 domcomment_get_nodeValue, 781 domcomment_put_nodeValue, 782 domcomment_get_nodeType, 783 domcomment_get_parentNode, 784 domcomment_get_childNodes, 785 domcomment_get_firstChild, 786 domcomment_get_lastChild, 787 domcomment_get_previousSibling, 788 domcomment_get_nextSibling, 789 domcomment_get_attributes, 790 domcomment_insertBefore, 791 domcomment_replaceChild, 792 domcomment_removeChild, 793 domcomment_appendChild, 794 domcomment_hasChildNodes, 795 domcomment_get_ownerDocument, 796 domcomment_cloneNode, 797 domcomment_get_nodeTypeString, 798 domcomment_get_text, 799 domcomment_put_text, 800 domcomment_get_specified, 801 domcomment_get_definition, 802 domcomment_get_nodeTypedValue, 803 domcomment_put_nodeTypedValue, 804 domcomment_get_dataType, 805 domcomment_put_dataType, 806 domcomment_get_xml, 807 domcomment_transformNode, 808 domcomment_selectNodes, 809 domcomment_selectSingleNode, 810 domcomment_get_parsed, 811 domcomment_get_namespaceURI, 812 domcomment_get_prefix, 813 domcomment_get_baseName, 814 domcomment_transformNodeToObject, 815 domcomment_get_data, 816 domcomment_put_data, 817 domcomment_get_length, 818 domcomment_substringData, 819 domcomment_appendData, 820 domcomment_insertData, 821 domcomment_deleteData, 822 domcomment_replaceData 823 }; 824 825 static const tid_t domcomment_iface_tids[] = { 826 IXMLDOMComment_tid, 827 0 828 }; 829 830 static dispex_static_data_t domcomment_dispex = { 831 NULL, 832 IXMLDOMComment_tid, 833 NULL, 834 domcomment_iface_tids 835 }; 836 837 IUnknown* create_comment( xmlNodePtr comment ) 838 { 839 domcomment *This; 840 841 This = heap_alloc( sizeof *This ); 842 if ( !This ) 843 return NULL; 844 845 This->IXMLDOMComment_iface.lpVtbl = &domcomment_vtbl; 846 This->ref = 1; 847 848 init_xmlnode(&This->node, comment, (IXMLDOMNode*)&This->IXMLDOMComment_iface, &domcomment_dispex); 849 850 return (IUnknown*)&This->IXMLDOMComment_iface; 851 } 852 853 #endif 854