cpp-terminal 1.0.0
Small C++ library for writing multiplatform terminal applications
Loading...
Searching...
No Matches
buffer.cpp
Go to the documentation of this file.
1/*
2* cpp-terminal
3* C++ library for writing multi-platform terminal applications.
4*
5* SPDX-FileCopyrightText: 2019-2024 cpp-terminal
6*
7* SPDX-License-Identifier: MIT
8*/
9
11
15
16#include <cstddef>
17
18static std::string replace(const Term::Buffer::int_type& c)
19{
20#if defined(_WIN32)
21 std::string ret;
22 if(static_cast<char>(c) == '\n') ret = "\r\n";
23 else
24 ret.push_back(static_cast<char>(c));
25 return ret;
26#else
27 std::string ret;
28 ret.push_back(static_cast<char>(c));
29 return ret;
30#endif
31}
32
33static bool newline_sequence(const std::string& str) //https://en.wikipedia.org/wiki/Newline
34{
35 if(str.back() == '\n' || str.back() == '\r' || str.back() == '\036' || str.back() == '\036' || str.back() == '\025') return true;
36 else
37 return false;
38}
39
41{
42 const int ret = Term::Private::out.write(m_buffer);
43 m_buffer.clear();
44 return ret;
45}
46
47Term::Buffer::Buffer(const Term::Buffer::Type& type, const std::streamsize& size)
48{
49 setType(type);
50 switch(m_type)
51 {
52 case Type::Unbuffered: setbuf(nullptr, 0); break;
53 case Type::LineBuffered:
54 case Type::FullBuffered: setbuf(&m_buffer[0], size); break;
55 }
56}
57
58void Term::Buffer::setType(const Term::Buffer::Type& type) { m_type = type; }
59
60std::streambuf* Term::Buffer::setbuf(char* s, std::streamsize n)
61{
62 if(s != nullptr) m_buffer.reserve(static_cast<std::size_t>(n));
63 return this;
64}
65
66Term::Buffer::int_type Term::Buffer::underflow()
67{
68 try
69 {
70 //TODO Maybe use input function ?
71 m_buffer.clear();
73 {
74 do {
75 std::string ret{Term::Private::in.read()};
76 if(!ret.empty())
77 {
78 if(ret[0] == '\x7f' || ret[0] == '\b')
79 {
80 Term::Private::out.write("\b \b"); //Backspace is DEL, CTRL+Backspace is Backspace '\b'
81 if(!m_buffer.empty()) m_buffer.erase(m_buffer.size() - 1);
82 }
83 else if(ret[0] == '\033')
84 {
85 continue; // For now if it's escape sequence do nothing
86 }
87 else if(ret[0] <= 31 && ret[0] != '\t' && ret[0] != '\b' && ret[0] != 127 && ret[0] != ' ' && ret[0] != '\n' && ret[0] != '\r') { continue; }
88 else
89 {
91 m_buffer += ret;
92 }
93 }
94 } while(m_buffer.empty() || !newline_sequence(m_buffer));
96 }
97 else
98 {
99 do {
100 std::string ret{Term::Private::in.read()};
101 m_buffer += ret;
102 } while(m_buffer.empty());
103 }
104 setg(&m_buffer[0], &m_buffer[0], &m_buffer[0] + m_buffer.size());
105 return traits_type::to_int_type(m_buffer.at(0));
106 }
107 catch(...)
108 {
109 return traits_type::eof();
110 }
111}
112
113Term::Buffer::int_type Term::Buffer::overflow(int c)
114{
115 if(c != std::char_traits<Term::Buffer::char_type>::eof())
116 {
117 switch(m_type)
118 {
119 case Type::Unbuffered:
120 {
121 Term::Private::out.write(replace(c));
122 break;
123 }
124 case Type::LineBuffered:
125 {
126 m_buffer += replace(c);
127 if(static_cast<char>(c) == '\n')
128 {
129 Term::Private::out.write(m_buffer);
130 m_buffer.clear();
131 }
132 break;
133 }
134 case Type::FullBuffered:
135 {
136 if(m_buffer.size() >= m_buffer.capacity())
137 {
138 Term::Private::out.write(m_buffer);
139 m_buffer.clear();
140 }
141 m_buffer += replace(c);
142 break;
143 }
144 }
145 }
146 return c;
147}
148
150{
151 //sync();
152}
~Buffer() override
Definition buffer.cpp:149
int sync() override
Definition buffer.cpp:40
void setType(const Term::Buffer::Type &type)
Definition buffer.cpp:58
int_type underflow() override
Definition buffer.cpp:66
std::string m_buffer
Definition buffer.hpp:43
std::streambuf * setbuf(char *s, std::streamsize n) override
Definition buffer.cpp:60
Buffer(const Term::Buffer::Type &type=Term::Buffer::Type::LineBuffered, const std::streamsize &size=BUFSIZ)
Definition buffer.cpp:47
int_type overflow(int c=std::char_traits< Term::Buffer::char_type >::eof()) override
Definition buffer.cpp:113
bool has(const Option &option) const noexcept
Definition options.cpp:35
std::string read() const
Definition file.cpp:127
std::size_t write(const std::string &str) const
Definition file.cpp:101
Term::Options getOptions() const noexcept
InputFileHandler & in
Definition file.cpp:43
OutputFileHandler & out
Definition file.cpp:44
@ Raw
Set terminal in raw mode.
Term::Terminal & terminal
Definition terminal.cpp:19