1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/build/stlport/src/details/fstream_win32io.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,629 @@ 1.4 +/* 1.5 + * Copyright (c) 1999 1.6 + * Silicon Graphics Computer Systems, Inc. 1.7 + * 1.8 + * Copyright (c) 1999 1.9 + * Boris Fomitchev 1.10 + * 1.11 + * This material is provided "as is", with absolutely no warranty expressed 1.12 + * or implied. Any use is at your own risk. 1.13 + * 1.14 + * Permission to use or copy this software for any purpose is hereby granted 1.15 + * without fee, provided the above notices are retained on all copies. 1.16 + * Permission to modify the code and to distribute modified code is granted, 1.17 + * provided the above notices are retained, and a notice that the code was 1.18 + * modified is included with the above copyright notice. 1.19 + * 1.20 + */ 1.21 + 1.22 +#include <fstream> 1.23 + 1.24 +#if !defined (_STLP_WCE) 1.25 +# ifdef __BORLANDC__ 1.26 +# include <cfcntl.h> // For _O_RDONLY, etc 1.27 +# else 1.28 +# include <io.h> // For _get_osfhandle 1.29 +# include <fcntl.h> // For _O_RDONLY, etc 1.30 +# endif 1.31 +# include <sys/stat.h> // For _fstat 1.32 +#endif 1.33 + 1.34 +#define _TEXTBUF_SIZE 0x1000 1.35 + 1.36 +const _STLP_fd INVALID_STLP_FD = INVALID_HANDLE_VALUE; 1.37 + 1.38 +#if !defined (INVALID_SET_FILE_POINTER) 1.39 +# define INVALID_SET_FILE_POINTER 0xffffffff 1.40 +#endif 1.41 + 1.42 +#ifndef O_ACCMODE 1.43 +# define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) 1.44 +#endif 1.45 + 1.46 +_STLP_BEGIN_NAMESPACE 1.47 + 1.48 +#if !defined(__MSL__) && !defined(_STLP_WCE) 1.49 +static ios_base::openmode flag_to_openmode(int mode) { 1.50 + ios_base::openmode ret = ios_base::__default_mode; 1.51 + 1.52 + switch (mode & O_ACCMODE) { 1.53 + case O_RDONLY: 1.54 + ret = ios_base::in; break; 1.55 + case O_WRONLY: 1.56 + ret = ios_base::out; break; 1.57 + case O_RDWR: 1.58 + ret = ios_base::in | ios_base::out; break; 1.59 + } 1.60 + 1.61 + if (mode & O_APPEND) 1.62 + ret |= ios_base::app; 1.63 + 1.64 + if (mode & O_BINARY) 1.65 + ret |= ios_base::binary; 1.66 + 1.67 + return ret; 1.68 +} 1.69 +#endif 1.70 + 1.71 +_STLP_MOVE_TO_PRIV_NAMESPACE 1.72 + 1.73 +// Helper functions for _Filebuf_base. 1.74 + 1.75 +static bool __is_regular_file(_STLP_fd fd) { 1.76 + BY_HANDLE_FILE_INFORMATION info; 1.77 + 1.78 + // Return true if the file handle isn't a directory. 1.79 + return GetFileInformationByHandle(fd, &info) && 1.80 + ((info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0); 1.81 +} 1.82 + 1.83 +// Number of characters in the file. 1.84 +static streamoff __file_size(_STLP_fd fd) { 1.85 + streamoff ret = 0; 1.86 + 1.87 + LARGE_INTEGER li; 1.88 + li.LowPart = GetFileSize(fd, (unsigned long*) &li.HighPart); 1.89 + if (li.LowPart != INVALID_FILE_SIZE || GetLastError() == NO_ERROR) 1.90 + ret = li.QuadPart; 1.91 + 1.92 + return ret; 1.93 +} 1.94 + 1.95 +_STLP_MOVE_TO_STD_NAMESPACE 1.96 + 1.97 +// Visual C++ and Intel use this, but not Metrowerks 1.98 +// Also MinGW, msvcrt.dll (but not crtdll.dll) dependent version 1.99 +#if (defined (_STLP_MSVC_LIB) && !defined (_STLP_WCE)) || \ 1.100 + (defined (__MINGW32__) && defined (__MSVCRT__)) 1.101 + 1.102 +// fcntl(fileno, F_GETFL) for Microsoft library 1.103 +// 'semi-documented' defines: 1.104 +# define IOINFO_L2E 5 1.105 +# define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E) 1.106 +# define _pioinfo(i) ( __pioinfo[(i) >> IOINFO_L2E] + \ 1.107 + ((i) & (IOINFO_ARRAY_ELTS - 1)) ) 1.108 +# define FAPPEND 0x20 // O_APPEND flag 1.109 +# define FTEXT 0x80 // O_TEXT flag 1.110 +// end of 'semi-documented' defines 1.111 + 1.112 +// 'semi-documented' internal structure 1.113 +extern "C" { 1.114 + struct ioinfo { 1.115 + long osfhnd; // the real os HANDLE 1.116 + char osfile; // file handle flags 1.117 + char pipech; // pipe buffer 1.118 +# if defined (_MT) 1.119 + // multi-threaded locking 1.120 + int lockinitflag; 1.121 + CRITICAL_SECTION lock; 1.122 +# endif 1.123 + }; 1.124 +# if defined (__MINGW32__) 1.125 + __MINGW_IMPORT ioinfo * __pioinfo[]; 1.126 +# else 1.127 + extern _CRTIMP ioinfo * __pioinfo[]; 1.128 +# endif 1.129 +} // extern "C" 1.130 +// end of 'semi-documented' declarations 1.131 + 1.132 +static ios_base::openmode _get_osfflags(int fd, HANDLE oshandle) { 1.133 + char dosflags = 0; 1.134 + if (fd >= 0) 1.135 + dosflags = _pioinfo(fd)->osfile; 1.136 + //else 1.137 + //the file will be considered as open in binary mode with no append attribute 1.138 + // end of 'semi-documented' stuff 1.139 + 1.140 + int mode = 0; 1.141 + if (dosflags & FAPPEND) 1.142 + mode |= O_APPEND; 1.143 + 1.144 + if (dosflags & FTEXT) 1.145 + mode |= O_TEXT; 1.146 + else 1.147 + mode |= O_BINARY; 1.148 + 1.149 + // For Read/Write access we have to guess 1.150 + DWORD dummy, dummy2; 1.151 + BOOL writeOk = WriteFile(oshandle, &dummy2, 0, &dummy, 0); 1.152 + BOOL readOk = ReadFile(oshandle, &dummy2, 0, &dummy, NULL); 1.153 + if (writeOk && readOk) 1.154 + mode |= O_RDWR; 1.155 + else if (readOk) 1.156 + mode |= O_RDONLY; 1.157 + else 1.158 + mode |= O_WRONLY; 1.159 + 1.160 + return flag_to_openmode(mode); 1.161 +} 1.162 + 1.163 +#elif defined (__DMC__) 1.164 + 1.165 +# define FHND_APPEND 0x04 1.166 +# define FHND_DEVICE 0x08 1.167 +# define FHND_TEXT 0x10 1.168 + 1.169 +extern "C" unsigned char __fhnd_info[_NFILE]; 1.170 + 1.171 +static ios_base::openmode _get_osfflags(int fd, HANDLE oshandle) { 1.172 + int mode = 0; 1.173 + 1.174 + if (__fhnd_info[fd] & FHND_APPEND) 1.175 + mode |= O_APPEND; 1.176 + 1.177 + if (__fhnd_info[fd] & FHND_TEXT == 0) 1.178 + mode |= O_BINARY; 1.179 + 1.180 + for (FILE *fp = &_iob[0]; fp < &_iob[_NFILE]; fp++) { 1.181 + if ((fileno(fp) == fd) && (fp->_flag & (_IOREAD | _IOWRT | _IORW))) { 1.182 + const int osflags = fp->_flag; 1.183 + 1.184 + if ((osflags & _IOREAD) && !(osflags & _IOWRT) && !(osflags & _IORW)) 1.185 + mode |= O_RDONLY; 1.186 + else if ((osflags & _IOWRT) && !(osflags & _IOREAD) && !(osflags & _IORW)) 1.187 + mode |= O_WRONLY; 1.188 + else 1.189 + mode |= O_RDWR; 1.190 + break; 1.191 + } 1.192 + } 1.193 + 1.194 + return flag_to_openmode(mode); 1.195 +} 1.196 +#endif 1.197 + 1.198 +size_t _Filebuf_base::_M_page_size = 4096; 1.199 + 1.200 +_Filebuf_base::_Filebuf_base() 1.201 + : _M_file_id(INVALID_STLP_FD), 1.202 + _M_openmode(0), 1.203 + _M_is_open(false), 1.204 + _M_should_close(false), 1.205 + _M_view_id(0) 1.206 +{} 1.207 + 1.208 +void _Filebuf_base::_S_initialize() { 1.209 + SYSTEM_INFO SystemInfo; 1.210 + GetSystemInfo(&SystemInfo); 1.211 + _M_page_size = SystemInfo.dwPageSize; 1.212 + // might be .dwAllocationGranularity 1.213 +} 1.214 + 1.215 +// Return the size of the file. This is a wrapper for stat. 1.216 +// Returns zero if the size cannot be determined or is ill-defined. 1.217 +streamoff _Filebuf_base::_M_file_size() { 1.218 + return _STLP_PRIV __file_size(_M_file_id); 1.219 +} 1.220 + 1.221 +bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode, 1.222 + long permission) { 1.223 + _STLP_fd file_no; 1.224 + 1.225 + if (_M_is_open) 1.226 + return false; 1.227 + 1.228 + DWORD dwDesiredAccess, dwCreationDisposition; 1.229 + bool doTruncate = false; 1.230 + 1.231 + switch (openmode & (~ios_base::ate & ~ios_base::binary)) { 1.232 + case ios_base::out: 1.233 + case ios_base::out | ios_base::trunc: 1.234 + dwDesiredAccess = GENERIC_WRITE; 1.235 + dwCreationDisposition = OPEN_ALWAYS; 1.236 + // boris : even though it is very non-intuitive, standard 1.237 + // requires them both to behave same. 1.238 + doTruncate = true; 1.239 + break; 1.240 + case ios_base::out | ios_base::app: 1.241 + dwDesiredAccess = GENERIC_WRITE; 1.242 + dwCreationDisposition = OPEN_ALWAYS; 1.243 + break; 1.244 + case ios_base::in: 1.245 + dwDesiredAccess = GENERIC_READ; 1.246 + dwCreationDisposition = OPEN_EXISTING; 1.247 + permission = 0; // Irrelevant unless we're writing. 1.248 + break; 1.249 + case ios_base::in | ios_base::out: 1.250 + dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; 1.251 + dwCreationDisposition = OPEN_EXISTING; 1.252 + break; 1.253 + case ios_base::in | ios_base::out | ios_base::trunc: 1.254 + dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; 1.255 + dwCreationDisposition = OPEN_ALWAYS; 1.256 + doTruncate = true; 1.257 + break; 1.258 + default: // The above are the only combinations of 1.259 + return false; // flags allowed by the C++ standard. 1.260 + } 1.261 + 1.262 + DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; 1.263 + 1.264 +#if defined(_STLP_USE_WIDE_INTERFACE) 1.265 + file_no = CreateFile (_STLP_PRIV __ASCIIToWide(name).c_str(), 1.266 +#else 1.267 + file_no = CreateFileA(name, 1.268 +#endif 1.269 + dwDesiredAccess, dwShareMode, 0, 1.270 + dwCreationDisposition, permission, 0); 1.271 + 1.272 + if (file_no == INVALID_STLP_FD) 1.273 + return false; 1.274 + 1.275 + if ( 1.276 +#if !defined (_STLP_WCE) 1.277 + GetFileType(file_no) == FILE_TYPE_DISK && 1.278 +#endif 1.279 + ((doTruncate && SetEndOfFile(file_no) == 0) || 1.280 + (((openmode & ios_base::ate) != 0) && 1.281 + (SetFilePointer(file_no, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER)))) { 1.282 + CloseHandle(file_no); 1.283 + return false; 1.284 + } 1.285 + 1.286 + _M_is_open = true; 1.287 + _M_file_id = file_no; 1.288 + _M_should_close = _M_is_open; 1.289 + _M_openmode = openmode; 1.290 + 1.291 + if (_M_is_open) 1.292 + _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id); 1.293 + 1.294 + return (_M_is_open != 0); 1.295 +} 1.296 + 1.297 +bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode) { 1.298 + // This doesn't really grant everyone in the world read/write 1.299 + // access. On Unix, file-creation system calls always clear 1.300 + // bits that are set in the umask from the permissions flag. 1.301 + return this->_M_open(name, openmode, FILE_ATTRIBUTE_NORMAL); 1.302 +} 1.303 + 1.304 +bool _Filebuf_base::_M_open(_STLP_fd __id, ios_base::openmode init_mode) { 1.305 +#if (defined (_STLP_MSVC_LIB) && !defined (_STLP_WCE)) || \ 1.306 + (defined (__MINGW32__) && defined (__MSVCRT__)) || defined (__DMC__) 1.307 + 1.308 + if (_M_is_open || __id == INVALID_STLP_FD) 1.309 + return false; 1.310 + 1.311 + if (init_mode != ios_base::__default_mode) 1.312 + _M_openmode = init_mode; 1.313 + else 1.314 + _M_openmode = _get_osfflags(-1, __id); 1.315 + 1.316 + _M_is_open = true; 1.317 + _M_file_id = __id; 1.318 + _M_should_close = false; 1.319 + _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id); 1.320 + 1.321 + return true; 1.322 +#else 1.323 + (void)__id; 1.324 + (void)init_mode; // dwa 4/27/00 - suppress unused parameter warning 1.325 + 1.326 + // not available for the API 1.327 + return false; 1.328 + 1.329 +#endif 1.330 +} 1.331 + 1.332 +// Associated the filebuf with a file descriptor pointing to an already- 1.333 +// open file. Mode is set to be consistent with the way that the file 1.334 +// was opened. 1.335 +bool _Filebuf_base::_M_open(int file_no, ios_base::openmode init_mode) { 1.336 + if (_M_is_open || file_no < 0) 1.337 + return false; 1.338 + 1.339 +#if (defined (_STLP_MSVC_LIB) && !defined (_STLP_WCE)) || \ 1.340 + (defined (__MINGW32__) && defined (__MSVCRT__)) || defined (__DMC__) 1.341 + 1.342 + HANDLE oshandle = (HANDLE)_get_osfhandle(file_no); 1.343 + if (oshandle == INVALID_STLP_FD) 1.344 + return false; 1.345 + 1.346 + if (init_mode != ios_base::__default_mode) 1.347 + _M_openmode = init_mode; 1.348 + else 1.349 + _M_openmode = _get_osfflags(file_no, oshandle); 1.350 + 1.351 + _M_file_id = oshandle; 1.352 + _M_is_open = true; 1.353 + _M_should_close = false; 1.354 + _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id); 1.355 + return true; 1.356 +#else 1.357 + _STLP_MARK_PARAMETER_AS_UNUSED(&init_mode) 1.358 + // not available for the API 1.359 + return false; 1.360 +#endif 1.361 +} 1.362 + 1.363 +bool _Filebuf_base::_M_close() { 1.364 + if (!_M_is_open) 1.365 + return false; 1.366 + 1.367 + bool ok; 1.368 + 1.369 + if (!_M_should_close) 1.370 + ok = true; 1.371 + else { 1.372 + if (_M_file_id != INVALID_STLP_FD) { 1.373 + ok = (CloseHandle(_M_file_id) != 0); 1.374 + } 1.375 + else { 1.376 + ok = false; 1.377 + } 1.378 + } 1.379 + 1.380 + _M_is_open = _M_should_close = false; 1.381 + _M_openmode = 0; 1.382 + return ok; 1.383 +} 1.384 + 1.385 + 1.386 +#define _STLP_LF 10 1.387 +#define _STLP_CR 13 1.388 +#define _STLP_CTRLZ 26 1.389 + 1.390 +// Read up to n characters into a buffer. Return value is number of 1.391 +// characters read. 1.392 +ptrdiff_t _Filebuf_base::_M_read(char* buf, ptrdiff_t n) { 1.393 + ptrdiff_t readen = 0; 1.394 + //Here cast to size_t is safe as n cannot be negative. 1.395 + size_t chunkSize = (min)(size_t(0xffffffff), __STATIC_CAST(size_t, n)); 1.396 + // The following, while validating that we are still able to extract chunkSize 1.397 + // charaters to the buffer, avoids extraction of too small chunk of datas 1.398 + // which would be counter performant. 1.399 + while (__STATIC_CAST(size_t, (n - readen)) >= chunkSize) { 1.400 + DWORD numberOfBytesRead; 1.401 + ReadFile(_M_file_id, buf + readen, __STATIC_CAST(DWORD, chunkSize), &numberOfBytesRead, 0); 1.402 + 1.403 + if (numberOfBytesRead == 0) 1.404 + break; 1.405 + 1.406 + if (!(_M_openmode & ios_base::binary)) { 1.407 + // translate CR-LFs to LFs in the buffer 1.408 + char *to = buf + readen; 1.409 + char *from = to; 1.410 + char *last = from + numberOfBytesRead - 1; 1.411 + for (; from <= last && *from != _STLP_CTRLZ; ++from) { 1.412 + if (*from != _STLP_CR) 1.413 + *to++ = *from; 1.414 + else { // found CR 1.415 + if (from < last) { // not at buffer end 1.416 + if (*(from + 1) != _STLP_LF) 1.417 + *to++ = _STLP_CR; 1.418 + } 1.419 + else { // last char is CR, peek for LF 1.420 + char peek = ' '; 1.421 + DWORD NumberOfBytesPeeked; 1.422 + ReadFile(_M_file_id, (LPVOID)&peek, 1, &NumberOfBytesPeeked, 0); 1.423 + if (NumberOfBytesPeeked != 0) { 1.424 + if (peek != _STLP_LF) { //not a <CR><LF> combination 1.425 + *to++ = _STLP_CR; 1.426 + if ((to < buf + n) && (peek != _STLP_CR)) 1.427 + //We have enough place to store peek and it is no a special 1.428 + //_STLP_CR character, we can store it. 1.429 + *to++ = peek; 1.430 + else 1.431 + SetFilePointer(_M_file_id, (LONG)-1, 0, FILE_CURRENT); 1.432 + } 1.433 + else { 1.434 + // A <CR><LF> combination, we keep the <LF>: 1.435 + *to++ = _STLP_LF; 1.436 + } 1.437 + } 1.438 + else { 1.439 + /* This case is tedious, we could 1.440 + * - put peek back in the file but this would then generate an infinite loop 1.441 + * - report an error as we don't know if in a future call to ReadFile we won't then 1.442 + * get a <LF>. Doing so would make all files with a <CR> last an invalid file 1.443 + * for STLport, a hard solution for STLport clients. 1.444 + * - store the <CR> in the returned buffer, the chosen solution, even if in this 1.445 + * case we could miss a <CR><LF> combination. 1.446 + */ 1.447 + *to++ = _STLP_CR; 1.448 + } 1.449 + } 1.450 + } // found CR 1.451 + } // for 1.452 + readen = to - buf; 1.453 + // seek back to TEXT end of file if hit CTRL-Z 1.454 + if (from <= last) { // terminated due to CTRLZ 1.455 + SetFilePointer(_M_file_id, -(LONG)((last + 1) - from), 0, FILE_CURRENT); 1.456 + break; 1.457 + } 1.458 + } 1.459 + else 1.460 + readen += numberOfBytesRead; 1.461 + } 1.462 + return readen; 1.463 +} 1.464 + 1.465 +// Write n characters from a buffer. Return value: true if we managed 1.466 +// to write the entire buffer, false if we didn't. 1.467 +bool _Filebuf_base::_M_write(char* buf, ptrdiff_t n) { 1.468 + for (;;) { 1.469 + ptrdiff_t written; 1.470 + 1.471 + //In the following implementation we are going to cast most of the ptrdiff_t 1.472 + //values in size_t to work with coherent unsigned values. Doing so make code 1.473 + //more simple especially in the min function call. 1.474 + 1.475 + // In append mode, every write does an implicit seek to the end 1.476 + // of the file. 1.477 + if (_M_openmode & ios_base::app) 1.478 + _M_seek(0, ios_base::end); 1.479 + 1.480 + if (_M_openmode & ios_base::binary) { 1.481 + // binary mode 1.482 + size_t bytes_to_write = (size_t)n; 1.483 + DWORD NumberOfBytesWritten; 1.484 + written = 0; 1.485 + for (; bytes_to_write != 0;) { 1.486 + WriteFile(_M_file_id, buf + written, 1.487 + __STATIC_CAST(DWORD, (min)(size_t(0xffffffff), bytes_to_write)), 1.488 + &NumberOfBytesWritten, 0); 1.489 + if (NumberOfBytesWritten == 0) 1.490 + return false; 1.491 + bytes_to_write -= NumberOfBytesWritten; 1.492 + written += NumberOfBytesWritten; 1.493 + } 1.494 + } 1.495 + else { 1.496 + char textbuf[_TEXTBUF_SIZE + 1]; // extra 1 in case LF at end 1.497 + char * nextblock = buf, * ptrtextbuf = textbuf; 1.498 + char * endtextbuf = textbuf + _TEXTBUF_SIZE; 1.499 + char * endblock = buf + n; 1.500 + ptrdiff_t nextblocksize = (min) (n, (ptrdiff_t)_TEXTBUF_SIZE); 1.501 + char * nextlf; 1.502 + 1.503 + while ( (nextblocksize > 0) && 1.504 + (nextlf = (char *)memchr(nextblock, _STLP_LF, nextblocksize)) != 0) { 1.505 + ptrdiff_t linelength = nextlf - nextblock; 1.506 + memcpy(ptrtextbuf, nextblock, linelength); 1.507 + ptrtextbuf += linelength; 1.508 + nextblock += (linelength + 1); 1.509 + * ptrtextbuf ++ = _STLP_CR; 1.510 + * ptrtextbuf ++ = _STLP_LF; 1.511 + nextblocksize = (min) (ptrdiff_t(endblock - nextblock), 1.512 + (max) (ptrdiff_t(0), ptrdiff_t(endtextbuf - ptrtextbuf))); 1.513 + } 1.514 + // write out what's left, > condition is here since for LF at the end , 1.515 + // endtextbuf may get < ptrtextbuf ... 1.516 + if (nextblocksize > 0) { 1.517 + memcpy(ptrtextbuf, nextblock, nextblocksize); 1.518 + ptrtextbuf += nextblocksize; 1.519 + nextblock += nextblocksize; 1.520 + } 1.521 + // now write out the translated buffer 1.522 + char * writetextbuf = textbuf; 1.523 + for (size_t NumberOfBytesToWrite = (size_t)(ptrtextbuf - textbuf); 1.524 + NumberOfBytesToWrite;) { 1.525 + DWORD NumberOfBytesWritten; 1.526 + WriteFile((HANDLE)_M_file_id, writetextbuf, 1.527 + __STATIC_CAST(DWORD, (min)(size_t(0xffffffff), NumberOfBytesToWrite)), 1.528 + &NumberOfBytesWritten, 0); 1.529 + if (!NumberOfBytesWritten) // write shortfall 1.530 + return false; 1.531 + writetextbuf += NumberOfBytesWritten; 1.532 + NumberOfBytesToWrite -= NumberOfBytesWritten; 1.533 + } 1.534 + // count non-translated characters 1.535 + written = (nextblock - buf); 1.536 + } 1.537 + 1.538 + if (n == written) 1.539 + return true; 1.540 + else if (written > 0 && written < n) { 1.541 + n -= written; 1.542 + buf += written; 1.543 + } 1.544 + else 1.545 + return false; 1.546 + } 1.547 +} 1.548 + 1.549 +// Wrapper for lseek or the like. 1.550 +streamoff _Filebuf_base::_M_seek(streamoff offset, ios_base::seekdir dir) { 1.551 + streamoff result = -1; 1.552 + int whence; 1.553 + 1.554 + switch(dir) { 1.555 + case ios_base::beg: 1.556 + if (offset < 0 /* || offset > _M_file_size() */ ) 1.557 + return streamoff(-1); 1.558 + whence = FILE_BEGIN; 1.559 + break; 1.560 + case ios_base::cur: 1.561 + whence = FILE_CURRENT; 1.562 + break; 1.563 + case ios_base::end: 1.564 + if (/* offset > 0 || */ -offset > _M_file_size() ) 1.565 + return streamoff(-1); 1.566 + whence = FILE_END; 1.567 + break; 1.568 + default: 1.569 + return streamoff(-1); 1.570 + } 1.571 + 1.572 + LARGE_INTEGER li; 1.573 + li.QuadPart = offset; 1.574 + li.LowPart = SetFilePointer(_M_file_id, li.LowPart, &li.HighPart, whence); 1.575 + if (li.LowPart != INVALID_SET_FILE_POINTER || GetLastError() == NO_ERROR) 1.576 + result = li.QuadPart; 1.577 + 1.578 + return result; 1.579 +} 1.580 + 1.581 + 1.582 +// Attempts to memory-map len bytes of the current file, starting 1.583 +// at position offset. Precondition: offset is a multiple of the 1.584 +// page size. Postcondition: return value is a null pointer if the 1.585 +// memory mapping failed. Otherwise the return value is a pointer to 1.586 +// the memory-mapped file and the file position is set to offset. 1.587 +void* _Filebuf_base::_M_mmap(streamoff offset, streamoff len) { 1.588 + void* base; 1.589 + _M_view_id = CreateFileMapping(_M_file_id, (PSECURITY_ATTRIBUTES)0 , 1.590 + PAGE_READONLY, 0 /* len >> 32 */ , 1.591 + 0 /* len & 0xFFFFFFFF */ , // low-order DWORD of size 1.592 + 0); 1.593 + 1.594 + if (_M_view_id) { 1.595 +#if 0 1.596 +/* 1.597 + printf("view %x created from file %x, error = %d, size = %d, map_offset = %d map_len = %d\n", 1.598 + _M_view_id, _M_file_id, GetLastError(), 1.599 + (int)cur_filesize, ULL(offset) & 0xffffffff, len); 1.600 +*/ 1.601 +#endif 1.602 + LARGE_INTEGER li; 1.603 + li.QuadPart = offset; 1.604 + base = MapViewOfFile(_M_view_id, FILE_MAP_READ, li.HighPart, li.LowPart, 1.605 +#if !defined (__DMC__) 1.606 + __STATIC_CAST(SIZE_T, len)); 1.607 +#else 1.608 + __STATIC_CAST(DWORD, len)); 1.609 +#endif 1.610 + // check if mapping succeded and is usable 1.611 + if (base == 0 || _M_seek(offset + len, ios_base::beg) < 0) { 1.612 + this->_M_unmap(base, len); 1.613 + base = 0; 1.614 + } 1.615 + } else 1.616 + base = 0; 1.617 + 1.618 + return base; 1.619 +} 1.620 + 1.621 +void _Filebuf_base::_M_unmap(void* base, streamoff len) { 1.622 + // precondition : there is a valid mapping at the moment 1.623 + if (base != NULL) 1.624 + UnmapViewOfFile(base); 1.625 + // destroy view handle as well 1.626 + if (_M_view_id != NULL) 1.627 + CloseHandle(_M_view_id); 1.628 + _M_view_id = NULL; 1.629 + (void)len; //unused variable 1.630 +} 1.631 + 1.632 +_STLP_END_NAMESPACE