Commit c55d0e0d by Magnus Fromreide Committed by Jason Merrill

* sstream: Backport libstdc++-V3 sstream to V2.

From-SVN: r38000
parent c00996a3
2000-11-24 Magnus Fromreide <magfr@lysator.liu.se>
* sstream: Backport libstdc++-V3 sstream to V2.
2000-10-23 Gabriel Dos Reis <gdr@codesourcery.com> 2000-10-23 Gabriel Dos Reis <gdr@codesourcery.com>
* std/std_valarray.h (valarray::valarray): Use __valarray_copy, * std/std_valarray.h (valarray::valarray): Use __valarray_copy,
......
...@@ -23,13 +23,14 @@ This exception does not however invalidate any other reasons why ...@@ -23,13 +23,14 @@ This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */ the executable file might be covered by the GNU General Public License. */
/* Written by Magnus Fromreide (magfr@lysator.liu.se). */ /* Written by Magnus Fromreide (magfr@lysator.liu.se). */
/* seekoff and ideas for overflow is largely borrowed from libstdc++-v3 */
#ifndef __SSTREAM__ #ifndef __SSTREAM__
#define __SSTREAM__ #define __SSTREAM__
#include <string>
#include <iostream.h> #include <iostream.h>
#include <streambuf.h> #include <streambuf.h>
#include <string>
namespace std namespace std
{ {
...@@ -41,185 +42,302 @@ namespace std ...@@ -41,185 +42,302 @@ namespace std
typedef streampos pos_type; typedef streampos pos_type;
typedef streamoff off_type; typedef streamoff off_type;
explicit stringbuf(int which=ios::in|ios::out) : explicit
streambuf(which), buf(), mode(static_cast<ios::open_mode>(which)), stringbuf(int which=ios::in|ios::out)
rpos(0), bufsize(1) : streambuf(), mode(static_cast<ios::open_mode>(which)),
{ } stream(NULL), stream_len(0)
{
stringbuf_init();
}
explicit stringbuf(const std::string &s, int which=ios::in|ios::out) : explicit
streambuf(which), buf(s), mode(static_cast<ios::open_mode>(which)), stringbuf(const string &str, int which=ios::in|ios::out)
bufsize(1) : streambuf(), mode(static_cast<ios::open_mode>(which)),
stream(NULL), stream_len(0)
{ {
if(mode & ios::in) if (mode & (ios::in|ios::out))
{ {
setg(&defbuf, &defbuf + bufsize, &defbuf + bufsize); stream_len = str.size();
stream = new char_type[stream_len];
str.copy(stream, stream_len);
}
stringbuf_init();
} }
if(mode & ios::out)
virtual
~stringbuf()
{ {
setp(&defbuf, &defbuf + bufsize); delete[] stream;
} }
rpos = (mode & ios::ate ? s.size() : 0);
string
str() const
{
if (pbase() != 0)
return string(stream, pptr()-pbase());
else
return string();
} }
std::string str() const void
str(const string& str)
{ {
const_cast<stringbuf*>(this)->sync(); // Sigh, really ugly hack delete[] stream;
return buf; stream_len = str.size();
}; stream = new char_type[stream_len];
str.copy(stream, stream_len);
stringbuf_init();
}
protected:
// The buffer is already in gptr, so if it ends then it is out of data.
virtual int
underflow()
{
return EOF;
}
void str(const std::string& s) virtual int
overflow(int c = EOF)
{
int res;
if (mode & ios::out)
{ {
buf = s; if (c != EOF)
if(mode & ios::in)
{ {
gbump(egptr() - gptr()); streamsize old_stream_len = stream_len;
stream_len += 1;
char_type* new_stream = new char_type[stream_len];
memcpy(new_stream, stream, old_stream_len);
delete[] stream;
stream = new_stream;
stringbuf_sync(gptr()-eback(), pptr()-pbase());
sputc(c);
res = c;
}
else
res = EOF;
}
else
res = 0;
return res;
} }
if(mode & ios::out)
virtual streambuf*
setbuf(char_type* s, streamsize n)
{
if (n != 0)
{ {
pbump(pbase() - pptr()); delete[] stream;
stream = new char_type[n];
memcpy(stream, s, n);
stream_len = n;
stringbuf_sync(0, 0);
} }
rpos = (mode & ios::ate ? s.size() : 0); return this;
} }
protected: virtual pos_type
inline virtual int sync(); seekoff(off_type off, ios::seek_dir way, int which = ios::in | ios::out)
inline virtual int overflow(int = EOF); {
inline virtual int underflow(); pos_type ret = pos_type(off_type(-1));
private: bool testin = which & ios::in && mode & ios::in;
std::string buf; bool testout = which & ios::out && mode & ios::out;
ios::open_mode mode; bool testboth = testin && testout && way != ios::cur;
std::string::size_type rpos;
streamsize bufsize;
char defbuf;
};
class stringstreambase : virtual public ios { if (stream_len && ((testin != testout) || testboth))
protected:
stringbuf __my_sb;
public:
std::string str() const
{ {
return dynamic_cast<stringbuf*>(_strbuf)->str(); char_type* beg = stream;
char_type* curi = NULL;
char_type* curo = NULL;
char_type* endi = NULL;
char_type* endo = NULL;
if (testin)
{
curi = gptr();
endi = egptr();
} }
void str(const std::string& s) if (testout)
{ {
clear(); curo = pptr();
dynamic_cast<stringbuf*>(_strbuf)->str(s); endo = epptr();
} }
stringbuf* rdbuf() off_type newoffi = 0;
off_type newoffo = 0;
if (way == ios::beg)
{ {
return &__my_sb; newoffi = beg - curi;
newoffo = beg - curo;
} }
protected: else if (way == ios::end)
stringstreambase(int which) :
__my_sb(which)
{ {
init (&__my_sb); newoffi = endi - curi;
newoffo = endo - curo;
} }
stringstreambase(const std::string& s, int which) : if (testin && newoffi + off + curi - beg >= 0 &&
__my_sb(s, which) endi - beg >= newoffi + off + curi - beg)
{ {
init (&__my_sb); gbump(newoffi + off);
ret = pos_type(newoffi + off + curi);
}
if (testout && newoffo + off + curo - beg >= 0 &&
endo - beg >= newoffo + off + curo - beg)
{
pbump(newoffo + off);
ret = pos_type(newoffo + off + curo);
}
}
return ret;
} }
};
class istringstream : public stringstreambase, public istream { virtual pos_type
public: seekpos(pos_type sp, int which = ios::in | ios::out)
istringstream(int which=ios::in) : {
stringstreambase(which) pos_type ret = seekoff(sp, ios::beg, which);
{ } return ret;
}
istringstream(const std::string& s, int which=ios::in) : private:
stringstreambase(s, which) void
{ } stringbuf_sync(streamsize i, streamsize o)
{
if (mode & ios::in)
setg(stream, stream + i, stream + stream_len);
if (mode & ios::out)
{
setp(stream, stream + stream_len);
pbump(o);
}
}
void
stringbuf_init()
{
if (mode & ios::ate)
stringbuf_sync(0, stream_len);
else
stringbuf_sync(0, 0);
}
private:
ios::open_mode mode;
char_type* stream;
streamsize stream_len;
}; };
class ostringstream : public stringstreambase, public ostream { class istringstream : public istream {
public: public:
ostringstream(int which=ios::out) : typedef char char_type;
stringstreambase(which) typedef int int_type;
typedef streampos pos_type;
typedef streamoff off_type;
explicit
istringstream(int which=ios::in)
: istream(&sb), sb(which | ios::in)
{ } { }
ostringstream(const std::string& s, int which=ios::out) : explicit
stringstreambase(s, which) istringstream(const string& str, int which=ios::in)
: istream(&sb), sb(str, which | ios::in)
{ } { }
stringbuf*
rdbuf() const
{
return const_cast<stringbuf*>(&sb);
}
string
str() const
{
return rdbuf()->str();
}
void
str(const string& s)
{
rdbuf()->str(s);
}
private:
stringbuf sb;
}; };
class stringstream : public stringstreambase, public iostream { class ostringstream : public ostream {
public: public:
stringstream(int which=ios::in|ios::out) : typedef char char_type;
stringstreambase(which) typedef int int_type;
typedef streampos pos_type;
typedef streamoff off_type;
explicit
ostringstream(int which=ios::out)
: ostream(&sb), sb(which | ios::out)
{ } { }
stringstream(const std::string &s, int which=ios::in|ios::out) : explicit
stringstreambase(s, which) ostringstream(const string& str, int which=ios::out)
: ostream(&sb), sb(str, which | ios::out)
{ } { }
};
}
inline int std::stringbuf::sync() stringbuf*
{ rdbuf() const
if((mode & ios::out) == 0) {
return EOF; return const_cast<stringbuf*>(&sb);
}
streamsize n = pptr() - pbase(); string
if(n) str() const
{ {
buf.replace(rpos, std::string::npos, pbase(), n); return rdbuf()->str();
if(buf.size() - rpos != n)
return EOF;
rpos += n;
pbump(-n);
gbump(egptr() - gptr());
} }
return 0;
}
inline int std::stringbuf::overflow(int ch) void str(const string& s)
{ {
if((mode & ios::out) == 0) rdbuf()->str(s);
return EOF; }
private:
stringbuf sb;
};
streamsize n = pptr() - pbase(); class stringstream : public iostream {
public:
typedef char char_type;
typedef int int_type;
typedef streampos pos_type;
typedef streamoff off_type;
if(n && sync()) explicit
return EOF; stringstream(int which=ios::out|ios::in)
: iostream(&sb), sb(which)
{ }
if(ch != EOF) explicit
{ stringstream(const string& str, int which=ios::out|ios::in)
std::string::size_type oldSize = buf.size(); : iostream(&sb), sb(str, which)
{ }
buf.replace(rpos, std::string::npos, ch); stringbuf*
if(buf.size() - oldSize != 1) rdbuf() const
return EOF; {
++rpos; return const_cast<stringbuf*>(&sb);
} }
return 0;
}
inline int std::stringbuf::underflow() string
{ str() const
sync();
if((mode & ios::in) == 0)
{ {
return EOF; return rdbuf()->str();
} }
if(rpos >= buf.size())
void
str(const string& s)
{ {
return EOF; rdbuf()->str(s);
} }
private:
std::string::size_type n = egptr() - eback(); stringbuf sb;
std::string::size_type s; };
};
s = buf.copy(eback(), n, rpos);
pbump(pbase() - pptr());
gbump(eback() - gptr());
int res = (0377 & buf[rpos]);
rpos += s;
return res;
}
#endif /* not __STRSTREAM__ */ #endif /* not __STRSTREAM__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment