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 #include "oox/core/xmlfilterbase.hxx"
23
24 #include <cstdio>
25 #include <com/sun/star/container/XNameContainer.hpp>
26 #include <com/sun/star/embed/XRelationshipAccess.hpp>
27 #include <com/sun/star/xml/sax/InputSource.hpp>
28 #include <com/sun/star/xml/sax/XFastParser.hpp>
29 #include <com/sun/star/document/XDocumentProperties.hpp>
30 #include <comphelper/mediadescriptor.hxx>
31 #include <sax/fshelper.hxx>
32 #include <rtl/strbuf.hxx>
33 #include <rtl/ustrbuf.hxx>
34 #include "oox/core/fastparser.hxx"
35 #include "oox/core/filterdetect.hxx"
36 #include "oox/core/fragmenthandler.hxx"
37 #include "oox/core/recordparser.hxx"
38 #include "oox/core/relationshandler.hxx"
39 #include "oox/helper/containerhelper.hxx"
40 #include "oox/helper/propertyset.hxx"
41 #include "oox/helper/zipstorage.hxx"
42
43 namespace oox {
44 namespace core {
45
46 // ============================================================================
47
48 using namespace ::com::sun::star::beans;
49 using namespace ::com::sun::star::container;
50 using namespace ::com::sun::star::document;
51 using namespace ::com::sun::star::embed;
52 using namespace ::com::sun::star::io;
53 using namespace ::com::sun::star::lang;
54 using namespace ::com::sun::star::uno;
55 using namespace ::com::sun::star::util;
56 using namespace ::com::sun::star::xml::sax;
57
58 using ::comphelper::MediaDescriptor;
59 using ::rtl::OStringBuffer;
60 using ::rtl::OUString;
61 using ::rtl::OUStringBuffer;
62 using ::sax_fastparser::FSHelperPtr;
63 using ::sax_fastparser::FastSerializerHelper;
64
65 // ============================================================================
66
67 namespace {
68
lclHasSuffix(const OUString & rFragmentPath,const OUString & rSuffix)69 bool lclHasSuffix( const OUString& rFragmentPath, const OUString& rSuffix )
70 {
71 sal_Int32 nSuffixPos = rFragmentPath.getLength() - rSuffix.getLength();
72 return (nSuffixPos >= 0) && rFragmentPath.match( rSuffix, nSuffixPos );
73 }
74
75 } // namespace
76
77 // ============================================================================
78
79 struct XmlFilterBaseImpl
80 {
81 typedef RefMap< OUString, Relations > RelationsMap;
82
83 FastParser maFastParser;
84 const OUString maBinSuffix;
85 const OUString maVmlSuffix;
86 RelationsMap maRelationsMap;
87 TextFieldStack maTextFieldStack;
88
89 explicit XmlFilterBaseImpl( const Reference< XComponentContext >& rxContext ) throw( RuntimeException );
90 ~XmlFilterBaseImpl();
91 };
92
93 // ----------------------------------------------------------------------------
94
XmlFilterBaseImpl(const Reference<XComponentContext> & rxContext)95 XmlFilterBaseImpl::XmlFilterBaseImpl( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
96 maFastParser( rxContext ),
97 maBinSuffix( CREATE_OUSTRING( ".bin" ) ),
98 maVmlSuffix( CREATE_OUSTRING( ".vml" ) )
99 {
100 // register XML namespaces
101 maFastParser.registerNamespace( NMSP_xml );
102 maFastParser.registerNamespace( NMSP_packageRel );
103 maFastParser.registerNamespace( NMSP_officeRel );
104
105 maFastParser.registerNamespace( NMSP_dml );
106 maFastParser.registerNamespace( NMSP_dmlDiagram );
107 maFastParser.registerNamespace( NMSP_dmlChart );
108 maFastParser.registerNamespace( NMSP_dmlChartDr );
109 maFastParser.registerNamespace( NMSP_dmlSpreadDr );
110
111 maFastParser.registerNamespace( NMSP_vml );
112 maFastParser.registerNamespace( NMSP_vmlOffice );
113 maFastParser.registerNamespace( NMSP_vmlWord );
114 maFastParser.registerNamespace( NMSP_vmlExcel );
115 maFastParser.registerNamespace( NMSP_vmlPowerpoint );
116
117 maFastParser.registerNamespace( NMSP_xls );
118 maFastParser.registerNamespace( NMSP_ppt );
119
120 maFastParser.registerNamespace( NMSP_ax );
121 maFastParser.registerNamespace( NMSP_xm );
122 maFastParser.registerNamespace( NMSP_markupCompat ); // i123528
123 }
124
~XmlFilterBaseImpl()125 XmlFilterBaseImpl::~XmlFilterBaseImpl()
126 {
127 }
128
129 // ============================================================================
130
XmlFilterBase(const Reference<XComponentContext> & rxContext)131 XmlFilterBase::XmlFilterBase( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
132 FilterBase( rxContext ),
133 mxImpl( new XmlFilterBaseImpl( rxContext ) ),
134 mnRelId( 1 ),
135 mnMaxDocId( 0 )
136 {
137 }
138
~XmlFilterBase()139 XmlFilterBase::~XmlFilterBase()
140 {
141 // #118640# Reset the DocumentHandler at the FastSaxParser manually; this is
142 // needed since the mechanism is that instances of FragmentHandler execute
143 // their stuff (creating objects, setting attributes, ...) on being destroyed.
144 // They get destroyed by setting a new DocumentHandler. This also happens in
145 // the following implicit destruction chain of ~XmlFilterBaseImpl, but in that
146 // case it's member RelationsMap maRelationsMap will be destroyed, but maybe
147 // still be used by ~FragmentHandler -> crash.
148 mxImpl->maFastParser.setDocumentHandler( 0 );
149 }
150
151 // ----------------------------------------------------------------------------
152
getFragmentPathFromFirstType(const OUString & rType)153 OUString XmlFilterBase::getFragmentPathFromFirstType( const OUString& rType )
154 {
155 // importRelations() caches the relations map for subsequence calls
156 return importRelations( OUString() )->getFragmentPathFromFirstType( rType );
157 }
158
importFragment(const::rtl::Reference<FragmentHandler> & rxHandler)159 bool XmlFilterBase::importFragment( const ::rtl::Reference< FragmentHandler >& rxHandler )
160 {
161 OSL_ENSURE( rxHandler.is(), "XmlFilterBase::importFragment - missing fragment handler" );
162 if( !rxHandler.is() )
163 return false;
164
165 // fragment handler must contain path to fragment stream
166 OUString aFragmentPath = rxHandler->getFragmentPath();
167 OSL_ENSURE( aFragmentPath.getLength() > 0, "XmlFilterBase::importFragment - missing fragment path" );
168 if( aFragmentPath.getLength() == 0 )
169 return false;
170
171 // try to import binary streams (fragment extension must be '.bin')
172 if( lclHasSuffix( aFragmentPath, mxImpl->maBinSuffix ) )
173 {
174 try
175 {
176 // try to open the fragment stream (this may fail - do not assert)
177 Reference< XInputStream > xInStrm( openInputStream( aFragmentPath ), UNO_SET_THROW );
178
179 // create the record parser
180 RecordParser aParser;
181 aParser.setFragmentHandler( rxHandler );
182
183 // create the input source and parse the stream
184 RecordInputSource aSource;
185 aSource.mxInStream.reset( new BinaryXInputStream( xInStrm, true ) );
186 aSource.maSystemId = aFragmentPath;
187 aParser.parseStream( aSource );
188 return true;
189 }
190 catch( Exception& )
191 {
192 }
193 return false;
194 }
195
196 // get the XFastDocumentHandler interface from the fragment handler
197 Reference< XFastDocumentHandler > xDocHandler( rxHandler.get() );
198 if( !xDocHandler.is() )
199 return false;
200
201 // try to import XML stream
202 try
203 {
204 /* Try to open the fragment stream (may fail, do not throw/assert).
205 Using the virtual function openFragmentStream() allows a document
206 handler to create specialized input streams, e.g. VML streams that
207 have to preprocess the raw input data. */
208 Reference< XInputStream > xInStrm = rxHandler->openFragmentStream();
209
210 // own try/catch block for showing parser failure assertion with fragment path
211 if( xInStrm.is() ) try
212 {
213 mxImpl->maFastParser.setDocumentHandler( xDocHandler );
214 mxImpl->maFastParser.parseStream( xInStrm, aFragmentPath );
215 return true;
216 }
217 catch( Exception& )
218 {
219 OSL_ENSURE( false, OStringBuffer( "XmlFilterBase::importFragment - XML parser failed in fragment '" ).
220 append( OUStringToOString( aFragmentPath, RTL_TEXTENCODING_ASCII_US ) ).append( '\'' ).getStr() );
221 }
222 }
223 catch( Exception& )
224 {
225 }
226 return false;
227 }
228
importRelations(const OUString & rFragmentPath)229 RelationsRef XmlFilterBase::importRelations( const OUString& rFragmentPath )
230 {
231 // try to find cached relations
232 RelationsRef& rxRelations = mxImpl->maRelationsMap[ rFragmentPath ];
233 if( !rxRelations )
234 {
235 // import and cache relations
236 rxRelations.reset( new Relations( rFragmentPath ) );
237 importFragment( new RelationsFragment( *this, rxRelations ) );
238 }
239 return rxRelations;
240 }
241
openFragmentStream(const OUString & rStreamName,const OUString & rMediaType)242 Reference< XOutputStream > XmlFilterBase::openFragmentStream( const OUString& rStreamName, const OUString& rMediaType )
243 {
244 Reference< XOutputStream > xOutputStream = openOutputStream( rStreamName );
245 PropertySet aPropSet( xOutputStream );
246 aPropSet.setProperty( PROP_MediaType, rMediaType );
247 return xOutputStream;
248 }
249
openFragmentStreamWithSerializer(const OUString & rStreamName,const OUString & rMediaType)250 FSHelperPtr XmlFilterBase::openFragmentStreamWithSerializer( const OUString& rStreamName, const OUString& rMediaType )
251 {
252 return FSHelperPtr( new FastSerializerHelper( openFragmentStream( rStreamName, rMediaType ) ) );
253 }
254
getTextFieldStack() const255 TextFieldStack& XmlFilterBase::getTextFieldStack() const
256 {
257 return mxImpl->maTextFieldStack;
258 }
259
260 namespace {
261
lclAddRelation(const Reference<XRelationshipAccess> xRelations,sal_Int32 nId,const OUString & rType,const OUString & rTarget,bool bExternal)262 OUString lclAddRelation( const Reference< XRelationshipAccess > xRelations, sal_Int32 nId, const OUString& rType, const OUString& rTarget, bool bExternal )
263 {
264 OUString sId = OUStringBuffer().appendAscii( "rId" ).append( nId ).makeStringAndClear();
265
266 Sequence< StringPair > aEntry( bExternal ? 3 : 2 );
267 aEntry[0].First = CREATE_OUSTRING( "Type" );
268 aEntry[0].Second = rType;
269 aEntry[1].First = CREATE_OUSTRING( "Target" );
270 aEntry[1].Second = rTarget;
271 if( bExternal )
272 {
273 aEntry[2].First = CREATE_OUSTRING( "TargetMode" );
274 aEntry[2].Second = CREATE_OUSTRING( "External" );
275 }
276 xRelations->insertRelationshipByID( sId, aEntry, sal_True );
277
278 return sId;
279 }
280
281 } // namespace
282
addRelation(const OUString & rType,const OUString & rTarget,bool bExternal)283 OUString XmlFilterBase::addRelation( const OUString& rType, const OUString& rTarget, bool bExternal )
284 {
285 Reference< XRelationshipAccess > xRelations( getStorage()->getXStorage(), UNO_QUERY );
286 if( xRelations.is() )
287 return lclAddRelation( xRelations, mnRelId ++, rType, rTarget, bExternal );
288
289 return OUString();
290 }
291
addRelation(const Reference<XOutputStream> xOutputStream,const OUString & rType,const OUString & rTarget,bool bExternal)292 OUString XmlFilterBase::addRelation( const Reference< XOutputStream > xOutputStream, const OUString& rType, const OUString& rTarget, bool bExternal )
293 {
294 sal_Int32 nId = 0;
295
296 PropertySet aPropSet( xOutputStream );
297 if( aPropSet.is() )
298 aPropSet.getProperty( nId, PROP_RelId );
299 else
300 nId = mnRelId++;
301
302 Reference< XRelationshipAccess > xRelations( xOutputStream, UNO_QUERY );
303 if( xRelations.is() )
304 return lclAddRelation( xRelations, nId, rType, rTarget, bExternal );
305
306 return OUString();
307 }
308
309 static void
writeElement(FSHelperPtr pDoc,sal_Int32 nXmlElement,const OUString & sValue)310 writeElement( FSHelperPtr pDoc, sal_Int32 nXmlElement, const OUString& sValue )
311 {
312 if( sValue.getLength() == 0 )
313 return;
314 pDoc->startElement( nXmlElement, FSEND );
315 pDoc->write( sValue );
316 pDoc->endElement( nXmlElement );
317 }
318
319 static void
writeElement(FSHelperPtr pDoc,sal_Int32 nXmlElement,const sal_Int32 nValue)320 writeElement( FSHelperPtr pDoc, sal_Int32 nXmlElement, const sal_Int32 nValue )
321 {
322 pDoc->startElement( nXmlElement, FSEND );
323 pDoc->write( OUString::valueOf( nValue ) );
324 pDoc->endElement( nXmlElement );
325 }
326
327 static void
writeElement(FSHelperPtr pDoc,sal_Int32 nXmlElement,const DateTime & rTime)328 writeElement( FSHelperPtr pDoc, sal_Int32 nXmlElement, const DateTime& rTime )
329 {
330 if( rTime.Year == 0 )
331 return;
332
333 if ( ( nXmlElement >> 16 ) != XML_dcterms )
334 pDoc->startElement( nXmlElement, FSEND );
335 else
336 pDoc->startElement( nXmlElement,
337 FSNS( XML_xsi, XML_type ), "dcterms:W3CDTF",
338 FSEND );
339
340 char pStr[200];
341 snprintf( pStr, sizeof( pStr ), "%d-%02d-%02dT%02d:%02d:%02d.%02dZ",
342 rTime.Year, rTime.Month, rTime.Day,
343 rTime.Hours, rTime.Minutes, rTime.Seconds,
344 rTime.HundredthSeconds );
345
346 pDoc->write( pStr );
347
348 pDoc->endElement( nXmlElement );
349 }
350
351 static void
writeElement(FSHelperPtr pDoc,sal_Int32 nXmlElement,Sequence<rtl::OUString> aItems)352 writeElement( FSHelperPtr pDoc, sal_Int32 nXmlElement, Sequence< rtl::OUString > aItems )
353 {
354 if( aItems.getLength() == 0 )
355 return;
356
357 OUStringBuffer sRep;
358 sRep.append( aItems[ 0 ] );
359
360 for( sal_Int32 i = 1, end = aItems.getLength(); i < end; ++i )
361 {
362 sRep.appendAscii( " " ).append( aItems[ i ] );
363 }
364
365 writeElement( pDoc, nXmlElement, sRep.makeStringAndClear() );
366 }
367
368 static void
writeElement(FSHelperPtr pDoc,sal_Int32 nXmlElement,const Locale & rLocale)369 writeElement( FSHelperPtr pDoc, sal_Int32 nXmlElement, const Locale& rLocale )
370 {
371 // TODO: what to do with .Country and .Variant
372 writeElement( pDoc, nXmlElement, rLocale.Language );
373 }
374
375 static void
writeCoreProperties(XmlFilterBase & rSelf,Reference<XDocumentProperties> xProperties)376 writeCoreProperties( XmlFilterBase& rSelf, Reference< XDocumentProperties > xProperties )
377 {
378 rSelf.addRelation(
379 CREATE_OUSTRING( "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" ),
380 CREATE_OUSTRING( "docProps/core.xml" ) );
381 FSHelperPtr pCoreProps = rSelf.openFragmentStreamWithSerializer(
382 CREATE_OUSTRING( "docProps/core.xml" ),
383 CREATE_OUSTRING( "application/vnd.openxmlformats-package.core-properties+xml" ) );
384 pCoreProps->startElementNS( XML_cp, XML_coreProperties,
385 FSNS( XML_xmlns, XML_cp ), "http://schemas.openxmlformats.org/package/2006/metadata/core-properties",
386 FSNS( XML_xmlns, XML_dc ), "http://purl.org/dc/elements/1.1/",
387 FSNS( XML_xmlns, XML_dcterms ), "http://purl.org/dc/terms/",
388 FSNS( XML_xmlns, XML_dcmitype ), "http://purl.org/dc/dcmitype/",
389 FSNS( XML_xmlns, XML_xsi ), "http://www.w3.org/2001/XMLSchema-instance",
390 FSEND );
391
392 #if OOXTODO
393 writeElement( pCoreProps, FSNS( XML_cp, XML_category ), "category" );
394 writeElement( pCoreProps, FSNS( XML_cp, XML_contentStatus ), "status" );
395 writeElement( pCoreProps, FSNS( XML_cp, XML_contentType ), "contentType" );
396 #endif /* def OOXTODO */
397 writeElement( pCoreProps, FSNS( XML_dcterms, XML_created ), xProperties->getCreationDate() );
398 writeElement( pCoreProps, FSNS( XML_dc, XML_creator ), xProperties->getAuthor() );
399 writeElement( pCoreProps, FSNS( XML_dc, XML_description ), xProperties->getDescription() );
400 #if OOXTODO
401 writeElement( pCoreProps, FSNS( XML_dc, XML_identifier ), "ident" );
402 #endif /* def OOXTODO */
403 writeElement( pCoreProps, FSNS( XML_cp, XML_keywords ), xProperties->getKeywords() );
404 writeElement( pCoreProps, FSNS( XML_dc, XML_language ), xProperties->getLanguage() );
405 writeElement( pCoreProps, FSNS( XML_cp, XML_lastModifiedBy ), xProperties->getModifiedBy() );
406 writeElement( pCoreProps, FSNS( XML_cp, XML_lastPrinted ), xProperties->getPrintDate() );
407 writeElement( pCoreProps, FSNS( XML_dcterms, XML_modified ), xProperties->getModificationDate() );
408 writeElement( pCoreProps, FSNS( XML_cp, XML_revision ), xProperties->getEditingCycles() );
409 writeElement( pCoreProps, FSNS( XML_dc, XML_subject ), xProperties->getSubject() );
410 writeElement( pCoreProps, FSNS( XML_dc, XML_title ), xProperties->getTitle() );
411 #if OOXTODO
412 writeElement( pCoreProps, FSNS( XML_cp, XML_version ), "version" );
413 #endif /* def OOXTODO */
414
415 pCoreProps->endElementNS( XML_cp, XML_coreProperties );
416 }
417
418 static void
writeAppProperties(XmlFilterBase & rSelf,Reference<XDocumentProperties> xProperties)419 writeAppProperties( XmlFilterBase& rSelf, Reference< XDocumentProperties > xProperties )
420 {
421 rSelf.addRelation(
422 CREATE_OUSTRING( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" ),
423 CREATE_OUSTRING( "docProps/app.xml" ) );
424 FSHelperPtr pAppProps = rSelf.openFragmentStreamWithSerializer(
425 CREATE_OUSTRING( "docProps/app.xml" ),
426 CREATE_OUSTRING( "application/vnd.openxmlformats-officedocument.extended-properties+xml" ) );
427 pAppProps->startElement( XML_Properties,
428 XML_xmlns, "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties",
429 FSNS( XML_xmlns, XML_vt ), "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes",
430 FSEND );
431
432 writeElement( pAppProps, XML_Template, xProperties->getTemplateName() );
433 #if OOXTODO
434 writeElement( pAppProps, XML_Manager, "manager" );
435 writeElement( pAppProps, XML_Company, "company" );
436 writeElement( pAppProps, XML_Pages, "pages" );
437 writeElement( pAppProps, XML_Words, "words" );
438 writeElement( pAppProps, XML_Characters, "characters" );
439 writeElement( pAppProps, XML_PresentationFormat, "presentation format" );
440 writeElement( pAppProps, XML_Lines, "lines" );
441 writeElement( pAppProps, XML_Paragraphs, "paragraphs" );
442 writeElement( pAppProps, XML_Slides, "slides" );
443 writeElement( pAppProps, XML_Notes, "notes" );
444 #endif /* def OOXTODO */
445 writeElement( pAppProps, XML_TotalTime, xProperties->getEditingDuration() );
446 #if OOXTODO
447 writeElement( pAppProps, XML_HiddenSlides, "hidden slides" );
448 writeElement( pAppProps, XML_MMClips, "mm clips" );
449 writeElement( pAppProps, XML_ScaleCrop, "scale crop" );
450 writeElement( pAppProps, XML_HeadingPairs, "heading pairs" );
451 writeElement( pAppProps, XML_TitlesOfParts, "titles of parts" );
452 writeElement( pAppProps, XML_LinksUpToDate, "links up-to-date" );
453 writeElement( pAppProps, XML_CharactersWithSpaces, "characters with spaces" );
454 writeElement( pAppProps, XML_SharedDoc, "shared doc" );
455 writeElement( pAppProps, XML_HyperlinkBase, "hyperlink base" );
456 writeElement( pAppProps, XML_HLinks, "hlinks" );
457 writeElement( pAppProps, XML_HyperlinksChanged, "hyperlinks changed" );
458 writeElement( pAppProps, XML_DigSig, "digital signature" );
459 #endif /* def OOXTODO */
460 writeElement( pAppProps, XML_Application, xProperties->getGenerator() );
461 #if OOXTODO
462 writeElement( pAppProps, XML_AppVersion, "app version" );
463 writeElement( pAppProps, XML_DocSecurity, "doc security" );
464 #endif /* def OOXTODO */
465 pAppProps->endElement( XML_Properties );
466 }
467
exportDocumentProperties(Reference<XDocumentProperties> xProperties)468 XmlFilterBase& XmlFilterBase::exportDocumentProperties( Reference< XDocumentProperties > xProperties )
469 {
470 if( xProperties.is() )
471 {
472 writeCoreProperties( *this, xProperties );
473 writeAppProperties( *this, xProperties );
474 Sequence< ::com::sun::star::beans::NamedValue > aStats = xProperties->getDocumentStatistics();
475 printf( "# Document Statistics:\n" );
476 for( sal_Int32 i = 0, end = aStats.getLength(); i < end; ++i )
477 {
478 ::com::sun::star::uno::Any aValue = aStats[ i ].Value;
479 ::rtl::OUString sValue;
480 bool bHaveString = aValue >>= sValue;
481 printf ("#\t%s=%s [%s]\n",
482 OUStringToOString( aStats[ i ].Name, RTL_TEXTENCODING_UTF8 ).getStr(),
483 bHaveString
484 ? OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr()
485 : "<unconvertable>",
486 OUStringToOString( aValue.getValueTypeName(), RTL_TEXTENCODING_UTF8 ).getStr());
487 }
488 }
489 return *this;
490 }
491
492 // protected ------------------------------------------------------------------
493
implGetInputStream(MediaDescriptor & rMediaDesc) const494 Reference< XInputStream > XmlFilterBase::implGetInputStream( MediaDescriptor& rMediaDesc ) const
495 {
496 /* Get the input stream directly from the media descriptor, or decrypt the
497 package again. The latter is needed e.g. when the document is reloaded.
498 All this is implemented in the detector service. */
499 FilterDetect aDetector( getComponentContext() );
500 return aDetector.extractUnencryptedPackage( rMediaDesc );
501 }
502
503 // private --------------------------------------------------------------------
504
implCreateStorage(const Reference<XInputStream> & rxInStream) const505 StorageRef XmlFilterBase::implCreateStorage( const Reference< XInputStream >& rxInStream ) const
506 {
507 return StorageRef( new ZipStorage( getComponentContext(), rxInStream ) );
508 }
509
implCreateStorage(const Reference<XStream> & rxOutStream) const510 StorageRef XmlFilterBase::implCreateStorage( const Reference< XStream >& rxOutStream ) const
511 {
512 return StorageRef( new ZipStorage( getComponentContext(), rxOutStream ) );
513 }
514
515 // ============================================================================
516
517 } // namespace core
518 } // namespace oox
519