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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_comphelper.hxx"
26 
27 #ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
28 #include <com/sun/star/beans/StringPair.hpp>
29 #endif
30 #ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP
31 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
32 #endif
33 #ifndef _COM_SUN_STAR_IO_XACTIVEDATASOURCE_HPP
34 #include <com/sun/star/io/XActiveDataSource.hpp>
35 #endif
36 #ifndef _COM_SUN_STAR_XML_SAX_XPARSER_HPP
37 #include <com/sun/star/xml/sax/XParser.hpp>
38 #endif
39 #ifndef _COM_SUN_STAR_XML_SAX_XDOCUMENTHANDLER_HPP
40 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
41 #endif
42 #ifndef _COM_SUN_STAR_LANG_ILLEGALARGUMENTEXCEPTION_HPP
43 #include <com/sun/star/lang/IllegalArgumentException.hpp>
44 #endif
45 
46 #include <comphelper/ofopxmlhelper.hxx>
47 #include <comphelper/attributelist.hxx>
48 
49 #define RELATIONINFO_FORMAT	0
50 #define CONTENTTYPE_FORMAT	1
51 #define FORMAT_MAX_ID CONTENTTYPE_FORMAT
52 
53 using namespace ::com::sun::star;
54 
55 namespace comphelper {
56 
57 // -----------------------------------
ReadRelationsInfoSequence(const uno::Reference<io::XInputStream> & xInStream,const::rtl::OUString aStreamName,const uno::Reference<lang::XMultiServiceFactory> xFactory)58 uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OFOPXMLHelper::ReadRelationsInfoSequence( const uno::Reference< io::XInputStream >& xInStream, const ::rtl::OUString aStreamName, const uno::Reference< lang::XMultiServiceFactory > xFactory )
59 	throw( uno::Exception )
60 {
61 	::rtl::OUString aStringID = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels/" ) );
62 	aStringID += aStreamName;
63 	return ReadSequence_Impl( xInStream, aStringID, RELATIONINFO_FORMAT, xFactory );
64 }
65 
66 // -----------------------------------
ReadContentTypeSequence(const uno::Reference<io::XInputStream> & xInStream,const uno::Reference<lang::XMultiServiceFactory> xFactory)67 uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OFOPXMLHelper::ReadContentTypeSequence( const uno::Reference< io::XInputStream >& xInStream, const uno::Reference< lang::XMultiServiceFactory > xFactory )
68 	throw( uno::Exception )
69 {
70 	::rtl::OUString aStringID = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "[Content_Types].xml" ) );
71 	return ReadSequence_Impl( xInStream, aStringID, CONTENTTYPE_FORMAT, xFactory );
72 }
73 
74 // -----------------------------------
WriteRelationsInfoSequence(const uno::Reference<io::XOutputStream> & xOutStream,const uno::Sequence<uno::Sequence<beans::StringPair>> & aSequence,const uno::Reference<lang::XMultiServiceFactory> xFactory)75 void SAL_CALL OFOPXMLHelper::WriteRelationsInfoSequence( const uno::Reference< io::XOutputStream >& xOutStream, const uno::Sequence< uno::Sequence< beans::StringPair > >& aSequence, const uno::Reference< lang::XMultiServiceFactory > xFactory )
76 	throw( uno::Exception )
77 {
78 	if ( !xOutStream.is() )
79 		throw uno::RuntimeException();
80 
81 	uno::Reference< io::XActiveDataSource > xWriterSource(
82 		xFactory->createInstance(
83 			::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Writer" ) ) ),
84 		uno::UNO_QUERY_THROW );
85 	uno::Reference< xml::sax::XDocumentHandler > xWriterHandler( xWriterSource, uno::UNO_QUERY_THROW );
86 
87 	xWriterSource->setOutputStream( xOutStream );
88 
89 	::rtl::OUString aRelListElement( RTL_CONSTASCII_USTRINGPARAM( "Relationships" ) );
90 	::rtl::OUString aRelElement( RTL_CONSTASCII_USTRINGPARAM( "Relationship" ) );
91 	::rtl::OUString aIDAttr( RTL_CONSTASCII_USTRINGPARAM( "Id" ) );
92 	::rtl::OUString aTypeAttr( RTL_CONSTASCII_USTRINGPARAM( "Type" ) );
93 	::rtl::OUString aTargetModeAttr( RTL_CONSTASCII_USTRINGPARAM( "TargetMode" ) );
94 	::rtl::OUString aTargetAttr( RTL_CONSTASCII_USTRINGPARAM( "Target" ) );
95 	::rtl::OUString aCDATAString( RTL_CONSTASCII_USTRINGPARAM ( "CDATA" ) );
96 	::rtl::OUString aWhiteSpace( RTL_CONSTASCII_USTRINGPARAM ( " " ) );
97 
98 	// write the namespace
99 	AttributeList* pRootAttrList = new AttributeList;
100 	uno::Reference< xml::sax::XAttributeList > xRootAttrList( pRootAttrList );
101 	pRootAttrList->AddAttribute(
102 		::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "xmlns" ) ),
103 		aCDATAString,
104 		::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "http://schemas.openxmlformats.org/package/2006/relationships" ) ) );
105 
106 	xWriterHandler->startDocument();
107 	xWriterHandler->startElement( aRelListElement, xRootAttrList );
108 
109 	for ( sal_Int32 nInd = 0; nInd < aSequence.getLength(); nInd++ )
110 	{
111 		AttributeList *pAttrList = new AttributeList;
112 		uno::Reference< xml::sax::XAttributeList > xAttrList( pAttrList );
113 		for( sal_Int32 nSecInd = 0; nSecInd < aSequence[nInd].getLength(); nSecInd++ )
114 		{
115 			if ( aSequence[nInd][nSecInd].First.equals( aIDAttr )
116 			  || aSequence[nInd][nSecInd].First.equals( aTypeAttr )
117 			  || aSequence[nInd][nSecInd].First.equals( aTargetModeAttr )
118 			  || aSequence[nInd][nSecInd].First.equals( aTargetAttr ) )
119 			{
120 				pAttrList->AddAttribute( aSequence[nInd][nSecInd].First, aCDATAString, aSequence[nInd][nSecInd].Second );
121 			}
122 			else
123 			{
124 				// TODO/LATER: should the extensions be allowed?
125 				throw lang::IllegalArgumentException();
126 			}
127 		}
128 
129 		xWriterHandler->startElement( aRelElement, xAttrList );
130 		xWriterHandler->ignorableWhitespace( aWhiteSpace );
131 		xWriterHandler->endElement( aRelElement );
132 	}
133 
134 	xWriterHandler->ignorableWhitespace( aWhiteSpace );
135 	xWriterHandler->endElement( aRelListElement );
136 	xWriterHandler->endDocument();
137 }
138 
139 // -----------------------------------
WriteContentSequence(const uno::Reference<io::XOutputStream> & xOutStream,const uno::Sequence<beans::StringPair> & aDefaultsSequence,const uno::Sequence<beans::StringPair> & aOverridesSequence,const uno::Reference<lang::XMultiServiceFactory> xFactory)140 void SAL_CALL OFOPXMLHelper::WriteContentSequence( const uno::Reference< io::XOutputStream >& xOutStream, const uno::Sequence< beans::StringPair >& aDefaultsSequence, const uno::Sequence< beans::StringPair >& aOverridesSequence, const uno::Reference< lang::XMultiServiceFactory > xFactory )
141 	throw( uno::Exception )
142 {
143 	if ( !xOutStream.is() )
144 		throw uno::RuntimeException();
145 
146 	uno::Reference< io::XActiveDataSource > xWriterSource(
147 		xFactory->createInstance(
148 			::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Writer" ) ) ),
149 		uno::UNO_QUERY_THROW );
150 	uno::Reference< xml::sax::XDocumentHandler > xWriterHandler( xWriterSource, uno::UNO_QUERY_THROW );
151 
152 	xWriterSource->setOutputStream( xOutStream );
153 
154 	::rtl::OUString aTypesElement( RTL_CONSTASCII_USTRINGPARAM( "Types" ) );
155 	::rtl::OUString aDefaultElement( RTL_CONSTASCII_USTRINGPARAM( "Default" ) );
156 	::rtl::OUString aOverrideElement( RTL_CONSTASCII_USTRINGPARAM( "Override" ) );
157 	::rtl::OUString aExtensionAttr( RTL_CONSTASCII_USTRINGPARAM( "Extension" ) );
158 	::rtl::OUString aPartNameAttr( RTL_CONSTASCII_USTRINGPARAM( "PartName" ) );
159 	::rtl::OUString aContentTypeAttr( RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) );
160 	::rtl::OUString aCDATAString( RTL_CONSTASCII_USTRINGPARAM ( "CDATA" ) );
161 	::rtl::OUString aWhiteSpace( RTL_CONSTASCII_USTRINGPARAM ( " " ) );
162 
163 	// write the namespace
164 	AttributeList* pRootAttrList = new AttributeList;
165 	uno::Reference< xml::sax::XAttributeList > xRootAttrList( pRootAttrList );
166 	pRootAttrList->AddAttribute(
167 		::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "xmlns" ) ),
168 		aCDATAString,
169 		::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "http://schemas.openxmlformats.org/package/2006/content-types" ) ) );
170 
171 	xWriterHandler->startDocument();
172 	xWriterHandler->startElement( aTypesElement, xRootAttrList );
173 
174 	for ( sal_Int32 nInd = 0; nInd < aDefaultsSequence.getLength(); nInd++ )
175 	{
176 		AttributeList *pAttrList = new AttributeList;
177 		uno::Reference< xml::sax::XAttributeList > xAttrList( pAttrList );
178 		pAttrList->AddAttribute( aExtensionAttr, aCDATAString, aDefaultsSequence[nInd].First );
179 		pAttrList->AddAttribute( aContentTypeAttr, aCDATAString, aDefaultsSequence[nInd].Second );
180 
181 		xWriterHandler->startElement( aDefaultElement, xAttrList );
182 		xWriterHandler->ignorableWhitespace( aWhiteSpace );
183 		xWriterHandler->endElement( aDefaultElement );
184 	}
185 
186 	for ( sal_Int32 nInd = 0; nInd < aOverridesSequence.getLength(); nInd++ )
187 	{
188 		AttributeList *pAttrList = new AttributeList;
189 		uno::Reference< xml::sax::XAttributeList > xAttrList( pAttrList );
190 		pAttrList->AddAttribute( aPartNameAttr, aCDATAString, aOverridesSequence[nInd].First );
191 		pAttrList->AddAttribute( aContentTypeAttr, aCDATAString, aOverridesSequence[nInd].Second );
192 
193 		xWriterHandler->startElement( aOverrideElement, xAttrList );
194 		xWriterHandler->ignorableWhitespace( aWhiteSpace );
195 		xWriterHandler->endElement( aOverrideElement );
196 	}
197 
198 	xWriterHandler->ignorableWhitespace( aWhiteSpace );
199 	xWriterHandler->endElement( aTypesElement );
200 	xWriterHandler->endDocument();
201 
202 }
203 
204 // ==================================================================================
205 
206 // -----------------------------------
ReadSequence_Impl(const uno::Reference<io::XInputStream> & xInStream,const::rtl::OUString & aStringID,sal_uInt16 nFormat,const uno::Reference<lang::XMultiServiceFactory> xFactory)207 uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OFOPXMLHelper::ReadSequence_Impl( const uno::Reference< io::XInputStream >& xInStream, const ::rtl::OUString& aStringID, sal_uInt16 nFormat, const uno::Reference< lang::XMultiServiceFactory > xFactory )
208 	throw( uno::Exception )
209 {
210 	if ( !xFactory.is() || !xInStream.is() || nFormat > FORMAT_MAX_ID )
211 		throw uno::RuntimeException();
212 
213 	uno::Sequence< uno::Sequence< beans::StringPair > > aResult;
214 
215 	uno::Reference< xml::sax::XParser > xParser( xFactory->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Parser" ) ) ), uno::UNO_QUERY_THROW );
216 
217 	OFOPXMLHelper* pHelper = new OFOPXMLHelper( nFormat );
218 	uno::Reference< xml::sax::XDocumentHandler > xHelper( static_cast< xml::sax::XDocumentHandler* >( pHelper ) );
219 	xml::sax::InputSource aParserInput;
220 	aParserInput.aInputStream = xInStream;
221 	aParserInput.sSystemId = aStringID;
222 	xParser->setDocumentHandler( xHelper );
223 	xParser->parseStream( aParserInput );
224 	xParser->setDocumentHandler( uno::Reference < xml::sax::XDocumentHandler > () );
225 
226 	return pHelper->GetParsingResult();
227 }
228 
229 // -----------------------------------
OFOPXMLHelper(sal_uInt16 nFormat)230 OFOPXMLHelper::OFOPXMLHelper( sal_uInt16 nFormat )
231 : m_nFormat( nFormat )
232 , m_aRelListElement( RTL_CONSTASCII_USTRINGPARAM( "Relationships" ) )
233 , m_aRelElement( RTL_CONSTASCII_USTRINGPARAM( "Relationship" ) )
234 , m_aIDAttr( RTL_CONSTASCII_USTRINGPARAM( "Id" ) )
235 , m_aTypeAttr( RTL_CONSTASCII_USTRINGPARAM( "Type" ) )
236 , m_aTargetModeAttr( RTL_CONSTASCII_USTRINGPARAM( "TargetMode" ) )
237 , m_aTargetAttr( RTL_CONSTASCII_USTRINGPARAM( "Target" ) )
238 , m_aTypesElement( RTL_CONSTASCII_USTRINGPARAM( "Types" ) )
239 , m_aDefaultElement( RTL_CONSTASCII_USTRINGPARAM( "Default" ) )
240 , m_aOverrideElement( RTL_CONSTASCII_USTRINGPARAM( "Override" ) )
241 , m_aExtensionAttr( RTL_CONSTASCII_USTRINGPARAM( "Extension" ) )
242 , m_aPartNameAttr( RTL_CONSTASCII_USTRINGPARAM( "PartName" ) )
243 , m_aContentTypeAttr( RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) )
244 {
245 }
246 
247 // -----------------------------------
~OFOPXMLHelper()248 OFOPXMLHelper::~OFOPXMLHelper()
249 {
250 }
251 
252 // -----------------------------------
GetParsingResult()253 uno::Sequence< uno::Sequence< beans::StringPair > > OFOPXMLHelper::GetParsingResult()
254 {
255 	if ( m_aElementsSeq.getLength() )
256 		throw uno::RuntimeException(); // the parsing has still not finished!
257 
258 	return m_aResultSeq;
259 }
260 
261 // -----------------------------------
startDocument()262 void SAL_CALL OFOPXMLHelper::startDocument()
263 		throw(xml::sax::SAXException, uno::RuntimeException)
264 {
265 }
266 
267 // -----------------------------------
endDocument()268 void SAL_CALL OFOPXMLHelper::endDocument()
269 		throw(xml::sax::SAXException, uno::RuntimeException)
270 {
271 }
272 
273 // -----------------------------------
startElement(const::rtl::OUString & aName,const uno::Reference<xml::sax::XAttributeList> & xAttribs)274 void SAL_CALL OFOPXMLHelper::startElement( const ::rtl::OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs )
275 		throw( xml::sax::SAXException, uno::RuntimeException )
276 {
277 	if ( m_nFormat == RELATIONINFO_FORMAT )
278 	{
279 		if ( aName == m_aRelListElement )
280 		{
281 			sal_Int32 nNewLength = m_aElementsSeq.getLength() + 1;
282 
283 			if ( nNewLength != 1 )
284 				throw xml::sax::SAXException(); // TODO: this element must be the first level element
285 
286 			m_aElementsSeq.realloc( nNewLength );
287 			m_aElementsSeq[nNewLength-1] = aName;
288 
289 			return; // nothing to do
290 		}
291 		else if ( aName == m_aRelElement )
292 		{
293 			sal_Int32 nNewLength = m_aElementsSeq.getLength() + 1;
294 			if ( nNewLength != 2 )
295 				throw xml::sax::SAXException(); // TODO: this element must be the second level element
296 
297 			m_aElementsSeq.realloc( nNewLength );
298 			m_aElementsSeq[nNewLength-1] = aName;
299 
300 			sal_Int32 nNewEntryNum = m_aResultSeq.getLength() + 1;
301 			m_aResultSeq.realloc( nNewEntryNum );
302 			sal_Int32 nAttrNum = 0;
303 			m_aResultSeq[nNewEntryNum-1].realloc( 4 ); // the maximal expected number of arguments is 4
304 
305 			::rtl::OUString aIDValue = xAttribs->getValueByName( m_aIDAttr );
306 			if ( aIDValue.isEmpty() )
307 				throw xml::sax::SAXException(); // TODO: the ID value must present
308 
309 			::rtl::OUString aTypeValue = xAttribs->getValueByName( m_aTypeAttr );
310 			::rtl::OUString aTargetValue = xAttribs->getValueByName( m_aTargetAttr );
311 			::rtl::OUString aTargetModeValue = xAttribs->getValueByName( m_aTargetModeAttr );
312 
313 			m_aResultSeq[nNewEntryNum-1][++nAttrNum - 1].First = m_aIDAttr;
314 			m_aResultSeq[nNewEntryNum-1][nAttrNum - 1].Second = aIDValue;
315 
316 			if ( !aTypeValue.isEmpty() )
317 			{
318 				m_aResultSeq[nNewEntryNum-1][++nAttrNum - 1].First = m_aTypeAttr;
319 				m_aResultSeq[nNewEntryNum-1][nAttrNum - 1].Second = aTypeValue;
320 			}
321 
322 			if ( !aTargetValue.isEmpty() )
323 			{
324 				m_aResultSeq[nNewEntryNum-1][++nAttrNum - 1].First = m_aTargetAttr;
325 				m_aResultSeq[nNewEntryNum-1][nAttrNum - 1].Second = aTargetValue;
326 			}
327 
328 			if ( !aTargetModeValue.isEmpty() )
329 			{
330 				m_aResultSeq[nNewEntryNum-1][++nAttrNum - 1].First = m_aTargetModeAttr;
331 				m_aResultSeq[nNewEntryNum-1][nAttrNum - 1].Second = aTargetModeValue;
332 			}
333 
334 			m_aResultSeq[nNewEntryNum-1].realloc( nAttrNum );
335 		}
336 		else
337 			throw xml::sax::SAXException(); // TODO: no other elements expected!
338 	}
339 	else if ( m_nFormat == CONTENTTYPE_FORMAT )
340 	{
341 		if ( aName == m_aTypesElement )
342 		{
343 			sal_Int32 nNewLength = m_aElementsSeq.getLength() + 1;
344 
345 			if ( nNewLength != 1 )
346 				throw xml::sax::SAXException(); // TODO: this element must be the first level element
347 
348 			m_aElementsSeq.realloc( nNewLength );
349 			m_aElementsSeq[nNewLength-1] = aName;
350 
351 			if ( !m_aResultSeq.getLength() )
352 				m_aResultSeq.realloc( 2 );
353 
354 			return; // nothing to do
355 		}
356 		else if ( aName == m_aDefaultElement )
357 		{
358 			sal_Int32 nNewLength = m_aElementsSeq.getLength() + 1;
359 			if ( nNewLength != 2 )
360 				throw xml::sax::SAXException(); // TODO: this element must be the second level element
361 
362 			m_aElementsSeq.realloc( nNewLength );
363 			m_aElementsSeq[nNewLength-1] = aName;
364 
365 			if ( !m_aResultSeq.getLength() )
366 				m_aResultSeq.realloc( 2 );
367 
368 			if ( m_aResultSeq.getLength() != 2 )
369 				throw uno::RuntimeException();
370 
371 			::rtl::OUString aExtensionValue = xAttribs->getValueByName( m_aExtensionAttr );
372 			if ( aExtensionValue.isEmpty() )
373 				throw xml::sax::SAXException(); // TODO: the Extension value must present
374 
375 			::rtl::OUString aContentTypeValue = xAttribs->getValueByName( m_aContentTypeAttr );
376 			if ( aContentTypeValue.isEmpty() )
377 				throw xml::sax::SAXException(); // TODO: the ContentType value must present
378 
379 			sal_Int32 nNewResultLen = m_aResultSeq[0].getLength() + 1;
380 			m_aResultSeq[0].realloc( nNewResultLen );
381 
382 			m_aResultSeq[0][nNewResultLen-1].First = aExtensionValue;
383 			m_aResultSeq[0][nNewResultLen-1].Second = aContentTypeValue;
384 		}
385 		else if ( aName == m_aOverrideElement )
386 		{
387 			sal_Int32 nNewLength = m_aElementsSeq.getLength() + 1;
388 			if ( nNewLength != 2 )
389 				throw xml::sax::SAXException(); // TODO: this element must be the second level element
390 
391 			m_aElementsSeq.realloc( nNewLength );
392 			m_aElementsSeq[nNewLength-1] = aName;
393 
394 			if ( !m_aResultSeq.getLength() )
395 				m_aResultSeq.realloc( 2 );
396 
397 			if ( m_aResultSeq.getLength() != 2 )
398 				throw uno::RuntimeException();
399 
400 			::rtl::OUString aPartNameValue = xAttribs->getValueByName( m_aPartNameAttr );
401 			if ( aPartNameValue.isEmpty() )
402 				throw xml::sax::SAXException(); // TODO: the PartName value must present
403 
404 			::rtl::OUString aContentTypeValue = xAttribs->getValueByName( m_aContentTypeAttr );
405 			if ( aContentTypeValue.isEmpty() )
406 				throw xml::sax::SAXException(); // TODO: the ContentType value must present
407 
408 			sal_Int32 nNewResultLen = m_aResultSeq[1].getLength() + 1;
409 			m_aResultSeq[1].realloc( nNewResultLen );
410 
411 			m_aResultSeq[1][nNewResultLen-1].First = aPartNameValue;
412 			m_aResultSeq[1][nNewResultLen-1].Second = aContentTypeValue;
413 		}
414 		else
415 			throw xml::sax::SAXException(); // TODO: no other elements expected!
416 	}
417 	else
418 		throw xml::sax::SAXException(); // TODO: no other elements expected!
419 }
420 
421 // -----------------------------------
endElement(const::rtl::OUString & aName)422 void SAL_CALL OFOPXMLHelper::endElement( const ::rtl::OUString& aName )
423 	throw( xml::sax::SAXException, uno::RuntimeException )
424 {
425 	if ( m_nFormat == RELATIONINFO_FORMAT || m_nFormat == CONTENTTYPE_FORMAT )
426 	{
427 		sal_Int32 nLength = m_aElementsSeq.getLength();
428 		if ( nLength <= 0 )
429 			throw xml::sax::SAXException(); // TODO: no other end elements expected!
430 
431 		if ( !m_aElementsSeq[nLength-1].equals( aName ) )
432 			throw xml::sax::SAXException(); // TODO: unexpected element ended
433 
434 		m_aElementsSeq.realloc( nLength - 1 );
435 	}
436 }
437 
438 // -----------------------------------
characters(const::rtl::OUString &)439 void SAL_CALL OFOPXMLHelper::characters( const ::rtl::OUString& /*aChars*/ )
440 		throw(xml::sax::SAXException, uno::RuntimeException)
441 {
442 }
443 
444 // -----------------------------------
ignorableWhitespace(const::rtl::OUString &)445 void SAL_CALL OFOPXMLHelper::ignorableWhitespace( const ::rtl::OUString& /*aWhitespaces*/ )
446 		throw(xml::sax::SAXException, uno::RuntimeException)
447 {
448 }
449 
450 // -----------------------------------
processingInstruction(const::rtl::OUString &,const::rtl::OUString &)451 void SAL_CALL OFOPXMLHelper::processingInstruction( const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ )
452 		throw(xml::sax::SAXException, uno::RuntimeException)
453 {
454 }
455 
456 // -----------------------------------
setDocumentLocator(const uno::Reference<xml::sax::XLocator> &)457 void SAL_CALL OFOPXMLHelper::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& /*xLocator*/ )
458 		throw(xml::sax::SAXException, uno::RuntimeException)
459 {
460 }
461 
462 } // namespace comphelper
463 
464