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 <osl/diagnose.h>
25 #include <rtl/ustrbuf.hxx>
26 #include <oox/helper/binaryinputstream.hxx>
27 #include <oox/helper/binaryoutputstream.hxx>
31 using namespace ::com::sun::star::embed
;
32 using namespace ::com::sun::star::io
;
33 using namespace ::com::sun::star::uno
;
37 void lclSplitFirstElement( OUString
& orElement
, OUString
& orRemainder
, const OUString
& _aFullName
)
39 OUString aFullName
= _aFullName
;
40 sal_Int32 nSlashPos
= aFullName
.indexOf( '/' );
42 // strip leading slashes
43 while( nSlashPos
== 0 )
45 aFullName
= aFullName
.copy(1);
46 nSlashPos
= aFullName
.indexOf( '/' );
49 if( (0 <= nSlashPos
) && (nSlashPos
< aFullName
.getLength()) )
51 orElement
= aFullName
.copy( 0, nSlashPos
);
52 orRemainder
= aFullName
.copy( nSlashPos
+ 1 );
56 orElement
= aFullName
;
62 StorageBase::StorageBase( const Reference
< XInputStream
>& rxInStream
, bool bBaseStreamAccess
) :
63 mxInStream( rxInStream
),
64 mbBaseStreamAccess( bBaseStreamAccess
),
67 OSL_ENSURE( mxInStream
.is(), "StorageBase::StorageBase - missing base input stream" );
70 StorageBase::StorageBase( const Reference
< XStream
>& rxOutStream
, bool bBaseStreamAccess
) :
71 mxOutStream( rxOutStream
),
72 mbBaseStreamAccess( bBaseStreamAccess
),
75 OSL_ENSURE( mxOutStream
.is(), "StorageBase::StorageBase - missing base output stream" );
78 StorageBase::StorageBase( const StorageBase
& rParentStorage
, const OUString
& rStorageName
, bool bReadOnly
) :
79 maParentPath( rParentStorage
.getPath() ),
80 maStorageName( rStorageName
),
81 mbBaseStreamAccess( false ),
82 mbReadOnly( bReadOnly
)
86 StorageBase::~StorageBase()
90 bool StorageBase::isStorage() const
92 return implIsStorage();
95 bool StorageBase::isRootStorage() const
97 return implIsStorage() && maStorageName
.isEmpty();
100 Reference
< XStorage
> StorageBase::getXStorage() const
102 return implGetXStorage();
105 OUString
StorageBase::getPath() const
107 OUStringBuffer
aBuffer( maParentPath
);
108 if( !aBuffer
.isEmpty() )
109 aBuffer
.append( '/' );
110 aBuffer
.append( maStorageName
);
111 return aBuffer
.makeStringAndClear();
114 void StorageBase::getElementNames( ::std::vector
< OUString
>& orElementNames
) const
116 orElementNames
.clear();
117 implGetElementNames( orElementNames
);
120 StorageRef
StorageBase::openSubStorage( const OUString
& rStorageName
, bool bCreateMissing
)
122 StorageRef xSubStorage
;
123 OSL_ENSURE( !bCreateMissing
|| !mbReadOnly
, "StorageBase::openSubStorage - cannot create substorage in read-only mode" );
124 if( !bCreateMissing
|| !mbReadOnly
)
126 OUString aElement
, aRemainder
;
127 lclSplitFirstElement( aElement
, aRemainder
, rStorageName
);
128 if( !aElement
.isEmpty() )
129 xSubStorage
= getSubStorage( aElement
, bCreateMissing
);
130 if( xSubStorage
.get() && !aRemainder
.isEmpty() )
131 xSubStorage
= xSubStorage
->openSubStorage( aRemainder
, bCreateMissing
);
136 Reference
< XInputStream
> StorageBase::openInputStream( const OUString
& rStreamName
)
138 Reference
< XInputStream
> xInStream
;
139 OUString aElement
, aRemainder
;
140 lclSplitFirstElement( aElement
, aRemainder
, rStreamName
);
141 if( !aElement
.isEmpty() )
143 if( !aRemainder
.isEmpty() )
145 StorageRef xSubStorage
= getSubStorage( aElement
, false );
146 if( xSubStorage
.get() )
147 xInStream
= xSubStorage
->openInputStream( aRemainder
);
151 xInStream
= implOpenInputStream( aElement
);
154 else if( mbBaseStreamAccess
)
156 xInStream
= mxInStream
;
161 Reference
< XOutputStream
> StorageBase::openOutputStream( const OUString
& rStreamName
)
163 Reference
< XOutputStream
> xOutStream
;
164 OSL_ENSURE( !mbReadOnly
, "StorageBase::openOutputStream - cannot create output stream in read-only mode" );
167 OUString aElement
, aRemainder
;
168 lclSplitFirstElement( aElement
, aRemainder
, rStreamName
);
169 if( !aElement
.isEmpty() )
171 if( !aRemainder
.isEmpty() )
173 StorageRef xSubStorage
= getSubStorage( aElement
, true );
174 if( xSubStorage
.get() )
175 xOutStream
= xSubStorage
->openOutputStream( aRemainder
);
179 xOutStream
= implOpenOutputStream( aElement
);
182 else if( mbBaseStreamAccess
)
184 xOutStream
= mxOutStream
->getOutputStream();
190 void StorageBase::copyToStorage( StorageBase
& rDestStrg
, const OUString
& rElementName
)
192 OSL_ENSURE( rDestStrg
.isStorage() && !rDestStrg
.isReadOnly(), "StorageBase::copyToStorage - invalid destination" );
193 OSL_ENSURE( !rElementName
.isEmpty(), "StorageBase::copyToStorage - invalid element name" );
194 if( rDestStrg
.isStorage() && !rDestStrg
.isReadOnly() && !rElementName
.isEmpty() )
196 StorageRef xSubStrg
= openSubStorage( rElementName
, false );
199 StorageRef xDestSubStrg
= rDestStrg
.openSubStorage( rElementName
, true );
200 if( xDestSubStrg
.get() )
201 xSubStrg
->copyStorageToStorage( *xDestSubStrg
);
205 Reference
< XInputStream
> xInStrm
= openInputStream( rElementName
);
208 Reference
< XOutputStream
> xOutStrm
= rDestStrg
.openOutputStream( rElementName
);
211 BinaryXInputStream
aInStrm( xInStrm
, true );
212 BinaryXOutputStream
aOutStrm( xOutStrm
, true );
213 aInStrm
.copyToStream( aOutStrm
);
220 void StorageBase::copyStorageToStorage( StorageBase
& rDestStrg
)
222 OSL_ENSURE( rDestStrg
.isStorage() && !rDestStrg
.isReadOnly(), "StorageBase::copyToStorage - invalid destination" );
223 if( rDestStrg
.isStorage() && !rDestStrg
.isReadOnly() )
225 ::std::vector
< OUString
> aElements
;
226 getElementNames( aElements
);
227 for (auto const& elem
: aElements
)
228 copyToStorage(rDestStrg
, elem
);
232 void StorageBase::commit()
234 OSL_ENSURE( !mbReadOnly
, "StorageBase::commit - cannot commit in read-only mode" );
237 // commit all open substorages
238 maSubStorages
.forEachMem( &StorageBase::commit
);
239 // commit this storage
244 // private --------------------------------------------------------------------
246 StorageRef
StorageBase::getSubStorage( const OUString
& rElementName
, bool bCreateMissing
)
248 StorageRef
& rxSubStrg
= maSubStorages
[ rElementName
];
250 rxSubStrg
= implOpenSubStorage( rElementName
, bCreateMissing
);
256 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */