1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "oox/helper/storagebase.hxx"
22 #include <com/sun/star/embed/XTransactedObject.hpp>
23 #include <com/sun/star/io/XStream.hpp>
24 #include <rtl/ustrbuf.hxx>
25 #include "oox/helper/binaryinputstream.hxx"
26 #include "oox/helper/binaryoutputstream.hxx"
30 // ============================================================================
32 using namespace ::com::sun::star::embed
;
33 using namespace ::com::sun::star::io
;
34 using namespace ::com::sun::star::uno
;
36 // ============================================================================
40 void lclSplitFirstElement( OUString
& orElement
, OUString
& orRemainder
, OUString aFullName
)
42 sal_Int32 nSlashPos
= aFullName
.indexOf( '/' );
44 // strip leading slashes
45 while( nSlashPos
== 0 )
47 aFullName
= aFullName
.copy(1);
48 nSlashPos
= aFullName
.indexOf( '/' );
51 if( (0 <= nSlashPos
) && (nSlashPos
< aFullName
.getLength()) )
53 orElement
= aFullName
.copy( 0, nSlashPos
);
54 orRemainder
= aFullName
.copy( nSlashPos
+ 1 );
58 orElement
= aFullName
;
64 // ----------------------------------------------------------------------------
66 StorageBase::StorageBase( const Reference
< XInputStream
>& rxInStream
, bool bBaseStreamAccess
) :
67 mxInStream( rxInStream
),
68 mbBaseStreamAccess( bBaseStreamAccess
),
71 OSL_ENSURE( mxInStream
.is(), "StorageBase::StorageBase - missing base input stream" );
74 StorageBase::StorageBase( const Reference
< XStream
>& rxOutStream
, bool bBaseStreamAccess
) :
75 mxOutStream( rxOutStream
),
76 mbBaseStreamAccess( bBaseStreamAccess
),
79 OSL_ENSURE( mxOutStream
.is(), "StorageBase::StorageBase - missing base output stream" );
82 StorageBase::StorageBase( const StorageBase
& rParentStorage
, const OUString
& rStorageName
, bool bReadOnly
) :
83 maParentPath( rParentStorage
.getPath() ),
84 maStorageName( rStorageName
),
85 mbBaseStreamAccess( false ),
86 mbReadOnly( bReadOnly
)
90 StorageBase::~StorageBase()
94 bool StorageBase::isStorage() const
96 return implIsStorage();
99 bool StorageBase::isRootStorage() const
101 return implIsStorage() && maStorageName
.isEmpty();
104 bool StorageBase::isReadOnly() const
109 Reference
< XStorage
> StorageBase::getXStorage() const
111 return implGetXStorage();
114 const OUString
& StorageBase::getName() const
116 return maStorageName
;
119 OUString
StorageBase::getPath() const
121 OUStringBuffer
aBuffer( maParentPath
);
122 if( !aBuffer
.isEmpty() )
123 aBuffer
.append( '/' );
124 aBuffer
.append( maStorageName
);
125 return aBuffer
.makeStringAndClear();
128 void StorageBase::getElementNames( ::std::vector
< OUString
>& orElementNames
) const
130 orElementNames
.clear();
131 implGetElementNames( orElementNames
);
134 StorageRef
StorageBase::openSubStorage( const OUString
& rStorageName
, bool bCreateMissing
)
136 StorageRef xSubStorage
;
137 OSL_ENSURE( !bCreateMissing
|| !mbReadOnly
, "StorageBase::openSubStorage - cannot create substorage in read-only mode" );
138 if( !bCreateMissing
|| !mbReadOnly
)
140 OUString aElement
, aRemainder
;
141 lclSplitFirstElement( aElement
, aRemainder
, rStorageName
);
142 if( !aElement
.isEmpty() )
143 xSubStorage
= getSubStorage( aElement
, bCreateMissing
);
144 if( xSubStorage
.get() && !aRemainder
.isEmpty() )
145 xSubStorage
= xSubStorage
->openSubStorage( aRemainder
, bCreateMissing
);
150 Reference
< XInputStream
> StorageBase::openInputStream( const OUString
& rStreamName
)
152 Reference
< XInputStream
> xInStream
;
153 OUString aElement
, aRemainder
;
154 lclSplitFirstElement( aElement
, aRemainder
, rStreamName
);
155 if( !aElement
.isEmpty() )
157 if( !aRemainder
.isEmpty() )
159 StorageRef xSubStorage
= getSubStorage( aElement
, false );
160 if( xSubStorage
.get() )
161 xInStream
= xSubStorage
->openInputStream( aRemainder
);
165 xInStream
= implOpenInputStream( aElement
);
168 else if( mbBaseStreamAccess
)
170 xInStream
= mxInStream
;
175 Reference
< XOutputStream
> StorageBase::openOutputStream( const OUString
& rStreamName
)
177 Reference
< XOutputStream
> xOutStream
;
178 OSL_ENSURE( !mbReadOnly
, "StorageBase::openOutputStream - cannot create output stream in read-only mode" );
181 OUString aElement
, aRemainder
;
182 lclSplitFirstElement( aElement
, aRemainder
, rStreamName
);
183 if( !aElement
.isEmpty() )
185 if( !aRemainder
.isEmpty() )
187 StorageRef xSubStorage
= getSubStorage( aElement
, true );
188 if( xSubStorage
.get() )
189 xOutStream
= xSubStorage
->openOutputStream( aRemainder
);
193 xOutStream
= implOpenOutputStream( aElement
);
196 else if( mbBaseStreamAccess
)
198 xOutStream
= mxOutStream
->getOutputStream();
204 void StorageBase::copyToStorage( StorageBase
& rDestStrg
, const OUString
& rElementName
)
206 OSL_ENSURE( rDestStrg
.isStorage() && !rDestStrg
.isReadOnly(), "StorageBase::copyToStorage - invalid destination" );
207 OSL_ENSURE( !rElementName
.isEmpty(), "StorageBase::copyToStorage - invalid element name" );
208 if( rDestStrg
.isStorage() && !rDestStrg
.isReadOnly() && !rElementName
.isEmpty() )
210 StorageRef xSubStrg
= openSubStorage( rElementName
, false );
213 StorageRef xDestSubStrg
= rDestStrg
.openSubStorage( rElementName
, true );
214 if( xDestSubStrg
.get() )
215 xSubStrg
->copyStorageToStorage( *xDestSubStrg
);
219 Reference
< XInputStream
> xInStrm
= openInputStream( rElementName
);
222 Reference
< XOutputStream
> xOutStrm
= rDestStrg
.openOutputStream( rElementName
);
225 BinaryXInputStream
aInStrm( xInStrm
, true );
226 BinaryXOutputStream
aOutStrm( xOutStrm
, true );
227 aInStrm
.copyToStream( aOutStrm
);
234 void StorageBase::copyStorageToStorage( StorageBase
& rDestStrg
)
236 OSL_ENSURE( rDestStrg
.isStorage() && !rDestStrg
.isReadOnly(), "StorageBase::copyToStorage - invalid destination" );
237 if( rDestStrg
.isStorage() && !rDestStrg
.isReadOnly() )
239 ::std::vector
< OUString
> aElements
;
240 getElementNames( aElements
);
241 for( ::std::vector
< OUString
>::iterator aIt
= aElements
.begin(), aEnd
= aElements
.end(); aIt
!= aEnd
; ++aIt
)
242 copyToStorage( rDestStrg
, *aIt
);
246 void StorageBase::commit()
248 OSL_ENSURE( !mbReadOnly
, "StorageBase::commit - cannot commit in read-only mode" );
251 // commit all open substorages
252 maSubStorages
.forEachMem( &StorageBase::commit
);
253 // commit this storage
258 // private --------------------------------------------------------------------
260 StorageRef
StorageBase::getSubStorage( const OUString
& rElementName
, bool bCreateMissing
)
262 StorageRef
& rxSubStrg
= maSubStorages
[ rElementName
];
264 rxSubStrg
= implOpenSubStorage( rElementName
, bCreateMissing
);
268 // ============================================================================
272 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */