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
path: root/src/boost
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost')
-rw-r--r--src/boost/CMakeLists.txt20
-rw-r--r--src/boost/nowide/args.hpp167
-rw-r--r--src/boost/nowide/cenv.hpp124
-rw-r--r--src/boost/nowide/config.hpp54
-rw-r--r--src/boost/nowide/convert.hpp154
-rw-r--r--src/boost/nowide/cstdio.hpp101
-rw-r--r--src/boost/nowide/cstdlib.hpp16
-rw-r--r--src/boost/nowide/filebuf.hpp415
-rw-r--r--src/boost/nowide/fstream.hpp283
-rw-r--r--src/boost/nowide/integration/filesystem.hpp28
-rw-r--r--src/boost/nowide/iostream.cpp261
-rw-r--r--src/boost/nowide/iostream.hpp99
-rw-r--r--src/boost/nowide/stackstring.hpp154
-rw-r--r--src/boost/nowide/system.hpp46
-rw-r--r--src/boost/nowide/utf8_codecvt.hpp499
-rw-r--r--src/boost/nowide/windows.hpp39
16 files changed, 2460 insertions, 0 deletions
diff --git a/src/boost/CMakeLists.txt b/src/boost/CMakeLists.txt
new file mode 100644
index 000000000..2b23ec3b2
--- /dev/null
+++ b/src/boost/CMakeLists.txt
@@ -0,0 +1,20 @@
+project(nowide)
+cmake_minimum_required(VERSION 2.6)
+
+add_library(nowide STATIC
+ nowide/args.hpp
+ nowide/cenv.hpp
+ nowide/config.hpp
+ nowide/convert.hpp
+ nowide/cstdio.hpp
+ nowide/cstdlib.hpp
+ nowide/filebuf.hpp
+ nowide/fstream.hpp
+ nowide/integration/filesystem.hpp
+ nowide/iostream.cpp
+ nowide/iostream.hpp
+ nowide/stackstring.hpp
+ nowide/system.hpp
+ nowide/utf8_codecvt.hpp
+ nowide/windows.hpp
+)
diff --git a/src/boost/nowide/args.hpp b/src/boost/nowide/args.hpp
new file mode 100644
index 000000000..bb806d02e
--- /dev/null
+++ b/src/boost/nowide/args.hpp
@@ -0,0 +1,167 @@
+//
+// 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)
+//
+#ifndef BOOST_NOWIDE_ARGS_HPP_INCLUDED
+#define BOOST_NOWIDE_ARGS_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/nowide/stackstring.hpp>
+#include <vector>
+#ifdef BOOST_WINDOWS
+#include <boost/nowide/windows.hpp>
+#endif
+
+namespace boost {
+namespace nowide {
+ #if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN)
+ class args {
+ public:
+ args(int &,char **&) {}
+ args(int &,char **&,char **&){}
+ ~args() {}
+ };
+
+ #else
+
+ ///
+ /// \brief args is a class that fixes standard main() function arguments and changes them to UTF-8 under
+ /// Microsoft Windows.
+ ///
+ /// The class uses \c GetCommandLineW(), \c CommandLineToArgvW() and \c GetEnvironmentStringsW()
+ /// in order to obtain the information. It does not relates to actual values of argc,argv and env
+ /// under Windows.
+ ///
+ /// It restores the original values in its destructor
+ ///
+ /// \note the class owns the memory of the newly allocated strings
+ ///
+ class args {
+ public:
+
+ ///
+ /// Fix command line agruments
+ ///
+ args(int &argc,char **&argv) :
+ old_argc_(argc),
+ old_argv_(argv),
+ old_env_(0),
+ old_argc_ptr_(&argc),
+ old_argv_ptr_(&argv),
+ old_env_ptr_(0)
+ {
+ fix_args(argc,argv);
+ }
+ ///
+ /// Fix command line agruments and environment
+ ///
+ args(int &argc,char **&argv,char **&en) :
+ old_argc_(argc),
+ old_argv_(argv),
+ old_env_(en),
+ old_argc_ptr_(&argc),
+ old_argv_ptr_(&argv),
+ old_env_ptr_(&en)
+ {
+ fix_args(argc,argv);
+ fix_env(en);
+ }
+ ///
+ /// Restore original argc,argv,env values, if changed
+ ///
+ ~args()
+ {
+ if(old_argc_ptr_)
+ *old_argc_ptr_ = old_argc_;
+ if(old_argv_ptr_)
+ *old_argv_ptr_ = old_argv_;
+ if(old_env_ptr_)
+ *old_env_ptr_ = old_env_;
+ }
+ private:
+ void fix_args(int &argc,char **&argv)
+ {
+ int wargc;
+ wchar_t **wargv = CommandLineToArgvW(GetCommandLineW(),&wargc);
+ if(!wargv) {
+ argc = 0;
+ static char *dummy = 0;
+ argv = &dummy;
+ return;
+ }
+ try{
+ args_.resize(wargc+1,0);
+ arg_values_.resize(wargc);
+ for(int i=0;i<wargc;i++) {
+ if(!arg_values_[i].convert(wargv[i])) {
+ wargc = i;
+ break;
+ }
+ args_[i] = arg_values_[i].c_str();
+ }
+ argc = wargc;
+ argv = &args_[0];
+ }
+ catch(...) {
+ LocalFree(wargv);
+ throw;
+ }
+ LocalFree(wargv);
+ }
+ void fix_env(char **&en)
+ {
+ static char *dummy = 0;
+ en = &dummy;
+ wchar_t *wstrings = GetEnvironmentStringsW();
+ if(!wstrings)
+ return;
+ try {
+ wchar_t *wstrings_end = 0;
+ int count = 0;
+ for(wstrings_end = wstrings;*wstrings_end;wstrings_end+=wcslen(wstrings_end)+1)
+ count++;
+ if(env_.convert(wstrings,wstrings_end)) {
+ envp_.resize(count+1,0);
+ char *p=env_.c_str();
+ int pos = 0;
+ for(int i=0;i<count;i++) {
+ if(*p!='=')
+ envp_[pos++] = p;
+ p+=strlen(p)+1;
+ }
+ en = &envp_[0];
+ }
+ }
+ catch(...) {
+ FreeEnvironmentStringsW(wstrings);
+ throw;
+ }
+ FreeEnvironmentStringsW(wstrings);
+
+ }
+
+ std::vector<char *> args_;
+ std::vector<short_stackstring> arg_values_;
+ stackstring env_;
+ std::vector<char *> envp_;
+
+ int old_argc_;
+ char **old_argv_;
+ char **old_env_;
+
+ int *old_argc_ptr_;
+ char ***old_argv_ptr_;
+ char ***old_env_ptr_;
+ };
+
+ #endif
+
+} // nowide
+} // namespace boost
+#endif
+
+///
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/nowide/cenv.hpp b/src/boost/nowide/cenv.hpp
new file mode 100644
index 000000000..a38a24b97
--- /dev/null
+++ b/src/boost/nowide/cenv.hpp
@@ -0,0 +1,124 @@
+//
+// 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)
+//
+#ifndef BOOST_NOWIDE_CENV_H_INCLUDED
+#define BOOST_NOWIDE_CENV_H_INCLUDED
+
+#include <string>
+#include <stdexcept>
+#include <stdlib.h>
+#include <boost/config.hpp>
+#include <boost/nowide/stackstring.hpp>
+#include <vector>
+
+#ifdef BOOST_WINDOWS
+#include <boost/nowide/windows.hpp>
+#endif
+
+namespace boost {
+namespace nowide {
+ #if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN)
+ using ::getenv;
+ using ::setenv;
+ using ::unsetenv;
+ using ::putenv;
+ #else
+ ///
+ /// \brief UTF-8 aware getenv. Returns 0 if the variable is not set.
+ ///
+ /// This function is not thread safe or reenterable as defined by the standard library
+ ///
+ inline char *getenv(char const *key)
+ {
+ static stackstring value;
+
+ wshort_stackstring name;
+ if(!name.convert(key))
+ return 0;
+
+ static const size_t buf_size = 64;
+ wchar_t buf[buf_size];
+ std::vector<wchar_t> tmp;
+ wchar_t *ptr = buf;
+ size_t n = GetEnvironmentVariableW(name.c_str(),buf,buf_size);
+ if(n == 0 && GetLastError() == 203) // ERROR_ENVVAR_NOT_FOUND
+ return 0;
+ if(n >= buf_size) {
+ tmp.resize(n+1,L'\0');
+ n = GetEnvironmentVariableW(name.c_str(),&tmp[0],static_cast<unsigned>(tmp.size() - 1));
+ // The size may have changed
+ if(n >= tmp.size() - 1)
+ return 0;
+ ptr = &tmp[0];
+ }
+ if(!value.convert(ptr))
+ return 0;
+ return value.c_str();
+ }
+ ///
+ /// \brief UTF-8 aware setenv, \a key - the variable name, \a value is a new UTF-8 value,
+ ///
+ /// if override is not 0, that the old value is always overridded, otherwise,
+ /// if the variable exists it remains unchanged
+ ///
+ inline int setenv(char const *key,char const *value,int override)
+ {
+ wshort_stackstring name;
+ if(!name.convert(key))
+ return -1;
+ if(!override) {
+ wchar_t unused[2];
+ if(!(GetEnvironmentVariableW(name.c_str(),unused,2)==0 && GetLastError() == 203)) // ERROR_ENVVAR_NOT_FOUND
+ return 0;
+ }
+ wstackstring wval;
+ if(!wval.convert(value))
+ return -1;
+ if(SetEnvironmentVariableW(name.c_str(),wval.c_str()))
+ return 0;
+ return -1;
+ }
+ ///
+ /// \brief Remove enviroment variable \a key
+ ///
+ inline int unsetenv(char const *key)
+ {
+ wshort_stackstring name;
+ if(!name.convert(key))
+ return -1;
+ if(SetEnvironmentVariableW(name.c_str(),0))
+ return 0;
+ return -1;
+ }
+ ///
+ /// \brief UTF-8 aware putenv implementation, expects string in format KEY=VALUE
+ ///
+ inline int putenv(char *string)
+ {
+ char const *key = string;
+ char const *key_end = string;
+ while(*key_end != '=' && *key_end != 0)
+ ++ key_end;
+ if(*key_end == 0)
+ return -1;
+ wshort_stackstring wkey;
+ if(!wkey.convert(key,key_end))
+ return -1;
+ wstackstring wvalue;
+ if(!wvalue.convert(key_end+1))
+ return -1;
+ if(SetEnvironmentVariableW(wkey.c_str(),wvalue.c_str()))
+ return 0;
+ return -1;
+ }
+ #endif
+} // nowide
+} // namespace boost
+
+#endif
+///
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/nowide/config.hpp b/src/boost/nowide/config.hpp
new file mode 100644
index 000000000..d983109f3
--- /dev/null
+++ b/src/boost/nowide/config.hpp
@@ -0,0 +1,54 @@
+//
+// 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)
+//
+#ifndef BOOST_NOWIDE_CONFIG_HPP_INCLUDED
+#define BOOST_NOWIDE_CONFIG_HPP_INCLUDED
+
+#include <boost/config.hpp>
+
+#ifndef BOOST_SYMBOL_VISIBLE
+# define BOOST_SYMBOL_VISIBLE
+#endif
+
+#ifdef BOOST_HAS_DECLSPEC
+# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_NOWIDE_DYN_LINK)
+# ifdef BOOST_NOWIDE_SOURCE
+# define BOOST_NOWIDE_DECL BOOST_SYMBOL_EXPORT
+# else
+# define BOOST_NOWIDE_DECL BOOST_SYMBOL_IMPORT
+# endif // BOOST_NOWIDE_SOURCE
+# endif // DYN_LINK
+#endif // BOOST_HAS_DECLSPEC
+
+#ifndef BOOST_NOWIDE_DECL
+# define BOOST_NOWIDE_DECL
+#endif
+
+//
+// Automatically link to the correct build variant where possible.
+//
+#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_NOWIDE_NO_LIB) && !defined(BOOST_NOWIDE_SOURCE)
+//
+// Set the name of our library, this will get undef'ed by auto_link.hpp
+// once it's done with it:
+//
+#define BOOST_LIB_NAME boost_nowide
+//
+// If we're importing code from a dll, then tell auto_link.hpp about it:
+//
+#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_NOWIDE_DYN_LINK)
+# define BOOST_DYN_LINK
+#endif
+//
+// And include the header that does the work:
+//
+#include <boost/config/auto_link.hpp>
+#endif // auto-linking disabled
+
+
+#endif // boost/nowide/config.hpp
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 \ No newline at end of file
diff --git a/src/boost/nowide/convert.hpp b/src/boost/nowide/convert.hpp
new file mode 100644
index 000000000..89b8871d0
--- /dev/null
+++ b/src/boost/nowide/convert.hpp
@@ -0,0 +1,154 @@
+//
+// 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)
+//
+#ifndef BOOST_NOWIDE_CONVERT_H_INCLUDED
+#define BOOST_NOWIDE_CONVERT_H_INCLUDED
+
+#include <string>
+#include <boost/locale/encoding_utf.hpp>
+
+namespace boost {
+namespace nowide {
+ ///
+ /// \brief Template function that converts a buffer of UTF sequences in range [source_begin,source_end)
+ /// to the output \a buffer of size \a buffer_size.
+ ///
+ /// In case of success a NULL terminated string is returned (buffer), otherwise 0 is returned.
+ ///
+ /// If there is not enough room in the buffer or the source sequence contains invalid UTF,
+ /// 0 is returned, and the contents of the buffer are undefined.
+ ///
+ template<typename CharOut,typename CharIn>
+ CharOut *basic_convert(CharOut *buffer,size_t buffer_size,CharIn const *source_begin,CharIn const *source_end)
+ {
+ CharOut *rv = buffer;
+ if(buffer_size == 0)
+ return 0;
+ buffer_size --;
+ while(source_begin!=source_end) {
+ using namespace boost::locale::utf;
+ code_point c = utf_traits<CharIn>::template decode<CharIn const *>(source_begin,source_end);
+ if(c==illegal || c==incomplete) {
+ rv = 0;
+ break;
+ }
+ size_t width = utf_traits<CharOut>::width(c);
+ if(buffer_size < width) {
+ rv=0;
+ break;
+ }
+ buffer = utf_traits<CharOut>::template encode<CharOut *>(c,buffer);
+ buffer_size -= width;
+ }
+ *buffer++ = 0;
+ return rv;
+ }
+
+ /// \cond INTERNAL
+ namespace details {
+ //
+ // wcslen defined only in C99... So we will not use it
+ //
+ template<typename Char>
+ Char const *basic_strend(Char const *s)
+ {
+ while(*s)
+ s++;
+ return s;
+ }
+ }
+ /// \endcond
+
+ ///
+ /// Convert NULL terminated UTF source string to NULL terminated \a output string of size at
+ /// most output_size (including NULL)
+ ///
+ /// In case of success output is returned, if the input sequence is illegal,
+ /// or there is not enough room NULL is returned
+ ///
+ inline char *narrow(char *output,size_t output_size,wchar_t const *source)
+ {
+ return basic_convert(output,output_size,source,details::basic_strend(source));
+ }
+ ///
+ /// Convert UTF text in range [begin,end) to NULL terminated \a output string of size at
+ /// most output_size (including NULL)
+ ///
+ /// In case of success output is returned, if the input sequence is illegal,
+ /// or there is not enough room NULL is returned
+ ///
+ inline char *narrow(char *output,size_t output_size,wchar_t const *begin,wchar_t const *end)
+ {
+ return basic_convert(output,output_size,begin,end);
+ }
+ ///
+ /// Convert NULL terminated UTF source string to NULL terminated \a output string of size at
+ /// most output_size (including NULL)
+ ///
+ /// In case of success output is returned, if the input sequence is illegal,
+ /// or there is not enough room NULL is returned
+ ///
+ inline wchar_t *widen(wchar_t *output,size_t output_size,char const *source)
+ {
+ return basic_convert(output,output_size,source,details::basic_strend(source));
+ }
+ ///
+ /// Convert UTF text in range [begin,end) to NULL terminated \a output string of size at
+ /// most output_size (including NULL)
+ ///
+ /// In case of success output is returned, if the input sequence is illegal,
+ /// or there is not enough room NULL is returned
+ ///
+ inline wchar_t *widen(wchar_t *output,size_t output_size,char const *begin,char const *end)
+ {
+ return basic_convert(output,output_size,begin,end);
+ }
+
+
+ ///
+ /// Convert between Wide - UTF-16/32 string and UTF-8 string.
+ ///
+ /// boost::locale::conv::conversion_error is thrown in a case of a error
+ ///
+ inline std::string narrow(wchar_t const *s)
+ {
+ return boost::locale::conv::utf_to_utf<char>(s);
+ }
+ ///
+ /// Convert between UTF-8 and UTF-16 string, implemented only on Windows platform
+ ///
+ /// boost::locale::conv::conversion_error is thrown in a case of a error
+ ///
+ inline std::wstring widen(char const *s)
+ {
+ return boost::locale::conv::utf_to_utf<wchar_t>(s);
+ }
+ ///
+ /// Convert between Wide - UTF-16/32 string and UTF-8 string
+ ///
+ /// boost::locale::conv::conversion_error is thrown in a case of a error
+ ///
+ inline std::string narrow(std::wstring const &s)
+ {
+ return boost::locale::conv::utf_to_utf<char>(s);
+ }
+ ///
+ /// Convert between UTF-8 and UTF-16 string, implemented only on Windows platform
+ ///
+ /// boost::locale::conv::conversion_error is thrown in a case of a error
+ ///
+ inline std::wstring widen(std::string const &s)
+ {
+ return boost::locale::conv::utf_to_utf<wchar_t>(s);
+ }
+
+} // nowide
+} // namespace boost
+
+#endif
+///
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/nowide/cstdio.hpp b/src/boost/nowide/cstdio.hpp
new file mode 100644
index 000000000..d0bda97a0
--- /dev/null
+++ b/src/boost/nowide/cstdio.hpp
@@ -0,0 +1,101 @@
+//
+// 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)
+//
+#ifndef BOOST_NOWIDE_CSTDIO_H_INCLUDED
+#define BOOST_NOWIDE_CSTDIO_H_INCLUDED
+
+#include <cstdio>
+#include <stdio.h>
+#include <boost/config.hpp>
+#include <boost/nowide/convert.hpp>
+#include <boost/nowide/stackstring.hpp>
+#include <errno.h>
+
+#ifdef BOOST_MSVC
+# pragma warning(push)
+# pragma warning(disable : 4996)
+#endif
+
+
+namespace boost {
+namespace nowide {
+#if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN)
+ using std::fopen;
+ using std::freopen;
+ using std::remove;
+ using std::rename;
+#else
+
+///
+/// \brief Same as freopen but file_name and mode are UTF-8 strings
+///
+/// If invalid UTF-8 given, NULL is returned and errno is set to EINVAL
+///
+inline FILE *freopen(char const *file_name,char const *mode,FILE *stream)
+{
+ wstackstring wname;
+ wshort_stackstring wmode;
+ if(!wname.convert(file_name) || !wmode.convert(mode)) {
+ errno = EINVAL;
+ return 0;
+ }
+ return _wfreopen(wname.c_str(),wmode.c_str(),stream);
+}
+///
+/// \brief Same as fopen but file_name and mode are UTF-8 strings
+///
+/// If invalid UTF-8 given, NULL is returned and errno is set to EINVAL
+///
+inline FILE *fopen(char const *file_name,char const *mode)
+{
+ wstackstring wname;
+ wshort_stackstring wmode;
+ if(!wname.convert(file_name) || !wmode.convert(mode)) {
+ errno = EINVAL;
+ return 0;
+ }
+ return _wfopen(wname.c_str(),wmode.c_str());
+}
+///
+/// \brief Same as rename but old_name and new_name are UTF-8 strings
+///
+/// If invalid UTF-8 given, -1 is returned and errno is set to EINVAL
+///
+inline int rename(char const *old_name,char const *new_name)
+{
+ wstackstring wold,wnew;
+ if(!wold.convert(old_name) || !wnew.convert(new_name)) {
+ errno = EINVAL;
+ return -1;
+ }
+ return _wrename(wold.c_str(),wnew.c_str());
+}
+///
+/// \brief Same as rename but name is UTF-8 string
+///
+/// If invalid UTF-8 given, -1 is returned and errno is set to EINVAL
+///
+inline int remove(char const *name)
+{
+ wstackstring wname;
+ if(!wname.convert(name)) {
+ errno = EINVAL;
+ return -1;
+ }
+ return _wremove(wname.c_str());
+}
+#endif
+} // nowide
+} // namespace boost
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
+///
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/nowide/cstdlib.hpp b/src/boost/nowide/cstdlib.hpp
new file mode 100644
index 000000000..27e20610a
--- /dev/null
+++ b/src/boost/nowide/cstdlib.hpp
@@ -0,0 +1,16 @@
+//
+// 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)
+//
+#ifndef BOOST_NOWIDE_CSTDLIB_HPP_INCLUDED
+#define BOOST_NOWIDE_CSTDLIB_HPP_INCLUDED
+
+#include <boost/nowide/cenv.hpp>
+#include <boost/nowide/system.hpp>
+
+#endif
+///
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/nowide/filebuf.hpp b/src/boost/nowide/filebuf.hpp
new file mode 100644
index 000000000..2d6f4a443
--- /dev/null
+++ b/src/boost/nowide/filebuf.hpp
@@ -0,0 +1,415 @@
+//
+// 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)
+//
+#ifndef BOOST_NOWIDE_FILEBUF_HPP
+#define BOOST_NOWIDE_FILEBUF_HPP
+
+#include <iosfwd>
+#include <boost/config.hpp>
+#include <boost/nowide/stackstring.hpp>
+#include <fstream>
+#include <streambuf>
+#include <stdio.h>
+
+#ifdef BOOST_MSVC
+# pragma warning(push)
+# pragma warning(disable : 4996 4244 4800)
+#endif
+
+
+namespace boost {
+namespace nowide {
+#if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_FSTREAM_TESTS) && !defined(BOOST_NOWIDE_DOXYGEN)
+ using std::basic_filebuf;
+ using std::filebuf;
+#else // Windows
+
+ ///
+ /// \brief This forward declaration defined the basic_filebuf type.
+ ///
+ /// it is implemented and specialized for CharType = char, it behaves
+ /// implements std::filebuf over standard C I/O
+ ///
+ template<typename CharType,typename Traits = std::char_traits<CharType> >
+ class basic_filebuf;
+
+ ///
+ /// \brief This is implementation of std::filebuf
+ ///
+ /// it is implemented and specialized for CharType = char, it behaves
+ /// implements std::filebuf over standard C I/O
+ ///
+ template<>
+ class basic_filebuf<char> : public std::basic_streambuf<char> {
+ public:
+ ///
+ /// Creates new filebuf
+ ///
+ basic_filebuf() :
+ buffer_size_(4),
+ buffer_(0),
+ file_(0),
+ own_(true),
+ mode_(std::ios::in | std::ios::out)
+ {
+ setg(0,0,0);
+ setp(0,0);
+ }
+
+ virtual ~basic_filebuf()
+ {
+ if(file_) {
+ ::fclose(file_);
+ file_ = 0;
+ }
+ if(own_ && buffer_)
+ delete [] buffer_;
+ }
+
+ ///
+ /// Same as std::filebuf::open but s is UTF-8 string
+ ///
+ basic_filebuf *open(std::string const &s,std::ios_base::openmode mode)
+ {
+ return open(s.c_str(),mode);
+ }
+ ///
+ /// Same as std::filebuf::open but s is UTF-8 string
+ ///
+ basic_filebuf *open(char const *s,std::ios_base::openmode mode)
+ {
+ if(file_) {
+ sync();
+ ::fclose(file_);
+ file_ = 0;
+ }
+ bool ate = bool(mode & std::ios_base::ate);
+ if(ate)
+ mode = mode ^ std::ios_base::ate;
+ wchar_t const *smode = get_mode(mode);
+ if(!smode)
+ return 0;
+ wstackstring name;
+ if(!name.convert(s))
+ return 0;
+ #ifdef BOOST_NOWIDE_FSTREAM_TESTS
+ FILE *f = ::fopen(s,boost::nowide::convert(smode).c_str());
+ #else
+ FILE *f = ::_wfopen(name.c_str(),smode);
+ #endif
+ if(!f)
+ return 0;
+ if(ate && fseek(f,0,SEEK_END)!=0) {
+ fclose(f);
+ return 0;
+ }
+ file_ = f;
+ return this;
+ }
+ ///
+ /// Same as std::filebuf::close()
+ ///
+ basic_filebuf *close()
+ {
+ bool res = sync() == 0;
+ if(file_) {
+ if(::fclose(file_)!=0)
+ res = false;
+ file_ = 0;
+ }
+ return res ? this : 0;
+ }
+ ///
+ /// Same as std::filebuf::is_open()
+ ///
+ bool is_open() const
+ {
+ return file_ != 0;
+ }
+
+ private:
+ void make_buffer()
+ {
+ if(buffer_)
+ return;
+ if(buffer_size_ > 0) {
+ buffer_ = new char [buffer_size_];
+ own_ = true;
+ }
+ }
+ protected:
+
+ virtual std::streambuf *setbuf(char *s,std::streamsize n)
+ {
+ if(!buffer_ && n>=0) {
+ buffer_ = s;
+ buffer_size_ = n;
+ own_ = false;
+ }
+ return this;
+ }
+
+#ifdef BOOST_NOWIDE_DEBUG_FILEBUF
+
+ void print_buf(char *b,char *p,char *e)
+ {
+ std::cerr << "-- Is Null: " << (b==0) << std::endl;;
+ if(b==0)
+ return;
+ if(e != 0)
+ std::cerr << "-- Total: " << e - b <<" offset from start " << p - b << std::endl;
+ else
+ std::cerr << "-- Total: " << p - b << std::endl;
+
+ std::cerr << "-- [";
+ for(char *ptr = b;ptr<p;ptr++)
+ std::cerr << *ptr;
+ if(e!=0) {
+ std::cerr << "|";
+ for(char *ptr = p;ptr<e;ptr++)
+ std::cerr << *ptr;
+ }
+ std::cerr << "]" << std::endl;
+
+ }
+
+ void print_state()
+ {
+ std::cerr << "- Output:" << std::endl;
+ print_buf(pbase(),pptr(),0);
+ std::cerr << "- Input:" << std::endl;
+ print_buf(eback(),gptr(),egptr());
+ std::cerr << "- fpos: " << (file_ ? ftell(file_) : -1L) << std::endl;
+ }
+
+ struct print_guard
+ {
+ print_guard(basic_filebuf *p,char const *func)
+ {
+ self = p;
+ f=func;
+ std::cerr << "In: " << f << std::endl;
+ self->print_state();
+ }
+ ~print_guard()
+ {
+ std::cerr << "Out: " << f << std::endl;
+ self->print_state();
+ }
+ basic_filebuf *self;
+ char const *f;
+ };
+#else
+#endif
+
+ int overflow(int c)
+ {
+#ifdef BOOST_NOWIDE_DEBUG_FILEBUF
+ print_guard g(this,__FUNCTION__);
+#endif
+ if(!file_)
+ return EOF;
+
+ if(fixg() < 0)
+ return EOF;
+
+ size_t n = pptr() - pbase();
+ if(n > 0) {
+ if(::fwrite(pbase(),1,n,file_) < n)
+ return -1;
+ fflush(file_);
+ }
+
+ if(buffer_size_ > 0) {
+ make_buffer();
+ setp(buffer_,buffer_+buffer_size_);
+ if(c!=EOF)
+ sputc(c);
+ }
+ else if(c!=EOF) {
+ if(::fputc(c,file_)==EOF)
+ return EOF;
+ fflush(file_);
+ }
+ return 0;
+ }
+
+
+ int sync()
+ {
+ return overflow(EOF);
+ }
+
+ int underflow()
+ {
+#ifdef BOOST_NOWIDE_DEBUG_FILEBUF
+ print_guard g(this,__FUNCTION__);
+#endif
+ if(!file_)
+ return EOF;
+ if(fixp() < 0)
+ return EOF;
+ if(buffer_size_ == 0) {
+ int c = ::fgetc(file_);
+ if(c==EOF) {
+ return EOF;
+ }
+ last_char_ = c;
+ setg(&last_char_,&last_char_,&last_char_ + 1);
+ return c;
+ }
+ make_buffer();
+ size_t n = ::fread(buffer_,1,buffer_size_,file_);
+ setg(buffer_,buffer_,buffer_+n);
+ if(n == 0)
+ return EOF;
+ return std::char_traits<char>::to_int_type(*gptr());
+ }
+
+ int pbackfail(int)
+ {
+ return pubseekoff(-1,std::ios::cur);
+ }
+
+ std::streampos seekoff(std::streamoff off,
+ std::ios_base::seekdir seekdir,
+ std::ios_base::openmode /*m*/)
+ {
+#ifdef BOOST_NOWIDE_DEBUG_FILEBUF
+ print_guard g(this,__FUNCTION__);
+#endif
+ if(!file_)
+ return EOF;
+ if(fixp() < 0 || fixg() < 0)
+ return EOF;
+ if(seekdir == std::ios_base::cur) {
+ if( ::fseek(file_,off,SEEK_CUR) < 0)
+ return EOF;
+ }
+ else if(seekdir == std::ios_base::beg) {
+ if( ::fseek(file_,off,SEEK_SET) < 0)
+ return EOF;
+ }
+ else if(seekdir == std::ios_base::end) {
+ if( ::fseek(file_,off,SEEK_END) < 0)
+ return EOF;
+ }
+ else
+ return -1;
+ return ftell(file_);
+ }
+ std::streampos seekpos(std::streampos off,std::ios_base::openmode m)
+ {
+ return seekoff(std::streamoff(off),std::ios_base::beg,m);
+ }
+ private:
+ int fixg()
+ {
+ if(gptr()!=egptr()) {
+ std::streamsize off = gptr() - egptr();
+ setg(0,0,0);
+ if(fseek(file_,off,SEEK_CUR) != 0)
+ return -1;
+ }
+ setg(0,0,0);
+ return 0;
+ }
+
+ int fixp()
+ {
+ if(pptr()!=0) {
+ int r = sync();
+ setp(0,0);
+ return r;
+ }
+ return 0;
+ }
+
+ void reset(FILE *f = 0)
+ {
+ sync();
+ if(file_) {
+ fclose(file_);
+ file_ = 0;
+ }
+ file_ = f;
+ }
+
+
+ static wchar_t const *get_mode(std::ios_base::openmode mode)
+ {
+ //
+ // done according to n2914 table 106 27.9.1.4
+ //
+
+ // note can't use switch case as overload operator can't be used
+ // in constant expression
+ if(mode == (std::ios_base::out))
+ return L"w";
+ if(mode == (std::ios_base::out | std::ios_base::app))
+ return L"a";
+ if(mode == (std::ios_base::app))
+ return L"a";
+ if(mode == (std::ios_base::out | std::ios_base::trunc))
+ return L"w";
+ if(mode == (std::ios_base::in))
+ return L"r";
+ if(mode == (std::ios_base::in | std::ios_base::out))
+ return L"r+";
+ if(mode == (std::ios_base::in | std::ios_base::out | std::ios_base::trunc))
+ return L"w+";
+ if(mode == (std::ios_base::in | std::ios_base::out | std::ios_base::app))
+ return L"a+";
+ if(mode == (std::ios_base::in | std::ios_base::app))
+ return L"a+";
+ if(mode == (std::ios_base::binary | std::ios_base::out))
+ return L"wb";
+ if(mode == (std::ios_base::binary | std::ios_base::out | std::ios_base::app))
+ return L"ab";
+ if(mode == (std::ios_base::binary | std::ios_base::app))
+ return L"ab";
+ if(mode == (std::ios_base::binary | std::ios_base::out | std::ios_base::trunc))
+ return L"wb";
+ if(mode == (std::ios_base::binary | std::ios_base::in))
+ return L"rb";
+ if(mode == (std::ios_base::binary | std::ios_base::in | std::ios_base::out))
+ return L"r+b";
+ if(mode == (std::ios_base::binary | std::ios_base::in | std::ios_base::out | std::ios_base::trunc))
+ return L"w+b";
+ if(mode == (std::ios_base::binary | std::ios_base::in | std::ios_base::out | std::ios_base::app))
+ return L"a+b";
+ if(mode == (std::ios_base::binary | std::ios_base::in | std::ios_base::app))
+ return L"a+b";
+ return 0;
+ }
+
+ size_t buffer_size_;
+ char *buffer_;
+ FILE *file_;
+ bool own_;
+ char last_char_;
+ std::ios::openmode mode_;
+ };
+
+ ///
+ /// \brief Convinience typedef
+ ///
+ typedef basic_filebuf<char> filebuf;
+
+ #endif // windows
+
+} // nowide
+} // namespace boost
+
+#ifdef BOOST_MSVC
+# pragma warning(pop)
+#endif
+
+
+#endif
+
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/nowide/fstream.hpp b/src/boost/nowide/fstream.hpp
new file mode 100644
index 000000000..b0824a51b
--- /dev/null
+++ b/src/boost/nowide/fstream.hpp
@@ -0,0 +1,283 @@
+//
+// 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)
+//
+#ifndef BOOST_NOWIDE_FSTREAM_INCLUDED_HPP
+#define BOOST_NOWIDE_FSTREAM_INCLUDED_HPP
+
+//#include <iosfwd>
+#include <boost/config.hpp>
+#include <boost/nowide/convert.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <fstream>
+#include <memory>
+#include <boost/nowide/filebuf.hpp>
+
+namespace boost {
+///
+/// \brief This namespace includes implementation of the standard library functios
+/// such that they accept UTF-8 strings on Windows. On other platforms it is just an alias
+/// of std namespace (i.e. not on Windows)
+///
+namespace nowide {
+#if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_FSTREAM_TESTS) && !defined(BOOST_NOWIDE_DOXYGEN)
+
+ using std::basic_ifstream;
+ using std::basic_ofstream;
+ using std::basic_fstream;
+ using std::ifstream;
+ using std::ofstream;
+ using std::fstream;
+
+#else
+ ///
+ /// \brief Same as std::basic_ifstream<char> but accepts UTF-8 strings under Windows
+ ///
+ template<typename CharType,typename Traits = std::char_traits<CharType> >
+ class basic_ifstream : public std::basic_istream<CharType,Traits>
+ {
+ public:
+ typedef basic_filebuf<CharType,Traits> internal_buffer_type;
+ typedef std::basic_istream<CharType,Traits> internal_stream_type;
+
+ basic_ifstream() :
+ internal_stream_type(0)
+ {
+ buf_.reset(new internal_buffer_type());
+ std::ios::rdbuf(buf_.get());
+ }
+
+ explicit basic_ifstream(char const *file_name,std::ios_base::openmode mode = std::ios_base::in) :
+ internal_stream_type(0)
+ {
+ buf_.reset(new internal_buffer_type());
+ std::ios::rdbuf(buf_.get());
+ open(file_name,mode);
+ }
+
+ explicit basic_ifstream(std::string const &file_name,std::ios_base::openmode mode = std::ios_base::in) :
+ internal_stream_type(0)
+ {
+ buf_.reset(new internal_buffer_type());
+ std::ios::rdbuf(buf_.get());
+ open(file_name,mode);
+ }
+
+
+ void open(std::string const &file_name,std::ios_base::openmode mode = std::ios_base::in)
+ {
+ open(file_name.c_str(),mode);
+ }
+ void open(char const *file_name,std::ios_base::openmode mode = std::ios_base::in)
+ {
+ if(!buf_->open(file_name,mode | std::ios_base::in)) {
+ this->setstate(std::ios_base::failbit);
+ }
+ else {
+ this->clear();
+ }
+ }
+ bool is_open()
+ {
+ return buf_->is_open();
+ }
+ bool is_open() const
+ {
+ return buf_->is_open();
+ }
+ void close()
+ {
+ if(!buf_->close())
+ this->setstate(std::ios_base::failbit);
+ else
+ this->clear();
+ }
+
+ internal_buffer_type *rdbuf() const
+ {
+ return buf_.get();
+ }
+ ~basic_ifstream()
+ {
+ buf_->close();
+ }
+
+ private:
+ boost::scoped_ptr<internal_buffer_type> buf_;
+ };
+
+ ///
+ /// \brief Same as std::basic_ofstream<char> but accepts UTF-8 strings under Windows
+ ///
+
+ template<typename CharType,typename Traits = std::char_traits<CharType> >
+ class basic_ofstream : public std::basic_ostream<CharType,Traits>
+ {
+ public:
+ typedef basic_filebuf<CharType,Traits> internal_buffer_type;
+ typedef std::basic_ostream<CharType,Traits> internal_stream_type;
+
+ basic_ofstream() :
+ internal_stream_type(0)
+ {
+ buf_.reset(new internal_buffer_type());
+ std::ios::rdbuf(buf_.get());
+ }
+ explicit basic_ofstream(char const *file_name,std::ios_base::openmode mode = std::ios_base::out) :
+ internal_stream_type(0)
+ {
+ buf_.reset(new internal_buffer_type());
+ std::ios::rdbuf(buf_.get());
+ open(file_name,mode);
+ }
+ explicit basic_ofstream(std::string const &file_name,std::ios_base::openmode mode = std::ios_base::out) :
+ internal_stream_type(0)
+ {
+ buf_.reset(new internal_buffer_type());
+ std::ios::rdbuf(buf_.get());
+ open(file_name,mode);
+ }
+ void open(std::string const &file_name,std::ios_base::openmode mode = std::ios_base::out)
+ {
+ open(file_name.c_str(),mode);
+ }
+ void open(char const *file_name,std::ios_base::openmode mode = std::ios_base::out)
+ {
+ if(!buf_->open(file_name,mode | std::ios_base::out)) {
+ this->setstate(std::ios_base::failbit);
+ }
+ else {
+ this->clear();
+ }
+ }
+ bool is_open()
+ {
+ return buf_->is_open();
+ }
+ bool is_open() const
+ {
+ return buf_->is_open();
+ }
+ void close()
+ {
+ if(!buf_->close())
+ this->setstate(std::ios_base::failbit);
+ else
+ this->clear();
+ }
+
+ internal_buffer_type *rdbuf() const
+ {
+ return buf_.get();
+ }
+ ~basic_ofstream()
+ {
+ buf_->close();
+ }
+
+ private:
+ boost::scoped_ptr<internal_buffer_type> buf_;
+ };
+
+ ///
+ /// \brief Same as std::basic_fstream<char> but accepts UTF-8 strings under Windows
+ ///
+
+ template<typename CharType,typename Traits = std::char_traits<CharType> >
+ class basic_fstream : public std::basic_iostream<CharType,Traits>
+ {
+ public:
+ typedef basic_filebuf<CharType,Traits> internal_buffer_type;
+ typedef std::basic_iostream<CharType,Traits> internal_stream_type;
+
+ basic_fstream() :
+ internal_stream_type(0)
+ {
+ buf_.reset(new internal_buffer_type());
+ std::ios::rdbuf(buf_.get());
+ }
+ explicit basic_fstream(char const *file_name,std::ios_base::openmode mode = std::ios_base::out | std::ios_base::in) :
+ internal_stream_type(0)
+ {
+ buf_.reset(new internal_buffer_type());
+ std::ios::rdbuf(buf_.get());
+ open(file_name,mode);
+ }
+ explicit basic_fstream(std::string const &file_name,std::ios_base::openmode mode = std::ios_base::out | std::ios_base::in) :
+ internal_stream_type(0)
+ {
+ buf_.reset(new internal_buffer_type());
+ std::ios::rdbuf(buf_.get());
+ open(file_name,mode);
+ }
+ void open(std::string const &file_name,std::ios_base::openmode mode = std::ios_base::out | std::ios_base::out)
+ {
+ open(file_name.c_str(),mode);
+ }
+ void open(char const *file_name,std::ios_base::openmode mode = std::ios_base::out | std::ios_base::out)
+ {
+ if(!buf_->open(file_name,mode)) {
+ this->setstate(std::ios_base::failbit);
+ }
+ else {
+ this->clear();
+ }
+ }
+ bool is_open()
+ {
+ return buf_->is_open();
+ }
+ bool is_open() const
+ {
+ return buf_->is_open();
+ }
+ void close()
+ {
+ if(!buf_->close())
+ this->setstate(std::ios_base::failbit);
+ else
+ this->clear();
+ }
+
+ internal_buffer_type *rdbuf() const
+ {
+ return buf_.get();
+ }
+ ~basic_fstream()
+ {
+ buf_->close();
+ }
+
+ private:
+ boost::scoped_ptr<internal_buffer_type> buf_;
+ };
+
+
+ ///
+ /// \brief Same as std::filebuf but accepts UTF-8 strings under Windows
+ ///
+ typedef basic_filebuf<char> filebuf;
+ ///
+ /// Same as std::ifstream but accepts UTF-8 strings under Windows
+ ///
+ typedef basic_ifstream<char> ifstream;
+ ///
+ /// Same as std::ofstream but accepts UTF-8 strings under Windows
+ ///
+ typedef basic_ofstream<char> ofstream;
+ ///
+ /// Same as std::fstream but accepts UTF-8 strings under Windows
+ ///
+ typedef basic_fstream<char> fstream;
+
+#endif
+} // nowide
+} // namespace boost
+
+
+
+#endif
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/nowide/integration/filesystem.hpp b/src/boost/nowide/integration/filesystem.hpp
new file mode 100644
index 000000000..c2a44b4ee
--- /dev/null
+++ b/src/boost/nowide/integration/filesystem.hpp
@@ -0,0 +1,28 @@
+//
+// 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)
+//
+#ifndef BOOST_NOWIDE_INTEGRATION_FILESYSTEM_HPP_INCLUDED
+#define BOOST_NOWIDE_INTEGRATION_FILESYSTEM_HPP_INCLUDED
+
+#include <boost/filesystem/path.hpp>
+#include <boost/nowide/utf8_codecvt.hpp>
+namespace boost {
+ namespace nowide {
+ ///
+ /// Instal utf8_codecvt facet into boost::filesystem::path such all char strings are interpreted as utf-8 strings
+ ///
+ inline void nowide_filesystem()
+ {
+ std::locale tmp = std::locale(std::locale(),new boost::nowide::utf8_codecvt<wchar_t>());
+ boost::filesystem::path::imbue(tmp);
+ }
+ } // nowide
+} // boost
+
+#endif
+///
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
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
diff --git a/src/boost/nowide/iostream.hpp b/src/boost/nowide/iostream.hpp
new file mode 100644
index 000000000..6ab004a25
--- /dev/null
+++ b/src/boost/nowide/iostream.hpp
@@ -0,0 +1,99 @@
+//
+// 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)
+//
+#ifndef BOOST_NOWIDE_IOSTREAM_HPP_INCLUDED
+#define BOOST_NOWIDE_IOSTREAM_HPP_INCLUDED
+
+#include <boost/nowide/config.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <iostream>
+#include <ostream>
+#include <istream>
+
+#ifdef BOOST_MSVC
+# pragma warning(push)
+# pragma warning(disable : 4251)
+#endif
+
+
+namespace boost {
+namespace nowide {
+ #if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN)
+ using std::cout;
+ using std::cerr;
+ using std::cin;
+ using std::clog;
+ #else
+
+ /// \cond INTERNAL
+ namespace details {
+ class console_output_buffer;
+ class console_input_buffer;
+
+ class BOOST_NOWIDE_DECL winconsole_ostream : public std::ostream {
+ winconsole_ostream(winconsole_ostream const &);
+ void operator=(winconsole_ostream const &);
+ public:
+ winconsole_ostream(int fd);
+ ~winconsole_ostream();
+ private:
+ boost::scoped_ptr<console_output_buffer> d;
+ };
+
+ class BOOST_NOWIDE_DECL winconsole_istream : public std::istream {
+ winconsole_istream(winconsole_istream const &);
+ void operator=(winconsole_istream const &);
+ public:
+
+ winconsole_istream();
+ ~winconsole_istream();
+ private:
+ struct data;
+ boost::scoped_ptr<console_input_buffer> d;
+ };
+ } // details
+
+ /// \endcond
+
+ ///
+ /// \brief Same as std::cin, but uses UTF-8
+ ///
+ /// Note, the stream is not synchronized with stdio and not affected by std::ios::sync_with_stdio
+ ///
+ extern BOOST_NOWIDE_DECL details::winconsole_istream cin;
+ ///
+ /// \brief Same as std::cout, but uses UTF-8
+ ///
+ /// Note, the stream is not synchronized with stdio and not affected by std::ios::sync_with_stdio
+ ///
+ extern BOOST_NOWIDE_DECL details::winconsole_ostream cout;
+ ///
+ /// \brief Same as std::cerr, but uses UTF-8
+ ///
+ /// Note, the stream is not synchronized with stdio and not affected by std::ios::sync_with_stdio
+ ///
+ extern BOOST_NOWIDE_DECL details::winconsole_ostream cerr;
+ ///
+ /// \brief Same as std::clog, but uses UTF-8
+ ///
+ /// Note, the stream is not synchronized with stdio and not affected by std::ios::sync_with_stdio
+ ///
+ extern BOOST_NOWIDE_DECL details::winconsole_ostream clog;
+
+ #endif
+
+} // nowide
+} // namespace boost
+
+#ifdef BOOST_MSVC
+# pragma warning(pop)
+#endif
+
+
+#endif
+///
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/nowide/stackstring.hpp b/src/boost/nowide/stackstring.hpp
new file mode 100644
index 000000000..948a22f7f
--- /dev/null
+++ b/src/boost/nowide/stackstring.hpp
@@ -0,0 +1,154 @@
+//
+// 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)
+//
+#ifndef BOOST_NOWIDE_DETAILS_WIDESTR_H_INCLUDED
+#define BOOST_NOWIDE_DETAILS_WIDESTR_H_INCLUDED
+#include <boost/nowide/convert.hpp>
+#include <string.h>
+#include <algorithm>
+
+namespace boost {
+namespace nowide {
+
+///
+/// \brief A class that allows to create a temporary wide or narrow UTF strings from
+/// wide or narrow UTF source.
+///
+/// It uses on stack buffer of the string is short enough
+/// and allocated a buffer on the heap if the size of the buffer is too small
+///
+template<typename CharOut=wchar_t,typename CharIn = char,size_t BufferSize = 256>
+class basic_stackstring {
+public:
+
+ static const size_t buffer_size = BufferSize;
+ typedef CharOut output_char;
+ typedef CharIn input_char;
+
+ basic_stackstring(basic_stackstring const &other) :
+ mem_buffer_(0)
+ {
+ clear();
+ if(other.mem_buffer_) {
+ size_t len = 0;
+ while(other.mem_buffer_[len])
+ len ++;
+ mem_buffer_ = new output_char[len + 1];
+ memcpy(mem_buffer_,other.mem_buffer_,sizeof(output_char) * (len+1));
+ }
+ else {
+ memcpy(buffer_,other.buffer_,buffer_size * sizeof(output_char));
+ }
+ }
+
+ void swap(basic_stackstring &other)
+ {
+ std::swap(mem_buffer_,other.mem_buffer_);
+ for(size_t i=0;i<buffer_size;i++)
+ std::swap(buffer_[i],other.buffer_[i]);
+ }
+ basic_stackstring &operator=(basic_stackstring const &other)
+ {
+ if(this != &other) {
+ basic_stackstring tmp(other);
+ swap(tmp);
+ }
+ return *this;
+ }
+
+ basic_stackstring() : mem_buffer_(0)
+ {
+ }
+ bool convert(input_char const *input)
+ {
+ return convert(input,details::basic_strend(input));
+ }
+ bool convert(input_char const *begin,input_char const *end)
+ {
+ clear();
+
+ size_t space = get_space(sizeof(input_char),sizeof(output_char),end - begin) + 1;
+ if(space <= buffer_size) {
+ if(basic_convert(buffer_,buffer_size,begin,end))
+ return true;
+ clear();
+ return false;
+ }
+ else {
+ mem_buffer_ = new output_char[space];
+ if(!basic_convert(mem_buffer_,space,begin,end)) {
+ clear();
+ return false;
+ }
+ return true;
+ }
+
+ }
+ output_char *c_str()
+ {
+ if(mem_buffer_)
+ return mem_buffer_;
+ return buffer_;
+ }
+ output_char const *c_str() const
+ {
+ if(mem_buffer_)
+ return mem_buffer_;
+ return buffer_;
+ }
+ void clear()
+ {
+ if(mem_buffer_) {
+ delete [] mem_buffer_;
+ mem_buffer_=0;
+ }
+ buffer_[0] = 0;
+ }
+ ~basic_stackstring()
+ {
+ clear();
+ }
+private:
+ static size_t get_space(size_t insize,size_t outsize,size_t in)
+ {
+ if(insize <= outsize)
+ return in;
+ else if(insize == 2 && outsize == 1)
+ return 3 * in;
+ else if(insize == 4 && outsize == 1)
+ return 4 * in;
+ else // if(insize == 4 && outsize == 2)
+ return 2 * in;
+ }
+ output_char buffer_[buffer_size];
+ output_char *mem_buffer_;
+}; //basic_stackstring
+
+///
+/// Convinience typedef
+///
+typedef basic_stackstring<wchar_t,char,256> wstackstring;
+///
+/// Convinience typedef
+///
+typedef basic_stackstring<char,wchar_t,256> stackstring;
+///
+/// Convinience typedef
+///
+typedef basic_stackstring<wchar_t,char,16> wshort_stackstring;
+///
+/// Convinience typedef
+///
+typedef basic_stackstring<char,wchar_t,16> short_stackstring;
+
+
+} // nowide
+} // namespace boost
+
+#endif
+///
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/nowide/system.hpp b/src/boost/nowide/system.hpp
new file mode 100644
index 000000000..a1fc97505
--- /dev/null
+++ b/src/boost/nowide/system.hpp
@@ -0,0 +1,46 @@
+//
+// 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)
+//
+#ifndef BOOST_NOWIDE_CSTDLIB_HPP
+#define BOOST_NOWIDE_CSTDLIB_HPP
+
+#include <stdlib.h>
+#include <errno.h>
+#include <boost/nowide/stackstring.hpp>
+namespace boost {
+namespace nowide {
+
+#if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN)
+
+using ::system;
+
+#else // Windows
+
+///
+/// Same as std::system but cmd is UTF-8.
+///
+/// If the input is not valid UTF-8, -1 returned and errno set to EINVAL
+///
+inline int system(char const *cmd)
+{
+ if(!cmd)
+ return _wsystem(0);
+ wstackstring wcmd;
+ if(!wcmd.convert(cmd)) {
+ errno = EINVAL;
+ return -1;
+ }
+ return _wsystem(wcmd.c_str());
+}
+
+#endif
+} // nowide
+} // namespace boost
+
+#endif
+///
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/nowide/utf8_codecvt.hpp b/src/boost/nowide/utf8_codecvt.hpp
new file mode 100644
index 000000000..cc5046fc8
--- /dev/null
+++ b/src/boost/nowide/utf8_codecvt.hpp
@@ -0,0 +1,499 @@
+//
+// Copyright (c) 2015 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)
+//
+#ifndef BOOST_NOWIDE_UTF8_CODECVT_HPP
+#define BOOST_NOWIDE_UTF8_CODECVT_HPP
+
+#include <boost/locale/utf.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/static_assert.hpp>
+#include <locale>
+
+namespace boost {
+namespace nowide {
+
+//
+// Make sure that mbstate can keep 16 bit of UTF-16 sequence
+//
+BOOST_STATIC_ASSERT(sizeof(std::mbstate_t)>=2);
+
+#ifdef _MSC_VER
+// MSVC do_length is non-standard it counts wide characters instead of narrow and does not change mbstate
+#define BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST
+#endif
+
+template<typename CharType,int CharSize=sizeof(CharType)>
+class utf8_codecvt;
+
+template<typename CharType>
+class utf8_codecvt<CharType,2> : public std::codecvt<CharType,char,std::mbstate_t>
+{
+public:
+ utf8_codecvt(size_t refs = 0) : std::codecvt<CharType,char,std::mbstate_t>(refs)
+ {
+ }
+protected:
+
+ typedef CharType uchar;
+
+ virtual std::codecvt_base::result do_unshift(std::mbstate_t &s,char *from,char * /*to*/,char *&next) const
+ {
+ boost::uint16_t &state = *reinterpret_cast<boost::uint16_t *>(&s);
+#ifdef DEBUG_CODECVT
+ std::cout << "Entering unshift " << std::hex << state << std::dec << std::endl;
+#endif
+ if(state != 0)
+ return std::codecvt_base::error;
+ next=from;
+ return std::codecvt_base::ok;
+ }
+ virtual int do_encoding() const throw()
+ {
+ return 0;
+ }
+ virtual int do_max_length() const throw()
+ {
+ return 4;
+ }
+ virtual bool do_always_noconv() const throw()
+ {
+ return false;
+ }
+
+ virtual int
+ do_length( std::mbstate_t
+ #ifdef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST
+ const
+ #endif
+ &std_state,
+ char const *from,
+ char const *from_end,
+ size_t max) const
+ {
+ #ifndef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST
+ char const *save_from = from;
+ boost::uint16_t &state = *reinterpret_cast<boost::uint16_t *>(&std_state);
+ #else
+ size_t save_max = max;
+ boost::uint16_t state = *reinterpret_cast<boost::uint16_t const *>(&std_state);
+ #endif
+ while(max > 0 && from < from_end){
+ char const *prev_from = from;
+ boost::uint32_t ch=boost::locale::utf::utf_traits<char>::decode(from,from_end);
+ if(ch==boost::locale::utf::incomplete || ch==boost::locale::utf::illegal) {
+ from = prev_from;
+ break;
+ }
+ max --;
+ if(ch > 0xFFFF) {
+ if(state == 0) {
+ from = prev_from;
+ state = 1;
+ }
+ else {
+ state = 0;
+ }
+ }
+ }
+ #ifndef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST
+ return from - save_from;
+ #else
+ return save_max - max;
+ #endif
+ }
+
+
+ virtual std::codecvt_base::result
+ do_in( std::mbstate_t &std_state,
+ char const *from,
+ char const *from_end,
+ char const *&from_next,
+ uchar *to,
+ uchar *to_end,
+ uchar *&to_next) const
+ {
+ std::codecvt_base::result r=std::codecvt_base::ok;
+
+ // mbstate_t is POD type and should be initialized to 0 (i.a. state = stateT())
+ // according to standard. We use it to keep a flag 0/1 for surrogate pair writing
+ //
+ // if 0 no code above >0xFFFF observed, of 1 a code above 0xFFFF observerd
+ // and first pair is written, but no input consumed
+ boost::uint16_t &state = *reinterpret_cast<boost::uint16_t *>(&std_state);
+ while(to < to_end && from < from_end)
+ {
+#ifdef DEBUG_CODECVT
+ std::cout << "Entering IN--------------" << std::endl;
+ std::cout << "State " << std::hex << state <<std::endl;
+ std::cout << "Left in " << std::dec << from_end - from << " out " << to_end -to << std::endl;
+#endif
+ char const *from_saved = from;
+
+ uint32_t ch=boost::locale::utf::utf_traits<char>::decode(from,from_end);
+
+ if(ch==boost::locale::utf::illegal) {
+ from = from_saved;
+ r=std::codecvt_base::error;
+ break;
+ }
+ if(ch==boost::locale::utf::incomplete) {
+ from = from_saved;
+ r=std::codecvt_base::partial;
+ break;
+ }
+ // Normal codepoints go direcly to stream
+ if(ch <= 0xFFFF) {
+ *to++=ch;
+ }
+ else {
+ // for other codepoints we do following
+ //
+ // 1. We can't consume our input as we may find ourselfs
+ // in state where all input consumed but not all output written,i.e. only
+ // 1st pair is written
+ // 2. We only write first pair and mark this in the state, we also revert back
+ // the from pointer in order to make sure this codepoint would be read
+ // once again and then we would consume our input together with writing
+ // second surrogate pair
+ ch-=0x10000;
+ boost::uint16_t vh = ch >> 10;
+ boost::uint16_t vl = ch & 0x3FF;
+ boost::uint16_t w1 = vh + 0xD800;
+ boost::uint16_t w2 = vl + 0xDC00;
+ if(state == 0) {
+ from = from_saved;
+ *to++ = w1;
+ state = 1;
+ }
+ else {
+ *to++ = w2;
+ state = 0;
+ }
+ }
+ }
+ from_next=from;
+ to_next=to;
+ if(r == std::codecvt_base::ok && (from!=from_end || state!=0))
+ r = std::codecvt_base::partial;
+#ifdef DEBUG_CODECVT
+ std::cout << "Returning ";
+ switch(r) {
+ case std::codecvt_base::ok:
+ std::cout << "ok" << std::endl;
+ break;
+ case std::codecvt_base::partial:
+ std::cout << "partial" << std::endl;
+ break;
+ case std::codecvt_base::error:
+ std::cout << "error" << std::endl;
+ break;
+ default:
+ std::cout << "other" << std::endl;
+ break;
+ }
+ std::cout << "State " << std::hex << state <<std::endl;
+ std::cout << "Left in " << std::dec << from_end - from << " out " << to_end -to << std::endl;
+#endif
+ return r;
+ }
+
+ virtual std::codecvt_base::result
+ do_out( std::mbstate_t &std_state,
+ uchar const *from,
+ uchar const *from_end,
+ uchar const *&from_next,
+ char *to,
+ char *to_end,
+ char *&to_next) const
+ {
+ std::codecvt_base::result r=std::codecvt_base::ok;
+ // mbstate_t is POD type and should be initialized to 0 (i.a. state = stateT())
+ // according to standard. We assume that sizeof(mbstate_t) >=2 in order
+ // to be able to store first observerd surrogate pair
+ //
+ // State: state!=0 - a first surrogate pair was observerd (state = first pair),
+ // we expect the second one to come and then zero the state
+ ///
+ boost::uint16_t &state = *reinterpret_cast<boost::uint16_t *>(&std_state);
+ while(to < to_end && from < from_end)
+ {
+#ifdef DEBUG_CODECVT
+ std::cout << "Entering OUT --------------" << std::endl;
+ std::cout << "State " << std::hex << state <<std::endl;
+ std::cout << "Left in " << std::dec << from_end - from << " out " << to_end -to << std::endl;
+#endif
+ boost::uint32_t ch=0;
+ if(state != 0) {
+ // if the state idecates that 1st surrogate pair was written
+ // we should make sure that the second one that comes is actually
+ // second surrogate
+ boost::uint16_t w1 = state;
+ boost::uint16_t w2 = *from;
+ // we don't forward from as writing may fail to incomplete or
+ // partial conversion
+ if(0xDC00 <= w2 && w2<=0xDFFF) {
+ boost::uint16_t vh = w1 - 0xD800;
+ boost::uint16_t vl = w2 - 0xDC00;
+ ch=((uint32_t(vh) << 10) | vl) + 0x10000;
+ }
+ else {
+ // Invalid surrogate
+ r=std::codecvt_base::error;
+ break;
+ }
+ }
+ else {
+ ch = *from;
+ if(0xD800 <= ch && ch<=0xDBFF) {
+ // if this is a first surrogate pair we put
+ // it into the state and consume it, note we don't
+ // go forward as it should be illegal so we increase
+ // the from pointer manually
+ state = ch;
+ from++;
+ continue;
+ }
+ else if(0xDC00 <= ch && ch<=0xDFFF) {
+ // if we observe second surrogate pair and
+ // first only may be expected we should break from the loop with error
+ // as it is illegal input
+ r=std::codecvt_base::error;
+ break;
+ }
+ }
+ if(!boost::locale::utf::is_valid_codepoint(ch)) {
+ r=std::codecvt_base::error;
+ break;
+ }
+ int len = boost::locale::utf::utf_traits<char>::width(ch);
+ if(to_end - to < len) {
+ r=std::codecvt_base::partial;
+ break;
+ }
+ to = boost::locale::utf::utf_traits<char>::encode(ch,to);
+ state = 0;
+ from++;
+ }
+ from_next=from;
+ to_next=to;
+ if(r==std::codecvt_base::ok && from!=from_end)
+ r = std::codecvt_base::partial;
+#ifdef DEBUG_CODECVT
+ std::cout << "Returning ";
+ switch(r) {
+ case std::codecvt_base::ok:
+ std::cout << "ok" << std::endl;
+ break;
+ case std::codecvt_base::partial:
+ std::cout << "partial" << std::endl;
+ break;
+ case std::codecvt_base::error:
+ std::cout << "error" << std::endl;
+ break;
+ default:
+ std::cout << "other" << std::endl;
+ break;
+ }
+ std::cout << "State " << std::hex << state <<std::endl;
+ std::cout << "Left in " << std::dec << from_end - from << " out " << to_end -to << std::endl;
+#endif
+ return r;
+ }
+
+};
+
+template<typename CharType>
+class utf8_codecvt<CharType,4> : public std::codecvt<CharType,char,std::mbstate_t>
+{
+public:
+ utf8_codecvt(size_t refs = 0) : std::codecvt<CharType,char,std::mbstate_t>(refs)
+ {
+ }
+protected:
+
+ typedef CharType uchar;
+
+ virtual std::codecvt_base::result do_unshift(std::mbstate_t &/*s*/,char *from,char * /*to*/,char *&next) const
+ {
+ next=from;
+ return std::codecvt_base::ok;
+ }
+ virtual int do_encoding() const throw()
+ {
+ return 0;
+ }
+ virtual int do_max_length() const throw()
+ {
+ return 4;
+ }
+ virtual bool do_always_noconv() const throw()
+ {
+ return false;
+ }
+
+ virtual int
+ do_length( std::mbstate_t
+ #ifdef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST
+ const
+ #endif
+ &/*state*/,
+ char const *from,
+ char const *from_end,
+ size_t max) const
+ {
+ #ifndef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST
+ char const *start_from = from;
+ #else
+ size_t save_max = max;
+ #endif
+
+ while(max > 0 && from < from_end){
+ char const *save_from = from;
+ boost::uint32_t ch=boost::locale::utf::utf_traits<char>::decode(from,from_end);
+ if(ch==boost::locale::utf::incomplete || ch==boost::locale::utf::illegal) {
+ from = save_from;
+ break;
+ }
+ max--;
+ }
+ #ifndef BOOST_NOWIDE_DO_LENGTH_MBSTATE_CONST
+ return from - start_from;
+ #else
+ return save_max - max;
+ #endif
+ }
+
+
+ virtual std::codecvt_base::result
+ do_in( std::mbstate_t &/*state*/,
+ char const *from,
+ char const *from_end,
+ char const *&from_next,
+ uchar *to,
+ uchar *to_end,
+ uchar *&to_next) const
+ {
+ std::codecvt_base::result r=std::codecvt_base::ok;
+
+ // mbstate_t is POD type and should be initialized to 0 (i.a. state = stateT())
+ // according to standard. We use it to keep a flag 0/1 for surrogate pair writing
+ //
+ // if 0 no code above >0xFFFF observed, of 1 a code above 0xFFFF observerd
+ // and first pair is written, but no input consumed
+ while(to < to_end && from < from_end)
+ {
+#ifdef DEBUG_CODECVT
+ std::cout << "Entering IN--------------" << std::endl;
+ std::cout << "State " << std::hex << state <<std::endl;
+ std::cout << "Left in " << std::dec << from_end - from << " out " << to_end -to << std::endl;
+#endif
+ char const *from_saved = from;
+
+ uint32_t ch=boost::locale::utf::utf_traits<char>::decode(from,from_end);
+
+ if(ch==boost::locale::utf::illegal) {
+ r=std::codecvt_base::error;
+ from = from_saved;
+ break;
+ }
+ if(ch==boost::locale::utf::incomplete) {
+ r=std::codecvt_base::partial;
+ from=from_saved;
+ break;
+ }
+ *to++=ch;
+ }
+ from_next=from;
+ to_next=to;
+ if(r == std::codecvt_base::ok && from!=from_end)
+ r = std::codecvt_base::partial;
+#ifdef DEBUG_CODECVT
+ std::cout << "Returning ";
+ switch(r) {
+ case std::codecvt_base::ok:
+ std::cout << "ok" << std::endl;
+ break;
+ case std::codecvt_base::partial:
+ std::cout << "partial" << std::endl;
+ break;
+ case std::codecvt_base::error:
+ std::cout << "error" << std::endl;
+ break;
+ default:
+ std::cout << "other" << std::endl;
+ break;
+ }
+ std::cout << "State " << std::hex << state <<std::endl;
+ std::cout << "Left in " << std::dec << from_end - from << " out " << to_end -to << std::endl;
+#endif
+ return r;
+ }
+
+ virtual std::codecvt_base::result
+ do_out( std::mbstate_t &std_state,
+ uchar const *from,
+ uchar const *from_end,
+ uchar const *&from_next,
+ char *to,
+ char *to_end,
+ char *&to_next) const
+ {
+ std::codecvt_base::result r=std::codecvt_base::ok;
+ while(to < to_end && from < from_end)
+ {
+#ifdef DEBUG_CODECVT
+ std::cout << "Entering OUT --------------" << std::endl;
+ std::cout << "State " << std::hex << state <<std::endl;
+ std::cout << "Left in " << std::dec << from_end - from << " out " << to_end -to << std::endl;
+#endif
+ boost::uint32_t ch=0;
+ ch = *from;
+ if(!boost::locale::utf::is_valid_codepoint(ch)) {
+ r=std::codecvt_base::error;
+ break;
+ }
+ int len = boost::locale::utf::utf_traits<char>::width(ch);
+ if(to_end - to < len) {
+ r=std::codecvt_base::partial;
+ break;
+ }
+ to = boost::locale::utf::utf_traits<char>::encode(ch,to);
+ from++;
+ }
+ from_next=from;
+ to_next=to;
+ if(r==std::codecvt_base::ok && from!=from_end)
+ r = std::codecvt_base::partial;
+#ifdef DEBUG_CODECVT
+ std::cout << "Returning ";
+ switch(r) {
+ case std::codecvt_base::ok:
+ std::cout << "ok" << std::endl;
+ break;
+ case std::codecvt_base::partial:
+ std::cout << "partial" << std::endl;
+ break;
+ case std::codecvt_base::error:
+ std::cout << "error" << std::endl;
+ break;
+ default:
+ std::cout << "other" << std::endl;
+ break;
+ }
+ std::cout << "State " << std::hex << state <<std::endl;
+ std::cout << "Left in " << std::dec << from_end - from << " out " << to_end -to << std::endl;
+#endif
+ return r;
+ }
+};
+
+} // nowide
+} // namespace boost
+
+#endif
+///
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/src/boost/nowide/windows.hpp b/src/boost/nowide/windows.hpp
new file mode 100644
index 000000000..164ed5531
--- /dev/null
+++ b/src/boost/nowide/windows.hpp
@@ -0,0 +1,39 @@
+//
+// 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)
+//
+#ifndef BOOST_NOWIDE_WINDOWS_HPP_INCLUDED
+#define BOOST_NOWIDE_WINDOWS_HPP_INCLUDED
+
+#include <stddef.h>
+
+#ifdef BOOST_NOWIDE_USE_WINDOWS_H
+#include <windows.h>
+#else
+
+//
+// These are function prototypes... Allow to to include windows.h
+//
+extern "C" {
+
+__declspec(dllimport) wchar_t* __stdcall GetEnvironmentStringsW(void);
+__declspec(dllimport) int __stdcall FreeEnvironmentStringsW(wchar_t *);
+__declspec(dllimport) wchar_t* __stdcall GetCommandLineW(void);
+__declspec(dllimport) wchar_t** __stdcall CommandLineToArgvW(wchar_t const *,int *);
+__declspec(dllimport) unsigned long __stdcall GetLastError();
+__declspec(dllimport) void* __stdcall LocalFree(void *);
+__declspec(dllimport) int __stdcall SetEnvironmentVariableW(wchar_t const *,wchar_t const *);
+__declspec(dllimport) unsigned long __stdcall GetEnvironmentVariableW(wchar_t const *,wchar_t *,unsigned long);
+
+}
+
+#endif
+
+
+
+#endif
+///
+// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4