fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / comphelper / source / misc / storagehelper.cxx
blobd9077ab882f67713c06eda74cc6d60203aae8008
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/embed/ElementModes.hpp>
21 #include <com/sun/star/embed/XEncryptionProtectedSource2.hpp>
22 #include <com/sun/star/embed/XStorage.hpp>
23 #include <com/sun/star/embed/XTransactedObject.hpp>
24 #include <com/sun/star/embed/StorageFactory.hpp>
25 #include <com/sun/star/embed/FileSystemStorageFactory.hpp>
26 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
27 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
28 #include <com/sun/star/beans/XPropertySet.hpp>
29 #include <com/sun/star/beans/PropertyValue.hpp>
30 #include <com/sun/star/beans/NamedValue.hpp>
31 #include <com/sun/star/beans/IllegalTypeException.hpp>
32 #include <com/sun/star/xml/crypto/NSSInitializer.hpp>
33 #include <com/sun/star/xml/crypto/XDigestContext.hpp>
34 #include <com/sun/star/xml/crypto/XDigestContextSupplier.hpp>
35 #include <com/sun/star/xml/crypto/DigestID.hpp>
37 #include <vector>
38 #include <rtl/digest.h>
40 #include <ucbhelper/content.hxx>
42 #include <comphelper/fileformat.h>
43 #include <comphelper/processfactory.hxx>
44 #include <comphelper/documentconstants.hxx>
46 #include <comphelper/storagehelper.hxx>
49 using namespace ::com::sun::star;
51 namespace comphelper {
53 // ----------------------------------------------------------------------
54 uno::Reference< lang::XSingleServiceFactory > OStorageHelper::GetStorageFactory(
55 const uno::Reference< uno::XComponentContext >& rxContext )
56 throw ( uno::Exception )
58 uno::Reference< uno::XComponentContext> xContext = rxContext.is() ? rxContext : ::comphelper::getProcessComponentContext();
60 return embed::StorageFactory::create( xContext );
63 // ----------------------------------------------------------------------
64 uno::Reference< lang::XSingleServiceFactory > OStorageHelper::GetFileSystemStorageFactory(
65 const uno::Reference< uno::XComponentContext >& rxContext )
66 throw ( uno::Exception )
68 uno::Reference< uno::XComponentContext> xContext = rxContext.is() ? rxContext : ::comphelper::getProcessComponentContext();
70 return embed::FileSystemStorageFactory::create(rxContext);
73 // ----------------------------------------------------------------------
74 uno::Reference< embed::XStorage > OStorageHelper::GetTemporaryStorage(
75 const uno::Reference< uno::XComponentContext >& rxContext )
76 throw ( uno::Exception )
78 uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( rxContext )->createInstance(),
79 uno::UNO_QUERY );
80 if ( !xTempStorage.is() )
81 throw uno::RuntimeException();
83 return xTempStorage;
86 // ----------------------------------------------------------------------
87 uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromURL(
88 const OUString& aURL,
89 sal_Int32 nStorageMode,
90 const uno::Reference< uno::XComponentContext >& rxContext )
91 throw ( uno::Exception )
93 uno::Sequence< uno::Any > aArgs( 2 );
94 aArgs[0] <<= aURL;
95 aArgs[1] <<= nStorageMode;
97 uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( rxContext )->createInstanceWithArguments( aArgs ),
98 uno::UNO_QUERY );
99 if ( !xTempStorage.is() )
100 throw uno::RuntimeException();
102 return xTempStorage;
105 // ----------------------------------------------------------------------
106 uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromURL2(
107 const OUString& aURL,
108 sal_Int32 nStorageMode,
109 const uno::Reference< uno::XComponentContext >& rxContext )
110 throw ( uno::Exception )
112 uno::Sequence< uno::Any > aArgs( 2 );
113 aArgs[0] <<= aURL;
114 aArgs[1] <<= nStorageMode;
116 uno::Reference< lang::XSingleServiceFactory > xFact;
117 try {
118 ::ucbhelper::Content aCntnt( aURL,
119 uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > (),
120 getProcessComponentContext() );
121 if (aCntnt.isDocument()) {
122 xFact = GetStorageFactory( rxContext );
123 } else {
124 xFact = GetFileSystemStorageFactory( rxContext );
126 } catch (uno::Exception &) { }
128 if (!xFact.is()) throw uno::RuntimeException();
130 uno::Reference< embed::XStorage > xTempStorage(
131 xFact->createInstanceWithArguments( aArgs ), uno::UNO_QUERY );
132 if ( !xTempStorage.is() )
133 throw uno::RuntimeException();
135 return xTempStorage;
138 // ----------------------------------------------------------------------
139 uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromInputStream(
140 const uno::Reference < io::XInputStream >& xStream,
141 const uno::Reference< uno::XComponentContext >& rxContext )
142 throw ( uno::Exception )
144 uno::Sequence< uno::Any > aArgs( 2 );
145 aArgs[0] <<= xStream;
146 aArgs[1] <<= embed::ElementModes::READ;
148 uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( rxContext )->createInstanceWithArguments( aArgs ),
149 uno::UNO_QUERY );
150 if ( !xTempStorage.is() )
151 throw uno::RuntimeException();
153 return xTempStorage;
156 // ----------------------------------------------------------------------
157 uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromStream(
158 const uno::Reference < io::XStream >& xStream,
159 sal_Int32 nStorageMode,
160 const uno::Reference< uno::XComponentContext >& rxContext )
161 throw ( uno::Exception )
163 uno::Sequence< uno::Any > aArgs( 2 );
164 aArgs[0] <<= xStream;
165 aArgs[1] <<= nStorageMode;
167 uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( rxContext )->createInstanceWithArguments( aArgs ),
168 uno::UNO_QUERY );
169 if ( !xTempStorage.is() )
170 throw uno::RuntimeException();
172 return xTempStorage;
175 // ----------------------------------------------------------------------
176 void OStorageHelper::CopyInputToOutput(
177 const uno::Reference< io::XInputStream >& xInput,
178 const uno::Reference< io::XOutputStream >& xOutput )
179 throw ( uno::Exception )
181 static const sal_Int32 nConstBufferSize = 32000;
183 sal_Int32 nRead;
184 uno::Sequence < sal_Int8 > aSequence ( nConstBufferSize );
188 nRead = xInput->readBytes ( aSequence, nConstBufferSize );
189 if ( nRead < nConstBufferSize )
191 uno::Sequence < sal_Int8 > aTempBuf ( aSequence.getConstArray(), nRead );
192 xOutput->writeBytes ( aTempBuf );
194 else
195 xOutput->writeBytes ( aSequence );
197 while ( nRead == nConstBufferSize );
200 // ----------------------------------------------------------------------
201 uno::Reference< io::XInputStream > OStorageHelper::GetInputStreamFromURL(
202 const OUString& aURL,
203 const uno::Reference< uno::XComponentContext >& context )
204 throw ( uno::Exception )
206 uno::Reference< io::XInputStream > xInputStream = ucb::SimpleFileAccess::create(context)->openFileRead( aURL );
207 if ( !xInputStream.is() )
208 throw uno::RuntimeException();
210 return xInputStream;
213 // ----------------------------------------------------------------------
214 void OStorageHelper::SetCommonStorageEncryptionData(
215 const uno::Reference< embed::XStorage >& xStorage,
216 const uno::Sequence< beans::NamedValue >& aEncryptionData )
217 throw ( uno::Exception )
219 uno::Reference< embed::XEncryptionProtectedSource2 > xEncrSet( xStorage, uno::UNO_QUERY );
220 if ( !xEncrSet.is() )
221 throw io::IOException(); // TODO
223 xEncrSet->setEncryptionData( aEncryptionData );
226 // ----------------------------------------------------------------------
227 sal_Int32 OStorageHelper::GetXStorageFormat(
228 const uno::Reference< embed::XStorage >& xStorage )
229 throw ( uno::Exception )
231 uno::Reference< beans::XPropertySet > xStorProps( xStorage, uno::UNO_QUERY_THROW );
233 OUString aMediaType;
234 xStorProps->getPropertyValue( OUString( "MediaType" ) ) >>= aMediaType;
236 sal_Int32 nResult = 0;
238 // TODO/LATER: the filter configuration could be used to detect it later, or batter a special service
239 if (
240 aMediaType.equalsIgnoreAsciiCase(MIMETYPE_VND_SUN_XML_WRITER_ASCII ) ||
241 aMediaType.equalsIgnoreAsciiCase(MIMETYPE_VND_SUN_XML_WRITER_WEB_ASCII ) ||
242 aMediaType.equalsIgnoreAsciiCase(MIMETYPE_VND_SUN_XML_WRITER_GLOBAL_ASCII) ||
243 aMediaType.equalsIgnoreAsciiCase(MIMETYPE_VND_SUN_XML_DRAW_ASCII ) ||
244 aMediaType.equalsIgnoreAsciiCase(MIMETYPE_VND_SUN_XML_IMPRESS_ASCII ) ||
245 aMediaType.equalsIgnoreAsciiCase(MIMETYPE_VND_SUN_XML_CALC_ASCII ) ||
246 aMediaType.equalsIgnoreAsciiCase(MIMETYPE_VND_SUN_XML_CHART_ASCII ) ||
247 aMediaType.equalsIgnoreAsciiCase(MIMETYPE_VND_SUN_XML_MATH_ASCII )
250 nResult = SOFFICE_FILEFORMAT_60;
252 else if (
253 aMediaType.equalsIgnoreAsciiCase(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII ) ||
254 aMediaType.equalsIgnoreAsciiCase(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_WEB_ASCII ) ||
255 aMediaType.equalsIgnoreAsciiCase(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_ASCII ) ||
256 aMediaType.equalsIgnoreAsciiCase(MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_ASCII ) ||
257 aMediaType.equalsIgnoreAsciiCase(MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII) ||
258 aMediaType.equalsIgnoreAsciiCase(MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII ) ||
259 aMediaType.equalsIgnoreAsciiCase(MIMETYPE_OASIS_OPENDOCUMENT_CHART_ASCII ) ||
260 aMediaType.equalsIgnoreAsciiCase(MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_ASCII ) ||
261 aMediaType.equalsIgnoreAsciiCase(MIMETYPE_OASIS_OPENDOCUMENT_DATABASE_ASCII ) ||
262 aMediaType.equalsIgnoreAsciiCase(MIMETYPE_OASIS_OPENDOCUMENT_REPORT_ASCII ) ||
263 aMediaType.equalsIgnoreAsciiCase(MIMETYPE_OASIS_OPENDOCUMENT_REPORT_CHART_ASCII ) ||
264 aMediaType.equalsIgnoreAsciiCase(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_TEMPLATE_ASCII ) ||
265 aMediaType.equalsIgnoreAsciiCase(MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_TEMPLATE_ASCII ) ||
266 aMediaType.equalsIgnoreAsciiCase(MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE_ASCII) ||
267 aMediaType.equalsIgnoreAsciiCase(MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_TEMPLATE_ASCII ) ||
268 aMediaType.equalsIgnoreAsciiCase(MIMETYPE_OASIS_OPENDOCUMENT_CHART_TEMPLATE_ASCII ) ||
269 aMediaType.equalsIgnoreAsciiCase(MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_TEMPLATE_ASCII )
272 nResult = SOFFICE_FILEFORMAT_8;
274 else
276 // the mediatype is not known
277 throw beans::IllegalTypeException();
280 return nResult;
283 // ----------------------------------------------------------------------
284 uno::Reference< embed::XStorage > OStorageHelper::GetStorageOfFormatFromURL(
285 const OUString& aFormat,
286 const OUString& aURL,
287 sal_Int32 nStorageMode,
288 const uno::Reference< uno::XComponentContext >& rxContext,
289 sal_Bool bRepairStorage )
290 throw ( uno::Exception )
292 uno::Sequence< beans::PropertyValue > aProps( 1 );
293 aProps[0].Name = "StorageFormat";
294 aProps[0].Value <<= aFormat;
295 if ( bRepairStorage )
297 aProps.realloc( 2 );
298 aProps[1].Name = "RepairPackage";
299 aProps[1].Value <<= bRepairStorage;
302 uno::Sequence< uno::Any > aArgs( 3 );
303 aArgs[0] <<= aURL;
304 aArgs[1] <<= nStorageMode;
305 aArgs[2] <<= aProps;
307 uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( rxContext )->createInstanceWithArguments( aArgs ),
308 uno::UNO_QUERY );
309 if ( !xTempStorage.is() )
310 throw uno::RuntimeException();
312 return xTempStorage;
315 // ----------------------------------------------------------------------
316 uno::Reference< embed::XStorage > OStorageHelper::GetStorageOfFormatFromInputStream(
317 const OUString& aFormat,
318 const uno::Reference < io::XInputStream >& xStream,
319 const uno::Reference< uno::XComponentContext >& rxContext,
320 sal_Bool bRepairStorage )
321 throw ( uno::Exception )
323 uno::Sequence< beans::PropertyValue > aProps( 1 );
324 aProps[0].Name = "StorageFormat";
325 aProps[0].Value <<= aFormat;
326 if ( bRepairStorage )
328 aProps.realloc( 2 );
329 aProps[1].Name = "RepairPackage";
330 aProps[1].Value <<= bRepairStorage;
333 uno::Sequence< uno::Any > aArgs( 3 );
334 aArgs[0] <<= xStream;
335 aArgs[1] <<= embed::ElementModes::READ;
336 aArgs[2] <<= aProps;
338 uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( rxContext )->createInstanceWithArguments( aArgs ),
339 uno::UNO_QUERY );
340 if ( !xTempStorage.is() )
341 throw uno::RuntimeException();
343 return xTempStorage;
346 // ----------------------------------------------------------------------
347 uno::Reference< embed::XStorage > OStorageHelper::GetStorageOfFormatFromStream(
348 const OUString& aFormat,
349 const uno::Reference < io::XStream >& xStream,
350 sal_Int32 nStorageMode,
351 const uno::Reference< uno::XComponentContext >& rxContext,
352 sal_Bool bRepairStorage )
353 throw ( uno::Exception )
355 uno::Sequence< beans::PropertyValue > aProps( 1 );
356 aProps[0].Name = "StorageFormat";
357 aProps[0].Value <<= aFormat;
358 if ( bRepairStorage )
360 aProps.realloc( 2 );
361 aProps[1].Name = "RepairPackage";
362 aProps[1].Value <<= bRepairStorage;
365 uno::Sequence< uno::Any > aArgs( 3 );
366 aArgs[0] <<= xStream;
367 aArgs[1] <<= nStorageMode;
368 aArgs[2] <<= aProps;
370 uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( rxContext )->createInstanceWithArguments( aArgs ),
371 uno::UNO_QUERY );
372 if ( !xTempStorage.is() )
373 throw uno::RuntimeException();
375 return xTempStorage;
378 // ----------------------------------------------------------------------
379 uno::Sequence< beans::NamedValue > OStorageHelper::CreatePackageEncryptionData( const OUString& aPassword )
381 // TODO/LATER: Should not the method be part of DocPasswordHelper?
382 uno::Sequence< beans::NamedValue > aEncryptionData;
383 if ( !aPassword.isEmpty() )
385 sal_Int32 nSha1Ind = 0;
386 // generate SHA256 start key
389 uno::Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
391 uno::Reference< xml::crypto::XNSSInitializer > xDigestContextSupplier = xml::crypto::NSSInitializer::create(xContext);
392 uno::Reference< xml::crypto::XDigestContext > xDigestContext( xDigestContextSupplier->getDigestContext( xml::crypto::DigestID::SHA256, uno::Sequence< beans::NamedValue >() ), uno::UNO_SET_THROW );
394 OString aUTF8Password( OUStringToOString( aPassword, RTL_TEXTENCODING_UTF8 ) );
395 xDigestContext->updateDigest( uno::Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aUTF8Password.getStr() ), aUTF8Password.getLength() ) );
396 uno::Sequence< sal_Int8 > aDigest = xDigestContext->finalizeDigestAndDispose();
398 aEncryptionData.realloc( ++nSha1Ind );
399 aEncryptionData[0].Name = PACKAGE_ENCRYPTIONDATA_SHA256UTF8;
400 aEncryptionData[0].Value <<= aDigest;
402 catch ( uno::Exception& )
404 OSL_ENSURE( false, "Can not create SHA256 digest!" );
407 // MS_1252 encoding was used for SO60 document format password encoding,
408 // this encoding supports only a minor subset of nonascii characters,
409 // but for compatibility reasons it has to be used for old document formats
410 aEncryptionData.realloc( nSha1Ind + 2 );
411 aEncryptionData[nSha1Ind].Name = PACKAGE_ENCRYPTIONDATA_SHA1UTF8;
412 aEncryptionData[nSha1Ind + 1].Name = PACKAGE_ENCRYPTIONDATA_SHA1MS1252;
414 rtl_TextEncoding pEncoding[2] = { RTL_TEXTENCODING_UTF8, RTL_TEXTENCODING_MS_1252 };
416 for ( sal_Int32 nInd = 0; nInd < 2; nInd++ )
418 OString aByteStrPass = OUStringToOString( aPassword, pEncoding[nInd] );
420 sal_uInt8 pBuffer[RTL_DIGEST_LENGTH_SHA1];
421 rtlDigestError nError = rtl_digest_SHA1( aByteStrPass.getStr(),
422 aByteStrPass.getLength(),
423 pBuffer,
424 RTL_DIGEST_LENGTH_SHA1 );
426 if ( nError != rtl_Digest_E_None )
428 aEncryptionData.realloc( nSha1Ind );
429 break;
432 aEncryptionData[nSha1Ind+nInd].Value <<= uno::Sequence< sal_Int8 >( (sal_Int8*)pBuffer, RTL_DIGEST_LENGTH_SHA1 );
436 return aEncryptionData;
439 // ----------------------------------------------------------------------
440 sal_Bool OStorageHelper::IsValidZipEntryFileName( const OUString& aName, sal_Bool bSlashAllowed )
442 return IsValidZipEntryFileName( aName.getStr(), aName.getLength(), bSlashAllowed );
445 // ----------------------------------------------------------------------
446 sal_Bool OStorageHelper::IsValidZipEntryFileName(
447 const sal_Unicode *pChar, sal_Int32 nLength, sal_Bool bSlashAllowed )
449 for ( sal_Int32 i = 0; i < nLength; i++ )
451 switch ( pChar[i] )
453 case '\\':
454 case '?':
455 case '<':
456 case '>':
457 case '\"':
458 case '|':
459 case ':':
460 return sal_False;
461 case '/':
462 if ( !bSlashAllowed )
463 return sal_False;
464 break;
465 default:
466 if ( pChar[i] < 32 || (pChar[i] >= 0xD800 && pChar[i] <= 0xDFFF) )
467 return sal_False;
470 return sal_True;
473 // ----------------------------------------------------------------------
474 sal_Bool OStorageHelper::PathHasSegment( const OUString& aPath, const OUString& aSegment )
476 sal_Bool bResult = sal_False;
477 const sal_Int32 nPathLen = aPath.getLength();
478 const sal_Int32 nSegLen = aSegment.getLength();
480 if ( !aSegment.isEmpty() && nPathLen >= nSegLen )
482 OUString aEndSegment( "/" );
483 aEndSegment += aSegment;
485 OUString aInternalSegment( aEndSegment );
486 aInternalSegment += "/";
488 if ( aPath.indexOf( aInternalSegment ) >= 0 )
489 bResult = sal_True;
491 if ( !bResult && !aPath.compareTo( aSegment, nSegLen ) )
493 if ( nPathLen == nSegLen || aPath.getStr()[nSegLen] == (sal_Unicode)'/' )
494 bResult = sal_True;
497 if ( !bResult && nPathLen > nSegLen && aPath.copy( nPathLen - nSegLen - 1, nSegLen + 1 ) == aEndSegment )
498 bResult = sal_True;
501 return bResult;
504 class LifecycleProxy::Impl
505 : public std::vector< uno::Reference< embed::XStorage > > {};
506 LifecycleProxy::LifecycleProxy()
507 : m_pBadness( new Impl() ) { }
508 LifecycleProxy::~LifecycleProxy() { }
510 void LifecycleProxy::commitStorages()
512 for (Impl::reverse_iterator iter = m_pBadness->rbegin();
513 iter != m_pBadness->rend(); ++iter) // reverse order (outwards)
515 uno::Reference<embed::XTransactedObject> const xTransaction(*iter,
516 uno::UNO_QUERY);
517 if (xTransaction.is())
519 xTransaction->commit();
524 static void splitPath( std::vector<OUString> &rElems,
525 const OUString& rPath )
527 for (sal_Int32 i = 0; i >= 0;)
528 rElems.push_back( rPath.getToken( 0, '/', i ) );
531 static uno::Reference< embed::XStorage > LookupStorageAtPath(
532 const uno::Reference< embed::XStorage > &xParentStorage,
533 std::vector<OUString> &rElems, sal_uInt32 nOpenMode,
534 LifecycleProxy &rNastiness )
536 uno::Reference< embed::XStorage > xStorage( xParentStorage );
537 rNastiness.m_pBadness->push_back( xStorage );
538 for( size_t i = 0; i < rElems.size() && xStorage.is(); i++ )
540 xStorage = xStorage->openStorageElement( rElems[i], nOpenMode );
541 rNastiness.m_pBadness->push_back( xStorage );
543 return xStorage;
546 uno::Reference< embed::XStorage > OStorageHelper::GetStorageAtPath(
547 const uno::Reference< embed::XStorage > &xStorage,
548 const OUString& rPath, sal_uInt32 nOpenMode,
549 LifecycleProxy &rNastiness )
551 std::vector<OUString> aElems;
552 splitPath( aElems, rPath );
553 return LookupStorageAtPath( xStorage, aElems, nOpenMode, rNastiness );
556 uno::Reference< io::XStream > OStorageHelper::GetStreamAtPath(
557 const uno::Reference< embed::XStorage > &xParentStorage,
558 const OUString& rPath, sal_uInt32 nOpenMode,
559 LifecycleProxy &rNastiness )
561 std::vector<OUString> aElems;
562 splitPath( aElems, rPath );
563 OUString aName( aElems.back() );
564 aElems.pop_back();
565 sal_uInt32 nStorageMode = nOpenMode & ~embed::ElementModes::TRUNCATE;
566 uno::Reference< embed::XStorage > xStorage(
567 LookupStorageAtPath( xParentStorage, aElems, nStorageMode, rNastiness ),
568 uno::UNO_QUERY_THROW );
569 return xStorage->openStreamElement( aName, nOpenMode );
572 uno::Reference< io::XStream > OStorageHelper::GetStreamAtPackageURL(
573 uno::Reference< embed::XStorage > const& xParentStorage,
574 const OUString& rURL, sal_uInt32 const nOpenMode,
575 LifecycleProxy & rNastiness)
577 static char const s_PkgScheme[] = "vnd.sun.star.Package:";
578 if (0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength(
579 rURL.getStr(), rURL.getLength(),
580 s_PkgScheme, SAL_N_ELEMENTS(s_PkgScheme) - 1))
582 OUString const path(rURL.copy(SAL_N_ELEMENTS(s_PkgScheme)-1));
583 return GetStreamAtPath(xParentStorage, path, nOpenMode, rNastiness);
585 return 0;
590 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */