-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathmemoryfile.hpp
112 lines (100 loc) · 3.17 KB
/
memoryfile.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// solid/utility/memoryfile.hpp
//
// Copyright (c) 2007, 2008 Valentin Palade (vipalade @ gmail . com)
//
// This file is part of SolidFrame framework.
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.
//
#pragma once
#include "solid/system/common.hpp"
#include "solid/utility/algorithm.hpp"
#include "solid/utility/common.hpp"
#include <deque>
#include <limits>
namespace solid {
//! Store in memory files
/*!
It has the same interface like FileDevice.
It has support for writing only at different offsets.
It uses the given allocator for allocating/releasing data buffers.
*/
class MemoryFile {
public:
struct Allocator {
virtual ~Allocator() {}
virtual uint bufferSize() const = 0;
virtual char* allocate() = 0;
virtual void release(char*) = 0;
virtual uint64_t computeCapacity(uint64_t _cp) = 0;
};
template <uint Sz = 4096>
struct BasicAllocator : Allocator {
static BasicAllocator<Sz>& instance()
{
static BasicAllocator<Sz> ba;
return ba;
}
/*virtual*/ uint bufferSize() const { return Sz; }
/*virtual*/ char* allocate()
{
return new char[Sz];
}
/*virtual*/ void release(char* _p)
{
delete[] _p;
}
/*virtual*/ uint64_t computeCapacity(uint64_t _cp)
{
return ((_cp / Sz) + 1) * Sz;
}
};
public:
//! Constructor with the file capacity and the allocator
MemoryFile(const int64_t _cp = 0, Allocator& _ral = BasicAllocator<>::instance());
//! Destructor
~MemoryFile();
//! Read data from file from offset
ssize_t read(char* _pb, size_t _bl, int64_t _off);
//! Write data to file at offset
ssize_t write(const char* _pb, size_t _bl, int64_t _off);
//! Read data from file
ssize_t read(char* _pb, size_t _bl);
//! Write data to file
ssize_t write(const char* _pb, uint32_t _bl);
//! Move the file cursor at position
int64_t seek(int64_t _pos, SeekRef _ref = SeekBeg);
//! Truncate the file
int truncate(int64_t _len = 0);
//! Return the size of the file
int64_t size() const;
int64_t capacity() const;
private:
binary_search_result_t doFindBuffer(const size_t _idx) const;
binary_search_result_t doLocateBuffer(const size_t _idx) const;
char* doGetBuffer(const size_t _idx) const;
char* doCreateBuffer(const size_t _idx, bool& _created);
private:
struct Buffer {
Buffer(const size_t _idx = 0, char* _data = nullptr)
: idx(_idx)
, data(_data)
{
}
size_t idx;
char* data;
};
static int64_t compute_capacity(const int64_t _cp, Allocator& _ral);
struct BuffCmp;
friend struct BuffCmp;
typedef std::deque<Buffer> BufferVectorT;
const int64_t cp;
int64_t sz;
int64_t off;
mutable size_t crtbuffidx;
const size_t bufsz;
Allocator& ra;
BufferVectorT bv;
};
} // namespace solid