fileiter.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. /*
  2. *
  3. * Copyright (c) 1998-2002
  4. * John Maddock
  5. *
  6. * Use, modification and distribution are subject to the
  7. * Boost Software License, Version 1.0. (See accompanying file
  8. * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. *
  10. */
  11. /*
  12. * LOCATION: see http://www.boost.org for most recent version.
  13. * FILE fileiter.hpp
  14. * VERSION see <boost/version.hpp>
  15. * DESCRIPTION: Declares various platform independent file and
  16. * directory iterators, plus binary file input in
  17. * the form of class map_file.
  18. */
  19. #ifndef BOOST_RE_FILEITER_HPP_INCLUDED
  20. #define BOOST_RE_FILEITER_HPP_INCLUDED
  21. #ifndef BOOST_REGEX_CONFIG_HPP
  22. #include <boost/regex/config.hpp>
  23. #endif
  24. #include <boost/assert.hpp>
  25. #ifndef BOOST_REGEX_NO_FILEITER
  26. #if (defined(__CYGWIN__) || defined(__CYGWIN32__)) && !defined(BOOST_REGEX_NO_W32)
  27. #error "Sorry, can't mix <windows.h> with STL code and gcc compiler: if you ran configure, try again with configure --disable-ms-windows"
  28. #define BOOST_REGEX_FI_WIN32_MAP
  29. #define BOOST_REGEX_FI_POSIX_DIR
  30. #elif (defined(__WIN32__) || defined(_WIN32) || defined(WIN32)) && !defined(BOOST_REGEX_NO_W32)
  31. #define BOOST_REGEX_FI_WIN32_MAP
  32. #define BOOST_REGEX_FI_WIN32_DIR
  33. #else
  34. #define BOOST_REGEX_FI_POSIX_MAP
  35. #define BOOST_REGEX_FI_POSIX_DIR
  36. #endif
  37. #if defined(BOOST_REGEX_FI_WIN32_MAP)||defined(BOOST_REGEX_FI_WIN32_DIR)
  38. #include <windows.h>
  39. #endif
  40. #if defined(BOOST_REGEX_FI_WIN32_DIR)
  41. #include <cstddef>
  42. namespace boost{
  43. namespace BOOST_REGEX_DETAIL_NS{
  44. #ifndef BOOST_NO_ANSI_APIS
  45. typedef WIN32_FIND_DATAA _fi_find_data;
  46. #else
  47. typedef WIN32_FIND_DATAW _fi_find_data;
  48. #endif
  49. typedef HANDLE _fi_find_handle;
  50. } // namespace BOOST_REGEX_DETAIL_NS
  51. } // namespace boost
  52. #define _fi_invalid_handle INVALID_HANDLE_VALUE
  53. #define _fi_dir FILE_ATTRIBUTE_DIRECTORY
  54. #elif defined(BOOST_REGEX_FI_POSIX_DIR)
  55. #include <cstddef>
  56. #include <cstdio>
  57. #include <cctype>
  58. #include <iterator>
  59. #include <list>
  60. #include <cassert>
  61. #include <dirent.h>
  62. #if defined(__SUNPRO_CC)
  63. using std::list;
  64. #endif
  65. #ifndef MAX_PATH
  66. #define MAX_PATH 256
  67. #endif
  68. namespace boost{
  69. namespace BOOST_REGEX_DETAIL_NS{
  70. #ifdef BOOST_HAS_ABI_HEADERS
  71. # include BOOST_ABI_PREFIX
  72. #endif
  73. struct _fi_find_data
  74. {
  75. unsigned dwFileAttributes;
  76. char cFileName[MAX_PATH];
  77. };
  78. struct _fi_priv_data;
  79. typedef _fi_priv_data* _fi_find_handle;
  80. #define _fi_invalid_handle 0
  81. #define _fi_dir 1
  82. _fi_find_handle _fi_FindFirstFile(const char* lpFileName, _fi_find_data* lpFindFileData);
  83. bool _fi_FindNextFile(_fi_find_handle hFindFile, _fi_find_data* lpFindFileData);
  84. bool _fi_FindClose(_fi_find_handle hFindFile);
  85. #ifdef BOOST_HAS_ABI_HEADERS
  86. # include BOOST_ABI_SUFFIX
  87. #endif
  88. } // namespace BOOST_REGEX_DETAIL_NS
  89. } // namespace boost
  90. #ifdef FindFirstFile
  91. #undef FindFirstFile
  92. #endif
  93. #ifdef FindNextFile
  94. #undef FindNextFile
  95. #endif
  96. #ifdef FindClose
  97. #undef FindClose
  98. #endif
  99. #define FindFirstFileA _fi_FindFirstFile
  100. #define FindNextFileA _fi_FindNextFile
  101. #define FindClose _fi_FindClose
  102. #endif
  103. namespace boost{
  104. namespace BOOST_REGEX_DETAIL_NS{
  105. #ifdef BOOST_HAS_ABI_HEADERS
  106. # include BOOST_ABI_PREFIX
  107. #endif
  108. #ifdef BOOST_REGEX_FI_WIN32_MAP // win32 mapfile
  109. class BOOST_REGEX_DECL mapfile
  110. {
  111. HANDLE hfile;
  112. HANDLE hmap;
  113. const char* _first;
  114. const char* _last;
  115. public:
  116. typedef const char* iterator;
  117. mapfile(){ hfile = hmap = 0; _first = _last = 0; }
  118. mapfile(const char* file){ hfile = hmap = 0; _first = _last = 0; open(file); }
  119. ~mapfile(){ close(); }
  120. void open(const char* file);
  121. void close();
  122. const char* begin(){ return _first; }
  123. const char* end(){ return _last; }
  124. size_t size(){ return _last - _first; }
  125. bool valid(){ return (hfile != 0) && (hfile != INVALID_HANDLE_VALUE); }
  126. };
  127. #else
  128. class BOOST_REGEX_DECL mapfile_iterator;
  129. class BOOST_REGEX_DECL mapfile
  130. {
  131. typedef char* pointer;
  132. std::FILE* hfile;
  133. long int _size;
  134. pointer* _first;
  135. pointer* _last;
  136. mutable std::list<pointer*> condemed;
  137. enum sizes
  138. {
  139. buf_size = 4096
  140. };
  141. void lock(pointer* node)const;
  142. void unlock(pointer* node)const;
  143. public:
  144. typedef mapfile_iterator iterator;
  145. mapfile(){ hfile = 0; _size = 0; _first = _last = 0; }
  146. mapfile(const char* file){ hfile = 0; _size = 0; _first = _last = 0; open(file); }
  147. ~mapfile(){ close(); }
  148. void open(const char* file);
  149. void close();
  150. iterator begin()const;
  151. iterator end()const;
  152. unsigned long size()const{ return _size; }
  153. bool valid()const{ return hfile != 0; }
  154. friend class mapfile_iterator;
  155. };
  156. class BOOST_REGEX_DECL mapfile_iterator
  157. {
  158. typedef mapfile::pointer internal_pointer;
  159. internal_pointer* node;
  160. const mapfile* file;
  161. unsigned long offset;
  162. long position()const
  163. {
  164. return file ? ((node - file->_first) * mapfile::buf_size + offset) : 0;
  165. }
  166. void position(long pos)
  167. {
  168. if(file)
  169. {
  170. node = file->_first + (pos / mapfile::buf_size);
  171. offset = pos % mapfile::buf_size;
  172. }
  173. }
  174. public:
  175. typedef std::ptrdiff_t difference_type;
  176. typedef char value_type;
  177. typedef const char* pointer;
  178. typedef const char& reference;
  179. typedef std::random_access_iterator_tag iterator_category;
  180. mapfile_iterator() { node = 0; file = 0; offset = 0; }
  181. mapfile_iterator(const mapfile* f, long arg_position)
  182. {
  183. BOOST_ASSERT(f);
  184. file = f;
  185. node = f->_first + arg_position / mapfile::buf_size;
  186. offset = arg_position % mapfile::buf_size;
  187. file->lock(node);
  188. }
  189. mapfile_iterator(const mapfile_iterator& i)
  190. {
  191. file = i.file;
  192. node = i.node;
  193. offset = i.offset;
  194. if(file)
  195. file->lock(node);
  196. }
  197. ~mapfile_iterator()
  198. {
  199. if(file && node)
  200. file->unlock(node);
  201. }
  202. mapfile_iterator& operator = (const mapfile_iterator& i);
  203. char operator* ()const
  204. {
  205. BOOST_ASSERT(node >= file->_first);
  206. BOOST_ASSERT(node < file->_last);
  207. return file ? *(*node + sizeof(int) + offset) : char(0);
  208. }
  209. char operator[] (long off)const
  210. {
  211. mapfile_iterator tmp(*this);
  212. tmp += off;
  213. return *tmp;
  214. }
  215. mapfile_iterator& operator++ ();
  216. mapfile_iterator operator++ (int);
  217. mapfile_iterator& operator-- ();
  218. mapfile_iterator operator-- (int);
  219. mapfile_iterator& operator += (long off)
  220. {
  221. position(position() + off);
  222. return *this;
  223. }
  224. mapfile_iterator& operator -= (long off)
  225. {
  226. position(position() - off);
  227. return *this;
  228. }
  229. friend inline bool operator==(const mapfile_iterator& i, const mapfile_iterator& j)
  230. {
  231. return (i.file == j.file) && (i.node == j.node) && (i.offset == j.offset);
  232. }
  233. friend inline bool operator!=(const mapfile_iterator& i, const mapfile_iterator& j)
  234. {
  235. return !(i == j);
  236. }
  237. friend inline bool operator<(const mapfile_iterator& i, const mapfile_iterator& j)
  238. {
  239. return i.position() < j.position();
  240. }
  241. friend inline bool operator>(const mapfile_iterator& i, const mapfile_iterator& j)
  242. {
  243. return i.position() > j.position();
  244. }
  245. friend inline bool operator<=(const mapfile_iterator& i, const mapfile_iterator& j)
  246. {
  247. return i.position() <= j.position();
  248. }
  249. friend inline bool operator>=(const mapfile_iterator& i, const mapfile_iterator& j)
  250. {
  251. return i.position() >= j.position();
  252. }
  253. friend mapfile_iterator operator + (const mapfile_iterator& i, long off);
  254. friend mapfile_iterator operator + (long off, const mapfile_iterator& i)
  255. {
  256. mapfile_iterator tmp(i);
  257. return tmp += off;
  258. }
  259. friend mapfile_iterator operator - (const mapfile_iterator& i, long off);
  260. friend inline long operator - (const mapfile_iterator& i, const mapfile_iterator& j)
  261. {
  262. return i.position() - j.position();
  263. }
  264. };
  265. #endif
  266. // _fi_sep determines the directory separator, either '\\' or '/'
  267. BOOST_REGEX_DECL extern const char* _fi_sep;
  268. struct file_iterator_ref
  269. {
  270. _fi_find_handle hf;
  271. _fi_find_data _data;
  272. long count;
  273. };
  274. class BOOST_REGEX_DECL file_iterator
  275. {
  276. char* _root;
  277. char* _path;
  278. char* ptr;
  279. file_iterator_ref* ref;
  280. public:
  281. typedef std::ptrdiff_t difference_type;
  282. typedef const char* value_type;
  283. typedef const char** pointer;
  284. typedef const char*& reference;
  285. typedef std::input_iterator_tag iterator_category;
  286. file_iterator();
  287. file_iterator(const char* wild);
  288. ~file_iterator();
  289. file_iterator(const file_iterator&);
  290. file_iterator& operator=(const file_iterator&);
  291. const char* root()const { return _root; }
  292. const char* path()const { return _path; }
  293. const char* name()const { return ptr; }
  294. _fi_find_data* data() { return &(ref->_data); }
  295. void next();
  296. file_iterator& operator++() { next(); return *this; }
  297. file_iterator operator++(int);
  298. const char* operator*() { return path(); }
  299. friend inline bool operator == (const file_iterator& f1, const file_iterator& f2)
  300. {
  301. return ((f1.ref->hf == _fi_invalid_handle) && (f2.ref->hf == _fi_invalid_handle));
  302. }
  303. friend inline bool operator != (const file_iterator& f1, const file_iterator& f2)
  304. {
  305. return !(f1 == f2);
  306. }
  307. };
  308. // dwa 9/13/00 - suppress unused parameter warning
  309. inline bool operator < (const file_iterator&, const file_iterator&)
  310. {
  311. return false;
  312. }
  313. class BOOST_REGEX_DECL directory_iterator
  314. {
  315. char* _root;
  316. char* _path;
  317. char* ptr;
  318. file_iterator_ref* ref;
  319. public:
  320. typedef std::ptrdiff_t difference_type;
  321. typedef const char* value_type;
  322. typedef const char** pointer;
  323. typedef const char*& reference;
  324. typedef std::input_iterator_tag iterator_category;
  325. directory_iterator();
  326. directory_iterator(const char* wild);
  327. ~directory_iterator();
  328. directory_iterator(const directory_iterator& other);
  329. directory_iterator& operator=(const directory_iterator& other);
  330. const char* root()const { return _root; }
  331. const char* path()const { return _path; }
  332. const char* name()const { return ptr; }
  333. _fi_find_data* data() { return &(ref->_data); }
  334. void next();
  335. directory_iterator& operator++() { next(); return *this; }
  336. directory_iterator operator++(int);
  337. const char* operator*() { return path(); }
  338. static const char* separator() { return _fi_sep; }
  339. friend inline bool operator == (const directory_iterator& f1, const directory_iterator& f2)
  340. {
  341. return ((f1.ref->hf == _fi_invalid_handle) && (f2.ref->hf == _fi_invalid_handle));
  342. }
  343. friend inline bool operator != (const directory_iterator& f1, const directory_iterator& f2)
  344. {
  345. return !(f1 == f2);
  346. }
  347. };
  348. inline bool operator < (const directory_iterator&, const directory_iterator&)
  349. {
  350. return false;
  351. }
  352. #ifdef BOOST_HAS_ABI_HEADERS
  353. # include BOOST_ABI_SUFFIX
  354. #endif
  355. } // namespace BOOST_REGEX_DETAIL_NS
  356. using boost::BOOST_REGEX_DETAIL_NS::directory_iterator;
  357. using boost::BOOST_REGEX_DETAIL_NS::file_iterator;
  358. using boost::BOOST_REGEX_DETAIL_NS::mapfile;
  359. } // namespace boost
  360. #endif // BOOST_REGEX_NO_FILEITER
  361. #endif // BOOST_RE_FILEITER_HPP