Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/nowide/iostream.cpp')
-rw-r--r--src/boost/nowide/iostream.cpp261
1 files changed, 261 insertions, 0 deletions
diff --git a/src/boost/nowide/iostream.cpp b/src/boost/nowide/iostream.cpp
new file mode 100644
index 000000000..6b9099110
--- /dev/null
+++ b/src/boost/nowide/iostream.cpp
@@ -0,0 +1,261 @@
+//
+// Copyright (c) 2012 Artyom Beilis (Tonkikh)
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+#define BOOST_NOWIDE_SOURCE
+#include <boost/nowide/iostream.hpp>
+#include <boost/nowide/convert.hpp>
+#include <stdio.h>
+#include <vector>
+
+#ifdef BOOST_WINDOWS
+
+#ifndef NOMINMAX
+# define NOMINMAX
+#endif
+
+
+#include <windows.h>
+
+namespace boost {
+namespace nowide {
+namespace details {
+ class console_output_buffer : public std::streambuf {
+ public:
+ console_output_buffer(HANDLE h) :
+ handle_(h),
+ isatty_(false)
+ {
+ if(handle_) {
+ DWORD dummy;
+ isatty_ = GetConsoleMode(handle_,&dummy) == TRUE;
+ }
+ }
+ protected:
+ int sync()
+ {
+ return overflow(EOF);
+ }
+ int overflow(int c)
+ {
+ if(!handle_)
+ return -1;
+ int n = pptr() - pbase();
+ int r = 0;
+
+ if(n > 0 && (r=write(pbase(),n)) < 0)
+ return -1;
+ if(r < n) {
+ memmove(pbase(),pbase() + r,n-r);
+ }
+ setp(buffer_, buffer_ + buffer_size);
+ pbump(n-r);
+ if(c!=EOF)
+ sputc(c);
+ return 0;
+ }
+ private:
+
+ int write(char const *p,int n)
+ {
+ namespace uf = boost::locale::utf;
+ char const *b = p;
+ char const *e = p+n;
+ DWORD size=0;
+ if(!isatty_) {
+ if(!WriteFile(handle_,p,n,&size,0) || static_cast<int>(size) != n)
+ return -1;
+ return n;
+ }
+ if(n > buffer_size)
+ return -1;
+ wchar_t *out = wbuffer_;
+ uf::code_point c;
+ size_t decoded = 0;
+ while(p < e && (c = uf::utf_traits<char>::decode(p,e))!=uf::illegal && c!=uf::incomplete) {
+ out = uf::utf_traits<wchar_t>::encode(c,out);
+ decoded = p-b;
+ }
+ if(c==uf::illegal)
+ return -1;
+ if(!WriteConsoleW(handle_,wbuffer_,out - wbuffer_,&size,0))
+ return -1;
+ return decoded;
+ }
+
+ static const int buffer_size = 1024;
+ char buffer_[buffer_size];
+ wchar_t wbuffer_[buffer_size]; // for null
+ HANDLE handle_;
+ bool isatty_;
+ };
+
+ class console_input_buffer: public std::streambuf {
+ public:
+ console_input_buffer(HANDLE h) :
+ handle_(h),
+ isatty_(false),
+ wsize_(0)
+ {
+ if(handle_) {
+ DWORD dummy;
+ isatty_ = GetConsoleMode(handle_,&dummy) == TRUE;
+ }
+ }
+
+ protected:
+ int pbackfail(int c)
+ {
+ if(c==EOF)
+ return EOF;
+
+ if(gptr()!=eback()) {
+ gbump(-1);
+ *gptr() = c;
+ return 0;
+ }
+
+ if(pback_buffer_.empty()) {
+ pback_buffer_.resize(4);
+ char *b = &pback_buffer_[0];
+ char *e = b + pback_buffer_.size();
+ setg(b,e-1,e);
+ *gptr() = c;
+ }
+ else {
+ size_t n = pback_buffer_.size();
+ std::vector<char> tmp;
+ tmp.resize(n*2);
+ memcpy(&tmp[n],&pback_buffer_[0],n);
+ tmp.swap(pback_buffer_);
+ char *b = &pback_buffer_[0];
+ char *e = b + n * 2;
+ char *p = b+n-1;
+ *p = c;
+ setg(b,p,e);
+ }
+
+ return 0;
+ }
+
+ int underflow()
+ {
+ if(!handle_)
+ return -1;
+ if(!pback_buffer_.empty())
+ pback_buffer_.clear();
+
+ size_t n = read();
+ setg(buffer_,buffer_,buffer_+n);
+ if(n == 0)
+ return EOF;
+ return std::char_traits<char>::to_int_type(*gptr());
+ }
+
+ private:
+
+ size_t read()
+ {
+ namespace uf = boost::locale::utf;
+ if(!isatty_) {
+ DWORD read_bytes = 0;
+ if(!ReadFile(handle_,buffer_,buffer_size,&read_bytes,0))
+ return 0;
+ return read_bytes;
+ }
+ DWORD read_wchars = 0;
+ size_t n = wbuffer_size - wsize_;
+ if(!ReadConsoleW(handle_,wbuffer_,n,&read_wchars,0))
+ return 0;
+ wsize_ += read_wchars;
+ char *out = buffer_;
+ wchar_t *b = wbuffer_;
+ wchar_t *e = b + wsize_;
+ wchar_t *p = b;
+ uf::code_point c;
+ wsize_ = e-p;
+ while(p < e && (c = uf::utf_traits<wchar_t>::decode(p,e))!=uf::illegal && c!=uf::incomplete) {
+ out = uf::utf_traits<char>::encode(c,out);
+ wsize_ = e-p;
+ }
+
+ if(c==uf::illegal)
+ return -1;
+
+
+ if(c==uf::incomplete) {
+ memmove(b,e-wsize_,sizeof(wchar_t)*wsize_);
+ }
+
+ return out - buffer_;
+ }
+
+ static const size_t buffer_size = 1024 * 3;
+ static const size_t wbuffer_size = 1024;
+ char buffer_[buffer_size];
+ wchar_t wbuffer_[buffer_size]; // for null
+ HANDLE handle_;
+ bool isatty_;
+ int wsize_;
+ std::vector<char> pback_buffer_;
+ };
+
+ winconsole_ostream::winconsole_ostream(int fd) : std::ostream(0)
+ {
+ HANDLE h = 0;
+ switch(fd) {
+ case 1:
+ h = GetStdHandle(STD_OUTPUT_HANDLE);
+ break;
+ case 2:
+ h = GetStdHandle(STD_ERROR_HANDLE);
+ break;
+ }
+ d.reset(new console_output_buffer(h));
+ std::ostream::rdbuf(d.get());
+ }
+
+ winconsole_ostream::~winconsole_ostream()
+ {
+ }
+
+ winconsole_istream::winconsole_istream() : std::istream(0)
+ {
+ HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
+ d.reset(new console_input_buffer(h));
+ std::istream::rdbuf(d.get());
+ }
+
+ winconsole_istream::~winconsole_istream()
+ {
+ }
+
+} // details
+
+BOOST_NOWIDE_DECL details::winconsole_istream cin;
+BOOST_NOWIDE_DECL details::winconsole_ostream cout(1);
+BOOST_NOWIDE_DECL details::winconsole_ostream cerr(2);
+BOOST_NOWIDE_DECL details::winconsole_ostream clog(2);
+
+namespace {
+ struct initialize {
+ initialize()
+ {
+ boost::nowide::cin.tie(&boost::nowide::cout);
+ boost::nowide::cerr.tie(&boost::nowide::cout);
+ boost::nowide::clog.tie(&boost::nowide::cout);
+ }
+ } inst;
+}
+
+
+
+} // nowide
+} // namespace boost
+
+#endif
+///
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4