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/filebuf.hpp')
-rw-r--r--src/boost/nowide/filebuf.hpp415
1 files changed, 415 insertions, 0 deletions
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