LibreOffice Module package (master) 1
ocompinstream.cxx
Go to the documentation of this file.
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>
26#include <osl/diagnose.h>
27#include <sal/log.hxx>
28#include <utility>
29
30#include "owriteablestream.hxx"
31
32using namespace ::com::sun::star;
33
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
52OInputCompStream::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
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
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
103sal_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
115sal_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
128void 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
141sal_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
155{
156 dispose();
157}
158
159uno::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
171uno::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
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
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
209{
210 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
211 if ( m_bDisposed )
212 return;
213
215 {
216 lang::EventObject aSource( getXWeak() );
217 m_pInterfaceContainer->disposeAndClear( aSource );
218 }
219
220 m_xStream->closeInput();
221
222 if ( m_pImpl )
223 {
225 m_pImpl = nullptr;
226 }
227
228 m_bDisposed = true;
229}
230
231void 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
241 m_pInterfaceContainer.reset( new ::comphelper::OInterfaceContainerHelper3<css::lang::XEventListener>( m_xMutex->GetMutex() ) );
242
243 m_pInterfaceContainer->addInterface( xListener );
244}
245
246void 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
256 m_pInterfaceContainer->removeInterface( xListener );
257}
258
259sal_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
283namespace
284{
285
286const 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
294OUString 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, "Target");
309 if (pRel != aSeq.end())
310 return pRel->Second;
311
312 return OUString();
313}
314
315OUString 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, "Type");
330 if (pRel != aSeq.end())
331 return pRel->Second;
332
333 return OUString();
334}
335
336uno::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("Id", 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
361uno::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("Type", 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
387uno::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("relations info could not be read"); // the relations info could not be read
411}
412
413void 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
429void 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
445void 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
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
477uno::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
491void 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
509uno::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
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
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
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
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: */
OptionalString sType
::std::unique_ptr< XmlIdRegistry_Impl > m_pImpl
Reference< XInputStream > xStream
virtual void SAL_CALL removeRelationshipByID(const OUString &sID) override
virtual void SAL_CALL addVetoableChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &aListener) override
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
virtual css::uno::Sequence< css::uno::Sequence< css::beans::StringPair > > SAL_CALL getAllRelationships() override
sal_Int32 m_nStorageType
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &PropertyName) override
virtual void SAL_CALL skipBytes(sal_Int32 nBytesToSkip) override
virtual css::uno::Reference< css::io::XInputStream > SAL_CALL getInputStream() override
virtual void SAL_CALL insertRelationshipByID(const OUString &sID, const css::uno::Sequence< css::beans::StringPair > &aEntry, sal_Bool bReplace) override
OWriteStream_Impl * m_pImpl
virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > &aListener) override
virtual OUString SAL_CALL getTargetByID(const OUString &sID) override
virtual void SAL_CALL removePropertyChangeListener(const OUString &aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &aListener) override
virtual sal_Int32 SAL_CALL readBytes(css::uno::Sequence< sal_Int8 > &aData, sal_Int32 nBytesToRead) override
css::uno::Reference< css::io::XInputStream > m_xStream
virtual ~OInputCompStream() override
virtual OUString SAL_CALL getTypeByID(const OUString &sID) override
virtual void SAL_CALL dispose() override
virtual sal_Int32 SAL_CALL readSomeBytes(css::uno::Sequence< sal_Int8 > &aData, sal_Int32 nMaxBytesToRead) override
virtual css::uno::Sequence< css::uno::Sequence< css::beans::StringPair > > SAL_CALL getRelationshipsByType(const OUString &sType) override
virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
virtual sal_Bool SAL_CALL hasByID(const OUString &sID) override
virtual sal_Int32 SAL_CALL available() override
OInputCompStream(OWriteStream_Impl &pImpl, css::uno::Reference< css::io::XInputStream > xStream, const css::uno::Sequence< css::beans::PropertyValue > &aProps, sal_Int32 nStorageType)
virtual void SAL_CALL insertRelationships(const css::uno::Sequence< css::uno::Sequence< css::beans::StringPair > > &aEntries, sal_Bool bReplace) override
virtual css::uno::Sequence< css::beans::StringPair > SAL_CALL getRelationshipByID(const OUString &sID) override
virtual void SAL_CALL addPropertyChangeListener(const OUString &aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &xListener) override
rtl::Reference< comphelper::RefCountedMutex > m_xMutex
css::uno::Sequence< css::beans::PropertyValue > m_aProperties
virtual void SAL_CALL closeInput() override
std::unique_ptr<::comphelper::OInterfaceContainerHelper3< css::lang::XEventListener > > m_pInterfaceContainer
virtual void SAL_CALL setPropertyValue(const OUString &aPropertyName, const css::uno::Any &aValue) override
virtual void SAL_CALL clearRelationships() override
virtual css::uno::Reference< css::io::XOutputStream > SAL_CALL getOutputStream() override
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
virtual void SAL_CALL removeVetoableChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &aListener) override
ULONG m_refCount
bool m_bDisposed
Sequence< sal_Int8 > aSeq
#define SAL_INFO(area, stream)
constexpr OUStringLiteral aData
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
void InputStreamDisposed(OInputCompStream *pStream)
bool hasValue()
unsigned char sal_Bool
Reference< XStream > m_xStream