/* 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) extern "C++" { 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 } // namespace } // extern "C++" #endif