SDSL 3.0.2
Succinct Data Structure Library
Loading...
Searching...
No Matches
ram_filebuf.hpp
Go to the documentation of this file.
1// Copyright (c) 2016, the SDSL Project Authors. All rights reserved.
2// Please see the AUTHORS file for details. Use of this source code is governed
3// by a BSD license that can be found in the LICENSE file.
4#ifndef INCLUDED_SDSL_RAM_FSTREAMBUF
5#define INCLUDED_SDSL_RAM_FSTREAMBUF
6
7#include <algorithm>
8#include <fstream>
9#include <limits>
10#include <string>
11#include <vector>
12
14#include <sdsl/ram_fs.hpp>
15
16namespace sdsl
17{
18
19class ram_filebuf : public std::streambuf
20{
21private:
22 // TODO: also store filename/descriptor to implement is_open ???
23 ram_fs::content_type * m_ram_file = nullptr; // file handle
24 void pbump64(std::ptrdiff_t x)
25 {
26 while (x > std::numeric_limits<int>::max())
27 {
28 pbump(std::numeric_limits<int>::max());
29 x -= std::numeric_limits<int>::max();
30 }
31 pbump(x);
32 }
33
34public:
35 virtual ~ram_filebuf(){};
36
38
39 ram_filebuf(ram_fs::content_type & ram_file) : m_ram_file(&ram_file)
40 {
41 char * begin = m_ram_file->data();
42 char * end = begin + m_ram_file->size();
43 setg(begin, begin, end); // set get pointers eback(), eptr(), egptr()
44 }
45
46 std::streambuf * open(const std::string name, std::ios_base::openmode mode)
47 {
48 // open ram_file
49 if ((mode & std::ios_base::in) and !(mode & std::ios_base::trunc))
50 {
51 // file must exist, initial position at the start
52 if (!ram_fs::exists(name))
53 {
54 m_ram_file = nullptr;
55 }
56 else
57 {
58 m_ram_file = &ram_fs::content(name);
59 }
60 }
61 else
62 { // existence of file not required
63 if (!ram_fs::exists(name))
64 {
65 // create empty file, if it does not yet exist
66 ram_fs::store(name, ram_fs::content_type()); // TODO: create method in ram_fs?? or store w 1 arg?
67 }
68 m_ram_file = &ram_fs::content(name);
69 if ((mode & std::ios_base::out) and !(mode & std::ios_base::app))
70 {
71 m_ram_file->clear();
72 }
73 }
74
75 if (m_ram_file and (mode & std::ios_base::trunc))
76 {
77 m_ram_file->clear();
78 }
79 if (m_ram_file)
80 {
81 if (mode & std::ios_base::ate)
82 {
83 // TODO: move put pointer to the end of the file
84 }
85 else
86 {}
87 setg(m_ram_file->data(), m_ram_file->data(), m_ram_file->data() + m_ram_file->size());
88 setp(m_ram_file->data(), m_ram_file->data() + m_ram_file->size());
89 }
90 // ATTENTION: if m_ram_file->size() == 0, then data might be nullptr !!!
91 return m_ram_file ? this : nullptr;
92 }
93
94 bool is_open()
95 {
96 return m_ram_file != nullptr;
97 }
98
100 {
101 if (!this->is_open())
102 return nullptr;
103 m_ram_file = nullptr;
104 setg(nullptr, nullptr, nullptr);
105 setp(nullptr, nullptr);
106 return this;
107 }
108
109 pos_type seekpos(pos_type sp, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) override
110 {
111 if (sp >= (pos_type)0 and sp <= (pos_type)m_ram_file->size())
112 {
113 setg(m_ram_file->data(), m_ram_file->data() + sp, m_ram_file->data() + m_ram_file->size());
114 setp(m_ram_file->data(), m_ram_file->data() + m_ram_file->size());
115 pbump64(sp);
116 }
117 else
118 {
119 if (mode & std::ios_base::out)
120 {
121 // extend buffer
122 m_ram_file->reserve(sp);
123 m_ram_file->resize(sp, 0);
124 setg(m_ram_file->data(), m_ram_file->data() + sp, m_ram_file->data() + m_ram_file->size());
125 setp(m_ram_file->data(), m_ram_file->data() + m_ram_file->size());
126 pbump64(sp);
127 }
128 else
129 {
130 return pos_type(off_type(-1));
131 }
132 }
133 return sp;
134 }
135
136 pos_type pubseekoff(off_type off,
137 std::ios_base::seekdir way,
138 std::ios_base::openmode which = std::ios_base::in | std::ios_base::out)
139 {
140 if (std::ios_base::beg == way)
141 {
142 if (seekpos(off, which) == pos_type(-1))
143 {
144 return pos_type(-1);
145 }
146 }
147 else if (std::ios_base::cur == way)
148 {
149 if (seekpos(gptr() - eback() + off, which) == pos_type(-1))
150 {
151 return pos_type(-1);
152 }
153 }
154 else if (std::ios_base::end == way)
155 {
156 if (seekpos(egptr() - eback() + off, which) == pos_type(-1))
157 {
158 return pos_type(-1);
159 }
160 }
161 return gptr() - eback();
162 }
163
164 pos_type pubseekpos(pos_type sp, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out)
165 {
166 if (seekpos(sp, which) == pos_type(-1))
167 {
168 return pos_type(-1);
169 }
170 else
171 {
172 return gptr() - eback();
173 }
174 }
175
176 std::streamsize xsputn(char_type const * s, std::streamsize n) override
177 {
178 // std::cout<<"xsputn( , of size "<<n<<")"<<std::endl;
179 // std::cout<<"epptr()-pptr()="<<epptr()-pptr()<<std::endl;
180 if (!m_ram_file)
181 {
182 return 0;
183 }
184
185 if (n < epptr() - pptr())
186 {
187 std::copy(s, s + n, pptr());
188 pbump64(n);
189 return n;
190 }
191 else
192 {
193 if (epptr() - pbase() == (std::ptrdiff_t)m_ram_file->size() and epptr() == pptr())
194 {
195 m_ram_file->insert(m_ram_file->end(), s, s + n);
196 setp(m_ram_file->data(), m_ram_file->data() + m_ram_file->size());
197 std::ptrdiff_t add = epptr() - pbase();
198 pbump64(add);
199 setg(m_ram_file->data(), gptr(), m_ram_file->data() + m_ram_file->size());
200 return n;
201 }
202 else
203 {
204 for (std::streamsize i = 0; i < n; ++i)
205 {
206 if (traits_type::eq_int_type(sputc(s[i]), traits_type::eof()))
207 {
208 return i;
209 }
210 }
211 return n;
212 }
213 }
214 }
215
216 int sync() override
217 {
218 return 0; // we are always in sync, since buffer is sink
219 }
220
221 int_type overflow(int_type c = traits_type::eof()) override
222 {
223 if (m_ram_file)
224 {
225 m_ram_file->push_back(c);
226 setp(m_ram_file->data(), m_ram_file->data() + m_ram_file->size());
227 std::ptrdiff_t add = epptr() - pbase();
228 pbump64(add);
229 setg(m_ram_file->data(), gptr(), m_ram_file->data() + m_ram_file->size());
230 }
231 return traits_type::to_int_type(c);
232 }
233};
234} // namespace sdsl
235
236#endif
std::streambuf * open(const std::string name, std::ios_base::openmode mode)
int_type overflow(int_type c=traits_type::eof()) override
ram_filebuf(ram_fs::content_type &ram_file)
pos_type seekpos(pos_type sp, std::ios_base::openmode mode=std::ios_base::in|std::ios_base::out) override
std::streamsize xsputn(char_type const *s, std::streamsize n) override
virtual ~ram_filebuf()
pos_type pubseekpos(pos_type sp, std::ios_base::openmode which=std::ios_base::in|std::ios_base::out)
ram_filebuf * close()
pos_type pubseekoff(off_type off, std::ios_base::seekdir way, std::ios_base::openmode which=std::ios_base::in|std::ios_base::out)
int sync() override
memory_tracking.hpp contains two function for allocating and deallocating memory
void store(std::string const &name, content_type data)
Definition ram_fs.hpp:36
content_type & content(std::string const &name)
Get the content.
Definition ram_fs.hpp:67
bool exists(std::string const &name)
Check if the file exists.
Definition ram_fs.hpp:29
std::vector< char, track_allocator< char > > content_type
Namespace for the succinct data structure library.
ram_fs.hpp