• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #if defined _WIN32 || defined _WIN64
2 #include <sys/types.h>
3 #include <sys/stat.h>
4 #include <Windows.h>
5 #else  // defined _WIN32 || defined _WIN64
6 #include <sys/mman.h>
7 #include <sys/stat.h>
8 #include <sys/types.h>
9 #include <fcntl.h>
10 #include <unistd.h>
11 #endif  // defined _WIN32 || defined _WIN64
12 
13 #include "mapper.h"
14 
15 namespace marisa_alpha {
16 
17 #if defined _WIN32 || defined _WIN64
Mapper()18 Mapper::Mapper()
19     : ptr_(NULL), origin_(NULL), avail_(0), size_(0),
20       file_(NULL), map_(NULL) {}
21 
Mapper(const void * ptr,std::size_t size)22 Mapper::Mapper(const void *ptr, std::size_t size)
23     : ptr_(ptr), origin_(NULL), avail_(size), size_(0),
24       file_(NULL), map_(NULL) {
25   MARISA_ALPHA_THROW_IF((ptr == NULL) && (size != 0),
26       MARISA_ALPHA_PARAM_ERROR);
27 }
28 #else  // defined _WIN32 || defined _WIN64
29 Mapper::Mapper()
30     : ptr_(NULL), origin_(MAP_FAILED), avail_(0), size_(0), fd_(-1) {}
31 
32 Mapper::Mapper(const void *ptr, std::size_t size)
33     : ptr_(ptr), origin_(MAP_FAILED), avail_(size), size_(0), fd_(-1) {
34   MARISA_ALPHA_THROW_IF((ptr == NULL) && (size != 0),
35       MARISA_ALPHA_PARAM_ERROR);
36 }
37 #endif  // defined _WIN32 || defined _WIN64
38 
39 #if defined _WIN32 || defined _WIN64
~Mapper()40 Mapper::~Mapper() {
41   if (origin_ != NULL) {
42     ::UnmapViewOfFile(origin_);
43   }
44 
45   if (map_ != NULL) {
46     ::CloseHandle(map_);
47   }
48 
49   if (file_ != NULL) {
50     ::CloseHandle(file_);
51   }
52 }
53 #else  // defined _WIN32 || defined _WIN64
~Mapper()54 Mapper::~Mapper() {
55   if (origin_ != MAP_FAILED) {
56     ::munmap(origin_, size_);
57   }
58 
59   if (fd_ != -1) {
60     ::close(fd_);
61   }
62 }
63 #endif  // defined _WIN32 || defined _WIN64
64 
65 #if defined _WIN32 || defined _WIN64
open(const char * filename,long offset,int whence)66 void Mapper::open(const char *filename, long offset, int whence) {
67   MARISA_ALPHA_THROW_IF(is_open(), MARISA_ALPHA_STATE_ERROR);
68   MARISA_ALPHA_THROW_IF(filename == NULL, MARISA_ALPHA_PARAM_ERROR);
69 
70   struct __stat64 st;
71   if (::_stat64(filename, &st) != 0) {
72     MARISA_ALPHA_THROW(MARISA_ALPHA_IO_ERROR);
73   }
74   const UInt64 file_size = st.st_size;
75   MARISA_ALPHA_THROW_IF(file_size > MARISA_ALPHA_UINT32_MAX,
76       MARISA_ALPHA_SIZE_ERROR);
77 
78   Mapper temp;
79   temp.size_ = (std::size_t)file_size;
80 
81   temp.file_ = ::CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ,
82     NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
83   MARISA_ALPHA_THROW_IF(temp.file_ == NULL, MARISA_ALPHA_IO_ERROR);
84 
85   temp.map_ = ::CreateFileMapping(temp.file_, NULL, PAGE_READONLY, 0, 0, NULL);
86   MARISA_ALPHA_THROW_IF(temp.map_ == NULL, MARISA_ALPHA_IO_ERROR);
87 
88   temp.origin_ = ::MapViewOfFile(temp.map_, FILE_MAP_READ, 0, 0, 0);
89   MARISA_ALPHA_THROW_IF(temp.origin_ == NULL, MARISA_ALPHA_IO_ERROR);
90 
91   temp.seek(offset, whence);
92   temp.swap(this);
93 }
94 #else  // defined _WIN32 || defined _WIN64
open(const char * filename,long offset,int whence)95 void Mapper::open(const char *filename, long offset, int whence) {
96   MARISA_ALPHA_THROW_IF(is_open(), MARISA_ALPHA_STATE_ERROR);
97   MARISA_ALPHA_THROW_IF(filename == NULL, MARISA_ALPHA_PARAM_ERROR);
98 
99   struct stat st;
100   if (::stat(filename, &st) != 0) {
101     MARISA_ALPHA_THROW(MARISA_ALPHA_IO_ERROR);
102   }
103   UInt64 file_size = st.st_size;
104   MARISA_ALPHA_THROW_IF(file_size > MARISA_ALPHA_UINT32_MAX,
105       MARISA_ALPHA_SIZE_ERROR);
106 
107   Mapper temp;
108   temp.size_ = (std::size_t)file_size;
109 
110   temp.fd_ = ::open(filename, O_RDONLY);
111   MARISA_ALPHA_THROW_IF(temp.fd_ == -1, MARISA_ALPHA_IO_ERROR);
112 
113   temp.origin_ = ::mmap(NULL, temp.size_, PROT_READ, MAP_SHARED, temp.fd_, 0);
114   MARISA_ALPHA_THROW_IF(temp.origin_ == MAP_FAILED, MARISA_ALPHA_IO_ERROR);
115 
116   temp.seek(offset, whence);
117   temp.swap(this);
118 }
119 #endif  // defined _WIN32 || defined _WIN64
120 
clear()121 void Mapper::clear() {
122   Mapper().swap(this);
123 }
124 
swap(Mapper * rhs)125 void Mapper::swap(Mapper *rhs) {
126   MARISA_ALPHA_THROW_IF(rhs == NULL, MARISA_ALPHA_PARAM_ERROR);
127   Swap(&ptr_, &rhs->ptr_);
128   Swap(&avail_, &rhs->avail_);
129   Swap(&origin_, &rhs->origin_);
130   Swap(&size_, &rhs->size_);
131 #if defined _WIN32 || defined _WIN64
132   Swap(&file_, &rhs->file_);
133   Swap(&map_, &rhs->map_);
134 #else  // defined _WIN32 || defined _WIN64
135   Swap(&fd_, &rhs->fd_);
136 #endif  // defined _WIN32 || defined _WIN64
137 }
138 
seek(long offset,int whence)139 void Mapper::seek(long offset, int whence) {
140   switch (whence) {
141     case SEEK_SET:
142     case SEEK_CUR: {
143       MARISA_ALPHA_THROW_IF((offset < 0) || ((unsigned long)offset > size_),
144           MARISA_ALPHA_IO_ERROR);
145       ptr_ = static_cast<const UInt8 *>(origin_) + offset;
146       avail_ = (std::size_t)(size_ - offset);
147       return;
148     }
149     case SEEK_END: {
150       MARISA_ALPHA_THROW_IF((offset > 0) || ((unsigned long)-offset > size_),
151           MARISA_ALPHA_IO_ERROR);
152       ptr_ = static_cast<const UInt8 *>(origin_) + size_ + offset;
153       avail_ = (std::size_t)-offset;
154       return;
155     }
156     default: {
157       MARISA_ALPHA_THROW(MARISA_ALPHA_PARAM_ERROR);
158     }
159   }
160 }
161 
map_data(std::size_t size)162 const void *Mapper::map_data(std::size_t size) {
163   MARISA_ALPHA_THROW_IF(!is_open(), MARISA_ALPHA_STATE_ERROR);
164   MARISA_ALPHA_THROW_IF(size > avail_, MARISA_ALPHA_IO_ERROR);
165   ptr_ = static_cast<const UInt8 *>(ptr_) + size;
166   avail_ -= size;
167   return static_cast<const UInt8 *>(ptr_) - size;
168 }
169 
170 }  // namespace marisa_alpha
171