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