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 "ocompinstream.hxx"
21 #include <com/sun/star/embed/StorageFormats.hpp>
22 #include <com/sun/star/io/IOException.hpp>
23 #include <com/sun/star/lang/DisposedException.hpp>
24 #include <comphelper/sequence.hxx>
25 #include <cppuhelper/queryinterface.hxx>
26 #include <osl/diagnose.h>
27 #include <sal/log.hxx>
30 #include "owriteablestream.hxx"
32 using namespace ::com::sun::star
;
34 OInputCompStream::OInputCompStream( OWriteStream_Impl
& aImpl
,
35 uno::Reference
< io::XInputStream
> xStream
,
36 const uno::Sequence
< beans::PropertyValue
>& aProps
,
37 sal_Int32 nStorageType
)
39 , m_xMutex( m_pImpl
->m_xMutex
)
40 , m_xStream(std::move( xStream
))
41 , m_pByteReader( dynamic_cast<comphelper::ByteReader
*>(m_xStream
.get()) )
42 , m_aProperties( aProps
)
43 , m_bDisposed( false )
44 , m_nStorageType( nStorageType
)
46 OSL_ENSURE( m_pImpl
->m_xMutex
.is(), "No mutex is provided!" );
47 if ( !m_pImpl
->m_xMutex
.is() )
48 throw uno::RuntimeException(); // just a disaster
50 assert(m_xStream
.is());
51 assert(m_pByteReader
);
54 OInputCompStream::OInputCompStream( uno::Reference
< io::XInputStream
> xStream
,
55 const uno::Sequence
< beans::PropertyValue
>& aProps
,
56 sal_Int32 nStorageType
)
58 , m_xMutex( new comphelper::RefCountedMutex
)
59 , m_xStream(std::move( xStream
))
60 , m_pByteReader( dynamic_cast<comphelper::ByteReader
*>(m_xStream
.get()) )
61 , m_aProperties( aProps
)
62 , m_bDisposed( false )
63 , m_nStorageType( nStorageType
)
65 assert(m_xStream
.is());
66 assert(m_pByteReader
);
69 OInputCompStream::~OInputCompStream()
71 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
75 osl_atomic_increment(&m_refCount
);
80 uno::Any SAL_CALL
OInputCompStream::queryInterface( const uno::Type
& rType
)
83 uno::Any aReturn
= ::cppu::queryInterface
85 , static_cast<io::XInputStream
*> ( this )
86 , static_cast<io::XStream
*> ( this )
87 , static_cast<lang::XComponent
*> ( this )
88 , static_cast<beans::XPropertySet
*> ( this )
89 , static_cast<embed::XExtendedStorageStream
*> ( this ) );
91 if ( aReturn
.hasValue() )
94 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
)
96 aReturn
= ::cppu::queryInterface
98 , static_cast<embed::XRelationshipAccess
*> ( this ) );
100 if ( aReturn
.hasValue() )
104 return OWeakObject::queryInterface( rType
);
107 sal_Int32 SAL_CALL
OInputCompStream::readBytes( uno::Sequence
< sal_Int8
>& aData
, sal_Int32 nBytesToRead
)
109 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
112 SAL_INFO("package.xstor", "Disposed!");
113 throw lang::DisposedException();
116 return m_xStream
->readBytes( aData
, nBytesToRead
);
119 sal_Int32 SAL_CALL
OInputCompStream::readSomeBytes( uno::Sequence
< sal_Int8
>& aData
, sal_Int32 nMaxBytesToRead
)
121 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
124 SAL_INFO("package.xstor", "Disposed!");
125 throw lang::DisposedException();
128 return m_xStream
->readSomeBytes( aData
, nMaxBytesToRead
);
132 sal_Int32
OInputCompStream::readSomeBytes( sal_Int8
* aData
, sal_Int32 nMaxBytesToRead
)
134 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
137 SAL_INFO("package.xstor", "Disposed!");
138 throw lang::DisposedException();
141 return m_pByteReader
->readSomeBytes( aData
, nMaxBytesToRead
);
145 void SAL_CALL
OInputCompStream::skipBytes( sal_Int32 nBytesToSkip
)
147 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
150 SAL_INFO("package.xstor", "Disposed!");
151 throw lang::DisposedException();
154 m_xStream
->skipBytes( nBytesToSkip
);
158 sal_Int32 SAL_CALL
OInputCompStream::available( )
160 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
163 SAL_INFO("package.xstor", "Disposed!");
164 throw lang::DisposedException();
167 return m_xStream
->available();
171 void SAL_CALL
OInputCompStream::closeInput( )
176 uno::Reference
< io::XInputStream
> SAL_CALL
OInputCompStream::getInputStream()
178 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
181 SAL_INFO("package.xstor", "Disposed!");
182 throw lang::DisposedException();
188 uno::Reference
< io::XOutputStream
> SAL_CALL
OInputCompStream::getOutputStream()
190 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
193 SAL_INFO("package.xstor", "Disposed!");
194 throw lang::DisposedException();
197 return uno::Reference
< io::XOutputStream
>();
200 void OInputCompStream::InternalDispose()
202 // can be called only by OWriteStream_Impl
203 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
207 // the source object is also a kind of locker for the current object
208 // since the listeners could dispose the object while being notified
209 lang::EventObject
aSource( getXWeak() );
211 if ( m_pInterfaceContainer
)
212 m_pInterfaceContainer
->disposeAndClear( aSource
);
216 m_xStream
->closeInput();
218 catch( uno::Exception
& )
225 void SAL_CALL
OInputCompStream::dispose( )
227 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
231 if ( m_pInterfaceContainer
)
233 lang::EventObject
aSource( getXWeak() );
234 m_pInterfaceContainer
->disposeAndClear( aSource
);
237 m_xStream
->closeInput();
241 m_pImpl
->InputStreamDisposed( this );
248 void SAL_CALL
OInputCompStream::addEventListener( const uno::Reference
< lang::XEventListener
>& xListener
)
250 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
253 SAL_INFO("package.xstor", "Disposed!");
254 throw lang::DisposedException();
257 if ( !m_pInterfaceContainer
)
258 m_pInterfaceContainer
.reset( new ::comphelper::OInterfaceContainerHelper3
<css::lang::XEventListener
>( m_xMutex
->GetMutex() ) );
260 m_pInterfaceContainer
->addInterface( xListener
);
263 void SAL_CALL
OInputCompStream::removeEventListener( const uno::Reference
< lang::XEventListener
>& xListener
)
265 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
268 SAL_INFO("package.xstor", "Disposed!");
269 throw lang::DisposedException();
272 if ( m_pInterfaceContainer
)
273 m_pInterfaceContainer
->removeInterface( xListener
);
276 sal_Bool SAL_CALL
OInputCompStream::hasByID( const OUString
& sID
)
278 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
282 SAL_INFO("package.xstor", "Disposed!");
283 throw lang::DisposedException();
286 if ( m_nStorageType
!= embed::StorageFormats::OFOPXML
)
287 throw uno::RuntimeException();
291 getRelationshipByID( sID
);
294 catch( container::NoSuchElementException
& )
303 const beans::StringPair
* lcl_findPairByName(const uno::Sequence
<beans::StringPair
>& rSeq
, const OUString
& rName
)
305 return std::find_if(rSeq
.begin(), rSeq
.end(),
306 [&rName
](const beans::StringPair
& rPair
) { return rPair
.First
== rName
; });
311 OUString SAL_CALL
OInputCompStream::getTargetByID( const OUString
& sID
)
313 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
317 SAL_INFO("package.xstor", "Disposed!");
318 throw lang::DisposedException();
321 if ( m_nStorageType
!= embed::StorageFormats::OFOPXML
)
322 throw uno::RuntimeException();
324 const uno::Sequence
< beans::StringPair
> aSeq
= getRelationshipByID( sID
);
325 auto pRel
= lcl_findPairByName(aSeq
, u
"Target"_ustr
);
326 if (pRel
!= aSeq
.end())
332 OUString SAL_CALL
OInputCompStream::getTypeByID( const OUString
& sID
)
334 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
338 SAL_INFO("package.xstor", "Disposed!");
339 throw lang::DisposedException();
342 if ( m_nStorageType
!= embed::StorageFormats::OFOPXML
)
343 throw uno::RuntimeException();
345 const uno::Sequence
< beans::StringPair
> aSeq
= getRelationshipByID( sID
);
346 auto pRel
= lcl_findPairByName(aSeq
, u
"Type"_ustr
);
347 if (pRel
!= aSeq
.end())
353 uno::Sequence
< beans::StringPair
> SAL_CALL
OInputCompStream::getRelationshipByID( const OUString
& sID
)
355 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
359 SAL_INFO("package.xstor", "Disposed!");
360 throw lang::DisposedException();
363 if ( m_nStorageType
!= embed::StorageFormats::OFOPXML
)
364 throw uno::RuntimeException();
366 // TODO/LATER: in future the unification of the ID could be checked
367 const uno::Sequence
< uno::Sequence
< beans::StringPair
> > aSeq
= getAllRelationships();
368 const beans::StringPair
aIDRel(u
"Id"_ustr
, sID
);
369 auto pRel
= std::find_if(aSeq
.begin(), aSeq
.end(),
370 [&aIDRel
](const uno::Sequence
<beans::StringPair
>& rRel
){
371 return std::find(rRel
.begin(), rRel
.end(), aIDRel
) != rRel
.end(); });
372 if (pRel
!= aSeq
.end())
375 throw container::NoSuchElementException();
378 uno::Sequence
< uno::Sequence
< beans::StringPair
> > SAL_CALL
OInputCompStream::getRelationshipsByType( const OUString
& sType
)
380 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
384 SAL_INFO("package.xstor", "Disposed!");
385 throw lang::DisposedException();
388 if ( m_nStorageType
!= embed::StorageFormats::OFOPXML
)
389 throw uno::RuntimeException();
391 // TODO/LATER: in future the unification of the ID could be checked
392 const uno::Sequence
< uno::Sequence
< beans::StringPair
> > aSeq
= getAllRelationships();
393 const beans::StringPair
aTypeRel(u
"Type"_ustr
, sType
);
394 std::vector
< uno::Sequence
<beans::StringPair
> > aResult
;
395 aResult
.reserve(aSeq
.getLength());
397 std::copy_if(aSeq
.begin(), aSeq
.end(), std::back_inserter(aResult
),
398 [&aTypeRel
](const uno::Sequence
<beans::StringPair
>& rRel
) {
399 return std::find(rRel
.begin(), rRel
.end(), aTypeRel
) != rRel
.end(); });
401 return comphelper::containerToSequence(aResult
);
404 uno::Sequence
< uno::Sequence
< beans::StringPair
> > SAL_CALL
OInputCompStream::getAllRelationships()
406 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
410 SAL_INFO("package.xstor", "Disposed!");
411 throw lang::DisposedException();
414 if ( m_nStorageType
!= embed::StorageFormats::OFOPXML
)
415 throw uno::RuntimeException();
417 // TODO/LATER: in future the information could be taken directly from m_pImpl when possible
418 auto pProp
= std::find_if(std::cbegin(m_aProperties
), std::cend(m_aProperties
),
419 [](const beans::PropertyValue
& rProp
) { return rProp
.Name
== "RelationsInfo"; });
420 if (pProp
!= std::cend(m_aProperties
))
422 uno::Sequence
< uno::Sequence
< beans::StringPair
> > aResult
;
423 if (pProp
->Value
>>= aResult
)
427 throw io::IOException(u
"relations info could not be read"_ustr
); // the relations info could not be read
430 void SAL_CALL
OInputCompStream::insertRelationshipByID( const OUString
& /*sID*/, const uno::Sequence
< beans::StringPair
>& /*aEntry*/, sal_Bool
/*bReplace*/ )
432 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
436 SAL_INFO("package.xstor", "Disposed!");
437 throw lang::DisposedException();
440 if ( m_nStorageType
!= embed::StorageFormats::OFOPXML
)
441 throw uno::RuntimeException();
443 throw io::IOException(); // TODO: Access denied
446 void SAL_CALL
OInputCompStream::removeRelationshipByID( const OUString
& /*sID*/ )
448 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
452 SAL_INFO("package.xstor", "Disposed!");
453 throw lang::DisposedException();
456 if ( m_nStorageType
!= embed::StorageFormats::OFOPXML
)
457 throw uno::RuntimeException();
459 throw io::IOException(); // TODO: Access denied
462 void SAL_CALL
OInputCompStream::insertRelationships( const uno::Sequence
< uno::Sequence
< beans::StringPair
> >& /*aEntries*/, sal_Bool
/*bReplace*/ )
464 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
468 SAL_INFO("package.xstor", "Disposed!");
469 throw lang::DisposedException();
472 if ( m_nStorageType
!= embed::StorageFormats::OFOPXML
)
473 throw uno::RuntimeException();
475 throw io::IOException(); // TODO: Access denied
478 void SAL_CALL
OInputCompStream::clearRelationships()
480 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
484 SAL_INFO("package.xstor", "Disposed!");
485 throw lang::DisposedException();
488 if ( m_nStorageType
!= embed::StorageFormats::OFOPXML
)
489 throw uno::RuntimeException();
491 throw io::IOException(); // TODO: Access denied
494 uno::Reference
< beans::XPropertySetInfo
> SAL_CALL
OInputCompStream::getPropertySetInfo()
496 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
500 SAL_INFO("package.xstor", "Disposed!");
501 throw lang::DisposedException();
505 return uno::Reference
< beans::XPropertySetInfo
>();
508 void SAL_CALL
OInputCompStream::setPropertyValue( const OUString
& aPropertyName
, const uno::Any
& /*aValue*/ )
510 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
514 SAL_INFO("package.xstor", "Disposed!");
515 throw lang::DisposedException();
518 // all the provided properties are accessible
519 if (std::any_of(std::cbegin(m_aProperties
), std::cend(m_aProperties
),
520 [&aPropertyName
](const beans::PropertyValue
& rProp
) { return rProp
.Name
== aPropertyName
; }))
521 throw beans::PropertyVetoException(); // TODO
523 throw beans::UnknownPropertyException(aPropertyName
); // TODO
526 uno::Any SAL_CALL
OInputCompStream::getPropertyValue( const OUString
& aProp
)
528 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
532 SAL_INFO("package.xstor", "Disposed!");
533 throw lang::DisposedException();
536 OUString aPropertyName
;
537 if ( aProp
== "IsEncrypted" )
538 aPropertyName
= "Encrypted";
540 aPropertyName
= aProp
;
542 if ( aPropertyName
== "RelationsInfo" )
543 throw beans::UnknownPropertyException(aPropertyName
); // TODO
545 // all the provided properties are accessible
546 auto pProp
= std::find_if(std::cbegin(m_aProperties
), std::cend(m_aProperties
),
547 [&aPropertyName
](const beans::PropertyValue
& rProp
) { return rProp
.Name
== aPropertyName
; });
548 if (pProp
!= std::cend(m_aProperties
))
551 throw beans::UnknownPropertyException(aPropertyName
); // TODO
554 void SAL_CALL
OInputCompStream::addPropertyChangeListener(
555 const OUString
& /*aPropertyName*/,
556 const uno::Reference
< beans::XPropertyChangeListener
>& /*xListener*/ )
558 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
562 SAL_INFO("package.xstor", "Disposed!");
563 throw lang::DisposedException();
569 void SAL_CALL
OInputCompStream::removePropertyChangeListener(
570 const OUString
& /*aPropertyName*/,
571 const uno::Reference
< beans::XPropertyChangeListener
>& /*aListener*/ )
573 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
577 SAL_INFO("package.xstor", "Disposed!");
578 throw lang::DisposedException();
584 void SAL_CALL
OInputCompStream::addVetoableChangeListener(
585 const OUString
& /*PropertyName*/,
586 const uno::Reference
< beans::XVetoableChangeListener
>& /*aListener*/ )
588 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
592 SAL_INFO("package.xstor", "Disposed!");
593 throw lang::DisposedException();
599 void SAL_CALL
OInputCompStream::removeVetoableChangeListener(
600 const OUString
& /*PropertyName*/,
601 const uno::Reference
< beans::XVetoableChangeListener
>& /*aListener*/ )
603 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
607 SAL_INFO("package.xstor", "Disposed!");
608 throw lang::DisposedException();
614 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */