fstream_win32io.cpp
来自「stl的源码」· C++ 代码 · 共 630 行 · 第 1/2 页
CPP
630 行
/* * Copyright (c) 1999 * Silicon Graphics Computer Systems, Inc. * * Copyright (c) 1999 * Boris Fomitchev * * This material is provided "as is", with absolutely no warranty expressed * or implied. Any use is at your own risk. * * Permission to use or copy this software for any purpose is hereby granted * without fee, provided the above notices are retained on all copies. * Permission to modify the code and to distribute modified code is granted, * provided the above notices are retained, and a notice that the code was * modified is included with the above copyright notice. * */#include <fstream>#if !defined (_STLP_WCE)# ifdef __BORLANDC__# include <cfcntl.h> // For _O_RDONLY, etc# else# include <io.h> // For _get_osfhandle# include <fcntl.h> // For _O_RDONLY, etc# endif# include <sys/stat.h> // For _fstat#endif#define _TEXTBUF_SIZE 0x1000const _STLP_fd INVALID_STLP_FD = INVALID_HANDLE_VALUE;#if !defined (INVALID_SET_FILE_POINTER)# define INVALID_SET_FILE_POINTER 0xffffffff#endif#ifndef O_ACCMODE# define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)#endif_STLP_BEGIN_NAMESPACE#if !defined(__MSL__) && !defined(_STLP_WCE)static ios_base::openmode flag_to_openmode(int mode) { ios_base::openmode ret = ios_base::__default_mode; switch (mode & O_ACCMODE) { case O_RDONLY: ret = ios_base::in; break; case O_WRONLY: ret = ios_base::out; break; case O_RDWR: ret = ios_base::in | ios_base::out; break; } if (mode & O_APPEND) ret |= ios_base::app; if (mode & O_BINARY) ret |= ios_base::binary; return ret;}#endif_STLP_MOVE_TO_PRIV_NAMESPACE// Helper functions for _Filebuf_base.static bool __is_regular_file(_STLP_fd fd) { BY_HANDLE_FILE_INFORMATION info; // Return true if the file handle isn't a directory. return GetFileInformationByHandle(fd, &info) && ((info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0);}// Number of characters in the file.static streamoff __file_size(_STLP_fd fd) { streamoff ret = 0; LARGE_INTEGER li; li.LowPart = GetFileSize(fd, (unsigned long*) &li.HighPart); if (li.LowPart != INVALID_FILE_SIZE || GetLastError() == NO_ERROR) ret = li.QuadPart; return ret;}_STLP_MOVE_TO_STD_NAMESPACE// Visual C++ and Intel use this, but not Metrowerks// Also MinGW, msvcrt.dll (but not crtdll.dll) dependent version#if (defined (_STLP_MSVC_LIB) && !defined (_STLP_WCE)) || \ (defined (__MINGW32__) && defined (__MSVCRT__))// fcntl(fileno, F_GETFL) for Microsoft library// 'semi-documented' defines:# define IOINFO_L2E 5# define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)# define _pioinfo(i) ( __pioinfo[(i) >> IOINFO_L2E] + \ ((i) & (IOINFO_ARRAY_ELTS - 1)) )# define FAPPEND 0x20 // O_APPEND flag# define FTEXT 0x80 // O_TEXT flag// end of 'semi-documented' defines// 'semi-documented' internal structureextern "C" { struct ioinfo { long osfhnd; // the real os HANDLE char osfile; // file handle flags char pipech; // pipe buffer# if defined (_MT) // multi-threaded locking int lockinitflag; CRITICAL_SECTION lock;# endif };# if defined (__MINGW32__) __MINGW_IMPORT ioinfo * __pioinfo[];# else extern _CRTIMP ioinfo * __pioinfo[];# endif} // extern "C"// end of 'semi-documented' declarationsstatic ios_base::openmode _get_osfflags(int fd, HANDLE oshandle) { char dosflags = 0; if (fd >= 0) dosflags = _pioinfo(fd)->osfile; //else //the file will be considered as open in binary mode with no append attribute // end of 'semi-documented' stuff int mode = 0; if (dosflags & FAPPEND) mode |= O_APPEND; if (dosflags & FTEXT) mode |= O_TEXT; else mode |= O_BINARY; // For Read/Write access we have to guess DWORD dummy, dummy2; BOOL writeOk = WriteFile(oshandle, &dummy2, 0, &dummy, 0); BOOL readOk = ReadFile(oshandle, &dummy2, 0, &dummy, NULL); if (writeOk && readOk) mode |= O_RDWR; else if (readOk) mode |= O_RDONLY; else mode |= O_WRONLY; return flag_to_openmode(mode);}#elif defined (__DMC__)# define FHND_APPEND 0x04# define FHND_DEVICE 0x08# define FHND_TEXT 0x10extern "C" unsigned char __fhnd_info[_NFILE];static ios_base::openmode _get_osfflags(int fd, HANDLE oshandle) { int mode = 0; if (__fhnd_info[fd] & FHND_APPEND) mode |= O_APPEND; if (__fhnd_info[fd] & FHND_TEXT == 0) mode |= O_BINARY; for (FILE *fp = &_iob[0]; fp < &_iob[_NFILE]; fp++) { if ((fileno(fp) == fd) && (fp->_flag & (_IOREAD | _IOWRT | _IORW))) { const int osflags = fp->_flag; if ((osflags & _IOREAD) && !(osflags & _IOWRT) && !(osflags & _IORW)) mode |= O_RDONLY; else if ((osflags & _IOWRT) && !(osflags & _IOREAD) && !(osflags & _IORW)) mode |= O_WRONLY; else mode |= O_RDWR; break; } } return flag_to_openmode(mode);}#endifsize_t _Filebuf_base::_M_page_size = 4096;_Filebuf_base::_Filebuf_base() : _M_file_id(INVALID_STLP_FD), _M_openmode(0), _M_is_open(false), _M_should_close(false), _M_view_id(0){}void _Filebuf_base::_S_initialize() { SYSTEM_INFO SystemInfo; GetSystemInfo(&SystemInfo); _M_page_size = SystemInfo.dwPageSize; // might be .dwAllocationGranularity}// Return the size of the file. This is a wrapper for stat.// Returns zero if the size cannot be determined or is ill-defined.streamoff _Filebuf_base::_M_file_size() { return _STLP_PRIV __file_size(_M_file_id);}bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode, long permission) { _STLP_fd file_no; if (_M_is_open) return false; DWORD dwDesiredAccess, dwCreationDisposition; bool doTruncate = false; switch (openmode & (~ios_base::ate & ~ios_base::binary)) { case ios_base::out: case ios_base::out | ios_base::trunc: dwDesiredAccess = GENERIC_WRITE; dwCreationDisposition = OPEN_ALWAYS; // boris : even though it is very non-intuitive, standard // requires them both to behave same. doTruncate = true; break; case ios_base::out | ios_base::app: dwDesiredAccess = GENERIC_WRITE; dwCreationDisposition = OPEN_ALWAYS; break; case ios_base::in: dwDesiredAccess = GENERIC_READ; dwCreationDisposition = OPEN_EXISTING; permission = 0; // Irrelevant unless we're writing. break; case ios_base::in | ios_base::out: dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; dwCreationDisposition = OPEN_EXISTING; break; case ios_base::in | ios_base::out | ios_base::trunc: dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; dwCreationDisposition = OPEN_ALWAYS; doTruncate = true; break; default: // The above are the only combinations of return false; // flags allowed by the C++ standard. } DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;#if defined(_STLP_USE_WIDE_INTERFACE) file_no = CreateFile (_STLP_PRIV __ASCIIToWide(name).c_str(),#else file_no = CreateFileA(name,#endif dwDesiredAccess, dwShareMode, 0, dwCreationDisposition, permission, 0); if (file_no == INVALID_STLP_FD) return false; if (#if !defined (_STLP_WCE) GetFileType(file_no) == FILE_TYPE_DISK &&#endif ((doTruncate && SetEndOfFile(file_no) == 0) || (((openmode & ios_base::ate) != 0) && (SetFilePointer(file_no, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER)))) { CloseHandle(file_no); return false; } _M_is_open = true; _M_file_id = file_no; _M_should_close = _M_is_open; _M_openmode = openmode; if (_M_is_open) _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id); return (_M_is_open != 0);}bool _Filebuf_base::_M_open(const char* name, ios_base::openmode openmode) { // This doesn't really grant everyone in the world read/write // access. On Unix, file-creation system calls always clear // bits that are set in the umask from the permissions flag. return this->_M_open(name, openmode, FILE_ATTRIBUTE_NORMAL);}bool _Filebuf_base::_M_open(_STLP_fd __id, ios_base::openmode init_mode) {#if (defined (_STLP_MSVC_LIB) && !defined (_STLP_WCE)) || \ (defined (__MINGW32__) && defined (__MSVCRT__)) || defined (__DMC__) if (_M_is_open || __id == INVALID_STLP_FD) return false; if (init_mode != ios_base::__default_mode) _M_openmode = init_mode; else _M_openmode = _get_osfflags(-1, __id); _M_is_open = true; _M_file_id = __id; _M_should_close = false;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?