Author: sebor
Date: Sun Mar 19 17:27:18 2006
New Revision: 387098
URL: http://svn.apache.org/viewcvs?rev=387098&view=rev
Log:
2006-03-19 Martin Sebor <[EMAIL PROTECTED]>
STDCXX-3
* rw_streambuf.h: New header. Defines a test streambuf class template.
Added:
incubator/stdcxx/trunk/tests/include/rw_streambuf.h (with props)
Added: incubator/stdcxx/trunk/tests/include/rw_streambuf.h
URL:
http://svn.apache.org/viewcvs/incubator/stdcxx/trunk/tests/include/rw_streambuf.h?rev=387098&view=auto
==============================================================================
--- incubator/stdcxx/trunk/tests/include/rw_streambuf.h (added)
+++ incubator/stdcxx/trunk/tests/include/rw_streambuf.h Sun Mar 19 17:27:18 2006
@@ -0,0 +1,472 @@
+/************************************************************************
+ *
+ * rw_streambuf.h - definition of the MyStreambuf class template
+ *
+ * $Id$
+ *
+ ***************************************************************************
+ *
+ * Copyright 2006 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Copyright 2004-2006 Rogue Wave Software.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ **************************************************************************/
+
+#ifndef RW_STREAMBUF_H_INCLUDED
+#define RW_STREAMBUF_H_INCLUDED
+
+
+#include <cstring> // for memset()
+#include <streambuf> // for basic_streambuf
+
+#include <testdefs.h>
+
+
+enum MemFun {
+ // bitmask with a bit for each virtual member function
+ None = 0,
+ Setbuf = 0x0001,
+ Seekoff = 0x0002,
+ Seekpos = 0x0004,
+ Showmanyc = 0x0008,
+ Xsgetn = 0x0010,
+ Underflow = 0x0020,
+ Uflow = 0x0040,
+ Overflow = 0x0080,
+ Pbackfail = 0x0100,
+ Xsputn = 0x0200,
+ Sync = 0x0400,
+ // bit OR-ed with MemFun bits
+ Throw = 0x1000,
+ Failure = 0x2000,
+ Unknown = 0x4000
+};
+
+
+template <class charT, class Traits>
+struct MyStreambuf: std::basic_streambuf<charT, Traits>
+{
+ typedef charT char_type;
+ typedef Traits traits_type;
+ typedef std::basic_streambuf<char_type, traits_type> Base;
+ typedef typename Base::int_type int_type;
+ typedef typename Base::off_type off_type;
+ typedef typename Base::pos_type pos_type;
+
+ MyStreambuf (std::streamsize, int, int);
+
+ MyStreambuf (const char*, std::streamsize, int, int);
+
+ ~MyStreambuf () {
+ delete[] buf_;
+ }
+
+ // public interface to base class protected members
+ char_type* pubeback () const {
+ return this->eback ();
+ }
+
+ char_type* pubgptr () const {
+ return this->gptr ();
+ }
+
+ char_type* pubegptr () const {
+ return this->egptr ();
+ }
+
+ char_type* pubpbase () const {
+ return this->pbase ();
+ }
+
+ char_type* pubpptr () const {
+ return this->pptr ();
+ }
+
+ char_type* pubepptr () const {
+ return this->epptr ();
+ }
+
+ void pubsetg (charT *beg, charT *cur, charT *end) {
+ this->setg (beg, cur, end);
+ }
+
+ void pubsetp (charT *beg, charT *cur, charT *end) {
+ this->setp (beg, end);
+ this->pbump (cur - beg);
+ }
+
+private:
+
+ // overridden protected virtual functions
+ virtual Base* setbuf (char_type*, std::streamsize) {
+ return test (Setbuf) ? this : 0;
+ }
+
+ virtual pos_type
+ seekoff (off_type, std::ios_base::seekdir, std::ios_base::openmode) {
+ test (Seekoff);
+ return pos_type (off_type (-1));
+ }
+
+ virtual pos_type
+ seekpos (pos_type, std::ios_base::openmode) {
+ test (Seekpos);
+ return pos_type (off_type (-1));
+ }
+
+ virtual std::streamsize showmanyc () {
+ test (Showmanyc);
+ return 0;
+ }
+
+ virtual std::streamsize xsgetn (char_type*, std::streamsize) {
+ test (Xsgetn);
+ return 0;
+ }
+
+ virtual int_type underflow ();
+
+ virtual int_type uflow ();
+
+ virtual int_type
+ overflow (int_type = traits_type::eof ());
+
+ virtual int_type
+ pbackfail (int_type = traits_type::eof ());
+
+ virtual std::streamsize
+ xsputn (const char_type *buf, std::streamsize bufsize) {
+ if (!test (Xsputn))
+ return 0;
+ return Base::xsputn (buf, bufsize);
+ }
+
+ virtual int sync () {
+ test (Sync);
+ return 0;
+ }
+
+public:
+
+ int ncalls (MemFun) const;
+
+ char_type *buf_;
+ std::streamsize bufsize_;
+
+ int throw_set_; // functions that should throw
+ int fail_set_; // functions that should fail
+ MemFun threw_; // which function threw
+ MemFun failed_; // which function failed
+
+ int fail_when_; // call number on which to fail
+
+ // max size of the pending input sequence
+ static std::streamsize in_pending_;
+
+ // max size of the pending output sequence
+ static std::streamsize out_pending_;
+
+private:
+
+ bool test (MemFun) const;
+ int ncalls_ [11]; // number of calls made to each function
+};
+
+
+template <class charT, class Traits>
+std::streamsize MyStreambuf<charT, Traits>::
+in_pending_ = 1;
+
+
+template <class charT, class Traits>
+std::streamsize MyStreambuf<charT, Traits>::
+out_pending_ = 1;
+
+
+template <class charT, class Traits>
+MyStreambuf<charT, Traits>::
+MyStreambuf (std::streamsize bufsize, int fail_set, int when)
+ : Base (), buf_ (0), bufsize_ (bufsize),
+ throw_set_ (0), fail_set_ (0), threw_ (None), failed_ (None),
+ fail_when_ (when)
+{
+ // reset the member function call counters
+ std::memset (ncalls_, 0, sizeof ncalls_);
+
+ // allocate a (possibly wide) character buffer for output
+ buf_ = new charT [bufsize_];
+
+ // invalidate the contents of the buffer
+ traits_type::assign (buf_, bufsize_, charT ('\xfe'));
+
+ // set the put area to 0 size to force a call to overflow()
+ // on the first write attempt to the buffer
+ this->setp (buf_, buf_);
+
+ // set the fail and throw flags
+ if (fail_set & Throw) {
+ throw_set_ = fail_set & ~Throw;
+ }
+ else {
+ fail_set_ = fail_set;
+ }
+}
+
+
+template <class charT, class Traits>
+MyStreambuf<charT, Traits>::
+MyStreambuf (const char *buf, std::streamsize bufsize, int fail_set, int when)
+ : Base (), buf_ (0), bufsize_ (bufsize),
+ throw_set_ (0), fail_set_ (0), threw_ (None), failed_ (None),
+ fail_when_ (when)
+{
+ // reset the member function call counters
+ std::memset (ncalls_, 0, sizeof ncalls_);
+
+ // as a convenience, if `bufsize == -1' compute the size
+ // from the length of `buf'
+ if (std::streamsize (-1) == bufsize_)
+ bufsize_ = std::streamsize (std::char_traits<char>::length (buf)) + 1;
+
+ // allocate a (possibly wide) character buffer to copy
+ // (and widen) the contents of `buf' into
+ buf_ = new charT [bufsize_ + 1];
+
+ for (std::streamsize inx = 0; inx != bufsize_; ++inx) {
+ typedef unsigned char UChar;
+
+ buf_ [inx] = UChar (buf [inx]);
+ }
+
+ // zero out the (non-dereferenceable) element just past the end
+ // so that the buffer can be printed out as an ordinary string
+ buf_ [bufsize_] = charT ();
+
+ // set the get area to 0 size to force a call to underflow()
+ // on the first read attempt from the buffer
+ this->setg (buf_, buf_, buf_);
+
+ // set the fail and throw flags
+ if (fail_set & Throw) {
+ throw_set_ = fail_set & ~Throw;
+ }
+ else {
+ fail_set_ = fail_set;
+ }
+}
+
+
+template <class charT, class Traits>
+typename MyStreambuf<charT, Traits>::int_type
+MyStreambuf<charT, Traits>::
+underflow ()
+{
+ if (!test (Underflow))
+ return traits_type::eof ();
+
+ if (this->egptr () - this->gptr () > 0) {
+ this->gbump (1);
+ return traits_type::to_int_type (*this->gptr ());
+ }
+
+ if (this->egptr () < buf_ + bufsize_) {
+
+ // increase the pending input sequence by no more than
+ // the lesser of the available buffer space and `in_pending_'
+ std::streamsize pending = buf_ + bufsize_ - this->egptr ();
+
+ if (pending > in_pending_)
+ pending = in_pending_;
+
+ this->setg (this->eback (), this->gptr (), this->egptr () + pending);
+ return traits_type::to_int_type (*this->gptr ());
+ }
+
+ failed_ = Underflow;
+ return traits_type::eof ();
+}
+
+
+template <class charT, class Traits>
+typename MyStreambuf<charT, Traits>::int_type
+MyStreambuf<charT, Traits>::
+overflow (int_type c /* = traits_type::eof () */)
+{
+ if (!test (Overflow))
+ return traits_type::eof ();
+
+ if (this->epptr () - this->pptr () > 0) {
+ traits_type::assign (*this->pptr (), traits_type::to_char_type (c));
+ this->pbump (1);
+ return traits_type::not_eof (c);
+ }
+
+ if (this->epptr () < buf_ + bufsize_) {
+
+ // increase the pending output sequence by no more than
+ // the lesser of the available buffer space and `out_pending_'
+ std::streamsize pending = buf_ + bufsize_ - this->epptr ();
+
+ if (pending > out_pending_)
+ pending = out_pending_;
+
+ const std::streamsize pptr_off = this->pptr () - this->pbase ();
+
+ this->setp (this->pbase (), this->epptr () + pending);
+
+ this->pbump (pptr_off);
+
+ traits_type::assign (*this->pptr (), traits_type::to_char_type (c));
+
+ this->pbump (1);
+
+ return traits_type::not_eof (c);
+ }
+
+ failed_ = Overflow;
+ return traits_type::eof ();
+}
+
+
+template <class charT, class Traits>
+typename MyStreambuf<charT, Traits>::int_type
+MyStreambuf<charT, Traits>::
+pbackfail (int_type c /* = traits_type::eof () */)
+{
+ if (!test (Pbackfail))
+ return traits_type::eof ();
+
+ if (this->gptr () == buf_) {
+ failed_ = Pbackfail;
+ return traits_type::eof ();
+ }
+
+ this->setg (this->gptr () - 1, this->gptr () - 1, this->gptr ());
+
+ const int_type last = traits_type::to_int_type (*this->gptr ());
+
+ if (!traits_type::eq_int_type (c, traits_type::eof ()))
+ traits_type::assign (*this->gptr (), c);
+
+ return last;
+}
+
+
+template <class charT, class Traits>
+typename MyStreambuf<charT, Traits>::int_type
+MyStreambuf<charT, Traits>::
+uflow ()
+{
+ if (!test (Uflow))
+ return traits_type::eof ();
+
+ if (this->egptr () - this->gptr () > 0) {
+ this->gbump (1);
+ return traits_type::to_int_type (*this->gptr ());
+ }
+
+ if (this->egptr () < buf_ + bufsize_) {
+
+ // increase the pending input sequence by no more than
+ // the lesser of the available buffer space and `in_pending_'
+ std::streamsize pending = buf_ + bufsize_ - this->egptr ();
+
+ if (pending > in_pending_)
+ pending = in_pending_;
+
+ this->setg (this->eback (), this->gptr (), this->egptr () + pending);
+ return traits_type::to_int_type (*this->gptr ());
+ }
+
+ failed_ = Uflow;
+ return traits_type::eof ();
+}
+
+
+template <class charT, class Traits>
+int
+MyStreambuf<charT, Traits>::
+ncalls (MemFun which) const
+{
+ int inx = -1;
+
+ for (unsigned i = 0; i < sizeof (which) * _RWSTD_CHAR_BIT; ++i) {
+ if (which & (1U << i)) {
+ if (inx < 0)
+ inx = i;
+ else
+ return -1;
+ }
+ }
+
+ return ncalls_ [inx];
+}
+
+
+template <class charT, class Traits>
+bool
+MyStreambuf<charT, Traits>::
+test (MemFun which) const
+{
+ MyStreambuf* const self = _RWSTD_CONST_CAST (MyStreambuf*, this);
+
+ int inx = -1;
+
+ for (unsigned i = 0; i < sizeof (which) * _RWSTD_CHAR_BIT; ++i) {
+ if (which & (1U << i)) {
+ if (inx < 0)
+ inx = i;
+ else
+ return true;
+ }
+ }
+
+ // increment the counter tracking the number of calls made
+ // to each member function; do so regardless of whether
+ // an exception will be thrown below
+ const int callno = self->ncalls_ [inx]++;
+
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+ // if the call counter is equal to the `fail_when_' watermark
+ // and `shich' is set in the `throw_set_' bitmask, throw an
+ // exception with the value of the member id
+ if (callno == fail_when_ && throw_set_ & which) {
+ self->threw_ = which;
+ throw which;
+ }
+
+#else // if defined (_RWSTD_NO_EXCEPTIONS)
+
+ if (callno == fail_when_ && throw_set_ & which) {
+ self->threw_ = which;
+ return false;
+ }
+
+#endif // _RWSTD_NO_EXCEPTIONS
+
+ // ...otherwise check if the member should succeed or fail
+ // and return true or false, respectively
+ const bool success = !(fail_set_ & which) || callno != fail_when_;
+
+ if (!success)
+ self->failed_ = which;
+
+ return success;
+}
+
+
+#endif // RW_STREAMBUF_H_INCLUDED
Propchange: incubator/stdcxx/trunk/tests/include/rw_streambuf.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/stdcxx/trunk/tests/include/rw_streambuf.h
------------------------------------------------------------------------------
svn:keywords = Id