1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #include <characterdata.hxx> 25 26 #include <string.h> 27 28 #include <boost/shared_ptr.hpp> 29 30 #include <com/sun/star/xml/dom/events/XDocumentEvent.hpp> 31 32 #include "../events/mutationevent.hxx" 33 34 35 namespace DOM 36 { 37 CCharacterData(CDocument const & rDocument,::osl::Mutex const & rMutex,NodeType const & reNodeType,xmlNodePtr const & rpNode)38 CCharacterData::CCharacterData( 39 CDocument const& rDocument, ::osl::Mutex const& rMutex, 40 NodeType const& reNodeType, xmlNodePtr const& rpNode) 41 : CCharacterData_Base(rDocument, rMutex, reNodeType, rpNode) 42 { 43 } 44 dispatchEvent_Impl(OUString const & prevValue,OUString const & newValue)45 void CCharacterData::dispatchEvent_Impl( 46 OUString const& prevValue, OUString const& newValue) 47 { 48 Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY); 49 Reference< XMutationEvent > event(docevent->createEvent( 50 OUString::createFromAscii("DOMCharacterDataModified")), UNO_QUERY); 51 event->initMutationEvent( 52 OUString::createFromAscii("DOMCharacterDataModified"), 53 sal_True, sal_False, Reference< XNode >(), 54 prevValue, newValue, OUString(), (AttrChangeType)0 ); 55 dispatchEvent(Reference< XEvent >(event, UNO_QUERY)); 56 dispatchSubtreeModified(); 57 } 58 59 /** 60 Append the string to the end of the character data of the node. 61 */ appendData(const OUString & arg)62 void SAL_CALL CCharacterData::appendData(const OUString& arg) 63 { 64 ::osl::ClearableMutexGuard guard(m_rMutex); 65 66 if (m_aNodePtr != NULL) 67 { 68 OUString oldValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); 69 xmlNodeAddContent(m_aNodePtr, (const xmlChar*)(OUStringToOString(arg, RTL_TEXTENCODING_UTF8).getStr())); 70 OUString newValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); 71 72 guard.clear(); // release mutex before calling event handlers 73 dispatchEvent_Impl(oldValue, newValue); 74 } 75 } 76 77 /** 78 Remove a range of 16-bit units from the node. 79 */ deleteData(sal_Int32 offset,sal_Int32 count)80 void SAL_CALL CCharacterData::deleteData(sal_Int32 offset, sal_Int32 count) 81 { 82 ::osl::ClearableMutexGuard guard(m_rMutex); 83 84 if (m_aNodePtr != NULL) 85 { 86 // get current data 87 ::boost::shared_ptr<xmlChar const> const pContent( 88 xmlNodeGetContent(m_aNodePtr), xmlFree); 89 OString aData(reinterpret_cast<sal_Char const*>(pContent.get())); 90 OUString tmp( aData.getStr(), aData.getLength(), RTL_TEXTENCODING_UTF8); 91 if (offset > tmp.getLength() || offset < 0 || count < 0) { 92 DOMException e; 93 e.Code = DOMExceptionType_INDEX_SIZE_ERR; 94 throw e; 95 } 96 if ((offset+count) > tmp.getLength()) 97 count = tmp.getLength() - offset; 98 99 OUString tmp2 = tmp.copy(0, offset); 100 tmp2 += tmp.copy(offset+count, tmp.getLength() - (offset+count)); 101 OUString oldValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); 102 xmlNodeSetContent(m_aNodePtr, (const xmlChar*)(OUStringToOString(tmp2, RTL_TEXTENCODING_UTF8).getStr())); 103 OUString newValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); 104 105 guard.clear(); // release mutex before calling event handlers 106 dispatchEvent_Impl(oldValue, newValue); 107 } 108 } 109 110 111 /** 112 Return the character data of the node that implements this interface. 113 */ getData()114 OUString SAL_CALL CCharacterData::getData() 115 { 116 ::osl::MutexGuard const g(m_rMutex); 117 118 OUString aData; 119 if (m_aNodePtr != NULL) 120 { 121 OSL_ENSURE(m_aNodePtr->content, "character data node with NULL content, please inform lars.oppermann@sun.com!"); 122 if (m_aNodePtr->content != NULL) 123 { 124 aData = OUString((const sal_Char*)m_aNodePtr->content, strlen((const sal_Char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); 125 } 126 } 127 return aData; 128 } 129 130 /** 131 The number of 16-bit units that are available through data and the 132 substringData method below. 133 */ getLength()134 sal_Int32 SAL_CALL CCharacterData::getLength() 135 { 136 ::osl::MutexGuard const g(m_rMutex); 137 138 sal_Int32 length = 0; 139 if (m_aNodePtr != NULL) 140 { 141 OUString aData((const sal_Char*)m_aNodePtr->content, strlen((const sal_Char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); 142 length = aData.getLength(); 143 } 144 return length; 145 } 146 147 /** 148 Insert a string at the specified 16-bit unit offset. 149 */ insertData(sal_Int32 offset,const OUString & arg)150 void SAL_CALL CCharacterData::insertData(sal_Int32 offset, const OUString& arg) 151 { 152 ::osl::ClearableMutexGuard guard(m_rMutex); 153 154 if (m_aNodePtr != NULL) 155 { 156 // get current data 157 ::boost::shared_ptr<xmlChar const> const pContent( 158 xmlNodeGetContent(m_aNodePtr), xmlFree); 159 OString aData(reinterpret_cast<sal_Char const*>(pContent.get())); 160 OUString tmp( aData.getStr(), aData.getLength(), RTL_TEXTENCODING_UTF8); 161 if (offset > tmp.getLength() || offset < 0) { 162 DOMException e; 163 e.Code = DOMExceptionType_INDEX_SIZE_ERR; 164 throw e; 165 } 166 167 OUString tmp2 = tmp.copy(0, offset); 168 tmp2 += arg; 169 tmp2 += tmp.copy(offset, tmp.getLength() - offset); 170 OUString oldValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); 171 xmlNodeSetContent(m_aNodePtr, (const xmlChar*)(OUStringToOString(tmp2, RTL_TEXTENCODING_UTF8).getStr())); 172 OUString newValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); 173 174 guard.clear(); // release mutex before calling event handlers 175 dispatchEvent_Impl(oldValue, newValue); 176 } 177 } 178 179 180 /** 181 Replace the characters starting at the specified 16-bit unit offset 182 with the specified string. 183 */ replaceData(sal_Int32 offset,sal_Int32 count,const OUString & arg)184 void SAL_CALL CCharacterData::replaceData(sal_Int32 offset, sal_Int32 count, const OUString& arg) 185 { 186 ::osl::ClearableMutexGuard guard(m_rMutex); 187 188 if (m_aNodePtr != NULL) 189 { 190 // get current data 191 ::boost::shared_ptr<xmlChar const> const pContent( 192 xmlNodeGetContent(m_aNodePtr), xmlFree); 193 OString aData(reinterpret_cast<sal_Char const*>(pContent.get())); 194 OUString tmp( aData.getStr(), aData.getLength(), RTL_TEXTENCODING_UTF8); 195 if (offset > tmp.getLength() || offset < 0 || count < 0){ 196 DOMException e; 197 e.Code = DOMExceptionType_INDEX_SIZE_ERR; 198 throw e; 199 } 200 if ((offset+count) > tmp.getLength()) 201 count = tmp.getLength() - offset; 202 203 OUString tmp2 = tmp.copy(0, offset); 204 tmp2 += arg; 205 tmp2 += tmp.copy(offset+count, tmp.getLength() - (offset+count)); 206 OUString oldValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); 207 xmlNodeSetContent(m_aNodePtr, (const xmlChar*)(OUStringToOString(tmp2, RTL_TEXTENCODING_UTF8).getStr())); 208 OUString newValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); 209 210 guard.clear(); // release mutex before calling event handlers 211 dispatchEvent_Impl(oldValue, newValue); 212 } 213 } 214 215 /** 216 Set the character data of the node that implements this interface. 217 */ setData(const OUString & data)218 void SAL_CALL CCharacterData::setData(const OUString& data) 219 { 220 ::osl::ClearableMutexGuard guard(m_rMutex); 221 222 if (m_aNodePtr != NULL) 223 { 224 OUString oldValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); 225 xmlNodeSetContent(m_aNodePtr, (const xmlChar*)(OUStringToOString(data, RTL_TEXTENCODING_UTF8).getStr())); 226 OUString newValue((char*)m_aNodePtr->content, strlen((char*)m_aNodePtr->content), RTL_TEXTENCODING_UTF8); 227 228 guard.clear(); // release mutex before calling event handlers 229 dispatchEvent_Impl(oldValue, newValue); 230 } 231 } 232 233 /** 234 Extracts a range of data from the node. 235 */ subStringData(sal_Int32 offset,sal_Int32 count)236 OUString SAL_CALL CCharacterData::subStringData(sal_Int32 offset, sal_Int32 count) 237 { 238 ::osl::MutexGuard const g(m_rMutex); 239 240 OUString aStr; 241 if (m_aNodePtr != NULL) 242 { 243 // get current data 244 ::boost::shared_ptr<xmlChar const> const pContent( 245 xmlNodeGetContent(m_aNodePtr), xmlFree); 246 OString aData(reinterpret_cast<sal_Char const*>(pContent.get())); 247 OUString tmp( aData.getStr(), aData.getLength(), RTL_TEXTENCODING_UTF8); 248 if (offset > tmp.getLength() || offset < 0 || count < 0) { 249 DOMException e; 250 e.Code = DOMExceptionType_INDEX_SIZE_ERR; 251 throw e; 252 } 253 aStr = tmp.copy(offset, count); 254 } 255 return aStr; 256 } 257 258 259 } // namespace DOM 260