+/* This is part of libio/iostream, providing -*- C++ -*- input/output.\r
+Copyright (C) 2000 Free Software Foundation\r
+\r
+This file is part of the GNU IO Library. This library is free\r
+software; you can redistribute it and/or modify it under the\r
+terms of the GNU General Public License as published by the\r
+Free Software Foundation; either version 2, or (at your option)\r
+any later version.\r
+\r
+This library is distributed in the hope that it will be useful,\r
+but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+GNU General Public License for more details.\r
+\r
+You should have received a copy of the GNU General Public License\r
+along with this library; see the file COPYING. If not, write to the Free\r
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\r
+\r
+As a special exception, if you link this library with files\r
+compiled with a GNU compiler to produce an executable, this does not cause\r
+the resulting executable to be covered by the GNU General Public License.\r
+This exception does not however invalidate any other reasons why\r
+the executable file might be covered by the GNU General Public License. */\r
+\r
+/* Written by Magnus Fromreide (magfr@lysator.liu.se). */\r
+\r
+#ifndef __SSTREAM__\r
+#define __SSTREAM__\r
+\r
+#include <string>\r
+#include <iostream.h>\r
+#include <streambuf.h>\r
+\r
+namespace std\r
+{\r
+ class stringbuf : public streambuf\r
+ {\r
+ public:\r
+ typedef char char_type;\r
+ typedef int int_type;\r
+ typedef streampos pos_type;\r
+ typedef streamoff off_type;\r
+\r
+ explicit stringbuf(int which=ios::in|ios::out) :\r
+ streambuf(which), buf(), mode(static_cast<ios::open_mode>(which)),\r
+ rpos(0), bufsize(1)\r
+ { }\r
+ \r
+ explicit stringbuf(const std::string &s, int which=ios::in|ios::out) :\r
+ streambuf(which), buf(s), mode(static_cast<ios::open_mode>(which)),\r
+ bufsize(1)\r
+ {\r
+ if(mode & ios::in)\r
+ {\r
+ setg(&defbuf, &defbuf + bufsize, &defbuf + bufsize);\r
+ }\r
+ if(mode & ios::out)\r
+ {\r
+ setp(&defbuf, &defbuf + bufsize);\r
+ }\r
+ rpos = (mode & ios::ate ? s.size() : 0);\r
+ }\r
+ \r
+ std::string str() const\r
+ {\r
+ const_cast<stringbuf*>(this)->sync(); // Sigh, really ugly hack\r
+ return buf;\r
+ };\r
+\r
+ void str(const std::string& s)\r
+ {\r
+ buf = s;\r
+ if(mode & ios::in)\r
+ {\r
+ gbump(egptr() - gptr());\r
+ }\r
+ if(mode & ios::out)\r
+ {\r
+ pbump(pbase() - pptr());\r
+ }\r
+ rpos = (mode & ios::ate ? s.size() : 0);\r
+ }\r
+\r
+ protected:\r
+ inline virtual int sync();\r
+ inline virtual int overflow(int = EOF);\r
+ inline virtual int underflow();\r
+ private:\r
+ std::string buf;\r
+ ios::open_mode mode;\r
+ std::string::size_type rpos;\r
+ streamsize bufsize;\r
+ char defbuf;\r
+ };\r
+\r
+ class stringstreambase : virtual public ios {\r
+ protected:\r
+ stringbuf __my_sb;\r
+ public:\r
+ std::string str() const\r
+ {\r
+ return dynamic_cast<stringbuf*>(_strbuf)->str();\r
+ }\r
+ void str(const std::string& s)\r
+ {\r
+ clear();\r
+ dynamic_cast<stringbuf*>(_strbuf)->str(s);\r
+ }\r
+ \r
+ stringbuf* rdbuf()\r
+ {\r
+ return &__my_sb;\r
+ }\r
+ protected:\r
+ stringstreambase(int which) :\r
+ __my_sb(which)\r
+ {\r
+ init (&__my_sb);\r
+ }\r
+ \r
+ stringstreambase(const std::string& s, int which) :\r
+ __my_sb(s, which)\r
+ {\r
+ init (&__my_sb);\r
+ }\r
+ };\r
+ \r
+ class istringstream : public stringstreambase, public istream {\r
+ public:\r
+ istringstream(int which=ios::in) :\r
+ stringstreambase(which)\r
+ { }\r
+ \r
+ istringstream(const std::string& s, int which=ios::in) :\r
+ stringstreambase(s, which)\r
+ { }\r
+ };\r
+ \r
+ class ostringstream : public stringstreambase, public ostream {\r
+ public:\r
+ ostringstream(int which=ios::out) :\r
+ stringstreambase(which)\r
+ { }\r
+ \r
+ ostringstream(const std::string& s, int which=ios::out) :\r
+ stringstreambase(s, which)\r
+ { }\r
+ };\r
+ \r
+ class stringstream : public stringstreambase, public iostream {\r
+ public:\r
+ stringstream(int which=ios::in|ios::out) :\r
+ stringstreambase(which)\r
+ { }\r
+ \r
+ stringstream(const std::string &s, int which=ios::in|ios::out) :\r
+ stringstreambase(s, which)\r
+ { }\r
+ };\r
+}\r
+\r
+inline int std::stringbuf::sync()\r
+{\r
+ if((mode & ios::out) == 0)\r
+ return EOF;\r
+\r
+ streamsize n = pptr() - pbase();\r
+ if(n)\r
+ {\r
+ buf.replace(rpos, std::string::npos, pbase(), n);\r
+ if(buf.size() - rpos != n)\r
+ return EOF;\r
+ rpos += n;\r
+ pbump(-n);\r
+ gbump(egptr() - gptr());\r
+ }\r
+ return 0;\r
+}\r
+\r
+inline int std::stringbuf::overflow(int ch)\r
+{\r
+ if((mode & ios::out) == 0)\r
+ return EOF;\r
+\r
+ streamsize n = pptr() - pbase();\r
+\r
+ if(n && sync())\r
+ return EOF;\r
+\r
+ if(ch != EOF)\r
+ {\r
+ std::string::size_type oldSize = buf.size();\r
+ \r
+ buf.replace(rpos, std::string::npos, ch);\r
+ if(buf.size() - oldSize != 1)\r
+ return EOF;\r
+ ++rpos;\r
+ }\r
+ return 0;\r
+}\r
+\r
+inline int std::stringbuf::underflow()\r
+{\r
+ sync();\r
+ if((mode & ios::in) == 0)\r
+ {\r
+ return EOF;\r
+ }\r
+ if(rpos >= buf.size())\r
+ {\r
+ return EOF;\r
+ }\r
+ \r
+ std::string::size_type n = egptr() - eback();\r
+ std::string::size_type s;\r
+\r
+ s = buf.copy(eback(), n, rpos);\r
+ pbump(pbase() - pptr());\r
+ gbump(eback() - gptr());\r
+ int res = (0377 & buf[rpos]);\r
+ rpos += s;\r
+ return res;\r
+}\r
+\r
+#endif /* not __STRSTREAM__ */\r