mirror of https://github.com/openXC7/prjxray.git
lib: wrapper to manage memory-mapped files
Signed-off-by: Rick Altherr <kc8apf@kc8apf.net> Signed-off-by: Tim 'mithro' Ansell <mithro@mithis.com>
This commit is contained in:
parent
0b68be31a9
commit
30a1e466d3
|
|
@ -1,15 +1,22 @@
|
|||
cmake_minimum_required(VERSION 3.5.0)
|
||||
|
||||
project(prjxray)
|
||||
option(PRJXRAY_BUILD_TESTING "" ON)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Werror ${CMAKE_CXX_FLAGS} -O3" )
|
||||
|
||||
# Hack for missing option in cctz
|
||||
option(BUILD_TESTING "" OFF)
|
||||
|
||||
|
||||
if(PRJXRAY_BUILD_TESTING)
|
||||
enable_testing()
|
||||
endif()
|
||||
|
||||
add_subdirectory(third_party/googletest EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(third_party/gflags EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(third_party/cctz EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(third_party/abseil-cpp EXCLUDE_FROM_ALL)
|
||||
|
||||
add_subdirectory(lib)
|
||||
add_subdirectory(tools)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
add_library(libprjxray
|
||||
memory_mapped_file.cc)
|
||||
target_include_directories(libprjxray PUBLIC "include")
|
||||
|
||||
if (PRJXRAY_BUILD_TESTING)
|
||||
add_executable(memory_mapped_file_test memory_mapped_file_test.cc)
|
||||
target_link_libraries(memory_mapped_file_test libprjxray gtest_main)
|
||||
add_test(NAME memory_mapped_file_test
|
||||
COMMAND memory_mapped_file_test
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test_data)
|
||||
endif()
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef PRJXRAY_LIB_MEMORY_MAPPED_FILE
|
||||
#define PRJXRAY_LIB_MEMORY_MAPPED_FILE
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace prjxray {
|
||||
|
||||
class MemoryMappedFile {
|
||||
public:
|
||||
~MemoryMappedFile();
|
||||
|
||||
static std::unique_ptr<MemoryMappedFile> InitWithFile(
|
||||
const std::string &path);
|
||||
|
||||
const void* data() { return data_; }
|
||||
const size_t size() { return size_; }
|
||||
|
||||
private:
|
||||
MemoryMappedFile(void *data, size_t size)
|
||||
: data_(data), size_(size) {};
|
||||
|
||||
void *data_;
|
||||
size_t size_;
|
||||
};
|
||||
|
||||
} // namespace prjxray
|
||||
|
||||
#endif // PRJXRAY_LIB_MEMORY_MAPPED_FILE
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
#include <prjxray/memory_mapped_file.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace prjxray {
|
||||
|
||||
std::unique_ptr<MemoryMappedFile> MemoryMappedFile::InitWithFile(
|
||||
const std::string &path) {
|
||||
|
||||
int fd = open(path.c_str(), O_RDONLY, 0);
|
||||
if (fd == -1) return nullptr;
|
||||
|
||||
struct stat statbuf;
|
||||
if (fstat(fd, &statbuf) < 0) {
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void *file_map = mmap(NULL, statbuf.st_size, PROT_READ,
|
||||
MAP_PRIVATE | MAP_POPULATE, fd, 0);
|
||||
|
||||
// If mmap() succeeded, the fd is no longer needed as the mapping will
|
||||
// keep the file open. If mmap() failed, the fd needs to be closed
|
||||
// anyway.
|
||||
close(fd);
|
||||
|
||||
if (file_map == MAP_FAILED) return nullptr;
|
||||
|
||||
return std::unique_ptr<MemoryMappedFile>(
|
||||
new MemoryMappedFile(file_map, statbuf.st_size));
|
||||
}
|
||||
|
||||
MemoryMappedFile::~MemoryMappedFile() {
|
||||
munmap(data_, size_);
|
||||
}
|
||||
|
||||
} // namepsace prjxray
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
#include <prjxray/memory_mapped_file.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(MemoryMappedFileTest, NonExistantFile) {
|
||||
EXPECT_FALSE(prjxray::MemoryMappedFile::InitWithFile("does_not_exist"));
|
||||
}
|
||||
|
||||
TEST(MemoryMappedFileTest, ExistingFile) {
|
||||
auto file = prjxray::MemoryMappedFile::InitWithFile("small_file");
|
||||
ASSERT_TRUE(file);
|
||||
EXPECT_EQ(static_cast<size_t>(4), file->size());
|
||||
EXPECT_EQ(0, memcmp("foo\n", file->data(), 4));
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
foo
|
||||
Loading…
Reference in New Issue