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