-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Term::cout Term::clog Term::cin Term::clog
- Loading branch information
Showing
41 changed files
with
870 additions
and
446 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
#include "cpp-terminal/buffer.hpp" | ||
|
||
#include "cpp-terminal/options.hpp" | ||
#include "cpp-terminal/platforms/file.hpp" | ||
#include "cpp-terminal/terminal.hpp" | ||
|
||
static std::string remplace(const Term::Buffer::int_type& c) | ||
{ | ||
#if defined(_WIN32) | ||
std::string ret; | ||
if(static_cast<char>(c) == '\n') ret = "\r\n"; | ||
else | ||
ret.push_back(static_cast<char>(c)); | ||
return ret; | ||
#else | ||
std::string ret; | ||
ret.push_back(static_cast<char>(c)); | ||
return ret; | ||
#endif | ||
} | ||
|
||
static bool newline_sequence(const std::string& str) //https://en.wikipedia.org/wiki/Newline | ||
{ | ||
if(str.back() == '\n' || str.back() == '\r' || str.back() == '\036' || str.back() == '\036' || str.back() == '\025') return true; | ||
else | ||
return false; | ||
} | ||
|
||
int Term::Buffer::sync() | ||
{ | ||
int ret = Term::Private::out.write(m_buffer); | ||
m_buffer.clear(); | ||
return ret; | ||
} | ||
|
||
Term::Buffer::Buffer(const Term::Buffer::Type& type, const std::streamsize& size) | ||
{ | ||
setType(type); | ||
switch(m_type) | ||
{ | ||
case Type::Unbuffered: setbuf(nullptr, 0); break; | ||
case Type::LineBuffered: | ||
case Type::FullBuffered: setbuf(&m_buffer[0], size); break; | ||
} | ||
} | ||
|
||
void Term::Buffer::setType(const Term::Buffer::Type& type) { m_type = type; } | ||
|
||
std::streambuf* Term::Buffer::setbuf(char* s, std::streamsize n) | ||
{ | ||
if(s != nullptr) m_buffer.reserve(n); | ||
return this; | ||
} | ||
|
||
Term::Buffer::int_type Term::Buffer::underflow() | ||
{ | ||
try | ||
{ | ||
//TODO Maybe use input function ? | ||
m_buffer.clear(); | ||
if(terminal.getOptions().has(Option::Raw)) | ||
{ | ||
do { | ||
std::string ret{Term::Private::in.read()}; | ||
if(!ret.empty()) | ||
{ | ||
if(ret[0] == '\x7f' || ret[0] == '\b') | ||
{ | ||
Term::Private::out.write("\b \b"); //Backspace is DEL, CTRL+Backspace is Backspace '\b' | ||
if(!m_buffer.empty()) m_buffer.erase(m_buffer.size() - 1); | ||
} | ||
else if(ret[0] == '\033') | ||
{ | ||
continue; // For now if it's escape sequence do nothing | ||
} | ||
else if(ret[0] <= 31 && ret[0] != '\t' && ret[0] != '\b' && ret[0] != 127 && ret[0] != ' ' && ret[0] != '\n' && ret[0] != '\r') { continue; } | ||
else | ||
{ | ||
Term::Private::out.write(ret); | ||
m_buffer += ret; | ||
} | ||
} | ||
} while(m_buffer.empty() || !newline_sequence(m_buffer)); | ||
Term::Private::out.write('\n'); | ||
} | ||
else | ||
{ | ||
do { | ||
std::string ret{Term::Private::in.read()}; | ||
m_buffer += ret; | ||
} while(m_buffer.empty()); | ||
} | ||
setg(&m_buffer[0], &m_buffer[0], &m_buffer[0] + m_buffer.size()); | ||
return traits_type::to_int_type(m_buffer.at(0)); | ||
} | ||
catch(...) | ||
{ | ||
return traits_type::eof(); | ||
} | ||
} | ||
|
||
Term::Buffer::int_type Term::Buffer::overflow(int c) | ||
{ | ||
if(c != std::char_traits<Term::Buffer::char_type>::eof()) | ||
{ | ||
switch(m_type) | ||
{ | ||
case Type::Unbuffered: | ||
{ | ||
Term::Private::out.write(remplace(c)); | ||
break; | ||
} | ||
case Type::LineBuffered: | ||
{ | ||
m_buffer += remplace(c); | ||
if(static_cast<char>(c) == '\n') | ||
{ | ||
Term::Private::out.write(m_buffer); | ||
m_buffer.clear(); | ||
} | ||
break; | ||
} | ||
case Type::FullBuffered: | ||
{ | ||
if(m_buffer.size() >= m_buffer.capacity()) | ||
{ | ||
Term::Private::out.write(m_buffer); | ||
m_buffer.clear(); | ||
} | ||
m_buffer += remplace(c); | ||
break; | ||
} | ||
} | ||
} | ||
return c; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#pragma once | ||
|
||
#include <cstddef> | ||
#include <cstdint> | ||
#include <streambuf> | ||
|
||
namespace Term | ||
{ | ||
|
||
class Buffer : public std::streambuf | ||
{ | ||
public: | ||
enum class Type : std::uint8_t | ||
{ | ||
Unbuffered, | ||
LineBuffered, | ||
FullBuffered, | ||
}; | ||
explicit Buffer(const Term::Buffer::Type& type = Term::Buffer::Type::LineBuffered, const std::streamsize& size = BUFSIZ); | ||
virtual ~Buffer() = default; | ||
|
||
protected: | ||
virtual Term::Buffer::int_type underflow() final; | ||
virtual Term::Buffer::int_type overflow(int c = std::char_traits<Term::Buffer::char_type>::eof()); | ||
virtual int sync() final; | ||
|
||
private: | ||
void setType(const Term::Buffer::Type& type); | ||
std::streambuf* setbuf(char* s, std::streamsize n) final; | ||
std::string m_buffer; | ||
Term::Buffer::Type m_type{Term::Buffer::Type::LineBuffered}; | ||
}; | ||
|
||
} // namespace Term |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
#include "cpp-terminal/iostream.hpp" | ||
|
||
#include <iostream> | ||
#include <new> | ||
|
||
namespace Term | ||
{ | ||
// Output | ||
static char coutBuf[sizeof(Term::TOstream)]; | ||
TOstream& cout = reinterpret_cast<Term::TOstream&>(coutBuf); | ||
static char cerrBuf[sizeof(Term::TOstream)]; | ||
TOstream& cerr = reinterpret_cast<Term::TOstream&>(cerrBuf); | ||
static char clogBuf[sizeof(Term::TOstream)]; | ||
TOstream& clog = reinterpret_cast<Term::TOstream&>(clogBuf); | ||
// Input | ||
static char cinBuf[sizeof(Term::TIstream)]; | ||
TIstream& cin = reinterpret_cast<Term::TIstream&>(cinBuf); | ||
} // namespace Term */ | ||
|
||
int Term::StreamInitializer::m_counter{0}; | ||
|
||
void Term::StreamInitializer::init() | ||
{ | ||
if(m_counter++ == 0) | ||
{ | ||
std::ios_base::Init(); | ||
new(&Term::cout) TOstream(Term::Buffer::Type::FullBuffered, BUFSIZ); | ||
new(&Term::clog) TOstream(Term::Buffer::Type::LineBuffered, BUFSIZ); | ||
new(&Term::cerr) TOstream(Term::Buffer::Type::Unbuffered, 0); | ||
new(&Term::cin) TIstream(Term::Buffer::Type::FullBuffered, BUFSIZ); | ||
std::cin.rdbuf(Term::cin.rdbuf()); | ||
} | ||
} | ||
|
||
Term::StreamInitializer::StreamInitializer() { init(); } | ||
|
||
Term::StreamInitializer::~StreamInitializer() | ||
{ | ||
if(--m_counter == 0) | ||
{ | ||
(&Term::cout)->~TOstream(); | ||
(&Term::cerr)->~TOstream(); | ||
(&Term::clog)->~TOstream(); | ||
(&Term::cin)->~TIstream(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#pragma once | ||
|
||
#include "cpp-terminal/stream.hpp" | ||
|
||
namespace Term | ||
{ | ||
|
||
extern TIstream& cin; | ||
extern TOstream& cout; | ||
extern TOstream& cerr; | ||
extern TOstream& clog; | ||
|
||
class StreamInitializer | ||
{ | ||
public: | ||
StreamInitializer(); | ||
static void init(); | ||
~StreamInitializer(); | ||
StreamInitializer(const StreamInitializer&) = delete; | ||
StreamInitializer& operator=(const StreamInitializer&) = delete; | ||
StreamInitializer(StreamInitializer&&) = delete; | ||
StreamInitializer& operator=(StreamInitializer&&) = delete; | ||
|
||
private: | ||
static int m_counter; | ||
}; | ||
|
||
static StreamInitializer m_streams; | ||
|
||
} // namespace Term |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.