stdcxx-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From se...@apache.org
Subject svn commit: r387098 - /incubator/stdcxx/trunk/tests/include/rw_streambuf.h
Date Mon, 20 Mar 2006 01:27:20 GMT
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  <sebor@roguewave.com>

	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



Mime
View raw message