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