LibreOffice Module ucb (master)  1
std_inputstream.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 
10 #include <sal/config.h>
11 
12 #include <com/sun/star/io/IOException.hpp>
13 #include <com/sun/star/lang/IllegalArgumentException.hpp>
14 #include <sal/log.hxx>
16 
17 #include "std_inputstream.hxx"
18 
19 using namespace com::sun::star;
20 
21 namespace cmis
22 {
23  StdInputStream::StdInputStream( boost::shared_ptr< std::istream > const & pStream ) :
24  m_pStream( pStream ),
25  m_nLength( 0 )
26  {
27  if (m_pStream)
28  {
29  auto nInitPos = m_pStream->tellg( );
30  m_pStream->seekg( 0, std::ios_base::end );
31  auto nEndPos = m_pStream->tellg( );
32  m_pStream->seekg( nInitPos, std::ios_base::beg );
33 
34  m_nLength = sal_Int64( nEndPos - nInitPos );
35  }
36  }
37 
39  {
40  }
41 
43  {
44  uno::Any aRet = ::cppu::queryInterface( rType,
45  static_cast< XInputStream* >( this ),
46  static_cast< XSeekable* >( this ) );
47 
48  return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
49  }
50 
51  void SAL_CALL StdInputStream::acquire( ) noexcept
52  {
53  OWeakObject::acquire();
54  }
55 
56  void SAL_CALL StdInputStream::release( ) noexcept
57  {
58  OWeakObject::release();
59  }
60 
61  sal_Int32 SAL_CALL StdInputStream::readBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
62  {
63  std::scoped_lock aGuard( m_aMutex );
64 
65  if ( 0 <= nBytesToRead && aData.getLength() < nBytesToRead )
66  aData.realloc( nBytesToRead );
67 
68  if (!m_pStream)
69  throw io::IOException( );
70 
71  sal_Int32 nRead = 0;
72  try
73  {
74  m_pStream->read( reinterpret_cast< char* >( aData.getArray( ) ), nBytesToRead );
75  nRead = m_pStream->gcount();
76  }
77  catch ( const std::ios_base::failure& e )
78  {
79  SAL_INFO( "ucb.ucp.cmis", "StdInputStream::readBytes() error: " << e.what() );
80  throw io::IOException( );
81  }
82 
83  return nRead;
84  }
85 
86  sal_Int32 SAL_CALL StdInputStream::readSomeBytes( uno::Sequence< sal_Int8 >& aData,
87  sal_Int32 nMaxBytesToRead )
88  {
89  std::scoped_lock aGuard( m_aMutex );
90 
91  if ( 0 <= nMaxBytesToRead && aData.getLength() < nMaxBytesToRead )
92  aData.realloc( nMaxBytesToRead );
93 
94  if (!m_pStream)
95  throw io::IOException( );
96 
97  sal_Int32 nRead = 0;
98  try
99  {
100  nRead = m_pStream->readsome( reinterpret_cast< char* >( aData.getArray( ) ), nMaxBytesToRead );
101  }
102  catch ( const std::ios_base::failure& e )
103  {
104  SAL_INFO( "ucb.ucp.cmis", "StdInputStream::readBytes() error: " << e.what() );
105  throw io::IOException( );
106  }
107  return nRead;
108  }
109 
110  void SAL_CALL StdInputStream::skipBytes( sal_Int32 nBytesToSkip )
111  {
112  std::scoped_lock aGuard( m_aMutex );
113 
114  if (!m_pStream)
115  throw io::IOException( );
116 
117  try
118  {
119  m_pStream->seekg( nBytesToSkip, std::ios_base::cur );
120  }
121  catch ( const std::ios_base::failure& e )
122  {
123  SAL_INFO( "ucb.ucp.cmis", "StdInputStream::readBytes() error: " << e.what() );
124  throw io::IOException( );
125  }
126  }
127 
128  sal_Int32 SAL_CALL StdInputStream::available( )
129  {
130  return std::min<sal_Int64>( SAL_MAX_INT32, m_nLength - getPosition() );
131  }
132 
133  void SAL_CALL StdInputStream::closeInput( )
134  {
135  // No need to implement this for an istream
136  }
137 
138  void SAL_CALL StdInputStream::seek( sal_Int64 location )
139  {
140  std::scoped_lock aGuard( m_aMutex );
141 
142  if ( location < 0 || location > m_nLength )
143  throw lang::IllegalArgumentException(
144  "Location can't be negative or greater than the length",
145  static_cast< cppu::OWeakObject* >( this ), 0 );
146 
147  if (!m_pStream)
148  throw io::IOException( );
149 
150  try
151  {
152  m_pStream->clear( ); // may be needed to rewind the stream
153  m_pStream->seekg( location, std::ios_base::beg );
154  }
155  catch ( const std::ios_base::failure& e )
156  {
157  SAL_INFO( "ucb.ucp.cmis", "StdInputStream::readBytes() error: " << e.what() );
158  throw io::IOException( );
159  }
160  }
161 
162  sal_Int64 SAL_CALL StdInputStream::getPosition( )
163  {
164  std::scoped_lock aGuard( m_aMutex );
165 
166  if (!m_pStream)
167  throw io::IOException( );
168 
169  sal_Int64 nPos = m_pStream->tellg( );
170  if ( -1 == nPos )
171  throw io::IOException( );
172 
173  return nPos;
174  }
175 
176  sal_Int64 SAL_CALL StdInputStream::getLength( )
177  {
178  return m_nLength;
179  }
180 }
181 
182 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const sal_Int32 m_nLength
virtual void SAL_CALL release() noexcept override
virtual sal_Int32 SAL_CALL readSomeBytes(css::uno::Sequence< sal_Int8 > &aData, sal_Int32 nMaxBytesToRead) override
virtual sal_Int64 SAL_CALL getLength() override
bool hasValue()
virtual void SAL_CALL skipBytes(sal_Int32 nBytesToSkip) override
virtual sal_Int32 SAL_CALL available() override
#define SAL_MAX_INT32
virtual ~StdInputStream() override
virtual void SAL_CALL seek(sal_Int64 location) override
XSeekable.
virtual void SAL_CALL closeInput() override
virtual sal_Int64 SAL_CALL getPosition() override
#define SAL_INFO(area, stream)
virtual sal_Int32 SAL_CALL readBytes(css::uno::Sequence< sal_Int8 > &aData, sal_Int32 nBytesToRead) override
virtual void SAL_CALL acquire() noexcept override
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
sal_uInt16 nPos
boost::shared_ptr< std::istream > m_pStream