/** -*- 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_STREAMBUF #define __KAI_STREAMBUF #include #include namespace std { template class basic_streambuf { public: // Types 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; virtual ~basic_streambuf(); // 27.5.2.2.1 Locales: inline locale pubimbue(const locale &); inline locale getloc() const; // 27.5.2.2.2 buffers and positioning: inline basic_streambuf * pubsetbuf(char_type *, streamsize); inline pos_type pubseekoff(off_type off, ios_base::seekdir way, ios_base::openmode which=ios_base::in | ios_base::out); inline pos_type pubseekpos(pos_type sp, ios_base::openmode which=ios_base::in | ios_base::out); inline int pubsync(); // Get and Put areas: // 27.5.2.2.3 Get areas: inline streamsize in_avail(); inline int_type snextc(); inline int_type sbumpc(); inline int_type sgetc(); inline streamsize sgetn(char_type *, streamsize); // 27.5.2.2.4 Putback: inline int_type sputbackc(char_type); inline int_type sungetc(); // 27.5.2.2.5 Put areas: inline int_type sputc(charT c); inline streamsize sputn(const charT* , streamsize); protected: basic_streambuf(); // 27.5.2.3.1 Get area: inline char_type* eback() const; inline char_type* gptr() const; inline char_type* egptr() const; inline void gbump(int); inline void setg(char_type * gbeg, char_type *gnext, char_type *gend); // 27.5.2.3.2 Put area: inline char_type* pbase() const; inline char_type* pptr() const; inline char_type* epptr() const; inline void pbump(int); inline void setp(char_type *pbeg, char_type *pend); // 27.5.2.4 Virtual functions: // 27.5.2.4.1 Locales: virtual void imbue(const locale &); #if KAI_NONSTD_STREAMBUF public: /* Cfront makes these public */ #endif /* KAI_NONSTD_STREAMBUF */ // 27.5.2.4.2 Buffer management and positioning: virtual basic_streambuf* setbuf(char_type*, streamsize); virtual pos_type seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which=ios_base::in | ios_base::out); virtual pos_type seekpos(pos_type sp, ios_base::openmode which = ios_base::in | ios_base::out); virtual int sync(); protected: // 27.5.2.4.3 Get area: // ISO says: The class summary for basic_streambuf, in 27.5.2, says that showmanyc has // return type int. However, 27.5.2.4.3 says that its return type is streamsize // KAI has decided to resolve in favor of streamsize. virtual streamsize showmanyc(); // s how many c virtual streamsize xsgetn(char_type* s, streamsize n); virtual int_type underflow(); virtual int_type uflow(); // 27.5.2.4.4 Putback: virtual int_type pbackfail(int_type c=traits::eof()); // 27.5.2.4.5 Put area: virtual streamsize xsputn(const charT* s, streamsize n); virtual int_type overflow(int_type c=traits::eof()); // protected data member locale loc; char_type* gbeg; char_type* gnext; char_type* gend; char_type* pbeg; char_type* pnext; char_type* pend; // mutex locks for the get and put area. __KAI_DECL_SHARED_OBJ_LOCK(recursive_mutex,_mutex) #if MSIPL_MULTITHREAD template friend class basic_ios; #endif private: // to be undefined basic_streambuf(const basic_streambuf& rhs); basic_streambuf& operator=(const basic_streambuf& rhs); template friend class basic_ostream; template friend class basic_istream; template friend basic_istream& getline(basic_istream& is, basic_string& str, charT1 delim); }; template inline basic_streambuf::basic_streambuf() { gbeg=gnext=gend=pbeg=pnext=pend=0; loc = locale(); } // 27.5.2.2.1 Locales: template inline locale basic_streambuf::pubimbue(const locale& loc_arg) { locale loc_sav=loc; imbue(loc_arg); return loc_sav; } template inline locale basic_streambuf::getloc() const { return loc; } // 27.5.2.2.2 Buffer management and positioning: template inline basic_streambuf* basic_streambuf:: pubsetbuf(char_type* s, streamsize n) { return setbuf(s, n); } template inline basic_streambuf::pos_type basic_streambuf::pubseekoff(off_type off, ios_base::seekdir way, ios_base::openmode which) { return seekoff(off, way, which); } template inline basic_streambuf::pos_type basic_streambuf::pubseekpos(pos_type sp, ios_base::openmode which) { return seekpos(sp, which); } template inline int basic_streambuf::pubsync() { return sync(); } // 27.5.2.2.3 Get area: template inline streamsize basic_streambuf::in_avail() { return (gnext && gnext inline basic_streambuf::int_type basic_streambuf::snextc() { charT * p = gnext; if( p && p+1 < gend ) { // Make common case run fast. gnext = p+1; return traits::to_int_type(p[1]); } else { // In other cases, follow Standard (27.5.2.2.3) literally. int_type ch = sbumpc(); return traits::eq_int_type(ch, traits::eof()) ? traits::eof() : sgetc(); } } template inline basic_streambuf::int_type basic_streambuf::sbumpc() { return (gnext && gnext < gend ? traits::to_int_type(*gnext++) : uflow()); } template inline basic_streambuf::int_type basic_streambuf::sgetc() { return (gnext && gnext inline streamsize basic_streambuf::sgetn(char_type* s, streamsize n) { return xsgetn(s, n); } // 27.5.2.2.4 Putback: template inline basic_streambuf::int_type basic_streambuf::sputbackc(char_type c) { return ( (gnext && gbeg < gnext && (traits::eq(c, * (gnext-1)))) ? traits::to_int_type(*--gnext) : pbackfail(traits::to_int_type(c))); } template inline basic_streambuf::int_type basic_streambuf::sungetc() { return (gnext && gbeg < gnext ? traits::to_int_type(*--gnext) : pbackfail()); } // 27.5.2.2.5 Put area: template inline basic_streambuf::int_type basic_streambuf::sputc(char_type c) { return (pnext && pnext < pend ? traits::to_int_type(*pnext++=c) :overflow(traits::to_int_type(c))); } template inline streamsize basic_streambuf::sputn(const charT * s, streamsize n) { return xsputn(s, n); } // 27.5.2.3.1 Get area access: template inline charT* basic_streambuf::eback() const { return gbeg; } template inline charT* basic_streambuf::gptr() const { return gnext; } template inline charT* basic_streambuf::egptr() const { return gend; } template inline void basic_streambuf::gbump(int n) { gnext+=n; } template inline void basic_streambuf::setg(char_type* gbeg_arg, char_type* gnext_arg, char_type* gend_arg) { gbeg=gbeg_arg; gnext=gnext_arg; gend=gend_arg; } // 27.5.2.3.2 Put area access: template inline charT* basic_streambuf::pbase() const { return pbeg; } template inline charT* basic_streambuf::pptr() const { return pnext; } template inline charT* basic_streambuf::epptr() const { return pend; } template inline void basic_streambuf::pbump(int n) { pnext+=n; } template inline void basic_streambuf::setp(char_type* pbeg_arg, char_type* pend_arg) { pnext=pbeg=pbeg_arg; pend=pend_arg; } template basic_streambuf::~basic_streambuf() { } // 27.5.2.4.1 Locales: template inline void basic_streambuf::imbue(const locale& locarg) { loc=locarg; //Virtual Func. Derived classes should take care of this } // 27.5.2.4.2 Buffer management and positioning: // default behaviour template inline basic_streambuf* basic_streambuf::setbuf(char_type*, streamsize) { return this; } // default behaviour assuming this to be an invalid pos_type template inline basic_streambuf::pos_type basic_streambuf::seekoff(off_type, ios_base::seekdir, ios_base::openmode) { return pos_type(-1); } // default behaviour assuming this to be an invalid pos_type template inline basic_streambuf::pos_type basic_streambuf::seekpos(pos_type, ios_base::openmode) { return pos_type(-1); } // default behaviour template inline int basic_streambuf::sync() { return 0; } // 27.5.2.4.3 Get area: // default behaviour template inline streamsize basic_streambuf::showmanyc() { return 0; } template streamsize basic_streambuf::xsgetn(char_type* s, streamsize n) { streamsize nvalue=0; off_type nsize; int_type ch; while (n > 0) { nvalue += (nsize = n>gend-gnext ? gend-gnext : n); n -= nsize; traits::copy(s, gnext, nsize); s += nsize; gnext += nsize; if (n > 0) { if (traits::eq_int_type( (ch = uflow()), traits::eof())) break; else { *s++ = traits::to_char_type(ch); ++nvalue; --n; } } } return nvalue; } // default behaviour template inline basic_streambuf::int_type basic_streambuf::underflow() { return traits::eof(); } // default behaviour template inline basic_streambuf::int_type basic_streambuf::uflow() { // default behaviour if (underflow() == traits::eof()) return traits::eof(); else return traits::to_int_type(*gnext++); } // 27.5.2.4.4 Putback: // default behaviour template inline basic_streambuf::int_type basic_streambuf::pbackfail(int_type) { return traits::eof(); } // 27.5.2.4.5 Put area template streamsize basic_streambuf::xsputn(const charT* s, streamsize n) { streamsize nvalue=0; off_type nsize; while (n > 0) { nsize = (n > pend - pnext ? pend - pnext : n); nvalue += nsize; n -= nsize; traits::copy(pnext, s, nsize); s += nsize; pnext += nsize; if (n > 0) { if (traits::eq_int_type(overflow(traits::to_int_type(*s)), traits::eof())) break; else { ++s; ++nvalue; --n; } } } return nvalue; } // default behaviour template inline basic_streambuf::int_type basic_streambuf::overflow(int_type) { return traits::eof(); } typedef basic_streambuf streambuf; #ifdef MSIPL_WCHART typedef basic_streambuf wstreambuf; #endif } // namespace std #endif /* __KAI_STREAMBUF */