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