fileiter.cpp
来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 909 行 · 第 1/2 页
CPP
909 行
/* * * Copyright (c) 1998-2002 * John Maddock * * Use, modification and distribution are subject to the * Boost Software License, Version 1.0. (See accompanying file * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ /* * LOCATION: see http://www.boost.org for most recent version. * FILE: fileiter.cpp * VERSION: see <boost/version.hpp> * DESCRIPTION: Implements file io primitives + directory searching for class boost::RegEx. */#define BOOST_REGEX_SOURCE#include <climits>#include <stdexcept>#include <string>#include <boost/throw_exception.hpp>#include <boost/regex/v4/fileiter.hpp>#include <boost/regex/v4/regex_workaround.hpp>#include <boost/regex/pattern_except.hpp>#include <cstdio>#if defined(BOOST_NO_STDC_NAMESPACE)namespace std{ using ::sprintf; using ::fseek; using ::fread; using ::ftell; using ::fopen; using ::fclose; using ::FILE; using ::strcpy; using ::strcpy; using ::strcat; using ::strcmp; using ::strlen;}#endif#ifndef BOOST_REGEX_NO_FILEITER#if defined(__CYGWIN__) || defined(__CYGWIN32__)#include <sys/cygwin.h>#endif#ifdef BOOST_MSVC# pragma warning(disable: 4800)#endifnamespace boost{ namespace re_detail{// start with the operating system specific stuff:#if (defined(__BORLANDC__) || defined(BOOST_REGEX_FI_WIN32_DIR) || defined(BOOST_MSVC)) && !defined(BOOST_RE_NO_WIN32)// platform is DOS or Windows// directories are separated with '\\'// and names are insensitive of caseBOOST_REGEX_DECL const char* _fi_sep = "\\";const char* _fi_sep_alt = "/";#define BOOST_REGEX_FI_TRANSLATE(c) std::tolower(c)#else// platform is not DOS or Windows// directories are separated with '/'// and names are sensitive of caseBOOST_REGEX_DECL const char* _fi_sep = "/";const char* _fi_sep_alt = _fi_sep;#define BOOST_REGEX_FI_TRANSLATE(c) c#endif#ifdef BOOST_REGEX_FI_WIN32_MAPvoid mapfile::open(const char* file){#if defined(BOOST_NO_ANSI_APIS) int filename_size = strlen(file); LPWSTR wide_file = (LPWSTR)_alloca( (filename_size + 1) * sizeof(WCHAR) ); if(::MultiByteToWideChar(CP_ACP, 0, file, filename_size, wide_file, filename_size + 1) == 0) hfile = INVALID_HANDLE_VALUE; else hfile = CreateFileW(wide_file, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);#elif defined(__CYGWIN__)||defined(__CYGWIN32__) char win32file[ MAX_PATH ]; cygwin_conv_to_win32_path( file, win32file ); hfile = CreateFileA(win32file, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);#else hfile = CreateFileA(file, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);#endif if(hfile != INVALID_HANDLE_VALUE) { hmap = CreateFileMapping(hfile, 0, PAGE_READONLY, 0, 0, 0); if((hmap == INVALID_HANDLE_VALUE) || (hmap == NULL)) { CloseHandle(hfile); hmap = 0; hfile = 0; std::runtime_error err("Unable to create file mapping."); boost::re_detail::raise_runtime_error(err); } _first = static_cast<const char*>(MapViewOfFile(hmap, FILE_MAP_READ, 0, 0, 0)); if(_first == 0) { CloseHandle(hmap); CloseHandle(hfile); hmap = 0; hfile = 0; std::runtime_error err("Unable to create file mapping."); } _last = _first + GetFileSize(hfile, 0); } else { hfile = 0;#ifndef BOOST_NO_EXCEPTIONS throw std::runtime_error("Unable to open file.");#else BOOST_REGEX_NOEH_ASSERT(hfile != INVALID_HANDLE_VALUE);#endif }}void mapfile::close(){ if(hfile != INVALID_HANDLE_VALUE) { UnmapViewOfFile((void*)_first); CloseHandle(hmap); CloseHandle(hfile); hmap = hfile = 0; _first = _last = 0; }}#elif !defined(BOOST_RE_NO_STL)mapfile_iterator& mapfile_iterator::operator = (const mapfile_iterator& i){ if(file && node) file->unlock(node); file = i.file; node = i.node; offset = i.offset; if(file) file->lock(node); return *this;}mapfile_iterator& mapfile_iterator::operator++ (){ if((++offset == mapfile::buf_size) && file) { ++node; offset = 0; file->lock(node); file->unlock(node-1); } return *this;}mapfile_iterator mapfile_iterator::operator++ (int){ mapfile_iterator temp(*this); if((++offset == mapfile::buf_size) && file) { ++node; offset = 0; file->lock(node); file->unlock(node-1); } return temp;}mapfile_iterator& mapfile_iterator::operator-- (){ if((offset == 0) && file) { --node; offset = mapfile::buf_size - 1; file->lock(node); file->unlock(node + 1); } else --offset; return *this;}mapfile_iterator mapfile_iterator::operator-- (int){ mapfile_iterator temp(*this); if((offset == 0) && file) { --node; offset = mapfile::buf_size - 1; file->lock(node); file->unlock(node + 1); } else --offset; return temp;}mapfile_iterator operator + (const mapfile_iterator& i, long off){ mapfile_iterator temp(i); temp += off; return temp;}mapfile_iterator operator - (const mapfile_iterator& i, long off){ mapfile_iterator temp(i); temp -= off; return temp;}mapfile::iterator mapfile::begin()const{ return mapfile_iterator(this, 0);}mapfile::iterator mapfile::end()const{ return mapfile_iterator(this, _size);}void mapfile::lock(pointer* node)const{ BOOST_ASSERT(node >= _first); BOOST_ASSERT(node <= _last); if(node < _last) { if(*node == 0) { if(condemed.empty()) { *node = new char[sizeof(int) + buf_size]; *(reinterpret_cast<int*>(*node)) = 1; } else { pointer* p = condemed.front(); condemed.pop_front(); *node = *p; *p = 0; *(reinterpret_cast<int*>(*node)) = 1; } std::fseek(hfile, (node - _first) * buf_size, SEEK_SET); if(node == _last - 1) std::fread(*node + sizeof(int), _size % buf_size, 1, hfile); else std::fread(*node + sizeof(int), buf_size, 1, hfile); } else { if(*reinterpret_cast<int*>(*node) == 0) { *reinterpret_cast<int*>(*node) = 1; condemed.remove(node); } else ++(*reinterpret_cast<int*>(*node)); } }}void mapfile::unlock(pointer* node)const{ BOOST_ASSERT(node >= _first); BOOST_ASSERT(node <= _last); if(node < _last) { if(--(*reinterpret_cast<int*>(*node)) == 0) { condemed.push_back(node); } }}long int get_file_length(std::FILE* hfile){ long int result; std::fseek(hfile, 0, SEEK_END); result = std::ftell(hfile); std::fseek(hfile, 0, SEEK_SET); return result;}void mapfile::open(const char* file){ hfile = std::fopen(file, "rb");#ifndef BOOST_NO_EXCEPTIONS try{#endif if(hfile != 0) { _size = get_file_length(hfile); long cnodes = (_size + buf_size - 1) / buf_size; // check that number of nodes is not too high: if(cnodes > (long)((INT_MAX) / sizeof(pointer*))) { std::fclose(hfile); hfile = 0; _size = 0; return; } _first = new pointer[(int)cnodes]; _last = _first + cnodes; std::memset(_first, 0, cnodes*sizeof(pointer)); } else { std::runtime_error err("Unable to open file."); }#ifndef BOOST_NO_EXCEPTIONS }catch(...) { close(); throw; }#endif}void mapfile::close(){ if(hfile != 0) { pointer* p = _first; while(p != _last) { if(*p) delete[] *p; ++p; } delete[] _first; _size = 0; _first = _last = 0; std::fclose(hfile); hfile = 0; condemed.erase(condemed.begin(), condemed.end()); }}#endifinline _fi_find_handle find_first_file(const char* wild, _fi_find_data& data){#ifdef BOOST_NO_ANSI_APIS std::size_t wild_size = std::strlen(wild); LPWSTR wide_wild = (LPWSTR)_alloca( (wild_size + 1) * sizeof(WCHAR) ); if (::MultiByteToWideChar(CP_ACP, 0, wild, wild_size, wide_wild, wild_size + 1) == 0) return _fi_invalid_handle; return FindFirstFileW(wide_wild, &data);#else return FindFirstFileA(wild, &data);#endif}inline bool find_next_file(_fi_find_handle hf, _fi_find_data& data){#ifdef BOOST_NO_ANSI_APIS return FindNextFileW(hf, &data);#else return FindNextFileA(hf, &data);#endif} inline void copy_find_file_result_with_overflow_check(const _fi_find_data& data, char* path, size_t max_size){#ifdef BOOST_NO_ANSI_APIS if (::WideCharToMultiByte(CP_ACP, 0, data.cFileName, -1, path, max_size, NULL, NULL) == 0) re_detail::overflow_error_if_not_zero(1);#else re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(path, max_size, data.cFileName));#endif}inline bool is_not_current_or_parent_path_string(const _fi_find_data& data){#ifdef BOOST_NO_ANSI_APIS return (std::wcscmp(data.cFileName, L".") && std::wcscmp(data.cFileName, L".."));#else return (std::strcmp(data.cFileName, ".") && std::strcmp(data.cFileName, ".."));#endif}file_iterator::file_iterator(){ _root = _path = 0; ref = 0;#ifndef BOOST_NO_EXCEPTIONS try{#endif _root = new char[MAX_PATH]; BOOST_REGEX_NOEH_ASSERT(_root) _path = new char[MAX_PATH]; BOOST_REGEX_NOEH_ASSERT(_path) ptr = _path; *_path = 0; *_root = 0; ref = new file_iterator_ref(); BOOST_REGEX_NOEH_ASSERT(ref) ref->hf = _fi_invalid_handle; ref->count = 1;#ifndef BOOST_NO_EXCEPTIONS } catch(...) { delete[] _root; delete[] _path; delete ref; throw; }#endif}file_iterator::file_iterator(const char* wild){ _root = _path = 0; ref = 0;#ifndef BOOST_NO_EXCEPTIONS try{#endif _root = new char[MAX_PATH]; BOOST_REGEX_NOEH_ASSERT(_root) _path = new char[MAX_PATH]; BOOST_REGEX_NOEH_ASSERT(_path) re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_root, MAX_PATH, wild)); ptr = _root; while(*ptr)++ptr; while((ptr > _root) && (*ptr != *_fi_sep) && (*ptr != *_fi_sep_alt))--ptr; if((ptr == _root) && ( (*ptr== *_fi_sep) || (*ptr==*_fi_sep_alt) ) ) { _root[1]='\0'; re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(_path, MAX_PATH, _root)); } else { *ptr = 0;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?