source: mainline/uspace/lib/cpp/include/__bits/io/streambuf.hpp@ 8fd0675f

Last change on this file since 8fd0675f was b57ba05, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 3 years ago

Update headers in C++ files

  • Property mode set to 100644
File size: 10.4 KB
Line 
1/*
2 * SPDX-FileCopyrightText: 2018 Jaroslav Jindrak
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef LIBCPP_BITS_IO_STREAMBUF
8#define LIBCPP_BITS_IO_STREAMBUF
9
10#include <ios>
11#include <iosfwd>
12#include <locale>
13
14namespace std
15{
16
17 /**
18 * 27.6.3, class template basic_streambuf:
19 */
20
21 template<class Char, class Traits>
22 class basic_streambuf
23 {
24 public:
25 using traits_type = Traits;
26 using char_type = Char;
27 using int_type = typename traits_type::int_type;
28 using pos_type = typename traits_type::pos_type;
29 using off_type = typename traits_type::off_type;
30
31 virtual ~basic_streambuf()
32 { /* DUMMY BODY */ }
33
34 /**
35 * 27.6.3.2.1, locales:
36 */
37
38 locale pubimbue(const locale& loc)
39 {
40 imbue(loc);
41
42 return locale_;
43 }
44
45 locale getloc() const
46 {
47 return locale_;
48 }
49
50 /**
51 * 27.6.3.2.2, buffer and positioning:
52 */
53
54 basic_streambuf<Char, Traits>* pubsetbuf(char_type* s, streamsize n)
55 {
56 return setbuf(s, n);
57 }
58
59 pos_type pubseekoff(off_type off, ios_base::seekdir way,
60 ios_base::openmode which = ios_base::in | ios_base::out)
61 {
62 return seekoff(off, way, which);
63 }
64
65 pos_type pubseekpos(pos_type pos, ios_base::openmode which =
66 ios_base::in | ios_base::out)
67 {
68 return seekpos(pos, which);
69 }
70
71 int pubsync()
72 {
73 return sync();
74 }
75
76 /**
77 * 27.6.3.2.3, get area:
78 */
79
80 streamsize in_avail()
81 {
82 if (read_avail_())
83 return egptr() - gptr();
84 else
85 return showmanyc();
86 }
87
88 int_type snextc()
89 {
90 if (traits_type::eq(sbumpc(), traits_type::eof()))
91 return traits_type::eof();
92 else
93 return sgetc();
94 }
95
96 int_type sbumpc()
97 {
98 if (read_avail_())
99 return traits_type::to_int_type(*input_next_++);
100 else
101 return uflow();
102 }
103
104 int_type sgetc()
105 {
106 if (read_avail_())
107 return traits_type::to_int_type(*input_next_);
108 else
109 return underflow();
110 }
111
112 streamsize sgetn(char_type* s, streamsize n)
113 {
114 return xsgetn(s, n);
115 }
116
117 /**
118 * 27.6.2.4, putback:
119 */
120
121 int_type sputbackc(char_type c)
122 {
123 if (!putback_avail_() || traits_type::eq(c, gptr()[-1]))
124 return pbackfail(traits_type::to_int_type(c));
125 else
126 return traits_type::to_int_type(*(--input_next_));
127 }
128
129 int_type sungetc()
130 {
131 if (!putback_avail_())
132 return pbackfail();
133 else
134 return traits_type::to_int_type(*(--input_next_));
135 }
136
137 /**
138 * 27.6.2.5, put area:
139 */
140
141 int_type sputc(char_type c)
142 {
143 if (!write_avail_())
144 return overflow(traits_type::to_int_type(c));
145 else
146 {
147 traits_type::assign(*output_next_++, c);
148
149 return traits_type::to_int_type(c);
150 }
151 }
152
153 streamsize sputn(const char_type* s, streamsize n)
154 {
155 return xsputn(s, n);
156 }
157
158 protected:
159 basic_streambuf()
160 : input_begin_{}, input_next_{}, input_end_{},
161 output_begin_{}, output_next_{}, output_end_{},
162 locale_{locale()}
163 { /* DUMMY BODY */ }
164
165 basic_streambuf(const basic_streambuf& rhs)
166 {
167 input_begin_ = rhs.input_begin_;
168 input_next_ = rhs.input_next_;
169 input_end_ = rhs.input_end_;
170
171 output_begin_ = rhs.output_begin_;
172 output_next_ = rhs.output_next_;
173 output_end_ = rhs.output_end_;
174
175 locale_ = rhs.locale_;
176 }
177
178 basic_streambuf& operator=(const basic_streambuf& rhs)
179 {
180 input_begin_ = rhs.input_begin_;
181 input_next_ = rhs.input_next_;
182 input_end_ = rhs.input_end_;
183
184 output_begin_ = rhs.output_begin_;
185 output_next_ = rhs.output_next_;
186 output_end_ = rhs.output_end_;
187
188 locale_ = rhs.locale_;
189
190 return *this;
191 }
192
193 void swap(basic_streambuf& rhs)
194 {
195 swap(input_begin_, rhs.input_begin_);
196 swap(input_next_, rhs.input_next_);
197 swap(input_end_, rhs.input_end_);
198
199 swap(output_begin_, rhs.output_begin_);
200 swap(output_next_, rhs.output_next_);
201 swap(output_end_, rhs.output_end_);
202
203 swap(locale_, rhs.locale_);
204 }
205
206 /**
207 * 27.6.3.3.2, get area:
208 */
209
210 char_type* eback() const
211 {
212 return input_begin_;
213 }
214
215 char_type* gptr() const
216 {
217 return input_next_;
218 }
219
220 char_type* egptr() const
221 {
222 return input_end_;
223 }
224
225 void gbump(int n)
226 {
227 input_next_ += n;
228 }
229
230 void setg(char_type* gbeg, char_type* gnext, char_type* gend)
231 {
232 input_begin_ = gbeg;
233 input_next_ = gnext;
234 input_end_ = gend;
235 }
236
237 /**
238 * 27.6.3.3.3, put area:
239 */
240
241 char_type* pbase() const
242 {
243 return output_begin_;
244 }
245
246 char_type* pptr() const
247 {
248 return output_next_;
249 }
250
251 char_type* epptr() const
252 {
253 return output_end_;
254 }
255
256 void pbump(int n)
257 {
258 output_next_ += n;
259 }
260
261 void setp(char_type* pbeg, char_type* pend)
262 {
263 output_begin_ = pbeg;
264 output_next_ = pbeg;
265 output_end_ = pend;
266 }
267
268 /**
269 * 27.6.3.4.1, locales:
270 */
271
272 virtual void imbue(const locale& loc)
273 { /* DUMMY BODY */ }
274
275 /**
276 * 27.6.3.4.2, buffer management and positioning:
277 */
278
279 virtual basic_streambuf<Char, Traits>*
280 setbuf(char_type* s, streamsize n)
281 {
282 return this;
283 }
284
285 virtual pos_type seekoff(off_type off, ios_base::seekdir way,
286 ios_base::openmode which = ios_base::in | ios_base::out)
287 {
288 return pos_type(off_type(-1));
289 }
290
291 virtual pos_type seekpos(pos_type pos, ios_base::openmode which =
292 ios_base::in | ios_base::out)
293 {
294 return pos_type(off_type(-1));
295 }
296
297 virtual int sync()
298 {
299 return 0;
300 }
301
302 /**
303 * 27.6.3.4.3, get area:
304 */
305
306 virtual streamsize showmanyc()
307 {
308 return 0;
309 }
310
311 virtual streamsize xsgetn(char_type* s, streamsize n)
312 {
313 if (!s || n == 0)
314 return 0;
315
316 streamsize i{0};
317 auto eof = traits_type::eof();
318 for (; i <= n; ++i)
319 {
320 if (!read_avail_() && traits_type::eq_int_type(uflow(), eof))
321 break;
322
323 *s++ = *input_next_++;
324 }
325
326 return i;
327 }
328
329 virtual int_type underflow()
330 {
331 return traits_type::eof();
332 }
333
334 virtual int_type uflow()
335 {
336 auto res = underflow();
337 if (traits_type::eq_int_type(res, traits_type::eof()))
338 return traits_type::eof();
339 else
340 return traits_type::to_int_type(*input_next_++);
341 }
342
343 /**
344 * 27.6.3.4.4, putback:
345 */
346
347 virtual int_type pbackfail(int_type c = traits_type::eof())
348 {
349 return traits_type::eof();
350 }
351
352 /**
353 * 27.6.3.4.5, put area:
354 */
355
356 virtual streamsize xsputn(const char_type* s, streamsize n)
357 {
358 if (!s || n == 0)
359 return 0;
360
361 streamsize i{0};
362 for (; i <= n; ++i)
363 {
364 if (!write_avail_() && traits_type::eq_int_type(overflow(), traits_type::eof()))
365 break;
366
367 *output_next_++ = *s++;
368 }
369
370 return i;
371 }
372
373 virtual int_type overflow(int_type c = traits_type::eof())
374 {
375 return traits_type::eof();
376 }
377
378 protected:
379 char_type* input_begin_;
380 char_type* input_next_;
381 char_type* input_end_;
382
383 char_type* output_begin_;
384 char_type* output_next_;
385 char_type* output_end_;
386
387 locale locale_;
388
389 bool write_avail_() const
390 {
391 return output_next_ && output_next_ < output_end_;
392 }
393
394 bool putback_avail_() const
395 {
396 return input_next_ && input_begin_ < input_next_;
397 }
398
399 bool read_avail_() const
400 {
401 return input_next_ && input_next_ < input_end_;
402 }
403 };
404
405 using streambuf = basic_streambuf<char>;
406 using wstreambuf = basic_streambuf<wchar_t>;
407}
408
409#endif
Note: See TracBrowser for help on using the repository browser.