xref: /core/package/source/xstor/ocompinstream.cxx (revision 26166ad8)
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 "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>
28 #include <utility>
29 
30 #include "owriteablestream.hxx"
31 
32 using namespace ::com::sun::star;
33 
OInputCompStream(OWriteStream_Impl & aImpl,uno::Reference<io::XInputStream> xStream,const uno::Sequence<beans::PropertyValue> & aProps,sal_Int32 nStorageType)34 OInputCompStream::OInputCompStream( OWriteStream_Impl& aImpl,
35                                     uno::Reference < io::XInputStream > xStream,
36                                     const uno::Sequence< beans::PropertyValue >& aProps,
37                                     sal_Int32 nStorageType )
38 : m_pImpl( &aImpl )
39 , m_xMutex( m_pImpl->m_xMutex )
40 , m_xStream(std::move( xStream ))
41 , m_aProperties( aProps )
42 , m_bDisposed( false )
43 , m_nStorageType( nStorageType )
44 {
45     OSL_ENSURE( m_pImpl->m_xMutex.is(), "No mutex is provided!" );
46     if ( !m_pImpl->m_xMutex.is() )
47         throw uno::RuntimeException(); // just a disaster
48 
49     assert(m_xStream.is());
50 }
51 
OInputCompStream(uno::Reference<io::XInputStream> xStream,const uno::Sequence<beans::PropertyValue> & aProps,sal_Int32 nStorageType)52 OInputCompStream::OInputCompStream( uno::Reference < io::XInputStream > xStream,
53                                     const uno::Sequence< beans::PropertyValue >& aProps,
54                                     sal_Int32 nStorageType )
55 : m_pImpl( nullptr )
56 , m_xMutex( new comphelper::RefCountedMutex )
57 , m_xStream(std::move( xStream ))
58 , m_aProperties( aProps )
59 , m_bDisposed( false )
60 , m_nStorageType( nStorageType )
61 {
62     assert(m_xStream.is());
63 }
64 
~OInputCompStream()65 OInputCompStream::~OInputCompStream()
66 {
67     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
68 
69     if ( !m_bDisposed )
70     {
71         osl_atomic_increment(&m_refCount);
72         dispose();
73     }
74 }
75 
queryInterface(const uno::Type & rType)76 uno::Any SAL_CALL OInputCompStream::queryInterface( const uno::Type& rType )
77 {
78     // common interfaces
79     uno::Any aReturn = ::cppu::queryInterface
80                 (   rType
81                     ,   static_cast<io::XInputStream*> ( this )
82                     ,   static_cast<io::XStream*> ( this )
83                     ,   static_cast<lang::XComponent*> ( this )
84                     ,   static_cast<beans::XPropertySet*> ( this )
85                     ,   static_cast<embed::XExtendedStorageStream*> ( this ) );
86 
87     if ( aReturn.hasValue() )
88         return aReturn ;
89 
90     if ( m_nStorageType == embed::StorageFormats::OFOPXML )
91     {
92         aReturn = ::cppu::queryInterface
93                     (   rType
94                         ,   static_cast<embed::XRelationshipAccess*> ( this ) );
95 
96         if ( aReturn.hasValue() )
97             return aReturn ;
98     }
99 
100     return OWeakObject::queryInterface( rType );
101 }
102 
readBytes(uno::Sequence<sal_Int8> & aData,sal_Int32 nBytesToRead)103 sal_Int32 SAL_CALL OInputCompStream::readBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
104 {
105     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
106     if ( m_bDisposed )
107     {
108         SAL_INFO("package.xstor", "Disposed!");
109         throw lang::DisposedException();
110     }
111 
112     return m_xStream->readBytes( aData, nBytesToRead );
113 }
114 
readSomeBytes(uno::Sequence<sal_Int8> & aData,sal_Int32 nMaxBytesToRead)115 sal_Int32 SAL_CALL OInputCompStream::readSomeBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
116 {
117     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
118     if ( m_bDisposed )
119     {
120         SAL_INFO("package.xstor", "Disposed!");
121         throw lang::DisposedException();
122     }
123 
124     return m_xStream->readSomeBytes( aData, nMaxBytesToRead );
125 
126 }
127 
skipBytes(sal_Int32 nBytesToSkip)128 void SAL_CALL OInputCompStream::skipBytes( sal_Int32 nBytesToSkip )
129 {
130     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
131     if ( m_bDisposed )
132     {
133         SAL_INFO("package.xstor", "Disposed!");
134         throw lang::DisposedException();
135     }
136 
137     m_xStream->skipBytes( nBytesToSkip );
138 
139 }
140 
available()141 sal_Int32 SAL_CALL OInputCompStream::available(  )
142 {
143     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
144     if ( m_bDisposed )
145     {
146         SAL_INFO("package.xstor", "Disposed!");
147         throw lang::DisposedException();
148     }
149 
150     return m_xStream->available();
151 
152 }
153 
closeInput()154 void SAL_CALL OInputCompStream::closeInput(  )
155 {
156     dispose();
157 }
158 
getInputStream()159 uno::Reference< io::XInputStream > SAL_CALL OInputCompStream::getInputStream()
160 {
161     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
162     if ( m_bDisposed )
163     {
164         SAL_INFO("package.xstor", "Disposed!");
165         throw lang::DisposedException();
166     }
167 
168     return this;
169 }
170 
getOutputStream()171 uno::Reference< io::XOutputStream > SAL_CALL OInputCompStream::getOutputStream()
172 {
173     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
174     if ( m_bDisposed )
175     {
176         SAL_INFO("package.xstor", "Disposed!");
177         throw lang::DisposedException();
178     }
179 
180     return uno::Reference< io::XOutputStream >();
181 }
182 
InternalDispose()183 void OInputCompStream::InternalDispose()
184 {
185     // can be called only by OWriteStream_Impl
186     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
187     if ( m_bDisposed )
188         return;
189 
190     // the source object is also a kind of locker for the current object
191     // since the listeners could dispose the object while being notified
192     lang::EventObject aSource( getXWeak() );
193 
194     if ( m_pInterfaceContainer )
195         m_pInterfaceContainer->disposeAndClear( aSource );
196 
197     try
198     {
199         m_xStream->closeInput();
200     }
201     catch( uno::Exception& )
202     {}
203 
204     m_pImpl = nullptr;
205     m_bDisposed = true;
206 }
207 
dispose()208 void SAL_CALL OInputCompStream::dispose(  )
209 {
210     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
211     if ( m_bDisposed )
212         return;
213 
214     if ( m_pInterfaceContainer )
215     {
216         lang::EventObject aSource( getXWeak() );
217         m_pInterfaceContainer->disposeAndClear( aSource );
218     }
219 
220     m_xStream->closeInput();
221 
222     if ( m_pImpl )
223     {
224         m_pImpl->InputStreamDisposed( this );
225         m_pImpl = nullptr;
226     }
227 
228     m_bDisposed = true;
229 }
230 
addEventListener(const uno::Reference<lang::XEventListener> & xListener)231 void SAL_CALL OInputCompStream::addEventListener( const uno::Reference< lang::XEventListener >& xListener )
232 {
233     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
234     if ( m_bDisposed )
235     {
236         SAL_INFO("package.xstor", "Disposed!");
237         throw lang::DisposedException();
238     }
239 
240     if ( !m_pInterfaceContainer )
241         m_pInterfaceContainer.reset( new ::comphelper::OInterfaceContainerHelper3<css::lang::XEventListener>( m_xMutex->GetMutex() ) );
242 
243     m_pInterfaceContainer->addInterface( xListener );
244 }
245 
removeEventListener(const uno::Reference<lang::XEventListener> & xListener)246 void SAL_CALL OInputCompStream::removeEventListener( const uno::Reference< lang::XEventListener >& xListener )
247 {
248     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
249     if ( m_bDisposed )
250     {
251         SAL_INFO("package.xstor", "Disposed!");
252         throw lang::DisposedException();
253     }
254 
255     if ( m_pInterfaceContainer )
256         m_pInterfaceContainer->removeInterface( xListener );
257 }
258 
hasByID(const OUString & sID)259 sal_Bool SAL_CALL OInputCompStream::hasByID(  const OUString& sID )
260 {
261     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
262 
263     if ( m_bDisposed )
264     {
265         SAL_INFO("package.xstor", "Disposed!");
266         throw lang::DisposedException();
267     }
268 
269     if ( m_nStorageType != embed::StorageFormats::OFOPXML )
270         throw uno::RuntimeException();
271 
272     try
273     {
274         getRelationshipByID( sID );
275         return true;
276     }
277     catch( container::NoSuchElementException& )
278     {}
279 
280     return false;
281 }
282 
283 namespace
284 {
285 
lcl_findPairByName(const uno::Sequence<beans::StringPair> & rSeq,const OUString & rName)286 const beans::StringPair* lcl_findPairByName(const uno::Sequence<beans::StringPair>& rSeq, const OUString& rName)
287 {
288     return std::find_if(rSeq.begin(), rSeq.end(),
289         [&rName](const beans::StringPair& rPair) { return rPair.First == rName; });
290 }
291 
292 }
293 
getTargetByID(const OUString & sID)294 OUString SAL_CALL OInputCompStream::getTargetByID(  const OUString& sID  )
295 {
296     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
297 
298     if ( m_bDisposed )
299     {
300         SAL_INFO("package.xstor", "Disposed!");
301         throw lang::DisposedException();
302     }
303 
304     if ( m_nStorageType != embed::StorageFormats::OFOPXML )
305         throw uno::RuntimeException();
306 
307     const uno::Sequence< beans::StringPair > aSeq = getRelationshipByID( sID );
308     auto pRel = lcl_findPairByName(aSeq, u"Target"_ustr);
309     if (pRel != aSeq.end())
310         return pRel->Second;
311 
312     return OUString();
313 }
314 
getTypeByID(const OUString & sID)315 OUString SAL_CALL OInputCompStream::getTypeByID(  const OUString& sID  )
316 {
317     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
318 
319     if ( m_bDisposed )
320     {
321         SAL_INFO("package.xstor", "Disposed!");
322         throw lang::DisposedException();
323     }
324 
325     if ( m_nStorageType != embed::StorageFormats::OFOPXML )
326         throw uno::RuntimeException();
327 
328     const uno::Sequence< beans::StringPair > aSeq = getRelationshipByID( sID );
329     auto pRel = lcl_findPairByName(aSeq, u"Type"_ustr);
330     if (pRel != aSeq.end())
331         return pRel->Second;
332 
333     return OUString();
334 }
335 
getRelationshipByID(const OUString & sID)336 uno::Sequence< beans::StringPair > SAL_CALL OInputCompStream::getRelationshipByID(  const OUString& sID  )
337 {
338     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
339 
340     if ( m_bDisposed )
341     {
342         SAL_INFO("package.xstor", "Disposed!");
343         throw lang::DisposedException();
344     }
345 
346     if ( m_nStorageType != embed::StorageFormats::OFOPXML )
347         throw uno::RuntimeException();
348 
349     // TODO/LATER: in future the unification of the ID could be checked
350     const uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
351     const beans::StringPair aIDRel(u"Id"_ustr, sID);
352     auto pRel = std::find_if(aSeq.begin(), aSeq.end(),
353         [&aIDRel](const uno::Sequence<beans::StringPair>& rRel){
354             return std::find(rRel.begin(), rRel.end(), aIDRel) != rRel.end(); });
355     if (pRel != aSeq.end())
356         return *pRel;
357 
358     throw container::NoSuchElementException();
359 }
360 
getRelationshipsByType(const OUString & sType)361 uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OInputCompStream::getRelationshipsByType(  const OUString& sType  )
362 {
363     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
364 
365     if ( m_bDisposed )
366     {
367         SAL_INFO("package.xstor", "Disposed!");
368         throw lang::DisposedException();
369     }
370 
371     if ( m_nStorageType != embed::StorageFormats::OFOPXML )
372         throw uno::RuntimeException();
373 
374     // TODO/LATER: in future the unification of the ID could be checked
375     const uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
376     const beans::StringPair aTypeRel(u"Type"_ustr, sType);
377     std::vector< uno::Sequence<beans::StringPair> > aResult;
378     aResult.reserve(aSeq.getLength());
379 
380     std::copy_if(aSeq.begin(), aSeq.end(), std::back_inserter(aResult),
381         [&aTypeRel](const uno::Sequence<beans::StringPair>& rRel) {
382             return std::find(rRel.begin(), rRel.end(), aTypeRel) != rRel.end(); });
383 
384     return comphelper::containerToSequence(aResult);
385 }
386 
getAllRelationships()387 uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OInputCompStream::getAllRelationships()
388 {
389     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
390 
391     if ( m_bDisposed )
392     {
393         SAL_INFO("package.xstor", "Disposed!");
394         throw lang::DisposedException();
395     }
396 
397     if ( m_nStorageType != embed::StorageFormats::OFOPXML )
398         throw uno::RuntimeException();
399 
400     // TODO/LATER: in future the information could be taken directly from m_pImpl when possible
401     auto pProp = std::find_if(std::cbegin(m_aProperties), std::cend(m_aProperties),
402         [](const beans::PropertyValue& rProp) { return rProp.Name == "RelationsInfo"; });
403     if (pProp != std::cend(m_aProperties))
404     {
405         uno::Sequence< uno::Sequence< beans::StringPair > > aResult;
406         if (pProp->Value >>= aResult)
407             return aResult;
408     }
409 
410     throw io::IOException(u"relations info could not be read"_ustr); // the relations info could not be read
411 }
412 
insertRelationshipByID(const OUString &,const uno::Sequence<beans::StringPair> &,sal_Bool)413 void SAL_CALL OInputCompStream::insertRelationshipByID(  const OUString& /*sID*/, const uno::Sequence< beans::StringPair >& /*aEntry*/, sal_Bool /*bReplace*/  )
414 {
415     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
416 
417     if ( m_bDisposed )
418     {
419         SAL_INFO("package.xstor", "Disposed!");
420         throw lang::DisposedException();
421     }
422 
423     if ( m_nStorageType != embed::StorageFormats::OFOPXML )
424         throw uno::RuntimeException();
425 
426     throw io::IOException(); // TODO: Access denied
427 }
428 
removeRelationshipByID(const OUString &)429 void SAL_CALL OInputCompStream::removeRelationshipByID(  const OUString& /*sID*/  )
430 {
431     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
432 
433     if ( m_bDisposed )
434     {
435         SAL_INFO("package.xstor", "Disposed!");
436         throw lang::DisposedException();
437     }
438 
439     if ( m_nStorageType != embed::StorageFormats::OFOPXML )
440         throw uno::RuntimeException();
441 
442     throw io::IOException(); // TODO: Access denied
443 }
444 
insertRelationships(const uno::Sequence<uno::Sequence<beans::StringPair>> &,sal_Bool)445 void SAL_CALL OInputCompStream::insertRelationships(  const uno::Sequence< uno::Sequence< beans::StringPair > >& /*aEntries*/, sal_Bool /*bReplace*/  )
446 {
447     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
448 
449     if ( m_bDisposed )
450     {
451         SAL_INFO("package.xstor", "Disposed!");
452         throw lang::DisposedException();
453     }
454 
455     if ( m_nStorageType != embed::StorageFormats::OFOPXML )
456         throw uno::RuntimeException();
457 
458     throw io::IOException(); // TODO: Access denied
459 }
460 
clearRelationships()461 void SAL_CALL OInputCompStream::clearRelationships()
462 {
463     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
464 
465     if ( m_bDisposed )
466     {
467         SAL_INFO("package.xstor", "Disposed!");
468         throw lang::DisposedException();
469     }
470 
471     if ( m_nStorageType != embed::StorageFormats::OFOPXML )
472         throw uno::RuntimeException();
473 
474     throw io::IOException(); // TODO: Access denied
475 }
476 
getPropertySetInfo()477 uno::Reference< beans::XPropertySetInfo > SAL_CALL OInputCompStream::getPropertySetInfo()
478 {
479     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
480 
481     if ( m_bDisposed )
482     {
483         SAL_INFO("package.xstor", "Disposed!");
484         throw lang::DisposedException();
485     }
486 
487     //TODO:
488     return uno::Reference< beans::XPropertySetInfo >();
489 }
490 
setPropertyValue(const OUString & aPropertyName,const uno::Any &)491 void SAL_CALL OInputCompStream::setPropertyValue( const OUString& aPropertyName, const uno::Any& /*aValue*/ )
492 {
493     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
494 
495     if ( m_bDisposed )
496     {
497         SAL_INFO("package.xstor", "Disposed!");
498         throw lang::DisposedException();
499     }
500 
501     // all the provided properties are accessible
502     if (std::any_of(std::cbegin(m_aProperties), std::cend(m_aProperties),
503             [&aPropertyName](const beans::PropertyValue& rProp) { return rProp.Name == aPropertyName; }))
504         throw beans::PropertyVetoException(); // TODO
505 
506     throw beans::UnknownPropertyException(aPropertyName); // TODO
507 }
508 
getPropertyValue(const OUString & aProp)509 uno::Any SAL_CALL OInputCompStream::getPropertyValue( const OUString& aProp )
510 {
511     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
512 
513     if ( m_bDisposed )
514     {
515         SAL_INFO("package.xstor", "Disposed!");
516         throw lang::DisposedException();
517     }
518 
519     OUString aPropertyName;
520     if ( aProp == "IsEncrypted" )
521         aPropertyName = "Encrypted";
522     else
523         aPropertyName = aProp;
524 
525     if ( aPropertyName == "RelationsInfo" )
526         throw beans::UnknownPropertyException(aPropertyName); // TODO
527 
528     // all the provided properties are accessible
529     auto pProp = std::find_if(std::cbegin(m_aProperties), std::cend(m_aProperties),
530         [&aPropertyName](const beans::PropertyValue& rProp) { return rProp.Name == aPropertyName; });
531     if (pProp != std::cend(m_aProperties))
532         return pProp->Value;
533 
534     throw beans::UnknownPropertyException(aPropertyName); // TODO
535 }
536 
addPropertyChangeListener(const OUString &,const uno::Reference<beans::XPropertyChangeListener> &)537 void SAL_CALL OInputCompStream::addPropertyChangeListener(
538     const OUString& /*aPropertyName*/,
539     const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
540 {
541     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
542 
543     if ( m_bDisposed )
544     {
545         SAL_INFO("package.xstor", "Disposed!");
546         throw lang::DisposedException();
547     }
548 
549     //TODO:
550 }
551 
removePropertyChangeListener(const OUString &,const uno::Reference<beans::XPropertyChangeListener> &)552 void SAL_CALL OInputCompStream::removePropertyChangeListener(
553     const OUString& /*aPropertyName*/,
554     const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ )
555 {
556     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
557 
558     if ( m_bDisposed )
559     {
560         SAL_INFO("package.xstor", "Disposed!");
561         throw lang::DisposedException();
562     }
563 
564     //TODO:
565 }
566 
addVetoableChangeListener(const OUString &,const uno::Reference<beans::XVetoableChangeListener> &)567 void SAL_CALL OInputCompStream::addVetoableChangeListener(
568     const OUString& /*PropertyName*/,
569     const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
570 {
571     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
572 
573     if ( m_bDisposed )
574     {
575         SAL_INFO("package.xstor", "Disposed!");
576         throw lang::DisposedException();
577     }
578 
579     //TODO:
580 }
581 
removeVetoableChangeListener(const OUString &,const uno::Reference<beans::XVetoableChangeListener> &)582 void SAL_CALL OInputCompStream::removeVetoableChangeListener(
583     const OUString& /*PropertyName*/,
584     const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
585 {
586     ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
587 
588     if ( m_bDisposed )
589     {
590         SAL_INFO("package.xstor", "Disposed!");
591         throw lang::DisposedException();
592     }
593 
594     //TODO:
595 }
596 
597 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
598