Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <com/sun/star/uno/Sequence.hxx>
21 : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
22 : #include <com/sun/star/embed/XStorage.hpp>
23 : #include <com/sun/star/embed/ElementModes.hpp>
24 : #include <com/sun/star/beans/XPropertySet.hpp>
25 :
26 : #include <rtl/digest.h>
27 : #include <osl/file.hxx>
28 : #include <sot/stg.hxx>
29 : #include <sot/storinfo.hxx>
30 : #include <sot/storage.hxx>
31 : #include <sot/formats.hxx>
32 : #include <sot/exchange.hxx>
33 : #include <unotools/ucbstreamhelper.hxx>
34 : #include <tools/debug.hxx>
35 : #include <tools/urlobj.hxx>
36 : #include <unotools/localfilehelper.hxx>
37 : #include <unotools/ucbhelper.hxx>
38 : #include <comphelper/processfactory.hxx>
39 :
40 : using namespace ::com::sun::star;
41 :
42 : /************** class SotStorageStream ***********************************/
43 0 : class SotStorageStreamFactory : public SotFactory
44 : {
45 : public:
46 : TYPEINFO_OVERRIDE();
47 0 : SotStorageStreamFactory( const SvGlobalName & rName,
48 : const OUString & rClassName,
49 : CreateInstanceType pCreateFuncP )
50 0 : : SotFactory( rName, rClassName, pCreateFuncP )
51 0 : {}
52 : };
53 0 : TYPEINIT1(SotStorageStreamFactory,SotFactory);
54 :
55 :
56 0 : SO2_IMPL_BASIC_CLASS1_DLL(SotStorageStream,SotStorageStreamFactory,SotObject,
57 : SvGlobalName( 0xd7deb420, 0xf902, 0x11d0,
58 : 0xaa, 0xa1, 0x0, 0xa0, 0x24, 0x9d, 0x55, 0x90 ) )
59 :
60 0 : SvLockBytesRef MakeLockBytes_Impl( const OUString & rName, StreamMode nMode )
61 : {
62 0 : SvLockBytesRef xLB;
63 0 : if( !rName.isEmpty() )
64 : {
65 0 : SvStream * pFileStm = new SvFileStream( rName, nMode );
66 0 : xLB = new SvLockBytes( pFileStm, true );
67 : }
68 : else
69 : {
70 0 : SvStream * pCacheStm = new SvMemoryStream();
71 0 : xLB = new SvLockBytes( pCacheStm, true );
72 : }
73 0 : return xLB;
74 : }
75 :
76 0 : SotStorageStream::SotStorageStream( const OUString & rName, StreamMode nMode,
77 : StorageMode
78 : #ifdef DBG_UTIL
79 : nStorageMode
80 : #endif
81 : )
82 : : SvStream( MakeLockBytes_Impl( rName, nMode ) )
83 0 : , pOwnStm( NULL )
84 : {
85 0 : if( nMode & STREAM_WRITE )
86 0 : bIsWritable = true;
87 : else
88 0 : bIsWritable = false;
89 :
90 : DBG_ASSERT( !nStorageMode,"StorageModes ignored" );
91 0 : }
92 :
93 0 : SotStorageStream::SotStorageStream( BaseStorageStream * pStm )
94 : {
95 0 : if( pStm )
96 : {
97 0 : if( STREAM_WRITE & pStm->GetMode() )
98 0 : bIsWritable = true;
99 : else
100 0 : bIsWritable = false;
101 :
102 0 : pOwnStm = pStm;
103 0 : SetError( pStm->GetError() );
104 0 : pStm->ResetError();
105 : }
106 : else
107 : {
108 0 : pOwnStm = NULL;
109 0 : bIsWritable = true;
110 0 : SetError( SVSTREAM_INVALID_PARAMETER );
111 : }
112 0 : }
113 :
114 0 : SotStorageStream::SotStorageStream()
115 0 : : pOwnStm( NULL )
116 : {
117 : // ??? wenn Init virtuell ist, entsprechen setzen
118 0 : bIsWritable = true;
119 0 : }
120 :
121 0 : SotStorageStream::~SotStorageStream()
122 : {
123 0 : Flush(); //SetBufferSize(0);
124 0 : delete pOwnStm;
125 0 : }
126 :
127 0 : void SotStorageStream::ResetError()
128 : {
129 0 : SvStream::ResetError();
130 0 : if( pOwnStm )
131 0 : pOwnStm->ResetError();
132 0 : }
133 :
134 0 : sal_uLong SotStorageStream::GetData( void* pData, sal_uLong nSize )
135 : {
136 0 : sal_uLong nRet = 0;
137 :
138 0 : if( pOwnStm )
139 : {
140 0 : nRet = pOwnStm->Read( pData, nSize );
141 0 : SetError( pOwnStm->GetError() );
142 : }
143 : else
144 0 : nRet = SvStream::GetData( (sal_Char *)pData, nSize );
145 :
146 0 : return nRet;
147 : }
148 :
149 0 : sal_uLong SotStorageStream::PutData( const void* pData, sal_uLong nSize )
150 : {
151 0 : sal_uLong nRet = 0;
152 :
153 0 : if( pOwnStm )
154 : {
155 0 : nRet = pOwnStm->Write( pData, nSize );
156 0 : SetError( pOwnStm->GetError() );
157 : }
158 : else
159 0 : nRet = SvStream::PutData( (sal_Char *)pData, nSize );
160 0 : return nRet;
161 : }
162 :
163 0 : sal_uInt64 SotStorageStream::SeekPos(sal_uInt64 nPos)
164 : {
165 0 : sal_uLong nRet = 0;
166 :
167 0 : if( pOwnStm )
168 : {
169 0 : nRet = pOwnStm->Seek( nPos );
170 0 : SetError( pOwnStm->GetError() );
171 : }
172 : else
173 0 : nRet = SvStream::SeekPos( nPos );
174 :
175 0 : return nRet;
176 : }
177 :
178 0 : void SotStorageStream::FlushData()
179 : {
180 0 : if( pOwnStm )
181 : {
182 0 : pOwnStm->Flush();
183 0 : SetError( pOwnStm->GetError() );
184 : }
185 : else
186 0 : SvStream::FlushData();
187 0 : }
188 :
189 0 : void SotStorageStream::SetSize(sal_uInt64 const nNewSize)
190 : {
191 0 : sal_uInt64 const nPos = Tell();
192 0 : if( pOwnStm )
193 : {
194 0 : pOwnStm->SetSize( nNewSize );
195 0 : SetError( pOwnStm->GetError() );
196 : }
197 : else
198 0 : SvStream::SetSize( nNewSize );
199 :
200 0 : if( nNewSize < nPos )
201 : // ans Ende setzen
202 0 : Seek( nNewSize );
203 0 : }
204 :
205 0 : sal_uInt32 SotStorageStream::GetSize() const
206 : {
207 0 : sal_uLong nPos = Tell();
208 0 : ((SotStorageStream *)this)->Seek( STREAM_SEEK_TO_END );
209 0 : sal_uLong nSize = Tell();
210 0 : ((SotStorageStream *)this)->Seek( nPos );
211 0 : return nSize;
212 : }
213 :
214 0 : sal_uInt64 SotStorageStream::remainingSize()
215 : {
216 0 : if (pOwnStm)
217 0 : return pOwnStm->GetSize() - Tell();
218 :
219 0 : return SvStream::remainingSize();
220 : }
221 :
222 0 : bool SotStorageStream::CopyTo( SotStorageStream * pDestStm )
223 : {
224 0 : Flush(); // alle Daten schreiben
225 0 : pDestStm->ClearBuffer();
226 0 : if( !pOwnStm || !pDestStm->pOwnStm )
227 : {
228 : // Wenn Ole2 oder nicht nur eigene StorageStreams
229 0 : sal_uLong nPos = Tell(); // Position merken
230 0 : Seek( 0L );
231 0 : pDestStm->SetSize( 0 ); // Ziel-Stream leeren
232 :
233 0 : void * pMem = new sal_uInt8[ 8192 ];
234 : sal_uLong nRead;
235 0 : while( 0 != (nRead = Read( pMem, 8192 )) )
236 : {
237 0 : if( nRead != pDestStm->Write( pMem, nRead ) )
238 : {
239 0 : SetError( SVSTREAM_GENERALERROR );
240 0 : break;
241 : }
242 : }
243 0 : delete [] static_cast<sal_uInt8*>(pMem);
244 : // Position setzen
245 0 : pDestStm->Seek( nPos );
246 0 : Seek( nPos );
247 : }
248 : else
249 : {
250 0 : pOwnStm->CopyTo( pDestStm->pOwnStm );
251 0 : SetError( pOwnStm->GetError() );
252 : }
253 0 : return GetError() == SVSTREAM_OK;
254 : }
255 :
256 0 : bool SotStorageStream::Commit()
257 : {
258 0 : if( pOwnStm )
259 : {
260 0 : pOwnStm->Flush();
261 0 : if( pOwnStm->GetError() == SVSTREAM_OK )
262 0 : pOwnStm->Commit();
263 0 : SetError( pOwnStm->GetError() );
264 : }
265 0 : return GetError() == SVSTREAM_OK;
266 : }
267 :
268 0 : bool SotStorageStream::Revert()
269 : {
270 0 : if( pOwnStm )
271 : {
272 0 : pOwnStm->Revert();
273 0 : SetError( pOwnStm->GetError() );
274 : }
275 0 : return GetError() == SVSTREAM_OK;
276 : }
277 :
278 0 : bool SotStorageStream::SetProperty( const OUString& rName, const ::com::sun::star::uno::Any& rValue )
279 : {
280 0 : UCBStorageStream* pStg = PTR_CAST( UCBStorageStream, pOwnStm );
281 0 : if ( pStg )
282 : {
283 0 : return pStg->SetProperty( rName, rValue );
284 : }
285 : else
286 : {
287 : OSL_FAIL("Not implemented!");
288 0 : return false;
289 : }
290 : }
291 :
292 : /************** class SotStorage ******************************************
293 : *************************************************************************/
294 0 : class SotStorageFactory : public SotFactory
295 : {
296 : public:
297 : TYPEINFO_OVERRIDE();
298 0 : SotStorageFactory( const SvGlobalName & rName,
299 : const OUString & rClassName,
300 : CreateInstanceType pCreateFuncP )
301 0 : : SotFactory( rName, rClassName, pCreateFuncP )
302 0 : {}
303 : };
304 0 : TYPEINIT1(SotStorageFactory,SotFactory);
305 :
306 :
307 0 : SO2_IMPL_BASIC_CLASS1_DLL(SotStorage,SotStorageFactory,SotObject,
308 : SvGlobalName( 0x980ce7e0, 0xf905, 0x11d0,
309 : 0xaa, 0xa1, 0x0, 0xa0, 0x24, 0x9d, 0x55, 0x90 ) )
310 :
311 : /************************************************************************
312 : |*
313 : |* SotStorage::SotStorage()
314 : |*
315 : |* Beschreibung Es muss ein I... Objekt an SvObject uebergeben
316 : |* werden, da es sonst selbst ein IUnknown anlegt und
317 : |* festlegt, dass alle weiteren I... Objekte mit
318 : |* delete zerstoert werden (Owner() == true).
319 : |* Es werden aber nur IStorage Objekte benutzt und nicht
320 : |* selbst implementiert, deshalb wird so getan, als ob
321 : |* das IStorage Objekt von aussen kam und es wird mit
322 : |* Release() freigegeben.
323 : |* Die CreateStorage Methoden werden benoetigt, um
324 : |* ein IStorage Objekt vor dem Aufruf von SvObject
325 : |* zu erzeugen (Own, !Own automatik).
326 : |* Hat CreateStorage ein Objekt erzeugt, dann wurde
327 : |* der RefCounter schon um 1 erhoet.
328 : |* Die Uebergabe erfolgt in pStorageCTor. Die Variable
329 : |* ist NULL, wenn es nicht geklappt hat.
330 : |*
331 : *************************************************************************/
332 : #define INIT_SotStorage() \
333 : : m_pOwnStg( NULL ) \
334 : , m_pStorStm( NULL ) \
335 : , m_nError( SVSTREAM_OK ) \
336 : , m_bIsRoot( false ) \
337 : , m_bDelStm( false ) \
338 : , m_nVersion( SOFFICE_FILEFORMAT_CURRENT )
339 :
340 0 : SotStorage::SotStorage()
341 0 : INIT_SotStorage()
342 : {
343 : // ??? What's this ???
344 0 : }
345 :
346 : #define ERASEMASK ( STREAM_TRUNC | STREAM_WRITE | STREAM_SHARE_DENYALL )
347 : #include <com/sun/star/uno/Reference.h>
348 : #include <com/sun/star/ucb/XCommandEnvironment.hpp>
349 : #include <ucbhelper/content.hxx>
350 :
351 0 : SotStorage::SotStorage( const OUString & rName, StreamMode nMode, StorageMode nStorageMode )
352 0 : INIT_SotStorage()
353 : {
354 0 : m_aName = rName; // Namen merken
355 0 : CreateStorage( true, nMode, nStorageMode );
356 0 : if ( IsOLEStorage() )
357 0 : m_nVersion = SOFFICE_FILEFORMAT_50;
358 0 : }
359 :
360 0 : void SotStorage::CreateStorage( bool bForceUCBStorage, StreamMode nMode, StorageMode nStorageMode )
361 : {
362 : DBG_ASSERT( !m_pStorStm && !m_pOwnStg, "Use only in ctor!" );
363 0 : if( !m_aName.isEmpty() )
364 : {
365 : // named storage
366 0 : if( ( ( nMode & ERASEMASK ) == ERASEMASK ) )
367 0 : ::utl::UCBContentHelper::Kill( m_aName );
368 :
369 0 : INetURLObject aObj( m_aName );
370 0 : if ( aObj.GetProtocol() == INET_PROT_NOT_VALID )
371 : {
372 0 : OUString aURL;
373 0 : ::utl::LocalFileHelper::ConvertPhysicalNameToURL( m_aName, aURL );
374 0 : aObj.SetURL( aURL );
375 0 : m_aName = aObj.GetMainURL( INetURLObject::NO_DECODE );
376 : }
377 :
378 : // a new unpacked storage should be created
379 0 : if ( nStorageMode == STORAGE_CREATE_UNPACKED )
380 : {
381 : // don't open stream readwrite, content provider may not support this !
382 0 : OUString aURL = UCBStorage::CreateLinkFile( m_aName );
383 0 : if ( !aURL.isEmpty() )
384 : {
385 0 : ::ucbhelper::Content aContent( aURL, ::com::sun::star::uno::Reference < ::com::sun::star::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
386 0 : m_pOwnStg = new UCBStorage( aContent, aURL, nMode, false );
387 : }
388 : else
389 : {
390 0 : m_pOwnStg = new Storage( m_aName, nMode, false );
391 0 : SetError( ERRCODE_IO_NOTSUPPORTED );
392 0 : }
393 : }
394 : else
395 : {
396 : // check the stream
397 0 : m_pStorStm = ::utl::UcbStreamHelper::CreateStream( m_aName, nMode );
398 0 : if ( m_pStorStm && m_pStorStm->GetError() )
399 0 : DELETEZ( m_pStorStm );
400 :
401 0 : if ( m_pStorStm )
402 : {
403 : // try as UCBStorage, next try as OLEStorage
404 0 : bool bIsUCBStorage = UCBStorage::IsStorageFile( m_pStorStm );
405 0 : if ( !bIsUCBStorage && bForceUCBStorage )
406 : // if UCBStorage has priority, it should not be used only if it is really an OLEStorage
407 0 : bIsUCBStorage = !Storage::IsStorageFile( m_pStorStm );
408 :
409 0 : if ( bIsUCBStorage )
410 : {
411 0 : if ( !(UCBStorage::GetLinkedFile( *m_pStorStm ).isEmpty()) )
412 : {
413 : // detect special unpacked storages
414 0 : m_pOwnStg = new UCBStorage( *m_pStorStm, (nStorageMode & STORAGE_TRANSACTED) ? false : true );
415 0 : m_bDelStm = true;
416 : }
417 : else
418 : {
419 : // detect special disk spanned storages
420 0 : if ( UCBStorage::IsDiskSpannedFile( m_pStorStm ) )
421 0 : nMode |= STORAGE_DISKSPANNED_MODE;
422 :
423 : // UCBStorage always works directly on the UCB content, so discard the stream first
424 0 : DELETEZ( m_pStorStm );
425 0 : m_pOwnStg = new UCBStorage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? false : true );
426 : }
427 : }
428 : else
429 : {
430 : // OLEStorage can be opened with a stream
431 0 : m_pOwnStg = new Storage( *m_pStorStm, (nStorageMode & STORAGE_TRANSACTED) ? false : true );
432 0 : m_bDelStm = true;
433 : }
434 : }
435 0 : else if ( bForceUCBStorage )
436 : {
437 0 : m_pOwnStg = new UCBStorage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? false : true );
438 0 : SetError( ERRCODE_IO_NOTSUPPORTED );
439 : }
440 : else
441 : {
442 0 : m_pOwnStg = new Storage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? false : true );
443 0 : SetError( ERRCODE_IO_NOTSUPPORTED );
444 : }
445 0 : }
446 : }
447 : else
448 : {
449 : // temporary storage
450 0 : if ( bForceUCBStorage )
451 0 : m_pOwnStg = new UCBStorage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? false : true );
452 : else
453 0 : m_pOwnStg = new Storage( m_aName, nMode, (nStorageMode & STORAGE_TRANSACTED) ? false : true );
454 0 : m_aName = m_pOwnStg->GetName();
455 : }
456 :
457 0 : SetError( m_pOwnStg->GetError() );
458 :
459 0 : SignAsRoot( m_pOwnStg->IsRoot() );
460 0 : }
461 :
462 0 : SotStorage::SotStorage( bool bUCBStorage, const OUString & rName, StreamMode nMode, StorageMode nStorageMode )
463 0 : INIT_SotStorage()
464 : {
465 0 : m_aName = rName;
466 0 : CreateStorage( bUCBStorage, nMode, nStorageMode );
467 0 : if ( IsOLEStorage() )
468 0 : m_nVersion = SOFFICE_FILEFORMAT_50;
469 0 : }
470 :
471 0 : SotStorage::SotStorage( BaseStorage * pStor )
472 0 : INIT_SotStorage()
473 : {
474 0 : if ( pStor )
475 : {
476 0 : m_aName = pStor->GetName(); // Namen merken
477 0 : SignAsRoot( pStor->IsRoot() );
478 0 : SetError( pStor->GetError() );
479 : }
480 :
481 0 : m_pOwnStg = pStor;
482 0 : sal_uLong nErr = m_pOwnStg ? m_pOwnStg->GetError() : SVSTREAM_CANNOT_MAKE;
483 0 : SetError( nErr );
484 0 : if ( IsOLEStorage() )
485 0 : m_nVersion = SOFFICE_FILEFORMAT_50;
486 0 : }
487 :
488 0 : SotStorage::SotStorage( bool bUCBStorage, SvStream & rStm )
489 0 : INIT_SotStorage()
490 : {
491 0 : SetError( rStm.GetError() );
492 :
493 : // try as UCBStorage, next try as OLEStorage
494 0 : if ( UCBStorage::IsStorageFile( &rStm ) || bUCBStorage )
495 0 : m_pOwnStg = new UCBStorage( rStm, false );
496 : else
497 0 : m_pOwnStg = new Storage( rStm, false );
498 :
499 0 : SetError( m_pOwnStg->GetError() );
500 :
501 0 : if ( IsOLEStorage() )
502 0 : m_nVersion = SOFFICE_FILEFORMAT_50;
503 :
504 0 : SignAsRoot( m_pOwnStg->IsRoot() );
505 0 : }
506 :
507 0 : SotStorage::SotStorage( SvStream & rStm )
508 0 : INIT_SotStorage()
509 : {
510 0 : SetError( rStm.GetError() );
511 :
512 : // try as UCBStorage, next try as OLEStorage
513 0 : if ( UCBStorage::IsStorageFile( &rStm ) )
514 0 : m_pOwnStg = new UCBStorage( rStm, false );
515 : else
516 0 : m_pOwnStg = new Storage( rStm, false );
517 :
518 0 : SetError( m_pOwnStg->GetError() );
519 :
520 0 : if ( IsOLEStorage() )
521 0 : m_nVersion = SOFFICE_FILEFORMAT_50;
522 :
523 0 : SignAsRoot( m_pOwnStg->IsRoot() );
524 0 : }
525 :
526 0 : SotStorage::SotStorage( SvStream * pStm, bool bDelete )
527 0 : INIT_SotStorage()
528 : {
529 0 : SetError( pStm->GetError() );
530 :
531 : // try as UCBStorage, next try as OLEStorage
532 0 : if ( UCBStorage::IsStorageFile( pStm ) )
533 0 : m_pOwnStg = new UCBStorage( *pStm, false );
534 : else
535 0 : m_pOwnStg = new Storage( *pStm, false );
536 :
537 0 : SetError( m_pOwnStg->GetError() );
538 :
539 0 : m_pStorStm = pStm;
540 0 : m_bDelStm = bDelete;
541 0 : if ( IsOLEStorage() )
542 0 : m_nVersion = SOFFICE_FILEFORMAT_50;
543 :
544 0 : SignAsRoot( m_pOwnStg->IsRoot() );
545 0 : }
546 :
547 0 : SotStorage::~SotStorage()
548 : {
549 0 : delete m_pOwnStg;
550 0 : if( m_bDelStm )
551 0 : delete m_pStorStm;
552 0 : }
553 :
554 0 : SvMemoryStream * SotStorage::CreateMemoryStream()
555 : {
556 0 : SvMemoryStream * pStm = NULL;
557 0 : pStm = new SvMemoryStream( 0x8000, 0x8000 );
558 0 : SotStorageRef aStg = new SotStorage( *pStm );
559 0 : if( CopyTo( aStg ) )
560 : {
561 0 : aStg->Commit();
562 : }
563 : else
564 : {
565 0 : aStg.Clear(); // Storage vorher freigeben
566 0 : delete pStm;
567 0 : pStm = NULL;
568 : }
569 0 : return pStm;
570 : }
571 :
572 0 : bool SotStorage::IsStorageFile( const OUString & rFileName )
573 : {
574 0 : OUString aName( rFileName );
575 0 : INetURLObject aObj( aName );
576 0 : if ( aObj.GetProtocol() == INET_PROT_NOT_VALID )
577 : {
578 0 : OUString aURL;
579 0 : ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aURL );
580 0 : aObj.SetURL( aURL );
581 0 : aName = aObj.GetMainURL( INetURLObject::NO_DECODE );
582 : }
583 :
584 0 : SvStream * pStm = ::utl::UcbStreamHelper::CreateStream( aName, STREAM_STD_READ );
585 0 : bool bRet = SotStorage::IsStorageFile( pStm );
586 0 : delete pStm;
587 0 : return bRet;
588 : }
589 :
590 0 : bool SotStorage::IsStorageFile( SvStream* pStream )
591 : {
592 : /** code for new storages must come first! **/
593 0 : if ( pStream )
594 : {
595 0 : long nPos = pStream->Tell();
596 0 : bool bRet = UCBStorage::IsStorageFile( pStream );
597 0 : if ( !bRet )
598 0 : bRet = Storage::IsStorageFile( pStream );
599 0 : pStream->Seek( nPos );
600 0 : return bRet;
601 : }
602 : else
603 0 : return false;
604 : }
605 :
606 0 : const OUString & SotStorage::GetName() const
607 : {
608 0 : if( m_aName.isEmpty() )
609 : {
610 : DBG_ASSERT( Owner(), "must be owner" );
611 0 : if( m_pOwnStg )
612 0 : ((SotStorage *)this)->m_aName = m_pOwnStg->GetName();
613 : }
614 0 : return m_aName;
615 : }
616 :
617 0 : const OString& SotStorage::GetKey() const
618 : {
619 0 : return m_aKey;
620 : }
621 :
622 0 : void SotStorage::ResetError()
623 : {
624 0 : m_nError = SVSTREAM_OK;
625 0 : if( m_pOwnStg )
626 0 : m_pOwnStg->ResetError();
627 0 : }
628 :
629 0 : void SotStorage::SetClass( const SvGlobalName & rName,
630 : sal_uLong nOriginalClipFormat,
631 : const OUString & rUserTypeName )
632 : {
633 : DBG_ASSERT( Owner(), "must be owner" );
634 0 : if( m_pOwnStg )
635 0 : m_pOwnStg->SetClass( rName, nOriginalClipFormat, rUserTypeName );
636 : else
637 0 : SetError( SVSTREAM_GENERALERROR );
638 0 : }
639 :
640 0 : void SotStorage::SetConvertClass( const SvGlobalName & rName,
641 : sal_uLong nOriginalClipFormat,
642 : const OUString & rUserTypeName )
643 : {
644 : DBG_ASSERT( Owner(), "must be owner" );
645 0 : if( m_pOwnStg )
646 0 : m_pOwnStg->SetConvertClass( rName, nOriginalClipFormat, rUserTypeName );
647 : else
648 0 : SetError( SVSTREAM_GENERALERROR );
649 0 : }
650 :
651 0 : SvGlobalName SotStorage::GetClassName()
652 : {
653 0 : SvGlobalName aGN;
654 : DBG_ASSERT( Owner(), "must be owner" );
655 0 : if( m_pOwnStg )
656 0 : aGN = m_pOwnStg->GetClassName();
657 : else
658 0 : SetError( SVSTREAM_GENERALERROR );
659 0 : return aGN;
660 : }
661 :
662 0 : sal_uLong SotStorage::GetFormat()
663 : {
664 0 : sal_uLong nFormat = 0;
665 : DBG_ASSERT( Owner(), "must be owner" );
666 0 : if( m_pOwnStg )
667 0 : nFormat = m_pOwnStg->GetFormat();
668 : else
669 0 : SetError( SVSTREAM_GENERALERROR );
670 0 : return nFormat;
671 : }
672 :
673 0 : OUString SotStorage::GetUserName()
674 : {
675 0 : OUString aName;
676 : DBG_ASSERT( Owner(), "must be owner" );
677 0 : if( m_pOwnStg )
678 0 : aName = m_pOwnStg->GetUserName();
679 : else
680 0 : SetError( SVSTREAM_GENERALERROR );
681 0 : return aName;
682 : }
683 :
684 0 : bool SotStorage::ShouldConvert()
685 : {
686 : DBG_ASSERT( Owner(), "must be owner" );
687 0 : if( m_pOwnStg )
688 0 : return m_pOwnStg->ShouldConvert();
689 : else
690 0 : SetError( SVSTREAM_GENERALERROR );
691 0 : return false;
692 : }
693 :
694 0 : void SotStorage::FillInfoList( SvStorageInfoList * pFillList ) const
695 : {
696 : DBG_ASSERT( Owner(), "must be owner" );
697 0 : if( m_pOwnStg )
698 0 : m_pOwnStg->FillInfoList( pFillList );
699 0 : }
700 :
701 0 : bool SotStorage::CopyTo( SotStorage * pDestStg )
702 : {
703 : DBG_ASSERT( Owner(), "must be owner" );
704 : DBG_ASSERT( pDestStg->Owner(), "must be owner" );
705 0 : if( m_pOwnStg && pDestStg->m_pOwnStg )
706 : {
707 0 : m_pOwnStg->CopyTo( pDestStg->m_pOwnStg );
708 0 : SetError( m_pOwnStg->GetError() );
709 0 : pDestStg->m_aKey = m_aKey;
710 0 : pDestStg->m_nVersion = m_nVersion;
711 : }
712 : else
713 0 : SetError( SVSTREAM_GENERALERROR );
714 :
715 0 : return SVSTREAM_OK == GetError();
716 : }
717 :
718 0 : bool SotStorage::Commit()
719 : {
720 : DBG_ASSERT( Owner(), "must be owner" );
721 0 : if( m_pOwnStg )
722 : {
723 0 : if( !m_pOwnStg->Commit() )
724 0 : SetError( m_pOwnStg->GetError() );
725 : }
726 : else
727 0 : SetError( SVSTREAM_GENERALERROR );
728 :
729 0 : return SVSTREAM_OK == GetError();
730 : }
731 :
732 0 : bool SotStorage::Revert()
733 : {
734 : DBG_ASSERT( Owner(), "must be owner" );
735 0 : if( m_pOwnStg )
736 : {
737 0 : if( !m_pOwnStg->Revert() )
738 0 : SetError( m_pOwnStg->GetError() );
739 : }
740 : else
741 0 : SetError( SVSTREAM_GENERALERROR );
742 :
743 0 : return SVSTREAM_OK == GetError();
744 : }
745 :
746 0 : SotStorageStream * SotStorage::OpenSotStream( const OUString & rEleName,
747 : StreamMode nMode,
748 : StorageMode nStorageMode )
749 : {
750 : DBG_ASSERT( !nStorageMode, "StorageModes ignored" );
751 0 : SotStorageStream * pStm = NULL;
752 : DBG_ASSERT( Owner(), "must be owner" );
753 0 : if( m_pOwnStg )
754 : {
755 : // volle Ole-Patches einschalten
756 : // egal was kommt, nur exclusiv gestattet
757 0 : nMode |= STREAM_SHARE_DENYALL;
758 0 : ErrCode nE = m_pOwnStg->GetError();
759 : BaseStorageStream * p = m_pOwnStg->OpenStream( rEleName, nMode,
760 0 : (nStorageMode & STORAGE_TRANSACTED) ? false : true );
761 0 : pStm = new SotStorageStream( p );
762 :
763 0 : if( !nE )
764 0 : m_pOwnStg->ResetError(); // kein Fehler setzen
765 0 : if( nMode & STREAM_TRUNC )
766 0 : pStm->SetSize( 0 );
767 : }
768 : else
769 0 : SetError( SVSTREAM_GENERALERROR );
770 :
771 0 : return pStm;
772 : }
773 :
774 0 : SotStorage * SotStorage::OpenSotStorage( const OUString & rEleName,
775 : StreamMode nMode,
776 : StorageMode nStorageMode )
777 : {
778 : DBG_ASSERT( Owner(), "must be owner" );
779 0 : if( m_pOwnStg )
780 : {
781 0 : nMode |= STREAM_SHARE_DENYALL;
782 0 : ErrCode nE = m_pOwnStg->GetError();
783 : BaseStorage * p = m_pOwnStg->OpenStorage( rEleName, nMode,
784 0 : (nStorageMode & STORAGE_TRANSACTED) ? false : true );
785 0 : if( p )
786 : {
787 0 : SotStorage * pStor = new SotStorage( p );
788 0 : if( !nE )
789 0 : m_pOwnStg->ResetError(); // kein Fehler setzen
790 :
791 0 : return pStor;
792 : }
793 : }
794 :
795 0 : SetError( SVSTREAM_GENERALERROR );
796 :
797 0 : return NULL;
798 : }
799 :
800 0 : bool SotStorage::IsStorage( const OUString & rEleName ) const
801 : {
802 : DBG_ASSERT( Owner(), "must be owner" );
803 : // ein bisschen schneller
804 0 : if( m_pOwnStg )
805 0 : return m_pOwnStg->IsStorage( rEleName );
806 :
807 0 : return false;
808 : }
809 :
810 0 : bool SotStorage::IsStream( const OUString & rEleName ) const
811 : {
812 : DBG_ASSERT( Owner(), "must be owner" );
813 : // ein bisschen schneller
814 0 : if( m_pOwnStg )
815 0 : return m_pOwnStg->IsStream( rEleName );
816 :
817 0 : return false;
818 : }
819 :
820 0 : bool SotStorage::IsContained( const OUString & rEleName ) const
821 : {
822 : DBG_ASSERT( Owner(), "must be owner" );
823 : // ein bisschen schneller
824 0 : if( m_pOwnStg )
825 0 : return m_pOwnStg->IsContained( rEleName );
826 :
827 0 : return false;
828 : }
829 :
830 0 : bool SotStorage::Remove( const OUString & rEleName )
831 : {
832 : DBG_ASSERT( Owner(), "must be owner" );
833 0 : if( m_pOwnStg )
834 : {
835 0 : m_pOwnStg->Remove( rEleName );
836 0 : SetError( m_pOwnStg->GetError() );
837 : }
838 : else
839 0 : SetError( SVSTREAM_GENERALERROR );
840 :
841 0 : return SVSTREAM_OK == GetError();
842 : }
843 :
844 0 : bool SotStorage::Rename( const OUString & rEleName, const OUString & rNewName )
845 : {
846 : DBG_ASSERT( Owner(), "must be owner" );
847 0 : if( m_pOwnStg )
848 : {
849 0 : m_pOwnStg->Rename( rEleName, rNewName );
850 0 : SetError( m_pOwnStg->GetError() );
851 : }
852 : else
853 0 : SetError( SVSTREAM_GENERALERROR );
854 :
855 0 : return SVSTREAM_OK == GetError();
856 : }
857 :
858 0 : bool SotStorage::CopyTo( const OUString & rEleName,
859 : SotStorage * pNewSt, const OUString & rNewName )
860 : {
861 : DBG_ASSERT( Owner(), "must be owner" );
862 : DBG_ASSERT( pNewSt->Owner(), "must be owner" );
863 0 : if( m_pOwnStg )
864 : {
865 0 : m_pOwnStg->CopyTo( rEleName, pNewSt->m_pOwnStg, rNewName );
866 0 : SetError( m_pOwnStg->GetError() );
867 0 : SetError( pNewSt->GetError() );
868 : }
869 : else
870 0 : SetError( SVSTREAM_GENERALERROR );
871 :
872 0 : return SVSTREAM_OK == GetError();
873 : }
874 :
875 0 : bool SotStorage::MoveTo( const OUString & rEleName,
876 : SotStorage * pNewSt, const OUString & rNewName )
877 : {
878 : DBG_ASSERT( Owner(), "must be owner" );
879 : DBG_ASSERT( pNewSt->Owner(), "must be owner" );
880 0 : if( m_pOwnStg )
881 : {
882 0 : m_pOwnStg->MoveTo( rEleName, pNewSt->m_pOwnStg, rNewName );
883 0 : SetError( m_pOwnStg->GetError() );
884 0 : SetError( pNewSt->GetError() );
885 : }
886 : else
887 0 : SetError( SVSTREAM_GENERALERROR );
888 :
889 0 : return SVSTREAM_OK == GetError();
890 : }
891 :
892 0 : bool SotStorage::Validate()
893 : {
894 : DBG_ASSERT( m_bIsRoot, "Validate nur an Rootstorage" );
895 0 : if( m_pOwnStg )
896 0 : return m_pOwnStg->ValidateFAT();
897 : else
898 0 : return true;
899 : }
900 :
901 0 : bool SotStorage::IsOLEStorage() const
902 : {
903 0 : UCBStorage* pStg = PTR_CAST( UCBStorage, m_pOwnStg );
904 0 : return !pStg;
905 : }
906 :
907 0 : bool SotStorage::IsOLEStorage( const OUString & rFileName )
908 : {
909 0 : return Storage::IsStorageFile( rFileName );
910 : }
911 :
912 0 : bool SotStorage::IsOLEStorage( SvStream* pStream )
913 : {
914 0 : return Storage::IsStorageFile( pStream );
915 : }
916 :
917 0 : SotStorage* SotStorage::OpenOLEStorage( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& xStorage,
918 : const OUString& rEleName, StreamMode nMode )
919 : {
920 0 : sal_Int32 nEleMode = embed::ElementModes::SEEKABLEREAD;
921 0 : if ( nMode & STREAM_WRITE )
922 0 : nEleMode |= embed::ElementModes::WRITE;
923 0 : if ( nMode & STREAM_TRUNC )
924 0 : nEleMode |= embed::ElementModes::TRUNCATE;
925 0 : if ( nMode & STREAM_NOCREATE )
926 0 : nEleMode |= embed::ElementModes::NOCREATE;
927 :
928 0 : SvStream* pStream = NULL;
929 : try
930 : {
931 0 : uno::Reference < io::XStream > xStream = xStorage->openStreamElement( rEleName, nEleMode );
932 :
933 : // TODO/LATER: should it be done this way?
934 0 : if ( nMode & STREAM_WRITE )
935 : {
936 0 : uno::Reference < beans::XPropertySet > xStreamProps( xStream, uno::UNO_QUERY_THROW );
937 0 : xStreamProps->setPropertyValue(
938 : OUString( "MediaType" ),
939 0 : uno::makeAny( OUString( "application/vnd.sun.star.oleobject" ) ) );
940 : }
941 :
942 0 : pStream = utl::UcbStreamHelper::CreateStream( xStream );
943 : }
944 0 : catch ( uno::Exception& )
945 : {
946 : //TODO/LATER: ErrorHandling
947 0 : pStream = new SvMemoryStream;
948 0 : pStream->SetError( ERRCODE_IO_GENERAL );
949 : }
950 :
951 0 : return new SotStorage( pStream, true );
952 : }
953 :
954 0 : sal_Int32 SotStorage::GetFormatID( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& xStorage )
955 : {
956 0 : uno::Reference< beans::XPropertySet > xProps( xStorage, uno::UNO_QUERY );
957 0 : if ( !xProps.is() )
958 0 : return 0;
959 :
960 0 : OUString aMediaType;
961 0 : xProps->getPropertyValue("MediaType") >>= aMediaType;
962 0 : if ( !aMediaType.isEmpty() )
963 : {
964 0 : ::com::sun::star::datatransfer::DataFlavor aDataFlavor;
965 0 : aDataFlavor.MimeType = aMediaType;
966 0 : return SotExchange::GetFormat( aDataFlavor );
967 : }
968 :
969 0 : return 0;
970 : }
971 :
972 0 : sal_Int32 SotStorage::GetVersion( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& xStorage )
973 : {
974 0 : sal_Int32 nSotFormatID = SotStorage::GetFormatID( xStorage );
975 0 : switch( nSotFormatID )
976 : {
977 : case SOT_FORMATSTR_ID_STARWRITER_8:
978 : case SOT_FORMATSTR_ID_STARWRITER_8_TEMPLATE:
979 : case SOT_FORMATSTR_ID_STARWRITERWEB_8:
980 : case SOT_FORMATSTR_ID_STARWRITERGLOB_8:
981 : case SOT_FORMATSTR_ID_STARDRAW_8:
982 : case SOT_FORMATSTR_ID_STARDRAW_8_TEMPLATE:
983 : case SOT_FORMATSTR_ID_STARIMPRESS_8:
984 : case SOT_FORMATSTR_ID_STARIMPRESS_8_TEMPLATE:
985 : case SOT_FORMATSTR_ID_STARCALC_8:
986 : case SOT_FORMATSTR_ID_STARCALC_8_TEMPLATE:
987 : case SOT_FORMATSTR_ID_STARCHART_8:
988 : case SOT_FORMATSTR_ID_STARCHART_8_TEMPLATE:
989 : case SOT_FORMATSTR_ID_STARMATH_8:
990 : case SOT_FORMATSTR_ID_STARMATH_8_TEMPLATE:
991 0 : return SOFFICE_FILEFORMAT_8;
992 : case SOT_FORMATSTR_ID_STARWRITER_60:
993 : case SOT_FORMATSTR_ID_STARWRITERWEB_60:
994 : case SOT_FORMATSTR_ID_STARWRITERGLOB_60:
995 : case SOT_FORMATSTR_ID_STARDRAW_60:
996 : case SOT_FORMATSTR_ID_STARIMPRESS_60:
997 : case SOT_FORMATSTR_ID_STARCALC_60:
998 : case SOT_FORMATSTR_ID_STARCHART_60:
999 : case SOT_FORMATSTR_ID_STARMATH_60:
1000 0 : return SOFFICE_FILEFORMAT_60;
1001 : }
1002 :
1003 0 : return 0;
1004 : }
1005 :
1006 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|