Skip to content

Commit

Permalink
lib: wrapper to manage memory-mapped files
Browse files Browse the repository at this point in the history
Signed-off-by: Rick Altherr <[email protected]>
Signed-off-by: Tim 'mithro' Ansell <[email protected]>
  • Loading branch information
mx-shift authored and mithro committed Dec 20, 2017
1 parent 0b68be3 commit 30a1e46
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 0 deletions.
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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 changes: 11 additions & 0 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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()
29 changes: 29 additions & 0 deletions lib/include/prjxray/memory_mapped_file.h
Original file line number Diff line number Diff line change
@@ -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 changes: 40 additions & 0 deletions lib/memory_mapped_file.cc
Original file line number Diff line number Diff line change
@@ -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
14 changes: 14 additions & 0 deletions lib/memory_mapped_file_test.cc
Original file line number Diff line number Diff line change
@@ -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 change: 1 addition & 0 deletions lib/test_data/small_file
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
foo

0 comments on commit 30a1e46

Please sign in to comment.