SDSL  3.0.0
Succinct Data Structure Library
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 
12 namespace sdsl
13 {
14 
15 class 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
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::streambuf * open(const std::string name, std::ios_base::openmode mode)
Definition: ram_filebuf.hpp:43
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
content_type & content(const std::string &name)
Get the content.
Definition: ram_fs.hpp:61
void store(const std::string &name, content_type data)
Definition: ram_fs.hpp:33
std::vector< char, track_allocator< char > > content_type
Namespace for the succinct data structure library.
ram_fs.hpp