/** -*- C++ -*- ** ** KAI C++ Compiler ** ** Copyright (C) 1996-2001 Intel Corp. All rights reserved. **/ /** ** Lib++ : The Modena C++ Standard Library, ** Version 2.4, October 1997 ** ** Copyright (c) 1995-1997 Modena Software Inc. **/ #ifndef __KAI_SSTREAM #define __KAI_SSTREAM #include #include /* KAI change - Modena included overly-wide */ namespace std { template class basic_stringbuf : public basic_streambuf { static const ios_base::openmode mode_in_out = ios_base::in|ios_base::out; typedef basic_string string_type; 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 traits traits_type; // 27.7.1.1 Constructors: explicit basic_stringbuf(ios_base::openmode which = mode_in_out); explicit basic_stringbuf(const string_type& str, ios_base::openmode which = mode_in_out); virtual ~basic_stringbuf(); // 27.7.1.2 Get and set: string_type str() const; void str(const string_type& str_arg); protected: // 27.7.1.3 Overridden virtual functions: virtual int_type underflow(); virtual int_type pbackfail(int_type c = traits::eof()); virtual int_type overflow(int_type c = traits::eof()); virtual basic_streambuf* setbuf(charT*, streamsize); virtual pos_type seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = mode_in_out); virtual pos_type seekpos(pos_type sp, ios_base::openmode which = mode_in_out); private: ios_base::openmode mode; void init_string(const char_type* str, streamsize len, streamsize res); void init_copy(char_type* to, const char_type* from, streamsize len, streamsize res); void clean_string(); char_type* bend; // To keep track of the buffer end enum {inc_size = 64}; }; template class basic_istringstream : public basic_istream { typedef basic_string string_type; public: typedef charT char_type; typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; typedef typename traits::int_type int_type; typedef traits traits_type; typedef basic_stringbuf sb_type; explicit basic_istringstream(ios_base::openmode which = ios_base::in); explicit basic_istringstream(const string_type& str, ios_base::openmode which = ios_base::in); virtual ~basic_istringstream(); sb_type* rdbuf() const { return (sb_type*)&sbuf; } inline string_type str() const { return sbuf.str(); } inline void str(const string_type& str_arg) { sbuf.str(str_arg); } private: sb_type sbuf; }; template class basic_ostringstream : public basic_ostream { typedef basic_string string_type; public: typedef charT char_type; typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; typedef typename traits::int_type int_type; typedef traits traits_type; typedef basic_stringbuf sb_type; explicit basic_ostringstream(ios_base::openmode which = ios_base::out); explicit basic_ostringstream(const string_type& str, ios_base::openmode which = ios_base::out); virtual ~basic_ostringstream(); sb_type* rdbuf() const { return (sb_type*)&sbuf; } inline string_type str() const { return sbuf.str(); } inline void str(const string_type& str_arg) { sbuf.str(str_arg); } private: sb_type sbuf; }; template class basic_stringstream : public basic_iostream { static const ios_base::openmode mode_in_out = ios_base::in|ios_base::out; typedef basic_string string_type; public: typedef charT char_type; typedef typename traits::pos_type pos_type; typedef typename traits::off_type off_type; typedef typename traits::int_type int_type; typedef traits traits_type; typedef basic_stringbuf sb_type; explicit basic_stringstream(ios_base::openmode which = mode_in_out); explicit basic_stringstream(const string_type& str, ios_base::openmode which = mode_in_out); virtual ~basic_stringstream(); sb_type* rdbuf() const { return (sb_type*)&sbuf; } inline string_type str() const { return sbuf.str(); } inline void str(const string_type& str_arg) { sbuf.str(str_arg); } private: sb_type sbuf; }; template basic_stringbuf::basic_stringbuf(ios_base::openmode which) : basic_streambuf(), mode(which), bend(0) { } template basic_stringbuf::basic_stringbuf(const string_type& str, ios_base::openmode which) : basic_streambuf(), mode(which) { if (str.size() != 0) init_string(str.data(), str.size(), (str.size() / inc_size + 1) * inc_size); else bend = 0; } template inline void basic_stringbuf:: init_string(const char_type* str, streamsize len, streamsize res) { char_type* tmp = new char_type[res]; init_copy(tmp, str, len, res); } template void basic_stringbuf::init_copy(char_type* to, const char_type* from, streamsize len, streamsize res) { traits::copy(to, from, len); if (mode & ios_base::in) gbeg = gnext = to, gend = to + len; if (mode & ios_base::out) { pbeg=pnext=to; pend=to+len; // CHECK pnext=pend // dcn: Must check if appending if (mode&ios_base::app) pnext=pend; } bend = to + res; } template void basic_stringbuf::clean_string() { if (gnext) delete[] gbeg; else if (pnext) delete[] pbeg; gbeg = gnext = gend = pbeg = pnext = pend = bend = 0; } template basic_stringbuf::~basic_stringbuf() { if (gnext) delete[] gbeg; else if (pnext) delete[] pbeg; } template basic_stringbuf::string_type basic_stringbuf::str() const { // The string should include all of the input or output sequence. const charT *first, *last; if ((mode & mode_in_out) == ios_base::in) { first = gbeg; last = gend; } else { first = pbeg; last = pend; } // Code written to exploit return-slot optimization. string_type result; if( first ) { result.assign( first, last ); } return result; } template void basic_stringbuf::str(const string_type& str) { streamsize len = 0; char_type* tmp = 0; if (mode & ios_base::out) tmp = pbeg; else if (mode & ios_base::in) tmp = gbeg; len = bend - tmp; if (str.size() != 0) { if ( (str.size() > len) || !tmp) { clean_string(); init_string(str.data(), str.size(), ((str.size() / inc_size + 1) * inc_size)); } else init_copy(tmp, str.data(), str.size(), len); } else clean_string(); } template inline basic_streambuf* basic_stringbuf::setbuf(charT*, streamsize) { return this; } template inline basic_stringbuf:: int_type basic_stringbuf::underflow() { return (gnext && mode&ios_base::out && gnext >= gend && pnext > gend) ? gend=pnext, traits::to_int_type(*gnext) : traits::eof(); } template inline basic_stringbuf:: int_type basic_stringbuf::pbackfail(int_type c) { if (gnext && gbeg < gnext) { if (traits::eq_int_type(c, traits::eof())) { --gnext; return traits::not_eof(c); } else if (mode & ios_base::out) { --gnext; return *gnext=traits::to_char_type(c); } else if (traits::eq_int_type(c, traits::to_int_type(gnext[-1]))) { --gnext; return c; } } return traits::eof(); } template inline basic_stringbuf::int_type basic_stringbuf::overflow(int_type c) { if (traits::eq_int_type(c, traits::eof())) return traits::not_eof(c); if (mode & ios_base::out) { if (pend < bend) pend++; else { streamsize gsize = gnext - gbeg; streamsize psize = pnext - pbeg; size_t nsize = (psize / inc_size + 1) * inc_size; char_type* tmp = new char_type[nsize]; traits::copy(tmp, pbeg, psize); clean_string(); pbeg = tmp; pnext = pbeg + psize; pend = pnext + 1; bend = tmp + nsize; if (mode & ios_base::in) { gbeg = tmp; gnext = gbeg + gsize; } } *pnext = traits::to_char_type(c); ++pnext; if (mode & ios_base::in) gend = pnext; return c; } return traits::eof(); } template inline basic_stringbuf::pos_type basic_stringbuf::seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which) { off_type newoff = -1; if ((which & mode_in_out) == mode_in_out) { if (!gbeg || !pbeg) return pos_type(-1); switch (way) { case ios_base::beg: newoff = 0; break; case ios_base::end: newoff = pend-pbeg; break; default: return pos_type(-1); } if (newoff + off < 0 || newoff + off > pend - pbeg) return pos_type(-1); newoff += off; pnext = gnext = pbeg + newoff; if (gend < gnext) gend = gnext; } else if (which & ios_base::in && gbeg) { switch (way) { case ios_base::beg: newoff = 0; break; case ios_base::end: newoff = gend-gbeg; break; case ios_base::cur: newoff = gnext-gbeg; break; default: return pos_type(-1); } if (newoff+off < 0 || newoff+off > gend-gbeg) return pos_type(-1); newoff += off; gnext = gbeg + newoff; } else if (which & ios_base::out && pbeg) { switch (way) { case ios_base::beg: newoff = 0; break; case ios_base::end: newoff = pend-pbeg; break; case ios_base::cur: newoff = pnext-pbeg; break; default: return pos_type(-1); } if (newoff+off < 0 || newoff+off > pend-pbeg) return pos_type(-1); newoff += off; pnext = pbeg + newoff; } return pos_type(newoff); } template basic_stringbuf::pos_type basic_stringbuf::seekpos(pos_type sp, ios_base::openmode which) { off_type ret = -1, newoff = -1; if ((newoff = off_type(sp)) < 0) return pos_type(-1); if (gnext && pnext && gend < pnext) gend = pnext; if (which & ios_base::in && gnext && newoff <= gend-gbeg) gnext = gbeg + (ret = newoff); if (which & ios_base::out && pnext && newoff <= pend-pbeg) pnext = pbeg + (ret = newoff); return pos_type(ret); } // 27.7.2 Template class basic_istringstream template basic_istringstream::basic_istringstream(ios_base::openmode which) : basic_istream(&sbuf), sbuf(which | in) { init(&sbuf); } template basic_istringstream::basic_istringstream(const string_type& str, ios_base::openmode which) : basic_istream(&sbuf), sbuf(str, which | in) { init(&sbuf); } template basic_istringstream::~basic_istringstream() { } // 27.7.3 Template class basic_ostringstream template basic_ostringstream::basic_ostringstream(ios_base::openmode which) : basic_ostream(&sbuf), sbuf(which | out) { init(&sbuf); } template basic_ostringstream::basic_ostringstream(const string_type& str, ios_base::openmode which) : basic_ostream(&sbuf), sbuf(str, which | out) { init(&sbuf); } template basic_ostringstream::~basic_ostringstream() { } // 27.7.4 Template class basic_stringstream template basic_stringstream::basic_stringstream(ios_base::openmode which) : basic_iostream(&sbuf), sbuf(which) { init(&sbuf); } template basic_stringstream::basic_stringstream(const string_type& str, ios_base::openmode which) : basic_iostream(&sbuf), sbuf(str, which) { init(&sbuf); } template basic_stringstream::~basic_stringstream() { } typedef basic_stringbuf, allocator > stringbuf; typedef basic_istringstream, allocator > istringstream; typedef basic_ostringstream, allocator > ostringstream; typedef basic_stringstream, allocator > stringstream; #ifdef MSIPL_WCHART typedef basic_stringbuf, allocator > wstringbuf; typedef basic_istringstream, allocator > wistringstream; typedef basic_ostringstream, allocator > wostringstream; typedef basic_stringstream, allocator > wstringstream; #endif } // namespace std #endif /* __KAI_SSTREAM */