2008-12-10  Martin Sebor  <sebor@apache.org>

	Merged rev 723461 and 723465 from 4.2.x.

	2008-12-04  Martin Sebor  <sebor@apache.org>

	STDCXX-1026
	* include/streambuf.cc (basic_streambuf::xsgetn): Removed
	assumption that empty get area implies empty pending sequence.
	* tests/regress/27.streambuf.sgetn.stdcxx-1026.cpp: New test.

	2008-12-04  Martin Sebor  <sebor@apache.org>

	* streambuf.cc (basic_streambuf::uflow): Reverted "_TYPENAME"
	to "typename" change inadvertently introduced in rev 723461.


git-svn-id: https://svn.apache.org/repos/asf/stdcxx/trunk@725460 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/include/streambuf.cc b/include/streambuf.cc
index 356af26..fe884c6 100644
--- a/include/streambuf.cc
+++ b/include/streambuf.cc
@@ -23,7 +23,7 @@
  * implied.   See  the License  for  the  specific language  governing
  * permissions and limitations under the License.
  *
- * Copyright 1994-2006 Rogue Wave Software.
+ * Copyright 1994-2006 Rogue Wave Software, Inc.
  * 
  **************************************************************************/
 
@@ -90,23 +90,35 @@
         // number of characters available in get area
         streamsize __navail = egptr () - gptr ();
 
-        if (0 == __navail)
+        if (0 < __navail) {
+            if (__navail > __n)
+                __navail = __n;
+
+            // copy contents of get area to the destination buffer
+            traits_type::copy (__buf + __nget, gptr (), __navail);
+
+            // increment pointers and counts by the number of characters
+            // copied
+            gbump (__navail);
+            __n    -= __navail;
+            __nget += __navail;
+        }
+        else if (traits_type::eq_int_type (__c, traits_type::eof ())) {
+            // break out on underflow() failure (e.g., reaching EOF)
             break;
+        }
+        else {
+            // unbuffered mode: empty pending seuqence but non-EOF
+            // overflow() return value
 
-        if (__navail > __n)
-            __navail = __n;
+            // append character returned by underflow()
+            traits_type::assign (__buf [__nget],
+                                 traits_type::to_char_type (__c));
 
-        // copy contents of get area to the destination buffer
-        traits_type::copy (__buf + __nget, gptr (), __navail);
-
-        // increment pointers and counts by the number of characters copied
-        gbump (__navail);
-        __n    -= __navail;
-        __nget += __navail;
-
-        // break out on underflow error
-        if (traits_type::eq_int_type (__c, traits_type::eof ()))
-            break;
+            // avoid incrementing egptr() but adjust counters
+            --__n;
+            ++__nget;
+        }
     }
 
     return __nget;
diff --git a/tests/regress/27.streambuf.sgetn.stdcxx-1026.cpp b/tests/regress/27.streambuf.sgetn.stdcxx-1026.cpp
new file mode 100644
index 0000000..e943726
--- /dev/null
+++ b/tests/regress/27.streambuf.sgetn.stdcxx-1026.cpp
@@ -0,0 +1,58 @@
+/************************************************************************
+ *
+ * 27.streambuf.sgetn.stdcxx-1026.cpp - regression test for STDCXX-1026
+ *
+ * http://issues.apache.org/jira/browse/STDCXX-1026
+ *
+ * $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.
+ * 
+ **************************************************************************/
+
+#include <cassert>
+#include <istream>
+#include <streambuf>
+
+int main ()
+{
+    static int x = '0';
+
+    struct: std::streambuf {
+        // unbuffered, always successfully reads one character
+        int_type underflow () {
+            assert (gptr () == egptr ());
+            return x++;
+        }
+    } sb;
+
+    // "endless" stream that never reaches EOF
+    std::istream endless (&sb);
+
+    char s [4] = "";
+
+    endless.read (s, sizeof s);
+ 
+    // expect to find stream in good state (i.e., not EOF) and
+    // to have extracted as many characters as requested with
+    // just as many calls to underflow()
+    assert (endless.good ());
+    assert (sizeof s == endless.gcount ());
+    assert ('0' == s [0] && '1' == s [1] && '2' == s [2] && '3' == s [3]);
+}