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