00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef IXE_mappedFile_H
00026 #define IXE_mappedFile_H
00027
00028
00029 #include "platform.h"
00030
00031
00032 #include <iterator>
00033 #include <sys/types.h>
00034 #include <cerrno>
00035
00036
00037 #include "include/error.h"
00038 #include "io/FileHandle.h"
00039
00040 #ifdef _WIN32
00041 #include <windows.h>
00042 #endif
00043
00044 namespace IXE {
00045
00046 namespace io {
00047
00048
00061
00062
00063 class MappedFileView
00064 {
00065 public:
00067
00068 # ifdef _WIN32
00069 typedef DWORD size_type;
00070 # else
00071 typedef off64_t size_type;
00072 # endif
00073 typedef std::bidirectional_iterator_tag iterator_category;
00074 typedef char value_type;
00075 typedef ptrdiff_t difference_type;
00076 typedef value_type* pointer;
00077 typedef value_type& reference;
00078 typedef value_type const& const_reference;
00079
00081
00082 MappedFileView() : size_(0), addr_(0), ptr_(0)
00083 # ifdef _WIN32
00084 , map_(0)
00085 # endif
00086 { }
00087
00088 MappedFileView(FileHandle* fh, off64_t offset, size_type size,
00089 std::ios::openmode mode = std::ios::in) {
00090 open(fh, offset, size, mode);
00091 }
00092
00093 MappedFileView(FileHandle* fh) { open(fh, 0, (size_type)fh->size()); }
00094
00095 ~MappedFileView() { close(); }
00096
00098
00099 typedef value_type* iterator;
00100 typedef value_type const* const_iterator;
00101
00102 # ifdef _MSC_VER
00103 typedef std::reverse_bidirectional_iterator<iterator, char*> reverse_iterator;
00104 typedef std::reverse_bidirectional_iterator<const_iterator, char*, char const&> const_reverse_iterator;
00105 # else
00106 typedef std::reverse_iterator<char*> reverse_iterator;
00107 typedef const std::reverse_iterator<char const*> const_reverse_iterator;
00108 # endif
00109
00110 iterator begin() { return (iterator)ptr_; }
00111 const_iterator begin() const { return (const_iterator)ptr_; }
00112 iterator end() { return begin() + size_; }
00113 const_iterator end() const { return begin() + size_; }
00114
00115 reverse_iterator rbegin() { return reverse_iterator(end()); }
00116 reverse_iterator rend() { return reverse_iterator(begin()); }
00117 const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
00118 const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
00119
00121
00122 bool open(FileHandle* fh, off64_t offset, size_type size,
00123 std::ios::openmode mode = std::ios::in);
00124 void close();
00125
00126 reference back() { return *(end() - 1); }
00127 const_reference back() const { return *(end() - 1); }
00128 reference front() { return *begin(); }
00129 const_reference front() const { return *begin(); }
00130 bool empty() const { return !size_; }
00131 size_type max_size() const { return size_; }
00132 size_type size() const { return size_; }
00133
00134 reference operator [](size_type i) { return *(begin() + i); }
00135
00136 const_reference operator [](size_type i) const {
00137 return *(begin() + i);
00138 }
00139
00140 protected:
00141 # ifdef _WIN32
00142 HANDLE map_;
00143 # endif
00144 size_type size_;
00145 void* addr_;
00146 void* ptr_;
00147 };
00148
00152 class mappedFile : public MappedFileView
00153 {
00154 public:
00156
00157 mappedFile() { init(); }
00158 mappedFile(char const* path, std::ios::openmode mode = std::ios::in) {
00159 init();
00160 int r = open(path, mode);
00161 if (!r) {
00162 printf("%d\n", errno);
00163 throw MmapError(std::string("Cannot mmap file ") + path);
00164 }
00165 }
00166 ~mappedFile() { close(); }
00167
00169
00170 bool open(char const *path,
00171 std::ios::openmode = std::ios::in);
00172 void close();
00173 operator bool() const { return !errno_; }
00174 int error() const { return errno_; }
00175 bool write(off64_t offset, void const* data, Size length);
00176 bool remap(Size size, std::ios::openmode = std::ios::in);
00177 FileHandle& handle() { return fh_; }
00178
00179 private:
00180 FileHandle fh_;
00181 int errno_;
00182
00183 void init();
00184 };
00185
00186 }
00187 }
00188
00189 #endif