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 + -
显示快捷键?