Line data Source code
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 <stdio.h>
21 : #include <string.h>
22 : #include <sys/stat.h>
23 : #include <fcntl.h>
24 : #include <errno.h>
25 : #include <unistd.h>
26 : #include <limits.h>
27 :
28 : #include <tools/debug.hxx>
29 : #include <tools/stream.hxx>
30 : #include <vector>
31 :
32 : #include <osl/mutex.hxx>
33 : #include <osl/thread.h> // osl_getThreadTextEncoding
34 :
35 : // class FileBase
36 : #include <osl/file.hxx>
37 : #include <osl/detail/file.h>
38 : #include <rtl/instance.hxx>
39 : #include <rtl/strbuf.hxx>
40 :
41 : using namespace osl;
42 :
43 : // InternalLock ----------------------------------------------------------------
44 :
45 : namespace { struct LockMutex : public rtl::Static< osl::Mutex, LockMutex > {}; }
46 :
47 : class InternalStreamLock
48 : {
49 : sal_Size m_nStartPos;
50 : sal_Size m_nEndPos;
51 : SvFileStream* m_pStream;
52 : osl::DirectoryItem m_aItem;
53 :
54 : InternalStreamLock( sal_Size, sal_Size, SvFileStream* );
55 : ~InternalStreamLock();
56 : public:
57 : static bool LockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* );
58 : static void UnlockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* );
59 : };
60 :
61 : typedef ::std::vector< InternalStreamLock* > InternalStreamLockList;
62 :
63 : namespace { struct LockList : public rtl::Static< InternalStreamLockList, LockList > {}; }
64 :
65 0 : InternalStreamLock::InternalStreamLock(
66 : sal_Size nStart,
67 : sal_Size nEnd,
68 : SvFileStream* pStream ) :
69 : m_nStartPos( nStart ),
70 : m_nEndPos( nEnd ),
71 0 : m_pStream( pStream )
72 : {
73 0 : osl::DirectoryItem::get( m_pStream->GetFileName(), m_aItem );
74 0 : LockList::get().push_back( this );
75 : #if OSL_DEBUG_LEVEL > 1
76 : OString aFileName(OUStringToOString(m_pStream->GetFileName(),
77 : osl_getThreadTextEncoding()));
78 : fprintf( stderr, "locked %s", aFileName.getStr() );
79 : if( m_nStartPos || m_nEndPos )
80 : fprintf(stderr, " [ %ld ... %ld ]", m_nStartPos, m_nEndPos );
81 : fprintf( stderr, "\n" );
82 : #endif
83 0 : }
84 :
85 0 : InternalStreamLock::~InternalStreamLock()
86 : {
87 0 : for ( InternalStreamLockList::iterator it = LockList::get().begin();
88 0 : it != LockList::get().end();
89 : ++it
90 : ) {
91 0 : if ( this == *it ) {
92 0 : LockList::get().erase( it );
93 0 : break;
94 : }
95 : }
96 : #if OSL_DEBUG_LEVEL > 1
97 : OString aFileName(OUStringToOString(m_pStream->GetFileName(),
98 : osl_getThreadTextEncoding()));
99 : fprintf( stderr, "unlocked %s", aFileName.getStr() );
100 : if( m_nStartPos || m_nEndPos )
101 : fprintf(stderr, " [ %ld ... %ld ]", m_nStartPos, m_nEndPos );
102 : fprintf( stderr, "\n" );
103 : #endif
104 0 : }
105 :
106 144 : bool InternalStreamLock::LockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* pStream )
107 : {
108 144 : osl::MutexGuard aGuard( LockMutex::get() );
109 288 : osl::DirectoryItem aItem;
110 144 : if (osl::DirectoryItem::get( pStream->GetFileName(), aItem) != osl::FileBase::E_None )
111 : {
112 : SAL_INFO("tools.stream", "Failed to lookup stream for locking");
113 144 : return true;
114 : }
115 :
116 0 : osl::FileStatus aStatus( osl_FileStatus_Mask_Type );
117 0 : if ( aItem.getFileStatus( aStatus ) != osl::FileBase::E_None )
118 : {
119 : SAL_INFO("tools.stream", "Failed to stat stream for locking");
120 0 : return true;
121 : }
122 0 : if( aStatus.getFileType() == osl::FileStatus::Directory )
123 0 : return true;
124 :
125 0 : InternalStreamLock* pLock = NULL;
126 0 : InternalStreamLockList &rLockList = LockList::get();
127 0 : for( size_t i = 0; i < rLockList.size(); ++i )
128 : {
129 0 : pLock = rLockList[ i ];
130 0 : if( aItem.isIdenticalTo( pLock->m_aItem ) )
131 : {
132 0 : bool bDenyByOptions = false;
133 0 : StreamMode nLockMode = pLock->m_pStream->GetStreamMode();
134 0 : StreamMode nNewMode = pStream->GetStreamMode();
135 :
136 0 : if( nLockMode & STREAM_SHARE_DENYALL )
137 0 : bDenyByOptions = true;
138 0 : else if( ( nLockMode & STREAM_SHARE_DENYWRITE ) &&
139 0 : ( nNewMode & STREAM_WRITE ) )
140 0 : bDenyByOptions = true;
141 0 : else if( ( nLockMode & STREAM_SHARE_DENYREAD ) &&
142 0 : ( nNewMode & STREAM_READ ) )
143 0 : bDenyByOptions = true;
144 :
145 0 : if( bDenyByOptions )
146 : {
147 0 : if( pLock->m_nStartPos == 0 && pLock->m_nEndPos == 0 ) // whole file is already locked
148 0 : return false;
149 0 : if( nStart == 0 && nEnd == 0) // cannot lock whole file
150 0 : return false;
151 :
152 0 : if( ( nStart < pLock->m_nStartPos && nEnd > pLock->m_nStartPos ) ||
153 0 : ( nStart < pLock->m_nEndPos && nEnd > pLock->m_nEndPos ) )
154 0 : return false;
155 : }
156 : }
157 : }
158 : // hint: new InternalStreamLock() adds the entry to the global list
159 0 : pLock = new InternalStreamLock( nStart, nEnd, pStream );
160 144 : return true;
161 : }
162 :
163 5514 : void InternalStreamLock::UnlockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* pStream )
164 : {
165 5514 : osl::MutexGuard aGuard( LockMutex::get() );
166 5514 : InternalStreamLock* pLock = NULL;
167 5514 : InternalStreamLockList &rLockList = LockList::get();
168 5514 : if( nStart == 0 && nEnd == 0 )
169 : {
170 : // nStart & nEnd = 0, so delete all locks
171 5514 : for( size_t i = 0; i < rLockList.size(); ++i )
172 : {
173 0 : if( ( pLock = rLockList[ i ] )->m_pStream == pStream )
174 : {
175 : // hint: delete will remove pLock from the global list
176 0 : delete pLock;
177 0 : i--;
178 : }
179 : }
180 5514 : return;
181 : }
182 0 : for( size_t i = 0; i < rLockList.size(); ++i )
183 : {
184 0 : if ( ( pLock = rLockList[ i ] )->m_pStream == pStream
185 0 : && nStart == pLock->m_nStartPos
186 0 : && nEnd == pLock->m_nEndPos
187 : ) {
188 : // hint: delete will remove pLock from the global list
189 0 : delete pLock;
190 0 : return;
191 : }
192 0 : }
193 : }
194 :
195 : // StreamData ------------------------------------------------------------------
196 :
197 : class StreamData
198 : {
199 : public:
200 : oslFileHandle rHandle;
201 :
202 3592 : StreamData() : rHandle( 0 ) { }
203 : };
204 :
205 0 : static sal_uInt32 GetSvError( int nErrno )
206 : {
207 : static struct { int nErr; sal_uInt32 sv; } errArr[] =
208 : {
209 : { 0, SVSTREAM_OK },
210 : { EACCES, SVSTREAM_ACCESS_DENIED },
211 : { EBADF, SVSTREAM_INVALID_HANDLE },
212 : #if defined(RS6000) || defined(NETBSD) || \
213 : defined(FREEBSD) || defined(MACOSX) || defined(OPENBSD) || \
214 : defined(__FreeBSD_kernel__) || defined (AIX) || defined(DRAGONFLY) || \
215 : defined(IOS)
216 : { EDEADLK, SVSTREAM_LOCKING_VIOLATION },
217 : #else
218 : { EDEADLOCK, SVSTREAM_LOCKING_VIOLATION },
219 : #endif
220 : { EINVAL, SVSTREAM_INVALID_PARAMETER },
221 : { EMFILE, SVSTREAM_TOO_MANY_OPEN_FILES },
222 : { ENFILE, SVSTREAM_TOO_MANY_OPEN_FILES },
223 : { ENOENT, SVSTREAM_FILE_NOT_FOUND },
224 : { EPERM, SVSTREAM_ACCESS_DENIED },
225 : { EROFS, SVSTREAM_ACCESS_DENIED },
226 : { EAGAIN, SVSTREAM_LOCKING_VIOLATION },
227 : { EISDIR, SVSTREAM_PATH_NOT_FOUND },
228 : { ELOOP, SVSTREAM_PATH_NOT_FOUND },
229 : #if !defined(RS6000) && !defined(NETBSD) && !defined (FREEBSD) && \
230 : !defined(MACOSX) && !defined(OPENBSD) && !defined(__FreeBSD_kernel__) && \
231 : !defined(DRAGONFLY)
232 : { EMULTIHOP, SVSTREAM_PATH_NOT_FOUND },
233 : { ENOLINK, SVSTREAM_PATH_NOT_FOUND },
234 : #endif
235 : { ENOTDIR, SVSTREAM_PATH_NOT_FOUND },
236 : { ETXTBSY, SVSTREAM_ACCESS_DENIED },
237 : { EEXIST, SVSTREAM_CANNOT_MAKE },
238 : { ENOSPC, SVSTREAM_DISK_FULL },
239 : { (int)0xFFFF, SVSTREAM_GENERALERROR }
240 : };
241 :
242 0 : sal_uInt32 nRetVal = SVSTREAM_GENERALERROR; // default error
243 0 : int i=0;
244 0 : do
245 : {
246 0 : if ( errArr[i].nErr == nErrno )
247 : {
248 0 : nRetVal = errArr[i].sv;
249 0 : break;
250 : }
251 0 : ++i;
252 : }
253 0 : while( errArr[i].nErr != 0xFFFF );
254 0 : return nRetVal;
255 : }
256 :
257 804 : static sal_uInt32 GetSvError( oslFileError nErrno )
258 : {
259 : static struct { oslFileError nErr; sal_uInt32 sv; } errArr[] =
260 : {
261 : { osl_File_E_None, SVSTREAM_OK },
262 : { osl_File_E_ACCES, SVSTREAM_ACCESS_DENIED },
263 : { osl_File_E_BADF, SVSTREAM_INVALID_HANDLE },
264 : { osl_File_E_DEADLK, SVSTREAM_LOCKING_VIOLATION },
265 : { osl_File_E_INVAL, SVSTREAM_INVALID_PARAMETER },
266 : { osl_File_E_MFILE, SVSTREAM_TOO_MANY_OPEN_FILES },
267 : { osl_File_E_NFILE, SVSTREAM_TOO_MANY_OPEN_FILES },
268 : { osl_File_E_NOENT, SVSTREAM_FILE_NOT_FOUND },
269 : { osl_File_E_PERM, SVSTREAM_ACCESS_DENIED },
270 : { osl_File_E_ROFS, SVSTREAM_ACCESS_DENIED },
271 : { osl_File_E_AGAIN, SVSTREAM_LOCKING_VIOLATION },
272 : { osl_File_E_ISDIR, SVSTREAM_PATH_NOT_FOUND },
273 : { osl_File_E_LOOP, SVSTREAM_PATH_NOT_FOUND },
274 : { osl_File_E_MULTIHOP, SVSTREAM_PATH_NOT_FOUND },
275 : { osl_File_E_NOLINK, SVSTREAM_PATH_NOT_FOUND },
276 : { osl_File_E_NOTDIR, SVSTREAM_PATH_NOT_FOUND },
277 : { osl_File_E_EXIST, SVSTREAM_CANNOT_MAKE },
278 : { osl_File_E_NOSPC, SVSTREAM_DISK_FULL },
279 : { (oslFileError)0xFFFF, SVSTREAM_GENERALERROR }
280 : };
281 :
282 804 : sal_uInt32 nRetVal = SVSTREAM_GENERALERROR; // default error
283 804 : int i=0;
284 5628 : do
285 : {
286 6432 : if ( errArr[i].nErr == nErrno )
287 : {
288 804 : nRetVal = errArr[i].sv;
289 804 : break;
290 : }
291 5628 : ++i;
292 : }
293 5628 : while( errArr[i].nErr != (oslFileError)0xFFFF );
294 804 : return nRetVal;
295 : }
296 :
297 3318 : SvFileStream::SvFileStream( const OUString& rFileName, StreamMode nOpenMode )
298 : {
299 3318 : bIsOpen = false;
300 3318 : nLockCounter = 0;
301 3318 : bIsWritable = false;
302 3318 : pInstanceData = new StreamData;
303 :
304 3318 : SetBufferSize( 1024 );
305 : // convert URL to SystemPath, if necessary
306 3318 : OUString aSystemFileName;
307 3318 : if( FileBase::getSystemPathFromFileURL( rFileName , aSystemFileName )
308 : != FileBase::E_None )
309 : {
310 1047 : aSystemFileName = rFileName;
311 : }
312 3318 : Open( aSystemFileName, nOpenMode );
313 3318 : }
314 :
315 274 : SvFileStream::SvFileStream()
316 : {
317 274 : bIsOpen = false;
318 274 : nLockCounter = 0;
319 274 : bIsWritable = false;
320 274 : pInstanceData = new StreamData;
321 274 : SetBufferSize( 1024 );
322 274 : }
323 :
324 8446 : SvFileStream::~SvFileStream()
325 : {
326 3234 : Close();
327 :
328 3234 : InternalStreamLock::UnlockFile( 0, 0, this );
329 :
330 3234 : if (pInstanceData)
331 3234 : delete pInstanceData;
332 5212 : }
333 :
334 0 : sal_uInt32 SvFileStream::GetFileHandle() const
335 : {
336 : sal_IntPtr handle;
337 0 : if (osl_getFileOSHandle(pInstanceData->rHandle, &handle) == osl_File_E_None)
338 0 : return (sal_uInt32) handle;
339 : else
340 0 : return (sal_uInt32) -1;
341 : }
342 :
343 0 : sal_uInt16 SvFileStream::IsA() const
344 : {
345 0 : return ID_FILESTREAM;
346 : }
347 :
348 131055 : sal_Size SvFileStream::GetData( void* pData, sal_Size nSize )
349 : {
350 : #ifdef DBG_UTIL
351 : OStringBuffer aTraceStr("SvFileStream::GetData(): ");
352 : aTraceStr.append(static_cast<sal_Int64>(nSize));
353 : aTraceStr.append(" Bytes from ");
354 : aTraceStr.append(OUStringToOString(aFilename,
355 : osl_getThreadTextEncoding()));
356 : OSL_TRACE("%s", aTraceStr.getStr());
357 : #endif
358 :
359 131055 : sal_uInt64 nRead = 0;
360 131055 : if ( IsOpen() )
361 : {
362 131055 : oslFileError rc = osl_readFile(pInstanceData->rHandle,pData,(sal_uInt64)nSize,&nRead);
363 131055 : if ( rc != osl_File_E_None )
364 : {
365 0 : SetError( ::GetSvError( rc ));
366 0 : return -1;
367 : }
368 : }
369 131055 : return (sal_Size)nRead;
370 : }
371 :
372 20755 : sal_Size SvFileStream::PutData( const void* pData, sal_Size nSize )
373 : {
374 : #ifdef DBG_UTIL
375 : OStringBuffer aTraceStr("SvFileStream::PutData(): ");
376 : aTraceStr.append(static_cast<sal_Int64>(nSize));
377 : aTraceStr.append(" Bytes to ");
378 : aTraceStr.append(OUStringToOString(aFilename,
379 : osl_getThreadTextEncoding()));
380 : OSL_TRACE("%s", aTraceStr.getStr());
381 : #endif
382 :
383 20755 : sal_uInt64 nWrite = 0;
384 20755 : if ( IsOpen() )
385 : {
386 20755 : oslFileError rc = osl_writeFile(pInstanceData->rHandle,pData,(sal_uInt64)nSize,&nWrite);
387 20755 : if ( rc != osl_File_E_None )
388 : {
389 0 : SetError( ::GetSvError( rc ) );
390 0 : return -1;
391 : }
392 20755 : else if( !nWrite )
393 0 : SetError( SVSTREAM_DISK_FULL );
394 : }
395 20755 : return (sal_Size)nWrite;
396 : }
397 :
398 185436 : sal_Size SvFileStream::SeekPos( sal_Size nPos )
399 : {
400 185436 : if ( IsOpen() )
401 : {
402 : oslFileError rc;
403 : sal_uInt64 nNewPos;
404 185436 : if ( nPos != STREAM_SEEK_TO_END )
405 183592 : rc = osl_setFilePos( pInstanceData->rHandle, osl_Pos_Absolut, nPos );
406 : else
407 1844 : rc = osl_setFilePos( pInstanceData->rHandle, osl_Pos_End, 0 );
408 :
409 185436 : if ( rc != osl_File_E_None )
410 : {
411 0 : SetError( SVSTREAM_SEEK_ERROR );
412 0 : return 0L;
413 : }
414 185436 : rc = osl_getFilePos( pInstanceData->rHandle, &nNewPos );
415 185436 : return (sal_Size) nNewPos;
416 : }
417 0 : SetError( SVSTREAM_GENERALERROR );
418 0 : return 0L;
419 : }
420 :
421 691 : void SvFileStream::FlushData()
422 : {
423 : // does not exist locally
424 691 : }
425 :
426 2638 : bool SvFileStream::LockRange( sal_Size nByteOffset, sal_Size nBytes )
427 : {
428 2638 : int nLockMode = 0;
429 :
430 2638 : if ( ! IsOpen() )
431 0 : return false;
432 :
433 2638 : if ( eStreamMode & STREAM_SHARE_DENYALL )
434 : {
435 144 : if (bIsWritable)
436 144 : nLockMode = F_WRLCK;
437 : else
438 0 : nLockMode = F_RDLCK;
439 : }
440 :
441 2638 : if ( eStreamMode & STREAM_SHARE_DENYREAD )
442 : {
443 0 : if (bIsWritable)
444 0 : nLockMode = F_WRLCK;
445 : else
446 : {
447 0 : SetError(SVSTREAM_LOCKING_VIOLATION);
448 0 : return false;
449 : }
450 : }
451 :
452 2638 : if ( eStreamMode & STREAM_SHARE_DENYWRITE )
453 : {
454 1540 : if (bIsWritable)
455 0 : nLockMode = F_WRLCK;
456 : else
457 1540 : nLockMode = F_RDLCK;
458 : }
459 :
460 2638 : if (!nLockMode)
461 2494 : return true;
462 :
463 144 : if( ! InternalStreamLock::LockFile( nByteOffset, nByteOffset+nBytes, this ) )
464 : {
465 : #if OSL_DEBUG_LEVEL > 1
466 : fprintf( stderr, "InternalLock on %s [ %ld ... %ld ] failed\n",
467 : OUStringToOString(aFilename, osl_getThreadTextEncoding()).getStr(), nByteOffset, nByteOffset+nBytes );
468 : #endif
469 0 : return false;
470 : }
471 :
472 144 : return true;
473 : }
474 :
475 6686 : bool SvFileStream::UnlockRange( sal_Size nByteOffset, sal_Size nBytes )
476 : {
477 6686 : if ( ! IsOpen() )
478 4406 : return false;
479 :
480 2280 : InternalStreamLock::UnlockFile( nByteOffset, nByteOffset+nBytes, this );
481 :
482 2280 : return true;
483 : }
484 :
485 2638 : bool SvFileStream::LockFile()
486 : {
487 2638 : return LockRange( 0UL, 0UL );
488 : }
489 :
490 6686 : bool SvFileStream::UnlockFile()
491 : {
492 6686 : return UnlockRange( 0UL, 0UL );
493 : }
494 :
495 3442 : void SvFileStream::Open( const OUString& rFilename, StreamMode nOpenMode )
496 : {
497 : sal_uInt32 uFlags;
498 : oslFileHandle nHandleTmp;
499 :
500 3442 : Close();
501 3442 : errno = 0;
502 3442 : eStreamMode = nOpenMode;
503 3442 : eStreamMode &= ~STREAM_TRUNC; // don't truncat on reopen
504 :
505 3442 : aFilename = rFilename;
506 3442 : OString aLocalFilename(OUStringToOString(aFilename, osl_getThreadTextEncoding()));
507 :
508 : #ifdef DBG_UTIL
509 : OStringBuffer aTraceStr("SvFileStream::Open(): ");
510 : aTraceStr.append(aLocalFilename);
511 : OSL_TRACE( "%s", aTraceStr.getStr() );
512 : #endif
513 :
514 6884 : OUString aFileURL;
515 6884 : osl::DirectoryItem aItem;
516 6884 : osl::FileStatus aStatus( osl_FileStatus_Mask_Type | osl_FileStatus_Mask_LinkTargetURL );
517 :
518 : // FIXME: we really need to switch to a pure URL model ...
519 3442 : if ( osl::File::getFileURLFromSystemPath( aFilename, aFileURL ) != osl::FileBase::E_None )
520 0 : aFileURL = aFilename;
521 6026 : bool bStatValid = ( osl::DirectoryItem::get( aFileURL, aItem) == osl::FileBase::E_None &&
522 6026 : aItem.getFileStatus( aStatus ) == osl::FileBase::E_None );
523 :
524 : // SvFileStream can't open a directory
525 3442 : if( bStatValid && aStatus.getFileType() == osl::FileStatus::Directory )
526 : {
527 0 : SetError( ::GetSvError( EISDIR ) );
528 3442 : return;
529 : }
530 :
531 3442 : if ( !( nOpenMode & STREAM_WRITE ) )
532 3056 : uFlags = osl_File_OpenFlag_Read;
533 386 : else if ( !( nOpenMode & STREAM_READ ) )
534 184 : uFlags = osl_File_OpenFlag_Write;
535 : else
536 202 : uFlags = osl_File_OpenFlag_Read | osl_File_OpenFlag_Write;
537 :
538 : // Fix (MDA, 18.01.95): Don't open with O_CREAT upon RD_ONLY
539 : // Important for Read-Only-Filesystems (e.g, CDROM)
540 3442 : if ( (!( nOpenMode & STREAM_NOCREATE )) && ( uFlags != osl_File_OpenFlag_Read ) )
541 386 : uFlags |= osl_File_OpenFlag_Create;
542 3442 : if ( nOpenMode & STREAM_TRUNC )
543 232 : uFlags |= osl_File_OpenFlag_Trunc;
544 :
545 3442 : uFlags |= osl_File_OpenFlag_NoExcl | osl_File_OpenFlag_NoLock;
546 :
547 3442 : if ( nOpenMode & STREAM_WRITE)
548 : {
549 386 : if ( nOpenMode & STREAM_COPY_ON_SYMLINK )
550 : {
551 0 : if ( bStatValid && aStatus.getFileType() == osl::FileStatus::Link &&
552 0 : aStatus.getLinkTargetURL().getLength() > 0 )
553 : {
554 : // delete the symbolic link, and replace it with the contents of the link
555 0 : if (osl::File::remove( aFileURL ) == osl::FileBase::E_None )
556 : {
557 0 : File::copy( aStatus.getLinkTargetURL(), aFileURL );
558 : #if OSL_DEBUG_LEVEL > 0
559 : fprintf( stderr,
560 : "Removing link and replacing with file contents (%s) -> (%s).\n",
561 : OUStringToOString( aStatus.getLinkTargetURL(),
562 : RTL_TEXTENCODING_UTF8).getStr(),
563 : OUStringToOString( aFileURL,
564 : RTL_TEXTENCODING_UTF8).getStr() );
565 : #endif
566 : }
567 : }
568 : }
569 : }
570 :
571 3442 : oslFileError rc = osl_openFile( aFileURL.pData, &nHandleTmp, uFlags );
572 3442 : if ( rc != osl_File_E_None )
573 : {
574 804 : if ( uFlags & osl_File_OpenFlag_Write )
575 : {
576 : // Change to read-only
577 0 : uFlags &= ~osl_File_OpenFlag_Write;
578 0 : rc = osl_openFile( aFileURL.pData, &nHandleTmp, uFlags );
579 : }
580 : }
581 3442 : if ( rc == osl_File_E_None )
582 : {
583 2638 : pInstanceData->rHandle = nHandleTmp;
584 2638 : bIsOpen = true;
585 2638 : if ( uFlags & osl_File_OpenFlag_Write )
586 386 : bIsWritable = true;
587 :
588 2638 : if ( !LockFile() ) // whole file
589 : {
590 0 : rc = osl_closeFile( nHandleTmp );
591 0 : bIsOpen = false;
592 0 : bIsWritable = false;
593 0 : pInstanceData->rHandle = 0;
594 : }
595 : }
596 : else
597 4246 : SetError( ::GetSvError( rc ) );
598 : }
599 :
600 6686 : void SvFileStream::Close()
601 : {
602 6686 : UnlockFile();
603 :
604 6686 : if ( IsOpen() )
605 : {
606 : #ifdef DBG_UTIL
607 : OStringBuffer aTraceStr("SvFileStream::Close(): ");
608 : aTraceStr.append(OUStringToOString(aFilename,
609 : osl_getThreadTextEncoding()));
610 : OSL_TRACE("%s", aTraceStr.getStr());
611 : #endif
612 :
613 2280 : Flush();
614 2280 : osl_closeFile( pInstanceData->rHandle );
615 2280 : pInstanceData->rHandle = 0;
616 : }
617 :
618 6686 : bIsOpen = false;
619 6686 : bIsWritable = false;
620 6686 : SvStream::ClearBuffer();
621 6686 : SvStream::ClearError();
622 6686 : }
623 :
624 : /// set filepointer to beginning of file
625 67 : void SvFileStream::ResetError()
626 : {
627 67 : SvStream::ClearError();
628 67 : }
629 :
630 111 : void SvFileStream::SetSize (sal_Size nSize)
631 : {
632 111 : if (IsOpen())
633 : {
634 111 : oslFileError rc = osl_setFileSize( pInstanceData->rHandle, nSize );
635 111 : if (rc != osl_File_E_None )
636 : {
637 0 : SetError ( ::GetSvError( rc ));
638 : }
639 : }
640 111 : }
641 :
642 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|