PageRenderTime 66ms CodeModel.GetById 36ms RepoModel.GetById 1ms app.codeStats 0ms

/inc/lexertl/memory_file.hpp

https://bitbucket.org/catdog2/scully
C++ Header | 112 lines | 90 code | 15 blank | 7 comment | 9 complexity | fd010a045c34b3e4babf69f518c25b50 MD5 | raw file
  1. // memory_file.hpp
  2. // Copyright (c) 2012 Ben Hanson (http://www.benhanson.net/)
  3. // Inspired by http://en.wikibooks.org/wiki/Optimizing_C%2B%2B/General_optimization_techniques/Input/Output#Memory-mapped_file
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  6. // file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. #ifndef LEXERTL_MEMORY_FILE_H
  8. #define LEXERTL_MEMORY_FILE_H
  9. #ifdef __unix__
  10. #include <fcntl.h>
  11. #include <unistd.h>
  12. #include <sys/mman.h>
  13. #include <sys/stat.h>
  14. #elif defined _WIN32
  15. #include <windows.h>
  16. #endif
  17. // Only files small enough to fit into memory are supported.
  18. namespace lexertl
  19. {
  20. template<typename CharT>
  21. class basic_memory_file
  22. {
  23. public:
  24. basic_memory_file (const char *pathname_) :
  25. _data (0),
  26. _size (0)
  27. {
  28. #ifdef __unix__
  29. _fh = ::open (pathname_, O_RDONLY);
  30. if (_fh > -1)
  31. {
  32. struct stat sbuf_;
  33. if (::fstat (_fh, &sbuf_) > -1)
  34. {
  35. _data = static_cast<const CharT *>
  36. (::mmap (0, sbuf_.st_size, PROT_READ, MAP_SHARED, _fh, 0));
  37. if (_data == MAP_FAILED)
  38. {
  39. _data = 0;
  40. }
  41. else
  42. {
  43. _size = sbuf_.st_size;
  44. }
  45. }
  46. }
  47. #elif defined _WIN32
  48. _fh = ::CreateFileA (pathname_, GENERIC_READ, FILE_SHARE_READ, 0,
  49. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  50. _fmh = 0;
  51. if (_fh != INVALID_HANDLE_VALUE)
  52. {
  53. _fmh = ::CreateFileMapping (_fh, 0, PAGE_READONLY, 0, 0, 0);
  54. if (_fmh != 0)
  55. {
  56. _data = static_cast<CharT *>(::MapViewOfFile
  57. (_fmh, FILE_MAP_READ, 0, 0, 0));
  58. if (_data) _size = ::GetFileSize(_fh, 0);
  59. }
  60. }
  61. #endif
  62. }
  63. ~basic_memory_file ()
  64. {
  65. #if defined(__unix__)
  66. ::munmap(const_cast<CharT *>(_data), _size);
  67. ::close(_fh);
  68. #elif defined(_WIN32)
  69. ::UnmapViewOfFile(_data);
  70. ::CloseHandle(_fmh);
  71. ::CloseHandle(_fh);
  72. #endif
  73. }
  74. const CharT *data () const
  75. {
  76. return _data;
  77. }
  78. std::size_t size () const
  79. {
  80. return _size;
  81. }
  82. private:
  83. const CharT *_data;
  84. std::size_t _size;
  85. #ifdef __unix__
  86. int _fh;
  87. #elif defined _WIN32
  88. HANDLE _fh;
  89. HANDLE _fmh;
  90. #else
  91. #error Only Posix or Windows are supported.
  92. #endif
  93. };
  94. typedef basic_memory_file<char> memory_file;
  95. typedef basic_memory_file<wchar_t> wmemory_file;
  96. }
  97. #endif