fstream_win32io.cpp

来自「stl的源码」· C++ 代码 · 共 630 行 · 第 1/2 页

CPP
630
字号
  _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id);  return true;#else  (void)__id;  (void)init_mode;    // dwa 4/27/00 - suppress unused parameter warning  // not available for the API  return false;#endif}// 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 init_mode) {  if (_M_is_open || file_no < 0)    return false;#if (defined (_STLP_MSVC_LIB) && !defined (_STLP_WCE)) || \    (defined (__MINGW32__) && defined (__MSVCRT__)) || defined (__DMC__)  HANDLE oshandle = (HANDLE)_get_osfhandle(file_no);  if (oshandle == INVALID_STLP_FD)    return false;  if (init_mode != ios_base::__default_mode)    _M_openmode = init_mode;  else    _M_openmode = _get_osfflags(file_no, oshandle);  _M_file_id = oshandle;  _M_is_open = true;  _M_should_close = false;  _M_regular_file = _STLP_PRIV __is_regular_file(_M_file_id);  return true;#else  _STLP_MARK_PARAMETER_AS_UNUSED(&init_mode)  // not available for the API  return false;#endif}bool _Filebuf_base::_M_close() {  if (!_M_is_open)    return false;  bool ok;  if (!_M_should_close)    ok = true;  else {    if (_M_file_id != INVALID_STLP_FD) {      ok = (CloseHandle(_M_file_id) != 0);    }    else {      ok = false;    }  }  _M_is_open = _M_should_close = false;  _M_openmode = 0;  return ok;}#define _STLP_LF 10#define _STLP_CR 13#define _STLP_CTRLZ 26// 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) {  ptrdiff_t readen = 0;  //Here cast to size_t is safe as n cannot be negative.  size_t chunkSize = (min)(size_t(0xffffffff), __STATIC_CAST(size_t, n));  // The following, while validating that we are still able to extract chunkSize  // charaters to the buffer, avoids extraction of too small chunk of datas  // which would be counter performant.  while (__STATIC_CAST(size_t, (n - readen)) >= chunkSize) {    DWORD numberOfBytesRead;    ReadFile(_M_file_id, buf + readen, __STATIC_CAST(DWORD, chunkSize), &numberOfBytesRead, 0);    if (numberOfBytesRead == 0)      break;    if (!(_M_openmode & ios_base::binary)) {      // translate CR-LFs to LFs in the buffer      char *to = buf + readen;      char *from = to;      char *last = from + numberOfBytesRead - 1;      for (; from <= last && *from != _STLP_CTRLZ; ++from) {        if (*from != _STLP_CR)          *to++ = *from;        else { // found CR          if (from < last) { // not at buffer end            if (*(from + 1) != _STLP_LF)              *to++ = _STLP_CR;          }          else { // last char is CR, peek for LF            char peek = ' ';            DWORD NumberOfBytesPeeked;            ReadFile(_M_file_id, (LPVOID)&peek, 1, &NumberOfBytesPeeked, 0);            if (NumberOfBytesPeeked != 0) {              if (peek != _STLP_LF) { //not a <CR><LF> combination                *to++ = _STLP_CR;                if ((to < buf + n) && (peek != _STLP_CR))                  //We have enough place to store peek and it is no a special                  //_STLP_CR character, we can store it.                  *to++ = peek;                else                  SetFilePointer(_M_file_id, (LONG)-1, 0, FILE_CURRENT);              }              else {                // A <CR><LF> combination, we keep the <LF>:                *to++ = _STLP_LF;              }            }            else {              /* This case is tedious, we could               *  - put peek back in the file but this would then generate an infinite loop               *  - report an error as we don't know if in a future call to ReadFile we won't then               *    get a <LF>. Doing so would make all files with a <CR> last an invalid file               *    for STLport, a hard solution for STLport clients.               *  - store the <CR> in the returned buffer, the chosen solution, even if in this               *    case we could miss a <CR><LF> combination.               */              *to++ = _STLP_CR;            }          }        } // found CR      } // for      readen = to - buf;      // seek back to TEXT end of file if hit CTRL-Z      if (from <= last) { // terminated due to CTRLZ        SetFilePointer(_M_file_id, -(LONG)((last + 1) - from), 0, FILE_CURRENT);        break;      }    }    else      readen += numberOfBytesRead;  }  return readen;}// 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;    //In the following implementation we are going to cast most of the ptrdiff_t    //values in size_t to work with coherent unsigned values. Doing so make code    //more simple especially in the min function call.    // In append mode, every write does an implicit seek to the end    // of the file.    if (_M_openmode & ios_base::app)      _M_seek(0, ios_base::end);    if (_M_openmode & ios_base::binary) {      // binary mode      size_t bytes_to_write = (size_t)n;      DWORD NumberOfBytesWritten;      written = 0;      for (; bytes_to_write != 0;) {        WriteFile(_M_file_id, buf + written,                  __STATIC_CAST(DWORD, (min)(size_t(0xffffffff), bytes_to_write)),                  &NumberOfBytesWritten, 0);        if (NumberOfBytesWritten == 0)          return false;        bytes_to_write -= NumberOfBytesWritten;        written += NumberOfBytesWritten;      }    }    else {      char textbuf[_TEXTBUF_SIZE + 1]; // extra 1 in case LF at end      char * nextblock = buf, * ptrtextbuf = textbuf;      char * endtextbuf = textbuf + _TEXTBUF_SIZE;      char * endblock = buf + n;      ptrdiff_t nextblocksize = (min) (n, (ptrdiff_t)_TEXTBUF_SIZE);      char * nextlf;      while ( (nextblocksize > 0) &&              (nextlf = (char *)memchr(nextblock, _STLP_LF, nextblocksize)) != 0) {        ptrdiff_t linelength = nextlf - nextblock;        memcpy(ptrtextbuf, nextblock, linelength);        ptrtextbuf += linelength;        nextblock += (linelength + 1);        * ptrtextbuf ++ = _STLP_CR;        * ptrtextbuf ++ = _STLP_LF;        nextblocksize = (min) (ptrdiff_t(endblock - nextblock),                               (max) (ptrdiff_t(0), ptrdiff_t(endtextbuf - ptrtextbuf)));      }      // write out what's left, > condition is here since for LF at the end ,      // endtextbuf may get < ptrtextbuf ...      if (nextblocksize > 0) {        memcpy(ptrtextbuf, nextblock, nextblocksize);        ptrtextbuf += nextblocksize;        nextblock += nextblocksize;      }      // now write out the translated buffer      char * writetextbuf = textbuf;      for (size_t NumberOfBytesToWrite = (size_t)(ptrtextbuf - textbuf);           NumberOfBytesToWrite;) {        DWORD NumberOfBytesWritten;        WriteFile((HANDLE)_M_file_id, writetextbuf,                  __STATIC_CAST(DWORD, (min)(size_t(0xffffffff), NumberOfBytesToWrite)),                  &NumberOfBytesWritten, 0);        if (!NumberOfBytesWritten) // write shortfall          return false;        writetextbuf += NumberOfBytesWritten;        NumberOfBytesToWrite -= NumberOfBytesWritten;      }      // count non-translated characters      written = (nextblock - buf);    }    if (n == written)      return true;    else 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) {  streamoff result = -1;  int whence;  switch(dir) {  case ios_base::beg:    if (offset < 0 /* || offset > _M_file_size() */ )      return streamoff(-1);    whence = FILE_BEGIN;    break;  case ios_base::cur:    whence = FILE_CURRENT;    break;  case ios_base::end:    if (/* offset > 0 || */  -offset > _M_file_size() )      return streamoff(-1);    whence = FILE_END;    break;  default:    return streamoff(-1);  }  LARGE_INTEGER li;  li.QuadPart = offset;  li.LowPart = SetFilePointer(_M_file_id, li.LowPart, &li.HighPart, whence);  if (li.LowPart != INVALID_SET_FILE_POINTER || GetLastError() == NO_ERROR)    result = li.QuadPart;  return result;}// 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 offset, streamoff len) {  void* base;  _M_view_id = CreateFileMapping(_M_file_id, (PSECURITY_ATTRIBUTES)0 ,                                 PAGE_READONLY, 0 /* len >> 32 */ ,                                 0 /* len & 0xFFFFFFFF */ , // low-order DWORD of size                                 0);  if (_M_view_id) {#if 0/*    printf("view %x created from file %x, error = %d, size = %d, map_offset = %d map_len = %d\n",     _M_view_id, _M_file_id, GetLastError(),     (int)cur_filesize, ULL(offset) & 0xffffffff, len);*/#endif    LARGE_INTEGER li;    li.QuadPart = offset;    base = MapViewOfFile(_M_view_id, FILE_MAP_READ, li.HighPart, li.LowPart,#if !defined (__DMC__)                         __STATIC_CAST(SIZE_T, len));#else                         __STATIC_CAST(DWORD, len));#endif    // check if mapping succeded and is usable    if (base == 0  || _M_seek(offset + len, ios_base::beg) < 0) {      this->_M_unmap(base, len);      base = 0;    }  } else    base = 0;  return base;}void _Filebuf_base::_M_unmap(void* base, streamoff len) {  // precondition : there is a valid mapping at the moment  if (base != NULL)    UnmapViewOfFile(base);  // destroy view handle as well  if (_M_view_id != NULL)    CloseHandle(_M_view_id);  _M_view_id = NULL;  (void)len; //unused variable}_STLP_END_NAMESPACE

⌨️ 快捷键说明

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