xref: /trunk/main/unoxml/source/dom/characterdata.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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