48#if LASS_PLATFORM_TYPE == LASS_PLATFORM_TYPE_WIN32
49# define LASS_IO_MEMORY_MAP_WIN
52# if LASS_HAVE_SYS_MMAN_H && LASS_HAVE_SYS_STAT_H && LASS_HAVE_FCNTL_H && LASS_HAVE_UNISTD_H
53# define LASS_IO_MEMORY_MAP_MMAP
70#if defined(LASS_IO_MEMORY_MAP_WIN)
72class BinaryIMemoryMapImpl
75 BinaryIMemoryMapImpl(
const wchar_t* filename)
77 file_ = LASS_ENFORCE_WINAPI(::CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ,
78 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0));
80 if (!GetFileSizeEx(file_, &size))
82 const unsigned lastError = util::impl::lass_GetLastError();
83 LASS_THROW(
"Failed to get file size: (" << lastError <<
") "
84 << util::impl::lass_FormatMessage(lastError));
86#if LASS_ADDRESS_SIZE == 64
87 static_assert(
sizeof(size.QuadPart) ==
sizeof(size_t),
"LARGE_INTEGER::QuadPart must have same size as size_t");
88 fileSize_ =
static_cast<size_t>(size.QuadPart);
90 if (size.HighPart != 0)
92 LASS_THROW(
"File too large");
94 fileSize_ = size.LowPart;
96 map_ = LASS_ENFORCE_WINAPI(::CreateFileMapping(file_, 0, PAGE_READONLY, 0, 0, 0));
97 data_ =
static_cast<char*
>(LASS_ENFORCE_WINAPI(
98 ::MapViewOfFile(map_, FILE_MAP_READ, 0, 0, 0)));
101 BinaryIMemoryMapImpl(
const char* filename) :
102 BinaryIMemoryMapImpl(util::utf8ToWchar(filename).c_str())
106 ~BinaryIMemoryMapImpl()
108 LASS_WARN_WINAPI(::UnmapViewOfFile(data_));
110 LASS_WARN_WINAPI(::CloseHandle(map_));
112 LASS_WARN_WINAPI(::CloseHandle(file_));
116 size_t fileSize() const noexcept
121 const char* data()
const
133#elif defined(LASS_IO_MEMORY_MAP_MMAP)
135class BinaryIMemoryMapImpl
138 BinaryIMemoryMapImpl(
const char* filename)
140 file_ = LASS_ENFORCE_CLIB(::open(filename, O_RDONLY));
142 LASS_ENFORCE_CLIB(::fstat(file_, &buf));
143 fileSize_ =
static_cast<size_t>(buf.st_size);
144 view_ =
static_cast<char*
>(LASS_ENFORCE_CLIB_EX(
145 ::mmap(0,
static_cast<size_t>(fileSize_), PROT_READ, MAP_SHARED, file_, 0),
149 BinaryIMemoryMapImpl(
const wchar_t* filename) :
150 BinaryIMemoryMapImpl(util::wcharToUtf8(filename).c_str())
154 ~BinaryIMemoryMapImpl()
156 LASS_WARN_CLIB(::munmap(view_,
static_cast<size_t>(fileSize_)));
158 LASS_WARN_CLIB(::close(file_));
162 const char* data()
const
167 size_t fileSize() const noexcept
180# error "[LASS BUILD MSG] no implementation for BinaryIMemoryMap"
188BinaryIMemoryMap::BinaryIMemoryMap():
193BinaryIMemoryMap::BinaryIMemoryMap(
const char* filename):
199BinaryIMemoryMap::BinaryIMemoryMap(
const std::string& filename):
205#if LASS_HAVE_WCHAR_SUPPORT
207BinaryIMemoryMap::BinaryIMemoryMap(
const wchar_t* filename):
213BinaryIMemoryMap::BinaryIMemoryMap(
const std::wstring& filename):
221#if LASS_HAVE_STD_FILESYSTEM
223BinaryIMemoryMap::BinaryIMemoryMap(
const std::filesystem::path& filename):
231BinaryIMemoryMap::~BinaryIMemoryMap()
238void BinaryIMemoryMap::open(
const char* filename)
243 pimpl_.reset(
new impl::BinaryIMemoryMapImpl(filename));
245 catch (
const std::exception& error)
247 LASS_LOG(
"Error: " << error.what());
249 setstate(std::ios_base::badbit);
255void BinaryIMemoryMap::open(
const std::string& filename)
257 open(filename.c_str());
260#if LASS_HAVE_WCHAR_SUPPORT
262void BinaryIMemoryMap::open(
const wchar_t* filename)
267 pimpl_.reset(
new impl::BinaryIMemoryMapImpl(filename));
269 catch (
const std::exception& error)
271 LASS_LOG(
"Error: " << error.what());
273 setstate(std::ios_base::badbit);
279void BinaryIMemoryMap::open(
const std::wstring& filename)
281 open(filename.c_str());
288#if LASS_HAVE_STD_FILESYSTEM
290void BinaryIMemoryMap::open(
const std::filesystem::path& filename)
292 open(filename.native());
298void BinaryIMemoryMap::close()
305bool BinaryIMemoryMap::is_open()
const
307 return pimpl_.get() !=
nullptr;
314BinaryIMemoryMap::pos_type BinaryIMemoryMap::doTellg()
const
321void BinaryIMemoryMap::doSeekg(pos_type position)
326 setstate(std::ios_base::badbit);
329 position_ = position;
334void BinaryIMemoryMap::doSeekg(off_type offset, std::ios_base::seekdir direction)
340 setstate(std::ios_base::badbit);
344 auto seek = [
this](pos_type current, off_type offset)
348 const pos_type negoffset =
static_cast<pos_type
>(-offset);
349 if (negoffset > current)
351 setstate(std::ios_base::failbit);
354 this->position_ = current - negoffset;
358 const pos_type posoffset =
static_cast<pos_type
>(offset);
359 if (current > num::NumTraits<pos_type>::max - posoffset)
361 setstate(std::ios_base::failbit);
364 this->position_ = current + posoffset;
370 case std::ios_base::beg:
373 setstate(std::ios_base::failbit);
376 position_ =
static_cast<pos_type
>(offset);
378 case std::ios_base::cur:
379 seek(position_, offset);
381 case std::ios_base::end:
382 seek(pimpl_->fileSize(), offset);
385 LASS_ASSERT_UNREACHABLE;
386 setstate(std::ios_base::badbit);
393size_t BinaryIMemoryMap::doRead(
void* output,
size_t numberOfBytes)
402 setstate(std::ios_base::badbit);
406 const size_t size = pimpl_->fileSize();
407 const char* data = pimpl_->data();
408 if (position_ >= size)
410 setstate(std::ios_base::eofbit);
413 pos_type
next = position_ + numberOfBytes;
414 if (next > size || next < position_)
417 numberOfBytes = size - position_;
419 memcpy(output, &data[position_], numberOfBytes);
421 return numberOfBytes;
base class of binary input streams.
const lass::python::impl::IterNextSlot next("__next__", Py_tp_iternext)
__next__ method (iterator next)
streams, binary streams, vrmlstreams, ...
Library for Assembled Shared Sources.