1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/genericopenlibs/cppstdlib/stl/src/fstream.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1249 @@
1.4 +/*
1.5 + * Portions Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
1.6 + *
1.7 + * Copyright (c) 1999
1.8 + * Silicon Graphics Computer Systems, Inc.
1.9 + *
1.10 + * Copyright (c) 1999
1.11 + * Boris Fomitchev
1.12 + *
1.13 + * This material is provided "as is", with absolutely no warranty expressed
1.14 + * or implied. Any use is at your own risk.
1.15 + *
1.16 + * Permission to use or copy this software for any purpose is hereby granted
1.17 + * without fee, provided the above notices are retained on all copies.
1.18 + * Permission to modify the code and to distribute modified code is granted,
1.19 + * provided the above notices are retained, and a notice that the code was
1.20 + * modified is included with the above copyright notice.
1.21 + *
1.22 + */
1.23 +
1.24 +
1.25 +#include "stlport_prefix.h"
1.26 +
1.27 +#if defined (__SUNPPRO_CC) && !defined (_STLP_NO_NEW_C_HEADERS)
1.28 +# include <time.h>
1.29 +// For sunpro, it chokes if time.h is included through stat.h
1.30 +#endif
1.31 +
1.32 +#include <fstream>
1.33 +
1.34 +#ifdef __CYGWIN__
1.35 +# define __int64 long long
1.36 +#endif
1.37 +
1.38 +#if defined (_STLP_USE_UNIX_IO)
1.39 +extern "C" {
1.40 +// open/close/read/write
1.41 +# include <sys/stat.h> // For stat
1.42 +# if !defined (_CRAY) && ! defined (__EMX__)
1.43 +# include <sys/mman.h> // For mmap
1.44 +# endif
1.45 +
1.46 +// on HP-UX 11, this one contradicts with pthread.h on pthread_atfork, unless we unset this
1.47 +# if defined (__hpux) && defined (__GNUC__)
1.48 +# undef _INCLUDE_POSIX1C_SOURCE
1.49 +# endif
1.50 +
1.51 +# include <unistd.h>
1.52 +# include <fcntl.h>
1.53 +}
1.54 +# ifdef __APPLE__
1.55 +# include <sys/sysctl.h>
1.56 +# endif
1.57 +#elif defined (_STLP_USE_WIN32_IO)
1.58 +# define WIN32_LEAN_AND_MEAN
1.59 +# include <windows.h>
1.60 +
1.61 +# ifdef __BORLANDC__
1.62 +# include <cfcntl.h> // For _O_RDONLY, etc
1.63 +# include <sys/stat.h> // For _fstat
1.64 +# elif !defined(_STLP_WCE)
1.65 +# include <io.h> // For _get_osfhandle
1.66 +# include <fcntl.h> // For _O_RDONLY, etc
1.67 +# include <sys/stat.h> // For _fstat
1.68 +# endif
1.69 +# define _TEXTBUF_SIZE 0x1000
1.70 +#elif defined (_STLP_USE_UNIX_EMULATION_IO)
1.71 +# if defined( __MSL__ )
1.72 +# include <unistd.h>
1.73 +# else
1.74 +# include <io.h>
1.75 +# endif
1.76 +# include <fcntl.h>
1.77 +# include <sys/stat.h>
1.78 +#elif defined (_STLP_USE_STDIO_IO)
1.79 +# include <cstdio>
1.80 +# if !(defined(__MRC__) || defined(__SC__) || defined(__ISCPP__) )
1.81 +extern "C" {
1.82 +# include <sys/stat.h>
1.83 +}
1.84 +# endif
1.85 +# if defined( __MSL__ )
1.86 +# include <unix.h>
1.87 +# endif
1.88 +# if defined(__ISCPP__)
1.89 +# include <c_locale_is/filestat.h>
1.90 +# endif
1.91 +# if (defined(__BEOS__) && defined(__INTEL__)) || defined (__SYMBIAN32__)
1.92 +# include <fcntl.h>
1.93 +# include <sys/stat.h> // For _fstat
1.94 +# define _S_IREAD S_IREAD
1.95 +# define _S_IWRITE S_IWRITE
1.96 +# define _S_IFREG S_IFREG
1.97 +# endif
1.98 +#else
1.99 +# error "Configure i/o !"
1.100 +#endif
1.101 +
1.102 +#if defined (_STLP_USE_WIN32_IO)
1.103 +const _STLP_fd INVALID_STLP_FD = INVALID_HANDLE_VALUE;
1.104 +# if !defined (INVALID_SET_FILE_POINTER)
1.105 +# define INVALID_SET_FILE_POINTER 0xffffffff
1.106 +# endif
1.107 +#elif defined (_STLP_USE_UNIX_EMULATION_IO) || defined (_STLP_USE_STDIO_IO) || defined (_STLP_USE_UNIX_IO)
1.108 +const _STLP_fd INVALID_STLP_FD = -1;
1.109 +#else
1.110 +# error "Configure i/o !"
1.111 +#endif
1.112 +
1.113 +// map permission masks
1.114 +#if defined (_STLP_USE_UNIX_EMULATION_IO) || defined (_STLP_USE_STDIO_IO)
1.115 +# ifndef S_IRUSR
1.116 +# define S_IRUSR _S_IREAD
1.117 +# define S_IWUSR _S_IWRITE
1.118 +# define S_IRGRP _S_IREAD
1.119 +# define S_IWGRP _S_IWRITE
1.120 +# define S_IROTH _S_IREAD
1.121 +# define S_IWOTH _S_IWRITE
1.122 +# endif
1.123 +# ifndef O_RDONLY
1.124 +# define O_RDONLY _O_RDONLY
1.125 +# define O_WRONLY _O_WRONLY
1.126 +# define O_RDWR _O_RDWR
1.127 +# define O_APPEND _O_APPEND
1.128 +# define O_CREAT _O_CREAT
1.129 +# define O_TRUNC _O_TRUNC
1.130 +# define O_TEXT _O_TEXT
1.131 +# define O_BINARY _O_BINARY
1.132 +# endif
1.133 +
1.134 +# ifdef __MSL__
1.135 +# define _O_TEXT 0x0
1.136 +# if !defined( O_TEXT )
1.137 +# define O_TEXT _O_TEXT
1.138 +# endif
1.139 +# define _S_IFREG S_IFREG
1.140 +# define S_IREAD S_IRUSR
1.141 +# define S_IWRITE S_IWUSR
1.142 +# define S_IEXEC S_IXUSR
1.143 +# define _S_IWRITE S_IWRITE
1.144 +# define _S_IREAD S_IREAD
1.145 +# define _open open
1.146 +# define _lseek lseek
1.147 +# define _close close
1.148 +# define _read read
1.149 +# define _write write
1.150 +# endif
1.151 +#endif
1.152 +
1.153 +#ifndef O_ACCMODE
1.154 +# define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
1.155 +#endif
1.156 +
1.157 +#include "fstream_impl.h"
1.158 +
1.159 +#ifdef _STLP_LONG_LONG
1.160 +# define ULL(x) ((unsigned _STLP_LONG_LONG)x)
1.161 +#elif defined(__MRC__) || defined(__SC__) //*TY 02/25/2000 - added support for MPW compilers
1.162 +# include <Math64.h>
1.163 +# define ULL(x) (U64SetU(x))
1.164 +#elif defined(__ISCPP__)
1.165 +# include "uint64.h"
1.166 +#elif defined(__SYMBIAN32__)
1.167 +# include <sys/types.h>
1.168 +#else
1.169 +# error "there should be some long long type on the system!"
1.170 +#endif
1.171 +
1.172 +
1.173 +#if defined(__SYMBIAN32__WSD__)
1.174 +# include "libstdcppwsd.h"
1.175 +
1.176 +_STLP_DECLSPEC size_t& get_fstream_Filebuf_Base_GetPageSize()
1.177 +{
1.178 + return get_libcpp_wsd().fstream_Filebuf_base_M_page_size;
1.179 +}
1.180 +
1.181 +void filebuf_page_size_init()
1.182 +{
1.183 + get_fstream_Filebuf_Base_GetPageSize() = 4096;
1.184 +}
1.185 +#endif
1.186 +
1.187 +_STLP_BEGIN_NAMESPACE
1.188 +// Compare with streamoff definition in stl/char_traits.h!
1.189 +
1.190 +#ifdef _STLP_USE_DEFAULT_FILE_OFFSET
1.191 +# define FOPEN fopen
1.192 +# define FSEEK fseek
1.193 +# define FSTAT fstat
1.194 +# define STAT stat
1.195 +# define FTELL ftell
1.196 +# define LSEEK lseek
1.197 +# define MMAP mmap
1.198 +# define OPEN open
1.199 +#elif defined(_LARGEFILE_SOURCE) || defined(_LARGEFILE64_SOURCE) /* || defined(__USE_FILE_OFFSET64) */ \
1.200 + /* || (defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)) */ /* || defined(__sgi) */
1.201 +# define FOPEN fopen64
1.202 +# define FSEEK fseeko64
1.203 +# define FSTAT fstat64
1.204 +# define STAT stat64
1.205 +# define FTELL ftello64
1.206 +# define LSEEK lseek64
1.207 +# define MMAP mmap64
1.208 +# define OPEN open64
1.209 +#else
1.210 +# define OPEN open
1.211 +# define FSEEK fseek
1.212 +# define FSTAT fstat
1.213 +# define STAT stat
1.214 +# define FTELL ftell
1.215 +# define LSEEK lseek
1.216 +# define MMAP mmap
1.217 +# define OPEN open
1.218 +#endif
1.219 +#ifdef _STLP_USE_UNIX_IO
1.220 +# ifndef MAP_FAILED /* MMAP failure return code */
1.221 +# define MAP_FAILED -1
1.222 +# endif
1.223 +#elif defined (_STLP_USE_UNIX_EMULATION_IO)
1.224 +# define LSEEK _lseek
1.225 +#endif
1.226 +
1.227 +#if !defined(__MSL__) && !defined(__MRC__) && !defined(__SC__) && !defined(_STLP_WCE) //*TY 04/15/2000 - exclude mpw compilers also
1.228 +static ios_base::openmode flag_to_openmode(int mode) {
1.229 + ios_base::openmode ret = ios_base::__default_mode;
1.230 +
1.231 + switch(mode & O_ACCMODE) {
1.232 + case O_RDONLY:
1.233 + ret = ios_base::in; break;
1.234 + case O_WRONLY:
1.235 + ret = ios_base::out; break;
1.236 + case O_RDWR:
1.237 + ret = ios_base::in | ios_base::out; break;
1.238 + }
1.239 +
1.240 + if (mode & O_APPEND)
1.241 + ret |= ios_base::app;
1.242 +
1.243 +# if defined (_STLP_USE_WIN32_IO)
1.244 + if (mode & O_BINARY)
1.245 + ret |= ios_base::binary;
1.246 +# endif
1.247 +
1.248 + return ret;
1.249 +}
1.250 +#endif /* MSL */
1.251 +
1.252 +_STLP_MOVE_TO_PRIV_NAMESPACE
1.253 +
1.254 +// Helper functions for _Filebuf_base.
1.255 +
1.256 +bool __is_regular_file(_STLP_fd fd) {
1.257 +
1.258 +#if defined (_STLP_UNIX)
1.259 +
1.260 + struct STAT buf;
1.261 + return FSTAT(fd, &buf) == 0 && S_ISREG(buf.st_mode);
1.262 +
1.263 +#elif defined(__MRC__) || defined(__SC__) //*TY 02/25/2000 - added support for MPW compilers
1.264 +
1.265 +# pragma unused(fd)
1.266 + return true; // each file is a regular file under mac os, isn't it? (we don't have fstat())
1.267 +
1.268 +#elif defined(_STLP_USE_UNIX_EMULATION_IO) || defined (_STLP_USE_STDIO_IO)
1.269 +
1.270 + struct STAT buf;
1.271 + return FSTAT(fd, &buf) == 0 && (buf.st_mode & _S_IFREG) != 0 ;
1.272 +
1.273 +#elif defined (_STLP_USE_WIN32_IO) && !defined(_STLP_WCE)
1.274 +
1.275 + return (GetFileType(fd) & ~FILE_TYPE_REMOTE) == FILE_TYPE_DISK;
1.276 +
1.277 +#else
1.278 + (void)fd; // dwa 4/27/00 - suppress unused parameter warning
1.279 + return false;
1.280 +#endif
1.281 +}
1.282 +
1.283 +// Number of characters in the file.
1.284 +streamoff __file_size(_STLP_fd fd) {
1.285 + streamoff ret = 0;
1.286 +
1.287 +#if defined (_STLP_UNIX)
1.288 +
1.289 + struct STAT buf;
1.290 + if (FSTAT(fd, &buf) == 0 && S_ISREG(buf.st_mode))
1.291 + ret = buf.st_size > 0 ? buf.st_size : 0;
1.292 +
1.293 +#elif defined(__MRC__) || defined(__SC__) //*TY 02/25/2000 - added support for MPW compilers
1.294 +
1.295 +# pragma unused(fd)
1.296 +
1.297 +#elif defined(_STLP_USE_UNIX_EMULATION_IO) || defined (_STLP_USE_STDIO_IO)
1.298 +
1.299 + struct STAT buf;
1.300 + if (FSTAT(fd, &buf) == 0 && (buf.st_mode & _S_IFREG) != 0)
1.301 + ret = buf.st_size > 0 ? buf.st_size : 0;
1.302 +
1.303 +#elif defined (_STLP_USE_WIN32_IO)
1.304 +
1.305 + LARGE_INTEGER li;
1.306 + li.LowPart = GetFileSize(fd, (unsigned long*) &li.HighPart);
1.307 + if (li.LowPart != INVALID_FILE_SIZE || GetLastError() == NO_ERROR)
1.308 + ret = li.QuadPart;
1.309 +
1.310 +#else
1.311 + (void)fd; // dwa 4/27/00 - suppress unused parameter warning
1.312 +#endif
1.313 + return ret;
1.314 +}
1.315 +
1.316 +_STLP_MOVE_TO_STD_NAMESPACE
1.317 +
1.318 +// Visual C++ and Intel use this, but not Metrowerks
1.319 +// Also MinGW, msvcrt.dll (but not crtdll.dll) dependent version
1.320 +#if (!defined (__MSL__) && !defined (_STLP_WCE) && defined (_STLP_MSVC_LIB) && defined (_WIN32)) || \
1.321 + (defined (__MINGW32__) && defined (__MSVCRT__) && !(defined (__SYMBIAN32__) && defined(__GCCXML__)) )
1.322 +
1.323 +// fcntl(fileno, F_GETFL) for Microsoft library
1.324 +// 'semi-documented' defines:
1.325 +# define IOINFO_L2E 5
1.326 +# define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
1.327 +# define _pioinfo(i) ( __pioinfo[(i) >> IOINFO_L2E] + \
1.328 + ((i) & (IOINFO_ARRAY_ELTS - 1)) )
1.329 +# define FAPPEND 0x20 // O_APPEND flag
1.330 +# define FTEXT 0x80 // O_TEXT flag
1.331 +// end of 'semi-documented' defines
1.332 +
1.333 +// 'semi-documented' internal structure
1.334 +extern "C" {
1.335 + struct ioinfo {
1.336 + long osfhnd; // the real os HANDLE
1.337 + char osfile; // file handle flags
1.338 + char pipech; // pipe buffer
1.339 +# if defined (_MT)
1.340 + // multi-threaded locking
1.341 + int lockinitflag;
1.342 + CRITICAL_SECTION lock;
1.343 +# endif /* _MT */
1.344 + };
1.345 +# if defined (__MINGW32__)
1.346 + __MINGW_IMPORT ioinfo * __pioinfo[];
1.347 +# else
1.348 + extern _CRTIMP ioinfo * __pioinfo[];
1.349 +# endif
1.350 +} // extern "C"
1.351 +// end of 'semi-documented' declarations
1.352 +
1.353 +static ios_base::openmode _get_osfflags(int fd, HANDLE oshandle) {
1.354 + char dosflags = 0;
1.355 + if (fd >= 0)
1.356 + dosflags = _pioinfo(fd)->osfile;
1.357 + //else
1.358 + //the file will be considered as open in binary mode with no append attribute
1.359 + // end of 'semi-documented' stuff
1.360 +
1.361 + int mode = 0;
1.362 + if (dosflags & FAPPEND)
1.363 + mode |= O_APPEND;
1.364 +
1.365 + if (dosflags & FTEXT)
1.366 + mode |= O_TEXT;
1.367 + else
1.368 + mode |= O_BINARY;
1.369 +
1.370 + // For Read/Write access we have to guess
1.371 + DWORD dummy, dummy2;
1.372 + BOOL writeOk = WriteFile(oshandle, &dummy2, 0, &dummy, 0);
1.373 + BOOL readOk = ReadFile(oshandle, &dummy2, 0, &dummy, NULL);
1.374 + if (writeOk && readOk)
1.375 + mode |= O_RDWR;
1.376 + else if (readOk)
1.377 + mode |= O_RDONLY;
1.378 + else
1.379 + mode |= O_WRONLY;
1.380 +
1.381 + return flag_to_openmode(mode);
1.382 +}
1.383 +
1.384 +#elif defined (__DMC__)
1.385 +
1.386 +# define FHND_APPEND 0x04
1.387 +# define FHND_DEVICE 0x08
1.388 +# define FHND_TEXT 0x10
1.389 +
1.390 +extern "C" unsigned char __fhnd_info[_NFILE];
1.391 +
1.392 +static ios_base::openmode _get_osfflags(int fd, HANDLE oshandle) {
1.393 + int mode = 0;
1.394 +
1.395 + if (__fhnd_info[fd] & FHND_APPEND)
1.396 + mode |= O_APPEND;
1.397 +
1.398 + if (__fhnd_info[fd] & FHND_TEXT == 0)
1.399 + mode |= O_BINARY;
1.400 +
1.401 + for (FILE *fp = &_iob[0]; fp < &_iob[_NFILE]; fp++) {
1.402 + if ((fileno(fp) == fd) && (fp->_flag & (_IOREAD | _IOWRT | _IORW))) {
1.403 + const int osflags = fp->_flag;
1.404 +
1.405 + if ((osflags & _IOREAD) && !(osflags & _IOWRT) && !(osflags & _IORW))
1.406 + mode |= O_RDONLY;
1.407 + else if ((osflags & _IOWRT) && !(osflags & _IOREAD) && !(osflags & _IORW))
1.408 + mode |= O_WRONLY;
1.409 + else
1.410 + mode |= O_RDWR;
1.411 + break;
1.412 + }
1.413 + }
1.414 +
1.415 + return flag_to_openmode(mode);
1.416 +}
1.417 +#endif
1.418 +
1.419 +#if !defined(__SYMBIAN32__WSD__)
1.420 +size_t _Filebuf_base::_M_page_size = 4096;
1.421 +#endif //__SYMBIAN32__WSD__
1.422 +
1.423 +_STLP_DECLSPEC _Filebuf_base::_Filebuf_base()
1.424 + : _M_file_id(INVALID_STLP_FD),
1.425 +#if defined (_STLP_USE_WIN32_IO)
1.426 + _M_view_id(0),
1.427 +#endif
1.428 + _M_openmode(0),
1.429 + _M_is_open(false),
1.430 + _M_should_close(false)
1.431 +{}
1.432 +
1.433 +void _Filebuf_base::_S_initialize() {
1.434 +#if defined (_STLP_UNIX) && !defined (__DJGPP) && !defined (_CRAY)
1.435 +# if defined (__APPLE__)
1.436 + int mib[2];
1.437 + size_t pagesize, len;
1.438 + mib[0] = CTL_HW;
1.439 + mib[1] = HW_PAGESIZE;
1.440 + len = sizeof(pagesize);
1.441 + sysctl(mib, 2, &pagesize, &len, NULL, 0);
1.442 + _M_page_size = pagesize;
1.443 +# elif defined (__DJGPP) && defined (_CRAY)
1.444 + _M_page_size = BUFSIZ;
1.445 +# else
1.446 + _M_page_size = sysconf(_SC_PAGESIZE);
1.447 +# endif
1.448 +#elif defined (_STLP_USE_WIN32_IO)
1.449 + SYSTEM_INFO SystemInfo;
1.450 + GetSystemInfo(&SystemInfo);
1.451 + _M_page_size = SystemInfo.dwPageSize;
1.452 + // might be .dwAllocationGranularity
1.453 +#endif
1.454 +}
1.455 +
1.456 +// Return the size of the file. This is a wrapper for stat.
1.457 +// Returns zero if the size cannot be determined or is ill-defined.
1.458 +_STLP_DECLSPEC streamoff _Filebuf_base::_M_file_size() {
1.459 + return _STLP_PRIV __file_size(_M_file_id);
1.460 +}
1.461 +
1.462 +_STLP_DECLSPEC bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode,
1.463 + long permission) {
1.464 + _STLP_fd file_no;
1.465 +
1.466 + if (_M_is_open)
1.467 + return false;
1.468 +
1.469 +#if defined (_STLP_USE_UNIX_IO) || defined (_STLP_USE_UNIX_EMULATION_IO)
1.470 + int flags = 0;
1.471 +
1.472 + // Unix makes no distinction between text and binary files.
1.473 + switch(openmode & (~ios_base::ate & ~ios_base::binary)) {
1.474 + case ios_base::out:
1.475 + case ios_base::out | ios_base::trunc:
1.476 + flags = O_WRONLY | O_CREAT | O_TRUNC;
1.477 + break;
1.478 + case ios_base::out | ios_base::app:
1.479 + flags = O_WRONLY | O_CREAT | O_APPEND;
1.480 + break;
1.481 + case ios_base::in:
1.482 + flags = O_RDONLY;
1.483 + permission = 0; // Irrelevant unless we're writing.
1.484 + break;
1.485 + case ios_base::in | ios_base::out:
1.486 + flags = O_RDWR;
1.487 + break;
1.488 + case ios_base::in | ios_base::out | ios_base::trunc:
1.489 + flags = O_RDWR | O_CREAT | O_TRUNC;
1.490 + break;
1.491 + default: // The above are the only combinations of
1.492 + return false; // flags allowed by the C++ standard.
1.493 + }
1.494 +
1.495 +# if defined (_STLP_USE_UNIX_EMULATION_IO)
1.496 + if (openmode & ios_base::binary)
1.497 + flags |= O_BINARY;
1.498 + else
1.499 + flags |= O_TEXT;
1.500 +
1.501 + file_no = _open(name, flags, permission);
1.502 +# else
1.503 + file_no = OPEN(name, flags, permission);
1.504 +# endif /* _STLP_USE_UNIX_EMULATION_IO */
1.505 +
1.506 + if (file_no < 0)
1.507 + return false;
1.508 +
1.509 + _M_is_open = true;
1.510 +
1.511 + if (openmode & ios_base::ate)
1.512 + if (LSEEK(file_no, 0, SEEK_END) == -1)
1.513 + _M_is_open = false;
1.514 +
1.515 +#elif defined (_STLP_USE_STDIO_IO)
1.516 + // use FILE-based i/o
1.517 + const char* flags;
1.518 +
1.519 + switch(openmode & (~ios_base::ate)) {
1.520 + case ios_base::out:
1.521 + case ios_base::out | ios_base::trunc:
1.522 + flags = "w";
1.523 + break;
1.524 +
1.525 + case ios_base::out | ios_base::binary:
1.526 + case ios_base::out | ios_base::trunc | ios_base::binary:
1.527 + flags = "wb";
1.528 + break;
1.529 +
1.530 + case ios_base::out | ios_base::app:
1.531 + flags = "a";
1.532 + break;
1.533 +
1.534 + case ios_base::out | ios_base::app | ios_base::binary:
1.535 + flags = "ab";
1.536 + break;
1.537 +
1.538 + case ios_base::in:
1.539 + flags = "r";
1.540 + break;
1.541 +
1.542 + case ios_base::in | ios_base::binary:
1.543 + flags = "rb";
1.544 + break;
1.545 +
1.546 + case ios_base::in | ios_base::out:
1.547 + flags = "r+";
1.548 + break;
1.549 +
1.550 + case ios_base::in | ios_base::out | ios_base::binary:
1.551 + flags = "r+b";
1.552 + break;
1.553 +
1.554 +
1.555 + case ios_base::in | ios_base::out | ios_base::trunc:
1.556 + flags = "w+";
1.557 + break;
1.558 +
1.559 + case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
1.560 + flags = "w+b";
1.561 + break;
1.562 +
1.563 + default: // The above are the only combinations of
1.564 + return false; // flags allowed by the C++ standard.
1.565 + }
1.566 +
1.567 + // fbp : : set permissions !
1.568 + (void)permission; // currently unused //*TY 02/26/2000 - added to suppress warning message
1.569 + _M_file = FOPEN(name, flags);
1.570 +
1.571 + if (_M_file) {
1.572 + file_no = fileno(_M_file);
1.573 + }
1.574 + else
1.575 + return false;
1.576 +
1.577 + // unset buffering immediately
1.578 + setbuf(_M_file, 0);
1.579 +
1.580 + _M_is_open = true;
1.581 +
1.582 + if (openmode & ios_base::ate) {
1.583 + if (FSEEK(_M_file, 0, SEEK_END) == -1)
1.584 + _M_is_open = false;
1.585 + }
1.586 +
1.587 +#elif defined (_STLP_USE_WIN32_IO)
1.588 + DWORD dwDesiredAccess, dwCreationDisposition;
1.589 + bool doTruncate = false;
1.590 +
1.591 + switch (openmode & (~ios_base::ate & ~ios_base::binary)) {
1.592 + case ios_base::out:
1.593 + case ios_base::out | ios_base::trunc:
1.594 + dwDesiredAccess = GENERIC_WRITE;
1.595 + dwCreationDisposition = OPEN_ALWAYS;
1.596 + // boris : even though it is very non-intuitive, standard
1.597 + // requires them both to behave same.
1.598 + doTruncate = true;
1.599 + break;
1.600 + case ios_base::out | ios_base::app:
1.601 + dwDesiredAccess = GENERIC_WRITE;
1.602 + dwCreationDisposition = OPEN_ALWAYS;
1.603 + break;
1.604 + case ios_base::in:
1.605 + dwDesiredAccess = GENERIC_READ;
1.606 + dwCreationDisposition = OPEN_EXISTING;
1.607 + permission = 0; // Irrelevant unless we're writing.
1.608 + break;
1.609 + case ios_base::in | ios_base::out:
1.610 + dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
1.611 + dwCreationDisposition = OPEN_EXISTING;
1.612 + break;
1.613 + case ios_base::in | ios_base::out | ios_base::trunc:
1.614 + dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
1.615 + dwCreationDisposition = OPEN_ALWAYS;
1.616 + doTruncate = true;
1.617 + break;
1.618 + default: // The above are the only combinations of
1.619 + return false; // flags allowed by the C++ standard.
1.620 + }
1.621 +
1.622 + DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
1.623 +
1.624 +# if defined(_STLP_USE_WIDE_INTERFACE)
1.625 + file_no = CreateFile (_STLP_PRIV __ASCIIToWide(name).c_str(),
1.626 +# else
1.627 + file_no = CreateFileA(name,
1.628 +# endif
1.629 + dwDesiredAccess, dwShareMode, 0,
1.630 + dwCreationDisposition, permission, 0);
1.631 +
1.632 + if (file_no == INVALID_STLP_FD)
1.633 + return false;
1.634 +
1.635 + if ((doTruncate && SetEndOfFile(file_no) == 0) ||
1.636 + (((openmode & ios_base::ate) != 0) &&
1.637 + (SetFilePointer(file_no, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER))) {
1.638 + CloseHandle(file_no);
1.639 + return false;
1.640 + }
1.641 +
1.642 + _M_is_open = true;
1.643 +
1.644 +#else
1.645 +# error "Port!"
1.646 +#endif /* __unix */
1.647 +
1.648 + _M_file_id = file_no;
1.649 + _M_should_close = _M_is_open;
1.650 + _M_openmode = openmode;
1.651 +
1.652 + if (_M_is_open)
1.653 + _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id);
1.654 +
1.655 + return (_M_is_open != 0);
1.656 +}
1.657 +
1.658 +
1.659 +_STLP_DECLSPEC bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode) {
1.660 + // This doesn't really grant everyone in the world read/write
1.661 + // access. On Unix, file-creation system calls always clear
1.662 + // bits that are set in the umask from the permissions flag.
1.663 +#ifdef _STLP_USE_WIN32_IO
1.664 + return this->_M_open(name, openmode, FILE_ATTRIBUTE_NORMAL);
1.665 +#elif defined(__MRC__) || defined(__SC__) //*TY 02/26/2000 - added support for MPW compilers
1.666 + return this->_M_open(name, openmode, 0);
1.667 +#else
1.668 + return this->_M_open(name, openmode, S_IRUSR | S_IWUSR | S_IRGRP |
1.669 + S_IWGRP | S_IROTH | S_IWOTH);
1.670 +#endif
1.671 +}
1.672 +
1.673 +
1.674 +#if defined (_STLP_USE_WIN32_IO)
1.675 +bool _Filebuf_base::_M_open(_STLP_fd __id, ios_base::openmode init_mode) {
1.676 +# if (defined (_STLP_MSVC_LIB) && !defined (_STLP_WCE)) || \
1.677 + (defined (__MINGW32__) && defined (__MSVCRT__)) || defined (__DMC__)
1.678 +
1.679 + if (_M_is_open || __id == INVALID_STLP_FD)
1.680 + return false;
1.681 +
1.682 + if (init_mode != ios_base::__default_mode)
1.683 + _M_openmode = init_mode;
1.684 + else
1.685 + _M_openmode = _get_osfflags(-1, __id);
1.686 +
1.687 + _M_is_open = true;
1.688 + _M_file_id = __id;
1.689 + _M_should_close = false;
1.690 + _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id);
1.691 +
1.692 + return true;
1.693 +# else
1.694 + (void)__id;
1.695 + (void)init_mode; // dwa 4/27/00 - suppress unused parameter warning
1.696 +
1.697 + // not available for the API
1.698 + return false;
1.699 +
1.700 +# endif
1.701 +}
1.702 +#endif /* _STLP_USE_WIN32_IO */
1.703 +
1.704 +// Associated the filebuf with a file descriptor pointing to an already-
1.705 +// open file. Mode is set to be consistent with the way that the file
1.706 +// was opened.
1.707 +_STLP_DECLSPEC bool _Filebuf_base::_M_open(int file_no, ios_base::openmode init_mode) {
1.708 + if (_M_is_open || file_no < 0)
1.709 + return false;
1.710 +
1.711 +#if defined (_STLP_UNIX)
1.712 + (void)init_mode; // dwa 4/27/00 - suppress unused parameter warning
1.713 + int mode ;
1.714 + mode = fcntl(file_no, F_GETFL);
1.715 +
1.716 + if (mode == -1)
1.717 + return false;
1.718 +
1.719 + _M_openmode = flag_to_openmode(mode);
1.720 + _M_file_id = file_no;
1.721 +#elif defined(__MRC__) || defined(__SC__) //*TY 02/26/2000 - added support for MPW compilers
1.722 + (void)init_mode; // dwa 4/27/00 - suppress unused parameter warning
1.723 + switch (_iob[file_no]._flag & (_IOREAD|_IOWRT|_IORW) )
1.724 + {
1.725 + case _IOREAD:
1.726 + _M_openmode = ios_base::in; break;
1.727 + case _IOWRT:
1.728 + _M_openmode = ios_base::out; break;
1.729 + case _IORW:
1.730 + _M_openmode = ios_base::in | ios_base::out; break;
1.731 + default:
1.732 + return false;
1.733 + }
1.734 + _M_file_id = file_no;
1.735 +#elif defined (_STLP_USE_UNIX_EMULATION_IO) || defined (_STLP_USE_STDIO_IO)
1.736 + (void)init_mode; // dwa 4/27/00 - suppress unused parameter warning
1.737 + int mode ;
1.738 + struct STAT buf;
1.739 + if (FSTAT(file_no, &buf) != 0)
1.740 + return false;
1.741 + mode = buf.st_mode;
1.742 +
1.743 + switch(mode & (_S_IWRITE | _S_IREAD) ) {
1.744 + case _S_IREAD:
1.745 + _M_openmode = ios_base::in; break;
1.746 + case _S_IWRITE:
1.747 + _M_openmode = ios_base::out; break;
1.748 + case (_S_IWRITE | _S_IREAD):
1.749 + _M_openmode = ios_base::in | ios_base::out; break;
1.750 + default:
1.751 + return false;
1.752 + }
1.753 + _M_file_id = file_no;
1.754 +#elif (defined (_STLP_USE_WIN32_IO) && defined (_STLP_MSVC_LIB) && !defined (_STLP_WCE) ) || \
1.755 + (defined (__MINGW32__) && defined (__MSVCRT__)) || \
1.756 + defined (__DMC__)
1.757 +
1.758 + HANDLE oshandle = (HANDLE)_get_osfhandle(file_no);
1.759 + if (oshandle == INVALID_STLP_FD)
1.760 + return false;
1.761 +
1.762 + if (init_mode != ios_base::__default_mode)
1.763 + _M_openmode = init_mode;
1.764 + else
1.765 + _M_openmode = _get_osfflags(file_no, oshandle);
1.766 +
1.767 + _M_file_id = oshandle;
1.768 +#else
1.769 + (void)init_mode; // dwa 4/27/00 - suppress unused parameter warning
1.770 + // not available for the API
1.771 +# define _STLP_NO_IMPLEMENTATION
1.772 +#endif
1.773 +
1.774 +#if !defined (_STLP_NO_IMPLEMENTATION)
1.775 + _M_is_open = true;
1.776 + _M_should_close = false;
1.777 + _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id);
1.778 + return true;
1.779 +#else
1.780 +# undef _STLP_NO_IMPLEMENTATION
1.781 + return false;
1.782 +#endif
1.783 +}
1.784 +
1.785 +_STLP_DECLSPEC bool _Filebuf_base::_M_close() {
1.786 + if (!_M_is_open)
1.787 + return false;
1.788 +
1.789 + bool ok;
1.790 +
1.791 + if (!_M_should_close)
1.792 + ok = true;
1.793 + else {
1.794 +
1.795 +#if defined (_STLP_USE_UNIX_IO)
1.796 +
1.797 + ok = (close(_M_file_id) == 0);
1.798 +
1.799 +#elif defined (_STLP_USE_UNIX_EMULATION_IO)
1.800 +
1.801 + ok = (_close(_M_file_id) == 0);
1.802 +
1.803 +#elif defined (_STLP_USE_STDIO_IO)
1.804 +
1.805 + ok = (fclose(_M_file) == 0);
1.806 +
1.807 +#elif defined (_STLP_USE_WIN32_IO)
1.808 +
1.809 + if (_M_file_id != INVALID_STLP_FD) {
1.810 + ok = (CloseHandle(_M_file_id) != 0);
1.811 + }
1.812 + else {
1.813 + ok = false;
1.814 + }
1.815 +
1.816 +#else
1.817 +
1.818 + ok = false;
1.819 +
1.820 +#endif /* _STLP_USE_UNIX_IO */
1.821 + }
1.822 +
1.823 + _M_is_open = _M_should_close = false;
1.824 + _M_openmode = 0;
1.825 + return ok;
1.826 +}
1.827 +
1.828 +
1.829 +#define _STLP_LF 10
1.830 +#define _STLP_CR 13
1.831 +#define _STLP_CTRLZ 26
1.832 +
1.833 +// Read up to n characters into a buffer. Return value is number of
1.834 +// characters read.
1.835 +_STLP_DECLSPEC ptrdiff_t _Filebuf_base::_M_read(char* buf, ptrdiff_t n) {
1.836 +#if defined (_STLP_USE_UNIX_IO)
1.837 +
1.838 + return read(_M_file_id, buf, n);
1.839 +
1.840 +#elif defined (_STLP_USE_UNIX_EMULATION_IO)
1.841 +
1.842 + return _read(_M_file_id, buf, n);
1.843 +
1.844 +#elif defined (_STLP_USE_WIN32_IO)
1.845 + ptrdiff_t readen = 0;
1.846 + //Here cast to size_t is safe as n cannot be negative.
1.847 + size_t chunkSize = (min)(size_t(0xffffffff), __STATIC_CAST(size_t, n));
1.848 + // The following, while validating that we are still able to extract chunkSize
1.849 + // charaters to the buffer, avoids extraction of too small chunk of datas
1.850 + // which would be counter performant.
1.851 + while (__STATIC_CAST(size_t, (n - readen)) >= chunkSize) {
1.852 + DWORD NumberOfBytesRead;
1.853 + ReadFile(_M_file_id, buf + readen, __STATIC_CAST(DWORD, chunkSize), &NumberOfBytesRead, 0);
1.854 +
1.855 + if (NumberOfBytesRead == 0)
1.856 + break;
1.857 +
1.858 + if (!(_M_openmode & ios_base::binary)) {
1.859 + // translate CR-LFs to LFs in the buffer
1.860 + char *to = buf + readen;
1.861 + char *from = to;
1.862 + char *last = from + NumberOfBytesRead - 1;
1.863 + for (; from <= last && *from != _STLP_CTRLZ; ++from) {
1.864 + if (*from != _STLP_CR)
1.865 + *to++ = *from;
1.866 + else { // found CR
1.867 + if (from < last) { // not at buffer end
1.868 + if (*(from + 1) != _STLP_LF)
1.869 + *to++ = _STLP_CR;
1.870 + }
1.871 + else { // last char is CR, peek for LF
1.872 + char peek = ' ';
1.873 + DWORD NumberOfBytesPeeked;
1.874 + ReadFile(_M_file_id, (LPVOID)&peek, 1, &NumberOfBytesPeeked, 0);
1.875 + if (NumberOfBytesPeeked != 0) {
1.876 + if (peek != _STLP_LF) { //not a <CR><LF> combination
1.877 + *to++ = _STLP_CR;
1.878 + if ((to < buf + n) && (peek != _STLP_CR))
1.879 + //We have enough place to store peek and it is no a special
1.880 + //_STLP_CR character, we can store it.
1.881 + *to++ = peek;
1.882 + else
1.883 + SetFilePointer(_M_file_id, (LONG)-1, 0, SEEK_CUR);
1.884 + }
1.885 + else {
1.886 + // A <CR><LF> combination, we keep the <LF>:
1.887 + *to++ = _STLP_LF;
1.888 + }
1.889 + }
1.890 + else {
1.891 + /* This case is tedious, we could
1.892 + * - put peek back in the file but this would then generate an infinite loop
1.893 + * - report an error as we don't know if in a future call to ReadFile we won't then
1.894 + * get a <LF>. Doing so would make all files with a <CR> last an invalid file
1.895 + * for STLport, a hard solution for STLport clients.
1.896 + * - store the <CR> in the returned buffer, the chosen solution, even if in this
1.897 + * case we could miss a <CR><LF> combination.
1.898 + */
1.899 + *to++ = _STLP_CR;
1.900 + }
1.901 + }
1.902 + } // found CR
1.903 + } // for
1.904 + // seek back to TEXT end of file if hit CTRL-Z
1.905 + if (from <= last) // terminated due to CTRLZ
1.906 + SetFilePointer(_M_file_id, (LONG)((last+1) - from), 0, SEEK_CUR);
1.907 + readen += to - (buf + readen);
1.908 + }
1.909 + else
1.910 + readen += NumberOfBytesRead;
1.911 + }
1.912 + return readen;
1.913 +
1.914 +#elif defined (_STLP_USE_STDIO_IO)
1.915 +
1.916 + return fread(buf, 1, n, _M_file);
1.917 +
1.918 +#else
1.919 +# error "Port!"
1.920 +#endif /* __unix */
1.921 +}
1.922 +
1.923 +// Write n characters from a buffer. Return value: true if we managed
1.924 +// to write the entire buffer, false if we didn't.
1.925 +_STLP_DECLSPEC bool _Filebuf_base::_M_write(char* buf, ptrdiff_t n) {
1.926 + for (;;) {
1.927 + ptrdiff_t written;
1.928 +
1.929 +#if defined (_STLP_USE_UNIX_IO)
1.930 +
1.931 + written = write(_M_file_id, buf, n);
1.932 +
1.933 +#elif defined (_STLP_USE_UNIX_EMULATION_IO)
1.934 +
1.935 + written = _write(_M_file_id, buf, n);
1.936 +
1.937 +#elif defined (_STLP_USE_WIN32_IO)
1.938 +
1.939 + //In the following implementation we are going to cast most of the ptrdiff_t
1.940 + //values in size_t to work with coherent unsigned values. Doing so make code
1.941 + //more simple especially in the min function call.
1.942 +
1.943 + // In append mode, every write does an implicit seek to the end
1.944 + // of the file.
1.945 + if (_M_openmode & ios_base::app)
1.946 + _M_seek(0, ios_base::end);
1.947 +
1.948 + if (_M_openmode & ios_base::binary) {
1.949 + // binary mode
1.950 + size_t bytes_to_write = (size_t)n;
1.951 + DWORD NumberOfBytesWritten;
1.952 + written = 0;
1.953 + for (; bytes_to_write != 0;) {
1.954 + WriteFile(_M_file_id, buf + written,
1.955 + __STATIC_CAST(DWORD, (min)(size_t(0xffffffff), bytes_to_write)),
1.956 + &NumberOfBytesWritten, 0);
1.957 + if (NumberOfBytesWritten == 0)
1.958 + return false;
1.959 + bytes_to_write -= NumberOfBytesWritten;
1.960 + written += NumberOfBytesWritten;
1.961 + }
1.962 + }
1.963 + else {
1.964 + char textbuf[_TEXTBUF_SIZE + 1]; // extra 1 in case LF at end
1.965 + char * nextblock = buf, * ptrtextbuf = textbuf;
1.966 + char * endtextbuf = textbuf + _TEXTBUF_SIZE;
1.967 + char * endblock = buf + n;
1.968 + ptrdiff_t nextblocksize = (min) (n, (ptrdiff_t)_TEXTBUF_SIZE);
1.969 + char * nextlf;
1.970 +
1.971 + while ( (nextblocksize > 0) &&
1.972 + (nextlf = (char *)memchr(nextblock, _STLP_LF, nextblocksize)) != 0) {
1.973 + ptrdiff_t linelength = nextlf - nextblock;
1.974 + memcpy(ptrtextbuf, nextblock, linelength);
1.975 + ptrtextbuf += linelength;
1.976 + nextblock += (linelength + 1);
1.977 + * ptrtextbuf ++ = _STLP_CR;
1.978 + * ptrtextbuf ++ = _STLP_LF;
1.979 + nextblocksize = (min) (ptrdiff_t(endblock - nextblock),
1.980 + (max) (ptrdiff_t(0), ptrdiff_t(endtextbuf - ptrtextbuf)));
1.981 + }
1.982 + // write out what's left, > condition is here since for LF at the end ,
1.983 + // endtextbuf may get < ptrtextbuf ...
1.984 + if (nextblocksize > 0) {
1.985 + memcpy(ptrtextbuf, nextblock, nextblocksize);
1.986 + ptrtextbuf += nextblocksize;
1.987 + nextblock += nextblocksize;
1.988 + }
1.989 + // now write out the translated buffer
1.990 + char * writetextbuf = textbuf;
1.991 + for (size_t NumberOfBytesToWrite = (size_t)(ptrtextbuf - textbuf);
1.992 + NumberOfBytesToWrite;) {
1.993 + DWORD NumberOfBytesWritten;
1.994 + WriteFile((HANDLE)_M_file_id, writetextbuf,
1.995 + __STATIC_CAST(DWORD, (min)(size_t(0xffffffff), NumberOfBytesToWrite)),
1.996 + &NumberOfBytesWritten, 0);
1.997 + if (!NumberOfBytesWritten) // write shortfall
1.998 + return false;
1.999 + writetextbuf += NumberOfBytesWritten;
1.1000 + NumberOfBytesToWrite -= NumberOfBytesWritten;
1.1001 + }
1.1002 + // count non-translated characters
1.1003 + written = (nextblock - buf);
1.1004 + }
1.1005 +
1.1006 +#elif defined (_STLP_USE_STDIO_IO)
1.1007 +
1.1008 + written = fwrite(buf, 1, n, _M_file);
1.1009 +
1.1010 +#else
1.1011 +# error "Port!"
1.1012 +#endif /* __unix */
1.1013 +
1.1014 + if (n == written)
1.1015 + return true;
1.1016 + else if (written > 0 && written < n) {
1.1017 + n -= written;
1.1018 + buf += written;
1.1019 + }
1.1020 + else
1.1021 + return false;
1.1022 + }
1.1023 +}
1.1024 +
1.1025 +
1.1026 +#ifdef _STLP_USE_WIN32_IO
1.1027 +# define STL_SEEK_SET FILE_BEGIN
1.1028 +# define STL_SEEK_CUR FILE_CURRENT
1.1029 +# define STL_SEEK_END FILE_END
1.1030 +#else
1.1031 +# define STL_SEEK_SET SEEK_SET
1.1032 +# define STL_SEEK_CUR SEEK_CUR
1.1033 +# define STL_SEEK_END SEEK_END
1.1034 +#endif
1.1035 +
1.1036 +// Wrapper for lseek or the like.
1.1037 +_STLP_DECLSPEC streamoff _Filebuf_base::_M_seek(streamoff offset, ios_base::seekdir dir) {
1.1038 + streamoff result = -1;
1.1039 + int whence;
1.1040 +
1.1041 + switch(dir) {
1.1042 + case ios_base::beg:
1.1043 + if (offset < 0 /* || offset > _M_file_size() */ )
1.1044 + return streamoff(-1);
1.1045 + whence = STL_SEEK_SET;
1.1046 + break;
1.1047 + case ios_base::cur:
1.1048 + whence = STL_SEEK_CUR;
1.1049 + break;
1.1050 + case ios_base::end:
1.1051 + if (/* offset > 0 || */ -offset > _M_file_size() )
1.1052 + return streamoff(-1);
1.1053 + whence = STL_SEEK_END;
1.1054 + break;
1.1055 + default:
1.1056 + return streamoff(-1);
1.1057 + }
1.1058 +
1.1059 +#if defined (_STLP_USE_UNIX_IO) || defined (_STLP_USE_UNIX_EMULATION_IO)
1.1060 +
1.1061 + result = LSEEK(_M_file_id, offset, whence);
1.1062 +
1.1063 +#elif defined (_STLP_USE_STDIO_IO)
1.1064 +
1.1065 +#if defined (__SYMBIAN32__)
1.1066 + /* This function is a wrapper for lseek and expects to return the offset in bytes from the beginning of the file.
1.1067 + It is used by tellg as well as tellp (for setting/getting the file pointer).
1.1068 + We don't want to use fseek for that. */
1.1069 + if (FSEEK(_M_file, offset, whence) != 0)
1.1070 + return streamoff(-1);
1.1071 + result = FTELL(_M_file);
1.1072 +#else
1.1073 + result = FSEEK(_M_file, offset, whence);
1.1074 +#endif
1.1075 +
1.1076 +#elif defined (_STLP_USE_WIN32_IO)
1.1077 +
1.1078 + LARGE_INTEGER li;
1.1079 + li.QuadPart = offset;
1.1080 + li.LowPart = SetFilePointer(_M_file_id, li.LowPart, &li.HighPart, whence);
1.1081 + if (li.LowPart != INVALID_SET_FILE_POINTER || GetLastError() == NO_ERROR)
1.1082 + result = li.QuadPart;
1.1083 +
1.1084 +#else
1.1085 +# error "Port!"
1.1086 +#endif
1.1087 +
1.1088 + return result;
1.1089 +}
1.1090 +
1.1091 +
1.1092 +// Attempts to memory-map len bytes of the current file, starting
1.1093 +// at position offset. Precondition: offset is a multiple of the
1.1094 +// page size. Postcondition: return value is a null pointer if the
1.1095 +// memory mapping failed. Otherwise the return value is a pointer to
1.1096 +// the memory-mapped file and the file position is set to offset.
1.1097 +_STLP_DECLSPEC void* _Filebuf_base::_M_mmap(streamoff offset, streamoff len) {
1.1098 + void* base;
1.1099 +#if defined (_STLP_UNIX) && !defined(__DJGPP) && !defined(_CRAY)
1.1100 + base = MMAP(0, len, PROT_READ, MAP_PRIVATE, _M_file_id, offset);
1.1101 + if (base != (void*)MAP_FAILED) {
1.1102 + if (LSEEK(_M_file_id, offset + len, SEEK_SET) < 0) {
1.1103 + this->_M_unmap(base, len);
1.1104 + base = 0;
1.1105 + }
1.1106 + } else
1.1107 + base =0;
1.1108 +
1.1109 +#elif defined (_STLP_USE_WIN32_IO)
1.1110 + _M_view_id = CreateFileMapping(_M_file_id, (PSECURITY_ATTRIBUTES)0 ,
1.1111 + PAGE_READONLY, 0 /* len >> 32 */ ,
1.1112 + 0 /* len & 0xFFFFFFFF */ , // low-order DWORD of size
1.1113 + 0);
1.1114 +
1.1115 + if (_M_view_id) {
1.1116 +# if 0
1.1117 +/*
1.1118 + printf("view %x created from file %x, error = %d, size = %d, map_offset = %d map_len = %d\n",
1.1119 + _M_view_id, _M_file_id, GetLastError(),
1.1120 + (int)cur_filesize, ULL(offset) & 0xffffffff, len);
1.1121 +*/
1.1122 +# endif
1.1123 + base = MapViewOfFile(_M_view_id, FILE_MAP_READ, __STATIC_CAST(DWORD, ULL(offset) >> 32),
1.1124 + __STATIC_CAST(DWORD, ULL(offset) & 0xffffffff),
1.1125 +# if !defined (__DMC__)
1.1126 + __STATIC_CAST(SIZE_T, len));
1.1127 +# else
1.1128 + __STATIC_CAST(DWORD, len));
1.1129 +# endif
1.1130 + // check if mapping succeded and is usable
1.1131 + if (base == 0 || _M_seek(offset + len, ios_base::beg) < 0) {
1.1132 + this->_M_unmap(base, len);
1.1133 + base = 0;
1.1134 + }
1.1135 + } else
1.1136 + base = 0;
1.1137 +#else
1.1138 + (void)len; //*TY 02/26/2000 - unused variables
1.1139 + (void)offset; //*TY 02/26/2000 -
1.1140 + base = 0;
1.1141 +#endif
1.1142 + return base;
1.1143 +}
1.1144 +
1.1145 +_STLP_DECLSPEC void _Filebuf_base::_M_unmap(void* base, streamoff len) {
1.1146 + // precondition : there is a valid mapping at the moment
1.1147 +#if defined (_STLP_UNIX) && !defined(__DJGPP) && !defined(_CRAY)
1.1148 + munmap((char*)base, len);
1.1149 +#elif defined (_STLP_USE_WIN32_IO)
1.1150 + if (base != NULL)
1.1151 + UnmapViewOfFile(base);
1.1152 + // destroy view handle as well
1.1153 + if (_M_view_id != NULL)
1.1154 + CloseHandle(_M_view_id);
1.1155 + _M_view_id = NULL;
1.1156 + (void)len; //unused variable
1.1157 +#else
1.1158 + (void)len; //*TY 02/26/2000 - unused variables
1.1159 + (void)base; //*TY 02/26/2000 -
1.1160 +#endif
1.1161 +}
1.1162 +
1.1163 +#if defined (__SYMBIAN32__) && defined(__EPOC32__)
1.1164 +_STLP_DECLSPEC size_t _Filebuf_base::__page_size()
1.1165 +{
1.1166 + return _Filebuf_base::_M_page_size;
1.1167 +}
1.1168 +#endif
1.1169 +// fbp : let us map 1 MB maximum, just be sure not to trash VM
1.1170 +#define MMAP_CHUNK 0x100000L
1.1171 +
1.1172 +_STLP_DECLSPEC int _STLP_CALL
1.1173 +_Underflow<char, char_traits<char> >::_M_doit (basic_filebuf<char, char_traits<char> >* __this) {
1.1174 + if (!__this->_M_in_input_mode) {
1.1175 + if (!__this->_M_switch_to_input_mode())
1.1176 + return traits_type::eof();
1.1177 + }
1.1178 + else if (__this->_M_in_putback_mode) {
1.1179 + __this->_M_exit_putback_mode();
1.1180 + if (__this->gptr() != __this->egptr()) {
1.1181 + int_type __c = traits_type::to_int_type(*__this->gptr());
1.1182 + return __c;
1.1183 + }
1.1184 + }
1.1185 +
1.1186 + // If it's a disk file, and if the internal and external character
1.1187 + // sequences are guaranteed to be identical, then try to use memory
1.1188 + // mapped I/O. Otherwise, revert to ordinary read.
1.1189 + if (__this->_M_base.__regular_file()
1.1190 + && __this->_M_always_noconv
1.1191 + && __this->_M_base._M_in_binary_mode()) {
1.1192 + // If we've mmapped part of the file already, then unmap it.
1.1193 + if (__this->_M_mmap_base)
1.1194 + __this->_M_base._M_unmap(__this->_M_mmap_base, __this->_M_mmap_len);
1.1195 + __this->_M_mmap_base = 0;
1.1196 + __this->_M_mmap_len = 0;
1.1197 +
1.1198 + // Determine the position where we start mapping. It has to be
1.1199 + // a multiple of the page size.
1.1200 + streamoff __cur = __this->_M_base._M_seek(0, ios_base::cur);
1.1201 + streamoff __size = __this->_M_base._M_file_size();
1.1202 + if (__size > 0 && __cur >= 0 && __cur < __size) {
1.1203 + streamoff __offset = (__cur / __this->_M_base.__page_size()) * __this->_M_base.__page_size();
1.1204 + streamoff __remainder = __cur - __offset;
1.1205 +
1.1206 + __this->_M_mmap_len = __size - __offset;
1.1207 +
1.1208 + if (__this->_M_mmap_len > MMAP_CHUNK)
1.1209 + __this->_M_mmap_len = MMAP_CHUNK;
1.1210 +
1.1211 + if ((__this->_M_mmap_base =
1.1212 + __this->_M_base._M_mmap(__offset, __this->_M_mmap_len)) != 0) {
1.1213 + __this->setg((char*) __this->_M_mmap_base,
1.1214 + (char*) __this->_M_mmap_base + __STATIC_CAST(ptrdiff_t, __remainder),
1.1215 + (char*) __this->_M_mmap_base + __STATIC_CAST(ptrdiff_t, __this->_M_mmap_len));
1.1216 + return traits_type::to_int_type(*__this->gptr());
1.1217 + }
1.1218 + } else /* size > 0 ... */ {
1.1219 + // There is nothing to map. We unmapped the file above, now zap pointers.
1.1220 + __this->_M_mmap_base = 0;
1.1221 + __this->_M_mmap_len = 0;
1.1222 + }
1.1223 + }
1.1224 +
1.1225 + return __this->_M_underflow_aux();
1.1226 +}
1.1227 +
1.1228 +
1.1229 +//----------------------------------------------------------------------
1.1230 +// Force instantiation of filebuf and fstream classes.
1.1231 +#if !defined(_STLP_NO_FORCE_INSTANTIATE)
1.1232 +
1.1233 +template class basic_filebuf<char, char_traits<char> >;
1.1234 +template class basic_ifstream<char, char_traits<char> >;
1.1235 +template class basic_ofstream<char, char_traits<char> >;
1.1236 +template class basic_fstream<char, char_traits<char> >;
1.1237 +
1.1238 +# if !defined (_STLP_NO_WCHAR_T)
1.1239 +template class _Underflow<wchar_t, char_traits<wchar_t> >;
1.1240 +template class basic_filebuf<wchar_t, char_traits<wchar_t> >;
1.1241 +template class basic_ifstream<wchar_t, char_traits<wchar_t> >;
1.1242 +template class basic_ofstream<wchar_t, char_traits<wchar_t> >;
1.1243 +template class basic_fstream<wchar_t, char_traits<wchar_t> >;
1.1244 +# endif /* _STLP_NO_WCHAR_T */
1.1245 +
1.1246 +#endif
1.1247 +
1.1248 +_STLP_END_NAMESPACE
1.1249 +
1.1250 +// Local Variables:
1.1251 +// mode:C++
1.1252 +// End: