Joedb 10.2.1
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 = (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 base = file.get_size();
48
49 if (base < 0)
50 return pos_type(off_type(-1));
51 else
52 return seekpos(base + off, which);
53 }
54
55 ////////////////////////////////////////////////////////////////////////////
56 filebuf::pos_type filebuf::seekpos
57 ////////////////////////////////////////////////////////////////////////////
58 (
59 pos_type pos,
60 std::ios_base::openmode which
61 )
62 {
63 sync();
64
65 if (which & std::ios_base::in)
66 in_pos = pos;
67
68 if (which & std::ios_base::out)
69 out_pos = pos;
70
71 return pos;
72 }
73
74 ////////////////////////////////////////////////////////////////////////////
76 ////////////////////////////////////////////////////////////////////////////
77 {
78 syncg();
79 syncp();
80 return 0;
81 }
82
83 ////////////////////////////////////////////////////////////////////////////
84 std::streamsize filebuf::showmanyc()
85 ////////////////////////////////////////////////////////////////////////////
86 {
87 const int64_t size = file.get_size();
88 if (size < 0)
89 return 0;
90 return size - (in_pos + gptr() - eback());
91 }
92
93 ////////////////////////////////////////////////////////////////////////////
94 filebuf::int_type filebuf::underflow()
95 ////////////////////////////////////////////////////////////////////////////
96 {
97 if (gptr() == egptr())
98 {
99 in_pos += gptr() - eback();
100 const size_t size = file.pread(buffer.data(), buffer.size(), in_pos);
101 setg(buffer.data(), buffer.data(), buffer.data() + size);
102 if (size == 0)
103 return traits_type::eof();
104 }
105
106 return traits_type::to_int_type(*gptr());
107 }
108
109 ////////////////////////////////////////////////////////////////////////////
110 std::streamsize filebuf::xsgetn(char_type* s, std::streamsize count)
111 ////////////////////////////////////////////////////////////////////////////
112 {
113 std::streamsize result = 0;
114
115 {
116 const std::streamsize available = egptr() - gptr();
117 const std::streamsize n = std::min(available, count);
118 std::memcpy(s, gptr(), n);
119 gbump(int(n));
120 result += n;
121 s += n;
122 count -= n;
123 }
124
125 if (count > 0)
126 {
127 syncg();
128
129 do
130 {
131 const std::streamsize n = std::streamsize(file.pread(s, count, in_pos));
132 if (n > 0)
133 {
134 in_pos += n;
135 result += n;
136 s += n;
137 count -= n;
138 }
139 else
140 break;
141 }
142 while (count > 0);
143 }
144
145 return result;
146 }
147
148 ////////////////////////////////////////////////////////////////////////////
149 std::streamsize filebuf::xsputn(const char_type* s, std::streamsize count)
150 ////////////////////////////////////////////////////////////////////////////
151 {
152 const ptrdiff_t available = epptr() - pptr();
153
154 if (available >= count)
155 {
156 std::memcpy(pptr(), s, count);
157 pbump(int(count));
158 }
159 else
160 {
161 syncp();
162 file.pwrite(s, count, out_pos);
163 out_pos += count;
164 }
165
166 return count;
167 }
168
169 ////////////////////////////////////////////////////////////////////////////
170 filebuf::int_type filebuf::overflow(int_type ch)
171 ////////////////////////////////////////////////////////////////////////////
172 {
173 if (pptr() >= epptr())
174 syncp();
175
176 if (!traits_type::eq_int_type(ch, traits_type::eof()))
177 {
178 *pptr() = traits_type::to_char_type(ch);
179 pbump(1);
180 }
181
182 return traits_type::not_eof(ch);
183 }
184
185 ////////////////////////////////////////////////////////////////////////////
186 filebuf::int_type filebuf::pbackfail(int_type c)
187 ////////////////////////////////////////////////////////////////////////////
188 {
189 if (gptr() == eback() && in_pos > 0)
190 {
191 in_pos -= 1;
192 setg(buffer.data(), buffer.data() + 1, buffer.data() + 1);
193 file.pread(buffer.data(), 1, in_pos);
194 }
195
196 if (gptr() > eback())
197 {
198 gbump(-1);
199 if (!traits_type::eq_int_type(c, traits_type::eof()))
200 {
201 const char cc = traits_type::to_char_type(c);
202 if (*gptr() != cc)
203 {
204 *gptr() = cc;
205 file.pwrite(gptr(), 1, in_pos + gptr() - eback());
206 }
207 }
208 return *gptr();
209 }
210
211 return traits_type::eof();
212 }
213
214 ////////////////////////////////////////////////////////////////////////////
216 ////////////////////////////////////////////////////////////////////////////
217 {
218 in_pos = 0;
219 setg(buffer.data(), buffer.data(), buffer.data());
220
221 out_pos = 0;
222 setp(buffer.data(), buffer.data() + buffer_size);
223 }
224
225 ////////////////////////////////////////////////////////////////////////////
227 ////////////////////////////////////////////////////////////////////////////
228 {
229 if (pptr() > pbase())
230 {
231 Destructor_Logger::warning("filebuf: flushing buffer");
232 try {syncp();} catch (...) {}
233 }
234 }
235}
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(std::string_view message) noexcept
int sync() override
Definition filebuf.cpp:75
pos_type seekpos(pos_type pos, std::ios_base::openmode which) override
Definition filebuf.cpp:58
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:84
filebuf(Abstract_File &file)
Definition filebuf.cpp:215
~filebuf() override
Definition filebuf.cpp:226
int_type pbackfail(int_type c) override
Definition filebuf.cpp:186
int_type overflow(int_type ch) override
Definition filebuf.cpp:170
std::streamsize xsputn(const char_type *s, std::streamsize count) override
Definition filebuf.cpp:149
int_type underflow() override
Definition filebuf.cpp:94
std::streamsize xsgetn(char_type *s, std::streamsize count) override
Definition filebuf.cpp:110