177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner/* 277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * Copyright (c) 1999 377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * Silicon Graphics Computer Systems, Inc. 477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * 577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * Copyright (c) 1999 677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * Boris Fomitchev 777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * 877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * This material is provided "as is", with absolutely no warranty expressed 977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * or implied. Any use is at your own risk. 1077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * 1177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * Permission to use or copy this software for any purpose is hereby granted 1277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * without fee, provided the above notices are retained on all copies. 1377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * Permission to modify the code and to distribute modified code is granted, 1477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * provided the above notices are retained, and a notice that the code was 1577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * modified is included with the above copyright notice. 1677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * 1777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner */ 1877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 1977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#include <fstream> 2077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 2177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#if !defined (_STLP_WCE) 2277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner# ifdef __BORLANDC__ 2377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner# include <cfcntl.h> // For _O_RDONLY, etc 2477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner# else 2577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner# include <io.h> // For _get_osfhandle 2677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner# include <fcntl.h> // For _O_RDONLY, etc 2777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner# endif 2877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner# include <sys/stat.h> // For _fstat 2977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#endif 3077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 3177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#define _TEXTBUF_SIZE 0x1000 3277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 3377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerconst _STLP_fd INVALID_STLP_FD = INVALID_HANDLE_VALUE; 3477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 3577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#if !defined (INVALID_SET_FILE_POINTER) 3677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner# define INVALID_SET_FILE_POINTER 0xffffffff 3777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#endif 3877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 3977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#ifndef O_ACCMODE 4077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner# define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) 4177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#endif 4277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 4377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner_STLP_BEGIN_NAMESPACE 4477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 4577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#if !defined(__MSL__) && !defined(_STLP_WCE) 4677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerstatic ios_base::openmode flag_to_openmode(int mode) { 4777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner ios_base::openmode ret = ios_base::__default_mode; 4877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 4977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner switch (mode & O_ACCMODE) { 5077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner case O_RDONLY: 5177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner ret = ios_base::in; break; 5277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner case O_WRONLY: 5377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner ret = ios_base::out; break; 5477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner case O_RDWR: 5577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner ret = ios_base::in | ios_base::out; break; 5677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 5777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 5877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (mode & O_APPEND) 5977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner ret |= ios_base::app; 6077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 6177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (mode & O_BINARY) 6277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner ret |= ios_base::binary; 6377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 6477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return ret; 6577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 6677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#endif 6777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 6877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner_STLP_MOVE_TO_PRIV_NAMESPACE 6977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 7077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner// Helper functions for _Filebuf_base. 7177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 7277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerstatic bool __is_regular_file(_STLP_fd fd) { 7377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner BY_HANDLE_FILE_INFORMATION info; 7477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 7577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // Return true if the file handle isn't a directory. 7677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return GetFileInformationByHandle(fd, &info) && 7777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner ((info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0); 7877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 7977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 8077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner// Number of characters in the file. 8177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerstatic streamoff __file_size(_STLP_fd fd) { 8277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner streamoff ret = 0; 8377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 8477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner LARGE_INTEGER li; 8577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner li.LowPart = GetFileSize(fd, (unsigned long*) &li.HighPart); 8677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (li.LowPart != INVALID_FILE_SIZE || GetLastError() == NO_ERROR) 8777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner ret = li.QuadPart; 8877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 8977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return ret; 9077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 9177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 9277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner_STLP_MOVE_TO_STD_NAMESPACE 9377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 9477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner// Visual C++ and Intel use this, but not Metrowerks 9577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner// Also MinGW, msvcrt.dll (but not crtdll.dll) dependent version 9677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#if (defined (_STLP_MSVC_LIB) && !defined (_STLP_WCE)) || \ 9777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner (defined (__MINGW32__) && defined (__MSVCRT__)) 9877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 9977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner// fcntl(fileno, F_GETFL) for Microsoft library 10077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner// 'semi-documented' defines: 10177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner# define IOINFO_L2E 5 10277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner# define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E) 10377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner# define _pioinfo(i) ( __pioinfo[(i) >> IOINFO_L2E] + \ 10477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner ((i) & (IOINFO_ARRAY_ELTS - 1)) ) 10577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner# define FAPPEND 0x20 // O_APPEND flag 10677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner# define FTEXT 0x80 // O_TEXT flag 10777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner// end of 'semi-documented' defines 10877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 10977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner// 'semi-documented' internal structure 11077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerextern "C" { 11177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner struct ioinfo { 11277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner long osfhnd; // the real os HANDLE 11377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner char osfile; // file handle flags 11477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner char pipech; // pipe buffer 11577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner# if defined (_MT) 11677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // multi-threaded locking 11777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner int lockinitflag; 11877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner CRITICAL_SECTION lock; 11977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner# endif 12077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner }; 12177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner# if defined (__MINGW32__) 12277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner __MINGW_IMPORT ioinfo * __pioinfo[]; 12377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner# else 12477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner extern _CRTIMP ioinfo * __pioinfo[]; 12577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner# endif 12677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} // extern "C" 12777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner// end of 'semi-documented' declarations 12877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 12977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerstatic ios_base::openmode _get_osfflags(int fd, HANDLE oshandle) { 13077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner char dosflags = 0; 13177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (fd >= 0) 13277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner dosflags = _pioinfo(fd)->osfile; 13377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner //else 13477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner //the file will be considered as open in binary mode with no append attribute 13577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // end of 'semi-documented' stuff 13677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 13777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner int mode = 0; 13877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (dosflags & FAPPEND) 13977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner mode |= O_APPEND; 14077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 14177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (dosflags & FTEXT) 14277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner mode |= O_TEXT; 14377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner else 14477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner mode |= O_BINARY; 14577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 14677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // For Read/Write access we have to guess 14777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner DWORD dummy, dummy2; 14877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner BOOL writeOk = WriteFile(oshandle, &dummy2, 0, &dummy, 0); 14977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner BOOL readOk = ReadFile(oshandle, &dummy2, 0, &dummy, NULL); 15077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (writeOk && readOk) 15177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner mode |= O_RDWR; 15277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner else if (readOk) 15377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner mode |= O_RDONLY; 15477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner else 15577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner mode |= O_WRONLY; 15677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 15777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return flag_to_openmode(mode); 15877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 15977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 16077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#elif defined (__DMC__) 16177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 16277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner# define FHND_APPEND 0x04 16377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner# define FHND_DEVICE 0x08 16477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner# define FHND_TEXT 0x10 16577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 16677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerextern "C" unsigned char __fhnd_info[_NFILE]; 16777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 16877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerstatic ios_base::openmode _get_osfflags(int fd, HANDLE oshandle) { 16977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner int mode = 0; 17077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 17177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (__fhnd_info[fd] & FHND_APPEND) 17277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner mode |= O_APPEND; 17377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 17477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (__fhnd_info[fd] & FHND_TEXT == 0) 17577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner mode |= O_BINARY; 17677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 17777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner for (FILE *fp = &_iob[0]; fp < &_iob[_NFILE]; fp++) { 17877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if ((fileno(fp) == fd) && (fp->_flag & (_IOREAD | _IOWRT | _IORW))) { 17977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner const int osflags = fp->_flag; 18077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 18177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if ((osflags & _IOREAD) && !(osflags & _IOWRT) && !(osflags & _IORW)) 18277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner mode |= O_RDONLY; 18377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner else if ((osflags & _IOWRT) && !(osflags & _IOREAD) && !(osflags & _IORW)) 18477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner mode |= O_WRONLY; 18577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner else 18677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner mode |= O_RDWR; 18777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner break; 18877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 18977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 19077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 19177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return flag_to_openmode(mode); 19277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 19377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#endif 19477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 19577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnersize_t _Filebuf_base::_M_page_size = 4096; 19677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 19777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner_Filebuf_base::_Filebuf_base() 19877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner : _M_file_id(INVALID_STLP_FD), 19977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_openmode(0), 20077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_is_open(false), 20177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_should_close(false), 20277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_view_id(0) 20377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner{} 20477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 20577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnervoid _Filebuf_base::_S_initialize() { 20677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner SYSTEM_INFO SystemInfo; 20777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner GetSystemInfo(&SystemInfo); 20877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_page_size = SystemInfo.dwPageSize; 20977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // might be .dwAllocationGranularity 21077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 21177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 21277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner// Return the size of the file. This is a wrapper for stat. 21377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner// Returns zero if the size cannot be determined or is ill-defined. 21477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerstreamoff _Filebuf_base::_M_file_size() { 21577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return _STLP_PRIV __file_size(_M_file_id); 21677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 21777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 21877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerbool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode, 21977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner long permission) { 22077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _STLP_fd file_no; 22177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 22277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (_M_is_open) 22377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return false; 22477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 22577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner DWORD dwDesiredAccess, dwCreationDisposition; 22677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner bool doTruncate = false; 22777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 22877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner switch (openmode & (~ios_base::ate & ~ios_base::binary)) { 22977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner case ios_base::out: 23077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner case ios_base::out | ios_base::trunc: 23177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner dwDesiredAccess = GENERIC_WRITE; 23277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner dwCreationDisposition = OPEN_ALWAYS; 23377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // boris : even though it is very non-intuitive, standard 23477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // requires them both to behave same. 23577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner doTruncate = true; 23677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner break; 23777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner case ios_base::out | ios_base::app: 23877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner dwDesiredAccess = GENERIC_WRITE; 23977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner dwCreationDisposition = OPEN_ALWAYS; 24077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner break; 24177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner case ios_base::in: 24277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner dwDesiredAccess = GENERIC_READ; 24377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner dwCreationDisposition = OPEN_EXISTING; 24477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner permission = 0; // Irrelevant unless we're writing. 24577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner break; 24677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner case ios_base::in | ios_base::out: 24777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; 24877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner dwCreationDisposition = OPEN_EXISTING; 24977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner break; 25077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner case ios_base::in | ios_base::out | ios_base::trunc: 25177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; 25277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner dwCreationDisposition = OPEN_ALWAYS; 25377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner doTruncate = true; 25477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner break; 25577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner default: // The above are the only combinations of 25677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return false; // flags allowed by the C++ standard. 25777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 25877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 25977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; 26077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 26177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#if defined(_STLP_USE_WIDE_INTERFACE) 26277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner file_no = CreateFile (_STLP_PRIV __ASCIIToWide(name).c_str(), 26377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#else 26477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner file_no = CreateFileA(name, 26577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#endif 26677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner dwDesiredAccess, dwShareMode, 0, 26777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner dwCreationDisposition, permission, 0); 26877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 26977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (file_no == INVALID_STLP_FD) 27077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return false; 27177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 27277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if ( 27377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#if !defined (_STLP_WCE) 27477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner GetFileType(file_no) == FILE_TYPE_DISK && 27577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#endif 27677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner ((doTruncate && SetEndOfFile(file_no) == 0) || 27777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner (((openmode & ios_base::ate) != 0) && 27877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner (SetFilePointer(file_no, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER)))) { 27977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner CloseHandle(file_no); 28077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return false; 28177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 28277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 28377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_is_open = true; 28477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_file_id = file_no; 28577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_should_close = _M_is_open; 28677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_openmode = openmode; 28777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 28877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (_M_is_open) 28977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id); 29077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 29177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return (_M_is_open != 0); 29277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 29377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 29477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerbool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode) { 29577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // This doesn't really grant everyone in the world read/write 29677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // access. On Unix, file-creation system calls always clear 29777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // bits that are set in the umask from the permissions flag. 29877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return this->_M_open(name, openmode, FILE_ATTRIBUTE_NORMAL); 29977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 30077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 30177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerbool _Filebuf_base::_M_open(_STLP_fd __id, ios_base::openmode init_mode) { 30277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#if (defined (_STLP_MSVC_LIB) && !defined (_STLP_WCE)) || \ 30377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner (defined (__MINGW32__) && defined (__MSVCRT__)) || defined (__DMC__) 30477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 30577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (_M_is_open || __id == INVALID_STLP_FD) 30677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return false; 30777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 30877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (init_mode != ios_base::__default_mode) 30977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_openmode = init_mode; 31077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner else 31177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_openmode = _get_osfflags(-1, __id); 31277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 31377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_is_open = true; 31477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_file_id = __id; 31577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_should_close = false; 31677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id); 31777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 31877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return true; 31977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#else 32077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner (void)__id; 32177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner (void)init_mode; // dwa 4/27/00 - suppress unused parameter warning 32277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 32377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // not available for the API 32477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return false; 32577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 32677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#endif 32777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 32877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 32977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner// Associated the filebuf with a file descriptor pointing to an already- 33077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner// open file. Mode is set to be consistent with the way that the file 33177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner// was opened. 33277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerbool _Filebuf_base::_M_open(int file_no, ios_base::openmode init_mode) { 33377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (_M_is_open || file_no < 0) 33477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return false; 33577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 33677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#if (defined (_STLP_MSVC_LIB) && !defined (_STLP_WCE)) || \ 33777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner (defined (__MINGW32__) && defined (__MSVCRT__)) || defined (__DMC__) 33877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 33977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner HANDLE oshandle = (HANDLE)_get_osfhandle(file_no); 34077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (oshandle == INVALID_STLP_FD) 34177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return false; 34277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 34377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (init_mode != ios_base::__default_mode) 34477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_openmode = init_mode; 34577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner else 34677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_openmode = _get_osfflags(file_no, oshandle); 34777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 34877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_file_id = oshandle; 34977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_is_open = true; 35077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_should_close = false; 35177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id); 35277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return true; 35377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#else 35477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _STLP_MARK_PARAMETER_AS_UNUSED(&init_mode) 35577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // not available for the API 35677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return false; 35777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#endif 35877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 35977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 36077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerbool _Filebuf_base::_M_close() { 36177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (!_M_is_open) 36277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return false; 36377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 36477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner bool ok; 36577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 36677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (!_M_should_close) 36777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner ok = true; 36877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner else { 36977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (_M_file_id != INVALID_STLP_FD) { 37077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner ok = (CloseHandle(_M_file_id) != 0); 37177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 37277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner else { 37377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner ok = false; 37477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 37577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 37677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 37777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_is_open = _M_should_close = false; 37877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_openmode = 0; 37977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return ok; 38077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 38177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 38277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 38377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#define _STLP_LF 10 38477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#define _STLP_CR 13 38577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#define _STLP_CTRLZ 26 38677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 38777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner// Read up to n characters into a buffer. Return value is number of 38877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner// characters read. 38977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerptrdiff_t _Filebuf_base::_M_read(char* buf, ptrdiff_t n) { 39077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner ptrdiff_t readen = 0; 39177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner //Here cast to size_t is safe as n cannot be negative. 39277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner size_t chunkSize = (min)(size_t(0xffffffff), __STATIC_CAST(size_t, n)); 39377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // The following, while validating that we are still able to extract chunkSize 39477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // charaters to the buffer, avoids extraction of too small chunk of datas 39577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // which would be counter performant. 39677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner while (__STATIC_CAST(size_t, (n - readen)) >= chunkSize) { 39777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner DWORD numberOfBytesRead; 39877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner ReadFile(_M_file_id, buf + readen, __STATIC_CAST(DWORD, chunkSize), &numberOfBytesRead, 0); 39977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 40077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (numberOfBytesRead == 0) 40177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner break; 40277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 40377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (!(_M_openmode & ios_base::binary)) { 40477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // translate CR-LFs to LFs in the buffer 40577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner char *to = buf + readen; 40677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner char *from = to; 40777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner char *last = from + numberOfBytesRead - 1; 40877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner for (; from <= last && *from != _STLP_CTRLZ; ++from) { 40977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (*from != _STLP_CR) 41077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner *to++ = *from; 41177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner else { // found CR 41277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (from < last) { // not at buffer end 41377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (*(from + 1) != _STLP_LF) 41477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner *to++ = _STLP_CR; 41577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 41677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner else { // last char is CR, peek for LF 41777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner char peek = ' '; 41877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner DWORD NumberOfBytesPeeked; 41977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner ReadFile(_M_file_id, (LPVOID)&peek, 1, &NumberOfBytesPeeked, 0); 42077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (NumberOfBytesPeeked != 0) { 42177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (peek != _STLP_LF) { //not a <CR><LF> combination 42277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner *to++ = _STLP_CR; 42377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if ((to < buf + n) && (peek != _STLP_CR)) 42477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner //We have enough place to store peek and it is no a special 42577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner //_STLP_CR character, we can store it. 42677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner *to++ = peek; 42777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner else 42877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner SetFilePointer(_M_file_id, (LONG)-1, 0, FILE_CURRENT); 42977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 43077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner else { 43177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // A <CR><LF> combination, we keep the <LF>: 43277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner *to++ = _STLP_LF; 43377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 43477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 43577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner else { 43677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner /* This case is tedious, we could 43777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * - put peek back in the file but this would then generate an infinite loop 43877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * - report an error as we don't know if in a future call to ReadFile we won't then 43977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * get a <LF>. Doing so would make all files with a <CR> last an invalid file 44077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * for STLport, a hard solution for STLport clients. 44177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * - store the <CR> in the returned buffer, the chosen solution, even if in this 44277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * case we could miss a <CR><LF> combination. 44377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner */ 44477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner *to++ = _STLP_CR; 44577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 44677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 44777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } // found CR 44877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } // for 44977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner readen = to - buf; 45077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // seek back to TEXT end of file if hit CTRL-Z 45177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (from <= last) { // terminated due to CTRLZ 45277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner SetFilePointer(_M_file_id, -(LONG)((last + 1) - from), 0, FILE_CURRENT); 45377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner break; 45477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 45577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 45677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner else 45777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner readen += numberOfBytesRead; 45877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 45977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return readen; 46077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 46177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 46277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner// Write n characters from a buffer. Return value: true if we managed 46377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner// to write the entire buffer, false if we didn't. 46477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerbool _Filebuf_base::_M_write(char* buf, ptrdiff_t n) { 46577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner for (;;) { 46677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner ptrdiff_t written; 46777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 46877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner //In the following implementation we are going to cast most of the ptrdiff_t 46977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner //values in size_t to work with coherent unsigned values. Doing so make code 47077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner //more simple especially in the min function call. 47177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 47277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // In append mode, every write does an implicit seek to the end 47377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // of the file. 47477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (_M_openmode & ios_base::app) 47577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_seek(0, ios_base::end); 47677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 47777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (_M_openmode & ios_base::binary) { 47877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // binary mode 47977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner size_t bytes_to_write = (size_t)n; 48077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner DWORD NumberOfBytesWritten; 48177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner written = 0; 48277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner for (; bytes_to_write != 0;) { 48377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner WriteFile(_M_file_id, buf + written, 48477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner __STATIC_CAST(DWORD, (min)(size_t(0xffffffff), bytes_to_write)), 48577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner &NumberOfBytesWritten, 0); 48677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (NumberOfBytesWritten == 0) 48777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return false; 48877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner bytes_to_write -= NumberOfBytesWritten; 48977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner written += NumberOfBytesWritten; 49077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 49177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 49277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner else { 49377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner char textbuf[_TEXTBUF_SIZE + 1]; // extra 1 in case LF at end 49477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner char * nextblock = buf, * ptrtextbuf = textbuf; 49577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner char * endtextbuf = textbuf + _TEXTBUF_SIZE; 49677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner char * endblock = buf + n; 49777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner ptrdiff_t nextblocksize = (min) (n, (ptrdiff_t)_TEXTBUF_SIZE); 49877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner char * nextlf; 49977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 50077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner while ( (nextblocksize > 0) && 50177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner (nextlf = (char *)memchr(nextblock, _STLP_LF, nextblocksize)) != 0) { 50277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner ptrdiff_t linelength = nextlf - nextblock; 50377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner memcpy(ptrtextbuf, nextblock, linelength); 50477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner ptrtextbuf += linelength; 50577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner nextblock += (linelength + 1); 50677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * ptrtextbuf ++ = _STLP_CR; 50777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner * ptrtextbuf ++ = _STLP_LF; 50877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner nextblocksize = (min) (ptrdiff_t(endblock - nextblock), 50977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner (max) (ptrdiff_t(0), ptrdiff_t(endtextbuf - ptrtextbuf))); 51077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 51177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // write out what's left, > condition is here since for LF at the end , 51277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // endtextbuf may get < ptrtextbuf ... 51377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (nextblocksize > 0) { 51477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner memcpy(ptrtextbuf, nextblock, nextblocksize); 51577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner ptrtextbuf += nextblocksize; 51677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner nextblock += nextblocksize; 51777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 51877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // now write out the translated buffer 51977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner char * writetextbuf = textbuf; 52077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner for (size_t NumberOfBytesToWrite = (size_t)(ptrtextbuf - textbuf); 52177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner NumberOfBytesToWrite;) { 52277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner DWORD NumberOfBytesWritten; 52377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner WriteFile((HANDLE)_M_file_id, writetextbuf, 52477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner __STATIC_CAST(DWORD, (min)(size_t(0xffffffff), NumberOfBytesToWrite)), 52577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner &NumberOfBytesWritten, 0); 52677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (!NumberOfBytesWritten) // write shortfall 52777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return false; 52877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner writetextbuf += NumberOfBytesWritten; 52977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner NumberOfBytesToWrite -= NumberOfBytesWritten; 53077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 53177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // count non-translated characters 53277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner written = (nextblock - buf); 53377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 53477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 53577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (n == written) 53677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return true; 53777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner else if (written > 0 && written < n) { 53877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner n -= written; 53977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner buf += written; 54077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 54177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner else 54277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return false; 54377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 54477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 54577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 54677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner// Wrapper for lseek or the like. 54777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnerstreamoff _Filebuf_base::_M_seek(streamoff offset, ios_base::seekdir dir) { 54877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner streamoff result = -1; 54977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner int whence; 55077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 55177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner switch(dir) { 55277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner case ios_base::beg: 55377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (offset < 0 /* || offset > _M_file_size() */ ) 55477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return streamoff(-1); 55577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner whence = FILE_BEGIN; 55677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner break; 55777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner case ios_base::cur: 55877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner whence = FILE_CURRENT; 55977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner break; 56077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner case ios_base::end: 56177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (/* offset > 0 || */ -offset > _M_file_size() ) 56277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return streamoff(-1); 56377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner whence = FILE_END; 56477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner break; 56577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner default: 56677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return streamoff(-1); 56777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 56877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 56977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner LARGE_INTEGER li; 57077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner li.QuadPart = offset; 57177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner li.LowPart = SetFilePointer(_M_file_id, li.LowPart, &li.HighPart, whence); 57277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (li.LowPart != INVALID_SET_FILE_POINTER || GetLastError() == NO_ERROR) 57377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner result = li.QuadPart; 57477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 57577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return result; 57677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 57777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 57877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 57977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner// Attempts to memory-map len bytes of the current file, starting 58077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner// at position offset. Precondition: offset is a multiple of the 58177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner// page size. Postcondition: return value is a null pointer if the 58277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner// memory mapping failed. Otherwise the return value is a pointer to 58377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner// the memory-mapped file and the file position is set to offset. 58477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnervoid* _Filebuf_base::_M_mmap(streamoff offset, streamoff len) { 58577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner void* base; 58677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_view_id = CreateFileMapping(_M_file_id, (PSECURITY_ATTRIBUTES)0 , 58777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner PAGE_READONLY, 0 /* len >> 32 */ , 58877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 0 /* len & 0xFFFFFFFF */ , // low-order DWORD of size 58977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 0); 59077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 59177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (_M_view_id) { 59277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#if 0 59377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner/* 59477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner printf("view %x created from file %x, error = %d, size = %d, map_offset = %d map_len = %d\n", 59577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_view_id, _M_file_id, GetLastError(), 59677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner (int)cur_filesize, ULL(offset) & 0xffffffff, len); 59777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner*/ 59877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#endif 59977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner LARGE_INTEGER li; 60077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner li.QuadPart = offset; 60177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner base = MapViewOfFile(_M_view_id, FILE_MAP_READ, li.HighPart, li.LowPart, 60277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#if !defined (__DMC__) 60377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner __STATIC_CAST(SIZE_T, len)); 60477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#else 60577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner __STATIC_CAST(DWORD, len)); 60677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner#endif 60777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // check if mapping succeded and is usable 60877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (base == 0 || _M_seek(offset + len, ios_base::beg) < 0) { 60977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner this->_M_unmap(base, len); 61077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner base = 0; 61177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } 61277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner } else 61377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner base = 0; 61477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 61577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner return base; 61677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 61777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 61877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turnervoid _Filebuf_base::_M_unmap(void* base, streamoff len) { 61977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // precondition : there is a valid mapping at the moment 62077dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (base != NULL) 62177dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner UnmapViewOfFile(base); 62277dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner // destroy view handle as well 62377dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner if (_M_view_id != NULL) 62477dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner CloseHandle(_M_view_id); 62577dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner _M_view_id = NULL; 62677dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner (void)len; //unused variable 62777dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner} 62877dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner 62977dc872c5c4ae67e051d1bf7edf96ce36c7b9be2David 'Digit' Turner_STLP_END_NAMESPACE 630