1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: file.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sal.hxx"
36 #define _WIN32_WINNT 0x0500
37 #include "systools/win32/uwinapi.h"
39 #include "osl/file.hxx"
42 #include "file_error.h"
44 #include "osl/diagnose.h"
45 #include "rtl/alloc.h"
46 #include "rtl/byteseq.h"
47 #include "rtl/ustring.hxx"
60 #ifdef max /* conflict w/ std::numeric_limits<T>::max() */
67 //##################################################################
68 // File handle implementation
69 //##################################################################
70 struct FileHandle_Impl
78 STATE_SEEKABLE
= 1, /* open() sets, iff regular file */
79 STATE_READABLE
= 2, /* open() sets, read() requires */
80 STATE_WRITEABLE
= 4, /* open() sets, write() requires */
81 STATE_MODIFIED
= 8 /* write() sets, flush() resets */
85 sal_uInt64 m_size
; /* file size */
86 LONGLONG m_offset
; /* physical offset from begin of file */
87 LONGLONG m_filepos
; /* logical offset from begin of file */
89 LONGLONG m_bufptr
; /* buffer offset from begin of file */
90 SIZE_T m_buflen
; /* buffer filled [0, m_bufsiz - 1] */
95 explicit FileHandle_Impl (HANDLE hFile
);
98 static void* operator new(size_t n
);
99 static void operator delete(void * p
, size_t);
100 static SIZE_T
getpagesize();
102 sal_uInt64
getPos() const;
103 oslFileError
setPos (sal_uInt64 uPos
);
105 sal_uInt64
getSize() const;
106 oslFileError
setSize (sal_uInt64 uPos
);
108 oslFileError
readAt (
111 DWORD nBytesRequested
,
112 sal_uInt64
* pBytesRead
);
114 oslFileError
writeAt (
116 void const * pBuffer
,
118 sal_uInt64
* pBytesWritten
);
120 oslFileError
readFileAt (
123 sal_uInt64 uBytesRequested
,
124 sal_uInt64
* pBytesRead
);
126 oslFileError
writeFileAt (
128 void const * pBuffer
,
129 sal_uInt64 uBytesToWrite
,
130 sal_uInt64
* pBytesWritten
);
132 oslFileError
readLineAt (
134 sal_Sequence
** ppSequence
,
135 sal_uInt64
* pBytesRead
);
137 oslFileError
writeSequence_Impl (
138 sal_Sequence
** ppSequence
,
140 const void * pBuffer
,
143 oslFileError
syncFile();
145 /** Buffer cache / allocator.
149 rtl_cache_type
* m_cache
;
152 Allocator (Allocator
const &);
153 Allocator
& operator= (Allocator
const &);
156 static Allocator
& get();
158 void allocate (sal_uInt8
** ppBuffer
, SIZE_T
* pnSize
);
159 void deallocate (sal_uInt8
* pBuffer
);
167 FileHandle_Impl::Allocator
&
168 FileHandle_Impl::Allocator::get()
170 static Allocator g_aBufferAllocator
;
171 return g_aBufferAllocator
;
174 FileHandle_Impl::Allocator::Allocator()
178 SIZE_T
const pagesize
= FileHandle_Impl::getpagesize();
179 m_cache
= rtl_cache_create (
180 "osl_file_buffer_cache", pagesize
, 0, 0, 0, 0, 0, 0, 0);
185 FileHandle_Impl::Allocator::~Allocator()
187 rtl_cache_destroy(m_cache
), m_cache
= 0;
190 void FileHandle_Impl::Allocator::allocate (sal_uInt8
** ppBuffer
, SIZE_T
* pnSize
)
192 OSL_PRECOND((0 != ppBuffer
) && (0 != pnSize
), "FileHandle_Impl::Allocator::allocate(): contract violation");
193 *ppBuffer
= static_cast< sal_uInt8
* >(rtl_cache_alloc(m_cache
)), *pnSize
= m_bufsiz
;
196 void FileHandle_Impl::Allocator::deallocate (sal_uInt8
* pBuffer
)
199 rtl_cache_free (m_cache
, pBuffer
);
202 FileHandle_Impl::FileHandle_Impl(HANDLE hFile
)
204 m_state (STATE_READABLE
| STATE_WRITEABLE
),
213 Allocator::get().allocate (&m_buffer
, &m_bufsiz
);
215 memset (m_buffer
, 0, m_bufsiz
);
218 FileHandle_Impl::~FileHandle_Impl()
220 Allocator::get().deallocate (m_buffer
), m_buffer
= 0;
223 void * FileHandle_Impl::operator new(size_t n
)
225 return rtl_allocateMemory(n
);
228 void FileHandle_Impl::operator delete(void * p
, size_t)
233 SIZE_T
FileHandle_Impl::getpagesize()
236 ::GetSystemInfo (&info
);
237 return sal::static_int_cast
< SIZE_T
>(info
.dwPageSize
);
240 sal_uInt64
FileHandle_Impl::getPos() const
242 return sal::static_int_cast
< sal_uInt64
>(m_filepos
);
245 oslFileError
FileHandle_Impl::setPos (sal_uInt64 uPos
)
247 m_filepos
= sal::static_int_cast
< LONGLONG
>(uPos
);
248 return osl_File_E_None
;
251 sal_uInt64
FileHandle_Impl::getSize() const
253 LONGLONG bufend
= std::max((LONGLONG
)(0), m_bufptr
) + m_buflen
;
254 return std::max(m_size
, sal::static_int_cast
< sal_uInt64
>(bufend
));
257 oslFileError
FileHandle_Impl::setSize (sal_uInt64 uSize
)
259 LARGE_INTEGER nDstPos
; nDstPos
.QuadPart
= sal::static_int_cast
< LONGLONG
>(uSize
);
260 if (!::SetFilePointerEx(m_hFile
, nDstPos
, 0, FILE_BEGIN
))
261 return oslTranslateFileError( GetLastError() );
263 if (!::SetEndOfFile(m_hFile
))
264 return oslTranslateFileError( GetLastError() );
267 nDstPos
.QuadPart
= m_offset
;
268 if (!::SetFilePointerEx(m_hFile
, nDstPos
, 0, FILE_BEGIN
))
269 return oslTranslateFileError( GetLastError() );
271 return osl_File_E_None
;
274 oslFileError
FileHandle_Impl::readAt (
277 DWORD nBytesRequested
,
278 sal_uInt64
* pBytesRead
)
280 OSL_PRECOND(m_state
& STATE_SEEKABLE
, "FileHandle_Impl::readAt(): not seekable");
281 if (!(m_state
& STATE_SEEKABLE
))
282 return osl_File_E_SPIPE
;
284 OSL_PRECOND(m_state
& STATE_READABLE
, "FileHandle_Impl::readAt(): not readable");
285 if (!(m_state
& STATE_READABLE
))
286 return osl_File_E_BADF
;
288 if (nOffset
!= m_offset
)
290 LARGE_INTEGER liOffset
; liOffset
.QuadPart
= nOffset
;
291 if (!::SetFilePointerEx(m_hFile
, liOffset
, 0, FILE_BEGIN
))
292 return oslTranslateFileError( GetLastError() );
297 if (!::ReadFile(m_hFile
, pBuffer
, nBytesRequested
, &dwDone
, 0))
298 return oslTranslateFileError( GetLastError() );
301 *pBytesRead
= dwDone
;
302 return osl_File_E_None
;
305 oslFileError
FileHandle_Impl::writeAt (
307 void const * pBuffer
,
309 sal_uInt64
* pBytesWritten
)
311 OSL_PRECOND(m_state
& STATE_SEEKABLE
, "FileHandle_Impl::writeAt(): not seekable");
312 if (!(m_state
& STATE_SEEKABLE
))
313 return osl_File_E_SPIPE
;
315 OSL_PRECOND(m_state
& STATE_WRITEABLE
, "FileHandle_Impl::writeAt(): not writeable");
316 if (!(m_state
& STATE_WRITEABLE
))
317 return osl_File_E_BADF
;
319 if (nOffset
!= m_offset
)
321 LARGE_INTEGER liOffset
; liOffset
.QuadPart
= nOffset
;
322 if (!::SetFilePointerEx (m_hFile
, liOffset
, 0, FILE_BEGIN
))
323 return oslTranslateFileError( GetLastError() );
328 if (!::WriteFile(m_hFile
, pBuffer
, nBytesToWrite
, &dwDone
, 0))
329 return oslTranslateFileError( GetLastError() );
332 m_size
= std::max(m_size
, sal::static_int_cast
< sal_uInt64
>(m_offset
));
334 *pBytesWritten
= dwDone
;
335 return osl_File_E_None
;
338 oslFileError
FileHandle_Impl::readFileAt (
341 sal_uInt64 uBytesRequested
,
342 sal_uInt64
* pBytesRead
)
344 static sal_uInt64
const g_limit_dword
= std::numeric_limits
< DWORD
>::max();
345 if (g_limit_dword
< uBytesRequested
)
346 return osl_File_E_OVERFLOW
;
347 DWORD nBytesRequested
= sal::static_int_cast
< DWORD
>(uBytesRequested
);
349 if (0 == (m_state
& STATE_SEEKABLE
))
351 // not seekable (pipe)
353 if (!::ReadFile(m_hFile
, pBuffer
, nBytesRequested
, &dwDone
, 0))
354 return oslTranslateFileError( GetLastError() );
355 *pBytesRead
= dwDone
;
356 return osl_File_E_None
;
358 else if (0 == m_buffer
)
361 return readAt (nOffset
, pBuffer
, nBytesRequested
, pBytesRead
);
365 sal_uInt8
* buffer
= static_cast< sal_uInt8
* >(pBuffer
);
366 for (*pBytesRead
= 0; nBytesRequested
> 0; )
368 LONGLONG
const bufptr
= (nOffset
/ m_bufsiz
) * m_bufsiz
;
369 SIZE_T
const bufpos
= (nOffset
% m_bufsiz
);
371 if (bufptr
!= m_bufptr
)
373 // flush current buffer
374 oslFileError result
= syncFile();
375 if (result
!= osl_File_E_None
)
378 if (nBytesRequested
>= m_bufsiz
)
380 // buffer too small, read through from file
381 sal_uInt64 uDone
= 0;
382 result
= readAt (nOffset
, &(buffer
[*pBytesRead
]), nBytesRequested
, &uDone
);
383 if (result
!= osl_File_E_None
)
386 nBytesRequested
-= sal::static_int_cast
< DWORD
>(uDone
), *pBytesRead
+= uDone
;
387 return osl_File_E_None
;
390 // update buffer (pointer)
391 sal_uInt64 uDone
= 0;
392 result
= readAt (bufptr
, m_buffer
, m_bufsiz
, &uDone
);
393 if (result
!= osl_File_E_None
)
395 m_bufptr
= bufptr
, m_buflen
= sal::static_int_cast
< SIZE_T
>(uDone
);
397 if (bufpos
>= m_buflen
)
400 return osl_File_E_None
;
403 SIZE_T
const bytes
= std::min(m_buflen
- bufpos
, nBytesRequested
);
404 memcpy (&(buffer
[*pBytesRead
]), &(m_buffer
[bufpos
]), bytes
);
405 nBytesRequested
-= bytes
, *pBytesRead
+= bytes
, nOffset
+= bytes
;
407 return osl_File_E_None
;
411 oslFileError
FileHandle_Impl::writeFileAt (
413 void const * pBuffer
,
414 sal_uInt64 uBytesToWrite
,
415 sal_uInt64
* pBytesWritten
)
417 static sal_uInt64
const g_limit_dword
= std::numeric_limits
< DWORD
>::max();
418 if (g_limit_dword
< uBytesToWrite
)
419 return osl_File_E_OVERFLOW
;
420 DWORD nBytesToWrite
= sal::static_int_cast
< DWORD
>(uBytesToWrite
);
422 if (0 == (m_state
& STATE_SEEKABLE
))
424 // not seekable (pipe)
426 if (!::WriteFile(m_hFile
, pBuffer
, nBytesToWrite
, &dwDone
, 0))
427 return oslTranslateFileError( GetLastError() );
428 *pBytesWritten
= dwDone
;
429 return osl_File_E_None
;
431 else if (0 == m_buffer
)
434 return writeAt(nOffset
, pBuffer
, nBytesToWrite
, pBytesWritten
);
438 sal_uInt8
const * buffer
= static_cast< sal_uInt8
const* >(pBuffer
);
439 for (*pBytesWritten
= 0; nBytesToWrite
> 0; )
441 LONGLONG
const bufptr
= (nOffset
/ m_bufsiz
) * m_bufsiz
;
442 SIZE_T
const bufpos
= (nOffset
% m_bufsiz
);
443 if (bufptr
!= m_bufptr
)
445 // flush current buffer
446 oslFileError result
= syncFile();
447 if (result
!= osl_File_E_None
)
450 if (nBytesToWrite
>= m_bufsiz
)
452 // buffer too small, write through to file
453 sal_uInt64 uDone
= 0;
454 result
= writeAt (nOffset
, &(buffer
[*pBytesWritten
]), nBytesToWrite
, &uDone
);
455 if (result
!= osl_File_E_None
)
457 if (uDone
!= nBytesToWrite
)
458 return osl_File_E_IO
;
460 nBytesToWrite
-= sal::static_int_cast
< DWORD
>(uDone
), *pBytesWritten
+= uDone
;
461 return osl_File_E_None
;
464 // update buffer (pointer)
465 sal_uInt64 uDone
= 0;
466 result
= readAt (bufptr
, m_buffer
, m_bufsiz
, &uDone
);
467 if (result
!= osl_File_E_None
)
469 m_bufptr
= bufptr
, m_buflen
= sal::static_int_cast
< SIZE_T
>(uDone
);
472 SIZE_T
const bytes
= std::min(m_bufsiz
- bufpos
, nBytesToWrite
);
473 memcpy (&(m_buffer
[bufpos
]), &(buffer
[*pBytesWritten
]), bytes
);
474 nBytesToWrite
-= bytes
, *pBytesWritten
+= bytes
, nOffset
+= bytes
;
476 m_buflen
= std::max(m_buflen
, bufpos
+ bytes
);
477 m_state
|= STATE_MODIFIED
;
479 return osl_File_E_None
;
483 oslFileError
FileHandle_Impl::readLineAt (
485 sal_Sequence
** ppSequence
,
486 sal_uInt64
* pBytesRead
)
488 oslFileError result
= osl_File_E_None
;
490 LONGLONG bufptr
= (nOffset
/ m_bufsiz
) * m_bufsiz
;
491 if (bufptr
!= m_bufptr
)
493 /* flush current buffer */
495 if (result
!= osl_File_E_None
)
498 /* update buffer (pointer) */
499 sal_uInt64 uDone
= 0;
500 result
= readAt (bufptr
, m_buffer
, m_bufsiz
, &uDone
);
501 if (result
!= osl_File_E_None
)
504 m_bufptr
= bufptr
, m_buflen
= sal::static_int_cast
< SIZE_T
>(uDone
);
507 static int const LINE_STATE_BEGIN
= 0;
508 static int const LINE_STATE_CR
= 1;
509 static int const LINE_STATE_LF
= 2;
511 SIZE_T bufpos
= sal::static_int_cast
< SIZE_T
>(nOffset
- m_bufptr
), curpos
= bufpos
, dstpos
= 0;
512 int state
= (bufpos
>= m_buflen
) ? LINE_STATE_LF
: LINE_STATE_BEGIN
;
514 for ( ; state
!= LINE_STATE_LF
; )
516 if (curpos
>= m_buflen
)
518 /* buffer examined */
519 if (0 < (curpos
- bufpos
))
521 /* flush buffer to sequence */
522 result
= writeSequence_Impl (
523 ppSequence
, &dstpos
, &(m_buffer
[bufpos
]), curpos
- bufpos
);
524 if (result
!= osl_File_E_None
)
526 *pBytesRead
+= curpos
- bufpos
, nOffset
+= curpos
- bufpos
;
529 bufptr
= nOffset
/ m_bufsiz
* m_bufsiz
;
530 if (bufptr
!= m_bufptr
)
532 /* update buffer (pointer) */
533 sal_uInt64 uDone
= 0;
534 result
= readAt (bufptr
, m_buffer
, m_bufsiz
, &uDone
);
535 if (result
!= osl_File_E_None
)
537 m_bufptr
= bufptr
, m_buflen
= sal::static_int_cast
< SIZE_T
>(uDone
);
540 bufpos
= sal::static_int_cast
< SIZE_T
>(nOffset
- m_bufptr
), curpos
= bufpos
;
541 if (bufpos
>= m_buflen
)
547 state
= LINE_STATE_LF
;
548 switch (m_buffer
[curpos
])
550 case 0x0A: /* CRLF */
551 /* eat current char */
554 default: /* single CR */
555 /* keep current char */
560 /* determine next state */
561 switch (m_buffer
[curpos
])
563 case 0x0A: /* single LF */
564 state
= LINE_STATE_LF
;
567 state
= LINE_STATE_CR
;
569 default: /* advance to next char */
573 if (state
!= LINE_STATE_BEGIN
)
575 /* store (and eat) the newline char */
576 m_buffer
[curpos
] = 0x0A, curpos
++;
578 /* flush buffer to sequence */
579 result
= writeSequence_Impl (
580 ppSequence
, &dstpos
, &(m_buffer
[bufpos
]), curpos
- bufpos
- 1);
581 if (result
!= osl_File_E_None
)
583 *pBytesRead
+= curpos
- bufpos
, nOffset
+= curpos
- bufpos
;
589 result
= writeSequence_Impl (ppSequence
, &dstpos
, 0, 0);
590 if (result
!= osl_File_E_None
)
593 return osl_File_E_None
;
594 if (bufpos
>= m_buflen
)
595 return osl_File_E_AGAIN
;
596 return osl_File_E_None
;
599 oslFileError
FileHandle_Impl::writeSequence_Impl (
600 sal_Sequence
** ppSequence
,
602 const void * pBuffer
,
605 sal_Int32 nElements
= *pnOffset
+ nBytes
;
608 /* construct sequence */
609 rtl_byte_sequence_constructNoDefault(ppSequence
, nElements
);
611 else if (nElements
!= (*ppSequence
)->nElements
)
613 /* resize sequence */
614 rtl_byte_sequence_realloc(ppSequence
, nElements
);
616 if (*ppSequence
!= 0)
619 memcpy(&((*ppSequence
)->elements
[*pnOffset
]), pBuffer
, nBytes
), *pnOffset
+= nBytes
;
621 return (*ppSequence
!= 0) ? osl_File_E_None
: osl_File_E_NOMEM
;
624 oslFileError
FileHandle_Impl::syncFile()
626 oslFileError result
= osl_File_E_None
;
627 if (m_state
& STATE_MODIFIED
)
629 sal_uInt64 uDone
= 0;
630 result
= writeAt (m_bufptr
, m_buffer
, m_buflen
, &uDone
);
631 if (result
!= osl_File_E_None
)
633 if (uDone
!= m_buflen
)
634 return osl_File_E_IO
;
635 m_state
&= ~STATE_MODIFIED
;
640 //##################################################################
641 // File I/O functions
642 //##################################################################
644 extern "C" oslFileHandle
645 SAL_CALL
osl_createFileHandleFromOSHandle (
649 if ( !IsValidHandle(hFile
) )
652 FileHandle_Impl
* pImpl
= new FileHandle_Impl(hFile
);
656 (void) ::CloseHandle(hFile
);
660 /* check for regular file */
661 if (FILE_TYPE_DISK
== GetFileType(hFile
))
664 pImpl
->m_state
|= FileHandle_Impl::STATE_SEEKABLE
;
666 /* init current size */
667 LARGE_INTEGER uSize
= { 0, 0 };
668 (void) ::GetFileSizeEx(hFile
, &uSize
);
669 pImpl
->m_size
= (sal::static_int_cast
<sal_uInt64
>(uSize
.HighPart
) << 32) + uSize
.LowPart
;
672 if (!(uFlags
& osl_File_OpenFlag_Read
))
673 pImpl
->m_state
&= ~FileHandle_Impl::STATE_READABLE
;
674 if (!(uFlags
& osl_File_OpenFlag_Write
))
675 pImpl
->m_state
&= ~FileHandle_Impl::STATE_WRITEABLE
;
678 (uFlags
& osl_File_OpenFlag_Read
) || (uFlags
& osl_File_OpenFlag_Write
),
679 "osl_createFileHandleFromOSHandle(): missing read/write access flags");
680 return (oslFileHandle
)(pImpl
);
683 //#############################################
685 SAL_CALL
osl_openFile(
686 rtl_uString
* strPath
,
687 oslFileHandle
* pHandle
,
690 rtl_uString
* strSysPath
= 0;
691 oslFileError result
= _osl_getSystemPathFromFileURL( strPath
, &strSysPath
, sal_False
);
692 if (result
!= osl_File_E_None
)
695 DWORD dwAccess
= GENERIC_READ
, dwShare
= FILE_SHARE_READ
, dwCreation
= 0, dwAttributes
= 0;
697 if ( uFlags
& osl_File_OpenFlag_Write
)
698 dwAccess
|= GENERIC_WRITE
;
700 dwShare
|= FILE_SHARE_WRITE
;
702 if ( uFlags
& osl_File_OpenFlag_NoLock
)
703 dwShare
|= FILE_SHARE_WRITE
;
705 if ( uFlags
& osl_File_OpenFlag_Create
)
706 dwCreation
|= CREATE_NEW
;
708 dwCreation
|= OPEN_EXISTING
;
710 HANDLE hFile
= CreateFileW(
711 reinterpret_cast<LPCWSTR
>(rtl_uString_getStr( strSysPath
)),
712 dwAccess
, dwShare
, NULL
, dwCreation
, dwAttributes
, NULL
);
714 // @@@ ERROR HANDLING @@@
715 if ( !IsValidHandle( hFile
) )
716 result
= oslTranslateFileError( GetLastError() );
718 *pHandle
= osl_createFileHandleFromOSHandle (hFile
, uFlags
| osl_File_OpenFlag_Read
);
720 rtl_uString_release( strSysPath
);
724 //#############################################
726 SAL_CALL
osl_syncFile(oslFileHandle Handle
)
728 FileHandle_Impl
* pImpl
= static_cast<FileHandle_Impl
*>(Handle
);
729 if ((0 == pImpl
) || !IsValidHandle(pImpl
->m_hFile
))
730 return osl_File_E_INVAL
;
732 oslFileError result
= pImpl
->syncFile();
733 if (result
!= osl_File_E_None
)
736 if (!FlushFileBuffers(pImpl
->m_hFile
))
737 return oslTranslateFileError(GetLastError());
739 return osl_File_E_None
;
742 //#############################################
744 SAL_CALL
osl_closeFile(oslFileHandle Handle
)
746 FileHandle_Impl
* pImpl
= static_cast<FileHandle_Impl
*>(Handle
);
747 if ((0 == pImpl
) || !IsValidHandle(pImpl
->m_hFile
))
748 return osl_File_E_INVAL
;
750 oslFileError result
= pImpl
->syncFile();
751 if (result
!= osl_File_E_None
)
753 /* ignore double failure */
754 (void)::CloseHandle(pImpl
->m_hFile
);
756 else if (!::CloseHandle(pImpl
->m_hFile
))
758 /* translate error code */
759 result
= oslTranslateFileError( GetLastError() );
766 //#############################################
768 SAL_CALL
osl_mapFile(
769 oslFileHandle Handle
,
779 explicit FileMapping (HANDLE hMap
)
785 (void)::CloseHandle(m_handle
);
789 FileHandle_Impl
* pImpl
= static_cast<FileHandle_Impl
*>(Handle
);
790 if ((0 == pImpl
) || !IsValidHandle(pImpl
->m_hFile
) || (0 == ppAddr
))
791 return osl_File_E_INVAL
;
794 static SIZE_T
const nLimit
= std::numeric_limits
< SIZE_T
>::max();
795 if (uLength
> nLimit
)
796 return osl_File_E_OVERFLOW
;
797 SIZE_T
const nLength
= sal::static_int_cast
< SIZE_T
>(uLength
);
799 OSVERSIONINFO osinfo
;
800 osinfo
.dwOSVersionInfoSize
= sizeof(OSVERSIONINFO
);
801 (void)::GetVersionEx(&osinfo
);
803 if (VER_PLATFORM_WIN32_NT
!= osinfo
.dwPlatformId
)
804 return osl_File_E_NOSYS
; // Unsupported
806 FileMapping
aMap( ::CreateFileMapping (pImpl
->m_hFile
, NULL
, SEC_COMMIT
| PAGE_READONLY
, 0, 0, NULL
) );
807 if (!IsValidHandle(aMap
.m_handle
))
808 return oslTranslateFileError( GetLastError() );
810 DWORD
const dwOffsetHi
= sal::static_int_cast
<DWORD
>(uOffset
>> 32);
811 DWORD
const dwOffsetLo
= sal::static_int_cast
<DWORD
>(uOffset
& 0xFFFFFFFF);
813 *ppAddr
= ::MapViewOfFile( aMap
.m_handle
, FILE_MAP_READ
, dwOffsetHi
, dwOffsetLo
, nLength
);
815 return oslTranslateFileError( GetLastError() );
817 if (uFlags
& osl_File_MapFlag_RandomAccess
)
819 // Determine memory pagesize.
821 ::GetSystemInfo( &info
);
822 DWORD
const dwPageSize
= info
.dwPageSize
;
825 * Pagein, touching first byte of each memory page.
826 * Note: volatile disables optimizing the loop away.
828 BYTE
* pData (reinterpret_cast<BYTE
*>(*ppAddr
));
829 SIZE_T
nSize (nLength
);
832 while (nSize
> dwPageSize
)
845 return osl_File_E_None
;
848 //#############################################
850 SAL_CALL
osl_unmapFile(void* pAddr
, sal_uInt64
/* uLength */)
853 return osl_File_E_INVAL
;
855 if (!::UnmapViewOfFile (pAddr
))
856 return oslTranslateFileError( GetLastError() );
858 return osl_File_E_None
;
861 //#############################################
863 SAL_CALL
osl_readLine(
864 oslFileHandle Handle
,
865 sal_Sequence
** ppSequence
)
867 FileHandle_Impl
* pImpl
= static_cast<FileHandle_Impl
*>(Handle
);
868 if ((0 == pImpl
) || !IsValidHandle(pImpl
->m_hFile
) || (0 == ppSequence
))
869 return osl_File_E_INVAL
;
870 sal_uInt64 uBytesRead
= 0;
872 // read at current filepos; filepos += uBytesRead;
873 oslFileError result
= pImpl
->readLineAt (
874 pImpl
->m_filepos
, ppSequence
, &uBytesRead
);
875 if (result
== osl_File_E_None
)
876 pImpl
->m_filepos
+= uBytesRead
;
880 //#############################################
882 SAL_CALL
osl_readFile(
883 oslFileHandle Handle
,
885 sal_uInt64 uBytesRequested
,
886 sal_uInt64
* pBytesRead
)
888 FileHandle_Impl
* pImpl
= static_cast<FileHandle_Impl
*>(Handle
);
889 if ((0 == pImpl
) || !IsValidHandle(pImpl
->m_hFile
) || (0 == pBuffer
) || (0 == pBytesRead
))
890 return osl_File_E_INVAL
;
892 // read at current filepos; filepos += *pBytesRead;
893 oslFileError result
= pImpl
->readFileAt (
894 pImpl
->m_filepos
, pBuffer
, uBytesRequested
, pBytesRead
);
895 if (result
== osl_File_E_None
)
896 pImpl
->m_filepos
+= *pBytesRead
;
900 //#############################################
902 SAL_CALL
osl_writeFile(
903 oslFileHandle Handle
,
904 const void * pBuffer
,
905 sal_uInt64 uBytesToWrite
,
906 sal_uInt64
* pBytesWritten
)
908 FileHandle_Impl
* pImpl
= static_cast<FileHandle_Impl
*>(Handle
);
910 if ((0 == pImpl
) || !IsValidHandle(pImpl
->m_hFile
) || (0 == pBuffer
) || (0 == pBytesWritten
))
911 return osl_File_E_INVAL
;
913 // write at current filepos; filepos += *pBytesWritten;
914 oslFileError result
= pImpl
->writeFileAt (
915 pImpl
->m_filepos
, pBuffer
, uBytesToWrite
, pBytesWritten
);
916 if (result
== osl_File_E_None
)
917 pImpl
->m_filepos
+= *pBytesWritten
;
921 //#############################################
923 SAL_CALL
osl_readFileAt(
924 oslFileHandle Handle
,
927 sal_uInt64 uBytesRequested
,
928 sal_uInt64
* pBytesRead
)
930 FileHandle_Impl
* pImpl
= static_cast<FileHandle_Impl
*>(Handle
);
932 if ((0 == pImpl
) || !IsValidHandle(pImpl
->m_hFile
) || (0 == pBuffer
) || (0 == pBytesRead
))
933 return osl_File_E_INVAL
;
934 if (0 == (pImpl
->m_state
& FileHandle_Impl::STATE_SEEKABLE
))
935 return osl_File_E_SPIPE
;
937 static sal_uInt64
const g_limit_longlong
= std::numeric_limits
< LONGLONG
>::max();
938 if (g_limit_longlong
< uOffset
)
939 return osl_File_E_OVERFLOW
;
940 LONGLONG
const nOffset
= sal::static_int_cast
< LONGLONG
>(uOffset
);
942 // read at specified fileptr
943 return pImpl
->readFileAt (nOffset
, pBuffer
, uBytesRequested
, pBytesRead
);
946 //#############################################
948 SAL_CALL
osl_writeFileAt(
949 oslFileHandle Handle
,
952 sal_uInt64 uBytesToWrite
,
953 sal_uInt64
* pBytesWritten
)
955 FileHandle_Impl
* pImpl
= static_cast<FileHandle_Impl
*>(Handle
);
957 if ((0 == pImpl
) || !IsValidHandle(pImpl
->m_hFile
) || (0 == pBuffer
) || (0 == pBytesWritten
))
958 return osl_File_E_INVAL
;
959 if (0 == (pImpl
->m_state
& FileHandle_Impl::STATE_SEEKABLE
))
960 return osl_File_E_SPIPE
;
962 static sal_uInt64
const g_limit_longlong
= std::numeric_limits
< LONGLONG
>::max();
963 if (g_limit_longlong
< uOffset
)
964 return osl_File_E_OVERFLOW
;
965 LONGLONG
const nOffset
= sal::static_int_cast
< LONGLONG
>(uOffset
);
967 // write at specified fileptr
968 return pImpl
->writeFileAt (nOffset
, pBuffer
, uBytesToWrite
, pBytesWritten
);
971 //#############################################
973 SAL_CALL
osl_isEndOfFile (oslFileHandle Handle
, sal_Bool
*pIsEOF
)
975 FileHandle_Impl
* pImpl
= static_cast<FileHandle_Impl
*>(Handle
);
977 if ((0 == pImpl
) || !IsValidHandle(pImpl
->m_hFile
) || (0 == pIsEOF
))
978 return osl_File_E_INVAL
;
980 *pIsEOF
= (pImpl
->getPos() == pImpl
->getSize());
981 return osl_File_E_None
;
984 //#############################################
986 SAL_CALL
osl_getFilePos(oslFileHandle Handle
, sal_uInt64
*pPos
)
988 FileHandle_Impl
* pImpl
= static_cast<FileHandle_Impl
*>(Handle
);
989 if ((0 == pImpl
) || !IsValidHandle(pImpl
->m_hFile
) || (0 == pPos
))
990 return osl_File_E_INVAL
;
992 *pPos
= pImpl
->getPos();
993 return osl_File_E_None
;
996 //#############################################
998 SAL_CALL
osl_setFilePos(oslFileHandle Handle
, sal_uInt32 uHow
, sal_Int64 uOffset
)
1000 FileHandle_Impl
* pImpl
= static_cast<FileHandle_Impl
*>(Handle
);
1001 if ((0 == pImpl
) || !IsValidHandle(pImpl
->m_hFile
))
1002 return osl_File_E_INVAL
;
1004 static sal_Int64
const g_limit_longlong
= std::numeric_limits
< LONGLONG
>::max();
1005 if (g_limit_longlong
< uOffset
)
1006 return osl_File_E_OVERFLOW
;
1007 LONGLONG nPos
= 0, nOffset
= sal::static_int_cast
< LONGLONG
>(uOffset
);
1011 case osl_Pos_Absolut
:
1013 return osl_File_E_INVAL
;
1016 case osl_Pos_Current
:
1017 nPos
= sal::static_int_cast
< LONGLONG
>(pImpl
->getPos());
1018 if ((0 > nOffset
) && (-1*nOffset
> nPos
))
1019 return osl_File_E_INVAL
;
1020 if (g_limit_longlong
< nPos
+ nOffset
)
1021 return osl_File_E_OVERFLOW
;
1025 nPos
= sal::static_int_cast
< LONGLONG
>(pImpl
->getSize());
1026 if ((0 > nOffset
) && (-1*nOffset
> nPos
))
1027 return osl_File_E_INVAL
;
1028 if (g_limit_longlong
< nPos
+ nOffset
)
1029 return osl_File_E_OVERFLOW
;
1033 return osl_File_E_INVAL
;
1036 return pImpl
->setPos (nPos
+ nOffset
);
1039 //#############################################
1041 SAL_CALL
osl_getFileSize (oslFileHandle Handle
, sal_uInt64
*pSize
)
1043 FileHandle_Impl
* pImpl
= static_cast<FileHandle_Impl
*>(Handle
);
1045 if ((0 == pImpl
) || !IsValidHandle(pImpl
->m_hFile
) || (0 == pSize
))
1046 return osl_File_E_INVAL
;
1048 *pSize
= pImpl
->getSize();
1049 return osl_File_E_None
;
1052 //#############################################
1054 SAL_CALL
osl_setFileSize (oslFileHandle Handle
, sal_uInt64 uSize
)
1056 FileHandle_Impl
* pImpl
= static_cast<FileHandle_Impl
*>(Handle
);
1058 if ((0 == pImpl
) || !IsValidHandle(pImpl
->m_hFile
))
1059 return osl_File_E_INVAL
;
1060 if (0 == (pImpl
->m_state
& FileHandle_Impl::STATE_WRITEABLE
))
1061 return osl_File_E_BADF
;
1063 static sal_uInt64
const g_limit_longlong
= std::numeric_limits
< LONGLONG
>::max();
1064 if (g_limit_longlong
< uSize
)
1065 return osl_File_E_OVERFLOW
;
1067 oslFileError result
= pImpl
->syncFile();
1068 if (result
!= osl_File_E_None
)
1070 pImpl
->m_bufptr
= -1, pImpl
->m_buflen
= 0;
1072 return pImpl
->setSize (uSize
);
1075 //##################################################################
1076 // File handling functions
1077 //##################################################################
1079 //#############################################
1080 oslFileError SAL_CALL
osl_removeFile( rtl_uString
* strPath
)
1082 rtl_uString
*strSysPath
= NULL
;
1083 oslFileError error
= _osl_getSystemPathFromFileURL( strPath
, &strSysPath
, sal_False
);
1085 if ( osl_File_E_None
== error
)
1087 if ( DeleteFile( reinterpret_cast<LPCTSTR
>(rtl_uString_getStr( strSysPath
)) ) )
1088 error
= osl_File_E_None
;
1090 error
= oslTranslateFileError( GetLastError() );
1092 rtl_uString_release( strSysPath
);
1097 //#############################################
1098 #define osl_File_CopyRecursive 0x0001
1099 #define osl_File_CopyOverwrite 0x0002
1101 oslFileError SAL_CALL
osl_copyFile( rtl_uString
* strPath
, rtl_uString
*strDestPath
)
1103 rtl_uString
*strSysPath
= NULL
, *strSysDestPath
= NULL
;
1104 oslFileError error
= _osl_getSystemPathFromFileURL( strPath
, &strSysPath
, sal_False
);
1106 if ( osl_File_E_None
== error
)
1107 error
= _osl_getSystemPathFromFileURL( strDestPath
, &strSysDestPath
, sal_False
);
1109 if ( osl_File_E_None
== error
)
1111 LPCTSTR src
= reinterpret_cast<LPCTSTR
>(rtl_uString_getStr( strSysPath
));
1112 LPCTSTR dst
= reinterpret_cast<LPCTSTR
>(rtl_uString_getStr( strSysDestPath
));
1114 if ( CopyFile( src
, dst
, FALSE
) )
1115 error
= osl_File_E_None
;
1117 error
= oslTranslateFileError( GetLastError() );
1121 rtl_uString_release( strSysPath
);
1122 if ( strSysDestPath
)
1123 rtl_uString_release( strSysDestPath
);
1128 //#############################################
1129 oslFileError SAL_CALL
osl_moveFile( rtl_uString
* strPath
, rtl_uString
*strDestPath
)
1131 rtl_uString
*strSysPath
= NULL
, *strSysDestPath
= NULL
;
1132 oslFileError error
= _osl_getSystemPathFromFileURL( strPath
, &strSysPath
, sal_False
);
1134 if ( osl_File_E_None
== error
)
1135 error
= _osl_getSystemPathFromFileURL( strDestPath
, &strSysDestPath
, sal_False
);
1137 if ( osl_File_E_None
== error
)
1139 LPCTSTR src
= reinterpret_cast<LPCTSTR
>(rtl_uString_getStr( strSysPath
));
1140 LPCTSTR dst
= reinterpret_cast<LPCTSTR
>(rtl_uString_getStr( strSysDestPath
));
1142 if ( MoveFileEx( src
, dst
, MOVEFILE_COPY_ALLOWED
| MOVEFILE_WRITE_THROUGH
| MOVEFILE_REPLACE_EXISTING
) )
1143 error
= osl_File_E_None
;
1145 error
= oslTranslateFileError( GetLastError() );
1149 rtl_uString_release( strSysPath
);
1150 if ( strSysDestPath
)
1151 rtl_uString_release( strSysDestPath
);