//
// MemoryMapFile.cpp
// Test
//
// Created by å¨è´ºä¼ on 2017/8/3.
// Copyright © 2017年 zhouhewei. All rights reserved.
//
#include "MemoryMapFile.hpp"
#include
#include
#include
#include
#include
IMemoryMapFile* createMemoryFileInstance(const char* fileName, long initFileSize)
{
return new CMemoryMapFile(fileName, initFileSize);
}
CMemoryMapFile::CMemoryMapFile()
{
m_size = 0;
m_capacity = 0;
m_map_file_ptr = NULL;
m_file_write_ptr = NULL;
m_file_read_ptr = NULL;
m_fd = -1;
}
CMemoryMapFile::CMemoryMapFile(_IN_ const char* fileName, _IN_ long initFileSize)
{
m_size = 0;
m_capacity = 0;
m_map_file_ptr = NULL;
m_file_write_ptr = NULL;
m_file_read_ptr = NULL;
m_fd = -1;
MMOpen(fileName, initFileSize);
}
CMemoryMapFile::~CMemoryMapFile()
{
MMClose();
}
//write functions
long CMemoryMapFile::getWritePosition()
{
if (!m_file_write_ptr) {
return 0;
}
return m_file_write_ptr - (char*)m_map_file_ptr;
}
bool CMemoryMapFile::setWritePosition(_IN_ long pos)
{
if (!m_file_write_ptr) {
return false;
}
if (pos >= m_capacity) {
return false;
}
m_file_write_ptr = (char*)m_map_file_ptr + pos;
return true;
}
bool CMemoryMapFile::writeData(_IN_ const void* buffer, _IN_ long size)
{
if (!m_file_write_ptr) {
return false;
}
long writeSpace = m_capacity - (m_file_write_ptr - (char*)m_map_file_ptr);
if (writeSpace < size) {
if(!reSizeFile(size - writeSpace + m_capacity)){
return false;
}
}
memcpy(m_file_write_ptr, buffer, size);
m_file_write_ptr += size;
if (m_file_write_ptr > (char*)m_map_file_ptr + m_size) {
m_size = m_file_write_ptr - (char*)m_map_file_ptr;
}
return true;
}
bool CMemoryMapFile::writeData(_IN_ long startPosition, _IN_ const void* buffer, _IN_ long size)
{
if (!m_file_write_ptr) {
return false;
}
if (setWritePosition(startPosition)) {
return writeData(buffer, size);
}
return false;
}
//read functions
long CMemoryMapFile::getReadPosition()
{
if (!m_file_read_ptr) {
return 0;
}
return m_file_read_ptr - (char*)m_map_file_ptr;
}
bool CMemoryMapFile::setReadPosition(_IN_ long pos)
{
if (!m_file_read_ptr) {
return false;
}
if (pos >= m_size) {
return false;
}
m_file_read_ptr = (char*)m_map_file_ptr + pos;
return true;
}
bool CMemoryMapFile::readData(_OUT_ void* buffer, _IN_ long size)
{
if (!m_file_read_ptr) {
return false;
}
long readSpace = m_size - (m_file_read_ptr - (char*)m_map_file_ptr);
if (readSpace < size) {
return false;
}
memcpy(buffer, m_file_read_ptr, size);
m_file_read_ptr += size;
return true;
}
bool CMemoryMapFile::readData(_IN_ long startPosition, _OUT_ void* buffer, _IN_ long size)
{
if (!m_file_read_ptr) {
return false;
}
if (setReadPosition(startPosition)) {
return readData(buffer, size);
}
return false;
}
//get property functions
const void* CMemoryMapFile::getRawMemory()
{
return m_map_file_ptr;
}
long CMemoryMapFile::getCapacity()
{
return m_capacity;
}
long CMemoryMapFile::getFileSize()
{
return m_size;
}
//control functions
bool CMemoryMapFile::MMOpen(_IN_ const char* fileName, _IN_ long initFileSize)
{
std::string file_name = fileName;
if (file_name.length() == 0) {
return false;
}
m_fd = open(file_name.c_str() ,O_RDWR | O_CREAT | O_TRUNC, 0666);
if(m_fd == -1){
printf("open file %s failed!:%m\n", file_name.c_str());
return false;
}
lseek(m_fd, initFileSize - 1, SEEK_SET);
write(m_fd, "z", 1);
struct stat st;
int re = fstat(m_fd, &st);
if(re == -1){
printf("get file %s 's size failed!:%m\n", file_name.c_str());
close(m_fd);
return false;
}
if (st.st_size != initFileSize) {
close(m_fd);
return false;
}
m_map_file_ptr = mmap(NULL, initFileSize, PROT_READ | PROT_WRITE, MAP_SHARED, m_fd, 0);
if (!m_map_file_ptr) {
close(m_fd);
return false;
}
m_size = 0;
m_capacity = initFileSize;
m_file_write_ptr = (char*)m_map_file_ptr;
m_file_read_ptr = (char*)m_map_file_ptr;
return true;
}
bool CMemoryMapFile::MMClose()
{
if (!m_map_file_ptr) {
return true;
}
int ret = munmap(m_map_file_ptr, m_capacity);
if (ret) {
printf("close file failed!:%m\n");
return false;
}
m_map_file_ptr = NULL;
m_size = 0;
m_capacity = 0;
m_file_write_ptr = NULL;
m_file_read_ptr = NULL;
return true;
}
//private funtcions
bool CMemoryMapFile::reSizeFile(long new_size)
{
if (new_size <= m_capacity) {
return false;
}
long current_write_pos = m_file_write_ptr - (char*)m_map_file_ptr;
long current_read_pos = m_file_read_ptr - (char*)m_map_file_ptr;
int ret = munmap(m_map_file_ptr, m_capacity);
if (ret) {
printf("close file failed!:%m\n");
return false;
}
lseek(m_fd, new_size - 1, SEEK_SET);
write(m_fd, "z", 1);
m_map_file_ptr = mmap(NULL, new_size, PROT_READ | PROT_WRITE, MAP_SHARED, m_fd, 0);
if (!m_map_file_ptr) {
printf("resize file failed, file will be closed!:%m\n");
close(m_fd);
return false;
}
m_file_write_ptr = (char*)m_map_file_ptr + current_write_pos;
m_file_read_ptr = (char*)m_map_file_ptr + current_read_pos;
m_capacity = new_size;
return true;
}