/* Copyright (C) 2004 Garrett A. Kajmowicz This file is part of the uClibc++ Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #ifndef HEADER_STD_STREAMBUF #define HEADER_STD_STREAMBUF 1 #include #pragma GCC visibility push(default) namespace std{ template class _UCXXEXPORT basic_streambuf{ public: #ifdef __UCLIBCXX_SUPPORT_CDIR__ friend ios_base::Init::Init(); #endif // Types: typedef charT char_type; typedef typename traits::int_type int_type; typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; typedef traits traits_type; virtual ~basic_streambuf(); locale pubimbue(const locale &loc); locale getloc() const{ return myLocale; } basic_streambuf* pubsetbuf(char_type* s, streamsize n){ return setbuf(s,n); } pos_type pubseekoff(off_type off, typename ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out ) { return seekoff(off,way,which); } pos_type pubseekpos(pos_type sp, ios_base::openmode which = ios_base::in | ios_base::out){ return seekpos(sp,which); } int pubsync(){ return sync(); } streamsize in_avail(); int_type snextc(); int_type sbumpc(); int_type sgetc(); streamsize sgetn(char_type* s, streamsize n){ return xsgetn(s,n); } int_type sputbackc(char_type c); int_type sungetc(); int_type sputc(char_type c); streamsize sputn(const char_type* s, streamsize n){ if(openedFor & ios_base::app){ seekoff(0, ios_base::end, ios_base::out); } return xsputn(s, n); } protected: locale myLocale; //Pointers for the "get" buffers charT * mgbeg; charT * mgnext; charT * mgend; //Pointers for the "put" buffers charT * mpbeg; charT * mpnext; charT * mpend; //In the event of null buffers Lets us know what the buffer is opened for ios_base::openmode openedFor; basic_streambuf(); basic_streambuf(const basic_streambuf > &) : myLocale(), mgbeg(0), mgnext(0), mgend(0), mpbeg(0), mpnext(0), mpend(0), openedFor(0) { } basic_streambuf > & operator=(const basic_streambuf > &){ return *this; } char_type* eback() const{ return mgbeg; } char_type* gptr() const{ return mgnext; } char_type* egptr() const{ return mgend; } void gbump(int n){ mgnext+=n; } void setg(char_type* gbeg, char_type* gnext, char_type* gend){ mgbeg = gbeg; mgnext = gnext; mgend = gend; } char_type* pbase() const{ return mpbeg; } char_type* pptr() const{ return mpnext; } char_type* epptr() const{ return mpend; } void pbump(int n){ mpnext+=n; } void setp(char_type* pbeg, char_type* pend){ mpbeg = pbeg; mpnext = pbeg; mpend = pend; } virtual void imbue(const locale &loc){ myLocale = loc; } //Virtual functions which we will not implement virtual basic_streambuf* setbuf(char_type* , streamsize){ return 0; } virtual pos_type seekoff(off_type , ios_base::seekdir, ios_base::openmode = ios_base::in | ios_base::out) { return 0; } virtual pos_type seekpos(pos_type , ios_base::openmode = ios_base::in | ios_base::out){ return 0; } virtual int sync(){ return 0; } virtual int showmanyc(){ return 0; } virtual streamsize xsgetn(char_type* , streamsize ){ return 0; } virtual int_type underflow(){ return traits_type::eof(); } virtual int_type uflow(){ int_type ret = underflow(); if (!traits_type::eq_int_type(ret, traits_type::eof())) gbump(1); return ret; } virtual int_type pbackfail(int_type c = traits::eof()){ return c; } virtual streamsize xsputn(const char_type* c, streamsize n){ //This function is designed to be replaced by subclasses for(streamsize i = 0; i< n; ++i){ if(sputc(c[i]) == traits::eof()){ return i; } } return n; } virtual int_type overflow (int_type c = traits::eof()){ return c; } }; typedef basic_streambuf streambuf; #ifdef __UCLIBCXX_HAS_WCHAR__ typedef basic_streambuf wstreambuf; #endif //Definitions put below to allow for easy expansion of code template basic_streambuf::~basic_streambuf(){ } template locale basic_streambuf::pubimbue(const locale &loc){ locale temp = myLocale; myLocale = loc; return temp; } template streamsize basic_streambuf::in_avail(){ if(mgend !=0 && mgnext !=0){ return mgend - mgnext; } return showmanyc(); } template typename basic_streambuf::int_type basic_streambuf::sbumpc(){ if(mgbeg == 0 || mgnext == mgend){ return uflow(); } int_type retval = T::to_int_type(*gptr()); gbump(1); return retval; } template typename basic_streambuf::int_type basic_streambuf::snextc(){ if(sbumpc() == T::eof() ){ return T::eof() ; } return sgetc(); } template typename basic_streambuf::int_type basic_streambuf::sgetc(){ if(mgbeg == 0 || mgnext == mgend){ return underflow(); } return T::to_int_type(*gptr()); } template typename basic_streambuf::int_type basic_streambuf::sputbackc(char_type c){ if(mgbeg == 0 || mgnext == mgbeg || !T::eq(c, gptr()[-1] )){ return pbackfail(T::to_int_type(c)); } gbump(-1); return T::to_int_type(*gptr()); } template typename basic_streambuf::int_type basic_streambuf::sungetc(){ if(mgbeg == 0 || mgnext == mgbeg){ return ios_base::failbit; } gbump(-1); return T::to_int_type(*gptr()); } template typename basic_streambuf::int_type basic_streambuf::sputc(char_type c){ if(openedFor & ios_base::app){ seekoff(0, ios_base::end, ios_base::out); } if(mpnext < mpend){ *mpnext = c; ++mpnext; }else{ return overflow( T::to_int_type(c) ); } return T::to_int_type(c); } template basic_streambuf::basic_streambuf() : myLocale(), mgbeg(0), mgnext(0), mgend(0), mpbeg(0), mpnext(0), mpend(0), openedFor(0) { } #ifdef __UCLIBCXX_EXPAND_STREAMBUF_CHAR__ #ifndef __UCLIBCXX_COMPILE_STREAMBUF__ #ifdef __UCLIBCXX_EXPAND_CONSTRUCTORS_DESTRUCTORS__ template <> _UCXXEXPORT streambuf::basic_streambuf(); template <> _UCXXEXPORT streambuf::~basic_streambuf(); #endif //__UCLIBCXX_EXPAND_CONSTRUCTORS_DESTRUCTORS__ template <> _UCXXEXPORT locale streambuf::pubimbue(const locale &loc); template <> _UCXXEXPORT streamsize streambuf::in_avail(); template <> _UCXXEXPORT streambuf::int_type streambuf::sbumpc(); template <> _UCXXEXPORT streambuf::int_type streambuf::snextc(); template <> _UCXXEXPORT streambuf::int_type streambuf::sgetc(); template <> _UCXXEXPORT streambuf::int_type streambuf::sputbackc(char_type c); template <> _UCXXEXPORT streambuf::int_type streambuf::sungetc(); template <> _UCXXEXPORT streambuf::int_type streambuf::sputc(char_type c); #endif #endif } #pragma GCC visibility pop #endif