LibreOffice Module ucb (master)  1
filstr.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 <sal/config.h>
21 
22 #include <com/sun/star/io/BufferSizeExceededException.hpp>
23 #include <com/sun/star/io/IOException.hpp>
24 #include <com/sun/star/lang/IllegalArgumentException.hpp>
25 #include <com/sun/star/uno/RuntimeException.hpp>
26 #include <osl/diagnose.h>
27 #include "filstr.hxx"
28 #include "filerror.hxx"
29 
30 using namespace fileaccess;
31 using namespace com::sun::star;
32 
33 #if OSL_DEBUG_LEVEL > 0
34 #define THROW_WHERE SAL_WHERE
35 #else
36 #define THROW_WHERE ""
37 #endif
38 
39 /******************************************************************************/
40 /* */
41 /* XStream_impl implementation */
42 /* */
43 /******************************************************************************/
44 
45 XStream_impl::XStream_impl( const OUString& aUncPath, bool bLock )
46  : m_bInputStreamCalled( false ),
47  m_bOutputStreamCalled( false ),
48  m_aFile( aUncPath ),
49  m_nErrorCode( TASKHANDLER_NO_ERROR ),
50  m_nMinorErrorCode( TASKHANDLER_NO_ERROR )
51 {
52  sal_uInt32 nFlags = ( osl_File_OpenFlag_Read | osl_File_OpenFlag_Write );
53  if ( !bLock )
54  nFlags |= osl_File_OpenFlag_NoLock;
55 
56  osl::FileBase::RC err = m_aFile.open( nFlags );
57  if( err != osl::FileBase::E_None )
58  {
59  m_nIsOpen = false;
60  m_aFile.close();
61 
63  m_nMinorErrorCode = err;
64  }
65  else
66  m_nIsOpen = true;
67 }
68 
69 
71 {
72  try
73  {
74  closeStream();
75  }
76  catch (const io::IOException&)
77  {
78  OSL_FAIL("unexpected situation");
79  }
80  catch (const uno::RuntimeException&)
81  {
82  OSL_FAIL("unexpected situation");
83  }
84 }
85 
86 
87 uno::Reference< io::XInputStream > SAL_CALL
89 {
90  {
91  osl::MutexGuard aGuard( m_aMutex );
92  m_bInputStreamCalled = true;
93  }
94  return uno::Reference< io::XInputStream >( this );
95 }
96 
97 
98 uno::Reference< io::XOutputStream > SAL_CALL
100 {
101  {
102  osl::MutexGuard aGuard( m_aMutex );
103  m_bOutputStreamCalled = true;
104  }
105  return uno::Reference< io::XOutputStream >( this );
106 }
107 
108 
109 void SAL_CALL XStream_impl::truncate()
110 {
111  if (osl::FileBase::E_None != m_aFile.setSize(0))
112  throw io::IOException( THROW_WHERE );
113 
114  if (osl::FileBase::E_None != m_aFile.setPos(osl_Pos_Absolut,sal_uInt64(0)))
115  throw io::IOException( THROW_WHERE );
116 }
117 
118 
119 // XStream_impl private non interface methods
120 
121 
122 sal_Int32 SAL_CALL
124  uno::Sequence< sal_Int8 >& aData,
125  sal_Int32 nBytesToRead )
126 {
127  if( ! m_nIsOpen )
128  throw io::IOException( THROW_WHERE );
129 
130  try
131  {
132  aData.realloc(nBytesToRead);
133  }
134  catch (const std::bad_alloc&)
135  {
136  if( m_nIsOpen ) m_aFile.close();
137  throw io::BufferSizeExceededException( THROW_WHERE );
138  }
139 
140  sal_uInt64 nrc(0);
141  if(m_aFile.read( aData.getArray(), sal_uInt64(nBytesToRead), nrc )
142  != osl::FileBase::E_None)
143  {
144  throw io::IOException( THROW_WHERE );
145  }
146  if (nrc != static_cast<sal_uInt64>(nBytesToRead))
147  aData.realloc(nrc);
148  return static_cast<sal_Int32>(nrc);
149 }
150 
151 
152 sal_Int32 SAL_CALL
154  uno::Sequence< sal_Int8 >& aData,
155  sal_Int32 nMaxBytesToRead )
156 {
157  return readBytes( aData,nMaxBytesToRead );
158 }
159 
160 
161 void SAL_CALL
162 XStream_impl::skipBytes( sal_Int32 nBytesToSkip )
163 {
164  m_aFile.setPos( osl_Pos_Current, sal_uInt64( nBytesToSkip ) );
165 }
166 
167 
168 sal_Int32 SAL_CALL
170 {
171  sal_Int64 avail = getLength() - getPosition();
172  return std::min<sal_Int64>(avail, SAL_MAX_INT32);
173 }
174 
175 
176 void SAL_CALL
177 XStream_impl::writeBytes( const uno::Sequence< sal_Int8 >& aData )
178 {
179  sal_uInt32 length = aData.getLength();
180  if(length)
181  {
182  sal_uInt64 nWrittenBytes(0);
183  const sal_Int8* p = aData.getConstArray();
184  if(osl::FileBase::E_None != m_aFile.write(static_cast<void const *>(p),sal_uInt64(length),nWrittenBytes) ||
185  nWrittenBytes != length )
186  throw io::IOException( THROW_WHERE );
187  }
188 }
189 
190 
191 void
193 {
194  if( m_nIsOpen )
195  {
196  osl::FileBase::RC err = m_aFile.close();
197 
198  if( err != osl::FileBase::E_None ) {
199  io::IOException ex;
200  ex.Message = "could not close file";
201  throw ex;
202  }
203 
204  m_nIsOpen = false;
205  }
206 }
207 
208 void SAL_CALL
210 {
211  osl::MutexGuard aGuard( m_aMutex );
212  m_bInputStreamCalled = false;
213 
214  if( ! m_bOutputStreamCalled )
215  closeStream();
216 }
217 
218 
219 void SAL_CALL
221 {
222  osl::MutexGuard aGuard( m_aMutex );
223  m_bOutputStreamCalled = false;
224 
225  if( ! m_bInputStreamCalled )
226  closeStream();
227 }
228 
229 
230 void SAL_CALL
231 XStream_impl::seek( sal_Int64 location )
232 {
233  if( location < 0 )
234  throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 0 );
235  if( osl::FileBase::E_None != m_aFile.setPos( osl_Pos_Absolut, sal_uInt64( location ) ) )
236  throw io::IOException( THROW_WHERE );
237 }
238 
239 
240 sal_Int64 SAL_CALL
242 {
243  sal_uInt64 uPos;
244  if( osl::FileBase::E_None != m_aFile.getPos( uPos ) )
245  throw io::IOException( THROW_WHERE );
246  return sal_Int64( uPos );
247 }
248 
249 sal_Int64 SAL_CALL
251 {
252  sal_uInt64 uEndPos;
253  if ( m_aFile.getSize(uEndPos) != osl::FileBase::E_None )
254  throw io::IOException( THROW_WHERE );
255  return sal_Int64( uEndPos );
256 }
257 
258 void SAL_CALL
260 {}
261 
263 {
264  // At least on UNIX, to reliably learn about any errors encountered by
265  // asynchronous NFS write operations, without closing the file directly
266  // afterwards, there appears to be no cheaper way than to call fsync:
267  if (m_nIsOpen && m_aFile.sync() != osl::FileBase::E_None) {
268  throw io::IOException(
269  "could not synchronize file to disc",
270  static_cast< OWeakObject * >(this));
271  }
272 }
273 
274 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_Int32 SAL_CALL readSomeBytes(css::uno::Sequence< sal_Int8 > &aData, sal_Int32 nMaxBytesToRead) override
Definition: filstr.cxx:153
sal_Int32 SAL_CALL available() override
Definition: filstr.cxx:169
virtual void SAL_CALL waitForCompletion() override
Definition: filstr.cxx:262
#define THROW_WHERE
Definition: filstr.cxx:34
::osl::FileBase::RC getSize(sal_uInt64 &rSize)
Definition: filrec.cxx:143
signed char sal_Int8
::osl::FileBase::RC close()
Definition: filrec.cxx:64
void SAL_CALL skipBytes(sal_Int32 nBytesToSkip) override
Definition: filstr.cxx:162
void SAL_CALL closeOutput() override
Definition: filstr.cxx:220
void SAL_CALL seek(sal_Int64 location) override
Definition: filstr.cxx:231
length
sal_Int32 SAL_CALL readBytes(css::uno::Sequence< sal_Int8 > &aData, sal_Int32 nBytesToRead) override
Definition: filstr.cxx:123
void SAL_CALL closeInput() override
Definition: filstr.cxx:209
::osl::FileBase::RC getPos(sal_uInt64 &uPos)
Definition: filrec.cxx:104
void SAL_CALL writeBytes(const css::uno::Sequence< sal_Int8 > &aData) override
Definition: filstr.cxx:177
sal_Int64 SAL_CALL getLength() override
Definition: filstr.cxx:250
void SAL_CALL flush() override
Definition: filstr.cxx:259
err
virtual void SAL_CALL truncate() override
Definition: filstr.cxx:109
#define SAL_MAX_INT32
sal_Int64 SAL_CALL getPosition() override
Definition: filstr.cxx:241
::osl::FileBase::RC write(const void *pBuffer, sal_uInt64 uBytesToWrite, sal_uInt64 &rBytesWritten)
Definition: filrec.cxx:174
::osl::FileBase::RC setPos(sal_uInt32 uHow, sal_Int64 uPos)
Definition: filrec.cxx:73
ReconnectingFile m_aFile
Definition: filstr.hxx:130
sal_Int32 m_nMinorErrorCode
Definition: filstr.hxx:133
::osl::FileBase::RC setSize(sal_uInt64 uSize)
Definition: filrec.cxx:112
virtual ~XStream_impl() override
Definition: filstr.cxx:70
virtual css::uno::Reference< css::io::XOutputStream > SAL_CALL getOutputStream() override
Definition: filstr.cxx:99
::osl::FileBase::RC open(sal_uInt32 uFlags)
Definition: filrec.cxx:48
::osl::FileBase::RC sync() const
Definition: filrec.cxx:182
virtual css::uno::Reference< css::io::XInputStream > SAL_CALL getInputStream() override
Definition: filstr.cxx:88
#define TASKHANDLER_NO_ERROR
Definition: filerror.hxx:27
::osl::FileBase::RC read(void *pBuffer, sal_uInt64 uBytesRequested, sal_uInt64 &rBytesRead)
Definition: filrec.cxx:166
XStream_impl(const OUString &aUncPath, bool bLock)
Definition: filstr.cxx:45
#define TASKHANDLING_OPEN_FOR_STREAM
Definition: filerror.hxx:48