Joedb 10.4.3
The Journal-Only Embedded Database
Loading...
Searching...
No Matches
filebuf.cpp
Go to the documentation of this file.
3
4namespace joedb
5{
6 ////////////////////////////////////////////////////////////////////////////
7 void filebuf::syncg()
8 ////////////////////////////////////////////////////////////////////////////
9 {
10 in_pos += gptr() - eback();
11 setg(buffer.data(), buffer.data(), buffer.data());
12 }
13
14 ////////////////////////////////////////////////////////////////////////////
15 void filebuf::syncp()
16 ////////////////////////////////////////////////////////////////////////////
17 {
18 const ptrdiff_t n = pptr() - pbase();
19 if (n)
20 {
21 file.pwrite(buffer.data(), n, out_pos);
22 out_pos += n;
23 setp(buffer.data(), buffer.data() + buffer_size);
24 }
25 }
26
27 ////////////////////////////////////////////////////////////////////////////
28 filebuf::pos_type filebuf::seekoff
29 ////////////////////////////////////////////////////////////////////////////
30 (
31 off_type off,
32 std::ios_base::seekdir dir,
33 std::ios_base::openmode which
34 )
35 {
36 pos_type base = -1;
37
38 if (dir == std::ios_base::beg)
39 base = 0;
40 else if (dir == std::ios_base::cur)
41 {
42 base = bool(which & std::ios_base::in)
43 ? in_pos + gptr() - eback()
44 : out_pos + pptr() - pbase();
45 }
46 else if (dir == std::ios_base::end)
47 {
48 syncp();
49 base = file.get_size();
50 }
51
52 if (base < 0)
53 return pos_type(off_type(-1));
54 else
55 return seekpos(base + off, which);
56 }
57
58 ////////////////////////////////////////////////////////////////////////////
59 filebuf::pos_type filebuf::seekpos
60 ////////////////////////////////////////////////////////////////////////////
61 (
62 pos_type pos,
63 std::ios_base::openmode which
64 )
65 {
66 sync();
67
68 if (which & std::ios_base::in)
69 in_pos = pos;
70
71 if (which & std::ios_base::out)
72 out_pos = pos;
73
74 return pos;
75 }
76
77 ////////////////////////////////////////////////////////////////////////////
79 ////////////////////////////////////////////////////////////////////////////
80 {
81 syncg();
82 syncp();
83 return 0;
84 }
85
86 ////////////////////////////////////////////////////////////////////////////
87 std::streamsize filebuf::showmanyc()
88 ////////////////////////////////////////////////////////////////////////////
89 {
90 const int64_t size = file.get_size();
91 if (size < 0)
92 return 0;
93 return size - (in_pos + gptr() - eback());
94 }
95
96 ////////////////////////////////////////////////////////////////////////////
97 filebuf::int_type filebuf::underflow()
98 ////////////////////////////////////////////////////////////////////////////
99 {
100 if (gptr() == egptr())
101 {
102 in_pos += gptr() - eback();
103 const size_t size = file.pread(buffer.data(), buffer.size(), in_pos);
104 setg(buffer.data(), buffer.data(), buffer.data() + size);
105 if (size == 0)
106 return traits_type::eof();
107 }
108
109 return traits_type::to_int_type(*gptr());
110 }
111
112 ////////////////////////////////////////////////////////////////////////////
113 std::streamsize filebuf::xsgetn(char_type* s, std::streamsize count)
114 ////////////////////////////////////////////////////////////////////////////
115 {
116 std::streamsize result = 0;
117
118 {
119 const std::streamsize available = egptr() - gptr();
120 const std::streamsize n = std::min(available, count);
121 std::memcpy(s, gptr(), n);
122 gbump(int(n));
123 result += n;
124 s += n;
125 count -= n;
126 }
127
128 if (count > 0)
129 {
130 syncg();
131
132 do
133 {
134 const std::streamsize n = std::streamsize(file.pread(s, count, in_pos));
135 if (n > 0)
136 {
137 in_pos += n;
138 result += n;
139 s += n;
140 count -= n;
141 }
142 else
143 break;
144 }
145 while (count > 0);
146 }
147
148 return result;
149 }
150
151 ////////////////////////////////////////////////////////////////////////////
152 std::streamsize filebuf::xsputn(const char_type* s, std::streamsize count)
153 ////////////////////////////////////////////////////////////////////////////
154 {
155 const ptrdiff_t available = epptr() - pptr();
156
157 if (available >= count)
158 {
159 std::memcpy(pptr(), s, count);
160 pbump(int(count));
161 }
162 else
163 {
164 syncp();
165 file.pwrite(s, count, out_pos);
166 out_pos += count;
167 }
168
169 return count;
170 }
171
172 ////////////////////////////////////////////////////////////////////////////
173 filebuf::int_type filebuf::overflow(int_type ch)
174 ////////////////////////////////////////////////////////////////////////////
175 {
176 if (pptr() >= epptr())
177 syncp();
178
179 if (!traits_type::eq_int_type(ch, traits_type::eof()))
180 {
181 *pptr() = traits_type::to_char_type(ch);
182 pbump(1);
183 }
184
185 return traits_type::not_eof(ch);
186 }
187
188 ////////////////////////////////////////////////////////////////////////////
189 filebuf::int_type filebuf::pbackfail(int_type c)
190 ////////////////////////////////////////////////////////////////////////////
191 {
192 if (gptr() == eback() && in_pos > 0)
193 {
194 in_pos -= 1;
195 setg(buffer.data(), buffer.data() + 1, buffer.data() + 1);
196 file.pread(buffer.data(), 1, in_pos);
197 }
198
199 if (gptr() > eback())
200 {
201 gbump(-1);
202 if (!traits_type::eq_int_type(c, traits_type::eof()))
203 {
204 const char cc = traits_type::to_char_type(c);
205 if (*gptr() != cc)
206 {
207 *gptr() = cc;
208 file.pwrite(gptr(), 1, in_pos + gptr() - eback());
209 }
210 }
211 return traits_type::to_int_type(*gptr());
212 }
213
214 return traits_type::eof();
215 }
216
217 ////////////////////////////////////////////////////////////////////////////
219 ////////////////////////////////////////////////////////////////////////////
220 {
221 in_pos = 0;
222 setg(buffer.data(), buffer.data(), buffer.data());
223
224 out_pos = 0;
225 setp(buffer.data(), buffer.data() + buffer_size);
226 }
227
228 ////////////////////////////////////////////////////////////////////////////
230 ////////////////////////////////////////////////////////////////////////////
231 {
232 if (pptr() > pbase())
233 {
234 Destructor_Logger::warning("filebuf: flushing buffer");
235 try {syncp();} catch (...) {}
236 }
237 }
238}
virtual int64_t get_size() const
Get the size of the file, or -1 if it is unknown.
virtual void pwrite(const char *data, size_t size, int64_t offset)
Write a range of bytes. Extend file size if necessary.
virtual size_t pread(char *data, size_t size, int64_t offset) const
Read a range of bytes.
static void warning(beman::cstring_view message) noexcept
int sync() override
Definition filebuf.cpp:78
pos_type seekpos(pos_type pos, std::ios_base::openmode which) override
Definition filebuf.cpp:61
pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which) override
Definition filebuf.cpp:30
std::streamsize showmanyc() override
Definition filebuf.cpp:87
filebuf(Abstract_File &file)
Definition filebuf.cpp:218
~filebuf() override
Definition filebuf.cpp:229
int_type pbackfail(int_type c) override
Definition filebuf.cpp:189
int_type overflow(int_type ch) override
Definition filebuf.cpp:173
std::streamsize xsputn(const char_type *s, std::streamsize count) override
Definition filebuf.cpp:152
int_type underflow() override
Definition filebuf.cpp:97
std::streamsize xsgetn(char_type *s, std::streamsize count) override
Definition filebuf.cpp:113