| 1 |
/* |
| 2 |
* Copyright (c) 1999 |
| 3 |
* Silicon Graphics Computer Systems, Inc. |
| 4 |
* |
| 5 |
* Copyright (c) 1999 |
| 6 |
* Boris Fomitchev |
| 7 |
* |
| 8 |
* This material is provided "as is", with absolutely no warranty expressed |
| 9 |
* or implied. Any use is at your own risk. |
| 10 |
* |
| 11 |
* Permission to use or copy this software for any purpose is hereby granted |
| 12 |
* without fee, provided the above notices are retained on all copies. |
| 13 |
* Permission to modify the code and to distribute modified code is granted, |
| 14 |
* provided the above notices are retained, and a notice that the code was |
| 15 |
* modified is included with the above copyright notice. |
| 16 |
* |
| 17 |
*/ |
| 18 |
|
| 19 |
#include "stlport_prefix.h" |
| 20 |
|
| 21 |
#ifdef _STLP_USE_UNIX_IO |
| 22 |
# include "details/fstream_unistd.cpp" |
| 23 |
#elif defined(_STLP_USE_STDIO_IO) |
| 24 |
# include "details/fstream_stdio.cpp" |
| 25 |
#elif defined(_STLP_USE_WIN32_IO) |
| 26 |
# include "details/fstream_win32io.cpp" |
| 27 |
#else |
| 28 |
# error "Can't recognize IO scheme to use" |
| 29 |
#endif |
| 30 |
|
| 31 |
_STLP_BEGIN_NAMESPACE |
| 32 |
|
| 33 |
// fbp : let us map 1 MB maximum, just be sure not to trash VM |
| 34 |
#define MMAP_CHUNK 0x100000L |
| 35 |
|
| 36 |
_Underflow< char, char_traits<char> >::int_type _STLP_CALL |
| 37 |
_Underflow< char, char_traits<char> >::_M_doit(basic_filebuf<char, char_traits<char> >* __this) |
| 38 |
{ |
| 39 |
typedef char_traits<char> traits_type; |
| 40 |
typedef traits_type::int_type int_type; |
| 41 |
|
| 42 |
if ( (__this->int_flags_ & basic_filebuf<char, char_traits<char> >::_in_input_mode) == 0 ) { |
| 43 |
if ( !__this->_M_switch_to_input_mode() ) { |
| 44 |
return traits_type::eof(); |
| 45 |
} |
| 46 |
} else if ( __this->int_flags_ & basic_filebuf<char, char_traits<char> >::_in_putback_mode ) { |
| 47 |
__this->_M_exit_putback_mode(); |
| 48 |
if (__this->gptr() != __this->egptr()) { |
| 49 |
int_type __c = traits_type::to_int_type(*__this->gptr()); |
| 50 |
return __c; |
| 51 |
} |
| 52 |
} |
| 53 |
|
| 54 |
// If it's a disk file, and if the internal and external character |
| 55 |
// sequences are guaranteed to be identical, then try to use memory |
| 56 |
// mapped I/O. Otherwise, revert to ordinary read. |
| 57 |
if (__this->_M_base.__regular_file() |
| 58 |
&& ((__this->int_flags_ & basic_filebuf<char, char_traits<char> >::_always_noconv) != 0) |
| 59 |
&& __this->_M_base._M_in_binary_mode()) { |
| 60 |
// If we've mmapped part of the file already, then unmap it. |
| 61 |
if (__this->_M_mmap_base) |
| 62 |
__this->_M_base._M_unmap(__this->_M_mmap_base, __this->_M_mmap_len); |
| 63 |
|
| 64 |
// Determine the position where we start mapping. It has to be |
| 65 |
// a multiple of the page size. |
| 66 |
streamoff __cur = __this->_M_base._M_seek(0, ios_base::cur); |
| 67 |
streamoff __size = __this->_M_base._M_file_size(); |
| 68 |
if (__size > 0 && __cur >= 0 && __cur < __size) { |
| 69 |
streamoff __offset = (__cur / __this->_M_base.__page_size()) * __this->_M_base.__page_size(); |
| 70 |
streamoff __remainder = __cur - __offset; |
| 71 |
|
| 72 |
__this->_M_mmap_len = __size - __offset; |
| 73 |
|
| 74 |
if (__this->_M_mmap_len > MMAP_CHUNK) |
| 75 |
__this->_M_mmap_len = MMAP_CHUNK; |
| 76 |
|
| 77 |
if ((__this->_M_mmap_base = __this->_M_base._M_mmap(__offset, __this->_M_mmap_len)) != 0) { |
| 78 |
__this->setg(__STATIC_CAST(char*, __this->_M_mmap_base), |
| 79 |
__STATIC_CAST(char*, __this->_M_mmap_base) + __STATIC_CAST(ptrdiff_t, __remainder), |
| 80 |
__STATIC_CAST(char*, __this->_M_mmap_base) + __STATIC_CAST(ptrdiff_t, __this->_M_mmap_len)); |
| 81 |
return traits_type::to_int_type(*__this->gptr()); |
| 82 |
} |
| 83 |
else |
| 84 |
__this->_M_mmap_len = 0; |
| 85 |
} |
| 86 |
else { |
| 87 |
__this->_M_mmap_base = 0; |
| 88 |
__this->_M_mmap_len = 0; |
| 89 |
} |
| 90 |
} |
| 91 |
|
| 92 |
return __this->_M_underflow_aux(); |
| 93 |
} |
| 94 |
|
| 95 |
//---------------------------------------------------------------------- |
| 96 |
// Force instantiation of filebuf and fstream classes. |
| 97 |
#if !defined(_STLP_NO_FORCE_INSTANTIATE) |
| 98 |
|
| 99 |
template class basic_filebuf<char, char_traits<char> >; |
| 100 |
template class basic_ifstream<char, char_traits<char> >; |
| 101 |
template class basic_ofstream<char, char_traits<char> >; |
| 102 |
template class basic_fstream<char, char_traits<char> >; |
| 103 |
|
| 104 |
# if !defined (_STLP_NO_WCHAR_T) |
| 105 |
template class _Underflow<wchar_t, char_traits<wchar_t> >; |
| 106 |
template class basic_filebuf<wchar_t, char_traits<wchar_t> >; |
| 107 |
template class basic_ifstream<wchar_t, char_traits<wchar_t> >; |
| 108 |
template class basic_ofstream<wchar_t, char_traits<wchar_t> >; |
| 109 |
template class basic_fstream<wchar_t, char_traits<wchar_t> >; |
| 110 |
# endif /* _STLP_NO_WCHAR_T */ |
| 111 |
|
| 112 |
#endif |
| 113 |
|
| 114 |
_STLP_END_NAMESPACE |