fstream_stdio.cpp

来自「stl的源码」· C++ 代码 · 共 388 行

CPP
388
字号
/* * 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. * */#if defined  (__SUNPPRO_CC)  && !defined (_STLP_NO_NEW_C_HEADERS)#  include <time.h>// For sunpro, it chokes if time.h is included through stat.h#endif#include <fstream>#ifdef __CYGWIN__#  define __int64 long long#endif#include <cstdio>#if !defined(__ISCPP__)extern "C" {#  include <sys/stat.h>}#endif#if defined( __MSL__ )#  include <unix.h>#endif#if defined(__ISCPP__)#  include <c_locale_is/filestat.h>#endif#if defined(__BEOS__) && defined(__INTEL__)#  include <fcntl.h>#  include <sys/stat.h>         // For _fstat#endif#if defined (_STLP_MSVC) || defined (__MINGW32__)#  include <fcntl.h>#  define S_IREAD _S_IREAD#  define S_IWRITE _S_IWRITE#  define S_IFREG _S_IFREG     // map permission masks#  ifndef S_IRUSR#    define S_IRUSR _S_IREAD#    define S_IWUSR _S_IWRITE#  endif#  ifndef S_IRGRP#    define S_IRGRP _S_IREAD#    define S_IWGRP _S_IWRITE#  endif#  ifndef S_IROTH#    define S_IROTH _S_IREAD#    define S_IWOTH _S_IWRITE#  endif#  ifndef O_RDONLY#    define O_RDONLY _O_RDONLY#    define O_WRONLY _O_WRONLY#    define O_RDWR   _O_RDWR#    define O_APPEND _O_APPEND#    define O_CREAT  _O_CREAT#    define O_TRUNC  _O_TRUNC#    define O_TEXT   _O_TEXT#    define O_BINARY _O_BINARY#  endif#  ifndef O_ACCMODE#    define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)#  endif#endifconst _STLP_fd INVALID_STLP_FD = -1;#  ifdef __MSL__#    define _O_TEXT 0x0#    if !defined( O_TEXT )#      define O_TEXT _O_TEXT#    endif#    define _S_IFREG S_IFREG#    define S_IREAD        S_IRUSR#    define S_IWRITE       S_IWUSR#    define S_IEXEC        S_IXUSR#    define _S_IWRITE S_IWRITE#    define _S_IREAD S_IREAD#    define _open open#    define _close close#    define _read read#    define _write write#  endif_STLP_BEGIN_NAMESPACE// Compare with streamoff definition in stl/char_traits.h!#if defined (_STLP_USE_DEFAULT_FILE_OFFSET) || \    (!defined(_LARGEFILE_SOURCE) && !defined(_LARGEFILE64_SOURCE))#  define FOPEN fopen#  define FSEEK fseek#  define FSTAT fstat#  define STAT  stat#  define FTELL ftell#else#  define FOPEN fopen64#  define FSEEK fseeko64#  define FSTAT fstat64#  define STAT  stat64#  define FTELL ftello64#endif_STLP_MOVE_TO_PRIV_NAMESPACE// Helper functions for _Filebuf_base.static bool __is_regular_file(_STLP_fd fd) {  struct STAT buf;  return FSTAT(fd, &buf) == 0 && (buf.st_mode & S_IFREG) != 0 ;}// Number of characters in the file.static streamoff __file_size(_STLP_fd fd) {  streamoff ret = 0;  struct STAT buf;  if (FSTAT(fd, &buf) == 0 && (buf.st_mode & S_IFREG) != 0)    ret = buf.st_size > 0 ? buf.st_size : 0;  return ret;}_STLP_MOVE_TO_STD_NAMESPACE// All version of Unix have mmap and lseek system calls.  Some also have// longer versions of those system calls to accommodate 64-bit offsets.// If we're on a Unix system, define some macros to encapsulate those// differences.size_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){}void _Filebuf_base::_S_initialize(){}// 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;  // use FILE-based i/o  const char* flags;  switch (openmode & (~ios_base::ate)) {    case ios_base::out:    case ios_base::out | ios_base::trunc:      flags = "w";      break;    case ios_base::out | ios_base::binary:    case ios_base::out | ios_base::trunc | ios_base::binary:      flags = "wb";      break;    case ios_base::out | ios_base::app:      flags = "a";      break;    case ios_base::out | ios_base::app | ios_base::binary:      flags = "ab";      break;    case ios_base::in:      flags = "r";      break;    case ios_base::in | ios_base::binary:      flags = "rb";      break;    case ios_base::in | ios_base::out:      flags = "r+";      break;    case ios_base::in | ios_base::out | ios_base::binary:      flags = "r+b";      break;    case ios_base::in | ios_base::out | ios_base::trunc:      flags = "w+";      break;    case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:      flags = "w+b";      break;    default:                      // The above are the only combinations of      return false;               // flags allowed by the C++ standard.  }  // fbp : TODO : set permissions !  (void)permission; // currently unused    //*TY 02/26/2000 - added to suppress warning message  _M_file = FOPEN(name, flags);  if (_M_file) {    file_no = fileno(_M_file);  } else {    return false;  }  // unset buffering immediately  setbuf(_M_file, 0);  _M_is_open = true;  if (openmode & ios_base::ate) {    if (FSEEK(_M_file, 0, SEEK_END) != 0)      _M_is_open = false;  }  _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, S_IRUSR | S_IWUSR | S_IRGRP |                                       S_IWGRP | S_IROTH | S_IWOTH);}// Associated the filebuf with a file descriptor pointing to an already-// open file.  Mode is set to be consistent with the way that the file// was opened.bool _Filebuf_base::_M_open( int file_no, ios_base::openmode ){  if (_M_is_open || file_no < 0)    return false;  struct STAT buf;  if (FSTAT(file_no, &buf) != 0)    return false;  int mode = buf.st_mode;  switch ( mode & (S_IWRITE | S_IREAD) ) {    case S_IREAD:      _M_openmode = ios_base::in;      break;    case S_IWRITE:      _M_openmode = ios_base::out;      break;    case (S_IWRITE | S_IREAD):      _M_openmode = ios_base::in | ios_base::out;      break;    default:      return false;  }  _M_file_id = file_no;  _M_is_open = true;  _M_should_close = false;  _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id);  return true;}bool _Filebuf_base::_M_close(){  if (!_M_is_open)    return false;  bool ok = _M_should_close ? (fclose(_M_file) == 0) : true;  _M_is_open = _M_should_close = false;  _M_openmode = 0;  return ok;}// Read up to n characters into a buffer.  Return value is number of// characters read.ptrdiff_t _Filebuf_base::_M_read(char* buf, ptrdiff_t n) {  return fread(buf, 1, n, _M_file);}// Write n characters from a buffer.  Return value: true if we managed// to write the entire buffer, false if we didn't.bool _Filebuf_base::_M_write(char* buf, ptrdiff_t n){  for (;;) {    ptrdiff_t written = fwrite(buf, 1, n, _M_file);    if (n == written) {      return true;    }    if (written > 0 && written < n) {      n -= written;      buf += written;    } else {      return false;    }  }}// Wrapper for lseek or the like.streamoff _Filebuf_base::_M_seek(streamoff offset, ios_base::seekdir dir){  int whence;  switch ( dir ) {    case ios_base::beg:      if (offset < 0 /* || offset > _M_file_size() */ )        return streamoff(-1);      whence = SEEK_SET;      break;    case ios_base::cur:      whence = SEEK_CUR;      break;    case ios_base::end:      if (/* offset > 0 || */  -offset > _M_file_size() )        return streamoff(-1);      whence = SEEK_END;      break;    default:      return streamoff(-1);  }  if ( FSEEK(_M_file, offset, whence) == 0 ) {    return FTELL(_M_file);  }  return streamoff(-1);}// Attempts to memory-map len bytes of the current file, starting// at position offset.  Precondition: offset is a multiple of the// page size.  Postcondition: return value is a null pointer if the// memory mapping failed.  Otherwise the return value is a pointer to// the memory-mapped file and the file position is set to offset.void *_Filebuf_base::_M_mmap(streamoff, streamoff ){  return 0;}void _Filebuf_base::_M_unmap(void*, streamoff){  // precondition : there is a valid mapping at the moment}_STLP_END_NAMESPACE

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?