/* 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 #ifndef HEADER_STD_SSTREAM #define HEADER_STD_SSTREAM 1 #include #include #include #include #include #include #pragma GCC visibility push(default) namespace std{ template class _UCXXEXPORT basic_stringbuf : public basic_streambuf { public: 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 typename Allocator::size_type size_type; explicit _UCXXEXPORT basic_stringbuf(ios_base::openmode which = ios_base::in | ios_base::out) : data(), ielement(0), oelement(0) { basic_streambuf::openedFor = which; } explicit _UCXXEXPORT basic_stringbuf(const basic_string& str, ios_base::openmode which = ios_base::in | ios_base::out) : data(str), ielement(0), oelement(0) { if(which & ios_base::ate){ oelement = data.length(); } basic_streambuf::openedFor = which; } virtual _UCXXEXPORT ~basic_stringbuf() { } _UCXXEXPORT basic_string str() const{ return data; } _UCXXEXPORT void str(const basic_string& s){ data = s; ielement = 0; if(basic_streambuf::openedFor & ios_base::ate){ oelement = data.length(); }else{ oelement = 0; } } protected: virtual _UCXXEXPORT int sync(){ return 0; } virtual _UCXXEXPORT int_type underflow(){ if(ielement >= data.length()){ return traits::eof(); } return traits::to_int_type(data[ielement]); } virtual _UCXXEXPORT int_type uflow(){ int_type retval = underflow(); if(retval != traits::eof()){ ++ielement; } return retval; } virtual _UCXXEXPORT int_type pbackfail(int_type c = traits::eof()){ //Error possibilities if(ielement == 0){ return traits::eof(); } if(ielement > data.length()){ ielement = data.length(); return traits::eof(); } //eof passed in if(traits::eq_int_type(c,traits::eof())==true){ --ielement; return traits::not_eof(c); } if(traits::eq(traits::to_char_type(c),data[ielement-1]) == true){ --ielement; return c; } if(basic_streambuf::openedFor & ios_base::out){ --ielement; data[ielement] = c; return c; } return traits::eof(); } virtual _UCXXEXPORT int showmanyc(){ return data.length() - ielement; } virtual _UCXXEXPORT streamsize xsgetn(char_type* c, streamsize n){ streamsize i = 0; while(ielement < data.length() && i < n ){ c[i] = data[ielement]; ++i; ++ielement; } return i; } virtual _UCXXEXPORT int_type overflow (int_type c = traits::eof()){ //Nothing to do if(traits::eq_int_type(c,traits::eof())){ return traits::not_eof(c); } //Actually add character, if possible if(basic_streambuf::openedFor & ios_base::out){ if(oelement >= data.length()){ data.push_back(c); }else{ data[oelement] = c; } ++oelement; return c; } //Not possible return traits::eof(); } virtual _UCXXEXPORT basic_streambuf* setbuf(charT*, streamsize){ //This function does nothing return this; } virtual _UCXXEXPORT streamsize xsputn(const char_type* s, streamsize n){ data.replace(oelement, n, s, n); oelement += n; return n; } virtual _UCXXEXPORT pos_type seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out) { //Test for invalid option if( (which & ios_base::in) && (which & ios_base::out) && (way == ios_base::cur)){ return -1; } //Calculate new location size_type newpos = 0; if(way == ios_base::beg){ newpos = off; }else if(way == ios_base::cur){ if(which & ios_base::out){ newpos = data.length() + off; } if(which & ios_base::in){ newpos = ielement + off; } }else{ newpos = data.length() + off; } //Test for error conditions if(newpos > data.length()){ return -1; } //Shuffle pointers if(which & ios_base::in){ ielement = newpos; } if(which & ios_base::out){ data.resize(newpos); if(ielement > data.length()){ ielement = data.length(); } } return newpos; } virtual _UCXXEXPORT pos_type seekpos(pos_type sp, ios_base::openmode which = ios_base::in | ios_base::out) { return seekoff(sp, ios_base::beg, which); } basic_string data; size_type ielement; size_type oelement; }; template class _UCXXEXPORT basic_istringstream : public basic_istream { public: 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; explicit _UCXXEXPORT basic_istringstream(ios_base::openmode m = ios_base::in) : basic_ios(&sb), basic_istream(&sb), sb(m) { } explicit _UCXXEXPORT basic_istringstream( const basic_string& str, ios_base::openmode which = ios_base::in) : basic_ios(&sb), basic_istream(&sb), sb(str, which) { } virtual _UCXXEXPORT ~basic_istringstream() { } _UCXXEXPORT basic_stringbuf* rdbuf() const{ return &sb; } _UCXXEXPORT basic_string str() const{ return sb.str(); } _UCXXEXPORT void str(const basic_string& s){ sb.str(s); basic_istream::clear(); } private: basic_stringbuf sb; }; template class _UCXXEXPORT basic_ostringstream : public basic_ostream { public: 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; explicit _UCXXEXPORT basic_ostringstream(ios_base::openmode m = ios_base::out) : basic_ios(&sb), basic_ostream(&sb), sb(m) { } explicit _UCXXEXPORT basic_ostringstream(const basic_string& str, ios_base::openmode which = ios_base::out) : basic_ios(&sb), basic_ostream(&sb), sb(str, which) { } virtual _UCXXEXPORT ~basic_ostringstream() { } _UCXXEXPORT basic_stringbuf* rdbuf() const{ return &sb; } _UCXXEXPORT basic_string str() const{ return sb.str(); } _UCXXEXPORT void str(const basic_string& s){ sb.str(s); basic_ostream::clear(); } private: basic_stringbuf sb; }; template class _UCXXEXPORT basic_stringstream : public basic_iostream { public: 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; explicit _UCXXEXPORT basic_stringstream(ios_base::openmode which = ios_base::out|ios_base::in) : basic_ios(&sb), basic_iostream(&sb), sb(which) { } explicit _UCXXEXPORT basic_stringstream(const basic_string& str, ios_base::openmode which = ios_base::out|ios_base::in) : basic_ios(&sb), basic_iostream(&sb), sb(str, which) { } virtual _UCXXEXPORT ~basic_stringstream(){ } _UCXXEXPORT basic_stringbuf* rdbuf(){ return &sb; } _UCXXEXPORT basic_string str() const{ return sb.str(); } _UCXXEXPORT void str(const basic_string& s){ sb.str(s); basic_iostream::clear(); } private: basic_stringbuf sb; }; #ifdef __UCLIBCXX_EXPAND_SSTREAM_CHAR__ #ifndef __UCLIBCXX_COMPILE_SSTREAM__ #ifdef __UCLIBCXX_EXPAND_CONSTRUCTORS_DESTRUCTORS__ template <> _UCXXEXPORT basic_stringbuf, allocator >:: basic_stringbuf(ios_base::openmode which); template <> _UCXXEXPORT basic_stringbuf, allocator >::~basic_stringbuf(); #endif // __UCLIBCXX_EXPAND_CONSTRUCTORS_DESTRUCTORS__ template <> _UCXXEXPORT basic_string, allocator > basic_stringbuf, allocator >::str() const; template <> _UCXXEXPORT basic_stringbuf, allocator >::int_type basic_stringbuf, allocator >:: pbackfail(basic_stringbuf, allocator >::int_type c); template <> _UCXXEXPORT basic_stringbuf, allocator >::pos_type basic_stringbuf, allocator >:: seekoff (basic_stringbuf, allocator >::off_type off, ios_base::seekdir way, ios_base::openmode which ); template <> _UCXXEXPORT basic_stringbuf, allocator >::int_type basic_stringbuf, allocator >:: overflow (basic_stringbuf, allocator >::int_type c); template <> _UCXXEXPORT basic_stringbuf, allocator >::int_type basic_stringbuf, allocator >::underflow (); template <> _UCXXEXPORT streamsize basic_stringbuf, allocator >:: xsputn(const char* s, streamsize n); #ifdef __UCLIBCXX_EXPAND_CONSTRUCTORS_DESTRUCTORS__ template <> _UCXXEXPORT basic_stringstream, allocator >:: basic_stringstream(ios_base::openmode which); template <> _UCXXEXPORT basic_stringstream, allocator >::~basic_stringstream(); template <> _UCXXEXPORT basic_istringstream, allocator >::~basic_istringstream(); template <> _UCXXEXPORT basic_ostringstream, allocator >::~basic_ostringstream(); #endif //__UCLIBCXX_EXPAND_CONSTRUCTORS_DESTRUCTORS__ #endif #endif #pragma GCC visibility pop } #endif