Author: sebor
Date: Mon Feb 5 17:59:05 2007
New Revision: 503954
URL: http://svn.apache.org/viewvc?view=rev&rev=503954
Log:
2007-02-05 Martin Sebor <[EMAIL PROTECTED]>
STDCXX-4
* 27.istream.readsome.cpp: New test exercising the member function
readsome() of basic_istream.
Added:
incubator/stdcxx/trunk/tests/iostream/27.istream.readsome.cpp (with props)
Added: incubator/stdcxx/trunk/tests/iostream/27.istream.readsome.cpp
URL:
http://svn.apache.org/viewvc/incubator/stdcxx/trunk/tests/iostream/27.istream.readsome.cpp?view=auto&rev=503954
==============================================================================
--- incubator/stdcxx/trunk/tests/iostream/27.istream.readsome.cpp (added)
+++ incubator/stdcxx/trunk/tests/iostream/27.istream.readsome.cpp Mon Feb 5
17:59:05 2007
@@ -0,0 +1,476 @@
+/************************************************************************
+ *
+ * 27.readsome.cpp - test exercising istream::readsome()
+ *
+ * $Id$
+ *
+ ************************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you 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.
+ *
+ * Copyright 2003-2007 Rogue Wave Software.
+ *
+ **************************************************************************/
+
+#include <istream>
+#include <sstream>
+
+#include <driver.h>
+#include <rw_char.h> // for UserChar, UserTraits
+#include <rw_printf.h> // for rw_printf()
+
+/***********************************************************************/
+
+template <class charT, class Traits>
+struct Streambuf: std::basic_streambuf<charT, Traits>
+{
+ typedef std::basic_streambuf<charT, Traits> Base;
+ typedef typename Base::traits_type traits_type;
+ typedef typename Base::int_type int_type;
+
+ // value returned from showmanyc()
+ int showmanyc_;
+
+ // underflow() will return eof () after extracting this many chars
+ int fail_after_;
+
+ // underflow() will throw am exception after extracting this many chars
+ int throw_after_;
+
+ const charT *end_; // the end of the buffer (future eback())
+
+ Streambuf (const charT *gbeg, const charT *gend)
+ : Base (),
+ showmanyc_ (0),
+ fail_after_ (-1), // never fail
+ throw_after_ (-1), // never throw
+ end_ (gend) {
+ this->setg (_RWSTD_CONST_CAST (charT*, gbeg),
+ _RWSTD_CONST_CAST (charT*, gbeg),
+ _RWSTD_CONST_CAST (charT*, gbeg));
+ }
+
+ const charT* pubeback () const {
+ return this->eback ();
+ }
+
+ const charT* pubgptr () const {
+ return this->gptr ();
+ }
+
+ const charT* pubegptr () const {
+ return this->egptr ();
+ }
+
+ /* virtual */ std::streamsize showmanyc () {
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+ if (-2 == showmanyc_)
+ throw (const char*)"showmanyc";
+
+#endif // _RWSTD_NO_EXCEPTIONS
+
+ return showmanyc_;
+ }
+
+ /* virtual */ int_type underflow () {
+ if (this->gptr () == end_)
+ return traits_type::eof ();
+
+ if (throw_after_ == this->gptr () - this->eback ()) {
+
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+ throw (const char*)"underflow";
+
+#else // if defined (_RWSTD_NO_EXCEPTIONS)
+
+ return traits_type::eof ();
+
+#endif // _RWSTD_NO_EXCEPTIONS
+
+ }
+
+ if (fail_after_ == this->gptr () - this->eback ())
+ return traits_type::eof ();
+
+ this->setg (this->eback (), this->gptr (), this->gptr () + 1);
+ return traits_type::to_int_type (*this->gptr ());
+ }
+};
+
+/***********************************************************************
+
+ 27.6.1.3, p30 and 31
+
+ streamsize readsome (char_type* s, streamsize n);
+
+ -30- Effects: If !good() calls setstate(failbit) which may throw an
+ exception, and return. Otherwise extracts characters and stores
+ them into successive locations of an array whose first element
+ is designated by s.
+ -- If rdbuf()>in_avail() == 1, calls setstate(eofbit) (which
+ may throw ios_base::failure (27.4.4.3)), and extracts no
+ characters;
+ -- If rdbuf()>in_avail() == 0, extracts no characters
+ -- If rdbuf()>in_avail() > 0, extracts min(rdbuf()>in_avail(),
+ n)).
+ -31- Returns: The number of characters extracted.
+
+************************************************************************/
+
+void
+memfun_info (int line, const char *cname, const char *tname)
+{
+ // format the ISTREAM environment variable w/o writing
+ // out any output
+ rw_fprintf (0,
+ "%{$ISTREAM!:@}",
+ "%{?}istream%{:}%{?}wistream"
+ "%{:}basic_istream<%s, %s>%{;}%{;}",
+ 'c' == *cname && 'c' == *tname,
+ 'w' == *cname && 'c' == *tname,
+ cname, tname);
+
+ rw_info (0, 0, line,
+ "std::%{$ISTREAM}::readsome (char_type*, streamsize)");
+}
+
+/************************************************************************/
+
+extern const std::ios_base::iostate
+states[] = {
+ std::ios_base::badbit,
+ std::ios_base::eofbit,
+ std::ios_base::failbit,
+ std::ios_base::goodbit,
+ std::ios_base::badbit | std::ios_base::eofbit,
+ std::ios_base::badbit | std::ios_base::failbit,
+ std::ios_base::eofbit | std::ios_base::failbit,
+ std::ios_base::badbit | std::ios_base::eofbit | std::ios_base::failbit
+};
+
+extern const unsigned nstates = sizeof states / sizeof *states;
+
+
+template <class charT, class Traits>
+void test_readsome (const charT *cbuf, const Traits*,
+ unsigned cbuf_size,
+ unsigned i, // index into states
+ unsigned j, // number of chars to read
+ unsigned k, // when underflow() will fail
+ int l, // value returned from showmanyc()
+ unsigned m) // how underflow should fail()
+{
+ typedef std::basic_istream<charT, Traits> Istream;
+
+ static unsigned iter = 0; // iteration counter
+
+ // construct a stream buffer object and initialize its read
+ // sequence with the character buffer
+ Streambuf<charT, Traits> sb (cbuf, cbuf + cbuf_size - 1);
+
+ sb.showmanyc_ = l;
+
+ const char* err_type = 0;
+
+ if (m < 1) {
+ // have the stream buffer object's underflow() fail (by
+ // throwing an exception if possible) after k characters
+ // have been extracted (this object calls underflow() for
+ // every char)
+ sb.throw_after_ = k;
+ err_type = "threw";
+ }
+ else {
+ // have the stream buffer object's underflow() fail by
+ // returning eof after k characters have been extracted
+ // (this object calls underflow() for every char)
+ sb.fail_after_ = k;
+ err_type = "returned EOF";
+ }
+
+ // construct an istream object and initialize it with the user
+ // defined streambuf object
+ Istream is (&sb);
+
+ // set the stream object's initial state
+ is.setstate (states [i]);
+
+ // the number of extracted whitespace characters expected to
+ // be reported by gcount() must equal the number of successful
+ // extractions computed by the the stream buffer overridden
+ // underflow member function
+ const int extract =
+ is.good () ? j < k ? int (j) < l ? j
+ : l < 0 ? 0 : l
+ : int (k) < l ? k
+ : l < 0 ? 0 : l
+ : 0;
+
+ charT buf [256] = { 0 };
+
+ std::streamsize nread = -1;
+
+ // format the FCALL environment variable so that it can be
+ // conveniently used in diagnostics below
+ rw_fprintf (0, "%u. %{$FCALL!:@}",
+ iter,
+ "%{$ISTREAM}(%{*Ac}).readsome(%p, %d)",
+ int (sizeof *cbuf), cbuf, buf, j);
+
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+ const char *caught = 0;
+
+ // on every other iteration set badbit in exceptions to check
+ // that the thrown object is propagated by the function
+ if (k % 2 && !is.bad ())
+ is.exceptions (std::ios_base::badbit);
+
+ try {
+ nread = is.readsome (buf, j);
+ }
+ catch (const char *s) {
+ caught = s;
+ }
+ catch (...) {
+
+ caught = "...";
+
+ rw_assert (0, 0, __LINE__,
+ "%{$FCALL} threw an exception of unexpected type");
+ }
+
+ //////////////////////////////////////////////////////////////////
+ // verify that the function propagates exceptions thrown from the
+ // streambuf object only when badbit is set in the stream object's
+ // exceptions()
+
+ rw_assert (!caught || (k % 2), 0, __LINE__,
+ "%{$FCALL} unexpectedly propagated an exception");
+
+#else // if defined (_RWSTD_NO_EXCEPTIONS)
+
+ nread = is.readsome (buf, j);
+
+#endif // _RWSTD_NO_EXCEPTIONS
+
+ //////////////////////////////////////////////////////////////////
+ // verify that the function returned the expected number of
+ // extracted characters
+
+ const std::streamsize extracted = sb.pubgptr () - sb.pubeback ();
+
+ rw_assert (extract == extracted, 0, __LINE__,
+ "%{$FCALL} expected to extract %d chars, got %u; "
+ "initial state = %{Is}, underflow %s at extraction %u",
+ extract, extracted, states [i],
+ err_type, k);
+
+ //////////////////////////////////////////////////////////////////
+ // verify that the expected number of characters have been
+ // extracted from the stream
+
+ rw_assert (cbuf + extract == sb.pubgptr (), 0, __LINE__,
+ "%{$FCALL} expected to extract %d chars, got %u; "
+ "initial state = %{Is}, underflow %s at extraction %u",
+ extract, extracted, states [i],
+ err_type, k);
+
+ //////////////////////////////////////////////////////////////////
+ // verify that the extracted characters match those in the buffer
+
+ rw_assert (0 == std::char_traits<charT>::compare (buf, cbuf, extract),
+ 0, __LINE__,
+ "%{$FCALL} expected to extract the first %d chars, got %{*Ac}",
+ extract, int (sizeof *buf), buf);
+
+ //////////////////////////////////////////////////////////////////
+ // verify that gcount() correctly reflects the number of
+ // characters successfully extracted from the stream
+
+ rw_assert (extract == is.gcount (), 0, __LINE__,
+ "%{$FCALL}: gcount() == %d, got %d; initial state = %{Is}, "
+ "underflow %s at extraction %u",
+ extract, is.gcount (), states [i],
+ err_type, k);
+
+ //////////////////////////////////////////////////////////////////
+ // verify the state of the stream object after the function call
+
+ // expected stream state after the function call is unchanged
+ // (i.e., the initial stream state), except...
+ std::ios_base::iostate expect_state = states [i];
+
+ if (!states [i]) {
+
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+ // ...if an extraction is attempted, or even if the first
+ // character on the stream is peeked at, and an exception
+ // is thrown during input, badbit should be set, otherwise
+ // if in_avail() returned -1, eofbit should be set, else
+ // the state should be good
+ if (-2 == l)
+ expect_state = std::ios_base::badbit;
+ else if (l < 0)
+ expect_state = std::ios_base::eofbit;
+ else
+ expect_state = std::ios_base::goodbit;
+
+#else // if defined (_RWSTD_NO_EXCEPTIONS)
+
+ if (l < 0)
+ expect_state = std::ios_base::eofbit;
+ else
+ expect_state = std::ios_base::goodbit;
+
+#endif // _RWSTD_NO_EXCEPTIONS
+
+ }
+ else {
+
+ // ...if the initial stream state is not good, failbit
+ // must be set
+ expect_state = states [i] | std::ios_base::failbit;
+ }
+
+ rw_assert (is.rdstate () == expect_state, 0, __LINE__,
+ "%{$FCALL}: rdstate() == %{Is}, got %{Is}; "
+ "extracted %u characters; "
+ "initial state = %{Is}, underflow %s at extraction %u",
+ expect_state, is.rdstate (), extracted,
+ states [i], err_type, k);
+
+ ++iter;
+}
+
+/***********************************************************************/
+
+
+template <class charT, class Traits>
+void test_readsome (const charT*, const Traits*,
+ const char *cname, const char *tname)
+{
+ memfun_info (__LINE__, cname, tname);
+
+ //////////////////////////////////////////////////////////////
+ // exercise 27.6.1.3, p1
+
+ const charT cbuf[] = { ' ', 'a', ' ', 'b', 'c', '\0' };
+ const unsigned cbuf_size = sizeof cbuf / sizeof *cbuf;
+
+ unsigned iter = 0; // iteration counter
+
+ // iterate over all possible settings of the stream state
+ for (unsigned i = 0; i != nstates; ++i) {
+
+ // call readsome(..., j) to extract j characters
+ for (unsigned j = 0; j != cbuf_size - 1; ++j) {
+
+ // have underflow() fail after the `k-th' extraction
+ for (unsigned k = 0; k != j + 1; ++k) {
+
+ // return `l' from showmanyc(); -2 will throw
+ for (int l = -4; l != int (k); ++l) {
+
+ // if (0 == m), underflow() will throw an exception
+ // at `k-th' extraction, otherwise the function will
+ // return EOF
+ for (unsigned m = 0; m != 2; ++m, ++iter) {
+
+ // prevent causing underflow() to fail by
+ // returning EOF when in_avail() promised
+ // it wouldn't (by returning a value
+ // greater than the number of extractions
+ // underflow() will allow to succeed)
+ if (1U == m && int (k) < l)
+ continue;
+
+ test_readsome (cbuf, (Traits*)0,
+ cbuf_size, i, j, k, l, m);
+ }
+ }
+ }
+ }
+ }
+}
+
+/***********************************************************************/
+
+static int opt_char;
+static int opt_wchar;
+static int opt_char_traits;
+static int opt_user_traits;
+
+
+static int
+run_test (int, char**)
+{
+ // introduce char_traits into scope
+ using namespace std;
+
+#undef TEST
+#define TEST(CharT, Traits) \
+ test_readsome ((CharT*)0, (Traits*)0, #CharT, #Traits)
+
+ if (rw_note (0 <= opt_char && 0 <= opt_char_traits, 0, __LINE__,
+ "basic_istream<char, char_traits<char>>::readsome() "
+ "tests disabled"))
+ TEST (char, char_traits<char>);
+
+ if (rw_note (0 <= opt_char && 0 <= opt_user_traits, 0, __LINE__,
+ "basic_istream<char, UserTraits<char>>::readsome() "
+ "tests disabled"))
+ TEST (char, UserTraits<char>);
+
+#ifndef _RWSTD_NO_WCHAR_T
+
+ if (rw_note (0 <= opt_wchar && 0 <= opt_char_traits, 0, __LINE__,
+ "basic_istream<wchar_t, char_traits<wchar_t>>::readsome() "
+ "tests disabled"))
+ TEST (wchar_t, char_traits<wchar_t>);
+
+ if (rw_note (0 <= opt_wchar && 0 <= opt_user_traits, 0, __LINE__,
+ "basic_istream<wchar_t, UserTraits<wchar_t>>::readsome() "
+ "tests disabled"))
+ TEST (wchar_t, UserTraits<wchar_t>);
+
+#endif // _RWSTD_NO_WCHAR_T
+
+ return 0;
+}
+
+/***********************************************************************/
+
+int main (int argc, char *argv[])
+{
+ return rw_test (argc, argv, __FILE__,
+ "istream.unformatted",
+ "readsome",
+ run_test,
+ "|-char~ "
+ "|-wchar_t~ "
+ "|-char_traits~ "
+ "|-UserTraits~ ",
+ &opt_char,
+ &opt_wchar,
+ &opt_char_traits,
+ &opt_user_traits,
+ (void*)0 /* sentinel */);
+}
Propchange: incubator/stdcxx/trunk/tests/iostream/27.istream.readsome.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/stdcxx/trunk/tests/iostream/27.istream.readsome.cpp
------------------------------------------------------------------------------
svn:keywords = Id