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