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:
Rick Altherr 2017-11-17 01:20:12 -08:00 committed by Tim 'mithro' Ansell
parent 0b68be31a9
commit 30a1e466d3
6 changed files with 102 additions and 0 deletions

View File

@ -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)

11
lib/CMakeLists.txt Normal file
View File

@ -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()

View File

@ -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

40
lib/memory_mapped_file.cc Normal file
View 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

View File

@ -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));
}

1
lib/test_data/small_file Normal file
View File

@ -0,0 +1 @@
foo