xref: /trunk/main/sot/source/sdstor/ucbstorage.cxx (revision 9204bf8294f34a46abdfeceee27c48e7b7b2ef12)
1046d9d1fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3046d9d1fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4046d9d1fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5046d9d1fSAndrew Rist  * distributed with this work for additional information
6046d9d1fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7046d9d1fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8046d9d1fSAndrew Rist  * "License"); you may not use this file except in compliance
9046d9d1fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11046d9d1fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13046d9d1fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14046d9d1fSAndrew Rist  * software distributed under the License is distributed on an
15046d9d1fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16046d9d1fSAndrew Rist  * KIND, either express or implied.  See the License for the
17046d9d1fSAndrew Rist  * specific language governing permissions and limitations
18046d9d1fSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20046d9d1fSAndrew Rist  *************************************************************/
21046d9d1fSAndrew Rist 
22046d9d1fSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sot.hxx"
26cdf0e10cSrcweir #include <com/sun/star/io/NotConnectedException.hpp>
27cdf0e10cSrcweir #include <com/sun/star/io/BufferSizeExceededException.hpp>
28cdf0e10cSrcweir #include <com/sun/star/uno/RuntimeException.hpp>
29cdf0e10cSrcweir #include <com/sun/star/lang/IllegalArgumentException.hpp>
30cdf0e10cSrcweir #include <ucbhelper/content.hxx>
31cdf0e10cSrcweir #include <com/sun/star/uno/Reference.h>
32cdf0e10cSrcweir #include <com/sun/star/ucb/XCommandEnvironment.hpp>
33cdf0e10cSrcweir #include <unotools/tempfile.hxx>
34cdf0e10cSrcweir #include <unotools/ucbstreamhelper.hxx>
35cdf0e10cSrcweir #include <com/sun/star/io/XInputStream.hpp>
36cdf0e10cSrcweir #include <com/sun/star/ucb/InsertCommandArgument.hpp>
37cdf0e10cSrcweir #include <com/sun/star/ucb/ResultSetException.hpp>
38cdf0e10cSrcweir #include <com/sun/star/uno/Sequence.h>
39cdf0e10cSrcweir #include <com/sun/star/sdbc/XResultSet.hdl>
40cdf0e10cSrcweir #include <com/sun/star/ucb/XContentAccess.hpp>
41cdf0e10cSrcweir #include <com/sun/star/sdbc/XRow.hpp>
42cdf0e10cSrcweir #include <com/sun/star/ucb/CommandAbortedException.hpp>
43cdf0e10cSrcweir #include <com/sun/star/datatransfer/DataFlavor.hpp>
44cdf0e10cSrcweir #include <com/sun/star/ucb/ContentInfo.hpp>
45cdf0e10cSrcweir #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
46cdf0e10cSrcweir #include <com/sun/star/beans/Property.hpp>
47cdf0e10cSrcweir #include <com/sun/star/packages/manifest/XManifestWriter.hpp>
48cdf0e10cSrcweir #include <com/sun/star/packages/manifest/XManifestReader.hpp>
49cdf0e10cSrcweir #include <com/sun/star/ucb/InteractiveIOException.hpp>
50cdf0e10cSrcweir 
51cdf0e10cSrcweir #include <rtl/digest.h>
52cdf0e10cSrcweir #include <tools/ref.hxx>
53cdf0e10cSrcweir #include <tools/debug.hxx>
54cdf0e10cSrcweir #include <unotools/streamhelper.hxx>
55cdf0e10cSrcweir #include <unotools/streamwrap.hxx>
56cdf0e10cSrcweir #include <unotools/ucbhelper.hxx>
57cdf0e10cSrcweir #include <unotools/localfilehelper.hxx>
58cdf0e10cSrcweir #include <tools/list.hxx>
59cdf0e10cSrcweir #include <tools/urlobj.hxx>
60cdf0e10cSrcweir #include <unotools/streamwrap.hxx>
61cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
62cdf0e10cSrcweir #include <cppuhelper/implbase2.hxx>
63cdf0e10cSrcweir #include <ucbhelper/commandenvironment.hxx>
64cdf0e10cSrcweir 
65cdf0e10cSrcweir #include "sot/stg.hxx"
66cdf0e10cSrcweir #include "sot/storinfo.hxx"
67cdf0e10cSrcweir #include <sot/storage.hxx>
68cdf0e10cSrcweir #include <sot/exchange.hxx>
69cdf0e10cSrcweir #include <sot/formats.hxx>
70cdf0e10cSrcweir #include "sot/clsids.hxx"
71cdf0e10cSrcweir 
72cdf0e10cSrcweir #include "unostorageholder.hxx"
73cdf0e10cSrcweir 
74cdf0e10cSrcweir using namespace ::com::sun::star::lang;
75cdf0e10cSrcweir using namespace ::com::sun::star::beans;
76cdf0e10cSrcweir using namespace ::com::sun::star::uno;
77cdf0e10cSrcweir using namespace ::com::sun::star::ucb;
78cdf0e10cSrcweir using namespace ::com::sun::star::io;
79cdf0e10cSrcweir using namespace ::com::sun::star::sdbc;
80cdf0e10cSrcweir using namespace ::ucbhelper;
81cdf0e10cSrcweir 
82cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
83cdf0e10cSrcweir #include <stdio.h>
84cdf0e10cSrcweir static int nOpenFiles=0;
85cdf0e10cSrcweir static int nOpenStreams=0;
86cdf0e10cSrcweir #endif
87cdf0e10cSrcweir 
88cdf0e10cSrcweir typedef ::cppu::WeakImplHelper2 < XInputStream, XSeekable > FileInputStreamWrapper_Base;
89cdf0e10cSrcweir class FileStreamWrapper_Impl : public FileInputStreamWrapper_Base
90cdf0e10cSrcweir {
91cdf0e10cSrcweir protected:
92cdf0e10cSrcweir     ::osl::Mutex    m_aMutex;
93cdf0e10cSrcweir     String          m_aURL;
94cdf0e10cSrcweir     SvStream*       m_pSvStream;
95cdf0e10cSrcweir 
96cdf0e10cSrcweir public:
97cdf0e10cSrcweir     FileStreamWrapper_Impl( const String& rName );
98cdf0e10cSrcweir     virtual ~FileStreamWrapper_Impl();
99cdf0e10cSrcweir 
100cdf0e10cSrcweir     //DECLARE_UNO3_AGG_DEFAULTS( FileStreamWrapper_Impl, FileInputStreamWrapper_Base);
101cdf0e10cSrcweir 
102cdf0e10cSrcweir     virtual void SAL_CALL seek( sal_Int64 _nLocation ) throw ( IllegalArgumentException, IOException, RuntimeException);
103cdf0e10cSrcweir     virtual sal_Int64 SAL_CALL getPosition(  ) throw ( IOException, RuntimeException);
104cdf0e10cSrcweir     virtual sal_Int64 SAL_CALL getLength(  ) throw ( IOException, RuntimeException);
105cdf0e10cSrcweir     virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead) throw( NotConnectedException, BufferSizeExceededException, RuntimeException );
106cdf0e10cSrcweir     virtual sal_Int32 SAL_CALL readSomeBytes( Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead) throw( NotConnectedException, BufferSizeExceededException, RuntimeException );
107cdf0e10cSrcweir     virtual void      SAL_CALL skipBytes(sal_Int32 nBytesToSkip) throw( NotConnectedException, BufferSizeExceededException, RuntimeException);
108cdf0e10cSrcweir     virtual sal_Int32 SAL_CALL available() throw( NotConnectedException, RuntimeException );
109cdf0e10cSrcweir     virtual void      SAL_CALL closeInput() throw( NotConnectedException, RuntimeException );
110cdf0e10cSrcweir 
111cdf0e10cSrcweir protected:
112cdf0e10cSrcweir     void checkConnected();
113cdf0e10cSrcweir     void checkError();
114cdf0e10cSrcweir };
115cdf0e10cSrcweir 
116cdf0e10cSrcweir //------------------------------------------------------------------
FileStreamWrapper_Impl(const String & rName)117cdf0e10cSrcweir FileStreamWrapper_Impl::FileStreamWrapper_Impl( const String& rName )
118cdf0e10cSrcweir     : m_aURL( rName )
119cdf0e10cSrcweir     , m_pSvStream(0)
120cdf0e10cSrcweir {
121cdf0e10cSrcweir     // if no URL is provided the stream is empty
122cdf0e10cSrcweir }
123cdf0e10cSrcweir 
124cdf0e10cSrcweir //------------------------------------------------------------------
~FileStreamWrapper_Impl()125cdf0e10cSrcweir FileStreamWrapper_Impl::~FileStreamWrapper_Impl()
126cdf0e10cSrcweir {
127cdf0e10cSrcweir     if ( m_pSvStream )
128cdf0e10cSrcweir     {
129cdf0e10cSrcweir         delete m_pSvStream;
130cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
131cdf0e10cSrcweir         --nOpenFiles;
132cdf0e10cSrcweir #endif
133cdf0e10cSrcweir     }
134cdf0e10cSrcweir 
135cdf0e10cSrcweir     if ( m_aURL.Len() )
136cdf0e10cSrcweir         ::utl::UCBContentHelper::Kill( m_aURL );
137cdf0e10cSrcweir }
138cdf0e10cSrcweir 
139cdf0e10cSrcweir //------------------------------------------------------------------------------
readBytes(Sequence<sal_Int8> & aData,sal_Int32 nBytesToRead)140cdf0e10cSrcweir sal_Int32 SAL_CALL FileStreamWrapper_Impl::readBytes(Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead)
141cdf0e10cSrcweir                 throw( NotConnectedException, BufferSizeExceededException, RuntimeException )
142cdf0e10cSrcweir {
143cdf0e10cSrcweir     if ( !m_aURL.Len() )
144cdf0e10cSrcweir     {
145cdf0e10cSrcweir         aData.realloc( 0 );
146cdf0e10cSrcweir         return 0;
147cdf0e10cSrcweir     }
148cdf0e10cSrcweir 
149cdf0e10cSrcweir     checkConnected();
150cdf0e10cSrcweir 
151cdf0e10cSrcweir     if (nBytesToRead < 0)
152cdf0e10cSrcweir         throw BufferSizeExceededException(::rtl::OUString(),static_cast<XWeak*>(this));
153cdf0e10cSrcweir 
154cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
155cdf0e10cSrcweir 
156cdf0e10cSrcweir     aData.realloc(nBytesToRead);
157cdf0e10cSrcweir 
158cdf0e10cSrcweir     sal_uInt32 nRead = m_pSvStream->Read((void*)aData.getArray(), nBytesToRead);
159cdf0e10cSrcweir     checkError();
160cdf0e10cSrcweir 
161cdf0e10cSrcweir     // Wenn gelesene Zeichen < MaxLength, Sequence anpassen
162cdf0e10cSrcweir     if (nRead < (sal_uInt32)nBytesToRead)
163cdf0e10cSrcweir         aData.realloc( nRead );
164cdf0e10cSrcweir 
165cdf0e10cSrcweir     return nRead;
166cdf0e10cSrcweir }
167cdf0e10cSrcweir 
168cdf0e10cSrcweir //------------------------------------------------------------------------------
readSomeBytes(Sequence<sal_Int8> & aData,sal_Int32 nMaxBytesToRead)169cdf0e10cSrcweir sal_Int32 SAL_CALL FileStreamWrapper_Impl::readSomeBytes(Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead) throw( NotConnectedException, BufferSizeExceededException, RuntimeException )
170cdf0e10cSrcweir {
171cdf0e10cSrcweir     if ( !m_aURL.Len() )
172cdf0e10cSrcweir     {
173cdf0e10cSrcweir         aData.realloc( 0 );
174cdf0e10cSrcweir         return 0;
175cdf0e10cSrcweir     }
176cdf0e10cSrcweir 
177cdf0e10cSrcweir     checkError();
178cdf0e10cSrcweir 
179cdf0e10cSrcweir     if (nMaxBytesToRead < 0)
180cdf0e10cSrcweir         throw BufferSizeExceededException(::rtl::OUString(),static_cast<XWeak*>(this));
181cdf0e10cSrcweir 
182cdf0e10cSrcweir     if (m_pSvStream->IsEof())
183cdf0e10cSrcweir     {
184cdf0e10cSrcweir         aData.realloc(0);
185cdf0e10cSrcweir         return 0;
186cdf0e10cSrcweir     }
187cdf0e10cSrcweir     else
188cdf0e10cSrcweir         return readBytes(aData, nMaxBytesToRead);
189cdf0e10cSrcweir }
190cdf0e10cSrcweir 
191cdf0e10cSrcweir //------------------------------------------------------------------------------
skipBytes(sal_Int32 nBytesToSkip)192cdf0e10cSrcweir void SAL_CALL FileStreamWrapper_Impl::skipBytes(sal_Int32 nBytesToSkip) throw( NotConnectedException, BufferSizeExceededException, RuntimeException )
193cdf0e10cSrcweir {
194cdf0e10cSrcweir     if ( !m_aURL.Len() )
195cdf0e10cSrcweir         return;
196cdf0e10cSrcweir 
197cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
198cdf0e10cSrcweir     checkError();
199cdf0e10cSrcweir 
200cdf0e10cSrcweir #ifdef DBG_UTIL
201cdf0e10cSrcweir     sal_uInt32 nCurrentPos = m_pSvStream->Tell();
202cdf0e10cSrcweir #endif
203cdf0e10cSrcweir 
204cdf0e10cSrcweir     m_pSvStream->SeekRel(nBytesToSkip);
205cdf0e10cSrcweir     checkError();
206cdf0e10cSrcweir 
207cdf0e10cSrcweir #ifdef DBG_UTIL
208cdf0e10cSrcweir     nCurrentPos = m_pSvStream->Tell();
209cdf0e10cSrcweir #endif
210cdf0e10cSrcweir }
211cdf0e10cSrcweir 
212cdf0e10cSrcweir //------------------------------------------------------------------------------
available()213cdf0e10cSrcweir sal_Int32 SAL_CALL FileStreamWrapper_Impl::available() throw( NotConnectedException, RuntimeException )
214cdf0e10cSrcweir {
215cdf0e10cSrcweir     if ( !m_aURL.Len() )
216cdf0e10cSrcweir         return 0;
217cdf0e10cSrcweir 
218cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
219cdf0e10cSrcweir     checkConnected();
220cdf0e10cSrcweir 
221cdf0e10cSrcweir     sal_uInt32 nPos = m_pSvStream->Tell();
222cdf0e10cSrcweir     checkError();
223cdf0e10cSrcweir 
224cdf0e10cSrcweir     m_pSvStream->Seek(STREAM_SEEK_TO_END);
225cdf0e10cSrcweir     checkError();
226cdf0e10cSrcweir 
227cdf0e10cSrcweir     sal_Int32 nAvailable = (sal_Int32)m_pSvStream->Tell() - nPos;
228cdf0e10cSrcweir     m_pSvStream->Seek(nPos);
229cdf0e10cSrcweir     checkError();
230cdf0e10cSrcweir 
231cdf0e10cSrcweir     return nAvailable;
232cdf0e10cSrcweir }
233cdf0e10cSrcweir 
234cdf0e10cSrcweir //------------------------------------------------------------------------------
closeInput()235cdf0e10cSrcweir void SAL_CALL FileStreamWrapper_Impl::closeInput() throw( NotConnectedException, RuntimeException )
236cdf0e10cSrcweir {
237cdf0e10cSrcweir     if ( !m_aURL.Len() )
238cdf0e10cSrcweir         return;
239cdf0e10cSrcweir 
240cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
241cdf0e10cSrcweir     checkConnected();
242cdf0e10cSrcweir     DELETEZ( m_pSvStream );
243cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
244cdf0e10cSrcweir     --nOpenFiles;
245cdf0e10cSrcweir #endif
246cdf0e10cSrcweir     ::utl::UCBContentHelper::Kill( m_aURL );
247cdf0e10cSrcweir     m_aURL.Erase();
248cdf0e10cSrcweir }
249cdf0e10cSrcweir 
250cdf0e10cSrcweir //------------------------------------------------------------------------------
seek(sal_Int64 _nLocation)251cdf0e10cSrcweir void SAL_CALL FileStreamWrapper_Impl::seek( sal_Int64 _nLocation ) throw (IllegalArgumentException, IOException, RuntimeException)
252cdf0e10cSrcweir {
253cdf0e10cSrcweir     if ( !m_aURL.Len() )
254cdf0e10cSrcweir         return;
255cdf0e10cSrcweir 
256cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
257cdf0e10cSrcweir     checkConnected();
258cdf0e10cSrcweir 
259cdf0e10cSrcweir     m_pSvStream->Seek((sal_uInt32)_nLocation);
260cdf0e10cSrcweir     checkError();
261cdf0e10cSrcweir }
262cdf0e10cSrcweir 
263cdf0e10cSrcweir //------------------------------------------------------------------------------
getPosition()264cdf0e10cSrcweir sal_Int64 SAL_CALL FileStreamWrapper_Impl::getPosition(  ) throw (IOException, RuntimeException)
265cdf0e10cSrcweir {
266cdf0e10cSrcweir     if ( !m_aURL.Len() )
267cdf0e10cSrcweir         return 0;
268cdf0e10cSrcweir 
269cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
270cdf0e10cSrcweir     checkConnected();
271cdf0e10cSrcweir 
272cdf0e10cSrcweir     sal_uInt32 nPos = m_pSvStream->Tell();
273cdf0e10cSrcweir     checkError();
274cdf0e10cSrcweir     return (sal_Int64)nPos;
275cdf0e10cSrcweir }
276cdf0e10cSrcweir 
277cdf0e10cSrcweir //------------------------------------------------------------------------------
getLength()278cdf0e10cSrcweir sal_Int64 SAL_CALL FileStreamWrapper_Impl::getLength(  ) throw (IOException, RuntimeException)
279cdf0e10cSrcweir {
280cdf0e10cSrcweir     if ( !m_aURL.Len() )
281cdf0e10cSrcweir         return 0;
282cdf0e10cSrcweir 
283cdf0e10cSrcweir     ::osl::MutexGuard aGuard( m_aMutex );
284cdf0e10cSrcweir     checkConnected();
285cdf0e10cSrcweir 
286cdf0e10cSrcweir     sal_uInt32 nCurrentPos = m_pSvStream->Tell();
287cdf0e10cSrcweir     checkError();
288cdf0e10cSrcweir 
289cdf0e10cSrcweir     m_pSvStream->Seek(STREAM_SEEK_TO_END);
290cdf0e10cSrcweir     sal_uInt32 nEndPos = m_pSvStream->Tell();
291cdf0e10cSrcweir     m_pSvStream->Seek(nCurrentPos);
292cdf0e10cSrcweir 
293cdf0e10cSrcweir     checkError();
294cdf0e10cSrcweir 
295cdf0e10cSrcweir     return (sal_Int64)nEndPos;
296cdf0e10cSrcweir }
297cdf0e10cSrcweir 
298cdf0e10cSrcweir //------------------------------------------------------------------------------
checkConnected()299cdf0e10cSrcweir void FileStreamWrapper_Impl::checkConnected()
300cdf0e10cSrcweir {
301cdf0e10cSrcweir     if ( !m_aURL.Len() )
302cdf0e10cSrcweir         throw NotConnectedException(::rtl::OUString(), const_cast<XWeak*>(static_cast<const XWeak*>(this)));
303cdf0e10cSrcweir     if ( !m_pSvStream )
304cdf0e10cSrcweir     {
305cdf0e10cSrcweir         m_pSvStream = ::utl::UcbStreamHelper::CreateStream( m_aURL, STREAM_STD_READ );
306cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
307cdf0e10cSrcweir         ++nOpenFiles;
308cdf0e10cSrcweir #endif
309cdf0e10cSrcweir     }
310cdf0e10cSrcweir }
311cdf0e10cSrcweir 
312cdf0e10cSrcweir //------------------------------------------------------------------------------
checkError()313cdf0e10cSrcweir void FileStreamWrapper_Impl::checkError()
314cdf0e10cSrcweir {
315cdf0e10cSrcweir     checkConnected();
316cdf0e10cSrcweir 
317cdf0e10cSrcweir     if (m_pSvStream->SvStream::GetError() != ERRCODE_NONE)
318cdf0e10cSrcweir         // TODO: really evaluate the error
319cdf0e10cSrcweir         throw NotConnectedException(::rtl::OUString(), const_cast<XWeak*>(static_cast<const XWeak*>(this)));
320cdf0e10cSrcweir }
321cdf0e10cSrcweir 
322cdf0e10cSrcweir TYPEINIT1( UCBStorageStream, BaseStorageStream );
323cdf0e10cSrcweir TYPEINIT1( UCBStorage, BaseStorage );
324cdf0e10cSrcweir 
325cdf0e10cSrcweir #define COMMIT_RESULT_FAILURE           0
326cdf0e10cSrcweir #define COMMIT_RESULT_NOTHING_TO_DO     1
327cdf0e10cSrcweir #define COMMIT_RESULT_SUCCESS           2
328cdf0e10cSrcweir 
329cdf0e10cSrcweir #define min( x, y ) (( x < y ) ? x : y)
330cdf0e10cSrcweir #define max( x, y ) (( x > y ) ? x : y)
331cdf0e10cSrcweir 
GetFormatId_Impl(SvGlobalName aName)332cdf0e10cSrcweir sal_Int32 GetFormatId_Impl( SvGlobalName aName )
333cdf0e10cSrcweir {
334cdf0e10cSrcweir //    if ( aName == SvGlobalName( SO3_SW_CLASSID_8 ) )
335cdf0e10cSrcweir //        return SOT_FORMATSTR_ID_STARWRITER_8;
336cdf0e10cSrcweir //    if ( aName == SvGlobalName( SO3_SWWEB_CLASSID_8 ) )
337cdf0e10cSrcweir //        return SOT_FORMATSTR_ID_STARWRITERWEB_8;
338cdf0e10cSrcweir //    if ( aName == SvGlobalName( SO3_SWGLOB_CLASSID_8 ) )
339cdf0e10cSrcweir //        return SOT_FORMATSTR_ID_STARWRITERGLOB_8;
340cdf0e10cSrcweir //    if ( aName == SvGlobalName( SO3_SDRAW_CLASSID_8 ) )
341cdf0e10cSrcweir //        return SOT_FORMATSTR_ID_STARDRAW_8;
342cdf0e10cSrcweir //    if ( aName == SvGlobalName( SO3_SIMPRESS_CLASSID_8 ) )
343cdf0e10cSrcweir //        return SOT_FORMATSTR_ID_STARIMPRESS_8;
344cdf0e10cSrcweir //    if ( aName == SvGlobalName( SO3_SC_CLASSID_8 ) )
345cdf0e10cSrcweir //        return SOT_FORMATSTR_ID_STARCALC_8;
346cdf0e10cSrcweir //    if ( aName == SvGlobalName( SO3_SCH_CLASSID_8 ) )
347cdf0e10cSrcweir //        return SOT_FORMATSTR_ID_STARCHART_8;
348cdf0e10cSrcweir //    if ( aName == SvGlobalName( SO3_SM_CLASSID_8 ) )
349cdf0e10cSrcweir //        return SOT_FORMATSTR_ID_STARMATH_8;
350cdf0e10cSrcweir     if ( aName == SvGlobalName( SO3_SW_CLASSID_60 ) )
351cdf0e10cSrcweir         return SOT_FORMATSTR_ID_STARWRITER_60;
352cdf0e10cSrcweir     if ( aName == SvGlobalName( SO3_SWWEB_CLASSID_60 ) )
353cdf0e10cSrcweir         return SOT_FORMATSTR_ID_STARWRITERWEB_60;
354cdf0e10cSrcweir     if ( aName == SvGlobalName( SO3_SWGLOB_CLASSID_60 ) )
355cdf0e10cSrcweir         return SOT_FORMATSTR_ID_STARWRITERGLOB_60;
356cdf0e10cSrcweir     if ( aName == SvGlobalName( SO3_SDRAW_CLASSID_60 ) )
357cdf0e10cSrcweir         return SOT_FORMATSTR_ID_STARDRAW_60;
358cdf0e10cSrcweir     if ( aName == SvGlobalName( SO3_SIMPRESS_CLASSID_60 ) )
359cdf0e10cSrcweir         return SOT_FORMATSTR_ID_STARIMPRESS_60;
360cdf0e10cSrcweir     if ( aName == SvGlobalName( SO3_SC_CLASSID_60 ) )
361cdf0e10cSrcweir         return SOT_FORMATSTR_ID_STARCALC_60;
362cdf0e10cSrcweir     if ( aName == SvGlobalName( SO3_SCH_CLASSID_60 ) )
363cdf0e10cSrcweir         return SOT_FORMATSTR_ID_STARCHART_60;
364cdf0e10cSrcweir     if ( aName == SvGlobalName( SO3_SM_CLASSID_60 ) )
365cdf0e10cSrcweir         return SOT_FORMATSTR_ID_STARMATH_60;
366cdf0e10cSrcweir     if ( aName == SvGlobalName( SO3_OUT_CLASSID ) ||
367cdf0e10cSrcweir          aName == SvGlobalName( SO3_APPLET_CLASSID ) ||
368cdf0e10cSrcweir          aName == SvGlobalName( SO3_PLUGIN_CLASSID ) ||
369cdf0e10cSrcweir          aName == SvGlobalName( SO3_IFRAME_CLASSID ) )
370cdf0e10cSrcweir         // allowed, but not supported
371cdf0e10cSrcweir         return 0;
372cdf0e10cSrcweir     else
373cdf0e10cSrcweir     {
374cdf0e10cSrcweir         DBG_ERROR( "Unknown UCB storage format!" );
375cdf0e10cSrcweir         return 0;
376cdf0e10cSrcweir     }
377cdf0e10cSrcweir }
378cdf0e10cSrcweir 
379cdf0e10cSrcweir 
GetClassId_Impl(sal_Int32 nFormat)380cdf0e10cSrcweir SvGlobalName GetClassId_Impl( sal_Int32 nFormat )
381cdf0e10cSrcweir {
382cdf0e10cSrcweir     switch ( nFormat )
383cdf0e10cSrcweir     {
384cdf0e10cSrcweir         case SOT_FORMATSTR_ID_STARWRITER_8 :
385cdf0e10cSrcweir         case SOT_FORMATSTR_ID_STARWRITER_8_TEMPLATE :
386cdf0e10cSrcweir             return SvGlobalName( SO3_SW_CLASSID_60 );
387cdf0e10cSrcweir         case SOT_FORMATSTR_ID_STARWRITERWEB_8 :
388cdf0e10cSrcweir             return SvGlobalName( SO3_SWWEB_CLASSID_60 );
389cdf0e10cSrcweir         case SOT_FORMATSTR_ID_STARWRITERGLOB_8 :
390cdf0e10cSrcweir             return SvGlobalName( SO3_SWGLOB_CLASSID_60 );
391cdf0e10cSrcweir         case SOT_FORMATSTR_ID_STARDRAW_8 :
392cdf0e10cSrcweir         case SOT_FORMATSTR_ID_STARDRAW_8_TEMPLATE :
393cdf0e10cSrcweir             return SvGlobalName( SO3_SDRAW_CLASSID_60 );
394cdf0e10cSrcweir         case SOT_FORMATSTR_ID_STARIMPRESS_8 :
395cdf0e10cSrcweir         case SOT_FORMATSTR_ID_STARIMPRESS_8_TEMPLATE :
396cdf0e10cSrcweir             return SvGlobalName( SO3_SIMPRESS_CLASSID_60 );
397cdf0e10cSrcweir         case SOT_FORMATSTR_ID_STARCALC_8 :
398cdf0e10cSrcweir         case SOT_FORMATSTR_ID_STARCALC_8_TEMPLATE :
399cdf0e10cSrcweir             return SvGlobalName( SO3_SC_CLASSID_60 );
400cdf0e10cSrcweir         case SOT_FORMATSTR_ID_STARCHART_8 :
401cdf0e10cSrcweir         case SOT_FORMATSTR_ID_STARCHART_8_TEMPLATE :
402cdf0e10cSrcweir             return SvGlobalName( SO3_SCH_CLASSID_60 );
403cdf0e10cSrcweir         case SOT_FORMATSTR_ID_STARMATH_8 :
404cdf0e10cSrcweir         case SOT_FORMATSTR_ID_STARMATH_8_TEMPLATE :
405cdf0e10cSrcweir             return SvGlobalName( SO3_SM_CLASSID_60 );
406cdf0e10cSrcweir         case SOT_FORMATSTR_ID_STARWRITER_60 :
407cdf0e10cSrcweir             return SvGlobalName( SO3_SW_CLASSID_60 );
408cdf0e10cSrcweir         case SOT_FORMATSTR_ID_STARWRITERWEB_60 :
409cdf0e10cSrcweir             return SvGlobalName( SO3_SWWEB_CLASSID_60 );
410cdf0e10cSrcweir         case SOT_FORMATSTR_ID_STARWRITERGLOB_60 :
411cdf0e10cSrcweir             return SvGlobalName( SO3_SWGLOB_CLASSID_60 );
412cdf0e10cSrcweir         case SOT_FORMATSTR_ID_STARDRAW_60 :
413cdf0e10cSrcweir             return SvGlobalName( SO3_SDRAW_CLASSID_60 );
414cdf0e10cSrcweir         case SOT_FORMATSTR_ID_STARIMPRESS_60 :
415cdf0e10cSrcweir             return SvGlobalName( SO3_SIMPRESS_CLASSID_60 );
416cdf0e10cSrcweir         case SOT_FORMATSTR_ID_STARCALC_60 :
417cdf0e10cSrcweir             return SvGlobalName( SO3_SC_CLASSID_60 );
418cdf0e10cSrcweir         case SOT_FORMATSTR_ID_STARCHART_60 :
419cdf0e10cSrcweir             return SvGlobalName( SO3_SCH_CLASSID_60 );
420cdf0e10cSrcweir         case SOT_FORMATSTR_ID_STARMATH_60 :
421cdf0e10cSrcweir             return SvGlobalName( SO3_SM_CLASSID_60 );
422cdf0e10cSrcweir         default :
423cdf0e10cSrcweir             //DBG_ERROR( "Unknown UCB storage format!" );
424cdf0e10cSrcweir             return SvGlobalName();
425cdf0e10cSrcweir     }
426cdf0e10cSrcweir }
427cdf0e10cSrcweir 
428cdf0e10cSrcweir // All storage and streams are refcounted internally; outside of this classes they are only accessible through a handle
429cdf0e10cSrcweir // class, that uses the refcounted object as impl-class.
430cdf0e10cSrcweir 
431cdf0e10cSrcweir enum RepresentModes {
432cdf0e10cSrcweir         nonset,
433cdf0e10cSrcweir         svstream,
434cdf0e10cSrcweir         xinputstream
435cdf0e10cSrcweir };
436cdf0e10cSrcweir 
437cdf0e10cSrcweir class UCBStorageStream_Impl : public SvRefBase, public SvStream
438cdf0e10cSrcweir {
439cdf0e10cSrcweir                                 ~UCBStorageStream_Impl();
440cdf0e10cSrcweir public:
441cdf0e10cSrcweir 
442cdf0e10cSrcweir     virtual sal_uLong               GetData( void* pData, sal_uLong nSize );
443cdf0e10cSrcweir     virtual sal_uLong               PutData( const void* pData, sal_uLong nSize );
444cdf0e10cSrcweir     virtual sal_uLong               SeekPos( sal_uLong nPos );
445cdf0e10cSrcweir     virtual void                SetSize( sal_uLong nSize );
446cdf0e10cSrcweir     virtual void                FlushData();
447cdf0e10cSrcweir     virtual void                ResetError();
448cdf0e10cSrcweir 
449cdf0e10cSrcweir     UCBStorageStream*           m_pAntiImpl;    // only valid if an external reference exists
450cdf0e10cSrcweir 
451cdf0e10cSrcweir     String                      m_aOriginalName;// the original name before accessing the stream
452cdf0e10cSrcweir     String                      m_aName;        // the actual name ( changed with a Rename command at the parent )
453cdf0e10cSrcweir     String                      m_aURL;         // the full path name to create the content
454cdf0e10cSrcweir     String                      m_aContentType;
455cdf0e10cSrcweir     String                      m_aOriginalContentType;
456cdf0e10cSrcweir     ByteString                  m_aKey;
457cdf0e10cSrcweir     ::ucbhelper::Content*       m_pContent;     // the content that provides the data
458cdf0e10cSrcweir     Reference<XInputStream>     m_rSource;      // the stream covering the original data of the content
459cdf0e10cSrcweir     SvStream*                   m_pStream;      // the stream worked on; for readonly streams it is the original stream of the content
460cdf0e10cSrcweir                                                 // for read/write streams it's a copy into a temporary file
461cdf0e10cSrcweir     String                      m_aTempURL;     // URL of this temporary stream
462cdf0e10cSrcweir     RepresentModes              m_nRepresentMode; // should it be used as XInputStream or as SvStream
463cdf0e10cSrcweir     long                        m_nError;
464cdf0e10cSrcweir     StreamMode                  m_nMode;        // open mode ( read/write/trunc/nocreate/sharing )
465cdf0e10cSrcweir     sal_Bool                        m_bSourceRead;  // Source still contains useful information
466cdf0e10cSrcweir     sal_Bool                        m_bModified;    // only modified streams will be sent to the original content
467cdf0e10cSrcweir     sal_Bool                        m_bCommited;    // sending the streams is coordinated by the root storage of the package
468cdf0e10cSrcweir     sal_Bool                        m_bDirect;      // the storage and its streams are opened in direct mode; for UCBStorages
469cdf0e10cSrcweir                                                 // this means that the root storage does an autocommit when its external
470cdf0e10cSrcweir                                                 // reference is destroyed
471cdf0e10cSrcweir     sal_Bool                        m_bIsOLEStorage;// an OLEStorage on a UCBStorageStream makes this an Autocommit-stream
472cdf0e10cSrcweir 
473cdf0e10cSrcweir                                 UCBStorageStream_Impl( const String&, StreamMode, UCBStorageStream*, sal_Bool, const ByteString* pKey=0, sal_Bool bRepair = sal_False, Reference< XProgressHandler > xProgress = Reference< XProgressHandler >() );
474cdf0e10cSrcweir 
475cdf0e10cSrcweir     void                        Free();
476cdf0e10cSrcweir     sal_Bool                        Init();
477cdf0e10cSrcweir     sal_Bool                        Clear();
478*ecbfceb0Smseidel     sal_Int16                   Commit();       // if modified and committed: transfer an XInputStream to the content
479cdf0e10cSrcweir     sal_Bool                        Revert();       // discard all changes
480cdf0e10cSrcweir     BaseStorage*                CreateStorage();// create an OLE Storage on the UCBStorageStream
481cdf0e10cSrcweir     sal_uLong                       GetSize();
482cdf0e10cSrcweir 
483cdf0e10cSrcweir     sal_uLong                       ReadSourceWriteTemporary( sal_uLong aLength ); // read aLength from source and copy to temporary,
484cdf0e10cSrcweir                                                                            // no seeking is produced
485cdf0e10cSrcweir     sal_uLong                       ReadSourceWriteTemporary();                // read source till the end and copy to temporary,
486cdf0e10cSrcweir                                                                            // no seeking is produced
487cdf0e10cSrcweir #if 0
488cdf0e10cSrcweir     sal_uLong                       CopySourceToTemporary( sal_uLong aLength ); // same as ReadSourceWriteToTemporary( aLength )
489cdf0e10cSrcweir                                                                         // but the writing is done at the end of temporary
490cdf0e10cSrcweir                                                                         // pointer position is not changed
491cdf0e10cSrcweir #endif
492cdf0e10cSrcweir 
493cdf0e10cSrcweir     sal_uLong                       CopySourceToTemporary();                // same as ReadSourceWriteToTemporary()
494cdf0e10cSrcweir                                                                         // but the writing is done at the end of temporary
495cdf0e10cSrcweir                                                                         // pointer position is not changed
496cdf0e10cSrcweir     Reference<XInputStream>     GetXInputStream();                      // return XInputStream, after that
497cdf0e10cSrcweir                                                                         // this class is close to be unusable
498cdf0e10cSrcweir                                                                         // since it can not read and write
499cdf0e10cSrcweir     using SvStream::SetError;
500cdf0e10cSrcweir     void                        SetError( sal_uInt32 nError );
501cdf0e10cSrcweir     void                        PrepareCachedForReopen( StreamMode nMode );
502cdf0e10cSrcweir };
503cdf0e10cSrcweir 
504cdf0e10cSrcweir SV_DECL_IMPL_REF( UCBStorageStream_Impl );
505cdf0e10cSrcweir 
506cdf0e10cSrcweir struct UCBStorageElement_Impl;
507cdf0e10cSrcweir DECLARE_LIST( UCBStorageElementList_Impl, UCBStorageElement_Impl* )
508cdf0e10cSrcweir 
509cdf0e10cSrcweir class UCBStorage_Impl : public SvRefBase
510cdf0e10cSrcweir {
511cdf0e10cSrcweir                                 ~UCBStorage_Impl();
512cdf0e10cSrcweir public:
513cdf0e10cSrcweir     UCBStorage*                 m_pAntiImpl;    // only valid if external references exists
514cdf0e10cSrcweir 
515cdf0e10cSrcweir     String                      m_aOriginalName;// the original name before accessing the storage
516cdf0e10cSrcweir     String                      m_aName;        // the actual name ( changed with a Rename command at the parent )
517cdf0e10cSrcweir     String                      m_aURL;         // the full path name to create the content
518cdf0e10cSrcweir     String                      m_aContentType;
519cdf0e10cSrcweir     String                      m_aOriginalContentType;
520cdf0e10cSrcweir     ::ucbhelper::Content*       m_pContent;     // the content that provides the storage elements
521cdf0e10cSrcweir     ::utl::TempFile*            m_pTempFile;    // temporary file, only for storages on stream
522cdf0e10cSrcweir     SvStream*                   m_pSource;      // original stream, only for storages on a stream
523cdf0e10cSrcweir     //SvStream*                   m_pStream;      // the corresponding editable stream, only for storage on a stream
524cdf0e10cSrcweir     long                        m_nError;
525cdf0e10cSrcweir     StreamMode                  m_nMode;        // open mode ( read/write/trunc/nocreate/sharing )
526cdf0e10cSrcweir     sal_Bool                        m_bModified;    // only modified elements will be sent to the original content
527cdf0e10cSrcweir     sal_Bool                        m_bCommited;    // sending the streams is coordinated by the root storage of the package
528cdf0e10cSrcweir     sal_Bool                        m_bDirect;      // the storage and its streams are opened in direct mode; for UCBStorages
529cdf0e10cSrcweir                                                 // this means that the root storage does an autocommit when its external
530cdf0e10cSrcweir                                                 // reference is destroyed
531*ecbfceb0Smseidel     sal_Bool                        m_bIsRoot;      // marks this storage as root storages that manages all commits and reverts
532cdf0e10cSrcweir     sal_Bool                        m_bDirty;           // ???
533cdf0e10cSrcweir     sal_Bool                        m_bIsLinked;
534cdf0e10cSrcweir     sal_Bool                        m_bListCreated;
535cdf0e10cSrcweir     sal_uLong                       m_nFormat;
536cdf0e10cSrcweir     String                      m_aUserTypeName;
537cdf0e10cSrcweir     SvGlobalName                m_aClassId;
538cdf0e10cSrcweir 
539cdf0e10cSrcweir     UCBStorageElementList_Impl  m_aChildrenList;
540cdf0e10cSrcweir 
541cdf0e10cSrcweir     sal_Bool                        m_bRepairPackage;
542cdf0e10cSrcweir     Reference< XProgressHandler > m_xProgressHandler;
543cdf0e10cSrcweir 
544cdf0e10cSrcweir     UNOStorageHolderList*       m_pUNOStorageHolderList;
545cdf0e10cSrcweir                                 UCBStorage_Impl( const ::ucbhelper::Content&, const String&, StreamMode, UCBStorage*, sal_Bool, sal_Bool, sal_Bool = sal_False, Reference< XProgressHandler > = Reference< XProgressHandler >() );
546cdf0e10cSrcweir                                 UCBStorage_Impl( const String&, StreamMode, UCBStorage*, sal_Bool, sal_Bool, sal_Bool = sal_False, Reference< XProgressHandler > = Reference< XProgressHandler >() );
547cdf0e10cSrcweir                                 UCBStorage_Impl( SvStream&, UCBStorage*, sal_Bool );
548cdf0e10cSrcweir     void                        Init();
549cdf0e10cSrcweir     sal_Int16                   Commit();
550cdf0e10cSrcweir     sal_Bool                        Revert();
551cdf0e10cSrcweir     sal_Bool                        Insert( ::ucbhelper::Content *pContent );
552cdf0e10cSrcweir     UCBStorage_Impl*            OpenStorage( UCBStorageElement_Impl* pElement, StreamMode nMode, sal_Bool bDirect );
553cdf0e10cSrcweir     UCBStorageStream_Impl*      OpenStream( UCBStorageElement_Impl*, StreamMode, sal_Bool, const ByteString* pKey=0 );
554cdf0e10cSrcweir     void                        SetProps( const Sequence < Sequence < PropertyValue > >& rSequence, const String& );
555cdf0e10cSrcweir     void                        GetProps( sal_Int32&, Sequence < Sequence < PropertyValue > >& rSequence, const String& );
556cdf0e10cSrcweir     sal_Int32                   GetObjectCount();
557cdf0e10cSrcweir     void                        ReadContent();
558cdf0e10cSrcweir     void                        CreateContent();
GetContent()559cdf0e10cSrcweir     ::ucbhelper::Content*       GetContent()
560cdf0e10cSrcweir                                 { if ( !m_pContent ) CreateContent(); return m_pContent; }
GetChildrenList()561cdf0e10cSrcweir     UCBStorageElementList_Impl& GetChildrenList()
562cdf0e10cSrcweir                                 {
563cdf0e10cSrcweir                                   long nError = m_nError;
564cdf0e10cSrcweir                                   ReadContent();
565cdf0e10cSrcweir                                   if ( m_nMode & STREAM_WRITE )
566cdf0e10cSrcweir                                   {
567cdf0e10cSrcweir                                     m_nError = nError;
568cdf0e10cSrcweir                                     if ( m_pAntiImpl )
569cdf0e10cSrcweir                                     {
570cdf0e10cSrcweir                                         m_pAntiImpl->ResetError();
571cdf0e10cSrcweir                                         m_pAntiImpl->SetError( nError );
572cdf0e10cSrcweir                                     }
573cdf0e10cSrcweir                                   }
574cdf0e10cSrcweir 
575cdf0e10cSrcweir                                   return m_aChildrenList;
576cdf0e10cSrcweir                                 }
577cdf0e10cSrcweir 
578cdf0e10cSrcweir     void                        SetError( long nError );
579cdf0e10cSrcweir };
580cdf0e10cSrcweir 
581cdf0e10cSrcweir SV_DECL_IMPL_REF( UCBStorage_Impl );
582cdf0e10cSrcweir 
58386e1cf34SPedro Giffuni // this struct contains all necessary information on an element inside a UCBStorage
584cdf0e10cSrcweir struct UCBStorageElement_Impl
585cdf0e10cSrcweir {
586cdf0e10cSrcweir     String                      m_aName;        // the actual URL relative to the root "folder"
587cdf0e10cSrcweir     String                      m_aOriginalName;// the original name in the content
588cdf0e10cSrcweir     sal_uLong                       m_nSize;
589cdf0e10cSrcweir     sal_Bool                        m_bIsFolder;    // Only sal_True when it is a UCBStorage !
590cdf0e10cSrcweir     sal_Bool                        m_bIsStorage;   // Also sal_True when it is an OLEStorage !
591cdf0e10cSrcweir     sal_Bool                        m_bIsRemoved;   // element will be removed on commit
592cdf0e10cSrcweir     sal_Bool                        m_bIsInserted;  // element will be removed on revert
593cdf0e10cSrcweir     UCBStorage_ImplRef          m_xStorage;     // reference to the "real" storage
594cdf0e10cSrcweir     UCBStorageStream_ImplRef    m_xStream;      // reference to the "real" stream
595cdf0e10cSrcweir 
UCBStorageElement_ImplUCBStorageElement_Impl596cdf0e10cSrcweir                                 UCBStorageElement_Impl( const ::rtl::OUString& rName,
597cdf0e10cSrcweir                                             sal_Bool bIsFolder = sal_False, sal_uLong nSize = 0 )
598cdf0e10cSrcweir                                     : m_aName( rName )
599cdf0e10cSrcweir                                     , m_aOriginalName( rName )
600cdf0e10cSrcweir                                     , m_nSize( nSize )
601cdf0e10cSrcweir                                     , m_bIsFolder( bIsFolder )
602cdf0e10cSrcweir                                     , m_bIsStorage( bIsFolder )
603cdf0e10cSrcweir                                     , m_bIsRemoved( sal_False )
604cdf0e10cSrcweir                                     , m_bIsInserted( sal_False )
605cdf0e10cSrcweir                                 {
606cdf0e10cSrcweir                                 }
607cdf0e10cSrcweir 
608cdf0e10cSrcweir     ::ucbhelper::Content*       GetContent();
609cdf0e10cSrcweir     sal_Bool                        IsModified();
610cdf0e10cSrcweir     String                      GetContentType();
611cdf0e10cSrcweir     void                        SetContentType( const String& );
612cdf0e10cSrcweir     String                      GetOriginalContentType();
IsLoadedUCBStorageElement_Impl613cdf0e10cSrcweir     sal_Bool                        IsLoaded()
614cdf0e10cSrcweir                                 { return m_xStream.Is() || m_xStorage.Is(); }
615cdf0e10cSrcweir };
616cdf0e10cSrcweir 
GetContent()617cdf0e10cSrcweir ::ucbhelper::Content* UCBStorageElement_Impl::GetContent()
618cdf0e10cSrcweir {
619cdf0e10cSrcweir     if ( m_xStream.Is() )
620cdf0e10cSrcweir         return m_xStream->m_pContent;
621cdf0e10cSrcweir     else if ( m_xStorage.Is() )
622cdf0e10cSrcweir         return m_xStorage->GetContent();
623cdf0e10cSrcweir     else
624cdf0e10cSrcweir         return NULL;
625cdf0e10cSrcweir }
626cdf0e10cSrcweir 
GetContentType()627cdf0e10cSrcweir String UCBStorageElement_Impl::GetContentType()
628cdf0e10cSrcweir {
629cdf0e10cSrcweir     if ( m_xStream.Is() )
630cdf0e10cSrcweir         return m_xStream->m_aContentType;
631cdf0e10cSrcweir     else if ( m_xStorage.Is() )
632cdf0e10cSrcweir         return m_xStorage->m_aContentType;
633cdf0e10cSrcweir     else
634cdf0e10cSrcweir     {
635cdf0e10cSrcweir         DBG_ERROR("Element not loaded!");
636cdf0e10cSrcweir         return String();
637cdf0e10cSrcweir     }
638cdf0e10cSrcweir }
639cdf0e10cSrcweir 
SetContentType(const String & rType)640cdf0e10cSrcweir void UCBStorageElement_Impl::SetContentType( const String& rType )
641cdf0e10cSrcweir {
642cdf0e10cSrcweir     if ( m_xStream.Is() ) {
643cdf0e10cSrcweir         m_xStream->m_aContentType = m_xStream->m_aOriginalContentType = rType;
644cdf0e10cSrcweir     }
645cdf0e10cSrcweir     else if ( m_xStorage.Is() ) {
646cdf0e10cSrcweir         m_xStorage->m_aContentType = m_xStorage->m_aOriginalContentType = rType;
647cdf0e10cSrcweir     }
648cdf0e10cSrcweir     else {
649cdf0e10cSrcweir         DBG_ERROR("Element not loaded!");
650cdf0e10cSrcweir     }
651cdf0e10cSrcweir }
652cdf0e10cSrcweir 
GetOriginalContentType()653cdf0e10cSrcweir String UCBStorageElement_Impl::GetOriginalContentType()
654cdf0e10cSrcweir {
655cdf0e10cSrcweir     if ( m_xStream.Is() )
656cdf0e10cSrcweir         return m_xStream->m_aOriginalContentType;
657cdf0e10cSrcweir     else if ( m_xStorage.Is() )
658cdf0e10cSrcweir         return m_xStorage->m_aOriginalContentType;
659cdf0e10cSrcweir     else
660cdf0e10cSrcweir         return String();
661cdf0e10cSrcweir }
662cdf0e10cSrcweir 
IsModified()663cdf0e10cSrcweir sal_Bool UCBStorageElement_Impl::IsModified()
664cdf0e10cSrcweir {
665cdf0e10cSrcweir     sal_Bool bModified = m_bIsRemoved || m_bIsInserted || m_aName != m_aOriginalName;
666cdf0e10cSrcweir     if ( bModified )
667cdf0e10cSrcweir     {
668cdf0e10cSrcweir         if ( m_xStream.Is() )
669cdf0e10cSrcweir             bModified = m_xStream->m_aContentType != m_xStream->m_aOriginalContentType;
670cdf0e10cSrcweir         else if ( m_xStorage.Is() )
671cdf0e10cSrcweir             bModified = m_xStorage->m_aContentType != m_xStorage->m_aOriginalContentType;
672cdf0e10cSrcweir     }
673cdf0e10cSrcweir 
674cdf0e10cSrcweir     return bModified;
675cdf0e10cSrcweir }
676cdf0e10cSrcweir 
UCBStorageStream_Impl(const String & rName,StreamMode nMode,UCBStorageStream * pStream,sal_Bool bDirect,const ByteString * pKey,sal_Bool bRepair,Reference<XProgressHandler> xProgress)677cdf0e10cSrcweir UCBStorageStream_Impl::UCBStorageStream_Impl( const String& rName, StreamMode nMode, UCBStorageStream* pStream, sal_Bool bDirect, const ByteString* pKey, sal_Bool bRepair, Reference< XProgressHandler > xProgress  )
678cdf0e10cSrcweir     : m_pAntiImpl( pStream )
679cdf0e10cSrcweir     , m_aURL( rName )
680cdf0e10cSrcweir     , m_pContent( NULL )
681cdf0e10cSrcweir     , m_pStream( NULL )
682cdf0e10cSrcweir     , m_nRepresentMode( nonset )
683cdf0e10cSrcweir     , m_nError( 0 )
684cdf0e10cSrcweir     , m_nMode( nMode )
685cdf0e10cSrcweir     , m_bSourceRead( !( nMode & STREAM_TRUNC ) )
686cdf0e10cSrcweir     , m_bModified( sal_False )
687cdf0e10cSrcweir     , m_bCommited( sal_False )
688cdf0e10cSrcweir     , m_bDirect( bDirect )
689cdf0e10cSrcweir     , m_bIsOLEStorage( sal_False )
690cdf0e10cSrcweir {
691cdf0e10cSrcweir     // name is last segment in URL
692cdf0e10cSrcweir     INetURLObject aObj( rName );
693cdf0e10cSrcweir     m_aName = m_aOriginalName = aObj.GetLastName();
694cdf0e10cSrcweir     try
695cdf0e10cSrcweir     {
696cdf0e10cSrcweir         // create the content
697cdf0e10cSrcweir         Reference< ::com::sun::star::ucb::XCommandEnvironment > xComEnv;
698cdf0e10cSrcweir 
699cdf0e10cSrcweir         ::rtl::OUString aTemp( rName );
700cdf0e10cSrcweir 
701cdf0e10cSrcweir         if ( bRepair )
702cdf0e10cSrcweir         {
703cdf0e10cSrcweir             xComEnv = new ::ucbhelper::CommandEnvironment( Reference< ::com::sun::star::task::XInteractionHandler >(),
704cdf0e10cSrcweir                                                      xProgress );
705cdf0e10cSrcweir             aTemp += rtl::OUString::createFromAscii("?repairpackage");
706cdf0e10cSrcweir         }
707cdf0e10cSrcweir 
708cdf0e10cSrcweir         m_pContent = new ::ucbhelper::Content( aTemp, xComEnv );
709cdf0e10cSrcweir 
710cdf0e10cSrcweir         if ( pKey )
711cdf0e10cSrcweir         {
712cdf0e10cSrcweir             m_aKey = *pKey;
713cdf0e10cSrcweir 
714cdf0e10cSrcweir             // stream is encrypted and should be decrypted (without setting the key we'll get the raw data)
715cdf0e10cSrcweir             sal_uInt8 aBuffer[RTL_DIGEST_LENGTH_SHA1];
716cdf0e10cSrcweir             rtlDigestError nErr = rtl_digest_SHA1( pKey->GetBuffer(), pKey->Len(), aBuffer, RTL_DIGEST_LENGTH_SHA1 );
717cdf0e10cSrcweir             if ( nErr == rtl_Digest_E_None )
718cdf0e10cSrcweir             {
719cdf0e10cSrcweir                 sal_uInt8* pBuffer = aBuffer;
720cdf0e10cSrcweir                 ::com::sun::star::uno::Sequence < sal_Int8 > aSequ( (sal_Int8*) pBuffer, RTL_DIGEST_LENGTH_SHA1 );
721cdf0e10cSrcweir                 ::com::sun::star::uno::Any aAny;
722cdf0e10cSrcweir                 aAny <<= aSequ;
723cdf0e10cSrcweir                 m_pContent->setPropertyValue( ::rtl::OUString::createFromAscii("EncryptionKey"), aAny );
724cdf0e10cSrcweir             }
725cdf0e10cSrcweir         }
726cdf0e10cSrcweir     }
727cdf0e10cSrcweir     catch ( ContentCreationException& )
728cdf0e10cSrcweir     {
729cdf0e10cSrcweir         // content could not be created
730cdf0e10cSrcweir         SetError( SVSTREAM_CANNOT_MAKE );
731cdf0e10cSrcweir     }
732cdf0e10cSrcweir     catch ( RuntimeException& )
733cdf0e10cSrcweir     {
734cdf0e10cSrcweir         // any other error - not specified
735cdf0e10cSrcweir         SetError( ERRCODE_IO_GENERAL );
736cdf0e10cSrcweir     }
737cdf0e10cSrcweir }
738cdf0e10cSrcweir 
~UCBStorageStream_Impl()739cdf0e10cSrcweir UCBStorageStream_Impl::~UCBStorageStream_Impl()
740cdf0e10cSrcweir {
741cdf0e10cSrcweir     if( m_rSource.is() )
742cdf0e10cSrcweir         m_rSource = Reference< XInputStream >();
743cdf0e10cSrcweir 
744cdf0e10cSrcweir     if( m_pStream )
745cdf0e10cSrcweir         delete m_pStream;
746cdf0e10cSrcweir 
747cdf0e10cSrcweir     if ( m_aTempURL.Len() )
748cdf0e10cSrcweir         ::utl::UCBContentHelper::Kill( m_aTempURL );
749cdf0e10cSrcweir 
750cdf0e10cSrcweir     if( m_pContent )
751cdf0e10cSrcweir         delete m_pContent;
752cdf0e10cSrcweir }
753cdf0e10cSrcweir 
754cdf0e10cSrcweir 
GetXInputStream()755cdf0e10cSrcweir Reference<XInputStream> UCBStorageStream_Impl::GetXInputStream()
756cdf0e10cSrcweir {
757cdf0e10cSrcweir     Reference< XInputStream > aResult;
758cdf0e10cSrcweir 
759cdf0e10cSrcweir     if( m_pAntiImpl && m_nRepresentMode != nonset )
760cdf0e10cSrcweir     {
761cdf0e10cSrcweir         DBG_ERROR( "Misuse of the XInputstream!" );
762cdf0e10cSrcweir         SetError( ERRCODE_IO_ACCESSDENIED );
763cdf0e10cSrcweir     }
764cdf0e10cSrcweir     else
765cdf0e10cSrcweir     {
766cdf0e10cSrcweir         if( m_bModified )
767cdf0e10cSrcweir         {
768cdf0e10cSrcweir             // use wrapper around temporary stream
769cdf0e10cSrcweir             if( Init() )
770cdf0e10cSrcweir             {
771cdf0e10cSrcweir                 CopySourceToTemporary();
772cdf0e10cSrcweir 
773cdf0e10cSrcweir                 // owner transfer of stream to wrapper
774cdf0e10cSrcweir                 aResult = new ::utl::OInputStreamWrapper( m_pStream, sal_True );
775cdf0e10cSrcweir                 m_pStream->Seek(0);
776cdf0e10cSrcweir 
777cdf0e10cSrcweir                 if( aResult.is() )
778cdf0e10cSrcweir                 {
779cdf0e10cSrcweir                     // temporary stream can not be used here any more
78086e1cf34SPedro Giffuni                     // and can not be opened until wrapper is closed
781cdf0e10cSrcweir                     // stream is deleted by wrapper after use
782cdf0e10cSrcweir                     m_pStream = NULL;
783cdf0e10cSrcweir                     m_nRepresentMode = xinputstream;
784cdf0e10cSrcweir                 }
785cdf0e10cSrcweir             }
786cdf0e10cSrcweir         }
787cdf0e10cSrcweir         else
788cdf0e10cSrcweir         {
789cdf0e10cSrcweir             Free();
790cdf0e10cSrcweir 
791cdf0e10cSrcweir             // open a new instance of XInputStream
792cdf0e10cSrcweir             try
793cdf0e10cSrcweir             {
794cdf0e10cSrcweir                 aResult = m_pContent->openStream();
795cdf0e10cSrcweir             }
796cdf0e10cSrcweir             catch ( Exception& )
797cdf0e10cSrcweir             {
798cdf0e10cSrcweir                 // usually means that stream could not be opened
799cdf0e10cSrcweir             }
800cdf0e10cSrcweir 
801cdf0e10cSrcweir             if( aResult.is() )
802cdf0e10cSrcweir                 m_nRepresentMode = xinputstream;
803cdf0e10cSrcweir             else
804cdf0e10cSrcweir                 SetError( ERRCODE_IO_ACCESSDENIED );
805cdf0e10cSrcweir         }
806cdf0e10cSrcweir     }
807cdf0e10cSrcweir 
808cdf0e10cSrcweir     return aResult;
809cdf0e10cSrcweir }
810cdf0e10cSrcweir 
Init()811cdf0e10cSrcweir sal_Bool UCBStorageStream_Impl::Init()
812cdf0e10cSrcweir {
813cdf0e10cSrcweir     if( m_nRepresentMode == xinputstream )
814cdf0e10cSrcweir     {
815cdf0e10cSrcweir         DBG_ERROR( "XInputStream misuse!" );
816cdf0e10cSrcweir         SetError( ERRCODE_IO_ACCESSDENIED );
817cdf0e10cSrcweir         return sal_False;
818cdf0e10cSrcweir     }
819cdf0e10cSrcweir 
820cdf0e10cSrcweir     if( !m_pStream )
821cdf0e10cSrcweir     {
822cdf0e10cSrcweir         // no temporary stream was created
823cdf0e10cSrcweir         // create one
824cdf0e10cSrcweir 
825cdf0e10cSrcweir         m_nRepresentMode = svstream; // can not be used as XInputStream
826cdf0e10cSrcweir 
827cdf0e10cSrcweir         if ( !m_aTempURL.Len() )
828cdf0e10cSrcweir             m_aTempURL = ::utl::TempFile().GetURL();
829cdf0e10cSrcweir 
830cdf0e10cSrcweir         m_pStream = ::utl::UcbStreamHelper::CreateStream( m_aTempURL, STREAM_STD_READWRITE, sal_True /* bFileExists */ );
831cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
832cdf0e10cSrcweir         ++nOpenFiles;
833cdf0e10cSrcweir #endif
834cdf0e10cSrcweir 
835cdf0e10cSrcweir         if( !m_pStream )
836cdf0e10cSrcweir         {
837cdf0e10cSrcweir             DBG_ERROR( "Suspicious temporary stream creation!" );
838cdf0e10cSrcweir             SetError( SVSTREAM_CANNOT_MAKE );
839cdf0e10cSrcweir             return sal_False;
840cdf0e10cSrcweir         }
841cdf0e10cSrcweir 
842cdf0e10cSrcweir         SetError( m_pStream->GetError() );
843cdf0e10cSrcweir     }
844cdf0e10cSrcweir 
845cdf0e10cSrcweir     if( m_bSourceRead && !m_rSource.is() )
846cdf0e10cSrcweir     {
84786e1cf34SPedro Giffuni         // source file contain useful information and is not opened
848cdf0e10cSrcweir         // open it from the point of noncopied data
849cdf0e10cSrcweir 
850cdf0e10cSrcweir         try
851cdf0e10cSrcweir         {
852cdf0e10cSrcweir             m_rSource = m_pContent->openStream();
853cdf0e10cSrcweir         }
854cdf0e10cSrcweir         catch ( Exception& )
855cdf0e10cSrcweir         {
856cdf0e10cSrcweir             // usually means that stream could not be opened
857cdf0e10cSrcweir         }
858cdf0e10cSrcweir 
859cdf0e10cSrcweir             if( m_rSource.is() )
860cdf0e10cSrcweir         {
861cdf0e10cSrcweir             m_pStream->Seek( STREAM_SEEK_TO_END );
862cdf0e10cSrcweir 
863cdf0e10cSrcweir             try
864cdf0e10cSrcweir             {
865cdf0e10cSrcweir                 m_rSource->skipBytes( m_pStream->Tell() );
866cdf0e10cSrcweir             }
867cdf0e10cSrcweir             catch( BufferSizeExceededException& )
868cdf0e10cSrcweir             {
869cdf0e10cSrcweir                 // the temporary stream already contain all the data
870cdf0e10cSrcweir                 m_bSourceRead = sal_False;
871cdf0e10cSrcweir             }
872cdf0e10cSrcweir             catch( Exception& )
873cdf0e10cSrcweir             {
874cdf0e10cSrcweir                 // something is really wrong
875cdf0e10cSrcweir                 m_bSourceRead = sal_False;
876cdf0e10cSrcweir                 DBG_ERROR( "Can not operate original stream!" );
877cdf0e10cSrcweir                 SetError( SVSTREAM_CANNOT_MAKE );
878cdf0e10cSrcweir             }
879cdf0e10cSrcweir 
880cdf0e10cSrcweir             m_pStream->Seek( 0 );
881cdf0e10cSrcweir         }
882cdf0e10cSrcweir         else
883cdf0e10cSrcweir         {
884*ecbfceb0Smseidel             // if the new file is edited then no source exist
885cdf0e10cSrcweir             m_bSourceRead = sal_False;
886cdf0e10cSrcweir                 //SetError( SVSTREAM_CANNOT_MAKE );
887cdf0e10cSrcweir         }
888cdf0e10cSrcweir     }
889cdf0e10cSrcweir 
890cdf0e10cSrcweir     DBG_ASSERT( m_rSource.is() || !m_bSourceRead, "Unreadable source stream!" );
891cdf0e10cSrcweir 
892cdf0e10cSrcweir     return sal_True;
893cdf0e10cSrcweir }
894cdf0e10cSrcweir 
ReadSourceWriteTemporary()895cdf0e10cSrcweir sal_uLong UCBStorageStream_Impl::ReadSourceWriteTemporary()
896cdf0e10cSrcweir {
897cdf0e10cSrcweir     // read source stream till the end and copy all the data to
898cdf0e10cSrcweir     // the current position of the temporary stream
899cdf0e10cSrcweir 
900cdf0e10cSrcweir     sal_uLong aResult = 0;
901cdf0e10cSrcweir 
902cdf0e10cSrcweir     if( m_bSourceRead )
903cdf0e10cSrcweir     {
904cdf0e10cSrcweir         Sequence<sal_Int8> aData(32000);
905cdf0e10cSrcweir 
906cdf0e10cSrcweir         try
907cdf0e10cSrcweir         {
908cdf0e10cSrcweir             sal_uLong aReaded;
909cdf0e10cSrcweir             do
910cdf0e10cSrcweir             {
911cdf0e10cSrcweir                 aReaded = m_rSource->readBytes( aData, 32000 );
912cdf0e10cSrcweir                 aResult += m_pStream->Write( aData.getArray(), aReaded );
913cdf0e10cSrcweir             } while( aReaded == 32000 );
914cdf0e10cSrcweir         }
915cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
916cdf0e10cSrcweir         catch( Exception & e )
917cdf0e10cSrcweir         {
918cdf0e10cSrcweir             OSL_ENSURE( sal_False, ::rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
919cdf0e10cSrcweir #else
920cdf0e10cSrcweir         catch( Exception & )
921cdf0e10cSrcweir         {
922cdf0e10cSrcweir #endif
923cdf0e10cSrcweir         }
924cdf0e10cSrcweir     }
925cdf0e10cSrcweir 
926cdf0e10cSrcweir     m_bSourceRead = sal_False;
927cdf0e10cSrcweir 
928cdf0e10cSrcweir     return aResult;
929cdf0e10cSrcweir 
930cdf0e10cSrcweir }
931cdf0e10cSrcweir 
932cdf0e10cSrcweir sal_uLong UCBStorageStream_Impl::ReadSourceWriteTemporary( sal_uLong aLength )
933cdf0e10cSrcweir {
934cdf0e10cSrcweir     // read aLength bite from the source stream and copy them to the current
935cdf0e10cSrcweir     // position of the temporary stream
936cdf0e10cSrcweir 
937cdf0e10cSrcweir     sal_uLong aResult = 0;
938cdf0e10cSrcweir 
939cdf0e10cSrcweir     if( m_bSourceRead )
940cdf0e10cSrcweir     {
941cdf0e10cSrcweir         Sequence<sal_Int8> aData(32000);
942cdf0e10cSrcweir 
943cdf0e10cSrcweir         try
944cdf0e10cSrcweir         {
945cdf0e10cSrcweir 
946cdf0e10cSrcweir             sal_uLong aReaded = 32000;
947cdf0e10cSrcweir 
948cdf0e10cSrcweir             for( sal_uLong pInd = 0; pInd < aLength && aReaded == 32000 ; pInd += 32000 )
949cdf0e10cSrcweir             {
950cdf0e10cSrcweir                 sal_uLong aToCopy = min( aLength - pInd, 32000 );
951cdf0e10cSrcweir                 aReaded = m_rSource->readBytes( aData, aToCopy );
952cdf0e10cSrcweir                 aResult += m_pStream->Write( aData.getArray(), aReaded );
953cdf0e10cSrcweir             }
954cdf0e10cSrcweir 
955cdf0e10cSrcweir             if( aResult < aLength )
956cdf0e10cSrcweir                 m_bSourceRead = sal_False;
957cdf0e10cSrcweir         }
958cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
959cdf0e10cSrcweir         catch( Exception & e )
960cdf0e10cSrcweir         {
961cdf0e10cSrcweir             OSL_ENSURE( sal_False, ::rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
962cdf0e10cSrcweir #else
963cdf0e10cSrcweir         catch( Exception & )
964cdf0e10cSrcweir         {
965cdf0e10cSrcweir #endif
966cdf0e10cSrcweir         }
967cdf0e10cSrcweir     }
968cdf0e10cSrcweir 
969cdf0e10cSrcweir     return aResult;
970cdf0e10cSrcweir }
971cdf0e10cSrcweir 
972cdf0e10cSrcweir sal_uLong UCBStorageStream_Impl::CopySourceToTemporary()
973cdf0e10cSrcweir {
974cdf0e10cSrcweir     // current position of the temporary stream is not changed
975cdf0e10cSrcweir     sal_uLong aResult = 0;
976cdf0e10cSrcweir 
977cdf0e10cSrcweir     if( m_bSourceRead )
978cdf0e10cSrcweir     {
979cdf0e10cSrcweir         sal_uLong aPos = m_pStream->Tell();
980cdf0e10cSrcweir         m_pStream->Seek( STREAM_SEEK_TO_END );
981cdf0e10cSrcweir         aResult = ReadSourceWriteTemporary();
982cdf0e10cSrcweir         m_pStream->Seek( aPos );
983cdf0e10cSrcweir     }
984cdf0e10cSrcweir 
985cdf0e10cSrcweir     return aResult;
986cdf0e10cSrcweir 
987cdf0e10cSrcweir }
988cdf0e10cSrcweir 
989cdf0e10cSrcweir #if 0
990cdf0e10cSrcweir sal_uLong UCBStorageStream_Impl::CopySourceToTemporary( sal_uLong aLength )
991cdf0e10cSrcweir {
992cdf0e10cSrcweir     // current position of the temporary stream is not changed
993cdf0e10cSrcweir     sal_uLong aResult = 0;
994cdf0e10cSrcweir 
995cdf0e10cSrcweir     if( m_bSourceRead )
996cdf0e10cSrcweir     {
997cdf0e10cSrcweir         sal_uLong aPos = m_pStream->Tell();
998cdf0e10cSrcweir         m_pStream->Seek( STREAM_SEEK_TO_END );
999cdf0e10cSrcweir         aResult = ReadSourceWriteTemporary( aLength );
1000cdf0e10cSrcweir         m_pStream->Seek( aPos );
1001cdf0e10cSrcweir     }
1002cdf0e10cSrcweir 
1003cdf0e10cSrcweir     return aResult;
1004cdf0e10cSrcweir 
1005cdf0e10cSrcweir }
1006cdf0e10cSrcweir #endif
1007cdf0e10cSrcweir 
1008cdf0e10cSrcweir // UCBStorageStream_Impl must have a SvStream interface, because it then can be used as underlying stream
1009cdf0e10cSrcweir // of an OLEStorage; so every write access caused by storage operations marks the UCBStorageStream as modified
1010cdf0e10cSrcweir sal_uLong UCBStorageStream_Impl::GetData( void* pData, sal_uLong nSize )
1011cdf0e10cSrcweir {
1012cdf0e10cSrcweir     sal_uLong aResult = 0;
1013cdf0e10cSrcweir 
1014cdf0e10cSrcweir     if( !Init() )
1015cdf0e10cSrcweir         return 0;
1016cdf0e10cSrcweir 
1017cdf0e10cSrcweir 
1018cdf0e10cSrcweir     // read data that is in temporary stream
1019cdf0e10cSrcweir     aResult = m_pStream->Read( pData, nSize );
1020cdf0e10cSrcweir     if( m_bSourceRead && aResult < nSize )
1021cdf0e10cSrcweir     {
1022cdf0e10cSrcweir         // read the tail of the data from original stream
1023cdf0e10cSrcweir         // copy this tail to the temporary stream
1024cdf0e10cSrcweir 
1025cdf0e10cSrcweir         sal_uLong aToRead = nSize - aResult;
1026cdf0e10cSrcweir         pData = (void*)( (char*)pData + aResult );
1027cdf0e10cSrcweir 
1028cdf0e10cSrcweir         try
1029cdf0e10cSrcweir         {
1030cdf0e10cSrcweir             Sequence<sal_Int8> aData( aToRead );
1031cdf0e10cSrcweir             sal_uLong aReaded = m_rSource->readBytes( aData, aToRead );
1032cdf0e10cSrcweir             aResult += m_pStream->Write( (void*)aData.getArray(), aReaded );
1033cdf0e10cSrcweir             memcpy( pData, aData.getArray(), aReaded );
1034cdf0e10cSrcweir         }
1035cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
1036cdf0e10cSrcweir         catch( Exception & e )
1037cdf0e10cSrcweir         {
1038cdf0e10cSrcweir             OSL_ENSURE( sal_False, ::rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
1039cdf0e10cSrcweir #else
1040cdf0e10cSrcweir         catch( Exception & )
1041cdf0e10cSrcweir         {
1042cdf0e10cSrcweir #endif
1043cdf0e10cSrcweir         }
1044cdf0e10cSrcweir 
1045cdf0e10cSrcweir         if( aResult < nSize )
1046cdf0e10cSrcweir             m_bSourceRead = sal_False;
1047cdf0e10cSrcweir     }
1048cdf0e10cSrcweir 
1049cdf0e10cSrcweir     return aResult;
1050cdf0e10cSrcweir }
1051cdf0e10cSrcweir 
1052cdf0e10cSrcweir sal_uLong UCBStorageStream_Impl::PutData( const void* pData, sal_uLong nSize )
1053cdf0e10cSrcweir {
1054cdf0e10cSrcweir     if ( !(m_nMode & STREAM_WRITE) )
1055cdf0e10cSrcweir     {
1056cdf0e10cSrcweir         SetError( ERRCODE_IO_ACCESSDENIED );
1057cdf0e10cSrcweir         return 0; // ?mav?
1058cdf0e10cSrcweir     }
1059cdf0e10cSrcweir 
1060cdf0e10cSrcweir     if( !nSize || !Init() )
1061cdf0e10cSrcweir         return 0;
1062cdf0e10cSrcweir 
1063cdf0e10cSrcweir     sal_uLong aResult = m_pStream->Write( pData, nSize );
1064cdf0e10cSrcweir 
1065cdf0e10cSrcweir     m_bModified = aResult > 0;
1066cdf0e10cSrcweir 
1067cdf0e10cSrcweir     return aResult;
1068cdf0e10cSrcweir 
1069cdf0e10cSrcweir }
1070cdf0e10cSrcweir 
1071cdf0e10cSrcweir sal_uLong UCBStorageStream_Impl::SeekPos( sal_uLong nPos )
1072cdf0e10cSrcweir {
1073cdf0e10cSrcweir     if( !Init() )
1074cdf0e10cSrcweir         return 0;
1075cdf0e10cSrcweir 
1076cdf0e10cSrcweir     sal_uLong aResult;
1077cdf0e10cSrcweir 
1078cdf0e10cSrcweir     if( nPos == STREAM_SEEK_TO_END )
1079cdf0e10cSrcweir     {
1080cdf0e10cSrcweir         m_pStream->Seek( STREAM_SEEK_TO_END );
1081cdf0e10cSrcweir         ReadSourceWriteTemporary();
1082cdf0e10cSrcweir         aResult = m_pStream->Tell();
1083cdf0e10cSrcweir     }
1084cdf0e10cSrcweir     else
1085cdf0e10cSrcweir     {
1086*ecbfceb0Smseidel         // the problem is that even if nPos is larger than the length
1087cdf0e10cSrcweir         // of the stream the stream pointer will be moved to this position
1088cdf0e10cSrcweir         // so we have to check if temporary stream does not contain required position
1089cdf0e10cSrcweir 
1090cdf0e10cSrcweir         if( m_pStream->Tell() > nPos
1091cdf0e10cSrcweir             || m_pStream->Seek( STREAM_SEEK_TO_END ) > nPos )
1092cdf0e10cSrcweir         {
1093*ecbfceb0Smseidel             // no copying is required
1094cdf0e10cSrcweir             aResult = m_pStream->Seek( nPos );
1095cdf0e10cSrcweir         }
1096cdf0e10cSrcweir         else
1097cdf0e10cSrcweir         {
1098cdf0e10cSrcweir             // the temp stream pointer points to the end now
1099cdf0e10cSrcweir             aResult = m_pStream->Tell();
1100cdf0e10cSrcweir 
1101cdf0e10cSrcweir             if( aResult < nPos )
1102cdf0e10cSrcweir             {
1103cdf0e10cSrcweir                 if( m_bSourceRead )
1104cdf0e10cSrcweir                 {
1105cdf0e10cSrcweir                     aResult += ReadSourceWriteTemporary( nPos - aResult );
1106cdf0e10cSrcweir                     if( aResult < nPos )
1107cdf0e10cSrcweir                         m_bSourceRead = sal_False;
1108cdf0e10cSrcweir 
1109cdf0e10cSrcweir                     DBG_ASSERT( aResult == m_pStream->Tell(), "Error in stream arithmetic!\n" );
1110cdf0e10cSrcweir                 }
1111cdf0e10cSrcweir 
1112cdf0e10cSrcweir                 if( (m_nMode & STREAM_WRITE) && !m_bSourceRead && aResult < nPos )
1113cdf0e10cSrcweir                 {
1114cdf0e10cSrcweir                     // it means that all the Source stream was copied already
1115cdf0e10cSrcweir                     // but the required position still was not reached
1116cdf0e10cSrcweir                     // for writable streams it should be done
1117cdf0e10cSrcweir                     m_pStream->SetStreamSize( nPos );
1118cdf0e10cSrcweir                     aResult = m_pStream->Seek( STREAM_SEEK_TO_END );
1119cdf0e10cSrcweir                     DBG_ASSERT( aResult == nPos, "Error in stream arithmetic!\n" );
1120cdf0e10cSrcweir                 }
1121cdf0e10cSrcweir             }
1122cdf0e10cSrcweir         }
1123cdf0e10cSrcweir     }
1124cdf0e10cSrcweir 
1125cdf0e10cSrcweir     return aResult;
1126cdf0e10cSrcweir }
1127cdf0e10cSrcweir 
1128cdf0e10cSrcweir void  UCBStorageStream_Impl::SetSize( sal_uLong nSize )
1129cdf0e10cSrcweir {
1130cdf0e10cSrcweir     if ( !(m_nMode & STREAM_WRITE) )
1131cdf0e10cSrcweir     {
1132cdf0e10cSrcweir         SetError( ERRCODE_IO_ACCESSDENIED );
1133cdf0e10cSrcweir         return;
1134cdf0e10cSrcweir     }
1135cdf0e10cSrcweir 
1136cdf0e10cSrcweir     if( !Init() )
1137cdf0e10cSrcweir         return;
1138cdf0e10cSrcweir 
1139cdf0e10cSrcweir     m_bModified = sal_True;
1140cdf0e10cSrcweir 
1141cdf0e10cSrcweir     if( m_bSourceRead )
1142cdf0e10cSrcweir     {
1143cdf0e10cSrcweir         sal_uLong aPos = m_pStream->Tell();
1144cdf0e10cSrcweir         m_pStream->Seek( STREAM_SEEK_TO_END );
1145cdf0e10cSrcweir         if( m_pStream->Tell() < nSize )
1146cdf0e10cSrcweir             ReadSourceWriteTemporary( nSize - m_pStream->Tell() );
1147cdf0e10cSrcweir         m_pStream->Seek( aPos );
1148cdf0e10cSrcweir     }
1149cdf0e10cSrcweir 
1150cdf0e10cSrcweir     m_pStream->SetStreamSize( nSize );
1151cdf0e10cSrcweir     m_bSourceRead = sal_False;
1152cdf0e10cSrcweir }
1153cdf0e10cSrcweir 
1154cdf0e10cSrcweir void UCBStorageStream_Impl::FlushData()
1155cdf0e10cSrcweir {
1156cdf0e10cSrcweir     if( m_pStream )
1157cdf0e10cSrcweir     {
1158cdf0e10cSrcweir         CopySourceToTemporary();
1159cdf0e10cSrcweir         m_pStream->Flush();
1160cdf0e10cSrcweir     }
1161cdf0e10cSrcweir 
1162cdf0e10cSrcweir     m_bCommited = sal_True;
1163cdf0e10cSrcweir }
1164cdf0e10cSrcweir 
1165cdf0e10cSrcweir void UCBStorageStream_Impl::SetError( sal_uInt32 nErr )
1166cdf0e10cSrcweir {
1167cdf0e10cSrcweir     if ( !m_nError )
1168cdf0e10cSrcweir     {
1169cdf0e10cSrcweir         m_nError = nErr;
1170cdf0e10cSrcweir         SvStream::SetError( nErr );
1171cdf0e10cSrcweir         if ( m_pAntiImpl ) m_pAntiImpl->SetError( nErr );
1172cdf0e10cSrcweir     }
1173cdf0e10cSrcweir }
1174cdf0e10cSrcweir 
1175cdf0e10cSrcweir void  UCBStorageStream_Impl::ResetError()
1176cdf0e10cSrcweir {
1177cdf0e10cSrcweir     m_nError = 0;
1178cdf0e10cSrcweir     SvStream::ResetError();
1179cdf0e10cSrcweir     if ( m_pAntiImpl )
1180cdf0e10cSrcweir         m_pAntiImpl->ResetError();
1181cdf0e10cSrcweir }
1182cdf0e10cSrcweir 
1183cdf0e10cSrcweir sal_uLong UCBStorageStream_Impl::GetSize()
1184cdf0e10cSrcweir {
1185cdf0e10cSrcweir     if( !Init() )
1186cdf0e10cSrcweir         return 0;
1187cdf0e10cSrcweir 
1188cdf0e10cSrcweir     sal_uLong nPos = m_pStream->Tell();
1189cdf0e10cSrcweir     m_pStream->Seek( STREAM_SEEK_TO_END );
1190cdf0e10cSrcweir     ReadSourceWriteTemporary();
1191cdf0e10cSrcweir     sal_uLong nRet = m_pStream->Tell();
1192cdf0e10cSrcweir     m_pStream->Seek( nPos );
1193cdf0e10cSrcweir 
1194cdf0e10cSrcweir     return nRet;
1195cdf0e10cSrcweir }
1196cdf0e10cSrcweir 
1197cdf0e10cSrcweir BaseStorage* UCBStorageStream_Impl::CreateStorage()
1198cdf0e10cSrcweir {
1199cdf0e10cSrcweir     // create an OLEStorage on a SvStream ( = this )
1200*ecbfceb0Smseidel     // it gets the root attribute because otherwise it would probably not write before my root is committed
1201cdf0e10cSrcweir     UCBStorageStream* pNewStorageStream = new UCBStorageStream( this );
1202cdf0e10cSrcweir     Storage *pStorage = new Storage( *pNewStorageStream, m_bDirect );
1203cdf0e10cSrcweir 
1204cdf0e10cSrcweir     // GetError() call cleares error code for OLE storages, must be changed in future
1205cdf0e10cSrcweir     long nTmpErr = pStorage->GetError();
1206cdf0e10cSrcweir     pStorage->SetError( nTmpErr );
1207cdf0e10cSrcweir 
1208cdf0e10cSrcweir     m_bIsOLEStorage = !nTmpErr;
1209cdf0e10cSrcweir     return static_cast< BaseStorage* > ( pStorage );
1210cdf0e10cSrcweir }
1211cdf0e10cSrcweir 
1212cdf0e10cSrcweir sal_Int16 UCBStorageStream_Impl::Commit()
1213cdf0e10cSrcweir {
1214cdf0e10cSrcweir     // send stream to the original content
1215cdf0e10cSrcweir     // the parent storage is responsible for the correct handling of deleted contents
1216cdf0e10cSrcweir     if ( m_bCommited || m_bIsOLEStorage || m_bDirect )
1217cdf0e10cSrcweir     {
1218cdf0e10cSrcweir         // modified streams with OLEStorages on it have autocommit; it is assumed that the OLEStorage
1219*ecbfceb0Smseidel         // was committed as well ( if not opened in direct mode )
1220cdf0e10cSrcweir 
1221cdf0e10cSrcweir         if ( m_bModified )
1222cdf0e10cSrcweir         {
1223cdf0e10cSrcweir             try
1224cdf0e10cSrcweir             {
1225cdf0e10cSrcweir                 CopySourceToTemporary();
1226cdf0e10cSrcweir 
1227cdf0e10cSrcweir                 // release all stream handles
1228cdf0e10cSrcweir                 Free();
1229cdf0e10cSrcweir 
1230cdf0e10cSrcweir                 // the temporary file does not exist only for truncated streams
1231cdf0e10cSrcweir                 DBG_ASSERT( m_aTempURL.Len() || ( m_nMode & STREAM_TRUNC ), "No temporary file to read from!");
1232cdf0e10cSrcweir                 if ( !m_aTempURL.Len() && !( m_nMode & STREAM_TRUNC ) )
1233cdf0e10cSrcweir                     throw RuntimeException();
1234cdf0e10cSrcweir 
1235cdf0e10cSrcweir                 // create wrapper to stream that is only used while reading inside package component
1236cdf0e10cSrcweir                 Reference < XInputStream > xStream = new FileStreamWrapper_Impl( m_aTempURL );
1237cdf0e10cSrcweir 
1238cdf0e10cSrcweir                 Any aAny;
1239cdf0e10cSrcweir                 InsertCommandArgument aArg;
1240cdf0e10cSrcweir                 aArg.Data = xStream;
1241cdf0e10cSrcweir                 aArg.ReplaceExisting = sal_True;
1242cdf0e10cSrcweir                 aAny <<= aArg;
1243cdf0e10cSrcweir                 m_pContent->executeCommand( ::rtl::OUString::createFromAscii("insert"), aAny );
1244cdf0e10cSrcweir 
1245cdf0e10cSrcweir                 // wrapper now controls lifetime of temporary file
1246cdf0e10cSrcweir                 m_aTempURL.Erase();
1247cdf0e10cSrcweir 
1248cdf0e10cSrcweir                 INetURLObject aObj( m_aURL );
1249cdf0e10cSrcweir                 aObj.SetName( m_aName );
1250cdf0e10cSrcweir                 m_aURL = aObj.GetMainURL( INetURLObject::NO_DECODE );
1251cdf0e10cSrcweir                 m_bModified = sal_False;
1252cdf0e10cSrcweir                 m_bSourceRead = sal_True;
1253cdf0e10cSrcweir             }
1254cdf0e10cSrcweir             catch ( CommandAbortedException& )
1255cdf0e10cSrcweir             {
1256cdf0e10cSrcweir                 // any command wasn't executed successfully - not specified
1257cdf0e10cSrcweir                 SetError( ERRCODE_IO_GENERAL );
1258cdf0e10cSrcweir                 return COMMIT_RESULT_FAILURE;
1259cdf0e10cSrcweir             }
1260cdf0e10cSrcweir             catch ( RuntimeException& )
1261cdf0e10cSrcweir             {
1262cdf0e10cSrcweir                 // any other error - not specified
1263cdf0e10cSrcweir                 SetError( ERRCODE_IO_GENERAL );
1264cdf0e10cSrcweir                 return COMMIT_RESULT_FAILURE;
1265cdf0e10cSrcweir             }
1266cdf0e10cSrcweir             catch ( Exception& )
1267cdf0e10cSrcweir             {
1268cdf0e10cSrcweir                 // any other error - not specified
1269cdf0e10cSrcweir                 SetError( ERRCODE_IO_GENERAL );
1270cdf0e10cSrcweir                 return COMMIT_RESULT_FAILURE;
1271cdf0e10cSrcweir             }
1272cdf0e10cSrcweir 
1273cdf0e10cSrcweir             m_bCommited = sal_False;
1274cdf0e10cSrcweir             return COMMIT_RESULT_SUCCESS;
1275cdf0e10cSrcweir         }
1276cdf0e10cSrcweir     }
1277cdf0e10cSrcweir 
1278cdf0e10cSrcweir     return COMMIT_RESULT_NOTHING_TO_DO;
1279cdf0e10cSrcweir }
1280cdf0e10cSrcweir 
1281cdf0e10cSrcweir sal_Bool UCBStorageStream_Impl::Revert()
1282cdf0e10cSrcweir {
128386e1cf34SPedro Giffuni     // if an OLEStorage is created on this stream, no "revert" is necessary because OLEStorages do nothing on "Revert" !
1284cdf0e10cSrcweir     if ( m_bCommited )
1285cdf0e10cSrcweir     {
1286cdf0e10cSrcweir         DBG_ERROR("Revert while commit is in progress!" );
1287cdf0e10cSrcweir         return sal_False;                   // ???
1288cdf0e10cSrcweir     }
1289cdf0e10cSrcweir 
1290cdf0e10cSrcweir     Free();
1291cdf0e10cSrcweir     if ( m_aTempURL.Len() )
1292cdf0e10cSrcweir     {
1293cdf0e10cSrcweir         ::utl::UCBContentHelper::Kill( m_aTempURL );
1294cdf0e10cSrcweir         m_aTempURL.Erase();
1295cdf0e10cSrcweir     }
1296cdf0e10cSrcweir 
1297cdf0e10cSrcweir     m_bSourceRead = sal_False;
1298cdf0e10cSrcweir     try
1299cdf0e10cSrcweir     {
1300cdf0e10cSrcweir         m_rSource = m_pContent->openStream();
1301cdf0e10cSrcweir         if( m_rSource.is() )
1302cdf0e10cSrcweir         {
1303cdf0e10cSrcweir             if ( m_pAntiImpl && ( m_nMode & STREAM_TRUNC ) )
1304cdf0e10cSrcweir                 // stream is in use and should be truncated
1305cdf0e10cSrcweir                 m_bSourceRead = sal_False;
1306cdf0e10cSrcweir             else
1307cdf0e10cSrcweir             {
1308cdf0e10cSrcweir                 m_nMode &= ~STREAM_TRUNC;
1309cdf0e10cSrcweir                 m_bSourceRead = sal_True;
1310cdf0e10cSrcweir             }
1311cdf0e10cSrcweir         }
1312cdf0e10cSrcweir         else
1313cdf0e10cSrcweir             SetError( SVSTREAM_CANNOT_MAKE );
1314cdf0e10cSrcweir     }
1315cdf0e10cSrcweir     catch ( ContentCreationException& )
1316cdf0e10cSrcweir     {
1317cdf0e10cSrcweir         SetError( ERRCODE_IO_GENERAL );
1318cdf0e10cSrcweir     }
1319cdf0e10cSrcweir     catch ( RuntimeException& )
1320cdf0e10cSrcweir     {
1321cdf0e10cSrcweir         SetError( ERRCODE_IO_GENERAL );
1322cdf0e10cSrcweir     }
1323cdf0e10cSrcweir     catch ( Exception& )
1324cdf0e10cSrcweir     {
1325cdf0e10cSrcweir     }
1326cdf0e10cSrcweir 
1327cdf0e10cSrcweir     m_bModified = sal_False;
1328cdf0e10cSrcweir     m_aName = m_aOriginalName;
1329cdf0e10cSrcweir     m_aContentType = m_aOriginalContentType;
1330cdf0e10cSrcweir     return ( GetError() == ERRCODE_NONE );
1331cdf0e10cSrcweir }
1332cdf0e10cSrcweir 
1333cdf0e10cSrcweir sal_Bool UCBStorageStream_Impl::Clear()
1334cdf0e10cSrcweir {
1335cdf0e10cSrcweir     sal_Bool bRet = ( m_pAntiImpl == NULL );
1336cdf0e10cSrcweir     DBG_ASSERT( bRet, "Removing used stream!" );
1337cdf0e10cSrcweir     if( bRet )
1338cdf0e10cSrcweir     {
1339cdf0e10cSrcweir         Free();
1340cdf0e10cSrcweir     }
1341cdf0e10cSrcweir 
1342cdf0e10cSrcweir     return bRet;
1343cdf0e10cSrcweir }
1344cdf0e10cSrcweir 
1345cdf0e10cSrcweir void UCBStorageStream_Impl::Free()
1346cdf0e10cSrcweir {
1347cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
1348cdf0e10cSrcweir     if ( m_pStream )
1349cdf0e10cSrcweir     {
1350cdf0e10cSrcweir         if ( m_aTempURL.Len() )
1351cdf0e10cSrcweir             --nOpenFiles;
1352cdf0e10cSrcweir         else
1353cdf0e10cSrcweir             --nOpenStreams;
1354cdf0e10cSrcweir     }
1355cdf0e10cSrcweir #endif
1356cdf0e10cSrcweir 
1357cdf0e10cSrcweir     m_nRepresentMode = nonset;
1358cdf0e10cSrcweir     m_rSource = Reference< XInputStream >();
1359cdf0e10cSrcweir     DELETEZ( m_pStream );
1360cdf0e10cSrcweir }
1361cdf0e10cSrcweir 
1362cdf0e10cSrcweir void UCBStorageStream_Impl::PrepareCachedForReopen( StreamMode nMode )
1363cdf0e10cSrcweir {
1364cdf0e10cSrcweir     sal_Bool isWritable = (( m_nMode & STREAM_WRITE ) != 0 );
1365cdf0e10cSrcweir     if ( isWritable )
1366cdf0e10cSrcweir     {
1367cdf0e10cSrcweir         // once stream was writable, never reset to readonly
1368cdf0e10cSrcweir         nMode |= STREAM_WRITE;
1369cdf0e10cSrcweir     }
1370cdf0e10cSrcweir 
1371cdf0e10cSrcweir     m_nMode = nMode;
1372cdf0e10cSrcweir     Free();
1373cdf0e10cSrcweir 
1374cdf0e10cSrcweir     if ( nMode & STREAM_TRUNC )
1375cdf0e10cSrcweir     {
1376cdf0e10cSrcweir         m_bSourceRead = 0; // usually it should be 0 already but just in case...
1377cdf0e10cSrcweir 
1378cdf0e10cSrcweir         if ( m_aTempURL.Len() )
1379cdf0e10cSrcweir         {
1380cdf0e10cSrcweir             ::utl::UCBContentHelper::Kill( m_aTempURL );
1381cdf0e10cSrcweir             m_aTempURL.Erase();
1382cdf0e10cSrcweir         }
1383cdf0e10cSrcweir     }
1384cdf0e10cSrcweir }
1385cdf0e10cSrcweir 
1386cdf0e10cSrcweir UCBStorageStream::UCBStorageStream( const String& rName, StreamMode nMode, sal_Bool bDirect, const ByteString* pKey )
1387cdf0e10cSrcweir {
1388cdf0e10cSrcweir     // pImp must be initialized in the body, because otherwise the vtable of the stream is not initialized
1389cdf0e10cSrcweir     // to class UCBStorageStream !
1390cdf0e10cSrcweir     pImp = new UCBStorageStream_Impl( rName, nMode, this, bDirect, pKey );
1391cdf0e10cSrcweir     pImp->AddRef();             // use direct refcounting because in header file only a pointer should be used
1392cdf0e10cSrcweir     StorageBase::m_nMode = pImp->m_nMode;
1393cdf0e10cSrcweir }
1394cdf0e10cSrcweir 
1395cdf0e10cSrcweir UCBStorageStream::UCBStorageStream( const String& rName, StreamMode nMode, sal_Bool bDirect, const ByteString* pKey, sal_Bool bRepair, Reference< XProgressHandler > xProgress )
1396cdf0e10cSrcweir {
1397cdf0e10cSrcweir     // pImp must be initialized in the body, because otherwise the vtable of the stream is not initialized
1398cdf0e10cSrcweir     // to class UCBStorageStream !
1399cdf0e10cSrcweir     pImp = new UCBStorageStream_Impl( rName, nMode, this, bDirect, pKey, bRepair, xProgress );
1400cdf0e10cSrcweir     pImp->AddRef();             // use direct refcounting because in header file only a pointer should be used
1401cdf0e10cSrcweir     StorageBase::m_nMode = pImp->m_nMode;
1402cdf0e10cSrcweir }
1403cdf0e10cSrcweir 
1404cdf0e10cSrcweir UCBStorageStream::UCBStorageStream( UCBStorageStream_Impl *pImpl )
1405cdf0e10cSrcweir     : pImp( pImpl )
1406cdf0e10cSrcweir {
1407cdf0e10cSrcweir     pImp->AddRef();             // use direct refcounting because in header file only a pointer should be used
1408cdf0e10cSrcweir     pImp->m_pAntiImpl = this;
1409cdf0e10cSrcweir     SetError( pImp->m_nError );
1410cdf0e10cSrcweir     StorageBase::m_nMode = pImp->m_nMode;
1411cdf0e10cSrcweir }
1412cdf0e10cSrcweir 
1413cdf0e10cSrcweir UCBStorageStream::~UCBStorageStream()
1414cdf0e10cSrcweir {
1415cdf0e10cSrcweir     if ( pImp->m_nMode & STREAM_WRITE )
1416cdf0e10cSrcweir         pImp->Flush();
1417cdf0e10cSrcweir     pImp->m_pAntiImpl = NULL;
1418cdf0e10cSrcweir     pImp->Free();
1419cdf0e10cSrcweir     pImp->ReleaseRef();
1420cdf0e10cSrcweir }
1421cdf0e10cSrcweir 
1422cdf0e10cSrcweir sal_uLong UCBStorageStream::Read( void * pData, sal_uLong nSize )
1423cdf0e10cSrcweir {
1424cdf0e10cSrcweir     //return pImp->m_pStream->Read( pData, nSize );
1425cdf0e10cSrcweir     return pImp->GetData( pData, nSize );
1426cdf0e10cSrcweir }
1427cdf0e10cSrcweir 
1428cdf0e10cSrcweir sal_uLong UCBStorageStream::Write( const void* pData, sal_uLong nSize )
1429cdf0e10cSrcweir {
1430cdf0e10cSrcweir /*
1431cdf0e10cSrcweir     // mba: does occur in writer !
1432cdf0e10cSrcweir     if ( pImp->m_bCommited )
1433cdf0e10cSrcweir     {
1434cdf0e10cSrcweir         DBG_ERROR("Writing while commit is in progress!" );
1435cdf0e10cSrcweir         return 0;
1436cdf0e10cSrcweir     }
1437cdf0e10cSrcweir */
1438cdf0e10cSrcweir     // pImp->m_bModified = sal_True;
1439cdf0e10cSrcweir     //return pImp->m_pStream->Write( pData, nSize );
1440cdf0e10cSrcweir     return pImp->PutData( pData, nSize );
1441cdf0e10cSrcweir }
1442cdf0e10cSrcweir 
1443cdf0e10cSrcweir sal_uLong UCBStorageStream::Seek( sal_uLong nPos )
1444cdf0e10cSrcweir {
1445cdf0e10cSrcweir     //return pImp->m_pStream->Seek( nPos );
1446cdf0e10cSrcweir     return pImp->Seek( nPos );
1447cdf0e10cSrcweir }
1448cdf0e10cSrcweir 
1449cdf0e10cSrcweir sal_uLong UCBStorageStream::Tell()
1450cdf0e10cSrcweir {
1451cdf0e10cSrcweir     if( !pImp->Init() )
1452cdf0e10cSrcweir         return 0;
1453cdf0e10cSrcweir     return pImp->m_pStream->Tell();
1454cdf0e10cSrcweir }
1455cdf0e10cSrcweir 
1456cdf0e10cSrcweir void UCBStorageStream::Flush()
1457cdf0e10cSrcweir {
1458cdf0e10cSrcweir     // streams are never really transacted, so flush also means commit !
1459cdf0e10cSrcweir     Commit();
1460cdf0e10cSrcweir }
1461cdf0e10cSrcweir 
1462cdf0e10cSrcweir sal_Bool UCBStorageStream::SetSize( sal_uLong nNewSize )
1463cdf0e10cSrcweir {
1464cdf0e10cSrcweir /*
1465cdf0e10cSrcweir     if ( pImp->m_bCommited )
1466cdf0e10cSrcweir     {
1467cdf0e10cSrcweir         DBG_ERROR("Changing stream size while commit is in progress!" );
1468cdf0e10cSrcweir         return sal_False;
1469cdf0e10cSrcweir     }
1470cdf0e10cSrcweir */
1471cdf0e10cSrcweir     // pImp->m_bModified = sal_True;
1472cdf0e10cSrcweir     //return pImp->m_pStream->SetStreamSize( nNewSize );
1473cdf0e10cSrcweir     pImp->SetSize( nNewSize );
1474cdf0e10cSrcweir     return !pImp->GetError();
1475cdf0e10cSrcweir }
1476cdf0e10cSrcweir 
1477cdf0e10cSrcweir sal_Bool UCBStorageStream::Validate( sal_Bool bWrite ) const
1478cdf0e10cSrcweir {
1479cdf0e10cSrcweir     return ( !bWrite || ( pImp->m_nMode & STREAM_WRITE ) );
1480cdf0e10cSrcweir }
1481cdf0e10cSrcweir 
1482cdf0e10cSrcweir sal_Bool UCBStorageStream::ValidateMode( StreamMode m ) const
1483cdf0e10cSrcweir {
1484cdf0e10cSrcweir     // ???
1485cdf0e10cSrcweir     if( m == ( STREAM_READ | STREAM_TRUNC ) )  // from stg.cxx
1486cdf0e10cSrcweir         return sal_True;
1487cdf0e10cSrcweir     sal_uInt16 nCurMode = 0xFFFF;
1488cdf0e10cSrcweir     if( ( m & 3 ) == STREAM_READ )
1489cdf0e10cSrcweir     {
1490cdf0e10cSrcweir         // only SHARE_DENYWRITE or SHARE_DENYALL allowed
1491cdf0e10cSrcweir         if( ( ( m & STREAM_SHARE_DENYWRITE )
1492cdf0e10cSrcweir            && ( nCurMode & STREAM_SHARE_DENYWRITE ) )
1493cdf0e10cSrcweir          || ( ( m & STREAM_SHARE_DENYALL )
1494cdf0e10cSrcweir            && ( nCurMode & STREAM_SHARE_DENYALL ) ) )
1495cdf0e10cSrcweir             return sal_True;
1496cdf0e10cSrcweir     }
1497cdf0e10cSrcweir     else
1498cdf0e10cSrcweir     {
1499cdf0e10cSrcweir         // only SHARE_DENYALL allowed
1500cdf0e10cSrcweir         // storages open in r/o mode are OK, since only
1501cdf0e10cSrcweir         // the commit may fail
1502cdf0e10cSrcweir         if( ( m & STREAM_SHARE_DENYALL )
1503cdf0e10cSrcweir          && ( nCurMode & STREAM_SHARE_DENYALL ) )
1504cdf0e10cSrcweir             return sal_True;
1505cdf0e10cSrcweir     }
1506cdf0e10cSrcweir 
1507cdf0e10cSrcweir     return sal_True;
1508cdf0e10cSrcweir }
1509cdf0e10cSrcweir 
1510cdf0e10cSrcweir const SvStream* UCBStorageStream::GetSvStream() const
1511cdf0e10cSrcweir {
1512cdf0e10cSrcweir     if( !pImp->Init() )
1513cdf0e10cSrcweir         return NULL;
1514cdf0e10cSrcweir 
1515cdf0e10cSrcweir     pImp->CopySourceToTemporary();
1516*ecbfceb0Smseidel     return pImp->m_pStream; // should not live longer than pImp!!!
1517cdf0e10cSrcweir }
1518cdf0e10cSrcweir 
1519cdf0e10cSrcweir SvStream* UCBStorageStream::GetModifySvStream()
1520cdf0e10cSrcweir {
1521cdf0e10cSrcweir     return (SvStream*)pImp;
1522cdf0e10cSrcweir }
1523cdf0e10cSrcweir 
1524cdf0e10cSrcweir Reference< XInputStream > UCBStorageStream::GetXInputStream() const
1525cdf0e10cSrcweir {
1526cdf0e10cSrcweir     return pImp->GetXInputStream();
1527cdf0e10cSrcweir }
1528cdf0e10cSrcweir 
1529cdf0e10cSrcweir sal_Bool UCBStorageStream::Equals( const BaseStorageStream& rStream ) const
1530cdf0e10cSrcweir {
1531cdf0e10cSrcweir     // ???
1532cdf0e10cSrcweir     return ((BaseStorageStream*) this ) == &rStream;
1533cdf0e10cSrcweir }
1534cdf0e10cSrcweir 
1535cdf0e10cSrcweir sal_Bool UCBStorageStream::Commit()
1536cdf0e10cSrcweir {
1537cdf0e10cSrcweir     // mark this stream for sending it on root commit
1538cdf0e10cSrcweir     pImp->FlushData();
1539cdf0e10cSrcweir     return sal_True;
1540cdf0e10cSrcweir }
1541cdf0e10cSrcweir 
1542cdf0e10cSrcweir sal_Bool UCBStorageStream::Revert()
1543cdf0e10cSrcweir {
1544cdf0e10cSrcweir     return pImp->Revert();
1545cdf0e10cSrcweir }
1546cdf0e10cSrcweir 
1547cdf0e10cSrcweir sal_Bool UCBStorageStream::CopyTo( BaseStorageStream* pDestStm )
1548cdf0e10cSrcweir {
1549cdf0e10cSrcweir     if( !pImp->Init() )
1550cdf0e10cSrcweir         return sal_False;
1551cdf0e10cSrcweir 
1552cdf0e10cSrcweir     UCBStorageStream* pStg = PTR_CAST( UCBStorageStream, pDestStm );
1553cdf0e10cSrcweir     if ( pStg )
1554cdf0e10cSrcweir         pStg->pImp->m_aContentType = pImp->m_aContentType;
1555cdf0e10cSrcweir 
1556cdf0e10cSrcweir     pDestStm->SetSize( 0 );
1557cdf0e10cSrcweir     Seek( STREAM_SEEK_TO_END );
1558cdf0e10cSrcweir     sal_Int32 n = Tell();
1559cdf0e10cSrcweir     if( n < 0 )
1560cdf0e10cSrcweir         return sal_False;
1561cdf0e10cSrcweir 
1562cdf0e10cSrcweir     if( pDestStm->SetSize( n ) && n )
1563cdf0e10cSrcweir     {
1564cdf0e10cSrcweir         sal_uInt8* p = new sal_uInt8[ 4096 ];
1565cdf0e10cSrcweir         Seek( 0L );
1566cdf0e10cSrcweir         pDestStm->Seek( 0L );
1567cdf0e10cSrcweir         while( n )
1568cdf0e10cSrcweir         {
1569cdf0e10cSrcweir             sal_uInt32 nn = n;
1570cdf0e10cSrcweir             if( nn > 4096 )
1571cdf0e10cSrcweir                 nn = 4096;
1572cdf0e10cSrcweir             if( Read( p, nn ) != nn )
1573cdf0e10cSrcweir                 break;
1574cdf0e10cSrcweir             if( pDestStm->Write( p, nn ) != nn )
1575cdf0e10cSrcweir                 break;
1576cdf0e10cSrcweir             n -= nn;
1577cdf0e10cSrcweir         }
1578cdf0e10cSrcweir 
1579cdf0e10cSrcweir         delete[] p;
1580cdf0e10cSrcweir     }
1581cdf0e10cSrcweir 
1582cdf0e10cSrcweir     return sal_True;
1583cdf0e10cSrcweir }
1584cdf0e10cSrcweir 
1585cdf0e10cSrcweir sal_Bool UCBStorageStream::SetProperty( const String& rName, const ::com::sun::star::uno::Any& rValue )
1586cdf0e10cSrcweir {
1587cdf0e10cSrcweir     if ( rName.CompareToAscii("Title") == COMPARE_EQUAL )
1588cdf0e10cSrcweir         return sal_False;
1589cdf0e10cSrcweir 
1590cdf0e10cSrcweir     if ( rName.CompareToAscii("MediaType") == COMPARE_EQUAL )
1591cdf0e10cSrcweir     {
1592cdf0e10cSrcweir         ::rtl::OUString aTmp;
1593cdf0e10cSrcweir         rValue >>= aTmp;
1594cdf0e10cSrcweir         pImp->m_aContentType = aTmp;
1595cdf0e10cSrcweir     }
1596cdf0e10cSrcweir 
1597cdf0e10cSrcweir     try
1598cdf0e10cSrcweir     {
1599cdf0e10cSrcweir         if ( pImp->m_pContent )
1600cdf0e10cSrcweir         {
1601cdf0e10cSrcweir             pImp->m_pContent->setPropertyValue( rName, rValue );
1602cdf0e10cSrcweir             return sal_True;
1603cdf0e10cSrcweir         }
1604cdf0e10cSrcweir     }
1605cdf0e10cSrcweir     catch ( Exception& )
1606cdf0e10cSrcweir     {
1607cdf0e10cSrcweir     }
1608cdf0e10cSrcweir 
1609cdf0e10cSrcweir     return sal_False;
1610cdf0e10cSrcweir }
1611cdf0e10cSrcweir 
1612cdf0e10cSrcweir sal_Bool UCBStorageStream::GetProperty( const String& rName, ::com::sun::star::uno::Any& rValue )
1613cdf0e10cSrcweir {
1614cdf0e10cSrcweir     try
1615cdf0e10cSrcweir     {
1616cdf0e10cSrcweir         if ( pImp->m_pContent )
1617cdf0e10cSrcweir         {
1618cdf0e10cSrcweir             rValue = pImp->m_pContent->getPropertyValue( rName );
1619cdf0e10cSrcweir             return sal_True;
1620cdf0e10cSrcweir         }
1621cdf0e10cSrcweir     }
1622cdf0e10cSrcweir     catch ( Exception& )
1623cdf0e10cSrcweir     {
1624cdf0e10cSrcweir     }
1625cdf0e10cSrcweir 
1626cdf0e10cSrcweir     return sal_False;
1627cdf0e10cSrcweir }
1628cdf0e10cSrcweir 
1629cdf0e10cSrcweir UCBStorage::UCBStorage( SvStream& rStrm, sal_Bool bDirect )
1630cdf0e10cSrcweir {
1631cdf0e10cSrcweir     String aURL = GetLinkedFile( rStrm );
1632cdf0e10cSrcweir     if ( aURL.Len() )
1633cdf0e10cSrcweir     {
1634cdf0e10cSrcweir         StreamMode nMode = STREAM_READ;
1635cdf0e10cSrcweir         if( rStrm.IsWritable() )
1636cdf0e10cSrcweir             nMode = STREAM_READ | STREAM_WRITE;
1637cdf0e10cSrcweir 
1638cdf0e10cSrcweir         ::ucbhelper::Content aContent( aURL, Reference < XCommandEnvironment >() );
1639cdf0e10cSrcweir         pImp = new UCBStorage_Impl( aContent, aURL, nMode, this, bDirect, sal_True );
1640cdf0e10cSrcweir     }
1641cdf0e10cSrcweir     else
1642cdf0e10cSrcweir     {
1643cdf0e10cSrcweir         // pImp must be initialized in the body, because otherwise the vtable of the stream is not initialized
1644cdf0e10cSrcweir         // to class UCBStorage !
1645cdf0e10cSrcweir         pImp = new UCBStorage_Impl( rStrm, this, bDirect );
1646cdf0e10cSrcweir     }
1647cdf0e10cSrcweir 
1648cdf0e10cSrcweir     pImp->AddRef();
1649cdf0e10cSrcweir     pImp->Init();
1650cdf0e10cSrcweir     StorageBase::m_nMode = pImp->m_nMode;
1651cdf0e10cSrcweir }
1652cdf0e10cSrcweir 
1653cdf0e10cSrcweir UCBStorage::UCBStorage( const ::ucbhelper::Content& rContent, const String& rName, StreamMode nMode, sal_Bool bDirect, sal_Bool bIsRoot )
1654cdf0e10cSrcweir {
1655cdf0e10cSrcweir     // pImp must be initialized in the body, because otherwise the vtable of the stream is not initialized
1656cdf0e10cSrcweir     // to class UCBStorage !
1657cdf0e10cSrcweir     pImp = new UCBStorage_Impl( rContent, rName, nMode, this, bDirect, bIsRoot );
1658cdf0e10cSrcweir     pImp->AddRef();
1659cdf0e10cSrcweir     pImp->Init();
1660cdf0e10cSrcweir     StorageBase::m_nMode = pImp->m_nMode;
1661cdf0e10cSrcweir }
1662cdf0e10cSrcweir 
1663cdf0e10cSrcweir UCBStorage::UCBStorage( const String& rName, StreamMode nMode, sal_Bool bDirect, sal_Bool bIsRoot, sal_Bool bIsRepair, Reference< XProgressHandler > xProgressHandler )
1664cdf0e10cSrcweir {
1665cdf0e10cSrcweir     // pImp must be initialized in the body, because otherwise the vtable of the stream is not initialized
1666cdf0e10cSrcweir     // to class UCBStorage !
1667cdf0e10cSrcweir     pImp = new UCBStorage_Impl( rName, nMode, this, bDirect, bIsRoot, bIsRepair, xProgressHandler );
1668cdf0e10cSrcweir     pImp->AddRef();
1669cdf0e10cSrcweir     pImp->Init();
1670cdf0e10cSrcweir     StorageBase::m_nMode = pImp->m_nMode;
1671cdf0e10cSrcweir }
1672cdf0e10cSrcweir 
1673cdf0e10cSrcweir UCBStorage::UCBStorage( const String& rName, StreamMode nMode, sal_Bool bDirect, sal_Bool bIsRoot )
1674cdf0e10cSrcweir {
1675cdf0e10cSrcweir     // pImp must be initialized in the body, because otherwise the vtable of the stream is not initialized
1676cdf0e10cSrcweir     // to class UCBStorage !
1677cdf0e10cSrcweir     pImp = new UCBStorage_Impl( rName, nMode, this, bDirect, bIsRoot, sal_False, Reference< XProgressHandler >() );
1678cdf0e10cSrcweir     pImp->AddRef();
1679cdf0e10cSrcweir     pImp->Init();
1680cdf0e10cSrcweir     StorageBase::m_nMode = pImp->m_nMode;
1681cdf0e10cSrcweir }
1682cdf0e10cSrcweir 
1683cdf0e10cSrcweir UCBStorage::UCBStorage( UCBStorage_Impl *pImpl )
1684cdf0e10cSrcweir     : pImp( pImpl )
1685cdf0e10cSrcweir {
1686cdf0e10cSrcweir     pImp->m_pAntiImpl = this;
1687cdf0e10cSrcweir     SetError( pImp->m_nError );
1688cdf0e10cSrcweir     pImp->AddRef();             // use direct refcounting because in header file only a pointer should be used
1689cdf0e10cSrcweir     StorageBase::m_nMode = pImp->m_nMode;
1690cdf0e10cSrcweir }
1691cdf0e10cSrcweir 
1692cdf0e10cSrcweir UCBStorage::~UCBStorage()
1693cdf0e10cSrcweir {
1694cdf0e10cSrcweir     if ( pImp->m_bIsRoot && pImp->m_bDirect && ( !pImp->m_pTempFile || pImp->m_pSource ) )
1695cdf0e10cSrcweir         // DirectMode is simulated with an AutoCommit
1696cdf0e10cSrcweir         Commit();
1697cdf0e10cSrcweir 
1698cdf0e10cSrcweir     pImp->m_pAntiImpl = NULL;
1699cdf0e10cSrcweir     pImp->ReleaseRef();
1700cdf0e10cSrcweir }
1701cdf0e10cSrcweir 
1702cdf0e10cSrcweir UCBStorage_Impl::UCBStorage_Impl( const ::ucbhelper::Content& rContent, const String& rName, StreamMode nMode, UCBStorage* pStorage, sal_Bool bDirect, sal_Bool bIsRoot, sal_Bool bIsRepair, Reference< XProgressHandler > xProgressHandler  )
1703cdf0e10cSrcweir     : m_pAntiImpl( pStorage )
1704cdf0e10cSrcweir     , m_pContent( new ::ucbhelper::Content( rContent ) )
1705cdf0e10cSrcweir     , m_pTempFile( NULL )
1706cdf0e10cSrcweir     , m_pSource( NULL )
1707cdf0e10cSrcweir     //, m_pStream( NULL )
1708cdf0e10cSrcweir     , m_nError( 0 )
1709cdf0e10cSrcweir     , m_nMode( nMode )
1710cdf0e10cSrcweir     , m_bModified( sal_False )
1711cdf0e10cSrcweir     , m_bCommited( sal_False )
1712cdf0e10cSrcweir     , m_bDirect( bDirect )
1713cdf0e10cSrcweir     , m_bIsRoot( bIsRoot )
1714cdf0e10cSrcweir     , m_bDirty( sal_False )
1715cdf0e10cSrcweir     , m_bIsLinked( sal_True )
1716cdf0e10cSrcweir     , m_bListCreated( sal_False )
1717cdf0e10cSrcweir     , m_nFormat( 0 )
1718cdf0e10cSrcweir     , m_aClassId( SvGlobalName() )
1719cdf0e10cSrcweir     , m_bRepairPackage( bIsRepair )
1720cdf0e10cSrcweir     , m_xProgressHandler( xProgressHandler )
1721cdf0e10cSrcweir     , m_pUNOStorageHolderList( NULL )
1722cdf0e10cSrcweir 
1723cdf0e10cSrcweir {
1724cdf0e10cSrcweir     String aName( rName );
1725cdf0e10cSrcweir     if( !aName.Len() )
1726cdf0e10cSrcweir     {
1727cdf0e10cSrcweir         // no name given = use temporary name!
1728cdf0e10cSrcweir         DBG_ASSERT( m_bIsRoot, "SubStorage must have a name!" );
1729cdf0e10cSrcweir         m_pTempFile = new ::utl::TempFile;
1730cdf0e10cSrcweir         m_pTempFile->EnableKillingFile( sal_True );
1731cdf0e10cSrcweir         m_aName = m_aOriginalName = aName = m_pTempFile->GetURL();
1732cdf0e10cSrcweir     }
1733cdf0e10cSrcweir 
1734cdf0e10cSrcweir     m_aURL = rName;
1735cdf0e10cSrcweir }
1736cdf0e10cSrcweir 
1737cdf0e10cSrcweir UCBStorage_Impl::UCBStorage_Impl( const String& rName, StreamMode nMode, UCBStorage* pStorage, sal_Bool bDirect, sal_Bool bIsRoot, sal_Bool bIsRepair, Reference< XProgressHandler > xProgressHandler )
1738cdf0e10cSrcweir     : m_pAntiImpl( pStorage )
1739cdf0e10cSrcweir     , m_pContent( NULL )
1740cdf0e10cSrcweir     , m_pTempFile( NULL )
1741cdf0e10cSrcweir     , m_pSource( NULL )
1742cdf0e10cSrcweir     //, m_pStream( NULL )
1743cdf0e10cSrcweir     , m_nError( 0 )
1744cdf0e10cSrcweir     , m_nMode( nMode )
1745cdf0e10cSrcweir     , m_bModified( sal_False )
1746cdf0e10cSrcweir     , m_bCommited( sal_False )
1747cdf0e10cSrcweir     , m_bDirect( bDirect )
1748cdf0e10cSrcweir     , m_bIsRoot( bIsRoot )
1749cdf0e10cSrcweir     , m_bDirty( sal_False )
1750cdf0e10cSrcweir     , m_bIsLinked( sal_False )
1751cdf0e10cSrcweir     , m_bListCreated( sal_False )
1752cdf0e10cSrcweir     , m_nFormat( 0 )
1753cdf0e10cSrcweir     , m_aClassId( SvGlobalName() )
1754cdf0e10cSrcweir     , m_bRepairPackage( bIsRepair )
1755cdf0e10cSrcweir     , m_xProgressHandler( xProgressHandler )
1756cdf0e10cSrcweir     , m_pUNOStorageHolderList( NULL )
1757cdf0e10cSrcweir {
1758cdf0e10cSrcweir     String aName( rName );
1759cdf0e10cSrcweir     if( !aName.Len() )
1760cdf0e10cSrcweir     {
1761cdf0e10cSrcweir         // no name given = use temporary name!
1762cdf0e10cSrcweir         DBG_ASSERT( m_bIsRoot, "SubStorage must have a name!" );
1763cdf0e10cSrcweir         m_pTempFile = new ::utl::TempFile;
1764cdf0e10cSrcweir         m_pTempFile->EnableKillingFile( sal_True );
1765cdf0e10cSrcweir         m_aName = m_aOriginalName = aName = m_pTempFile->GetURL();
1766cdf0e10cSrcweir     }
1767cdf0e10cSrcweir 
1768cdf0e10cSrcweir     if ( m_bIsRoot )
1769cdf0e10cSrcweir     {
1770cdf0e10cSrcweir         // create the special package URL for the package content
1771cdf0e10cSrcweir         String aTemp = String::CreateFromAscii("vnd.sun.star.pkg://");
1772cdf0e10cSrcweir         aTemp += String(INetURLObject::encode( aName, INetURLObject::PART_AUTHORITY, '%', INetURLObject::ENCODE_ALL ));
1773cdf0e10cSrcweir         m_aURL = aTemp;
1774cdf0e10cSrcweir 
1775cdf0e10cSrcweir         if ( m_nMode & STREAM_WRITE )
1776cdf0e10cSrcweir         {
1777cdf0e10cSrcweir             // the root storage opens the package, so make sure that there is any
1778cdf0e10cSrcweir             SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aName, STREAM_STD_READWRITE, m_pTempFile != 0 /* bFileExists */ );
1779cdf0e10cSrcweir             delete pStream;
1780cdf0e10cSrcweir         }
1781cdf0e10cSrcweir     }
1782cdf0e10cSrcweir     else
1783cdf0e10cSrcweir     {
1784cdf0e10cSrcweir         // substorages are opened like streams: the URL is a "child URL" of the root package URL
1785cdf0e10cSrcweir         m_aURL = rName;
1786cdf0e10cSrcweir         if ( m_aURL.CompareToAscii( "vnd.sun.star.pkg://", 19 ) != 0 )
1787cdf0e10cSrcweir             m_bIsLinked = sal_True;
1788cdf0e10cSrcweir     }
1789cdf0e10cSrcweir }
1790cdf0e10cSrcweir 
1791cdf0e10cSrcweir UCBStorage_Impl::UCBStorage_Impl( SvStream& rStream, UCBStorage* pStorage, sal_Bool bDirect )
1792cdf0e10cSrcweir     : m_pAntiImpl( pStorage )
1793cdf0e10cSrcweir     , m_pContent( NULL )
1794cdf0e10cSrcweir     , m_pTempFile( new ::utl::TempFile )
1795cdf0e10cSrcweir     , m_pSource( &rStream )
1796cdf0e10cSrcweir     , m_nError( 0 )
1797cdf0e10cSrcweir     , m_bModified( sal_False )
1798cdf0e10cSrcweir     , m_bCommited( sal_False )
1799cdf0e10cSrcweir     , m_bDirect( bDirect )
1800cdf0e10cSrcweir     , m_bIsRoot( sal_True )
1801cdf0e10cSrcweir     , m_bDirty( sal_False )
1802cdf0e10cSrcweir     , m_bIsLinked( sal_False )
1803cdf0e10cSrcweir     , m_bListCreated( sal_False )
1804cdf0e10cSrcweir     , m_nFormat( 0 )
1805cdf0e10cSrcweir     , m_aClassId( SvGlobalName() )
1806cdf0e10cSrcweir     , m_bRepairPackage( sal_False )
1807cdf0e10cSrcweir     , m_pUNOStorageHolderList( NULL )
1808cdf0e10cSrcweir {
1809cdf0e10cSrcweir     // opening in direct mode is too fuzzy because the data is transferred to the stream in the Commit() call,
1810cdf0e10cSrcweir     // which will be called in the storages' dtor
1811cdf0e10cSrcweir     m_pTempFile->EnableKillingFile( sal_True );
1812cdf0e10cSrcweir     DBG_ASSERT( !bDirect, "Storage on a stream must not be opened in direct mode!" );
1813cdf0e10cSrcweir 
1814cdf0e10cSrcweir     // UCBStorages work on a content, so a temporary file for a content must be created, even if the stream is only
1815cdf0e10cSrcweir     // accessed readonly
1816cdf0e10cSrcweir     // the root storage opens the package; create the special package URL for the package content
1817cdf0e10cSrcweir     String aTemp = String::CreateFromAscii("vnd.sun.star.pkg://");
1818cdf0e10cSrcweir     aTemp += String(INetURLObject::encode( m_pTempFile->GetURL(), INetURLObject::PART_AUTHORITY, '%', INetURLObject::ENCODE_ALL ));
1819cdf0e10cSrcweir     m_aURL = aTemp;
1820cdf0e10cSrcweir 
1821cdf0e10cSrcweir     // copy data into the temporary file
1822cdf0e10cSrcweir     SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( m_pTempFile->GetURL(), STREAM_STD_READWRITE, sal_True /* bFileExists */ );
1823cdf0e10cSrcweir     if ( pStream )
1824cdf0e10cSrcweir     {
1825cdf0e10cSrcweir         rStream.Seek(0);
1826cdf0e10cSrcweir         rStream >> *pStream;
1827cdf0e10cSrcweir         pStream->Flush();
1828cdf0e10cSrcweir         DELETEZ( pStream );
1829cdf0e10cSrcweir     }
1830cdf0e10cSrcweir 
1831cdf0e10cSrcweir     // close stream and let content access the file
1832cdf0e10cSrcweir     m_pSource->Seek(0);
1833cdf0e10cSrcweir 
1834cdf0e10cSrcweir     // check opening mode
1835cdf0e10cSrcweir     m_nMode = STREAM_READ;
1836cdf0e10cSrcweir     if( rStream.IsWritable() )
1837cdf0e10cSrcweir         m_nMode = STREAM_READ | STREAM_WRITE;
1838cdf0e10cSrcweir }
1839cdf0e10cSrcweir 
1840cdf0e10cSrcweir void UCBStorage_Impl::Init()
1841cdf0e10cSrcweir {
1842cdf0e10cSrcweir     // name is last segment in URL
1843cdf0e10cSrcweir     INetURLObject aObj( m_aURL );
1844cdf0e10cSrcweir     if ( !m_aName.Len() )
1845cdf0e10cSrcweir         // if the name was not already set to a temp name
1846cdf0e10cSrcweir         m_aName = m_aOriginalName = aObj.GetLastName();
1847cdf0e10cSrcweir 
1848cdf0e10cSrcweir     // don't create the content for disk spanned files, avoid too early access to directory and/or manifest
1849cdf0e10cSrcweir     if ( !m_pContent && !( m_nMode & STORAGE_DISKSPANNED_MODE ) )
1850cdf0e10cSrcweir         CreateContent();
1851cdf0e10cSrcweir 
1852cdf0e10cSrcweir     if ( m_nMode & STORAGE_DISKSPANNED_MODE )
1853cdf0e10cSrcweir     {
1854cdf0e10cSrcweir         // Hack! Avoid access to the manifest file until mediatype is not available in the first segment of a
1855cdf0e10cSrcweir         // disk spanned file
1856cdf0e10cSrcweir         m_aContentType = m_aOriginalContentType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("application/vnd.sun.xml.impress") );
1857cdf0e10cSrcweir     }
1858cdf0e10cSrcweir     else if ( m_pContent )
1859cdf0e10cSrcweir     {
1860cdf0e10cSrcweir         if ( m_bIsLinked )
1861cdf0e10cSrcweir         {
1862cdf0e10cSrcweir             if( m_bIsRoot )
1863cdf0e10cSrcweir             {
1864cdf0e10cSrcweir                 ReadContent();
1865cdf0e10cSrcweir                 if ( m_nError == ERRCODE_NONE )
1866cdf0e10cSrcweir                 {
1867cdf0e10cSrcweir                     // read the manifest.xml file
1868cdf0e10cSrcweir                     aObj.Append( String( RTL_CONSTASCII_USTRINGPARAM("META-INF") ) );
1869cdf0e10cSrcweir                     aObj.Append( String( RTL_CONSTASCII_USTRINGPARAM("manifest.xml") ) );
1870cdf0e10cSrcweir 
1871cdf0e10cSrcweir                     // create input stream
1872cdf0e10cSrcweir                     SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aObj.GetMainURL( INetURLObject::NO_DECODE ), STREAM_STD_READ );
1873cdf0e10cSrcweir                     // no stream means no manifest.xml
1874cdf0e10cSrcweir                     if ( pStream )
1875cdf0e10cSrcweir                     {
1876cdf0e10cSrcweir                         if ( !pStream->GetError() )
1877cdf0e10cSrcweir                         {
1878cdf0e10cSrcweir                             ::utl::OInputStreamWrapper* pHelper = new ::utl::OInputStreamWrapper( *pStream );
1879cdf0e10cSrcweir                             com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream > xInputStream( pHelper );
1880cdf0e10cSrcweir 
1881cdf0e10cSrcweir                             // create a manifest reader object that will read in the manifest from the stream
1882cdf0e10cSrcweir                             Reference < ::com::sun::star::packages::manifest::XManifestReader > xReader =
1883cdf0e10cSrcweir                                 Reference< ::com::sun::star::packages::manifest::XManifestReader >
1884cdf0e10cSrcweir                                     ( ::comphelper::getProcessServiceFactory()->createInstance(
1885cdf0e10cSrcweir                                         ::rtl::OUString::createFromAscii( "com.sun.star.packages.manifest.ManifestReader" )), UNO_QUERY) ;
1886cdf0e10cSrcweir                             Sequence < Sequence < PropertyValue > > aProps = xReader->readManifestSequence( xInputStream );
1887cdf0e10cSrcweir 
1888cdf0e10cSrcweir                             // cleanup
1889cdf0e10cSrcweir                             xReader = NULL;
1890cdf0e10cSrcweir                             xInputStream = NULL;
1891cdf0e10cSrcweir                             SetProps( aProps, String() );
1892cdf0e10cSrcweir                         }
1893cdf0e10cSrcweir 
1894cdf0e10cSrcweir                         delete pStream;
1895cdf0e10cSrcweir                     }
1896cdf0e10cSrcweir                 }
1897cdf0e10cSrcweir             }
1898cdf0e10cSrcweir             else
1899cdf0e10cSrcweir                 ReadContent();
1900cdf0e10cSrcweir         }
1901cdf0e10cSrcweir         else
1902cdf0e10cSrcweir         {
1903cdf0e10cSrcweir             // get the manifest information from the package
1904cdf0e10cSrcweir             try {
1905cdf0e10cSrcweir                 Any aAny = m_pContent->getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) );
1906cdf0e10cSrcweir                 rtl::OUString aTmp;
1907cdf0e10cSrcweir                 if ( ( aAny >>= aTmp ) && aTmp.getLength() )
1908cdf0e10cSrcweir                     m_aContentType = m_aOriginalContentType = aTmp;
1909cdf0e10cSrcweir             }
1910cdf0e10cSrcweir             catch( Exception& )
1911cdf0e10cSrcweir             {
1912cdf0e10cSrcweir                 DBG_ASSERT( sal_False,
1913cdf0e10cSrcweir                             "getPropertyValue has thrown an exception! Please let developers know the scenario!" );
1914cdf0e10cSrcweir             }
1915cdf0e10cSrcweir         }
1916cdf0e10cSrcweir     }
1917cdf0e10cSrcweir 
1918cdf0e10cSrcweir     if ( m_aContentType.Len() )
1919cdf0e10cSrcweir     {
1920cdf0e10cSrcweir         // get the clipboard format using the content type
1921cdf0e10cSrcweir         ::com::sun::star::datatransfer::DataFlavor aDataFlavor;
1922cdf0e10cSrcweir         aDataFlavor.MimeType = m_aContentType;
1923cdf0e10cSrcweir         m_nFormat = SotExchange::GetFormat( aDataFlavor );
1924cdf0e10cSrcweir 
1925cdf0e10cSrcweir         // get the ClassId using the clipboard format ( internal table )
1926cdf0e10cSrcweir         m_aClassId = GetClassId_Impl( m_nFormat );
1927cdf0e10cSrcweir 
1928cdf0e10cSrcweir         // get human presentable name using the clipboard format
1929cdf0e10cSrcweir         SotExchange::GetFormatDataFlavor( m_nFormat, aDataFlavor );
1930cdf0e10cSrcweir         m_aUserTypeName = aDataFlavor.HumanPresentableName;
1931cdf0e10cSrcweir 
1932cdf0e10cSrcweir         if( m_pContent && !m_bIsLinked && m_aClassId != SvGlobalName() )
1933cdf0e10cSrcweir             ReadContent();
1934cdf0e10cSrcweir     }
1935cdf0e10cSrcweir }
1936cdf0e10cSrcweir 
1937cdf0e10cSrcweir void UCBStorage_Impl::CreateContent()
1938cdf0e10cSrcweir {
1939cdf0e10cSrcweir     try
1940cdf0e10cSrcweir     {
1941cdf0e10cSrcweir         // create content; where to put StreamMode ?! ( already done when opening the file of the package ? )
1942cdf0e10cSrcweir         Reference< ::com::sun::star::ucb::XCommandEnvironment > xComEnv;
1943cdf0e10cSrcweir 
1944cdf0e10cSrcweir         ::rtl::OUString aTemp( m_aURL );
1945cdf0e10cSrcweir 
1946cdf0e10cSrcweir         if ( m_bRepairPackage )
1947cdf0e10cSrcweir         {
1948cdf0e10cSrcweir             xComEnv = new ::ucbhelper::CommandEnvironment( Reference< ::com::sun::star::task::XInteractionHandler >(),
1949cdf0e10cSrcweir                                                      m_xProgressHandler );
1950cdf0e10cSrcweir             aTemp += rtl::OUString::createFromAscii("?repairpackage");
1951cdf0e10cSrcweir         }
1952cdf0e10cSrcweir 
1953cdf0e10cSrcweir         m_pContent = new ::ucbhelper::Content( aTemp, xComEnv );
1954cdf0e10cSrcweir     }
1955cdf0e10cSrcweir     catch ( ContentCreationException& )
1956cdf0e10cSrcweir     {
1957cdf0e10cSrcweir         // content could not be created
1958cdf0e10cSrcweir         SetError( SVSTREAM_CANNOT_MAKE );
1959cdf0e10cSrcweir     }
1960cdf0e10cSrcweir     catch ( RuntimeException& )
1961cdf0e10cSrcweir     {
1962cdf0e10cSrcweir         // any other error - not specified
1963cdf0e10cSrcweir         SetError( SVSTREAM_CANNOT_MAKE );
1964cdf0e10cSrcweir     }
1965cdf0e10cSrcweir }
1966cdf0e10cSrcweir 
1967cdf0e10cSrcweir void UCBStorage_Impl::ReadContent()
1968cdf0e10cSrcweir {
1969cdf0e10cSrcweir    if ( m_bListCreated )
1970cdf0e10cSrcweir         return;
1971cdf0e10cSrcweir 
1972cdf0e10cSrcweir     m_bListCreated = sal_True;
1973cdf0e10cSrcweir 
1974cdf0e10cSrcweir     // create cursor for access to children
1975cdf0e10cSrcweir     Sequence< ::rtl::OUString > aProps(4);
1976cdf0e10cSrcweir     ::rtl::OUString* pProps = aProps.getArray();
1977cdf0e10cSrcweir     pProps[0] = ::rtl::OUString::createFromAscii( "Title" );
1978cdf0e10cSrcweir     pProps[1] = ::rtl::OUString::createFromAscii( "IsFolder" );
1979cdf0e10cSrcweir     pProps[2] = ::rtl::OUString::createFromAscii( "MediaType" );
1980cdf0e10cSrcweir     pProps[3] = ::rtl::OUString::createFromAscii( "Size" );
1981cdf0e10cSrcweir     ::ucbhelper::ResultSetInclude eInclude = ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS;
1982cdf0e10cSrcweir 
1983cdf0e10cSrcweir     try
1984cdf0e10cSrcweir     {
1985cdf0e10cSrcweir         GetContent();
1986cdf0e10cSrcweir         if ( !m_pContent )
1987cdf0e10cSrcweir             return;
1988cdf0e10cSrcweir 
1989cdf0e10cSrcweir         Reference< XResultSet > xResultSet = m_pContent->createCursor( aProps, eInclude );
1990cdf0e10cSrcweir         Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
1991cdf0e10cSrcweir         Reference< XRow > xRow( xResultSet, UNO_QUERY );
1992cdf0e10cSrcweir         if ( xResultSet.is() )
1993cdf0e10cSrcweir         {
1994cdf0e10cSrcweir             while ( xResultSet->next() )
1995cdf0e10cSrcweir             {
1996cdf0e10cSrcweir                 // insert all into the children list
1997cdf0e10cSrcweir                 ::rtl::OUString aTitle( xRow->getString(1) );
1998cdf0e10cSrcweir                 ::rtl::OUString aContentType;
1999cdf0e10cSrcweir                 if ( m_bIsLinked )
2000cdf0e10cSrcweir                 {
2001cdf0e10cSrcweir                     // unpacked storages have to deal with the meta-inf folder by themselves
2002cdf0e10cSrcweir                     if( aTitle.equalsAscii("META-INF") )
2003cdf0e10cSrcweir                         continue;
2004cdf0e10cSrcweir                 }
2005cdf0e10cSrcweir                 else
2006cdf0e10cSrcweir                 {
2007cdf0e10cSrcweir                     aContentType = xRow->getString(3);
2008cdf0e10cSrcweir                 }
2009cdf0e10cSrcweir 
2010cdf0e10cSrcweir                 sal_Bool bIsFolder( xRow->getBoolean(2) );
2011cdf0e10cSrcweir                 sal_Int64 nSize = xRow->getLong(4);
2012cdf0e10cSrcweir                 UCBStorageElement_Impl* pElement = new UCBStorageElement_Impl( aTitle, bIsFolder, (sal_uLong) nSize );
2013cdf0e10cSrcweir                 m_aChildrenList.Insert( pElement, LIST_APPEND );
2014cdf0e10cSrcweir 
2015cdf0e10cSrcweir                 sal_Bool bIsOfficeDocument = m_bIsLinked || ( m_aClassId != SvGlobalName() );
2016cdf0e10cSrcweir                 if ( bIsFolder )
2017cdf0e10cSrcweir                 {
2018cdf0e10cSrcweir                     if ( m_bIsLinked )
2019cdf0e10cSrcweir                         OpenStorage( pElement, m_nMode, m_bDirect );
2020cdf0e10cSrcweir                     if ( pElement->m_xStorage.Is() )
2021cdf0e10cSrcweir                         pElement->m_xStorage->Init();
2022cdf0e10cSrcweir                 }
2023cdf0e10cSrcweir                 else if ( bIsOfficeDocument )
2024cdf0e10cSrcweir                 {
2025cdf0e10cSrcweir                     // streams can be external OLE objects, so they are now folders, but storages!
2026cdf0e10cSrcweir                     String aName( m_aURL );
2027cdf0e10cSrcweir                     aName += '/';
2028cdf0e10cSrcweir                     aName += String( xRow->getString(1) );
2029cdf0e10cSrcweir 
2030cdf0e10cSrcweir                     Reference< ::com::sun::star::ucb::XCommandEnvironment > xComEnv;
2031cdf0e10cSrcweir                     if ( m_bRepairPackage )
2032cdf0e10cSrcweir                     {
2033cdf0e10cSrcweir                         xComEnv = new ::ucbhelper::CommandEnvironment( Reference< ::com::sun::star::task::XInteractionHandler >(),
2034cdf0e10cSrcweir                                                                 m_xProgressHandler );
2035cdf0e10cSrcweir                             aName += String( RTL_CONSTASCII_USTRINGPARAM( "?repairpackage" ) );
2036cdf0e10cSrcweir                     }
2037cdf0e10cSrcweir 
2038cdf0e10cSrcweir                     ::ucbhelper::Content aContent( aName, xComEnv );
2039cdf0e10cSrcweir 
2040cdf0e10cSrcweir                     ::rtl::OUString aMediaType;
2041cdf0e10cSrcweir                     Any aAny = aContent.getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) );
2042cdf0e10cSrcweir                     if ( ( aAny >>= aMediaType ) && ( aMediaType.compareToAscii("application/vnd.sun.star.oleobject") == 0 ) )
2043cdf0e10cSrcweir                         pElement->m_bIsStorage = sal_True;
2044cdf0e10cSrcweir                     else if ( !aMediaType.getLength() )
2045cdf0e10cSrcweir                     {
2046cdf0e10cSrcweir                         // older files didn't have that special content type, so they must be detected
2047cdf0e10cSrcweir                         OpenStream( pElement, STREAM_STD_READ, m_bDirect );
2048cdf0e10cSrcweir                         if ( Storage::IsStorageFile( pElement->m_xStream ) )
2049cdf0e10cSrcweir                             pElement->m_bIsStorage = sal_True;
2050cdf0e10cSrcweir                         else
2051cdf0e10cSrcweir                             pElement->m_xStream->Free();
2052cdf0e10cSrcweir                     }
2053cdf0e10cSrcweir                 }
2054cdf0e10cSrcweir             }
2055cdf0e10cSrcweir         }
2056cdf0e10cSrcweir     }
2057cdf0e10cSrcweir     catch ( InteractiveIOException& r )
2058cdf0e10cSrcweir     {
2059cdf0e10cSrcweir         if ( r.Code != IOErrorCode_NOT_EXISTING )
2060cdf0e10cSrcweir             SetError( ERRCODE_IO_GENERAL );
2061cdf0e10cSrcweir     }
2062cdf0e10cSrcweir     catch ( CommandAbortedException& )
2063cdf0e10cSrcweir     {
2064cdf0e10cSrcweir         // any command wasn't executed successfully - not specified
2065cdf0e10cSrcweir         if ( !( m_nMode & STREAM_WRITE ) )
2066*ecbfceb0Smseidel             // if the folder was just inserted and not already committed, this is not an error!
2067cdf0e10cSrcweir             SetError( ERRCODE_IO_GENERAL );
2068cdf0e10cSrcweir     }
2069cdf0e10cSrcweir     catch ( RuntimeException& )
2070cdf0e10cSrcweir     {
2071cdf0e10cSrcweir         // any other error - not specified
2072cdf0e10cSrcweir         SetError( ERRCODE_IO_GENERAL );
2073cdf0e10cSrcweir     }
2074cdf0e10cSrcweir     catch ( ResultSetException& )
2075cdf0e10cSrcweir     {
2076cdf0e10cSrcweir         // means that the package file is broken
2077cdf0e10cSrcweir         SetError( ERRCODE_IO_BROKENPACKAGE );
2078cdf0e10cSrcweir     }
2079cdf0e10cSrcweir     catch ( SQLException& )
2080cdf0e10cSrcweir     {
2081cdf0e10cSrcweir         // means that the file can be broken
2082cdf0e10cSrcweir         SetError( ERRCODE_IO_WRONGFORMAT );
2083cdf0e10cSrcweir     }
2084cdf0e10cSrcweir     catch ( Exception& )
2085cdf0e10cSrcweir     {
2086cdf0e10cSrcweir         // any other error - not specified
2087cdf0e10cSrcweir         SetError( ERRCODE_IO_GENERAL );
2088cdf0e10cSrcweir     }
2089cdf0e10cSrcweir }
2090cdf0e10cSrcweir 
2091cdf0e10cSrcweir void UCBStorage_Impl::SetError( long nError )
2092cdf0e10cSrcweir {
2093cdf0e10cSrcweir     if ( !m_nError )
2094cdf0e10cSrcweir     {
2095cdf0e10cSrcweir         m_nError = nError;
2096cdf0e10cSrcweir         if ( m_pAntiImpl ) m_pAntiImpl->SetError( nError );
2097cdf0e10cSrcweir     }
2098cdf0e10cSrcweir }
2099cdf0e10cSrcweir 
2100cdf0e10cSrcweir sal_Int32 UCBStorage_Impl::GetObjectCount()
2101cdf0e10cSrcweir {
2102cdf0e10cSrcweir     sal_Int32 nCount = m_aChildrenList.Count();
2103cdf0e10cSrcweir     UCBStorageElement_Impl* pElement = m_aChildrenList.First();
2104cdf0e10cSrcweir     while ( pElement )
2105cdf0e10cSrcweir     {
2106cdf0e10cSrcweir         DBG_ASSERT( !pElement->m_bIsFolder || pElement->m_xStorage.Is(), "Storage should be open!" );
2107cdf0e10cSrcweir         if ( pElement->m_bIsFolder && pElement->m_xStorage.Is() )
2108cdf0e10cSrcweir             nCount += pElement->m_xStorage->GetObjectCount();
2109cdf0e10cSrcweir         pElement = m_aChildrenList.Next();
2110cdf0e10cSrcweir     }
2111cdf0e10cSrcweir 
2112cdf0e10cSrcweir     return nCount;
2113cdf0e10cSrcweir }
2114cdf0e10cSrcweir 
2115cdf0e10cSrcweir ::rtl::OUString Find_Impl( const Sequence < Sequence < PropertyValue > >& rSequence, const ::rtl::OUString& rPath )
2116cdf0e10cSrcweir {
2117cdf0e10cSrcweir     sal_Bool bFound = sal_False;
2118cdf0e10cSrcweir     for ( sal_Int32 nSeqs=0; nSeqs<rSequence.getLength(); nSeqs++ )
2119cdf0e10cSrcweir     {
2120cdf0e10cSrcweir         const Sequence < PropertyValue >& rMyProps = rSequence[nSeqs];
2121cdf0e10cSrcweir         ::rtl::OUString aType;
2122cdf0e10cSrcweir 
2123cdf0e10cSrcweir         for ( sal_Int32 nProps=0; nProps<rMyProps.getLength(); nProps++ )
2124cdf0e10cSrcweir         {
2125cdf0e10cSrcweir             const PropertyValue& rAny = rMyProps[nProps];
2126cdf0e10cSrcweir             if ( rAny.Name.equalsAscii("FullPath") )
2127cdf0e10cSrcweir             {
2128cdf0e10cSrcweir                 rtl::OUString aTmp;
2129cdf0e10cSrcweir                 if ( ( rAny.Value >>= aTmp ) && aTmp == rPath )
2130cdf0e10cSrcweir                     bFound = sal_True;
2131cdf0e10cSrcweir                 if ( aType.getLength() )
2132cdf0e10cSrcweir                     break;
2133cdf0e10cSrcweir             }
2134cdf0e10cSrcweir             else if ( rAny.Name.equalsAscii("MediaType") )
2135cdf0e10cSrcweir             {
2136cdf0e10cSrcweir                 if ( ( rAny.Value >>= aType ) && aType.getLength() && bFound )
2137cdf0e10cSrcweir                     break;
2138cdf0e10cSrcweir             }
2139cdf0e10cSrcweir         }
2140cdf0e10cSrcweir 
2141cdf0e10cSrcweir         if ( bFound )
2142cdf0e10cSrcweir             return aType;
2143cdf0e10cSrcweir     }
2144cdf0e10cSrcweir 
2145cdf0e10cSrcweir     return ::rtl::OUString();
2146cdf0e10cSrcweir }
2147cdf0e10cSrcweir 
2148cdf0e10cSrcweir void UCBStorage_Impl::SetProps( const Sequence < Sequence < PropertyValue > >& rSequence, const String& rPath )
2149cdf0e10cSrcweir {
2150cdf0e10cSrcweir     String aPath( rPath );
2151cdf0e10cSrcweir     if ( !m_bIsRoot )
2152cdf0e10cSrcweir         aPath += m_aName;
2153cdf0e10cSrcweir     aPath += '/';
2154cdf0e10cSrcweir 
2155cdf0e10cSrcweir     m_aContentType = m_aOriginalContentType = Find_Impl( rSequence, aPath );
2156cdf0e10cSrcweir 
2157cdf0e10cSrcweir     if ( m_bIsRoot )
2158cdf0e10cSrcweir         // the "FullPath" of a child always starts without '/'
2159cdf0e10cSrcweir         aPath.Erase();
2160cdf0e10cSrcweir 
2161cdf0e10cSrcweir     UCBStorageElement_Impl* pElement = m_aChildrenList.First();
2162cdf0e10cSrcweir     while ( pElement )
2163cdf0e10cSrcweir     {
2164cdf0e10cSrcweir         DBG_ASSERT( !pElement->m_bIsFolder || pElement->m_xStorage.Is(), "Storage should be open!" );
2165cdf0e10cSrcweir         if ( pElement->m_bIsFolder && pElement->m_xStorage.Is() )
2166cdf0e10cSrcweir             pElement->m_xStorage->SetProps( rSequence, aPath );
2167cdf0e10cSrcweir         else
2168cdf0e10cSrcweir         {
2169cdf0e10cSrcweir             String aElementPath( aPath );
2170cdf0e10cSrcweir             aElementPath += pElement->m_aName;
2171cdf0e10cSrcweir             pElement->SetContentType( Find_Impl( rSequence, aElementPath ) );
2172cdf0e10cSrcweir         }
2173cdf0e10cSrcweir 
2174cdf0e10cSrcweir         pElement = m_aChildrenList.Next();
2175cdf0e10cSrcweir     }
2176cdf0e10cSrcweir 
2177cdf0e10cSrcweir     if ( m_aContentType.Len() )
2178cdf0e10cSrcweir     {
2179cdf0e10cSrcweir         // get the clipboard format using the content type
2180cdf0e10cSrcweir         ::com::sun::star::datatransfer::DataFlavor aDataFlavor;
2181cdf0e10cSrcweir         aDataFlavor.MimeType = m_aContentType;
2182cdf0e10cSrcweir         m_nFormat = SotExchange::GetFormat( aDataFlavor );
2183cdf0e10cSrcweir 
2184cdf0e10cSrcweir         // get the ClassId using the clipboard format ( internal table )
2185cdf0e10cSrcweir         m_aClassId = GetClassId_Impl( m_nFormat );
2186cdf0e10cSrcweir 
2187cdf0e10cSrcweir         // get human presentable name using the clipboard format
2188cdf0e10cSrcweir         SotExchange::GetFormatDataFlavor( m_nFormat, aDataFlavor );
2189cdf0e10cSrcweir         m_aUserTypeName = aDataFlavor.HumanPresentableName;
2190cdf0e10cSrcweir     }
2191cdf0e10cSrcweir }
2192cdf0e10cSrcweir 
2193cdf0e10cSrcweir void UCBStorage_Impl::GetProps( sal_Int32& nProps, Sequence < Sequence < PropertyValue > >& rSequence, const String& rPath )
2194cdf0e10cSrcweir {
2195cdf0e10cSrcweir     // first my own properties
2196cdf0e10cSrcweir     Sequence < PropertyValue > aProps(2);
2197cdf0e10cSrcweir 
2198cdf0e10cSrcweir     // first property is the "FullPath" name
2199cdf0e10cSrcweir     // it's '/' for the root storage and m_aName for each element, followed by a '/' if it's a folder
2200cdf0e10cSrcweir     String aPath( rPath );
2201cdf0e10cSrcweir     if ( !m_bIsRoot )
2202cdf0e10cSrcweir         aPath += m_aName;
2203cdf0e10cSrcweir     aPath += '/';
2204cdf0e10cSrcweir     aProps[0].Name = ::rtl::OUString::createFromAscii("MediaType");
2205cdf0e10cSrcweir     aProps[0].Value <<= (::rtl::OUString ) m_aContentType;
2206cdf0e10cSrcweir     aProps[1].Name = ::rtl::OUString::createFromAscii("FullPath");
2207cdf0e10cSrcweir     aProps[1].Value <<= (::rtl::OUString ) aPath;
2208cdf0e10cSrcweir     rSequence[ nProps++ ] = aProps;
2209cdf0e10cSrcweir 
2210cdf0e10cSrcweir     if ( m_bIsRoot )
2211cdf0e10cSrcweir         // the "FullPath" of a child always starts without '/'
2212cdf0e10cSrcweir         aPath.Erase();
2213cdf0e10cSrcweir 
2214cdf0e10cSrcweir     // now the properties of my elements
2215cdf0e10cSrcweir     UCBStorageElement_Impl* pElement = m_aChildrenList.First();
2216cdf0e10cSrcweir     while ( pElement )
2217cdf0e10cSrcweir     {
2218cdf0e10cSrcweir         DBG_ASSERT( !pElement->m_bIsFolder || pElement->m_xStorage.Is(), "Storage should be open!" );
2219cdf0e10cSrcweir         if ( pElement->m_bIsFolder && pElement->m_xStorage.Is() )
2220cdf0e10cSrcweir             // storages add there properties by themselves ( see above )
2221cdf0e10cSrcweir             pElement->m_xStorage->GetProps( nProps, rSequence, aPath );
2222cdf0e10cSrcweir         else
2223cdf0e10cSrcweir         {
2224cdf0e10cSrcweir             // properties of streams
2225cdf0e10cSrcweir             String aElementPath( aPath );
2226cdf0e10cSrcweir             aElementPath += pElement->m_aName;
2227cdf0e10cSrcweir             aProps[0].Name = ::rtl::OUString::createFromAscii("MediaType");
2228cdf0e10cSrcweir             aProps[0].Value <<= (::rtl::OUString ) pElement->GetContentType();
2229cdf0e10cSrcweir             aProps[1].Name = ::rtl::OUString::createFromAscii("FullPath");
2230cdf0e10cSrcweir             aProps[1].Value <<= (::rtl::OUString ) aElementPath;
2231cdf0e10cSrcweir             rSequence[ nProps++ ] = aProps;
2232cdf0e10cSrcweir         }
2233cdf0e10cSrcweir 
2234cdf0e10cSrcweir         pElement = m_aChildrenList.Next();
2235cdf0e10cSrcweir     }
2236cdf0e10cSrcweir }
2237cdf0e10cSrcweir 
2238cdf0e10cSrcweir UCBStorage_Impl::~UCBStorage_Impl()
2239cdf0e10cSrcweir {
2240cdf0e10cSrcweir     if ( m_pUNOStorageHolderList )
2241cdf0e10cSrcweir     {
2242cdf0e10cSrcweir         for ( UNOStorageHolderList::iterator aIter = m_pUNOStorageHolderList->begin();
2243cdf0e10cSrcweir               aIter != m_pUNOStorageHolderList->end(); aIter++ )
2244cdf0e10cSrcweir             if ( *aIter )
2245cdf0e10cSrcweir             {
2246cdf0e10cSrcweir                 (*aIter)->InternalDispose();
2247cdf0e10cSrcweir                 (*aIter)->release();
2248cdf0e10cSrcweir                 (*aIter) = NULL;
2249cdf0e10cSrcweir             }
2250cdf0e10cSrcweir 
2251cdf0e10cSrcweir         m_pUNOStorageHolderList->clear();
2252cdf0e10cSrcweir         DELETEZ( m_pUNOStorageHolderList );
2253cdf0e10cSrcweir     }
2254cdf0e10cSrcweir 
2255cdf0e10cSrcweir     // first delete elements!
2256cdf0e10cSrcweir     UCBStorageElement_Impl* pElement = m_aChildrenList.First();
2257cdf0e10cSrcweir     while ( pElement )
2258cdf0e10cSrcweir     {
2259cdf0e10cSrcweir         delete pElement;
2260cdf0e10cSrcweir         pElement = m_aChildrenList.Next();
2261cdf0e10cSrcweir     }
2262cdf0e10cSrcweir 
2263cdf0e10cSrcweir     m_aChildrenList.Clear();
2264cdf0e10cSrcweir     delete m_pContent;
2265cdf0e10cSrcweir     delete m_pTempFile;
2266cdf0e10cSrcweir }
2267cdf0e10cSrcweir 
2268cdf0e10cSrcweir sal_Bool UCBStorage_Impl::Insert( ::ucbhelper::Content *pContent )
2269cdf0e10cSrcweir {
2270cdf0e10cSrcweir     // a new substorage is inserted into a UCBStorage ( given by the parameter pContent )
2271cdf0e10cSrcweir     // it must be inserted with a title and a type
2272cdf0e10cSrcweir     sal_Bool bRet = sal_False;
2273cdf0e10cSrcweir 
2274cdf0e10cSrcweir     try
2275cdf0e10cSrcweir     {
2276cdf0e10cSrcweir         Sequence< ContentInfo > aInfo = pContent->queryCreatableContentsInfo();
2277cdf0e10cSrcweir         sal_Int32 nCount = aInfo.getLength();
2278cdf0e10cSrcweir         if ( nCount == 0 )
2279cdf0e10cSrcweir             return sal_False;
2280cdf0e10cSrcweir 
2281cdf0e10cSrcweir         for ( sal_Int32 i = 0; i < nCount; ++i )
2282cdf0e10cSrcweir         {
2283cdf0e10cSrcweir             // Simply look for the first KIND_FOLDER...
2284cdf0e10cSrcweir             const ContentInfo & rCurr = aInfo[i];
2285cdf0e10cSrcweir             if ( rCurr.Attributes & ContentInfoAttribute::KIND_FOLDER )
2286cdf0e10cSrcweir             {
2287cdf0e10cSrcweir                 // Make sure the only required bootstrap property is "Title",
2288cdf0e10cSrcweir                 const Sequence< Property > & rProps = rCurr.Properties;
2289cdf0e10cSrcweir                 if ( rProps.getLength() != 1 )
2290cdf0e10cSrcweir                     continue;
2291cdf0e10cSrcweir 
2292cdf0e10cSrcweir                 if ( !rProps[ 0 ].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
2293cdf0e10cSrcweir                     continue;
2294cdf0e10cSrcweir 
2295cdf0e10cSrcweir                 Sequence < ::rtl::OUString > aNames(1);
2296cdf0e10cSrcweir                 ::rtl::OUString* pNames = aNames.getArray();
2297cdf0e10cSrcweir                 pNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) );
2298cdf0e10cSrcweir                 Sequence < Any > aValues(1);
2299cdf0e10cSrcweir                 Any* pValues = aValues.getArray();
2300cdf0e10cSrcweir                 pValues[0] = makeAny( ::rtl::OUString( m_aName ) );
2301cdf0e10cSrcweir 
2302cdf0e10cSrcweir                 Content aNewFolder;
2303cdf0e10cSrcweir                 if ( !pContent->insertNewContent( rCurr.Type, aNames, aValues, aNewFolder ) )
2304cdf0e10cSrcweir                     continue;
2305cdf0e10cSrcweir 
2306cdf0e10cSrcweir                 // remove old content, create an "empty" new one and initialize it with the new inserted
2307cdf0e10cSrcweir                 DELETEZ( m_pContent );
2308cdf0e10cSrcweir                 m_pContent = new ::ucbhelper::Content( aNewFolder );
2309cdf0e10cSrcweir                 bRet = sal_True;
2310cdf0e10cSrcweir             }
2311cdf0e10cSrcweir         }
2312cdf0e10cSrcweir     }
2313cdf0e10cSrcweir     catch ( CommandAbortedException& )
2314cdf0e10cSrcweir     {
2315cdf0e10cSrcweir         // any command wasn't executed successfully - not specified
2316cdf0e10cSrcweir         SetError( ERRCODE_IO_GENERAL );
2317cdf0e10cSrcweir     }
2318cdf0e10cSrcweir     catch ( RuntimeException& )
2319cdf0e10cSrcweir     {
2320cdf0e10cSrcweir         // any other error - not specified
2321cdf0e10cSrcweir         SetError( ERRCODE_IO_GENERAL );
2322cdf0e10cSrcweir     }
2323cdf0e10cSrcweir     catch ( Exception& )
2324cdf0e10cSrcweir     {
2325cdf0e10cSrcweir         // any other error - not specified
2326cdf0e10cSrcweir         SetError( ERRCODE_IO_GENERAL );
2327cdf0e10cSrcweir     }
2328cdf0e10cSrcweir 
2329cdf0e10cSrcweir     return bRet;
2330cdf0e10cSrcweir }
2331cdf0e10cSrcweir 
2332cdf0e10cSrcweir sal_Int16 UCBStorage_Impl::Commit()
2333cdf0e10cSrcweir {
2334cdf0e10cSrcweir     // send all changes to the package
2335cdf0e10cSrcweir     UCBStorageElement_Impl* pElement = m_aChildrenList.First();
2336cdf0e10cSrcweir     sal_Int16 nRet = COMMIT_RESULT_NOTHING_TO_DO;
2337cdf0e10cSrcweir 
2338cdf0e10cSrcweir     // there is nothing to do if the storage has been opened readonly or if it was opened in transacted mode and no
2339cdf0e10cSrcweir     // commit command has been sent
2340cdf0e10cSrcweir     if ( ( m_nMode & STREAM_WRITE ) && ( m_bCommited || m_bDirect ) )
2341cdf0e10cSrcweir     {
2342cdf0e10cSrcweir         try
2343cdf0e10cSrcweir         {
2344cdf0e10cSrcweir             // all errors will be caught in the "catch" statement outside the loop
2345cdf0e10cSrcweir             while ( pElement && nRet )
2346cdf0e10cSrcweir             {
2347cdf0e10cSrcweir                 ::ucbhelper::Content* pContent = pElement->GetContent();
2348cdf0e10cSrcweir                 sal_Bool bDeleteContent = sal_False;
2349cdf0e10cSrcweir                 if ( !pContent && pElement->IsModified() )
2350cdf0e10cSrcweir                 {
2351cdf0e10cSrcweir                     // if the element has never been opened, no content has been created until now
2352cdf0e10cSrcweir                     bDeleteContent = sal_True;  // remember to delete it later
2353cdf0e10cSrcweir                     String aName( m_aURL );
2354cdf0e10cSrcweir                     aName += '/';
2355cdf0e10cSrcweir                     aName += pElement->m_aOriginalName;
2356cdf0e10cSrcweir                     pContent = new ::ucbhelper::Content( aName, Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
2357cdf0e10cSrcweir                 }
2358cdf0e10cSrcweir 
2359cdf0e10cSrcweir                 if ( pElement->m_bIsRemoved )
2360cdf0e10cSrcweir                 {
2361cdf0e10cSrcweir                     // was it inserted, then removed (so there would be nothing to do!)
2362cdf0e10cSrcweir                     if ( !pElement->m_bIsInserted )
2363cdf0e10cSrcweir                     {
2364cdf0e10cSrcweir                         // first remove all open stream handles
2365cdf0e10cSrcweir                         if( !pElement->m_xStream.Is() || pElement->m_xStream->Clear() )
2366cdf0e10cSrcweir                         {
2367cdf0e10cSrcweir                             pContent->executeCommand( ::rtl::OUString::createFromAscii("delete"), makeAny( sal_Bool( sal_True ) ) );
2368cdf0e10cSrcweir                             nRet = COMMIT_RESULT_SUCCESS;
2369cdf0e10cSrcweir                         }
2370cdf0e10cSrcweir                         else
2371cdf0e10cSrcweir                             // couldn't release stream because there are external references to it
2372cdf0e10cSrcweir                             nRet = COMMIT_RESULT_FAILURE;
2373cdf0e10cSrcweir                     }
2374cdf0e10cSrcweir                 }
2375cdf0e10cSrcweir                 else
2376cdf0e10cSrcweir                 {
2377cdf0e10cSrcweir                     sal_Int16 nLocalRet = COMMIT_RESULT_NOTHING_TO_DO;
2378cdf0e10cSrcweir                     if ( pElement->m_xStorage.Is() )
2379cdf0e10cSrcweir                     {
2380cdf0e10cSrcweir                         // element is a storage
2381cdf0e10cSrcweir                         // do a commit in the following cases:
2382cdf0e10cSrcweir                         //  - if storage is already inserted, and changed
2383cdf0e10cSrcweir                         //  - storage is not in a package
2384cdf0e10cSrcweir                         //  - it's a new storage, try to insert and commit if successful inserted
2385cdf0e10cSrcweir                         if ( !pElement->m_bIsInserted || m_bIsLinked || pElement->m_xStorage->Insert( m_pContent ) )
2386cdf0e10cSrcweir                         {
2387cdf0e10cSrcweir                             nLocalRet = pElement->m_xStorage->Commit();
2388cdf0e10cSrcweir                             pContent = pElement->GetContent();
2389cdf0e10cSrcweir                         }
2390cdf0e10cSrcweir                     }
2391cdf0e10cSrcweir                     else if ( pElement->m_xStream.Is() )
2392cdf0e10cSrcweir                     {
2393cdf0e10cSrcweir                         // element is a stream
2394cdf0e10cSrcweir                         nLocalRet = pElement->m_xStream->Commit();
2395cdf0e10cSrcweir                         if ( pElement->m_xStream->m_bIsOLEStorage )
2396cdf0e10cSrcweir                         {
2397*ecbfceb0Smseidel                             // OLE storage should be stored encrypted, if the storage uses encryption
2398cdf0e10cSrcweir                             pElement->m_xStream->m_aContentType = String::CreateFromAscii("application/vnd.sun.star.oleobject");
2399cdf0e10cSrcweir                             Any aValue;
2400cdf0e10cSrcweir                             aValue <<= (sal_Bool) sal_True;
2401cdf0e10cSrcweir                             pElement->m_xStream->m_pContent->setPropertyValue(String::CreateFromAscii("Encrypted"), aValue );
2402cdf0e10cSrcweir                         }
2403cdf0e10cSrcweir 
2404cdf0e10cSrcweir                         pContent = pElement->GetContent();
2405cdf0e10cSrcweir                     }
2406cdf0e10cSrcweir 
2407cdf0e10cSrcweir                     if ( pElement->m_aName != pElement->m_aOriginalName )
2408cdf0e10cSrcweir                     {
2409cdf0e10cSrcweir                         // name ( title ) of the element was changed
2410cdf0e10cSrcweir                         nLocalRet = COMMIT_RESULT_SUCCESS;
2411cdf0e10cSrcweir                         Any aAny;
2412cdf0e10cSrcweir                         aAny <<= (rtl::OUString) pElement->m_aName;
2413cdf0e10cSrcweir                         pContent->setPropertyValue( ::rtl::OUString::createFromAscii("Title"), aAny );
2414cdf0e10cSrcweir                     }
2415cdf0e10cSrcweir 
2416cdf0e10cSrcweir                     if ( pElement->IsLoaded() && pElement->GetContentType() != pElement->GetOriginalContentType() )
2417cdf0e10cSrcweir                     {
2418cdf0e10cSrcweir                         // mediatype of the element was changed
2419cdf0e10cSrcweir                         nLocalRet = COMMIT_RESULT_SUCCESS;
2420cdf0e10cSrcweir                         Any aAny;
2421cdf0e10cSrcweir                         aAny <<= (rtl::OUString) pElement->GetContentType();
2422cdf0e10cSrcweir                         pContent->setPropertyValue( ::rtl::OUString::createFromAscii("MediaType"), aAny );
2423cdf0e10cSrcweir                     }
2424cdf0e10cSrcweir 
2425cdf0e10cSrcweir                     if ( nLocalRet != COMMIT_RESULT_NOTHING_TO_DO )
2426cdf0e10cSrcweir                         nRet = nLocalRet;
2427cdf0e10cSrcweir                 }
2428cdf0e10cSrcweir 
2429cdf0e10cSrcweir                 if ( bDeleteContent )
2430cdf0e10cSrcweir                     // content was created inside the loop
2431cdf0e10cSrcweir                     delete pContent;
2432cdf0e10cSrcweir 
2433cdf0e10cSrcweir                 if ( nRet == COMMIT_RESULT_FAILURE )
2434cdf0e10cSrcweir                     break;
2435cdf0e10cSrcweir 
2436cdf0e10cSrcweir                 pElement = m_aChildrenList.Next();
2437cdf0e10cSrcweir             }
2438cdf0e10cSrcweir         }
2439cdf0e10cSrcweir         catch ( ContentCreationException& )
2440cdf0e10cSrcweir         {
2441cdf0e10cSrcweir             // content could not be created
2442cdf0e10cSrcweir             SetError( ERRCODE_IO_NOTEXISTS );
2443cdf0e10cSrcweir             return COMMIT_RESULT_FAILURE;
2444cdf0e10cSrcweir         }
2445cdf0e10cSrcweir         catch ( CommandAbortedException& )
2446cdf0e10cSrcweir         {
2447cdf0e10cSrcweir             // any command wasn't executed successfully - not specified
2448cdf0e10cSrcweir             SetError( ERRCODE_IO_GENERAL );
2449cdf0e10cSrcweir             return COMMIT_RESULT_FAILURE;
2450cdf0e10cSrcweir         }
2451cdf0e10cSrcweir         catch ( RuntimeException& )
2452cdf0e10cSrcweir         {
2453cdf0e10cSrcweir             // any other error - not specified
2454cdf0e10cSrcweir             SetError( ERRCODE_IO_GENERAL );
2455cdf0e10cSrcweir             return COMMIT_RESULT_FAILURE;
2456cdf0e10cSrcweir         }
2457cdf0e10cSrcweir         catch ( Exception& )
2458cdf0e10cSrcweir         {
2459cdf0e10cSrcweir             // any other error - not specified
2460cdf0e10cSrcweir             SetError( ERRCODE_IO_GENERAL );
2461cdf0e10cSrcweir             return COMMIT_RESULT_FAILURE;
2462cdf0e10cSrcweir         }
2463cdf0e10cSrcweir 
2464cdf0e10cSrcweir         if ( m_bIsRoot && m_pContent )
2465cdf0e10cSrcweir         {
2466cdf0e10cSrcweir             // the root storage must flush the root package content
2467cdf0e10cSrcweir             if ( nRet == COMMIT_RESULT_SUCCESS )
2468cdf0e10cSrcweir             {
2469cdf0e10cSrcweir                 try
2470cdf0e10cSrcweir                 {
2471cdf0e10cSrcweir                     // commit the media type to the JAR file
2472cdf0e10cSrcweir                     // clipboard format and ClassId will be retrieved from the media type when the file is loaded again
2473cdf0e10cSrcweir                     Any aType;
2474cdf0e10cSrcweir                     aType <<= (rtl::OUString) m_aContentType;
2475cdf0e10cSrcweir                     m_pContent->setPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ), aType );
2476cdf0e10cSrcweir 
2477cdf0e10cSrcweir                     if (  m_bIsLinked )
2478cdf0e10cSrcweir                     {
2479cdf0e10cSrcweir                         // write a manifest file
2480cdf0e10cSrcweir                         // first create a subfolder "META-inf"
2481cdf0e10cSrcweir                         Content aNewSubFolder;
2482cdf0e10cSrcweir                         sal_Bool bRet = ::utl::UCBContentHelper::MakeFolder( *m_pContent, String::CreateFromAscii("META-INF"), aNewSubFolder );
2483cdf0e10cSrcweir                         if ( bRet )
2484cdf0e10cSrcweir                         {
2485cdf0e10cSrcweir                             // create a stream to write the manifest file - use a temp file
2486cdf0e10cSrcweir                             String aURL( aNewSubFolder.getURL() );
2487cdf0e10cSrcweir                             ::utl::TempFile* pTempFile = new ::utl::TempFile( &aURL );
2488cdf0e10cSrcweir 
2489cdf0e10cSrcweir                             // get the stream from the temp file and create an output stream wrapper
2490cdf0e10cSrcweir                             SvStream* pStream = pTempFile->GetStream( STREAM_STD_READWRITE );
2491cdf0e10cSrcweir                             ::utl::OOutputStreamWrapper* pHelper = new ::utl::OOutputStreamWrapper( *pStream );
2492cdf0e10cSrcweir                             com::sun::star::uno::Reference < ::com::sun::star::io::XOutputStream > xOutputStream( pHelper );
2493cdf0e10cSrcweir 
2494cdf0e10cSrcweir                             // create a manifest writer object that will fill the stream
2495cdf0e10cSrcweir                             Reference < ::com::sun::star::packages::manifest::XManifestWriter > xWriter =
2496cdf0e10cSrcweir                                 Reference< ::com::sun::star::packages::manifest::XManifestWriter >
2497cdf0e10cSrcweir                                     ( ::comphelper::getProcessServiceFactory()->createInstance(
2498cdf0e10cSrcweir                                         ::rtl::OUString::createFromAscii( "com.sun.star.packages.manifest.ManifestWriter" )), UNO_QUERY) ;
2499cdf0e10cSrcweir                             sal_Int32 nCount = GetObjectCount() + 1;
2500cdf0e10cSrcweir                             Sequence < Sequence < PropertyValue > > aProps( nCount );
2501cdf0e10cSrcweir                             sal_Int32 nProps = 0;
2502cdf0e10cSrcweir                             GetProps( nProps, aProps, String() );
2503cdf0e10cSrcweir                             xWriter->writeManifestSequence( xOutputStream, aProps );
2504cdf0e10cSrcweir 
2505cdf0e10cSrcweir                             // move the stream to its desired location
2506cdf0e10cSrcweir                             Content aSource( pTempFile->GetURL(), Reference < XCommandEnvironment >() );
2507cdf0e10cSrcweir                             xWriter = NULL;
2508cdf0e10cSrcweir                             xOutputStream = NULL;
2509cdf0e10cSrcweir                             DELETEZ( pTempFile );
2510cdf0e10cSrcweir                             aNewSubFolder.transferContent( aSource, InsertOperation_MOVE, ::rtl::OUString::createFromAscii("manifest.xml"), NameClash::OVERWRITE );
2511cdf0e10cSrcweir                         }
2512cdf0e10cSrcweir                     }
2513cdf0e10cSrcweir                     else
2514cdf0e10cSrcweir                     {
2515cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
2516cdf0e10cSrcweir                         fprintf ( stderr, "Files: %i\n", nOpenFiles );
2517cdf0e10cSrcweir                         fprintf ( stderr, "Streams: %i\n", nOpenStreams );
2518cdf0e10cSrcweir #endif
2519cdf0e10cSrcweir                         // force writing
2520cdf0e10cSrcweir                         Any aAny;
2521cdf0e10cSrcweir                         m_pContent->executeCommand( ::rtl::OUString::createFromAscii("flush"), aAny );
2522cdf0e10cSrcweir                         if ( m_pSource != 0 )
2523cdf0e10cSrcweir                         {
2524cdf0e10cSrcweir                             SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( m_pTempFile->GetURL(), STREAM_STD_READ );
2525cdf0e10cSrcweir                             m_pSource->SetStreamSize(0);
2526cdf0e10cSrcweir                             // m_pSource->Seek(0);
2527cdf0e10cSrcweir                             *pStream >> *m_pSource;
2528cdf0e10cSrcweir                             DELETEZ( pStream );
2529cdf0e10cSrcweir                             m_pSource->Seek(0);
2530cdf0e10cSrcweir                         }
2531cdf0e10cSrcweir                     }
2532cdf0e10cSrcweir                 }
2533cdf0e10cSrcweir                 catch ( CommandAbortedException& )
2534cdf0e10cSrcweir                 {
2535cdf0e10cSrcweir                     // how to tell the content : forget all changes ?!
2536cdf0e10cSrcweir                     // or should we assume that the content does it by itself because he throwed an exception ?!
2537cdf0e10cSrcweir                     // any command wasn't executed successfully - not specified
2538cdf0e10cSrcweir                     SetError( ERRCODE_IO_GENERAL );
2539cdf0e10cSrcweir                     return COMMIT_RESULT_FAILURE;
2540cdf0e10cSrcweir                 }
2541cdf0e10cSrcweir                 catch ( RuntimeException& )
2542cdf0e10cSrcweir                 {
2543cdf0e10cSrcweir                     // how to tell the content : forget all changes ?!
2544cdf0e10cSrcweir                     // or should we assume that the content does it by itself because he throwed an exception ?!
2545cdf0e10cSrcweir                     // any other error - not specified
2546cdf0e10cSrcweir                     SetError( ERRCODE_IO_GENERAL );
2547cdf0e10cSrcweir                     return COMMIT_RESULT_FAILURE;
2548cdf0e10cSrcweir                 }
2549cdf0e10cSrcweir                 catch ( InteractiveIOException& r )
2550cdf0e10cSrcweir                 {
2551cdf0e10cSrcweir                     if ( r.Code == IOErrorCode_ACCESS_DENIED || r.Code == IOErrorCode_LOCKING_VIOLATION )
2552cdf0e10cSrcweir                         SetError( ERRCODE_IO_ACCESSDENIED );
2553cdf0e10cSrcweir                     else if ( r.Code == IOErrorCode_NOT_EXISTING )
2554cdf0e10cSrcweir                         SetError( ERRCODE_IO_NOTEXISTS );
2555cdf0e10cSrcweir                     else if ( r.Code == IOErrorCode_CANT_READ )
2556cdf0e10cSrcweir                         SetError( ERRCODE_IO_CANTREAD );
2557cdf0e10cSrcweir                     else if ( r.Code == IOErrorCode_CANT_WRITE )
2558cdf0e10cSrcweir                         SetError( ERRCODE_IO_CANTWRITE );
2559cdf0e10cSrcweir                     else
2560cdf0e10cSrcweir                         SetError( ERRCODE_IO_GENERAL );
2561cdf0e10cSrcweir 
2562cdf0e10cSrcweir                     return COMMIT_RESULT_FAILURE;
2563cdf0e10cSrcweir                 }
2564cdf0e10cSrcweir                 catch ( Exception& )
2565cdf0e10cSrcweir                 {
2566cdf0e10cSrcweir                     // how to tell the content : forget all changes ?!
2567cdf0e10cSrcweir                     // or should we assume that the content does it by itself because he throwed an exception ?!
2568cdf0e10cSrcweir                     // any other error - not specified
2569cdf0e10cSrcweir                     SetError( ERRCODE_IO_GENERAL );
2570cdf0e10cSrcweir                     return COMMIT_RESULT_FAILURE;
2571cdf0e10cSrcweir                 }
2572cdf0e10cSrcweir             }
2573cdf0e10cSrcweir             else if ( nRet != COMMIT_RESULT_NOTHING_TO_DO )
2574cdf0e10cSrcweir             {
2575cdf0e10cSrcweir                 // how to tell the content : forget all changes ?! Should we ?!
2576cdf0e10cSrcweir                 SetError( ERRCODE_IO_GENERAL );
2577cdf0e10cSrcweir                 return nRet;
2578cdf0e10cSrcweir             }
2579cdf0e10cSrcweir 
258086e1cf34SPedro Giffuni             // after successful root commit all elements names and types are adjusted and all removed elements
2581cdf0e10cSrcweir             // are also removed from the lists
2582cdf0e10cSrcweir             UCBStorageElement_Impl* pInnerElement = m_aChildrenList.First();
2583cdf0e10cSrcweir             sal_Bool bRet = sal_True;
2584cdf0e10cSrcweir             while ( pInnerElement && bRet )
2585cdf0e10cSrcweir             {
2586cdf0e10cSrcweir                 UCBStorageElement_Impl* pNext = m_aChildrenList.Next();
2587cdf0e10cSrcweir                 if ( pInnerElement->m_bIsRemoved )
2588cdf0e10cSrcweir                 {
2589cdf0e10cSrcweir                     // is this correct use of our list class ?!
2590cdf0e10cSrcweir                     m_aChildrenList.Remove( pInnerElement );
2591cdf0e10cSrcweir                 }
2592cdf0e10cSrcweir                 else
2593cdf0e10cSrcweir                 {
2594cdf0e10cSrcweir                     pInnerElement->m_aOriginalName = pInnerElement->m_aName;
2595cdf0e10cSrcweir                     pInnerElement->m_bIsInserted = sal_False;
2596cdf0e10cSrcweir                 }
2597cdf0e10cSrcweir 
2598cdf0e10cSrcweir                 pInnerElement = pNext;
2599cdf0e10cSrcweir             }
2600cdf0e10cSrcweir         }
2601cdf0e10cSrcweir 
2602cdf0e10cSrcweir         m_bCommited = sal_False;
2603cdf0e10cSrcweir     }
2604cdf0e10cSrcweir 
2605cdf0e10cSrcweir     return nRet;
2606cdf0e10cSrcweir }
2607cdf0e10cSrcweir 
2608cdf0e10cSrcweir sal_Bool UCBStorage_Impl::Revert()
2609cdf0e10cSrcweir {
2610cdf0e10cSrcweir     UCBStorageElement_Impl* pElement = m_aChildrenList.First();
2611cdf0e10cSrcweir     sal_Bool bRet = sal_True;
2612cdf0e10cSrcweir     while ( pElement && bRet )
2613cdf0e10cSrcweir     {
2614cdf0e10cSrcweir         pElement->m_bIsRemoved = sal_False;
2615cdf0e10cSrcweir         if ( pElement->m_bIsInserted )
2616cdf0e10cSrcweir         {
2617cdf0e10cSrcweir             m_aChildrenList.Remove( pElement );  // correct usage of list ???
2618cdf0e10cSrcweir         }
2619cdf0e10cSrcweir         else
2620cdf0e10cSrcweir         {
2621cdf0e10cSrcweir             if ( pElement->m_xStream.Is() )
2622cdf0e10cSrcweir             {
2623cdf0e10cSrcweir                 pElement->m_xStream->m_bCommited = sal_False;
2624cdf0e10cSrcweir                 pElement->m_xStream->Revert();
2625cdf0e10cSrcweir             }
2626cdf0e10cSrcweir             else if ( pElement->m_xStorage.Is() )
2627cdf0e10cSrcweir             {
2628cdf0e10cSrcweir                 pElement->m_xStorage->m_bCommited = sal_False;
2629cdf0e10cSrcweir                 pElement->m_xStorage->Revert();
2630cdf0e10cSrcweir             }
2631cdf0e10cSrcweir 
2632cdf0e10cSrcweir             pElement->m_aName = pElement->m_aOriginalName;
2633cdf0e10cSrcweir             pElement->m_bIsRemoved = sal_False;
2634cdf0e10cSrcweir         }
2635cdf0e10cSrcweir 
2636cdf0e10cSrcweir         pElement = m_aChildrenList.Next();
2637cdf0e10cSrcweir     }
2638cdf0e10cSrcweir 
2639cdf0e10cSrcweir     return bRet;
2640cdf0e10cSrcweir }
2641cdf0e10cSrcweir 
2642cdf0e10cSrcweir const String& UCBStorage::GetName() const
2643cdf0e10cSrcweir {
2644cdf0e10cSrcweir     return pImp->m_aName; // pImp->m_aURL ?!
2645cdf0e10cSrcweir }
2646cdf0e10cSrcweir 
2647cdf0e10cSrcweir sal_Bool UCBStorage::IsRoot() const
2648cdf0e10cSrcweir {
2649cdf0e10cSrcweir     return pImp->m_bIsRoot;
2650cdf0e10cSrcweir }
2651cdf0e10cSrcweir 
2652cdf0e10cSrcweir void UCBStorage::SetDirty()
2653cdf0e10cSrcweir {
2654cdf0e10cSrcweir     pImp->m_bDirty = sal_True;
2655cdf0e10cSrcweir }
2656cdf0e10cSrcweir 
2657cdf0e10cSrcweir void UCBStorage::SetClass( const SvGlobalName & rClass, sal_uLong nOriginalClipFormat, const String & rUserTypeName )
2658cdf0e10cSrcweir {
2659cdf0e10cSrcweir     pImp->m_aClassId = rClass;
2660cdf0e10cSrcweir     pImp->m_nFormat = nOriginalClipFormat;
2661cdf0e10cSrcweir     pImp->m_aUserTypeName = rUserTypeName;
2662cdf0e10cSrcweir 
2663cdf0e10cSrcweir     // in UCB storages only the content type will be stored, all other information can be reconstructed
2664cdf0e10cSrcweir     // ( see the UCBStorage_Impl::Init() method )
2665cdf0e10cSrcweir     ::com::sun::star::datatransfer::DataFlavor aDataFlavor;
2666cdf0e10cSrcweir     SotExchange::GetFormatDataFlavor( pImp->m_nFormat, aDataFlavor );
2667cdf0e10cSrcweir     pImp->m_aContentType = aDataFlavor.MimeType;
2668cdf0e10cSrcweir }
2669cdf0e10cSrcweir 
2670cdf0e10cSrcweir void UCBStorage::SetClassId( const ClsId& rClsId )
2671cdf0e10cSrcweir {
2672cdf0e10cSrcweir     pImp->m_aClassId = SvGlobalName( (const CLSID&) rClsId );
2673cdf0e10cSrcweir     if ( pImp->m_aClassId == SvGlobalName() )
2674cdf0e10cSrcweir         return;
2675cdf0e10cSrcweir 
2676cdf0e10cSrcweir     // in OLE storages the clipboard format an the user name will be transferred when a storage is copied because both are
2677cdf0e10cSrcweir     // stored in one the substreams
2678cdf0e10cSrcweir     // UCB storages store the content type information as content type in the manifest file and so this information must be
2679cdf0e10cSrcweir     // kept up to date, and also the other type information that is hold only at runtime because it can be reconstructed from
2680cdf0e10cSrcweir     // the content type
2681cdf0e10cSrcweir     pImp->m_nFormat = GetFormatId_Impl( pImp->m_aClassId );
2682cdf0e10cSrcweir     if ( pImp->m_nFormat )
2683cdf0e10cSrcweir     {
2684cdf0e10cSrcweir         ::com::sun::star::datatransfer::DataFlavor aDataFlavor;
2685cdf0e10cSrcweir         SotExchange::GetFormatDataFlavor( pImp->m_nFormat, aDataFlavor );
2686cdf0e10cSrcweir         pImp->m_aUserTypeName = aDataFlavor.HumanPresentableName;
2687cdf0e10cSrcweir         pImp->m_aContentType = aDataFlavor.MimeType;
2688cdf0e10cSrcweir     }
2689cdf0e10cSrcweir }
2690cdf0e10cSrcweir 
2691cdf0e10cSrcweir const ClsId& UCBStorage::GetClassId() const
2692cdf0e10cSrcweir {
2693cdf0e10cSrcweir     return ( const ClsId& ) pImp->m_aClassId.GetCLSID();
2694cdf0e10cSrcweir }
2695cdf0e10cSrcweir 
2696cdf0e10cSrcweir void UCBStorage::SetConvertClass( const SvGlobalName & /*rConvertClass*/, sal_uLong /*nOriginalClipFormat*/, const String & /*rUserTypeName*/ )
2697cdf0e10cSrcweir {
2698cdf0e10cSrcweir     // ???
2699cdf0e10cSrcweir }
2700cdf0e10cSrcweir 
2701cdf0e10cSrcweir sal_Bool UCBStorage::ShouldConvert()
2702cdf0e10cSrcweir {
2703cdf0e10cSrcweir     // ???
2704cdf0e10cSrcweir     return sal_False;
2705cdf0e10cSrcweir }
2706cdf0e10cSrcweir 
2707cdf0e10cSrcweir SvGlobalName UCBStorage::GetClassName()
2708cdf0e10cSrcweir {
2709cdf0e10cSrcweir     return  pImp->m_aClassId;
2710cdf0e10cSrcweir }
2711cdf0e10cSrcweir 
2712cdf0e10cSrcweir sal_uLong UCBStorage::GetFormat()
2713cdf0e10cSrcweir {
2714cdf0e10cSrcweir     return pImp->m_nFormat;
2715cdf0e10cSrcweir }
2716cdf0e10cSrcweir 
2717cdf0e10cSrcweir String UCBStorage::GetUserName()
2718cdf0e10cSrcweir {
2719cdf0e10cSrcweir     DBG_ERROR("UserName is not implemented in UCB storages!" );
2720cdf0e10cSrcweir     return pImp->m_aUserTypeName;
2721cdf0e10cSrcweir }
2722cdf0e10cSrcweir 
2723cdf0e10cSrcweir void UCBStorage::FillInfoList( SvStorageInfoList* pList ) const
2724cdf0e10cSrcweir {
2725cdf0e10cSrcweir     // put information in childrenlist into StorageInfoList
2726cdf0e10cSrcweir     UCBStorageElement_Impl* pElement = pImp->GetChildrenList().First();
2727cdf0e10cSrcweir     while ( pElement )
2728cdf0e10cSrcweir     {
2729cdf0e10cSrcweir         if ( !pElement->m_bIsRemoved )
2730cdf0e10cSrcweir         {
2731cdf0e10cSrcweir             // problem: what about the size of a substorage ?!
2732cdf0e10cSrcweir             sal_uLong nSize = pElement->m_nSize;
2733cdf0e10cSrcweir             if ( pElement->m_xStream.Is() )
2734cdf0e10cSrcweir                 nSize = pElement->m_xStream->GetSize();
2735cdf0e10cSrcweir             SvStorageInfo aInfo( pElement->m_aName, nSize, pElement->m_bIsStorage );
2736cdf0e10cSrcweir             pList->Append( aInfo );
2737cdf0e10cSrcweir         }
2738cdf0e10cSrcweir 
2739cdf0e10cSrcweir         pElement = pImp->m_aChildrenList.Next();
2740cdf0e10cSrcweir     }
2741cdf0e10cSrcweir }
2742cdf0e10cSrcweir 
2743cdf0e10cSrcweir sal_Bool UCBStorage::CopyStorageElement_Impl( UCBStorageElement_Impl& rElement, BaseStorage* pDest, const String& rNew ) const
2744cdf0e10cSrcweir {
2745cdf0e10cSrcweir     // insert stream or storage into the list or stream of the destination storage
2746cdf0e10cSrcweir     // not into the content, this will be done on commit !
2747cdf0e10cSrcweir     // be aware of name changes !
2748cdf0e10cSrcweir     if ( !rElement.m_bIsStorage )
2749cdf0e10cSrcweir     {
2750cdf0e10cSrcweir         // copy the streams data
2751cdf0e10cSrcweir         // the destination stream must not be open
2752cdf0e10cSrcweir         BaseStorageStream* pOtherStream = pDest->OpenStream( rNew, STREAM_WRITE | STREAM_SHARE_DENYALL, pImp->m_bDirect );
2753cdf0e10cSrcweir         BaseStorageStream* pStream = NULL;
2754cdf0e10cSrcweir         sal_Bool bDeleteStream = sal_False;
2755cdf0e10cSrcweir 
2756cdf0e10cSrcweir         // if stream is already open, it is allowed to copy it, so be aware of this
2757cdf0e10cSrcweir         if ( rElement.m_xStream.Is() )
2758cdf0e10cSrcweir             pStream = rElement.m_xStream->m_pAntiImpl;
2759cdf0e10cSrcweir         if ( !pStream )
2760cdf0e10cSrcweir         {
2761cdf0e10cSrcweir             pStream = ( const_cast < UCBStorage* > (this) )->OpenStream( rElement.m_aName, STREAM_STD_READ, pImp->m_bDirect );
2762cdf0e10cSrcweir             bDeleteStream = sal_True;
2763cdf0e10cSrcweir         }
2764cdf0e10cSrcweir 
2765cdf0e10cSrcweir         pStream->CopyTo( pOtherStream );
2766cdf0e10cSrcweir         SetError( pStream->GetError() );
2767cdf0e10cSrcweir         if( pOtherStream->GetError() )
2768cdf0e10cSrcweir             pDest->SetError( pOtherStream->GetError() );
2769cdf0e10cSrcweir         else
2770cdf0e10cSrcweir             pOtherStream->Commit();
2771cdf0e10cSrcweir 
2772cdf0e10cSrcweir         if ( bDeleteStream )
2773cdf0e10cSrcweir             delete pStream;
2774cdf0e10cSrcweir         delete pOtherStream;
2775cdf0e10cSrcweir     }
2776cdf0e10cSrcweir     else
2777cdf0e10cSrcweir     {
2778cdf0e10cSrcweir         // copy the storage content
2779cdf0e10cSrcweir         // the destination storage must not be open
2780cdf0e10cSrcweir         BaseStorage* pStorage = NULL;
2781cdf0e10cSrcweir 
2782cdf0e10cSrcweir         // if stream is already open, it is allowed to copy it, so be aware of this
2783cdf0e10cSrcweir         sal_Bool bDeleteStorage = sal_False;
2784cdf0e10cSrcweir         if ( rElement.m_xStorage.Is() )
2785cdf0e10cSrcweir             pStorage = rElement.m_xStorage->m_pAntiImpl;
2786cdf0e10cSrcweir         if ( !pStorage )
2787cdf0e10cSrcweir         {
2788cdf0e10cSrcweir             pStorage = ( const_cast < UCBStorage* > (this) )->OpenStorage( rElement.m_aName, pImp->m_nMode, pImp->m_bDirect );
2789cdf0e10cSrcweir             bDeleteStorage = sal_True;
2790cdf0e10cSrcweir         }
2791cdf0e10cSrcweir 
2792cdf0e10cSrcweir         UCBStorage* pUCBDest = PTR_CAST( UCBStorage, pDest );
2793cdf0e10cSrcweir         UCBStorage* pUCBCopy = PTR_CAST( UCBStorage, pStorage );
2794cdf0e10cSrcweir 
2795cdf0e10cSrcweir         sal_Bool bOpenUCBStorage = pUCBDest && pUCBCopy;
2796cdf0e10cSrcweir         BaseStorage* pOtherStorage = bOpenUCBStorage ?
2797cdf0e10cSrcweir                 pDest->OpenUCBStorage( rNew, STREAM_WRITE | STREAM_SHARE_DENYALL, pImp->m_bDirect ) :
2798cdf0e10cSrcweir                 pDest->OpenOLEStorage( rNew, STREAM_WRITE | STREAM_SHARE_DENYALL, pImp->m_bDirect );
2799cdf0e10cSrcweir 
2800cdf0e10cSrcweir         // For UCB storages, the class id and the format id may differ,
2801cdf0e10cSrcweir         // do passing the class id is not sufficient.
2802cdf0e10cSrcweir         if( bOpenUCBStorage )
2803cdf0e10cSrcweir             pOtherStorage->SetClass( pStorage->GetClassName(),
2804cdf0e10cSrcweir                                      pStorage->GetFormat(),
2805cdf0e10cSrcweir                                      pUCBCopy->pImp->m_aUserTypeName );
2806cdf0e10cSrcweir         else
2807cdf0e10cSrcweir             pOtherStorage->SetClassId( pStorage->GetClassId() );
2808cdf0e10cSrcweir         pStorage->CopyTo( pOtherStorage );
2809cdf0e10cSrcweir         SetError( pStorage->GetError() );
2810cdf0e10cSrcweir         if( pOtherStorage->GetError() )
2811cdf0e10cSrcweir             pDest->SetError( pOtherStorage->GetError() );
2812cdf0e10cSrcweir         else
2813cdf0e10cSrcweir             pOtherStorage->Commit();
2814cdf0e10cSrcweir 
2815cdf0e10cSrcweir         if ( bDeleteStorage )
2816cdf0e10cSrcweir             delete pStorage;
2817cdf0e10cSrcweir         delete pOtherStorage;
2818cdf0e10cSrcweir     }
2819cdf0e10cSrcweir 
2820cdf0e10cSrcweir     return sal_Bool( Good() && pDest->Good() );
2821cdf0e10cSrcweir }
2822cdf0e10cSrcweir 
2823cdf0e10cSrcweir UCBStorageElement_Impl* UCBStorage::FindElement_Impl( const String& rName ) const
2824cdf0e10cSrcweir {
2825cdf0e10cSrcweir     DBG_ASSERT( rName.Len(), "Name is empty!" );
2826cdf0e10cSrcweir     UCBStorageElement_Impl* pElement = pImp->GetChildrenList().First();
2827cdf0e10cSrcweir     while ( pElement )
2828cdf0e10cSrcweir     {
2829cdf0e10cSrcweir         if ( pElement->m_aName == rName && !pElement->m_bIsRemoved )
2830cdf0e10cSrcweir             break;
2831cdf0e10cSrcweir         pElement = pImp->m_aChildrenList.Next();
2832cdf0e10cSrcweir     }
2833cdf0e10cSrcweir 
2834cdf0e10cSrcweir     return pElement;
2835cdf0e10cSrcweir }
2836cdf0e10cSrcweir 
2837cdf0e10cSrcweir sal_Bool UCBStorage::CopyTo( BaseStorage* pDestStg ) const
2838cdf0e10cSrcweir {
2839cdf0e10cSrcweir     DBG_ASSERT( pDestStg != ((BaseStorage*)this), "Self-Copying is not possible!" );
2840cdf0e10cSrcweir     if ( pDestStg == ((BaseStorage*)this) )
2841cdf0e10cSrcweir         return sal_False;
2842cdf0e10cSrcweir 
2843cdf0e10cSrcweir     // perhaps it's also a problem if one storage is a parent of the other ?!
2844cdf0e10cSrcweir     // or if not: could be optimized ?!
2845cdf0e10cSrcweir 
2846cdf0e10cSrcweir     // For UCB storages, the class id and the format id may differ,
2847cdf0e10cSrcweir     // do passing the class id is not sufficient.
2848cdf0e10cSrcweir     if( pDestStg->ISA( UCBStorage ) )
2849cdf0e10cSrcweir         pDestStg->SetClass( pImp->m_aClassId, pImp->m_nFormat,
2850cdf0e10cSrcweir                             pImp->m_aUserTypeName );
2851cdf0e10cSrcweir     else
2852cdf0e10cSrcweir         pDestStg->SetClassId( GetClassId() );
2853cdf0e10cSrcweir     pDestStg->SetDirty();
2854cdf0e10cSrcweir 
2855cdf0e10cSrcweir     sal_Bool bRet = sal_True;
2856cdf0e10cSrcweir     UCBStorageElement_Impl* pElement = pImp->GetChildrenList().First();
2857cdf0e10cSrcweir     while ( pElement && bRet )
2858cdf0e10cSrcweir     {
2859cdf0e10cSrcweir         if ( !pElement->m_bIsRemoved )
2860cdf0e10cSrcweir             bRet = CopyStorageElement_Impl( *pElement, pDestStg, pElement->m_aName );
2861cdf0e10cSrcweir         pElement = pImp->m_aChildrenList.Next();
2862cdf0e10cSrcweir     }
2863cdf0e10cSrcweir 
2864cdf0e10cSrcweir     if( !bRet )
2865cdf0e10cSrcweir         SetError( pDestStg->GetError() );
2866cdf0e10cSrcweir     return sal_Bool( Good() && pDestStg->Good() );
2867cdf0e10cSrcweir }
2868cdf0e10cSrcweir 
2869cdf0e10cSrcweir sal_Bool UCBStorage::CopyTo( const String& rElemName, BaseStorage* pDest, const String& rNew )
2870cdf0e10cSrcweir {
2871cdf0e10cSrcweir     if( !rElemName.Len() )
2872cdf0e10cSrcweir         return sal_False;
2873cdf0e10cSrcweir 
2874cdf0e10cSrcweir     if ( pDest == ((BaseStorage*) this) )
2875cdf0e10cSrcweir     {
2876cdf0e10cSrcweir         // can't double an element
2877cdf0e10cSrcweir         return sal_False;
2878cdf0e10cSrcweir     }
2879cdf0e10cSrcweir     else
2880cdf0e10cSrcweir     {
288186e1cf34SPedro Giffuni         // for copying no optimization is useful, because in every case the stream data must be copied
2882cdf0e10cSrcweir             UCBStorageElement_Impl* pElement = FindElement_Impl( rElemName );
2883cdf0e10cSrcweir         if ( pElement )
2884cdf0e10cSrcweir             return CopyStorageElement_Impl( *pElement, pDest, rNew );
2885cdf0e10cSrcweir         else
2886cdf0e10cSrcweir         {
2887cdf0e10cSrcweir             SetError( SVSTREAM_FILE_NOT_FOUND );
2888cdf0e10cSrcweir             return sal_False;
2889cdf0e10cSrcweir         }
2890cdf0e10cSrcweir     }
2891cdf0e10cSrcweir }
2892cdf0e10cSrcweir 
2893cdf0e10cSrcweir sal_Bool UCBStorage::Commit()
2894cdf0e10cSrcweir {
2895cdf0e10cSrcweir     // mark this storage for sending it on root commit
2896cdf0e10cSrcweir     pImp->m_bCommited = sal_True;
2897cdf0e10cSrcweir     if ( pImp->m_bIsRoot )
289886e1cf34SPedro Giffuni         // the root storage coordinates committing by sending a Commit command to its content
2899cdf0e10cSrcweir         return ( pImp->Commit() != COMMIT_RESULT_FAILURE );
2900cdf0e10cSrcweir     else
2901cdf0e10cSrcweir         return sal_True;
2902cdf0e10cSrcweir }
2903cdf0e10cSrcweir 
2904cdf0e10cSrcweir sal_Bool UCBStorage::Revert()
2905cdf0e10cSrcweir {
2906cdf0e10cSrcweir     return pImp->Revert();
2907cdf0e10cSrcweir }
2908cdf0e10cSrcweir 
2909cdf0e10cSrcweir BaseStorageStream* UCBStorage::OpenStream( const String& rEleName, StreamMode nMode, sal_Bool bDirect, const ByteString* pKey )
2910cdf0e10cSrcweir {
2911cdf0e10cSrcweir     if( !rEleName.Len() )
2912cdf0e10cSrcweir         return NULL;
2913cdf0e10cSrcweir 
2914cdf0e10cSrcweir     // try to find the storage element
2915cdf0e10cSrcweir     UCBStorageElement_Impl *pElement = FindElement_Impl( rEleName );
2916cdf0e10cSrcweir     if ( !pElement )
2917cdf0e10cSrcweir     {
2918cdf0e10cSrcweir         // element does not exist, check if creation is allowed
2919cdf0e10cSrcweir         if( ( nMode & STREAM_NOCREATE ) )
2920cdf0e10cSrcweir         {
2921cdf0e10cSrcweir             SetError( ( nMode & STREAM_WRITE ) ? SVSTREAM_CANNOT_MAKE : SVSTREAM_FILE_NOT_FOUND );
2922cdf0e10cSrcweir             String aName( pImp->m_aURL );
2923cdf0e10cSrcweir             aName += '/';
2924cdf0e10cSrcweir             aName += rEleName;
2925cdf0e10cSrcweir             UCBStorageStream* pStream = new UCBStorageStream( aName, nMode, bDirect, pKey, pImp->m_bRepairPackage, pImp->m_xProgressHandler );
2926cdf0e10cSrcweir             pStream->SetError( GetError() );
2927cdf0e10cSrcweir             pStream->pImp->m_aName = rEleName;
2928cdf0e10cSrcweir             return pStream;
2929cdf0e10cSrcweir         }
2930cdf0e10cSrcweir         else
2931cdf0e10cSrcweir         {
2932cdf0e10cSrcweir             // create a new UCBStorageElement and insert it into the list
2933cdf0e10cSrcweir             pElement = new UCBStorageElement_Impl( rEleName );
2934cdf0e10cSrcweir             pElement->m_bIsInserted = sal_True;
2935cdf0e10cSrcweir             pImp->m_aChildrenList.Insert( pElement, LIST_APPEND );
2936cdf0e10cSrcweir         }
2937cdf0e10cSrcweir     }
2938cdf0e10cSrcweir 
2939cdf0e10cSrcweir     if ( pElement && !pElement->m_bIsFolder )
2940cdf0e10cSrcweir     {
2941cdf0e10cSrcweir         // check if stream is already created
2942cdf0e10cSrcweir         if ( pElement->m_xStream.Is() )
2943cdf0e10cSrcweir         {
2944cdf0e10cSrcweir             // stream has already been created; if it has no external reference, it may be opened another time
2945cdf0e10cSrcweir             if ( pElement->m_xStream->m_pAntiImpl )
2946cdf0e10cSrcweir             {
2947cdf0e10cSrcweir                 DBG_ERROR("Stream is already open!" );
2948cdf0e10cSrcweir                 SetError( SVSTREAM_ACCESS_DENIED );  // ???
2949cdf0e10cSrcweir                 return NULL;
2950cdf0e10cSrcweir             }
2951cdf0e10cSrcweir             else
2952cdf0e10cSrcweir             {
2953cdf0e10cSrcweir                 // check if stream is opened with the same keyword as before
2954cdf0e10cSrcweir                 // if not, generate a new stream because it could be encrypted vs. decrypted!
2955cdf0e10cSrcweir                 ByteString aKey;
2956cdf0e10cSrcweir                 if ( pKey )
2957cdf0e10cSrcweir                     aKey = *pKey;
2958cdf0e10cSrcweir                 if ( pElement->m_xStream->m_aKey == aKey )
2959cdf0e10cSrcweir                 {
2960cdf0e10cSrcweir                     pElement->m_xStream->PrepareCachedForReopen( nMode );
2961cdf0e10cSrcweir 
2962cdf0e10cSrcweir     //              DBG_ASSERT( bDirect == pElement->m_xStream->m_bDirect, "Wrong DirectMode!" );
2963cdf0e10cSrcweir                     return new UCBStorageStream( pElement->m_xStream );
2964cdf0e10cSrcweir                 }
2965cdf0e10cSrcweir             }
2966cdf0e10cSrcweir         }
2967cdf0e10cSrcweir 
2968cdf0e10cSrcweir         // stream is opened the first time
2969cdf0e10cSrcweir         pImp->OpenStream( pElement, nMode, bDirect, pKey );
2970cdf0e10cSrcweir 
2971cdf0e10cSrcweir         // if name has been changed before creating the stream: set name!
2972cdf0e10cSrcweir         pElement->m_xStream->m_aName = rEleName;
2973cdf0e10cSrcweir         return new UCBStorageStream( pElement->m_xStream );
2974cdf0e10cSrcweir     }
2975cdf0e10cSrcweir 
2976cdf0e10cSrcweir     return NULL;
2977cdf0e10cSrcweir }
2978cdf0e10cSrcweir 
2979cdf0e10cSrcweir UCBStorageStream_Impl* UCBStorage_Impl::OpenStream( UCBStorageElement_Impl* pElement, StreamMode nMode, sal_Bool bDirect, const ByteString* pKey )
2980cdf0e10cSrcweir {
2981cdf0e10cSrcweir     String aName( m_aURL );
2982cdf0e10cSrcweir     aName += '/';
2983cdf0e10cSrcweir     aName += pElement->m_aOriginalName;
2984cdf0e10cSrcweir     pElement->m_xStream = new UCBStorageStream_Impl( aName, nMode, NULL, bDirect, pKey, m_bRepairPackage, m_xProgressHandler );
2985cdf0e10cSrcweir     return pElement->m_xStream;
2986cdf0e10cSrcweir }
2987cdf0e10cSrcweir 
2988cdf0e10cSrcweir BaseStorage* UCBStorage::OpenUCBStorage( const String& rEleName, StreamMode nMode, sal_Bool bDirect )
2989cdf0e10cSrcweir {
2990cdf0e10cSrcweir     if( !rEleName.Len() )
2991cdf0e10cSrcweir         return NULL;
2992cdf0e10cSrcweir 
2993cdf0e10cSrcweir     return OpenStorage_Impl( rEleName, nMode, bDirect, sal_True );
2994cdf0e10cSrcweir }
2995cdf0e10cSrcweir 
2996cdf0e10cSrcweir BaseStorage* UCBStorage::OpenOLEStorage( const String& rEleName, StreamMode nMode, sal_Bool bDirect )
2997cdf0e10cSrcweir {
2998cdf0e10cSrcweir     if( !rEleName.Len() )
2999cdf0e10cSrcweir         return NULL;
3000cdf0e10cSrcweir 
3001cdf0e10cSrcweir     return OpenStorage_Impl( rEleName, nMode, bDirect, sal_False );
3002cdf0e10cSrcweir }
3003cdf0e10cSrcweir 
3004cdf0e10cSrcweir BaseStorage* UCBStorage::OpenStorage( const String& rEleName, StreamMode nMode, sal_Bool bDirect )
3005cdf0e10cSrcweir {
3006cdf0e10cSrcweir     if( !rEleName.Len() )
3007cdf0e10cSrcweir         return NULL;
3008cdf0e10cSrcweir 
3009cdf0e10cSrcweir     return OpenStorage_Impl( rEleName, nMode, bDirect, sal_True );
3010cdf0e10cSrcweir }
3011cdf0e10cSrcweir 
3012cdf0e10cSrcweir BaseStorage* UCBStorage::OpenStorage_Impl( const String& rEleName, StreamMode nMode, sal_Bool bDirect, sal_Bool bForceUCBStorage )
3013cdf0e10cSrcweir {
3014cdf0e10cSrcweir     // try to find the storage element
3015cdf0e10cSrcweir     UCBStorageElement_Impl *pElement = FindElement_Impl( rEleName );
3016cdf0e10cSrcweir     if ( !pElement )
3017cdf0e10cSrcweir     {
3018cdf0e10cSrcweir         // element does not exist, check if creation is allowed
3019cdf0e10cSrcweir         if( ( nMode & STREAM_NOCREATE ) )
3020cdf0e10cSrcweir         {
3021cdf0e10cSrcweir             SetError( ( nMode & STREAM_WRITE ) ? SVSTREAM_CANNOT_MAKE : SVSTREAM_FILE_NOT_FOUND );
3022cdf0e10cSrcweir             String aName( pImp->m_aURL );
3023cdf0e10cSrcweir             aName += '/';
3024cdf0e10cSrcweir             aName += rEleName;  // ???
3025cdf0e10cSrcweir             UCBStorage *pStorage = new UCBStorage( aName, nMode, bDirect, sal_False, pImp->m_bRepairPackage, pImp->m_xProgressHandler );
3026cdf0e10cSrcweir             pStorage->pImp->m_bIsRoot = sal_False;
3027cdf0e10cSrcweir             pStorage->pImp->m_bListCreated = sal_True; // the storage is pretty new, nothing to read
3028cdf0e10cSrcweir             pStorage->SetError( GetError() );
3029cdf0e10cSrcweir             return pStorage;
3030cdf0e10cSrcweir         }
3031cdf0e10cSrcweir 
3032cdf0e10cSrcweir         // create a new UCBStorageElement and insert it into the list
3033cdf0e10cSrcweir         // problem: perhaps an OLEStorage should be created ?!
3034cdf0e10cSrcweir         // Because nothing is known about the element that should be created, an external parameter is needed !
3035cdf0e10cSrcweir         pElement = new UCBStorageElement_Impl( rEleName );
3036cdf0e10cSrcweir         pElement->m_bIsInserted = sal_True;
3037cdf0e10cSrcweir         pImp->m_aChildrenList.Insert( pElement, LIST_APPEND );
3038cdf0e10cSrcweir     }
3039cdf0e10cSrcweir 
3040cdf0e10cSrcweir     if ( !pElement->m_bIsFolder && ( pElement->m_bIsStorage || !bForceUCBStorage ) )
3041cdf0e10cSrcweir     {
3042cdf0e10cSrcweir         // create OLE storages on a stream ( see ctor of SotStorage )
3043cdf0e10cSrcweir         // Such a storage will be created on a UCBStorageStream; it will write into the stream
3044cdf0e10cSrcweir         // if it is opened in direct mode or when it is committed. In this case the stream will be
3045*ecbfceb0Smseidel         // modified and then it MUST be treated as committed.
3046cdf0e10cSrcweir         if ( !pElement->m_xStream.Is() )
3047cdf0e10cSrcweir         {
3048cdf0e10cSrcweir             BaseStorageStream* pStr = OpenStream( rEleName, nMode, bDirect );
3049cdf0e10cSrcweir             UCBStorageStream* pStream = PTR_CAST( UCBStorageStream, pStr );
3050cdf0e10cSrcweir             if ( !pStream )
3051cdf0e10cSrcweir             {
3052cdf0e10cSrcweir                 SetError( ( nMode & STREAM_WRITE ) ? SVSTREAM_CANNOT_MAKE : SVSTREAM_FILE_NOT_FOUND );
3053cdf0e10cSrcweir                 return NULL;
3054cdf0e10cSrcweir             }
3055cdf0e10cSrcweir 
3056cdf0e10cSrcweir             pElement->m_xStream = pStream->pImp;
3057cdf0e10cSrcweir             delete pStream;
3058cdf0e10cSrcweir         }
3059cdf0e10cSrcweir 
3060cdf0e10cSrcweir         pElement->m_xStream->PrepareCachedForReopen( nMode );
3061cdf0e10cSrcweir         pElement->m_xStream->Init();
3062cdf0e10cSrcweir 
3063cdf0e10cSrcweir         pElement->m_bIsStorage = sal_True;
3064cdf0e10cSrcweir         return pElement->m_xStream->CreateStorage();  // can only be created in transacted mode
3065cdf0e10cSrcweir     }
3066cdf0e10cSrcweir     else if ( pElement->m_xStorage.Is() )
3067cdf0e10cSrcweir     {
3068cdf0e10cSrcweir         // storage has already been opened; if it has no external reference, it may be opened another time
3069cdf0e10cSrcweir         if ( pElement->m_xStorage->m_pAntiImpl )
3070cdf0e10cSrcweir         {
3071cdf0e10cSrcweir             DBG_ERROR("Storage is already open!" );
3072cdf0e10cSrcweir             SetError( SVSTREAM_ACCESS_DENIED );  // ???
3073cdf0e10cSrcweir         }
3074cdf0e10cSrcweir         else
3075cdf0e10cSrcweir         {
3076cdf0e10cSrcweir             sal_Bool bIsWritable = (( pElement->m_xStorage->m_nMode & STREAM_WRITE ) != 0);
3077cdf0e10cSrcweir             if ( !bIsWritable && (( nMode & STREAM_WRITE ) != 0 ))
3078cdf0e10cSrcweir             {
3079cdf0e10cSrcweir                 String aName( pImp->m_aURL );
3080cdf0e10cSrcweir                 aName += '/';
3081cdf0e10cSrcweir                 aName += pElement->m_aOriginalName;
3082cdf0e10cSrcweir                 UCBStorage* pStorage = new UCBStorage( aName, nMode, bDirect, sal_False, pImp->m_bRepairPackage, pImp->m_xProgressHandler );
3083cdf0e10cSrcweir                 pElement->m_xStorage = pStorage->pImp;
3084cdf0e10cSrcweir                 return pStorage;
3085cdf0e10cSrcweir             }
3086cdf0e10cSrcweir             else
3087cdf0e10cSrcweir             {
3088cdf0e10cSrcweir //                    DBG_ASSERT( bDirect == pElement->m_xStorage->m_bDirect, "Wrong DirectMode!" );
3089cdf0e10cSrcweir                 return new UCBStorage( pElement->m_xStorage );
3090cdf0e10cSrcweir             }
3091cdf0e10cSrcweir         }
3092cdf0e10cSrcweir     }
3093cdf0e10cSrcweir     else if ( !pElement->m_xStream.Is() )
3094cdf0e10cSrcweir     {
3095cdf0e10cSrcweir         // storage is opened the first time
3096cdf0e10cSrcweir         sal_Bool bIsWritable = (( pImp->m_nMode & STREAM_WRITE ) != 0 );
3097cdf0e10cSrcweir         if ( pImp->m_bIsLinked && pImp->m_bIsRoot && bIsWritable )
3098cdf0e10cSrcweir         {
3099cdf0e10cSrcweir             // make sure that the root storage object has been created before substorages will be created
3100cdf0e10cSrcweir             INetURLObject aFolderObj( pImp->m_aURL );
3101cdf0e10cSrcweir             String aName = aFolderObj.GetName();
3102cdf0e10cSrcweir             aFolderObj.removeSegment();
3103cdf0e10cSrcweir 
3104cdf0e10cSrcweir             Content aFolder( aFolderObj.GetMainURL( INetURLObject::NO_DECODE ), Reference < XCommandEnvironment >() );
3105cdf0e10cSrcweir             pImp->m_pContent = new Content;
3106cdf0e10cSrcweir             sal_Bool bRet = ::utl::UCBContentHelper::MakeFolder( aFolder, pImp->m_aName, *pImp->m_pContent );
3107cdf0e10cSrcweir             if ( !bRet )
3108cdf0e10cSrcweir             {
3109cdf0e10cSrcweir                 SetError( SVSTREAM_CANNOT_MAKE );
3110cdf0e10cSrcweir                 return NULL;
3111cdf0e10cSrcweir             }
3112cdf0e10cSrcweir         }
3113cdf0e10cSrcweir 
3114cdf0e10cSrcweir         UCBStorage_Impl* pStor = pImp->OpenStorage( pElement, nMode, bDirect );
3115cdf0e10cSrcweir         if ( pStor )
3116cdf0e10cSrcweir         {
3117cdf0e10cSrcweir             if ( pElement->m_bIsInserted )
3118cdf0e10cSrcweir                 pStor->m_bListCreated = sal_True; // the storage is pretty new, nothing to read
3119cdf0e10cSrcweir 
3120cdf0e10cSrcweir             return new UCBStorage( pStor );
3121cdf0e10cSrcweir         }
3122cdf0e10cSrcweir     }
3123cdf0e10cSrcweir 
3124cdf0e10cSrcweir     return NULL;
3125cdf0e10cSrcweir }
3126cdf0e10cSrcweir 
3127cdf0e10cSrcweir UCBStorage_Impl* UCBStorage_Impl::OpenStorage( UCBStorageElement_Impl* pElement, StreamMode nMode, sal_Bool bDirect )
3128cdf0e10cSrcweir {
3129cdf0e10cSrcweir     UCBStorage_Impl* pRet = NULL;
3130cdf0e10cSrcweir     String aName( m_aURL );
3131cdf0e10cSrcweir     aName += '/';
3132cdf0e10cSrcweir     aName += pElement->m_aOriginalName;  // ???
3133cdf0e10cSrcweir 
3134cdf0e10cSrcweir     pElement->m_bIsStorage = pElement->m_bIsFolder = sal_True;
3135cdf0e10cSrcweir 
3136cdf0e10cSrcweir     if ( m_bIsLinked && !::utl::UCBContentHelper::Exists( aName ) )
3137cdf0e10cSrcweir     {
3138cdf0e10cSrcweir         Content aNewFolder;
3139cdf0e10cSrcweir         sal_Bool bRet = ::utl::UCBContentHelper::MakeFolder( *m_pContent, pElement->m_aOriginalName, aNewFolder );
3140cdf0e10cSrcweir         if ( bRet )
3141cdf0e10cSrcweir             pRet = new UCBStorage_Impl( aNewFolder, aName, nMode, NULL, bDirect, sal_False, m_bRepairPackage, m_xProgressHandler );
3142cdf0e10cSrcweir     }
3143cdf0e10cSrcweir     else
3144cdf0e10cSrcweir     {
3145cdf0e10cSrcweir         pRet = new UCBStorage_Impl( aName, nMode, NULL, bDirect, sal_False, m_bRepairPackage, m_xProgressHandler );
3146cdf0e10cSrcweir     }
3147cdf0e10cSrcweir 
3148cdf0e10cSrcweir     if ( pRet )
3149cdf0e10cSrcweir     {
3150cdf0e10cSrcweir         pRet->m_bIsLinked = m_bIsLinked;
3151cdf0e10cSrcweir         pRet->m_bIsRoot = sal_False;
3152cdf0e10cSrcweir 
3153cdf0e10cSrcweir         // if name has been changed before creating the stream: set name!
3154cdf0e10cSrcweir         pRet->m_aName = pElement->m_aOriginalName;
3155cdf0e10cSrcweir         pElement->m_xStorage = pRet;
3156cdf0e10cSrcweir     }
3157cdf0e10cSrcweir 
3158cdf0e10cSrcweir     if ( pRet )
3159cdf0e10cSrcweir         pRet->Init();
3160cdf0e10cSrcweir 
3161cdf0e10cSrcweir     return pRet;
3162cdf0e10cSrcweir }
3163cdf0e10cSrcweir 
3164cdf0e10cSrcweir sal_Bool UCBStorage::IsStorage( const String& rEleName ) const
3165cdf0e10cSrcweir {
3166cdf0e10cSrcweir     if( !rEleName.Len() )
3167cdf0e10cSrcweir         return sal_False;
3168cdf0e10cSrcweir 
3169cdf0e10cSrcweir     const UCBStorageElement_Impl *pElement = FindElement_Impl( rEleName );
3170cdf0e10cSrcweir     return ( pElement && pElement->m_bIsStorage );
3171cdf0e10cSrcweir }
3172cdf0e10cSrcweir 
3173cdf0e10cSrcweir sal_Bool UCBStorage::IsStream( const String& rEleName ) const
3174cdf0e10cSrcweir {
3175cdf0e10cSrcweir     if( !rEleName.Len() )
3176cdf0e10cSrcweir         return sal_False;
3177cdf0e10cSrcweir 
3178cdf0e10cSrcweir     const UCBStorageElement_Impl *pElement = FindElement_Impl( rEleName );
3179cdf0e10cSrcweir     return ( pElement && !pElement->m_bIsStorage );
3180cdf0e10cSrcweir }
3181cdf0e10cSrcweir 
3182cdf0e10cSrcweir sal_Bool UCBStorage::IsContained( const String & rEleName ) const
3183cdf0e10cSrcweir {
3184cdf0e10cSrcweir     if( !rEleName.Len() )
3185cdf0e10cSrcweir         return sal_False;
3186cdf0e10cSrcweir     const UCBStorageElement_Impl *pElement = FindElement_Impl( rEleName );
3187cdf0e10cSrcweir     return ( pElement != NULL );
3188cdf0e10cSrcweir }
3189cdf0e10cSrcweir 
3190cdf0e10cSrcweir sal_Bool UCBStorage::Remove( const String& rEleName )
3191cdf0e10cSrcweir {
3192cdf0e10cSrcweir     if( !rEleName.Len() )
3193cdf0e10cSrcweir         return sal_False;
3194cdf0e10cSrcweir 
3195cdf0e10cSrcweir     UCBStorageElement_Impl *pElement = FindElement_Impl( rEleName );
3196cdf0e10cSrcweir     if ( pElement )
3197cdf0e10cSrcweir     {
3198cdf0e10cSrcweir         pElement->m_bIsRemoved = sal_True;
3199cdf0e10cSrcweir     }
3200cdf0e10cSrcweir     else
3201cdf0e10cSrcweir         SetError( SVSTREAM_FILE_NOT_FOUND );
3202cdf0e10cSrcweir 
3203cdf0e10cSrcweir     return ( pElement != NULL );
3204cdf0e10cSrcweir }
3205cdf0e10cSrcweir 
3206cdf0e10cSrcweir sal_Bool UCBStorage::Rename( const String& rEleName, const String& rNewName )
3207cdf0e10cSrcweir {
3208cdf0e10cSrcweir     if( !rEleName.Len()|| !rNewName.Len() )
3209cdf0e10cSrcweir         return sal_False;
3210cdf0e10cSrcweir 
3211cdf0e10cSrcweir     UCBStorageElement_Impl *pAlreadyExisting = FindElement_Impl( rNewName );
3212cdf0e10cSrcweir     if ( pAlreadyExisting )
3213cdf0e10cSrcweir     {
3214cdf0e10cSrcweir         SetError( SVSTREAM_ACCESS_DENIED );
3215cdf0e10cSrcweir         return sal_False;                       // can't change to a name that is already used
3216cdf0e10cSrcweir     }
3217cdf0e10cSrcweir 
3218cdf0e10cSrcweir     UCBStorageElement_Impl *pElement = FindElement_Impl( rEleName );
3219cdf0e10cSrcweir     if ( pElement )
3220cdf0e10cSrcweir     {
3221cdf0e10cSrcweir         pElement->m_aName = rNewName;
3222cdf0e10cSrcweir     }
3223cdf0e10cSrcweir     else
3224cdf0e10cSrcweir         SetError( SVSTREAM_FILE_NOT_FOUND );
3225cdf0e10cSrcweir 
3226cdf0e10cSrcweir     return pElement != NULL;
3227cdf0e10cSrcweir }
3228cdf0e10cSrcweir 
3229cdf0e10cSrcweir sal_Bool UCBStorage::MoveTo( const String& rEleName, BaseStorage* pNewSt, const String& rNewName )
3230cdf0e10cSrcweir {
3231cdf0e10cSrcweir     if( !rEleName.Len() || !rNewName.Len() )
3232cdf0e10cSrcweir         return sal_False;
3233cdf0e10cSrcweir 
3234cdf0e10cSrcweir     if ( pNewSt == ((BaseStorage*) this) && !FindElement_Impl( rNewName ) )
3235cdf0e10cSrcweir     {
3236cdf0e10cSrcweir         return Rename( rEleName, rNewName );
3237cdf0e10cSrcweir     }
3238cdf0e10cSrcweir     else
3239cdf0e10cSrcweir     {
3240cdf0e10cSrcweir /*
3241cdf0e10cSrcweir         if ( PTR_CAST( UCBStorage, pNewSt ) )
3242cdf0e10cSrcweir         {
3243cdf0e10cSrcweir             // because the element is moved, not copied, a special optimization is possible :
3244cdf0e10cSrcweir             // first copy the UCBStorageElement; flag old element as "Removed" and new as "Inserted",
3245cdf0e10cSrcweir             // clear original name/type of the new element
3246cdf0e10cSrcweir             // if moved element is open: copy content, but change absolute URL ( and those of all children of the element! ),
3247cdf0e10cSrcweir             // clear original name/type of new content, keep the old original stream/storage, but forget its working streams,
3248cdf0e10cSrcweir             // close original UCBContent and original stream, only the TempFile and its stream may remain unchanged, but now
3249cdf0e10cSrcweir             // belong to the new content
3250cdf0e10cSrcweir             // if original and editable stream are identical ( readonly element ), it has to be copied to the editable
3251cdf0e10cSrcweir             // stream of the destination object
3252cdf0e10cSrcweir             // Not implemented at the moment ( risky?! ), perhaps later
3253cdf0e10cSrcweir         }
3254cdf0e10cSrcweir */
3255cdf0e10cSrcweir         // MoveTo is done by first copying to the new destination and then removing the old element
3256cdf0e10cSrcweir         sal_Bool bRet = CopyTo( rEleName, pNewSt, rNewName );
3257cdf0e10cSrcweir         if ( bRet )
3258cdf0e10cSrcweir             bRet = Remove( rEleName );
3259cdf0e10cSrcweir         return bRet;
3260cdf0e10cSrcweir     }
3261cdf0e10cSrcweir }
3262cdf0e10cSrcweir 
3263cdf0e10cSrcweir sal_Bool UCBStorage::ValidateFAT()
3264cdf0e10cSrcweir {
3265cdf0e10cSrcweir     // ???
3266cdf0e10cSrcweir     return sal_True;
3267cdf0e10cSrcweir }
3268cdf0e10cSrcweir 
3269cdf0e10cSrcweir sal_Bool UCBStorage::Validate( sal_Bool  bWrite ) const
3270cdf0e10cSrcweir {
3271cdf0e10cSrcweir     // ???
3272cdf0e10cSrcweir     return ( !bWrite || ( pImp->m_nMode & STREAM_WRITE ) );
3273cdf0e10cSrcweir }
3274cdf0e10cSrcweir 
3275cdf0e10cSrcweir sal_Bool UCBStorage::ValidateMode( StreamMode m ) const
3276cdf0e10cSrcweir {
3277cdf0e10cSrcweir     // ???
3278cdf0e10cSrcweir     if( m == ( STREAM_READ | STREAM_TRUNC ) )  // from stg.cxx
3279cdf0e10cSrcweir         return sal_True;
3280cdf0e10cSrcweir     sal_uInt16 nCurMode = 0xFFFF;
3281cdf0e10cSrcweir     if( ( m & 3 ) == STREAM_READ )
3282cdf0e10cSrcweir     {
3283cdf0e10cSrcweir         // only SHARE_DENYWRITE or SHARE_DENYALL allowed
3284cdf0e10cSrcweir         if( ( ( m & STREAM_SHARE_DENYWRITE )
3285cdf0e10cSrcweir            && ( nCurMode & STREAM_SHARE_DENYWRITE ) )
3286cdf0e10cSrcweir          || ( ( m & STREAM_SHARE_DENYALL )
3287cdf0e10cSrcweir            && ( nCurMode & STREAM_SHARE_DENYALL ) ) )
3288cdf0e10cSrcweir             return sal_True;
3289cdf0e10cSrcweir     }
3290cdf0e10cSrcweir     else
3291cdf0e10cSrcweir     {
3292cdf0e10cSrcweir         // only SHARE_DENYALL allowed
3293cdf0e10cSrcweir         // storages open in r/o mode are OK, since only
3294cdf0e10cSrcweir         // the commit may fail
3295cdf0e10cSrcweir         if( ( m & STREAM_SHARE_DENYALL )
3296cdf0e10cSrcweir          && ( nCurMode & STREAM_SHARE_DENYALL ) )
3297cdf0e10cSrcweir             return sal_True;
3298cdf0e10cSrcweir     }
3299cdf0e10cSrcweir 
3300cdf0e10cSrcweir     return sal_True;
3301cdf0e10cSrcweir }
3302cdf0e10cSrcweir 
3303cdf0e10cSrcweir const SvStream* UCBStorage::GetSvStream() const
3304cdf0e10cSrcweir {
3305cdf0e10cSrcweir     // this would cause a complete download of the file
3306cdf0e10cSrcweir     // as it looks, this method is NOT used inside of SOT, only exported by class SotStorage - but for what ???
3307cdf0e10cSrcweir     return pImp->m_pSource;
3308cdf0e10cSrcweir }
3309cdf0e10cSrcweir 
3310cdf0e10cSrcweir sal_Bool UCBStorage::Equals( const BaseStorage& rStorage ) const
3311cdf0e10cSrcweir {
3312cdf0e10cSrcweir     // ???
3313cdf0e10cSrcweir     return ((BaseStorage*)this) == &rStorage;
3314cdf0e10cSrcweir }
3315cdf0e10cSrcweir 
3316cdf0e10cSrcweir sal_Bool UCBStorage::IsStorageFile( const String& rFileName )
3317cdf0e10cSrcweir {
3318cdf0e10cSrcweir     String aFileURL = rFileName;
3319cdf0e10cSrcweir     INetURLObject aObj( aFileURL );
3320cdf0e10cSrcweir     if ( aObj.GetProtocol() == INET_PROT_NOT_VALID )
3321cdf0e10cSrcweir     {
3322cdf0e10cSrcweir         ::utl::LocalFileHelper::ConvertPhysicalNameToURL( rFileName, aFileURL );
3323cdf0e10cSrcweir         aObj.SetURL( aFileURL );
3324cdf0e10cSrcweir         aFileURL = aObj.GetMainURL( INetURLObject::NO_DECODE );
3325cdf0e10cSrcweir     }
3326cdf0e10cSrcweir 
3327cdf0e10cSrcweir     SvStream * pStm = ::utl::UcbStreamHelper::CreateStream( aFileURL, STREAM_STD_READ );
3328cdf0e10cSrcweir     sal_Bool bRet = UCBStorage::IsStorageFile( pStm );
3329cdf0e10cSrcweir     delete pStm;
3330cdf0e10cSrcweir     return bRet;
3331cdf0e10cSrcweir }
3332cdf0e10cSrcweir 
3333cdf0e10cSrcweir sal_Bool UCBStorage::IsStorageFile( SvStream* pFile )
3334cdf0e10cSrcweir {
3335cdf0e10cSrcweir     if ( !pFile )
3336cdf0e10cSrcweir         return sal_False;
3337cdf0e10cSrcweir 
3338cdf0e10cSrcweir     sal_uLong nPos = pFile->Tell();
3339cdf0e10cSrcweir     pFile->Seek( STREAM_SEEK_TO_END );
3340cdf0e10cSrcweir     if ( pFile->Tell() < 4 )
3341cdf0e10cSrcweir         return sal_False;
3342cdf0e10cSrcweir 
3343cdf0e10cSrcweir     pFile->Seek(0);
3344cdf0e10cSrcweir     sal_uInt32 nBytes;
3345cdf0e10cSrcweir     *pFile >> nBytes;
3346cdf0e10cSrcweir 
3347cdf0e10cSrcweir     // search for the magic bytes
3348cdf0e10cSrcweir     sal_Bool bRet = ( nBytes == 0x04034b50 );
3349cdf0e10cSrcweir     if ( !bRet )
3350cdf0e10cSrcweir     {
3351cdf0e10cSrcweir         // disk spanned file have an additional header in front of the usual one
3352cdf0e10cSrcweir         bRet = ( nBytes == 0x08074b50 );
3353cdf0e10cSrcweir         if ( bRet )
3354cdf0e10cSrcweir         {
3355cdf0e10cSrcweir             *pFile >> nBytes;
3356cdf0e10cSrcweir             bRet = ( nBytes == 0x04034b50 );
3357cdf0e10cSrcweir         }
3358cdf0e10cSrcweir     }
3359cdf0e10cSrcweir 
3360cdf0e10cSrcweir     pFile->Seek( nPos );
3361cdf0e10cSrcweir     return bRet;
3362cdf0e10cSrcweir }
3363cdf0e10cSrcweir 
3364cdf0e10cSrcweir sal_Bool UCBStorage::IsDiskSpannedFile( SvStream* pFile )
3365cdf0e10cSrcweir {
3366cdf0e10cSrcweir     if ( !pFile )
3367cdf0e10cSrcweir         return sal_False;
3368cdf0e10cSrcweir 
3369cdf0e10cSrcweir     sal_uLong nPos = pFile->Tell();
3370cdf0e10cSrcweir     pFile->Seek( STREAM_SEEK_TO_END );
3371cdf0e10cSrcweir     if ( !pFile->Tell() )
3372cdf0e10cSrcweir         return sal_False;
3373cdf0e10cSrcweir 
3374cdf0e10cSrcweir     pFile->Seek(0);
3375cdf0e10cSrcweir     sal_uInt32 nBytes;
3376cdf0e10cSrcweir     *pFile >> nBytes;
3377cdf0e10cSrcweir 
3378cdf0e10cSrcweir     // disk spanned file have an additional header in front of the usual one
3379cdf0e10cSrcweir     sal_Bool bRet = ( nBytes == 0x08074b50 );
3380cdf0e10cSrcweir     if ( bRet )
3381cdf0e10cSrcweir     {
3382cdf0e10cSrcweir         *pFile >> nBytes;
3383cdf0e10cSrcweir         bRet = ( nBytes == 0x04034b50 );
3384cdf0e10cSrcweir     }
3385cdf0e10cSrcweir 
3386cdf0e10cSrcweir     pFile->Seek( nPos );
3387cdf0e10cSrcweir     return bRet;
3388cdf0e10cSrcweir }
3389cdf0e10cSrcweir 
3390cdf0e10cSrcweir String UCBStorage::GetLinkedFile( SvStream &rStream )
3391cdf0e10cSrcweir {
3392cdf0e10cSrcweir     String aString;
3393cdf0e10cSrcweir     sal_uLong nPos = rStream.Tell();
3394cdf0e10cSrcweir     rStream.Seek( STREAM_SEEK_TO_END );
3395cdf0e10cSrcweir     if ( !rStream.Tell() )
3396cdf0e10cSrcweir         return aString;
3397cdf0e10cSrcweir 
3398cdf0e10cSrcweir     rStream.Seek(0);
3399cdf0e10cSrcweir     sal_uInt32 nBytes;
3400cdf0e10cSrcweir     rStream >> nBytes;
3401cdf0e10cSrcweir     if( nBytes == 0x04034b50 )
3402cdf0e10cSrcweir     {
3403cdf0e10cSrcweir         ByteString aTmp;
3404cdf0e10cSrcweir         rStream.ReadByteString( aTmp );
3405cdf0e10cSrcweir         if ( aTmp.CompareTo( "ContentURL=", 11 ) == COMPARE_EQUAL )
3406cdf0e10cSrcweir         {
3407cdf0e10cSrcweir             aTmp.Erase( 0, 11 );
3408cdf0e10cSrcweir             aString = String( aTmp, RTL_TEXTENCODING_UTF8 );
3409cdf0e10cSrcweir         }
3410cdf0e10cSrcweir     }
3411cdf0e10cSrcweir 
3412cdf0e10cSrcweir     rStream.Seek( nPos );
3413cdf0e10cSrcweir     return aString;
3414cdf0e10cSrcweir }
3415cdf0e10cSrcweir 
3416cdf0e10cSrcweir String UCBStorage::CreateLinkFile( const String& rName )
3417cdf0e10cSrcweir {
3418cdf0e10cSrcweir     // create a stream to write the link file - use a temp file, because it may be no file content
3419cdf0e10cSrcweir     INetURLObject aFolderObj( rName );
3420cdf0e10cSrcweir     String aName = aFolderObj.GetName();
3421cdf0e10cSrcweir     aFolderObj.removeSegment();
3422cdf0e10cSrcweir     String aFolderURL( aFolderObj.GetMainURL( INetURLObject::NO_DECODE ) );
3423cdf0e10cSrcweir     ::utl::TempFile* pTempFile = new ::utl::TempFile( &aFolderURL );
3424cdf0e10cSrcweir 
3425cdf0e10cSrcweir     // get the stream from the temp file
3426cdf0e10cSrcweir     SvStream* pStream = pTempFile->GetStream( STREAM_STD_READWRITE | STREAM_TRUNC );
3427cdf0e10cSrcweir 
3428cdf0e10cSrcweir     // write header
3429cdf0e10cSrcweir     *pStream << ( sal_uInt32 ) 0x04034b50;
3430cdf0e10cSrcweir 
3431cdf0e10cSrcweir     // assemble a new folder name in the destination folder
3432cdf0e10cSrcweir     INetURLObject aObj( rName );
3433cdf0e10cSrcweir     String aTmpName = aObj.GetName();
3434cdf0e10cSrcweir     String aTitle = String::CreateFromAscii( "content." );
3435cdf0e10cSrcweir     aTitle += aTmpName;
3436cdf0e10cSrcweir 
3437cdf0e10cSrcweir     // create a folder and store its URL
3438cdf0e10cSrcweir     Content aFolder( aFolderURL, Reference < XCommandEnvironment >() );
3439cdf0e10cSrcweir     Content aNewFolder;
3440cdf0e10cSrcweir     sal_Bool bRet = ::utl::UCBContentHelper::MakeFolder( aFolder, aTitle, aNewFolder );
3441cdf0e10cSrcweir     if ( !bRet )
3442cdf0e10cSrcweir     {
3443cdf0e10cSrcweir         aFolderObj.insertName( aTitle );
3444cdf0e10cSrcweir         if ( ::utl::UCBContentHelper::Exists( aFolderObj.GetMainURL( INetURLObject::NO_DECODE ) ) )
3445cdf0e10cSrcweir         {
3446cdf0e10cSrcweir             // Hack, because already existing files give the same CommandAbortedException as any other error !
3447cdf0e10cSrcweir             // append a number until the name can be used for a new folder
3448cdf0e10cSrcweir             aTitle += '.';
3449cdf0e10cSrcweir             for ( sal_Int32 i=0; !bRet; i++ )
3450cdf0e10cSrcweir             {
3451cdf0e10cSrcweir                 String aTmp( aTitle );
3452cdf0e10cSrcweir                 aTmp += String::CreateFromInt32( i );
3453cdf0e10cSrcweir                 bRet = ::utl::UCBContentHelper::MakeFolder( aFolder, aTmp, aNewFolder );
3454cdf0e10cSrcweir                 if ( bRet )
3455cdf0e10cSrcweir                     aTitle = aTmp;
3456cdf0e10cSrcweir                 else
3457cdf0e10cSrcweir                 {
3458cdf0e10cSrcweir                     aFolderObj.SetName( aTmp );
3459cdf0e10cSrcweir                     if ( !::utl::UCBContentHelper::Exists( aFolderObj.GetMainURL( INetURLObject::NO_DECODE ) ) )
3460cdf0e10cSrcweir                         // Hack, because already existing files give the same CommandAbortedException as any other error !
3461cdf0e10cSrcweir                         break;
3462cdf0e10cSrcweir                 }
3463cdf0e10cSrcweir             }
3464cdf0e10cSrcweir         }
3465cdf0e10cSrcweir     }
3466cdf0e10cSrcweir 
3467cdf0e10cSrcweir     if ( bRet )
3468cdf0e10cSrcweir     {
3469cdf0e10cSrcweir         // get the URL
3470cdf0e10cSrcweir         aObj.SetName( aTitle );
3471cdf0e10cSrcweir         String aURL = aObj.GetMainURL( INetURLObject::NO_DECODE );
3472cdf0e10cSrcweir 
3473cdf0e10cSrcweir         // store it as key/value pair
3474cdf0e10cSrcweir         String aLink = String::CreateFromAscii("ContentURL=");
3475cdf0e10cSrcweir         aLink += aURL;
3476cdf0e10cSrcweir         pStream->WriteByteString( aLink, RTL_TEXTENCODING_UTF8 );
3477cdf0e10cSrcweir         pStream->Flush();
3478cdf0e10cSrcweir 
3479cdf0e10cSrcweir         // move the stream to its desired location
3480cdf0e10cSrcweir         Content aSource( pTempFile->GetURL(), Reference < XCommandEnvironment >() );
3481cdf0e10cSrcweir         DELETEZ( pTempFile );
3482cdf0e10cSrcweir         aFolder.transferContent( aSource, InsertOperation_MOVE, aName, NameClash::OVERWRITE );
3483cdf0e10cSrcweir         return aURL;
3484cdf0e10cSrcweir     }
3485cdf0e10cSrcweir 
3486cdf0e10cSrcweir     pTempFile->EnableKillingFile( sal_True );
3487cdf0e10cSrcweir     delete pTempFile;
3488cdf0e10cSrcweir     return String();
3489cdf0e10cSrcweir }
3490cdf0e10cSrcweir 
3491cdf0e10cSrcweir sal_Bool UCBStorage::SetProperty( const String& rName, const ::com::sun::star::uno::Any& rValue )
3492cdf0e10cSrcweir {
3493cdf0e10cSrcweir     if ( rName.CompareToAscii("Title") == COMPARE_EQUAL )
3494cdf0e10cSrcweir         return sal_False;
3495cdf0e10cSrcweir 
3496cdf0e10cSrcweir     if ( rName.CompareToAscii("MediaType") == COMPARE_EQUAL )
3497cdf0e10cSrcweir     {
3498cdf0e10cSrcweir         ::rtl::OUString aTmp;
3499cdf0e10cSrcweir         rValue >>= aTmp;
3500cdf0e10cSrcweir         pImp->m_aContentType = aTmp;
3501cdf0e10cSrcweir     }
3502cdf0e10cSrcweir 
3503cdf0e10cSrcweir     try
3504cdf0e10cSrcweir     {
3505cdf0e10cSrcweir         if ( pImp->GetContent() )
3506cdf0e10cSrcweir         {
3507cdf0e10cSrcweir             pImp->m_pContent->setPropertyValue( rName, rValue );
3508cdf0e10cSrcweir             return sal_True;
3509cdf0e10cSrcweir         }
3510cdf0e10cSrcweir     }
3511cdf0e10cSrcweir     catch ( Exception& )
3512cdf0e10cSrcweir     {
3513cdf0e10cSrcweir     }
3514cdf0e10cSrcweir 
3515cdf0e10cSrcweir     return sal_False;
3516cdf0e10cSrcweir }
3517cdf0e10cSrcweir 
3518cdf0e10cSrcweir sal_Bool UCBStorage::GetProperty( const String& rName, ::com::sun::star::uno::Any& rValue )
3519cdf0e10cSrcweir {
3520cdf0e10cSrcweir     try
3521cdf0e10cSrcweir     {
3522cdf0e10cSrcweir         if ( pImp->GetContent() )
3523cdf0e10cSrcweir         {
3524cdf0e10cSrcweir             rValue = pImp->m_pContent->getPropertyValue( rName );
3525cdf0e10cSrcweir             return sal_True;
3526cdf0e10cSrcweir         }
3527cdf0e10cSrcweir     }
3528cdf0e10cSrcweir     catch ( Exception& )
3529cdf0e10cSrcweir     {
3530cdf0e10cSrcweir     }
3531cdf0e10cSrcweir 
3532cdf0e10cSrcweir     return sal_False;
3533cdf0e10cSrcweir }
3534cdf0e10cSrcweir 
3535cdf0e10cSrcweir sal_Bool UCBStorage::GetProperty( const String& rEleName, const String& rName, ::com::sun::star::uno::Any& rValue )
3536cdf0e10cSrcweir {
3537cdf0e10cSrcweir     UCBStorageElement_Impl *pEle = FindElement_Impl( rEleName );
3538cdf0e10cSrcweir     if ( !pEle )
3539cdf0e10cSrcweir         return sal_False;
3540cdf0e10cSrcweir 
3541cdf0e10cSrcweir     if ( !pEle->m_bIsFolder )
3542cdf0e10cSrcweir     {
3543cdf0e10cSrcweir         if ( !pEle->m_xStream.Is() )
3544cdf0e10cSrcweir             pImp->OpenStream( pEle, pImp->m_nMode, pImp->m_bDirect );
3545cdf0e10cSrcweir         if ( pEle->m_xStream->m_nError )
3546cdf0e10cSrcweir         {
3547cdf0e10cSrcweir             pEle->m_xStream.Clear();
3548cdf0e10cSrcweir             return sal_False;
3549cdf0e10cSrcweir         }
3550cdf0e10cSrcweir 
3551cdf0e10cSrcweir         try
3552cdf0e10cSrcweir         {
3553cdf0e10cSrcweir             if ( pEle->m_xStream->m_pContent )
3554cdf0e10cSrcweir             {
3555cdf0e10cSrcweir                 rValue = pEle->m_xStream->m_pContent->getPropertyValue( rName );
3556cdf0e10cSrcweir                 return sal_True;
3557cdf0e10cSrcweir             }
3558cdf0e10cSrcweir         }
3559cdf0e10cSrcweir         catch ( Exception& )
3560cdf0e10cSrcweir         {
3561cdf0e10cSrcweir         }
3562cdf0e10cSrcweir     }
3563cdf0e10cSrcweir     else
3564cdf0e10cSrcweir     {
3565cdf0e10cSrcweir         if ( !pEle->m_xStorage.Is() )
3566cdf0e10cSrcweir             pImp->OpenStorage( pEle, pImp->m_nMode, pImp->m_bDirect );
3567cdf0e10cSrcweir         if ( pEle->m_xStorage->m_nError )
3568cdf0e10cSrcweir         {
3569cdf0e10cSrcweir             pEle->m_xStorage.Clear();
3570cdf0e10cSrcweir             return sal_False;
3571cdf0e10cSrcweir         }
3572cdf0e10cSrcweir 
3573cdf0e10cSrcweir         try
3574cdf0e10cSrcweir         {
3575cdf0e10cSrcweir             if ( pEle->m_xStorage->GetContent() )
3576cdf0e10cSrcweir             {
3577cdf0e10cSrcweir                 rValue = pEle->m_xStorage->m_pContent->getPropertyValue( rName );
3578cdf0e10cSrcweir                 return sal_True;
3579cdf0e10cSrcweir             }
3580cdf0e10cSrcweir         }
3581cdf0e10cSrcweir         catch ( Exception& )
3582cdf0e10cSrcweir         {
3583cdf0e10cSrcweir         }
3584cdf0e10cSrcweir     }
3585cdf0e10cSrcweir 
3586cdf0e10cSrcweir     return sal_False;
3587cdf0e10cSrcweir }
3588cdf0e10cSrcweir 
3589cdf0e10cSrcweir UNOStorageHolderList* UCBStorage::GetUNOStorageHolderList()
3590cdf0e10cSrcweir {
3591cdf0e10cSrcweir     if ( !pImp->m_pUNOStorageHolderList )
3592cdf0e10cSrcweir         pImp->m_pUNOStorageHolderList = new UNOStorageHolderList;
3593cdf0e10cSrcweir 
3594cdf0e10cSrcweir     return pImp->m_pUNOStorageHolderList;
3595cdf0e10cSrcweir }
3596