1 /* 2 * DOM CDATA node implementation 3 * 4 * Copyright 2007 Alistair Leslie-Hughes 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 46 { 47 xmlnode node; 48 IXMLDOMCDATASection IXMLDOMCDATASection_iface; 49 LONG ref; 50 } domcdata; 51 52 static const tid_t domcdata_se_tids[] = { 53 IXMLDOMNode_tid, 54 IXMLDOMCDATASection_tid, 55 NULL_tid 56 }; 57 58 static inline domcdata *impl_from_IXMLDOMCDATASection( IXMLDOMCDATASection *iface ) 59 { 60 return CONTAINING_RECORD(iface, domcdata, IXMLDOMCDATASection_iface); 61 } 62 63 static HRESULT WINAPI domcdata_QueryInterface( 64 IXMLDOMCDATASection *iface, 65 REFIID riid, 66 void** ppvObject ) 67 { 68 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 69 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject); 70 71 if ( IsEqualGUID( riid, &IID_IXMLDOMCDATASection ) || 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(domcdata_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 IXMLDOMCDATASection_AddRef(iface); 95 return S_OK; 96 } 97 98 static ULONG WINAPI domcdata_AddRef( 99 IXMLDOMCDATASection *iface ) 100 { 101 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 102 ULONG ref = InterlockedIncrement( &This->ref ); 103 TRACE("(%p)->(%d)\n", This, ref); 104 return ref; 105 } 106 107 static ULONG WINAPI domcdata_Release( 108 IXMLDOMCDATASection *iface ) 109 { 110 domcdata *This = impl_from_IXMLDOMCDATASection( 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 domcdata_GetTypeInfoCount( 124 IXMLDOMCDATASection *iface, 125 UINT* pctinfo ) 126 { 127 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 128 return IDispatchEx_GetTypeInfoCount(&This->node.dispex.IDispatchEx_iface, pctinfo); 129 } 130 131 static HRESULT WINAPI domcdata_GetTypeInfo( 132 IXMLDOMCDATASection *iface, 133 UINT iTInfo, LCID lcid, 134 ITypeInfo** ppTInfo ) 135 { 136 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 137 return IDispatchEx_GetTypeInfo(&This->node.dispex.IDispatchEx_iface, 138 iTInfo, lcid, ppTInfo); 139 } 140 141 static HRESULT WINAPI domcdata_GetIDsOfNames( 142 IXMLDOMCDATASection *iface, 143 REFIID riid, LPOLESTR* rgszNames, 144 UINT cNames, LCID lcid, DISPID* rgDispId ) 145 { 146 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 147 return IDispatchEx_GetIDsOfNames(&This->node.dispex.IDispatchEx_iface, 148 riid, rgszNames, cNames, lcid, rgDispId); 149 } 150 151 static HRESULT WINAPI domcdata_Invoke( 152 IXMLDOMCDATASection *iface, 153 DISPID dispIdMember, REFIID riid, LCID lcid, 154 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, 155 EXCEPINFO* pExcepInfo, UINT* puArgErr ) 156 { 157 domcdata *This = impl_from_IXMLDOMCDATASection( 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 domcdata_get_nodeName( 163 IXMLDOMCDATASection *iface, 164 BSTR* p ) 165 { 166 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 167 168 static const WCHAR cdata_sectionW[] = 169 {'#','c','d','a','t','a','-','s','e','c','t','i','o','n',0}; 170 171 TRACE("(%p)->(%p)\n", This, p); 172 173 return return_bstr(cdata_sectionW, p); 174 } 175 176 static HRESULT WINAPI domcdata_get_nodeValue( 177 IXMLDOMCDATASection *iface, 178 VARIANT* value) 179 { 180 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 181 182 TRACE("(%p)->(%p)\n", This, value); 183 184 return node_get_content(&This->node, value); 185 } 186 187 static HRESULT WINAPI domcdata_put_nodeValue( 188 IXMLDOMCDATASection *iface, 189 VARIANT value) 190 { 191 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 192 193 TRACE("(%p)->(%s)\n", This, debugstr_variant(&value)); 194 195 return node_put_value(&This->node, &value); 196 } 197 198 static HRESULT WINAPI domcdata_get_nodeType( 199 IXMLDOMCDATASection *iface, 200 DOMNodeType* domNodeType ) 201 { 202 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 203 204 TRACE("(%p)->(%p)\n", This, domNodeType); 205 206 *domNodeType = NODE_CDATA_SECTION; 207 return S_OK; 208 } 209 210 static HRESULT WINAPI domcdata_get_parentNode( 211 IXMLDOMCDATASection *iface, 212 IXMLDOMNode** parent ) 213 { 214 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 215 216 TRACE("(%p)->(%p)\n", This, parent); 217 218 return node_get_parent(&This->node, parent); 219 } 220 221 static HRESULT WINAPI domcdata_get_childNodes( 222 IXMLDOMCDATASection *iface, 223 IXMLDOMNodeList** outList) 224 { 225 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 226 227 TRACE("(%p)->(%p)\n", This, outList); 228 229 return node_get_child_nodes(&This->node, outList); 230 } 231 232 static HRESULT WINAPI domcdata_get_firstChild( 233 IXMLDOMCDATASection *iface, 234 IXMLDOMNode** domNode) 235 { 236 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 237 238 TRACE("(%p)->(%p)\n", This, domNode); 239 240 return return_null_node(domNode); 241 } 242 243 static HRESULT WINAPI domcdata_get_lastChild( 244 IXMLDOMCDATASection *iface, 245 IXMLDOMNode** domNode) 246 { 247 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 248 249 TRACE("(%p)->(%p)\n", This, domNode); 250 251 return return_null_node(domNode); 252 } 253 254 static HRESULT WINAPI domcdata_get_previousSibling( 255 IXMLDOMCDATASection *iface, 256 IXMLDOMNode** domNode) 257 { 258 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 259 260 TRACE("(%p)->(%p)\n", This, domNode); 261 262 return node_get_previous_sibling(&This->node, domNode); 263 } 264 265 static HRESULT WINAPI domcdata_get_nextSibling( 266 IXMLDOMCDATASection *iface, 267 IXMLDOMNode** domNode) 268 { 269 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 270 271 TRACE("(%p)->(%p)\n", This, domNode); 272 273 return node_get_next_sibling(&This->node, domNode); 274 } 275 276 static HRESULT WINAPI domcdata_get_attributes( 277 IXMLDOMCDATASection *iface, 278 IXMLDOMNamedNodeMap** attributeMap) 279 { 280 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 281 282 TRACE("(%p)->(%p)\n", This, attributeMap); 283 284 return return_null_ptr((void**)attributeMap); 285 } 286 287 static HRESULT WINAPI domcdata_insertBefore( 288 IXMLDOMCDATASection *iface, 289 IXMLDOMNode* newNode, VARIANT refChild, 290 IXMLDOMNode** outOldNode) 291 { 292 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 293 TRACE("(%p)->(%p %s %p)\n", This, newNode, debugstr_variant(&refChild), outOldNode); 294 if (outOldNode) *outOldNode = NULL; 295 return E_FAIL; 296 } 297 298 static HRESULT WINAPI domcdata_replaceChild( 299 IXMLDOMCDATASection *iface, 300 IXMLDOMNode* newNode, 301 IXMLDOMNode* oldNode, 302 IXMLDOMNode** outOldNode) 303 { 304 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 305 TRACE("(%p)->(%p %p %p)\n", This, newNode, oldNode, outOldNode); 306 if (outOldNode) *outOldNode = NULL; 307 return E_FAIL; 308 } 309 310 static HRESULT WINAPI domcdata_removeChild( 311 IXMLDOMCDATASection *iface, 312 IXMLDOMNode *child, IXMLDOMNode **oldChild) 313 { 314 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 315 TRACE("(%p)->(%p %p)\n", This, child, oldChild); 316 if (oldChild) *oldChild = NULL; 317 return E_FAIL; 318 } 319 320 static HRESULT WINAPI domcdata_appendChild( 321 IXMLDOMCDATASection *iface, 322 IXMLDOMNode *child, IXMLDOMNode **outChild) 323 { 324 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 325 TRACE("(%p)->(%p %p)\n", This, child, outChild); 326 if (outChild) *outChild = NULL; 327 return E_FAIL; 328 } 329 330 static HRESULT WINAPI domcdata_hasChildNodes( 331 IXMLDOMCDATASection *iface, 332 VARIANT_BOOL *ret) 333 { 334 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 335 TRACE("(%p)->(%p)\n", This, ret); 336 return return_var_false(ret); 337 } 338 339 static HRESULT WINAPI domcdata_get_ownerDocument( 340 IXMLDOMCDATASection *iface, 341 IXMLDOMDocument **doc) 342 { 343 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 344 TRACE("(%p)->(%p)\n", This, doc); 345 return node_get_owner_doc(&This->node, doc); 346 } 347 348 static HRESULT WINAPI domcdata_cloneNode( 349 IXMLDOMCDATASection *iface, 350 VARIANT_BOOL deep, IXMLDOMNode** outNode) 351 { 352 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 353 TRACE("(%p)->(%d %p)\n", This, deep, outNode); 354 return node_clone( &This->node, deep, outNode ); 355 } 356 357 static HRESULT WINAPI domcdata_get_nodeTypeString( 358 IXMLDOMCDATASection *iface, 359 BSTR* p) 360 { 361 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 362 static const WCHAR cdatasectionW[] = {'c','d','a','t','a','s','e','c','t','i','o','n',0}; 363 364 TRACE("(%p)->(%p)\n", This, p); 365 366 return return_bstr(cdatasectionW, p); 367 } 368 369 static HRESULT WINAPI domcdata_get_text( 370 IXMLDOMCDATASection *iface, 371 BSTR* p) 372 { 373 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 374 TRACE("(%p)->(%p)\n", This, p); 375 return node_get_text(&This->node, p); 376 } 377 378 static HRESULT WINAPI domcdata_put_text( 379 IXMLDOMCDATASection *iface, 380 BSTR p) 381 { 382 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 383 TRACE("(%p)->(%s)\n", This, debugstr_w(p)); 384 return node_put_text( &This->node, p ); 385 } 386 387 static HRESULT WINAPI domcdata_get_specified( 388 IXMLDOMCDATASection *iface, 389 VARIANT_BOOL* isSpecified) 390 { 391 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 392 FIXME("(%p)->(%p) stub!\n", This, isSpecified); 393 *isSpecified = VARIANT_TRUE; 394 return S_OK; 395 } 396 397 static HRESULT WINAPI domcdata_get_definition( 398 IXMLDOMCDATASection *iface, 399 IXMLDOMNode** definitionNode) 400 { 401 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 402 FIXME("(%p)->(%p)\n", This, definitionNode); 403 return E_NOTIMPL; 404 } 405 406 static HRESULT WINAPI domcdata_get_nodeTypedValue( 407 IXMLDOMCDATASection *iface, 408 VARIANT* v) 409 { 410 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 411 TRACE("(%p)->(%p)\n", This, v); 412 return node_get_content(&This->node, v); 413 } 414 415 static HRESULT WINAPI domcdata_put_nodeTypedValue( 416 IXMLDOMCDATASection *iface, 417 VARIANT typedValue) 418 { 419 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 420 FIXME("(%p)->(%s)\n", This, debugstr_variant(&typedValue)); 421 return E_NOTIMPL; 422 } 423 424 static HRESULT WINAPI domcdata_get_dataType( 425 IXMLDOMCDATASection *iface, 426 VARIANT* typename) 427 { 428 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 429 TRACE("(%p)->(%p)\n", This, typename); 430 return return_null_var( typename ); 431 } 432 433 static HRESULT WINAPI domcdata_put_dataType( 434 IXMLDOMCDATASection *iface, 435 BSTR p) 436 { 437 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 438 439 TRACE("(%p)->(%s)\n", This, debugstr_w(p)); 440 441 if(!p) 442 return E_INVALIDARG; 443 444 return E_FAIL; 445 } 446 447 static HRESULT WINAPI domcdata_get_xml( 448 IXMLDOMCDATASection *iface, 449 BSTR* p) 450 { 451 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 452 453 TRACE("(%p)->(%p)\n", This, p); 454 455 return node_get_xml(&This->node, FALSE, p); 456 } 457 458 static HRESULT WINAPI domcdata_transformNode( 459 IXMLDOMCDATASection *iface, 460 IXMLDOMNode *node, BSTR *p) 461 { 462 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 463 TRACE("(%p)->(%p %p)\n", This, node, p); 464 return node_transform_node(&This->node, node, p); 465 } 466 467 static HRESULT WINAPI domcdata_selectNodes( 468 IXMLDOMCDATASection *iface, 469 BSTR p, IXMLDOMNodeList** outList) 470 { 471 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 472 TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outList); 473 return node_select_nodes(&This->node, p, outList); 474 } 475 476 static HRESULT WINAPI domcdata_selectSingleNode( 477 IXMLDOMCDATASection *iface, 478 BSTR p, IXMLDOMNode** outNode) 479 { 480 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 481 TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outNode); 482 return node_select_singlenode(&This->node, p, outNode); 483 } 484 485 static HRESULT WINAPI domcdata_get_parsed( 486 IXMLDOMCDATASection *iface, 487 VARIANT_BOOL* isParsed) 488 { 489 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 490 FIXME("(%p)->(%p) stub!\n", This, isParsed); 491 *isParsed = VARIANT_TRUE; 492 return S_OK; 493 } 494 495 static HRESULT WINAPI domcdata_get_namespaceURI( 496 IXMLDOMCDATASection *iface, 497 BSTR* p) 498 { 499 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 500 TRACE("(%p)->(%p)\n", This, p); 501 return node_get_namespaceURI(&This->node, p); 502 } 503 504 static HRESULT WINAPI domcdata_get_prefix( 505 IXMLDOMCDATASection *iface, 506 BSTR* prefix) 507 { 508 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 509 TRACE("(%p)->(%p)\n", This, prefix); 510 return return_null_bstr( prefix ); 511 } 512 513 static HRESULT WINAPI domcdata_get_baseName( 514 IXMLDOMCDATASection *iface, 515 BSTR* name) 516 { 517 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 518 FIXME("(%p)->(%p): needs test\n", This, name); 519 return return_null_bstr( name ); 520 } 521 522 static HRESULT WINAPI domcdata_transformNodeToObject( 523 IXMLDOMCDATASection *iface, 524 IXMLDOMNode* domNode, VARIANT var1) 525 { 526 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 527 FIXME("(%p)->(%p %s)\n", This, domNode, debugstr_variant(&var1)); 528 return E_NOTIMPL; 529 } 530 531 static HRESULT WINAPI domcdata_get_data( 532 IXMLDOMCDATASection *iface, 533 BSTR *p) 534 { 535 HRESULT hr; 536 VARIANT vRet; 537 538 if(!p) 539 return E_INVALIDARG; 540 541 hr = IXMLDOMCDATASection_get_nodeValue( iface, &vRet ); 542 if(hr == S_OK) 543 { 544 *p = V_BSTR(&vRet); 545 } 546 547 return hr; 548 } 549 550 static HRESULT WINAPI domcdata_put_data( 551 IXMLDOMCDATASection *iface, 552 BSTR data) 553 { 554 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 555 TRACE("(%p)->(%s)\n", This, debugstr_w(data)); 556 return node_set_content(&This->node, data); 557 } 558 559 static HRESULT WINAPI domcdata_get_length( 560 IXMLDOMCDATASection *iface, 561 LONG *len) 562 { 563 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 564 HRESULT hr; 565 BSTR data; 566 567 TRACE("(%p)->(%p)\n", This, len); 568 569 if(!len) 570 return E_INVALIDARG; 571 572 hr = IXMLDOMCDATASection_get_data(iface, &data); 573 if(hr == S_OK) 574 { 575 *len = SysStringLen(data); 576 SysFreeString(data); 577 } 578 579 return S_OK; 580 } 581 582 static HRESULT WINAPI domcdata_substringData( 583 IXMLDOMCDATASection *iface, 584 LONG offset, LONG count, BSTR *p) 585 { 586 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 587 HRESULT hr; 588 BSTR data; 589 590 TRACE("(%p)->(%d %d %p)\n", This, offset, count, p); 591 592 if(!p) 593 return E_INVALIDARG; 594 595 *p = NULL; 596 if(offset < 0 || count < 0) 597 return E_INVALIDARG; 598 599 if(count == 0) 600 return S_FALSE; 601 602 hr = IXMLDOMCDATASection_get_data(iface, &data); 603 if(hr == S_OK) 604 { 605 LONG len = SysStringLen(data); 606 607 if(offset < len) 608 { 609 if(offset + count > len) 610 *p = SysAllocString(&data[offset]); 611 else 612 *p = SysAllocStringLen(&data[offset], count); 613 } 614 else 615 hr = S_FALSE; 616 617 SysFreeString(data); 618 } 619 620 return hr; 621 } 622 623 static HRESULT WINAPI domcdata_appendData( 624 IXMLDOMCDATASection *iface, 625 BSTR p) 626 { 627 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 628 HRESULT hr; 629 BSTR data; 630 LONG p_len; 631 632 TRACE("(%p)->(%s)\n", This, debugstr_w(p)); 633 634 /* Nothing to do if NULL or an Empty string passed in. */ 635 if((p_len = SysStringLen(p)) == 0) return S_OK; 636 637 hr = IXMLDOMCDATASection_get_data(iface, &data); 638 if(hr == S_OK) 639 { 640 LONG len = SysStringLen(data); 641 BSTR str = SysAllocStringLen(NULL, p_len + len); 642 643 memcpy(str, data, len*sizeof(WCHAR)); 644 memcpy(&str[len], p, p_len*sizeof(WCHAR)); 645 str[len+p_len] = 0; 646 647 hr = IXMLDOMCDATASection_put_data(iface, str); 648 649 SysFreeString(str); 650 SysFreeString(data); 651 } 652 653 return hr; 654 } 655 656 static HRESULT WINAPI domcdata_insertData( 657 IXMLDOMCDATASection *iface, 658 LONG offset, BSTR p) 659 { 660 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 661 HRESULT hr; 662 BSTR data; 663 LONG p_len; 664 665 TRACE("(%p)->(%d %s)\n", This, offset, debugstr_w(p)); 666 667 /* If have a NULL or empty string, don't do anything. */ 668 if((p_len = SysStringLen(p)) == 0) 669 return S_OK; 670 671 if(offset < 0) 672 { 673 return E_INVALIDARG; 674 } 675 676 hr = IXMLDOMCDATASection_get_data(iface, &data); 677 if(hr == S_OK) 678 { 679 LONG len = SysStringLen(data); 680 BSTR str; 681 682 if(len < offset) 683 { 684 SysFreeString(data); 685 return E_INVALIDARG; 686 } 687 688 str = SysAllocStringLen(NULL, len + p_len); 689 /* start part, supplied string and end part */ 690 memcpy(str, data, offset*sizeof(WCHAR)); 691 memcpy(&str[offset], p, p_len*sizeof(WCHAR)); 692 memcpy(&str[offset+p_len], &data[offset], (len-offset)*sizeof(WCHAR)); 693 str[len+p_len] = 0; 694 695 hr = IXMLDOMCDATASection_put_data(iface, str); 696 697 SysFreeString(str); 698 SysFreeString(data); 699 } 700 701 return hr; 702 } 703 704 static HRESULT WINAPI domcdata_deleteData( 705 IXMLDOMCDATASection *iface, 706 LONG offset, LONG count) 707 { 708 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 709 HRESULT hr; 710 LONG len = -1; 711 BSTR str; 712 713 TRACE("(%p)->(%d %d)\n", This, offset, count); 714 715 hr = IXMLDOMCDATASection_get_length(iface, &len); 716 if(hr != S_OK) return hr; 717 718 if((offset < 0) || (offset > len) || (count < 0)) 719 return E_INVALIDARG; 720 721 if(len == 0) return S_OK; 722 723 /* cutting start or end */ 724 if((offset == 0) || ((count + offset) >= len)) 725 { 726 if(offset == 0) 727 IXMLDOMCDATASection_substringData(iface, count, len - count, &str); 728 else 729 IXMLDOMCDATASection_substringData(iface, 0, offset, &str); 730 hr = IXMLDOMCDATASection_put_data(iface, str); 731 } 732 else 733 /* cutting from the inside */ 734 { 735 BSTR str_end; 736 737 IXMLDOMCDATASection_substringData(iface, 0, offset, &str); 738 IXMLDOMCDATASection_substringData(iface, offset + count, len - count, &str_end); 739 740 hr = IXMLDOMCDATASection_put_data(iface, str); 741 if(hr == S_OK) 742 hr = IXMLDOMCDATASection_appendData(iface, str_end); 743 744 SysFreeString(str_end); 745 } 746 747 SysFreeString(str); 748 749 return hr; 750 } 751 752 static HRESULT WINAPI domcdata_replaceData( 753 IXMLDOMCDATASection *iface, 754 LONG offset, LONG count, BSTR p) 755 { 756 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 757 HRESULT hr; 758 759 TRACE("(%p)->(%d %d %s)\n", This, offset, count, debugstr_w(p)); 760 761 hr = IXMLDOMCDATASection_deleteData(iface, offset, count); 762 763 if (hr == S_OK) 764 hr = IXMLDOMCDATASection_insertData(iface, offset, p); 765 766 return hr; 767 } 768 769 static HRESULT WINAPI domcdata_splitText( 770 IXMLDOMCDATASection *iface, 771 LONG offset, IXMLDOMText **txtNode) 772 { 773 domcdata *This = impl_from_IXMLDOMCDATASection( iface ); 774 IXMLDOMDocument *doc; 775 LONG length = 0; 776 HRESULT hr; 777 778 TRACE("(%p)->(%d %p)\n", This, offset, txtNode); 779 780 if (!txtNode || offset < 0) return E_INVALIDARG; 781 782 *txtNode = NULL; 783 784 IXMLDOMCDATASection_get_length(iface, &length); 785 786 if (offset > length) return E_INVALIDARG; 787 if (offset == length) return S_FALSE; 788 789 hr = IXMLDOMCDATASection_get_ownerDocument(iface, &doc); 790 if (hr == S_OK) 791 { 792 BSTR data; 793 794 hr = IXMLDOMCDATASection_substringData(iface, offset, length - offset, &data); 795 if (hr == S_OK) 796 { 797 hr = IXMLDOMDocument_createTextNode(doc, data, txtNode); 798 if (hr == S_OK) 799 { 800 IXMLDOMNode *parent; 801 802 hr = IXMLDOMCDATASection_get_parentNode(iface, &parent); 803 if (hr == S_OK) 804 { 805 IXMLDOMCDATASection_deleteData(iface, 0, offset); 806 hr = IXMLDOMNode_appendChild(parent, (IXMLDOMNode*)*txtNode, NULL); 807 IXMLDOMNode_Release(parent); 808 } 809 } 810 SysFreeString(data); 811 } 812 IXMLDOMDocument_Release(doc); 813 } 814 815 return hr; 816 } 817 818 static const struct IXMLDOMCDATASectionVtbl domcdata_vtbl = 819 { 820 domcdata_QueryInterface, 821 domcdata_AddRef, 822 domcdata_Release, 823 domcdata_GetTypeInfoCount, 824 domcdata_GetTypeInfo, 825 domcdata_GetIDsOfNames, 826 domcdata_Invoke, 827 domcdata_get_nodeName, 828 domcdata_get_nodeValue, 829 domcdata_put_nodeValue, 830 domcdata_get_nodeType, 831 domcdata_get_parentNode, 832 domcdata_get_childNodes, 833 domcdata_get_firstChild, 834 domcdata_get_lastChild, 835 domcdata_get_previousSibling, 836 domcdata_get_nextSibling, 837 domcdata_get_attributes, 838 domcdata_insertBefore, 839 domcdata_replaceChild, 840 domcdata_removeChild, 841 domcdata_appendChild, 842 domcdata_hasChildNodes, 843 domcdata_get_ownerDocument, 844 domcdata_cloneNode, 845 domcdata_get_nodeTypeString, 846 domcdata_get_text, 847 domcdata_put_text, 848 domcdata_get_specified, 849 domcdata_get_definition, 850 domcdata_get_nodeTypedValue, 851 domcdata_put_nodeTypedValue, 852 domcdata_get_dataType, 853 domcdata_put_dataType, 854 domcdata_get_xml, 855 domcdata_transformNode, 856 domcdata_selectNodes, 857 domcdata_selectSingleNode, 858 domcdata_get_parsed, 859 domcdata_get_namespaceURI, 860 domcdata_get_prefix, 861 domcdata_get_baseName, 862 domcdata_transformNodeToObject, 863 domcdata_get_data, 864 domcdata_put_data, 865 domcdata_get_length, 866 domcdata_substringData, 867 domcdata_appendData, 868 domcdata_insertData, 869 domcdata_deleteData, 870 domcdata_replaceData, 871 domcdata_splitText 872 }; 873 874 static const tid_t domcdata_iface_tids[] = { 875 IXMLDOMCDATASection_tid, 876 0 877 }; 878 879 static dispex_static_data_t domcdata_dispex = { 880 NULL, 881 IXMLDOMCDATASection_tid, 882 NULL, 883 domcdata_iface_tids 884 }; 885 886 IUnknown* create_cdata( xmlNodePtr text ) 887 { 888 domcdata *This; 889 890 This = heap_alloc( sizeof *This ); 891 if ( !This ) 892 return NULL; 893 894 This->IXMLDOMCDATASection_iface.lpVtbl = &domcdata_vtbl; 895 This->ref = 1; 896 897 init_xmlnode(&This->node, text, (IXMLDOMNode*)&This->IXMLDOMCDATASection_iface, &domcdata_dispex); 898 899 return (IUnknown*)&This->IXMLDOMCDATASection_iface; 900 } 901 902 #endif 903