source: mainline/uspace/lib/cpp/include/__bits/io/streambufs.hpp@ c6f23a7

Last change on this file since c6f23a7 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: 4.1 KB
Line 
1/*
2 * SPDX-FileCopyrightText: 2018 Jaroslav Jindrak
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef LIBCPP_BITS_IO_STREAMBUFS
8#define LIBCPP_BITS_IO_STREAMBUFS
9
10#include <iosfwd>
11#include <cstdio>
12#include <streambuf>
13
14namespace std::aux
15{
16 template<class Char, class Traits = char_traits<Char>>
17 class stdin_streambuf : public basic_streambuf<Char, Traits>
18 {
19 public:
20 stdin_streambuf()
21 : basic_streambuf<Char, Traits>{}, buffer_{nullptr}
22 { /* DUMMY BODY */ }
23
24 virtual ~stdin_streambuf()
25 {
26 if (buffer_)
27 delete[] buffer_;
28 }
29
30 protected:
31 using traits_type = Traits;
32 using char_type = typename traits_type::char_type;
33 using int_type = typename traits_type::int_type;
34 using off_type = typename traits_type::off_type;
35
36 using basic_streambuf<Char, Traits>::input_begin_;
37 using basic_streambuf<Char, Traits>::input_next_;
38 using basic_streambuf<Char, Traits>::input_end_;
39
40 int_type underflow() override
41 {
42 if (!this->gptr())
43 {
44 buffer_ = new char_type[buf_size_];
45 input_begin_ = input_next_ = input_end_ = buffer_;
46 }
47
48 off_type i{};
49 if (input_next_ < input_end_)
50 {
51 auto idx = static_cast<off_type>(input_next_ - input_begin_);
52 auto count = buf_size_ - idx;
53
54 for (; i < count; ++i, ++idx)
55 buffer_[i] = buffer_[idx];
56 }
57
58 for (; i < buf_size_; ++i)
59 {
60 auto c = fgetc(in_);
61 putchar(c); // TODO: Temporary source of feedback.
62 if (c == traits_type::eof())
63 break;
64
65 buffer_[i] = static_cast<char_type>(c);
66
67 if (buffer_[i] == '\n')
68 {
69 ++i;
70 break;
71 }
72 }
73
74 input_next_ = input_begin_;
75 input_end_ = input_begin_ + i;
76
77 if (i == 0)
78 return traits_type::eof();
79
80 return traits_type::to_int_type(*input_next_);
81 }
82
83 int_type uflow() override
84 {
85 auto res = underflow();
86 ++input_next_;
87
88 return res;
89 }
90
91 void imbue(const locale& loc)
92 {
93 this->locale_ = loc;
94 }
95
96 private:
97 FILE* in_{stdin};
98
99 char_type* buffer_;
100
101 static constexpr off_type buf_size_{128};
102 };
103
104 template<class Char, class Traits = char_traits<Char>>
105 class stdout_streambuf: public basic_streambuf<Char, Traits>
106 {
107 public:
108 stdout_streambuf()
109 : basic_streambuf<Char, Traits>{}
110 { /* DUMMY BODY */ }
111
112 virtual ~stdout_streambuf()
113 { /* DUMMY BODY */ }
114
115 protected:
116 using traits_type = Traits;
117 using char_type = typename traits_type::char_type;
118 using int_type = typename traits_type::int_type;
119 using off_type = typename traits_type::off_type;
120
121 int_type overflow(int_type c = traits_type::eof()) override
122 {
123 if (!traits_type::eq_int_type(c, traits_type::eof()))
124 {
125 auto cc = traits_type::to_char_type(c);
126 fwrite(&cc, sizeof(char_type), 1, out_);
127 }
128
129 return traits_type::not_eof(c);
130 }
131
132 streamsize xsputn(const char_type* s, streamsize n) override
133 {
134 return fwrite(s, sizeof(char_type), n, out_);
135 }
136
137 int sync() override
138 {
139 if (fflush(out_))
140 return -1;
141 return 0;
142 }
143
144 private:
145 FILE* out_{stdout};
146 };
147}
148
149#endif
Note: See TracBrowser for help on using the repository browser.