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 <sal/config.h>
22 #include <cppuhelper/implbase.hxx>
23 #include <cppuhelper/supportsservice.hxx>
24 #include <comphelper/seqstream.hxx>
25 #include <com/sun/star/lang/IllegalArgumentException.hpp>
26 #include <com/sun/star/lang/XServiceInfo.hpp>
27 #include <com/sun/star/io/NotConnectedException.hpp>
28 #include <com/sun/star/io/XSeekableInputStream.hpp>
29 #include <com/sun/star/lang/XInitialization.hpp>
30 #include <com/sun/star/frame/DoubleInitializationException.hpp>
33 namespace com::sun::star::uno
{ class XComponentContext
; }
35 using namespace ::com::sun::star
;
39 class SequenceInputStreamService
:
40 public ::cppu::WeakImplHelper
<
42 io::XSeekableInputStream
,
43 lang::XInitialization
>
46 explicit SequenceInputStreamService();
49 SequenceInputStreamService(const SequenceInputStreamService
&) = delete;
50 const SequenceInputStreamService
& operator=(const SequenceInputStreamService
&) = delete;
52 // css::lang::XServiceInfo:
53 virtual OUString SAL_CALL
getImplementationName() override
;
54 virtual sal_Bool SAL_CALL
supportsService( const OUString
& ServiceName
) override
;
55 virtual uno::Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() override
;
57 // css::io::XInputStream:
58 virtual ::sal_Int32 SAL_CALL
readBytes( uno::Sequence
< ::sal_Int8
> & aData
, ::sal_Int32 nBytesToRead
) override
;
59 virtual ::sal_Int32 SAL_CALL
readSomeBytes( uno::Sequence
< ::sal_Int8
> & aData
, ::sal_Int32 nMaxBytesToRead
) override
;
60 virtual void SAL_CALL
skipBytes( ::sal_Int32 nBytesToSkip
) override
;
61 virtual ::sal_Int32 SAL_CALL
available() override
;
62 virtual void SAL_CALL
closeInput() override
;
64 // css::io::XSeekable:
65 virtual void SAL_CALL
seek( ::sal_Int64 location
) override
;
66 virtual ::sal_Int64 SAL_CALL
getPosition() override
;
67 virtual ::sal_Int64 SAL_CALL
getLength() override
;
69 // css::lang::XInitialization:
70 virtual void SAL_CALL
initialize( const uno::Sequence
< css::uno::Any
> & aArguments
) override
;
73 virtual ~SequenceInputStreamService() override
{}
78 uno::Reference
< io::XInputStream
> m_xInputStream
;
79 uno::Reference
< io::XSeekable
> m_xSeekable
;
82 SequenceInputStreamService::SequenceInputStreamService()
83 : m_bInitialized( false )
86 // com.sun.star.uno.XServiceInfo:
87 OUString SAL_CALL
SequenceInputStreamService::getImplementationName()
89 return "com.sun.star.comp.SequenceInputStreamService";
92 sal_Bool SAL_CALL
SequenceInputStreamService::supportsService( OUString
const & serviceName
)
94 return cppu::supportsService(this, serviceName
);
97 uno::Sequence
< OUString
> SAL_CALL
SequenceInputStreamService::getSupportedServiceNames()
99 return { "com.sun.star.io.SequenceInputStream" };
102 // css::io::XInputStream:
103 ::sal_Int32 SAL_CALL
SequenceInputStreamService::readBytes( uno::Sequence
< ::sal_Int8
> & aData
, ::sal_Int32 nBytesToRead
)
105 std::scoped_lock
aGuard( m_aMutex
);
106 if ( !m_xInputStream
.is() )
107 throw io::NotConnectedException();
109 return m_xInputStream
->readBytes( aData
, nBytesToRead
);
112 ::sal_Int32 SAL_CALL
SequenceInputStreamService::readSomeBytes( uno::Sequence
< ::sal_Int8
> & aData
, ::sal_Int32 nMaxBytesToRead
)
114 std::scoped_lock
aGuard( m_aMutex
);
115 if ( !m_xInputStream
.is() )
116 throw io::NotConnectedException();
118 return m_xInputStream
->readSomeBytes( aData
, nMaxBytesToRead
);
121 void SAL_CALL
SequenceInputStreamService::skipBytes( ::sal_Int32 nBytesToSkip
)
123 std::scoped_lock
aGuard( m_aMutex
);
124 if ( !m_xInputStream
.is() )
125 throw io::NotConnectedException();
127 return m_xInputStream
->skipBytes( nBytesToSkip
);
130 ::sal_Int32 SAL_CALL
SequenceInputStreamService::available()
132 std::scoped_lock
aGuard( m_aMutex
);
133 if ( !m_xInputStream
.is() )
134 throw io::NotConnectedException();
136 return m_xInputStream
->available();
139 void SAL_CALL
SequenceInputStreamService::closeInput()
141 std::scoped_lock
aGuard( m_aMutex
);
142 if ( !m_xInputStream
.is() )
143 throw io::NotConnectedException();
145 m_xInputStream
->closeInput();
146 m_xInputStream
.clear();
150 // css::io::XSeekable:
151 void SAL_CALL
SequenceInputStreamService::seek( ::sal_Int64 location
)
153 std::scoped_lock
aGuard( m_aMutex
);
154 if ( !m_xSeekable
.is() )
155 throw io::NotConnectedException();
157 m_xSeekable
->seek( location
);
160 ::sal_Int64 SAL_CALL
SequenceInputStreamService::getPosition()
162 std::scoped_lock
aGuard( m_aMutex
);
163 if ( !m_xSeekable
.is() )
164 throw io::NotConnectedException();
166 return m_xSeekable
->getPosition();
169 ::sal_Int64 SAL_CALL
SequenceInputStreamService::getLength()
171 std::scoped_lock
aGuard( m_aMutex
);
172 if ( !m_xSeekable
.is() )
173 throw io::NotConnectedException();
175 return m_xSeekable
->getLength();
178 // css::lang::XInitialization:
179 void SAL_CALL
SequenceInputStreamService::initialize( const uno::Sequence
< css::uno::Any
> & aArguments
)
181 std::scoped_lock
aGuard( m_aMutex
);
182 if ( m_bInitialized
)
183 throw frame::DoubleInitializationException();
185 if ( aArguments
.getLength() != 1 )
186 throw lang::IllegalArgumentException( "Wrong number of arguments!",
187 static_cast< ::cppu::OWeakObject
* >(this),
190 uno::Sequence
< sal_Int8
> aSeq
;
191 if ( !(aArguments
[0] >>= aSeq
) )
192 throw lang::IllegalArgumentException( "Unexpected type of argument!",
193 static_cast< ::cppu::OWeakObject
* >(this),
196 uno::Reference
< io::XInputStream
> xInputStream(
197 static_cast< ::cppu::OWeakObject
* >( new ::comphelper::SequenceInputStream( aSeq
) ),
198 uno::UNO_QUERY_THROW
);
199 uno::Reference
< io::XSeekable
> xSeekable( xInputStream
, uno::UNO_QUERY_THROW
);
200 m_xInputStream
= xInputStream
;
201 m_xSeekable
= xSeekable
;
202 m_bInitialized
= true;
205 } // anonymous namespace
207 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
208 com_sun_star_comp_SequenceInputStreamService(
209 css::uno::XComponentContext
*,
210 css::uno::Sequence
<css::uno::Any
> const &)
212 return cppu::acquire(new SequenceInputStreamService());
215 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */