1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include <characterdata.hxx> 29 30 #include <string.h> 31 32 #include <boost/shared_ptr.hpp> 33 34 #include <com/sun/star/xml/dom/events/XDocumentEvent.hpp> 35 36 #include "../events/mutationevent.hxx" 37 38 39 namespace DOM 40 { 41 42 CCharacterData::CCharacterData( 43 CDocument const& rDocument, ::osl::Mutex const& rMutex, 44 NodeType const& reNodeType, xmlNodePtr const& rpNode) 45 : CCharacterData_Base(rDocument, rMutex, reNodeType, rpNode) 46 { 47 } 48 49 void CCharacterData::dispatchEvent_Impl( 50 OUString const& prevValue, OUString const& newValue) 51 { 52 Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY); 53 Reference< XMutationEvent > event(docevent->createEvent( 54 OUString::createFromAscii("DOMCharacterDataModified")), UNO_QUERY); 55 event->initMutationEvent( 56 OUString::createFromAscii("DOMCharacterDataModified"), 57 sal_True, sal_False, Reference< XNode >(), 58 prevValue, newValue, OUString(), (AttrChangeType)0 ); 59 dispatchEvent(Reference< XEvent >(event, UNO_QUERY)); 60 dispatchSubtreeModified(); 61 } 62 63 /** 64 Append the string to the end of the character data of the node. 65 */ 66 void SAL_CALL CCharacterData::appendData(const OUString& arg) 67 throw (RuntimeException, DOMException) 68 { 69 ::osl::ClearableMutexGuard guard(m_rMutex); 70 71 if (m_aNodePtr != NULL) 72 { 73 OUString oldValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); 74 xmlNodeAddContent(m_aNodePtr, (const xmlChar*)(OUStringToOString(arg, RTL_TEXTENCODING_UTF8).getStr())); 75 OUString newValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); 76 77 guard.clear(); // release mutex before calling event handlers 78 dispatchEvent_Impl(oldValue, newValue); 79 } 80 } 81 82 /** 83 Remove a range of 16-bit units from the node. 84 */ 85 void SAL_CALL CCharacterData::deleteData(sal_Int32 offset, sal_Int32 count) 86 throw (RuntimeException, DOMException) 87 { 88 ::osl::ClearableMutexGuard guard(m_rMutex); 89 90 if (m_aNodePtr != NULL) 91 { 92 // get current data 93 ::boost::shared_ptr<xmlChar const> const pContent( 94 xmlNodeGetContent(m_aNodePtr), xmlFree); 95 OString aData(reinterpret_cast<sal_Char const*>(pContent.get())); 96 OUString tmp(aData, aData.getLength(), RTL_TEXTENCODING_UTF8); 97 if (offset > tmp.getLength() || offset < 0 || count < 0) { 98 DOMException e; 99 e.Code = DOMExceptionType_INDEX_SIZE_ERR; 100 throw e; 101 } 102 if ((offset+count) > tmp.getLength()) 103 count = tmp.getLength() - offset; 104 105 OUString tmp2 = tmp.copy(0, offset); 106 tmp2 += tmp.copy(offset+count, tmp.getLength() - (offset+count)); 107 OUString oldValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); 108 xmlNodeSetContent(m_aNodePtr, (const xmlChar*)(OUStringToOString(tmp2, RTL_TEXTENCODING_UTF8).getStr())); 109 OUString newValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); 110 111 guard.clear(); // release mutex before calling event handlers 112 dispatchEvent_Impl(oldValue, newValue); 113 } 114 } 115 116 117 /** 118 Return the character data of the node that implements this interface. 119 */ 120 OUString SAL_CALL CCharacterData::getData() throw (RuntimeException) 121 { 122 ::osl::MutexGuard const g(m_rMutex); 123 124 OUString aData; 125 if (m_aNodePtr != NULL) 126 { 127 OSL_ENSURE(m_aNodePtr->content, "character data node with NULL content, please inform lars.oppermann@sun.com!"); 128 if (m_aNodePtr->content != NULL) 129 { 130 aData = OUString((const sal_Char*)m_aNodePtr->content, strlen((const sal_Char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); 131 } 132 } 133 return aData; 134 } 135 136 /** 137 The number of 16-bit units that are available through data and the 138 substringData method below. 139 */ 140 sal_Int32 SAL_CALL CCharacterData::getLength() throw (RuntimeException) 141 { 142 ::osl::MutexGuard const g(m_rMutex); 143 144 sal_Int32 length = 0; 145 if (m_aNodePtr != NULL) 146 { 147 OUString aData((const sal_Char*)m_aNodePtr->content, strlen((const sal_Char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); 148 length = aData.getLength(); 149 } 150 return length; 151 } 152 153 /** 154 Insert a string at the specified 16-bit unit offset. 155 */ 156 void SAL_CALL CCharacterData::insertData(sal_Int32 offset, const OUString& arg) 157 throw (RuntimeException, DOMException) 158 { 159 ::osl::ClearableMutexGuard guard(m_rMutex); 160 161 if (m_aNodePtr != NULL) 162 { 163 // get current data 164 ::boost::shared_ptr<xmlChar const> const pContent( 165 xmlNodeGetContent(m_aNodePtr), xmlFree); 166 OString aData(reinterpret_cast<sal_Char const*>(pContent.get())); 167 OUString tmp(aData, aData.getLength(), RTL_TEXTENCODING_UTF8); 168 if (offset > tmp.getLength() || offset < 0) { 169 DOMException e; 170 e.Code = DOMExceptionType_INDEX_SIZE_ERR; 171 throw e; 172 } 173 174 OUString tmp2 = tmp.copy(0, offset); 175 tmp2 += arg; 176 tmp2 += tmp.copy(offset, tmp.getLength() - offset); 177 OUString oldValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); 178 xmlNodeSetContent(m_aNodePtr, (const xmlChar*)(OUStringToOString(tmp2, RTL_TEXTENCODING_UTF8).getStr())); 179 OUString newValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); 180 181 guard.clear(); // release mutex before calling event handlers 182 dispatchEvent_Impl(oldValue, newValue); 183 } 184 } 185 186 187 /** 188 Replace the characters starting at the specified 16-bit unit offset 189 with the specified string. 190 */ 191 void SAL_CALL CCharacterData::replaceData(sal_Int32 offset, sal_Int32 count, const OUString& arg) 192 throw (RuntimeException, DOMException) 193 { 194 ::osl::ClearableMutexGuard guard(m_rMutex); 195 196 if (m_aNodePtr != NULL) 197 { 198 // get current data 199 ::boost::shared_ptr<xmlChar const> const pContent( 200 xmlNodeGetContent(m_aNodePtr), xmlFree); 201 OString aData(reinterpret_cast<sal_Char const*>(pContent.get())); 202 OUString tmp(aData, aData.getLength(), RTL_TEXTENCODING_UTF8); 203 if (offset > tmp.getLength() || offset < 0 || count < 0){ 204 DOMException e; 205 e.Code = DOMExceptionType_INDEX_SIZE_ERR; 206 throw e; 207 } 208 if ((offset+count) > tmp.getLength()) 209 count = tmp.getLength() - offset; 210 211 OUString tmp2 = tmp.copy(0, offset); 212 tmp2 += arg; 213 tmp2 += tmp.copy(offset+count, tmp.getLength() - (offset+count)); 214 OUString oldValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); 215 xmlNodeSetContent(m_aNodePtr, (const xmlChar*)(OUStringToOString(tmp2, RTL_TEXTENCODING_UTF8).getStr())); 216 OUString newValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); 217 218 guard.clear(); // release mutex before calling event handlers 219 dispatchEvent_Impl(oldValue, newValue); 220 } 221 } 222 223 /** 224 Set the character data of the node that implements this interface. 225 */ 226 void SAL_CALL CCharacterData::setData(const OUString& data) 227 throw (RuntimeException, DOMException) 228 { 229 ::osl::ClearableMutexGuard guard(m_rMutex); 230 231 if (m_aNodePtr != NULL) 232 { 233 OUString oldValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); 234 xmlNodeSetContent(m_aNodePtr, (const xmlChar*)(OUStringToOString(data, RTL_TEXTENCODING_UTF8).getStr())); 235 OUString newValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); 236 237 guard.clear(); // release mutex before calling event handlers 238 dispatchEvent_Impl(oldValue, newValue); 239 } 240 } 241 242 /** 243 Extracts a range of data from the node. 244 */ 245 OUString SAL_CALL CCharacterData::subStringData(sal_Int32 offset, sal_Int32 count) 246 throw (RuntimeException, DOMException) 247 { 248 ::osl::MutexGuard const g(m_rMutex); 249 250 OUString aStr; 251 if (m_aNodePtr != NULL) 252 { 253 // get current data 254 ::boost::shared_ptr<xmlChar const> const pContent( 255 xmlNodeGetContent(m_aNodePtr), xmlFree); 256 OString aData(reinterpret_cast<sal_Char const*>(pContent.get())); 257 OUString tmp(aData, aData.getLength(), RTL_TEXTENCODING_UTF8); 258 if (offset > tmp.getLength() || offset < 0 || count < 0) { 259 DOMException e; 260 e.Code = DOMExceptionType_INDEX_SIZE_ERR; 261 throw e; 262 } 263 aStr = tmp.copy(offset, count); 264 } 265 return aStr; 266 } 267 268 269 } // namspace DOM 270 271