genericopenlibs/cppstdlib/stl/src/fstream.cpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /*
       
     2  * Portions Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
       
     3  *
       
     4  * Copyright (c) 1999
       
     5  * Silicon Graphics Computer Systems, Inc.
       
     6  *
       
     7  * Copyright (c) 1999
       
     8  * Boris Fomitchev
       
     9  *
       
    10  * This material is provided "as is", with absolutely no warranty expressed
       
    11  * or implied. Any use is at your own risk.
       
    12  *
       
    13  * Permission to use or copy this software for any purpose is hereby granted
       
    14  * without fee, provided the above notices are retained on all copies.
       
    15  * Permission to modify the code and to distribute modified code is granted,
       
    16  * provided the above notices are retained, and a notice that the code was
       
    17  * modified is included with the above copyright notice.
       
    18  *
       
    19  */
       
    20 
       
    21 
       
    22 #include "stlport_prefix.h"
       
    23 
       
    24 #if defined  (__SUNPPRO_CC)  && !defined (_STLP_NO_NEW_C_HEADERS)
       
    25 #  include <time.h>
       
    26 // For sunpro, it chokes if time.h is included through stat.h
       
    27 #endif
       
    28 
       
    29 #include <fstream>
       
    30 
       
    31 #ifdef __CYGWIN__
       
    32 #  define __int64 long long
       
    33 #endif
       
    34 
       
    35 #if defined (_STLP_USE_UNIX_IO)
       
    36 extern "C" {
       
    37 // open/close/read/write
       
    38 #  include <sys/stat.h>           // For stat
       
    39 #  if !defined (_CRAY) && ! defined (__EMX__)
       
    40 #    include <sys/mman.h>           // For mmap
       
    41 #  endif
       
    42 
       
    43 //  on HP-UX 11, this one contradicts with pthread.h on pthread_atfork, unless we unset this
       
    44 #  if defined (__hpux) && defined (__GNUC__)
       
    45 #    undef _INCLUDE_POSIX1C_SOURCE
       
    46 #  endif
       
    47 
       
    48 #  include <unistd.h>
       
    49 #  include <fcntl.h>
       
    50 }
       
    51 #  ifdef __APPLE__
       
    52 #    include <sys/sysctl.h>
       
    53 #  endif
       
    54 #elif defined (_STLP_USE_WIN32_IO)
       
    55 #  define WIN32_LEAN_AND_MEAN
       
    56 #  include <windows.h>
       
    57 
       
    58 #  ifdef __BORLANDC__
       
    59 #      include <cfcntl.h>            // For _O_RDONLY, etc
       
    60 #    include <sys/stat.h>         // For _fstat
       
    61 #  elif !defined(_STLP_WCE)
       
    62 #    include <io.h>               // For _get_osfhandle
       
    63 #    include <fcntl.h>            // For _O_RDONLY, etc
       
    64 #    include <sys/stat.h>         // For _fstat
       
    65 #  endif
       
    66 #  define _TEXTBUF_SIZE 0x1000
       
    67 #elif defined (_STLP_USE_UNIX_EMULATION_IO)
       
    68 #  if defined( __MSL__ )
       
    69 #    include <unistd.h>
       
    70 #  else
       
    71 #    include <io.h>
       
    72 #  endif
       
    73 #  include <fcntl.h>
       
    74 #  include <sys/stat.h>
       
    75 #elif defined (_STLP_USE_STDIO_IO)
       
    76 #  include <cstdio>
       
    77 #  if !(defined(__MRC__) || defined(__SC__) || defined(__ISCPP__) )
       
    78 extern "C" {
       
    79 #    include <sys/stat.h>
       
    80 }
       
    81 #  endif
       
    82 #  if defined( __MSL__ )
       
    83 #    include <unix.h>
       
    84 #  endif
       
    85 #  if defined(__ISCPP__)
       
    86 #    include <c_locale_is/filestat.h>
       
    87 #  endif
       
    88 #  if (defined(__BEOS__) && defined(__INTEL__)) || defined (__SYMBIAN32__)
       
    89 #    include <fcntl.h>
       
    90 #    include <sys/stat.h>         // For _fstat
       
    91 #    define _S_IREAD S_IREAD
       
    92 #    define _S_IWRITE S_IWRITE
       
    93 #    define _S_IFREG S_IFREG
       
    94 #  endif
       
    95 #else
       
    96 #  error "Configure i/o !"
       
    97 #endif
       
    98 
       
    99 #if defined (_STLP_USE_WIN32_IO)
       
   100 const _STLP_fd INVALID_STLP_FD = INVALID_HANDLE_VALUE;
       
   101 #  if !defined (INVALID_SET_FILE_POINTER)
       
   102 #    define INVALID_SET_FILE_POINTER 0xffffffff
       
   103 #  endif
       
   104 #elif defined (_STLP_USE_UNIX_EMULATION_IO) || defined (_STLP_USE_STDIO_IO) || defined (_STLP_USE_UNIX_IO)
       
   105 const _STLP_fd INVALID_STLP_FD = -1;
       
   106 #else
       
   107 #  error "Configure i/o !"
       
   108 #endif
       
   109 
       
   110 // map permission masks
       
   111 #if defined (_STLP_USE_UNIX_EMULATION_IO) || defined (_STLP_USE_STDIO_IO)
       
   112 #  ifndef S_IRUSR
       
   113 #    define S_IRUSR _S_IREAD
       
   114 #    define S_IWUSR _S_IWRITE
       
   115 #    define S_IRGRP _S_IREAD
       
   116 #    define S_IWGRP _S_IWRITE
       
   117 #    define S_IROTH _S_IREAD
       
   118 #    define S_IWOTH _S_IWRITE
       
   119 #  endif
       
   120 #  ifndef O_RDONLY
       
   121 #    define O_RDONLY _O_RDONLY
       
   122 #    define O_WRONLY _O_WRONLY
       
   123 #    define O_RDWR   _O_RDWR
       
   124 #    define O_APPEND _O_APPEND
       
   125 #    define O_CREAT  _O_CREAT
       
   126 #    define O_TRUNC  _O_TRUNC
       
   127 #    define O_TEXT   _O_TEXT
       
   128 #    define O_BINARY _O_BINARY
       
   129 #  endif
       
   130 
       
   131 #  ifdef __MSL__
       
   132 #    define _O_TEXT 0x0
       
   133 #    if !defined( O_TEXT )
       
   134 #      define O_TEXT _O_TEXT
       
   135 #    endif
       
   136 #    define _S_IFREG S_IFREG
       
   137 #    define S_IREAD        S_IRUSR
       
   138 #    define S_IWRITE       S_IWUSR
       
   139 #    define S_IEXEC        S_IXUSR
       
   140 #    define _S_IWRITE S_IWRITE
       
   141 #    define _S_IREAD S_IREAD
       
   142 #    define _open open
       
   143 #    define _lseek lseek
       
   144 #    define _close close
       
   145 #    define _read read
       
   146 #    define _write write
       
   147 #  endif
       
   148 #endif
       
   149 
       
   150 #ifndef O_ACCMODE
       
   151 #  define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
       
   152 #endif
       
   153 
       
   154 #include "fstream_impl.h"
       
   155 
       
   156 #ifdef _STLP_LONG_LONG
       
   157 #  define ULL(x) ((unsigned _STLP_LONG_LONG)x)
       
   158 #elif defined(__MRC__) || defined(__SC__)    //*TY 02/25/2000 - added support for MPW compilers
       
   159 #  include <Math64.h>
       
   160 #  define ULL(x) (U64SetU(x))
       
   161 #elif defined(__ISCPP__)
       
   162 #  include "uint64.h"
       
   163 #elif defined(__SYMBIAN32__)
       
   164 #  include <sys/types.h>
       
   165 #else
       
   166 #  error "there should be some long long type on the system!"
       
   167 #endif
       
   168 
       
   169 
       
   170 #if defined(__SYMBIAN32__WSD__) 
       
   171 # include "libstdcppwsd.h"
       
   172 
       
   173 _STLP_DECLSPEC size_t& get_fstream_Filebuf_Base_GetPageSize()
       
   174 {
       
   175 	return get_libcpp_wsd().fstream_Filebuf_base_M_page_size;
       
   176 }
       
   177 
       
   178 void filebuf_page_size_init()
       
   179 {
       
   180 	get_fstream_Filebuf_Base_GetPageSize() = 4096;	
       
   181 }
       
   182 #endif
       
   183 
       
   184 _STLP_BEGIN_NAMESPACE
       
   185 // Compare with streamoff definition in stl/char_traits.h!
       
   186 
       
   187 #ifdef _STLP_USE_DEFAULT_FILE_OFFSET
       
   188 #  define FOPEN fopen
       
   189 #  define FSEEK fseek
       
   190 #  define FSTAT fstat
       
   191 #  define STAT  stat
       
   192 #  define FTELL ftell
       
   193 #  define LSEEK lseek
       
   194 #  define MMAP  mmap
       
   195 #  define OPEN  open
       
   196 #elif defined(_LARGEFILE_SOURCE) || defined(_LARGEFILE64_SOURCE) /* || defined(__USE_FILE_OFFSET64) */ \
       
   197       /* || (defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)) */ /* || defined(__sgi) */
       
   198 #  define FOPEN fopen64
       
   199 #  define FSEEK fseeko64
       
   200 #  define FSTAT fstat64
       
   201 #  define STAT  stat64
       
   202 #  define FTELL ftello64
       
   203 #  define LSEEK lseek64
       
   204 #  define MMAP  mmap64
       
   205 #  define OPEN  open64
       
   206 #else
       
   207 #  define OPEN  open
       
   208 #  define FSEEK fseek
       
   209 #  define FSTAT fstat
       
   210 #  define STAT  stat
       
   211 #  define FTELL ftell
       
   212 #  define LSEEK lseek
       
   213 #  define MMAP  mmap
       
   214 #  define OPEN  open
       
   215 #endif
       
   216 #ifdef _STLP_USE_UNIX_IO
       
   217 #  ifndef MAP_FAILED /* MMAP failure return code */
       
   218 #    define MAP_FAILED -1
       
   219 #  endif
       
   220 #elif defined (_STLP_USE_UNIX_EMULATION_IO)
       
   221 #  define LSEEK _lseek
       
   222 #endif
       
   223 
       
   224 #if !defined(__MSL__) && !defined(__MRC__) && !defined(__SC__) && !defined(_STLP_WCE)    //*TY 04/15/2000 - exclude mpw compilers also
       
   225 static ios_base::openmode flag_to_openmode(int mode) {
       
   226   ios_base::openmode ret = ios_base::__default_mode;
       
   227 
       
   228   switch(mode & O_ACCMODE) {
       
   229   case O_RDONLY:
       
   230     ret = ios_base::in; break;
       
   231   case O_WRONLY:
       
   232     ret = ios_base::out; break;
       
   233   case O_RDWR:
       
   234     ret = ios_base::in | ios_base::out; break;
       
   235   }
       
   236 
       
   237   if (mode & O_APPEND)
       
   238     ret |= ios_base::app;
       
   239 
       
   240 #  if defined (_STLP_USE_WIN32_IO)
       
   241   if (mode & O_BINARY)
       
   242     ret |= ios_base::binary;
       
   243 #  endif
       
   244 
       
   245   return ret;
       
   246 }
       
   247 #endif /* MSL */
       
   248 
       
   249 _STLP_MOVE_TO_PRIV_NAMESPACE
       
   250 
       
   251 // Helper functions for _Filebuf_base.
       
   252 
       
   253 bool __is_regular_file(_STLP_fd fd) {
       
   254 
       
   255 #if defined (_STLP_UNIX)
       
   256 
       
   257   struct STAT buf;
       
   258   return FSTAT(fd, &buf) == 0 && S_ISREG(buf.st_mode);
       
   259 
       
   260 #elif defined(__MRC__) || defined(__SC__)    //*TY 02/25/2000 - added support for MPW compilers
       
   261 
       
   262 #  pragma unused(fd)
       
   263   return true;  // each file is a regular file under mac os, isn't it? (we don't have fstat())
       
   264 
       
   265 #elif defined(_STLP_USE_UNIX_EMULATION_IO) || defined (_STLP_USE_STDIO_IO)
       
   266 
       
   267   struct STAT buf;
       
   268   return FSTAT(fd, &buf) == 0 && (buf.st_mode & _S_IFREG) != 0 ;
       
   269 
       
   270 #elif defined (_STLP_USE_WIN32_IO) && !defined(_STLP_WCE)
       
   271 
       
   272   return (GetFileType(fd) & ~FILE_TYPE_REMOTE) == FILE_TYPE_DISK;
       
   273 
       
   274 #else
       
   275   (void)fd;    // dwa 4/27/00 - suppress unused parameter warning
       
   276   return false;
       
   277 #endif
       
   278 }
       
   279 
       
   280 // Number of characters in the file.
       
   281 streamoff __file_size(_STLP_fd fd) {
       
   282   streamoff ret = 0;
       
   283 
       
   284 #if defined (_STLP_UNIX)
       
   285 
       
   286   struct STAT buf;
       
   287   if (FSTAT(fd, &buf) == 0 && S_ISREG(buf.st_mode))
       
   288     ret = buf.st_size > 0 ? buf.st_size : 0;
       
   289 
       
   290 #elif defined(__MRC__) || defined(__SC__)    //*TY 02/25/2000 - added support for MPW compilers
       
   291 
       
   292 #  pragma unused(fd)
       
   293 
       
   294 #elif defined(_STLP_USE_UNIX_EMULATION_IO) || defined (_STLP_USE_STDIO_IO)
       
   295 
       
   296   struct STAT buf;
       
   297   if (FSTAT(fd, &buf) == 0 && (buf.st_mode & _S_IFREG) != 0)
       
   298     ret = buf.st_size > 0 ? buf.st_size : 0;
       
   299 
       
   300 #elif defined (_STLP_USE_WIN32_IO)
       
   301 
       
   302  LARGE_INTEGER li;
       
   303  li.LowPart = GetFileSize(fd, (unsigned long*) &li.HighPart);
       
   304  if (li.LowPart != INVALID_FILE_SIZE || GetLastError() == NO_ERROR)
       
   305    ret = li.QuadPart;
       
   306 
       
   307 #else
       
   308   (void)fd;    // dwa 4/27/00 - suppress unused parameter warning
       
   309 #endif
       
   310   return ret;
       
   311 }
       
   312 
       
   313 _STLP_MOVE_TO_STD_NAMESPACE
       
   314 
       
   315 // Visual C++ and Intel use this, but not Metrowerks
       
   316 // Also MinGW, msvcrt.dll (but not crtdll.dll) dependent version
       
   317 #if (!defined (__MSL__) && !defined (_STLP_WCE) && defined (_STLP_MSVC_LIB) && defined (_WIN32)) || \
       
   318     (defined (__MINGW32__) && defined (__MSVCRT__) && !(defined (__SYMBIAN32__) && defined(__GCCXML__)) )
       
   319 
       
   320 // fcntl(fileno, F_GETFL) for Microsoft library
       
   321 // 'semi-documented' defines:
       
   322 #  define IOINFO_L2E          5
       
   323 #  define IOINFO_ARRAY_ELTS   (1 << IOINFO_L2E)
       
   324 #  define _pioinfo(i) ( __pioinfo[(i) >> IOINFO_L2E] + \
       
   325               ((i) & (IOINFO_ARRAY_ELTS - 1)) )
       
   326 #  define FAPPEND         0x20    // O_APPEND flag
       
   327 #  define FTEXT           0x80    // O_TEXT flag
       
   328 // end of 'semi-documented' defines
       
   329 
       
   330 // 'semi-documented' internal structure
       
   331 extern "C" {
       
   332   struct ioinfo {
       
   333     long osfhnd;    // the real os HANDLE
       
   334     char osfile;    // file handle flags
       
   335     char pipech;    // pipe buffer
       
   336 #  if defined (_MT)
       
   337     // multi-threaded locking
       
   338     int lockinitflag;
       
   339     CRITICAL_SECTION lock;
       
   340 #  endif  /* _MT */
       
   341   };
       
   342 #  if defined (__MINGW32__)
       
   343  __MINGW_IMPORT ioinfo * __pioinfo[];
       
   344 #  else
       
   345   extern _CRTIMP ioinfo * __pioinfo[];
       
   346 #  endif
       
   347 } // extern "C"
       
   348 // end of 'semi-documented' declarations
       
   349 
       
   350 static ios_base::openmode _get_osfflags(int fd, HANDLE oshandle) {
       
   351   char dosflags = 0;
       
   352   if (fd >= 0)
       
   353     dosflags = _pioinfo(fd)->osfile;
       
   354   //else
       
   355     //the file will be considered as open in binary mode with no append attribute
       
   356   // end of 'semi-documented' stuff
       
   357 
       
   358   int mode = 0;
       
   359   if (dosflags & FAPPEND)
       
   360     mode |= O_APPEND;
       
   361 
       
   362   if (dosflags & FTEXT)
       
   363     mode |= O_TEXT;
       
   364   else
       
   365     mode |= O_BINARY;
       
   366 
       
   367   // For Read/Write access we have to guess
       
   368   DWORD dummy, dummy2;
       
   369   BOOL writeOk = WriteFile(oshandle, &dummy2, 0, &dummy, 0);
       
   370   BOOL readOk = ReadFile(oshandle, &dummy2, 0, &dummy, NULL);
       
   371   if (writeOk && readOk)
       
   372     mode |= O_RDWR;
       
   373   else if (readOk)
       
   374     mode |= O_RDONLY;
       
   375   else
       
   376     mode |= O_WRONLY;
       
   377 
       
   378   return flag_to_openmode(mode);
       
   379 }
       
   380 
       
   381 #elif defined (__DMC__)
       
   382 
       
   383 #  define FHND_APPEND 0x04
       
   384 #  define FHND_DEVICE 0x08
       
   385 #  define FHND_TEXT   0x10
       
   386 
       
   387 extern "C" unsigned char __fhnd_info[_NFILE];
       
   388 
       
   389 static ios_base::openmode _get_osfflags(int fd, HANDLE oshandle) {
       
   390   int mode = 0;
       
   391 
       
   392   if (__fhnd_info[fd] & FHND_APPEND)
       
   393     mode |= O_APPEND;
       
   394 
       
   395   if (__fhnd_info[fd] & FHND_TEXT == 0)
       
   396     mode |= O_BINARY;
       
   397 
       
   398   for (FILE *fp = &_iob[0]; fp < &_iob[_NFILE]; fp++) {
       
   399     if ((fileno(fp) == fd) && (fp->_flag & (_IOREAD | _IOWRT | _IORW))) {
       
   400       const int osflags = fp->_flag;
       
   401 
       
   402       if ((osflags & _IOREAD) && !(osflags & _IOWRT) && !(osflags & _IORW))
       
   403         mode |= O_RDONLY;
       
   404       else if ((osflags & _IOWRT) && !(osflags & _IOREAD) && !(osflags & _IORW))
       
   405         mode |= O_WRONLY;
       
   406       else
       
   407         mode |= O_RDWR;
       
   408       break;
       
   409     }
       
   410   }
       
   411 
       
   412   return flag_to_openmode(mode);
       
   413 }
       
   414 #endif
       
   415 
       
   416 #if !defined(__SYMBIAN32__WSD__)
       
   417 size_t _Filebuf_base::_M_page_size = 4096;
       
   418 #endif //__SYMBIAN32__WSD__
       
   419 
       
   420 _STLP_DECLSPEC _Filebuf_base::_Filebuf_base()
       
   421   : _M_file_id(INVALID_STLP_FD),
       
   422 #if defined (_STLP_USE_WIN32_IO)
       
   423     _M_view_id(0),
       
   424 #endif
       
   425     _M_openmode(0),
       
   426     _M_is_open(false),
       
   427     _M_should_close(false)
       
   428 {}
       
   429 
       
   430 void _Filebuf_base::_S_initialize() {
       
   431 #if defined (_STLP_UNIX)  && !defined (__DJGPP) && !defined (_CRAY)
       
   432 #  if defined (__APPLE__)
       
   433   int mib[2];
       
   434   size_t pagesize, len;
       
   435   mib[0] = CTL_HW;
       
   436   mib[1] = HW_PAGESIZE;
       
   437   len = sizeof(pagesize);
       
   438   sysctl(mib, 2, &pagesize, &len, NULL, 0);
       
   439   _M_page_size = pagesize;
       
   440 #  elif defined (__DJGPP) && defined (_CRAY)
       
   441   _M_page_size = BUFSIZ;
       
   442 #  else
       
   443   _M_page_size = sysconf(_SC_PAGESIZE);
       
   444 #  endif
       
   445 #elif defined (_STLP_USE_WIN32_IO)
       
   446   SYSTEM_INFO SystemInfo;
       
   447   GetSystemInfo(&SystemInfo);
       
   448   _M_page_size = SystemInfo.dwPageSize;
       
   449   // might be .dwAllocationGranularity
       
   450 #endif
       
   451 }
       
   452 
       
   453 // Return the size of the file.  This is a wrapper for stat.
       
   454 // Returns zero if the size cannot be determined or is ill-defined.
       
   455 _STLP_DECLSPEC streamoff _Filebuf_base::_M_file_size() {
       
   456   return _STLP_PRIV __file_size(_M_file_id);
       
   457 }
       
   458 
       
   459 _STLP_DECLSPEC bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode,
       
   460                             long permission) {
       
   461   _STLP_fd file_no;
       
   462 
       
   463   if (_M_is_open)
       
   464     return false;
       
   465 
       
   466 #if defined (_STLP_USE_UNIX_IO) || defined (_STLP_USE_UNIX_EMULATION_IO)
       
   467   int flags = 0;
       
   468 
       
   469   // Unix makes no distinction between text and binary files.
       
   470   switch(openmode & (~ios_base::ate & ~ios_base::binary)) {
       
   471   case ios_base::out:
       
   472   case ios_base::out | ios_base::trunc:
       
   473     flags = O_WRONLY | O_CREAT | O_TRUNC;
       
   474     break;
       
   475   case ios_base::out | ios_base::app:
       
   476     flags = O_WRONLY | O_CREAT | O_APPEND;
       
   477     break;
       
   478   case ios_base::in:
       
   479     flags = O_RDONLY;
       
   480     permission = 0;             // Irrelevant unless we're writing.
       
   481     break;
       
   482   case ios_base::in | ios_base::out:
       
   483     flags = O_RDWR;
       
   484     break;
       
   485   case ios_base::in | ios_base::out | ios_base::trunc:
       
   486     flags = O_RDWR | O_CREAT | O_TRUNC;
       
   487     break;
       
   488   default:                      // The above are the only combinations of
       
   489     return false;               // flags allowed by the C++ standard.
       
   490   }
       
   491 
       
   492 #  if defined (_STLP_USE_UNIX_EMULATION_IO)
       
   493   if (openmode & ios_base::binary)
       
   494     flags |= O_BINARY;
       
   495   else
       
   496     flags |= O_TEXT;
       
   497 
       
   498   file_no = _open(name, flags, permission);
       
   499 #  else
       
   500   file_no = OPEN(name, flags, permission);
       
   501 #  endif /* _STLP_USE_UNIX_EMULATION_IO */
       
   502 
       
   503   if (file_no < 0)
       
   504     return false;
       
   505 
       
   506   _M_is_open = true;
       
   507 
       
   508   if (openmode & ios_base::ate)
       
   509     if (LSEEK(file_no, 0, SEEK_END) == -1)
       
   510       _M_is_open = false;
       
   511 
       
   512 #elif defined (_STLP_USE_STDIO_IO)
       
   513   // use FILE-based i/o
       
   514   const char* flags;
       
   515 
       
   516   switch(openmode & (~ios_base::ate)) {
       
   517   case ios_base::out:
       
   518   case ios_base::out | ios_base::trunc:
       
   519     flags = "w";
       
   520     break;
       
   521 
       
   522   case ios_base::out | ios_base::binary:
       
   523   case ios_base::out | ios_base::trunc | ios_base::binary:
       
   524     flags = "wb";
       
   525     break;
       
   526 
       
   527   case ios_base::out | ios_base::app:
       
   528     flags = "a";
       
   529     break;
       
   530 
       
   531   case ios_base::out | ios_base::app | ios_base::binary:
       
   532     flags = "ab";
       
   533     break;
       
   534 
       
   535   case ios_base::in:
       
   536     flags = "r";
       
   537     break;
       
   538 
       
   539   case ios_base::in | ios_base::binary:
       
   540     flags = "rb";
       
   541     break;
       
   542 
       
   543   case ios_base::in | ios_base::out:
       
   544     flags = "r+";
       
   545     break;
       
   546 
       
   547   case ios_base::in | ios_base::out | ios_base::binary:
       
   548     flags = "r+b";
       
   549     break;
       
   550 
       
   551 
       
   552   case ios_base::in | ios_base::out | ios_base::trunc:
       
   553     flags = "w+";
       
   554     break;
       
   555 
       
   556   case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
       
   557     flags = "w+b";
       
   558     break;
       
   559 
       
   560   default:                      // The above are the only combinations of
       
   561     return false;               // flags allowed by the C++ standard.
       
   562   }
       
   563 
       
   564   // fbp :  : set permissions !
       
   565   (void)permission; // currently unused    //*TY 02/26/2000 - added to suppress warning message
       
   566   _M_file = FOPEN(name, flags);
       
   567 
       
   568   if (_M_file) {
       
   569     file_no = fileno(_M_file);
       
   570   }
       
   571   else
       
   572     return false;
       
   573 
       
   574   // unset buffering immediately
       
   575   setbuf(_M_file, 0);
       
   576 
       
   577   _M_is_open = true;
       
   578 
       
   579   if (openmode & ios_base::ate) {
       
   580     if (FSEEK(_M_file, 0, SEEK_END) == -1)
       
   581       _M_is_open = false;
       
   582   }
       
   583 
       
   584 #elif defined (_STLP_USE_WIN32_IO)
       
   585   DWORD dwDesiredAccess, dwCreationDisposition;
       
   586   bool doTruncate = false;
       
   587 
       
   588   switch (openmode & (~ios_base::ate & ~ios_base::binary)) {
       
   589   case ios_base::out:
       
   590   case ios_base::out | ios_base::trunc:
       
   591     dwDesiredAccess = GENERIC_WRITE;
       
   592     dwCreationDisposition = OPEN_ALWAYS;
       
   593     // boris : even though it is very non-intuitive, standard
       
   594     // requires them both to behave same.
       
   595     doTruncate = true;
       
   596     break;
       
   597   case ios_base::out | ios_base::app:
       
   598     dwDesiredAccess = GENERIC_WRITE;
       
   599     dwCreationDisposition = OPEN_ALWAYS;
       
   600     break;
       
   601   case ios_base::in:
       
   602     dwDesiredAccess = GENERIC_READ;
       
   603     dwCreationDisposition = OPEN_EXISTING;
       
   604     permission = 0;             // Irrelevant unless we're writing.
       
   605     break;
       
   606   case ios_base::in | ios_base::out:
       
   607     dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
       
   608     dwCreationDisposition = OPEN_EXISTING;
       
   609     break;
       
   610   case ios_base::in | ios_base::out | ios_base::trunc:
       
   611     dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
       
   612     dwCreationDisposition = OPEN_ALWAYS;
       
   613     doTruncate = true;
       
   614     break;
       
   615   default:                      // The above are the only combinations of
       
   616     return false;               // flags allowed by the C++ standard.
       
   617   }
       
   618 
       
   619   DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
       
   620 
       
   621 #  if defined(_STLP_USE_WIDE_INTERFACE)
       
   622     file_no = CreateFile (_STLP_PRIV __ASCIIToWide(name).c_str(),
       
   623 #  else
       
   624     file_no = CreateFileA(name,
       
   625 #  endif
       
   626                           dwDesiredAccess, dwShareMode, 0,
       
   627                           dwCreationDisposition, permission, 0);
       
   628 
       
   629   if (file_no == INVALID_STLP_FD)
       
   630     return false;
       
   631 
       
   632   if ((doTruncate && SetEndOfFile(file_no) == 0) ||
       
   633       (((openmode & ios_base::ate) != 0) &&
       
   634        (SetFilePointer(file_no, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER))) {
       
   635     CloseHandle(file_no);
       
   636     return false;
       
   637   }
       
   638 
       
   639   _M_is_open = true;
       
   640 
       
   641 #else
       
   642 #  error "Port!"
       
   643 #endif /* __unix */
       
   644 
       
   645   _M_file_id = file_no;
       
   646   _M_should_close = _M_is_open;
       
   647   _M_openmode = openmode;
       
   648 
       
   649   if (_M_is_open)
       
   650     _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id);
       
   651 
       
   652   return (_M_is_open != 0);
       
   653 }
       
   654 
       
   655 
       
   656 _STLP_DECLSPEC bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode) {
       
   657   // This doesn't really grant everyone in the world read/write
       
   658   // access.  On Unix, file-creation system calls always clear
       
   659   // bits that are set in the umask from the permissions flag.
       
   660 #ifdef _STLP_USE_WIN32_IO
       
   661   return this->_M_open(name, openmode, FILE_ATTRIBUTE_NORMAL);
       
   662 #elif defined(__MRC__) || defined(__SC__)    //*TY 02/26/2000 - added support for MPW compilers
       
   663   return this->_M_open(name, openmode, 0);
       
   664 #else
       
   665   return this->_M_open(name, openmode, S_IRUSR | S_IWUSR | S_IRGRP |
       
   666                                        S_IWGRP | S_IROTH | S_IWOTH);
       
   667 #endif
       
   668 }
       
   669 
       
   670 
       
   671 #if defined (_STLP_USE_WIN32_IO)
       
   672 bool _Filebuf_base::_M_open(_STLP_fd __id, ios_base::openmode init_mode) {
       
   673 #  if (defined (_STLP_MSVC_LIB) && !defined (_STLP_WCE)) || \
       
   674       (defined (__MINGW32__) && defined (__MSVCRT__)) || defined (__DMC__)
       
   675 
       
   676   if (_M_is_open || __id == INVALID_STLP_FD)
       
   677     return false;
       
   678 
       
   679   if (init_mode != ios_base::__default_mode)
       
   680     _M_openmode = init_mode;
       
   681   else
       
   682     _M_openmode = _get_osfflags(-1, __id);
       
   683 
       
   684   _M_is_open = true;
       
   685   _M_file_id = __id;
       
   686   _M_should_close = false;
       
   687   _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id);
       
   688 
       
   689   return true;
       
   690 #  else
       
   691   (void)__id;
       
   692   (void)init_mode;    // dwa 4/27/00 - suppress unused parameter warning
       
   693 
       
   694   // not available for the API
       
   695   return false;
       
   696 
       
   697 #  endif
       
   698 }
       
   699 #endif /* _STLP_USE_WIN32_IO */
       
   700 
       
   701 // Associated the filebuf with a file descriptor pointing to an already-
       
   702 // open file.  Mode is set to be consistent with the way that the file
       
   703 // was opened.
       
   704 _STLP_DECLSPEC bool _Filebuf_base::_M_open(int file_no, ios_base::openmode init_mode) {
       
   705   if (_M_is_open || file_no < 0)
       
   706     return false;
       
   707 
       
   708 #if defined (_STLP_UNIX)
       
   709   (void)init_mode;    // dwa 4/27/00 - suppress unused parameter warning
       
   710   int mode ;
       
   711   mode = fcntl(file_no, F_GETFL);
       
   712 
       
   713   if (mode == -1)
       
   714     return false;
       
   715 
       
   716   _M_openmode = flag_to_openmode(mode);
       
   717   _M_file_id = file_no;
       
   718 #elif defined(__MRC__) || defined(__SC__)    //*TY 02/26/2000 - added support for MPW compilers
       
   719   (void)init_mode;    // dwa 4/27/00 - suppress unused parameter warning
       
   720   switch (_iob[file_no]._flag & (_IOREAD|_IOWRT|_IORW) )
       
   721   {
       
   722   case _IOREAD:
       
   723     _M_openmode = ios_base::in; break;
       
   724   case _IOWRT:
       
   725     _M_openmode = ios_base::out; break;
       
   726   case _IORW:
       
   727     _M_openmode = ios_base::in | ios_base::out; break;
       
   728   default:
       
   729     return false;
       
   730   }
       
   731   _M_file_id = file_no;
       
   732 #elif defined (_STLP_USE_UNIX_EMULATION_IO) || defined (_STLP_USE_STDIO_IO)
       
   733   (void)init_mode;    // dwa 4/27/00 - suppress unused parameter warning
       
   734   int mode ;
       
   735   struct STAT buf;
       
   736   if (FSTAT(file_no, &buf) != 0)
       
   737     return false;
       
   738   mode = buf.st_mode;
       
   739 
       
   740   switch(mode & (_S_IWRITE | _S_IREAD) ) {
       
   741   case _S_IREAD:
       
   742     _M_openmode = ios_base::in; break;
       
   743   case _S_IWRITE:
       
   744     _M_openmode = ios_base::out; break;
       
   745   case (_S_IWRITE | _S_IREAD):
       
   746     _M_openmode = ios_base::in | ios_base::out; break;
       
   747   default:
       
   748     return false;
       
   749   }
       
   750   _M_file_id = file_no;
       
   751 #elif (defined (_STLP_USE_WIN32_IO) && defined (_STLP_MSVC_LIB) && !defined (_STLP_WCE) ) || \
       
   752       (defined (__MINGW32__) && defined (__MSVCRT__)) || \
       
   753        defined (__DMC__)
       
   754 
       
   755   HANDLE oshandle = (HANDLE)_get_osfhandle(file_no);
       
   756   if (oshandle == INVALID_STLP_FD)
       
   757     return false;
       
   758 
       
   759   if (init_mode != ios_base::__default_mode)
       
   760     _M_openmode = init_mode;
       
   761   else
       
   762     _M_openmode = _get_osfflags(file_no, oshandle);
       
   763 
       
   764   _M_file_id = oshandle;
       
   765 #else
       
   766   (void)init_mode;    // dwa 4/27/00 - suppress unused parameter warning
       
   767   // not available for the API
       
   768 #  define _STLP_NO_IMPLEMENTATION
       
   769 #endif
       
   770 
       
   771 #if !defined (_STLP_NO_IMPLEMENTATION)
       
   772   _M_is_open = true;
       
   773   _M_should_close = false;
       
   774   _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id);
       
   775   return true;
       
   776 #else
       
   777 #  undef _STLP_NO_IMPLEMENTATION
       
   778   return false;
       
   779 #endif
       
   780 }
       
   781 
       
   782 _STLP_DECLSPEC bool _Filebuf_base::_M_close() {
       
   783   if (!_M_is_open)
       
   784     return false;
       
   785 
       
   786   bool ok;
       
   787 
       
   788   if (!_M_should_close)
       
   789     ok = true;
       
   790   else {
       
   791 
       
   792 #if defined (_STLP_USE_UNIX_IO)
       
   793 
       
   794     ok = (close(_M_file_id) == 0);
       
   795 
       
   796 #elif defined (_STLP_USE_UNIX_EMULATION_IO)
       
   797 
       
   798     ok = (_close(_M_file_id) == 0);
       
   799 
       
   800 #elif defined (_STLP_USE_STDIO_IO)
       
   801 
       
   802     ok = (fclose(_M_file) == 0);
       
   803 
       
   804 #elif defined (_STLP_USE_WIN32_IO)
       
   805 
       
   806     if (_M_file_id != INVALID_STLP_FD) {
       
   807       ok = (CloseHandle(_M_file_id) != 0);
       
   808     }
       
   809     else {
       
   810       ok = false;
       
   811     }
       
   812 
       
   813 #else
       
   814 
       
   815     ok = false;
       
   816 
       
   817 #endif /* _STLP_USE_UNIX_IO */
       
   818   }
       
   819 
       
   820   _M_is_open = _M_should_close = false;
       
   821   _M_openmode = 0;
       
   822   return ok;
       
   823 }
       
   824 
       
   825 
       
   826 #define _STLP_LF 10
       
   827 #define _STLP_CR 13
       
   828 #define _STLP_CTRLZ 26
       
   829 
       
   830 // Read up to n characters into a buffer.  Return value is number of
       
   831 // characters read.
       
   832 _STLP_DECLSPEC ptrdiff_t _Filebuf_base::_M_read(char* buf, ptrdiff_t n) {
       
   833 #if defined (_STLP_USE_UNIX_IO)
       
   834 
       
   835   return read(_M_file_id, buf, n);
       
   836 
       
   837 #elif defined (_STLP_USE_UNIX_EMULATION_IO)
       
   838 
       
   839   return _read(_M_file_id, buf, n);
       
   840 
       
   841 #elif defined (_STLP_USE_WIN32_IO)
       
   842   ptrdiff_t readen = 0;
       
   843   //Here cast to size_t is safe as n cannot be negative.
       
   844   size_t chunkSize = (min)(size_t(0xffffffff), __STATIC_CAST(size_t, n));
       
   845   // The following, while validating that we are still able to extract chunkSize
       
   846   // charaters to the buffer, avoids extraction of too small chunk of datas
       
   847   // which would be counter performant.
       
   848   while (__STATIC_CAST(size_t, (n - readen)) >= chunkSize) {
       
   849     DWORD NumberOfBytesRead;
       
   850     ReadFile(_M_file_id, buf + readen, __STATIC_CAST(DWORD, chunkSize), &NumberOfBytesRead, 0);
       
   851 
       
   852     if (NumberOfBytesRead == 0)
       
   853       break;
       
   854 
       
   855     if (!(_M_openmode & ios_base::binary)) {
       
   856       // translate CR-LFs to LFs in the buffer
       
   857       char *to = buf + readen;
       
   858       char *from = to;
       
   859       char *last = from + NumberOfBytesRead - 1;
       
   860       for (; from <= last && *from != _STLP_CTRLZ; ++from) {
       
   861         if (*from != _STLP_CR)
       
   862           *to++ = *from;
       
   863         else { // found CR
       
   864           if (from < last) { // not at buffer end
       
   865             if (*(from + 1) != _STLP_LF)
       
   866               *to++ = _STLP_CR;
       
   867           }
       
   868           else { // last char is CR, peek for LF
       
   869             char peek = ' ';
       
   870             DWORD NumberOfBytesPeeked;
       
   871             ReadFile(_M_file_id, (LPVOID)&peek, 1, &NumberOfBytesPeeked, 0);
       
   872             if (NumberOfBytesPeeked != 0) {
       
   873               if (peek != _STLP_LF) { //not a <CR><LF> combination
       
   874                 *to++ = _STLP_CR;
       
   875                 if ((to < buf + n) && (peek != _STLP_CR))
       
   876                   //We have enough place to store peek and it is no a special
       
   877                   //_STLP_CR character, we can store it.
       
   878                   *to++ = peek;
       
   879                 else
       
   880                   SetFilePointer(_M_file_id, (LONG)-1, 0, SEEK_CUR);
       
   881               }
       
   882               else {
       
   883                 // A <CR><LF> combination, we keep the <LF>:
       
   884                 *to++ = _STLP_LF;
       
   885               }
       
   886             }
       
   887             else {
       
   888               /* This case is tedious, we could
       
   889                *  - put peek back in the file but this would then generate an infinite loop
       
   890                *  - report an error as we don't know if in a future call to ReadFile we won't then
       
   891                *    get a <LF>. Doing so would make all files with a <CR> last an invalid file
       
   892                *    for STLport, a hard solution for STLport clients.
       
   893                *  - store the <CR> in the returned buffer, the chosen solution, even if in this
       
   894                *    case we could miss a <CR><LF> combination.
       
   895                */
       
   896               *to++ = _STLP_CR;
       
   897             }
       
   898           }
       
   899         } // found CR
       
   900       } // for
       
   901       // seek back to TEXT end of file if hit CTRL-Z
       
   902       if (from <= last) // terminated due to CTRLZ
       
   903         SetFilePointer(_M_file_id, (LONG)((last+1) - from), 0, SEEK_CUR);
       
   904       readen += to - (buf + readen);
       
   905     }
       
   906     else
       
   907       readen += NumberOfBytesRead;
       
   908   }
       
   909   return readen;
       
   910 
       
   911 #elif defined (_STLP_USE_STDIO_IO)
       
   912 
       
   913   return fread(buf, 1, n, _M_file);
       
   914 
       
   915 #else
       
   916 #  error "Port!"
       
   917 #endif /* __unix */
       
   918 }
       
   919 
       
   920 // Write n characters from a buffer.  Return value: true if we managed
       
   921 // to write the entire buffer, false if we didn't.
       
   922 _STLP_DECLSPEC bool _Filebuf_base::_M_write(char* buf, ptrdiff_t n) {
       
   923   for (;;) {
       
   924     ptrdiff_t written;
       
   925 
       
   926 #if defined (_STLP_USE_UNIX_IO)
       
   927 
       
   928     written = write(_M_file_id, buf, n);
       
   929 
       
   930 #elif defined (_STLP_USE_UNIX_EMULATION_IO)
       
   931 
       
   932     written = _write(_M_file_id, buf, n);
       
   933 
       
   934 #elif defined (_STLP_USE_WIN32_IO)
       
   935 
       
   936     //In the following implementation we are going to cast most of the ptrdiff_t
       
   937     //values in size_t to work with coherent unsigned values. Doing so make code
       
   938     //more simple especially in the min function call.
       
   939 
       
   940     // In append mode, every write does an implicit seek to the end
       
   941     // of the file.
       
   942     if (_M_openmode & ios_base::app)
       
   943       _M_seek(0, ios_base::end);
       
   944 
       
   945     if (_M_openmode & ios_base::binary) {
       
   946       // binary mode
       
   947       size_t bytes_to_write = (size_t)n;
       
   948       DWORD NumberOfBytesWritten;
       
   949       written = 0;
       
   950       for (; bytes_to_write != 0;) {
       
   951         WriteFile(_M_file_id, buf + written,
       
   952                   __STATIC_CAST(DWORD, (min)(size_t(0xffffffff), bytes_to_write)),
       
   953                   &NumberOfBytesWritten, 0);
       
   954         if (NumberOfBytesWritten == 0)
       
   955           return false;
       
   956         bytes_to_write -= NumberOfBytesWritten;
       
   957         written += NumberOfBytesWritten;
       
   958       }
       
   959     }
       
   960     else {
       
   961       char textbuf[_TEXTBUF_SIZE + 1]; // extra 1 in case LF at end
       
   962       char * nextblock = buf, * ptrtextbuf = textbuf;
       
   963       char * endtextbuf = textbuf + _TEXTBUF_SIZE;
       
   964       char * endblock = buf + n;
       
   965       ptrdiff_t nextblocksize = (min) (n, (ptrdiff_t)_TEXTBUF_SIZE);
       
   966       char * nextlf;
       
   967 
       
   968       while ( (nextblocksize > 0) &&
       
   969               (nextlf = (char *)memchr(nextblock, _STLP_LF, nextblocksize)) != 0) {
       
   970         ptrdiff_t linelength = nextlf - nextblock;
       
   971         memcpy(ptrtextbuf, nextblock, linelength);
       
   972         ptrtextbuf += linelength;
       
   973         nextblock += (linelength + 1);
       
   974         * ptrtextbuf ++ = _STLP_CR;
       
   975         * ptrtextbuf ++ = _STLP_LF;
       
   976         nextblocksize = (min) (ptrdiff_t(endblock - nextblock),
       
   977                                (max) (ptrdiff_t(0), ptrdiff_t(endtextbuf - ptrtextbuf)));
       
   978       }
       
   979       // write out what's left, > condition is here since for LF at the end ,
       
   980       // endtextbuf may get < ptrtextbuf ...
       
   981       if (nextblocksize > 0) {
       
   982         memcpy(ptrtextbuf, nextblock, nextblocksize);
       
   983         ptrtextbuf += nextblocksize;
       
   984         nextblock += nextblocksize;
       
   985       }
       
   986       // now write out the translated buffer
       
   987       char * writetextbuf = textbuf;
       
   988       for (size_t NumberOfBytesToWrite = (size_t)(ptrtextbuf - textbuf);
       
   989            NumberOfBytesToWrite;) {
       
   990         DWORD NumberOfBytesWritten;
       
   991         WriteFile((HANDLE)_M_file_id, writetextbuf,
       
   992                   __STATIC_CAST(DWORD, (min)(size_t(0xffffffff), NumberOfBytesToWrite)),
       
   993                   &NumberOfBytesWritten, 0);
       
   994         if (!NumberOfBytesWritten) // write shortfall
       
   995           return false;
       
   996         writetextbuf += NumberOfBytesWritten;
       
   997         NumberOfBytesToWrite -= NumberOfBytesWritten;
       
   998       }
       
   999       // count non-translated characters
       
  1000       written = (nextblock - buf);
       
  1001     }
       
  1002 
       
  1003 #elif defined (_STLP_USE_STDIO_IO)
       
  1004 
       
  1005     written = fwrite(buf, 1, n, _M_file);
       
  1006 
       
  1007 #else
       
  1008 #  error "Port!"
       
  1009 #endif /* __unix */
       
  1010 
       
  1011     if (n == written)
       
  1012       return true;
       
  1013     else if (written > 0 && written < n) {
       
  1014       n -= written;
       
  1015       buf += written;
       
  1016     }
       
  1017     else
       
  1018       return false;
       
  1019   }
       
  1020 }
       
  1021 
       
  1022 
       
  1023 #ifdef _STLP_USE_WIN32_IO
       
  1024 #  define STL_SEEK_SET FILE_BEGIN
       
  1025 #  define STL_SEEK_CUR FILE_CURRENT
       
  1026 #  define STL_SEEK_END FILE_END
       
  1027 #else
       
  1028 #  define STL_SEEK_SET SEEK_SET
       
  1029 #  define STL_SEEK_CUR SEEK_CUR
       
  1030 #  define STL_SEEK_END SEEK_END
       
  1031 #endif
       
  1032 
       
  1033 // Wrapper for lseek or the like.
       
  1034 _STLP_DECLSPEC streamoff _Filebuf_base::_M_seek(streamoff offset, ios_base::seekdir dir) {
       
  1035   streamoff result = -1;
       
  1036   int whence;
       
  1037 
       
  1038   switch(dir) {
       
  1039   case ios_base::beg:
       
  1040     if (offset < 0 /* || offset > _M_file_size() */ )
       
  1041       return streamoff(-1);
       
  1042     whence = STL_SEEK_SET;
       
  1043     break;
       
  1044   case ios_base::cur:
       
  1045     whence = STL_SEEK_CUR;
       
  1046     break;
       
  1047   case ios_base::end:
       
  1048     if (/* offset > 0 || */  -offset > _M_file_size() )
       
  1049       return streamoff(-1);
       
  1050     whence = STL_SEEK_END;
       
  1051     break;
       
  1052   default:
       
  1053     return streamoff(-1);
       
  1054   }
       
  1055 
       
  1056 #if defined (_STLP_USE_UNIX_IO) || defined (_STLP_USE_UNIX_EMULATION_IO)
       
  1057 
       
  1058   result = LSEEK(_M_file_id, offset, whence);
       
  1059 
       
  1060 #elif defined (_STLP_USE_STDIO_IO)
       
  1061 
       
  1062 #if defined (__SYMBIAN32__)
       
  1063   /* This function is a wrapper for lseek and expects to return the offset in bytes from the beginning of the file. 
       
  1064     It is used by tellg as well as tellp (for setting/getting the file pointer). 
       
  1065     We don't want to use fseek for that. */
       
  1066   if (FSEEK(_M_file, offset, whence) != 0)
       
  1067 	  return streamoff(-1);
       
  1068 	result = FTELL(_M_file);
       
  1069 #else
       
  1070   result = FSEEK(_M_file, offset, whence);
       
  1071 #endif
       
  1072 
       
  1073 #elif defined (_STLP_USE_WIN32_IO)
       
  1074 
       
  1075   LARGE_INTEGER li;
       
  1076   li.QuadPart = offset;
       
  1077   li.LowPart = SetFilePointer(_M_file_id, li.LowPart, &li.HighPart, whence);
       
  1078   if (li.LowPart != INVALID_SET_FILE_POINTER || GetLastError() == NO_ERROR)
       
  1079     result = li.QuadPart;
       
  1080 
       
  1081 #else
       
  1082 #  error "Port!"
       
  1083 #endif
       
  1084 
       
  1085   return result;
       
  1086 }
       
  1087 
       
  1088 
       
  1089 // Attempts to memory-map len bytes of the current file, starting
       
  1090 // at position offset.  Precondition: offset is a multiple of the
       
  1091 // page size.  Postcondition: return value is a null pointer if the
       
  1092 // memory mapping failed.  Otherwise the return value is a pointer to
       
  1093 // the memory-mapped file and the file position is set to offset.
       
  1094 _STLP_DECLSPEC void* _Filebuf_base::_M_mmap(streamoff offset, streamoff len) {
       
  1095   void* base;
       
  1096 #if defined (_STLP_UNIX) && !defined(__DJGPP) && !defined(_CRAY)
       
  1097   base = MMAP(0, len, PROT_READ, MAP_PRIVATE, _M_file_id, offset);
       
  1098   if (base != (void*)MAP_FAILED) {
       
  1099     if (LSEEK(_M_file_id, offset + len, SEEK_SET) < 0) {
       
  1100       this->_M_unmap(base, len);
       
  1101       base = 0;
       
  1102     }
       
  1103   } else
       
  1104     base =0;
       
  1105 
       
  1106 #elif defined (_STLP_USE_WIN32_IO)
       
  1107   _M_view_id = CreateFileMapping(_M_file_id, (PSECURITY_ATTRIBUTES)0 ,
       
  1108                                  PAGE_READONLY, 0 /* len >> 32 */ ,
       
  1109                                  0 /* len & 0xFFFFFFFF */ , // low-order DWORD of size
       
  1110                                  0);
       
  1111 
       
  1112   if (_M_view_id) {
       
  1113 #  if 0
       
  1114 /*
       
  1115     printf("view %x created from file %x, error = %d, size = %d, map_offset = %d map_len = %d\n",
       
  1116      _M_view_id, _M_file_id, GetLastError(),
       
  1117      (int)cur_filesize, ULL(offset) & 0xffffffff, len);
       
  1118 */
       
  1119 #  endif
       
  1120     base = MapViewOfFile(_M_view_id, FILE_MAP_READ, __STATIC_CAST(DWORD, ULL(offset) >> 32),
       
  1121                          __STATIC_CAST(DWORD, ULL(offset) & 0xffffffff),
       
  1122 #  if !defined (__DMC__)
       
  1123                          __STATIC_CAST(SIZE_T, len));
       
  1124 #  else
       
  1125                          __STATIC_CAST(DWORD, len));
       
  1126 #  endif
       
  1127     // check if mapping succeded and is usable
       
  1128     if (base == 0  || _M_seek(offset + len, ios_base::beg) < 0) {
       
  1129       this->_M_unmap(base, len);
       
  1130       base = 0;
       
  1131     }
       
  1132   } else
       
  1133     base = 0;
       
  1134 #else
       
  1135   (void)len;    //*TY 02/26/2000 - unused variables
       
  1136   (void)offset;    //*TY 02/26/2000 -
       
  1137   base = 0;
       
  1138 #endif
       
  1139   return base;
       
  1140 }
       
  1141 
       
  1142 _STLP_DECLSPEC void _Filebuf_base::_M_unmap(void* base, streamoff len) {
       
  1143   // precondition : there is a valid mapping at the moment
       
  1144 #if defined (_STLP_UNIX)  && !defined(__DJGPP) && !defined(_CRAY)
       
  1145   munmap((char*)base, len);
       
  1146 #elif defined (_STLP_USE_WIN32_IO)
       
  1147   if (base != NULL)
       
  1148     UnmapViewOfFile(base);
       
  1149   // destroy view handle as well
       
  1150   if (_M_view_id != NULL)
       
  1151     CloseHandle(_M_view_id);
       
  1152   _M_view_id = NULL;
       
  1153   (void)len; //unused variable
       
  1154 #else
       
  1155   (void)len;    //*TY 02/26/2000 - unused variables
       
  1156   (void)base;   //*TY 02/26/2000 -
       
  1157 #endif
       
  1158 }
       
  1159 
       
  1160 #if defined (__SYMBIAN32__) && defined(__EPOC32__)
       
  1161 _STLP_DECLSPEC size_t _Filebuf_base::__page_size()
       
  1162 {
       
  1163 	return _Filebuf_base::_M_page_size;
       
  1164 }
       
  1165 #endif
       
  1166 // fbp : let us map 1 MB maximum, just be sure not to trash VM
       
  1167 #define MMAP_CHUNK 0x100000L
       
  1168 
       
  1169 _STLP_DECLSPEC int _STLP_CALL
       
  1170 _Underflow<char, char_traits<char> >::_M_doit (basic_filebuf<char, char_traits<char> >* __this) {
       
  1171   if (!__this->_M_in_input_mode) {
       
  1172     if (!__this->_M_switch_to_input_mode())
       
  1173       return traits_type::eof();
       
  1174   }
       
  1175   else if (__this->_M_in_putback_mode) {
       
  1176     __this->_M_exit_putback_mode();
       
  1177     if (__this->gptr() != __this->egptr()) {
       
  1178       int_type __c = traits_type::to_int_type(*__this->gptr());
       
  1179       return __c;
       
  1180     }
       
  1181   }
       
  1182 
       
  1183   // If it's a disk file, and if the internal and external character
       
  1184   // sequences are guaranteed to be identical, then try to use memory
       
  1185   // mapped I/O.  Otherwise, revert to ordinary read.
       
  1186   if (__this->_M_base.__regular_file()
       
  1187       && __this->_M_always_noconv
       
  1188       && __this->_M_base._M_in_binary_mode()) {
       
  1189     // If we've mmapped part of the file already, then unmap it.
       
  1190     if (__this->_M_mmap_base)
       
  1191       __this->_M_base._M_unmap(__this->_M_mmap_base, __this->_M_mmap_len);
       
  1192     __this->_M_mmap_base = 0;
       
  1193     __this->_M_mmap_len = 0;
       
  1194 
       
  1195     // Determine the position where we start mapping.  It has to be
       
  1196     // a multiple of the page size.
       
  1197     streamoff __cur = __this->_M_base._M_seek(0, ios_base::cur);
       
  1198     streamoff __size = __this->_M_base._M_file_size();
       
  1199     if (__size > 0 && __cur >= 0 && __cur < __size) {
       
  1200       streamoff __offset = (__cur / __this->_M_base.__page_size()) * __this->_M_base.__page_size();
       
  1201       streamoff __remainder = __cur - __offset;
       
  1202 
       
  1203       __this->_M_mmap_len = __size - __offset;
       
  1204 
       
  1205       if (__this->_M_mmap_len > MMAP_CHUNK)
       
  1206         __this->_M_mmap_len = MMAP_CHUNK;
       
  1207 
       
  1208       if ((__this->_M_mmap_base =
       
  1209         __this->_M_base._M_mmap(__offset, __this->_M_mmap_len)) != 0) {
       
  1210         __this->setg((char*) __this->_M_mmap_base,
       
  1211                      (char*) __this->_M_mmap_base + __STATIC_CAST(ptrdiff_t, __remainder),
       
  1212                      (char*) __this->_M_mmap_base + __STATIC_CAST(ptrdiff_t, __this->_M_mmap_len));
       
  1213         return traits_type::to_int_type(*__this->gptr());
       
  1214       }
       
  1215     } else /* size > 0 ... */ {
       
  1216       // There is nothing to map. We unmapped the file above, now zap pointers.
       
  1217       __this->_M_mmap_base = 0;
       
  1218       __this->_M_mmap_len = 0;
       
  1219     }
       
  1220   }
       
  1221 
       
  1222   return __this->_M_underflow_aux();
       
  1223 }
       
  1224 
       
  1225 
       
  1226 //----------------------------------------------------------------------
       
  1227 // Force instantiation of filebuf and fstream classes.
       
  1228 #if !defined(_STLP_NO_FORCE_INSTANTIATE)
       
  1229 
       
  1230 template class basic_filebuf<char, char_traits<char> >;
       
  1231 template class basic_ifstream<char, char_traits<char> >;
       
  1232 template class basic_ofstream<char, char_traits<char> >;
       
  1233 template class basic_fstream<char, char_traits<char> >;
       
  1234 
       
  1235 #  if !defined (_STLP_NO_WCHAR_T)
       
  1236 template class _Underflow<wchar_t, char_traits<wchar_t> >;
       
  1237 template class basic_filebuf<wchar_t, char_traits<wchar_t> >;
       
  1238 template class basic_ifstream<wchar_t, char_traits<wchar_t> >;
       
  1239 template class basic_ofstream<wchar_t, char_traits<wchar_t> >;
       
  1240 template class basic_fstream<wchar_t, char_traits<wchar_t> >;
       
  1241 #  endif /* _STLP_NO_WCHAR_T */
       
  1242 
       
  1243 #endif
       
  1244 
       
  1245 _STLP_END_NAMESPACE
       
  1246 
       
  1247 // Local Variables:
       
  1248 // mode:C++
       
  1249 // End: