You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4cxx-dev@logging.apache.org by ca...@apache.org on 2007/11/09 17:11:56 UTC

svn commit: r593580 - in /logging/log4cxx/trunk/src: main/cpp/messagebuffer.cpp main/include/log4cxx/helpers/messagebuffer.h test/cpp/helpers/messagebuffertest.cpp

Author: carnold
Date: Fri Nov  9 08:11:55 2007
New Revision: 593580

URL: http://svn.apache.org/viewvc?rev=593580&view=rev
Log:
LOGCXX-18: Add unit tests to check for unexpected stream construction

Modified:
    logging/log4cxx/trunk/src/main/cpp/messagebuffer.cpp
    logging/log4cxx/trunk/src/main/include/log4cxx/helpers/messagebuffer.h
    logging/log4cxx/trunk/src/test/cpp/helpers/messagebuffertest.cpp

Modified: logging/log4cxx/trunk/src/main/cpp/messagebuffer.cpp
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/cpp/messagebuffer.cpp?rev=593580&r1=593579&r2=593580&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/cpp/messagebuffer.cpp (original)
+++ logging/log4cxx/trunk/src/main/cpp/messagebuffer.cpp Fri Nov  9 08:11:55 2007
@@ -1,23 +1,23 @@
-/*
- * 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.
- */
-
+/*
+ * 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 <log4cxx/helpers/messagebuffer.h>
-#include <log4cxx/helpers/transcoder.h>
-
+#include <log4cxx/helpers/transcoder.h>
+
 using namespace log4cxx::helpers;
 
 CharMessageBuffer::CharMessageBuffer() : stream(0) {}
@@ -77,10 +77,14 @@
 	return buf;
 }
 
+bool CharMessageBuffer::hasStream() const {
+    return (stream != 0);
+}
 
 
 
-#if LOG4CXX_HAS_WCHAR_T
+
+#if LOG4CXX_HAS_WCHAR_T
 WideMessageBuffer::WideMessageBuffer() : stream(0) {}
 
 WideMessageBuffer::~WideMessageBuffer() {
@@ -138,14 +142,21 @@
 	return buf;
 }
 
+bool WideMessageBuffer::hasStream() const {
+    return (stream != 0);
+}
+
+
 
+MessageBuffer::MessageBuffer()  : wbuf(0){
+}
+
+MessageBuffer::~MessageBuffer() {
+    delete wbuf;
+}
 
-
-MessageBuffer::MessageBuffer()  : wbuf(0){
-}
-
-MessageBuffer::~MessageBuffer() {
-    delete wbuf;
+bool MessageBuffer::hasStream() const {
+    return cbuf.hasStream() || (wbuf != 0 && wbuf->hasStream());
 }
 
 #endif

Modified: logging/log4cxx/trunk/src/main/include/log4cxx/helpers/messagebuffer.h
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/include/log4cxx/helpers/messagebuffer.h?rev=593580&r1=593579&r2=593580&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/include/log4cxx/helpers/messagebuffer.h (original)
+++ logging/log4cxx/trunk/src/main/include/log4cxx/helpers/messagebuffer.h Fri Nov  9 08:11:55 2007
@@ -17,22 +17,22 @@
 
 #ifndef _LOG4CXX_MESSAGE_BUFFER_H
 #define _LOG4CXX_MESSAGE_BUFFER_H
-
+
 #include <log4cxx/log4cxx.h>
 #include <string>
-#include <sstream>
+#include <sstream>
+
+namespace log4cxx {
+
 
-namespace log4cxx {
-
-
    namespace helpers {
-   
-
-   /**
-    *   This class is used by the LOG4CXX_INFO and similar
-    *   macros to support insertion operators in the message parameter.
-    *   The class is not intended for use outside of that context.
-    */
+   
+
+   /**
+    *   This class is used by the LOG4CXX_INFO and similar
+    *   macros to support insertion operators in the message parameter.
+    *   The class is not intended for use outside of that context.
+    */
    class LOG4CXX_EXPORT CharMessageBuffer {
    public:
         /**
@@ -42,7 +42,7 @@
         /**
          *  Destructor.
          */
-        ~CharMessageBuffer();
+        ~CharMessageBuffer();
 
         
         /**
@@ -50,40 +50,46 @@
          *   @param msg string append.
          *   @return this buffer.
          */
-        CharMessageBuffer& operator<<(const std::basic_string<char>& msg);
+        CharMessageBuffer& operator<<(const std::basic_string<char>& msg);
         /**
          *   Appends string to buffer.
          *   @param msg string to append.
          *   @return this buffer.
          */
-        CharMessageBuffer& operator<<(const char* msg);
+        CharMessageBuffer& operator<<(const char* msg);
 
         /**
          *   Appends character to buffer.
          *   @param msg character to append.
          *   @return this buffer.
          */
-        CharMessageBuffer& operator<<(const char msg);
-
-		/**
-		 *  Cast to ostream.
-		 */
-		operator std::basic_ostream<char>&();
-
-		/**
-		 *   Get content of buffer.
-		 *   @param os used only to signal that
-		 *       the embedded stream was used.
-		 */
-		const std::basic_string<char>& str(std::basic_ostream<char>& os);
-
-		/**
-		 *   Get content of buffer.
-		 *   @param buf used only to signal that
-		 *       the embedded stream was not used.
-		 */
-		const std::basic_string<char>& str(CharMessageBuffer& buf);
-
+        CharMessageBuffer& operator<<(const char msg);
+
+		/**
+		 *  Cast to ostream.
+		 */
+		operator std::basic_ostream<char>&();
+
+		/**
+		 *   Get content of buffer.
+		 *   @param os used only to signal that
+		 *       the embedded stream was used.
+		 */
+		const std::basic_string<char>& str(std::basic_ostream<char>& os);
+
+		/**
+		 *   Get content of buffer.
+		 *   @param buf used only to signal that
+		 *       the embedded stream was not used.
+		 */
+		const std::basic_string<char>& str(CharMessageBuffer& buf);
+
+        /**
+         *  Returns true if buffer has an encapsulated STL stream.
+         *  @return true if STL stream was created.
+         */
+        bool hasStream() const;
+
    private:
         /**
          * Prevent use of default copy constructor.
@@ -93,7 +99,7 @@
          *   Prevent use of default assignment operator.  
          */
 	   CharMessageBuffer& operator=(const CharMessageBuffer&);
-
+
 	   /**
          * Encapsulated std::string.
          */
@@ -103,109 +109,115 @@
          */
         std::basic_ostringstream<char>* stream;
    };
-
-template<class V>
-std::basic_ostream<char>& operator<<(CharMessageBuffer& os, const V& val) {
-	return ((std::basic_ostream<char>&) os) << val;
-}
-
-inline std::basic_ostream<char>& operator<<(CharMessageBuffer& os, std::ios_base& (*manip)(std::ios_base& s)) {
-	std::basic_ostream<char>& s = os;
-	(*manip)(s);
-	return s;
-}
 
-
+template<class V>
+std::basic_ostream<char>& operator<<(CharMessageBuffer& os, const V& val) {
+	return ((std::basic_ostream<char>&) os) << val;
+}
+
+inline std::basic_ostream<char>& operator<<(CharMessageBuffer& os, std::ios_base& (*manip)(std::ios_base& s)) {
+	std::basic_ostream<char>& s = os;
+	(*manip)(s);
+	return s;
+}
+
+
 #if LOG4CXX_HAS_WCHAR_T
-   /**
-    *   This class is designed to support insertion operations
-	*   in the message argument to the LOG4CXX_INFO and similar
-	*   macros and is not designed for general purpose use.
-	*/
-   class LOG4CXX_EXPORT WideMessageBuffer {
-   public:
-        /**
-         *  Creates a new instance.
-         */
-	    WideMessageBuffer();
-        /**
-         *  Destructor.
-         */
-        ~WideMessageBuffer();
-
-        
-        /**
-         *   Appends string to buffer.
-         *   @param msg string append.
-         *   @return this buffer.
-         */
-        WideMessageBuffer& operator<<(const std::basic_string<wchar_t>& msg);
-        /**
-         *   Appends string to buffer.
-         *   @param msg string to append.
-         *   @return this buffer.
-         */
-        WideMessageBuffer& operator<<(const wchar_t* msg);
-
-        /**
-         *   Appends character to buffer.
-         *   @param msg character to append.
-         *   @return this buffer.
-         */
-        WideMessageBuffer& operator<<(const wchar_t msg);
-
-		/**
-		 *  Cast to ostream.
-		 */
-		operator std::basic_ostream<wchar_t>&();
-
-		/**
-		 *   Get content of buffer.
-		 *   @param os used only to signal that
-		 *       the embedded stream was used.
-		 */
-		const std::basic_string<wchar_t>& str(std::basic_ostream<wchar_t>& os);
-
-		/**
-		 *   Get content of buffer.
-		 *   @param buf used only to signal that
-		 *       the embedded stream was not used.
-		 */
-		const std::basic_string<wchar_t>& str(WideMessageBuffer& buf);
-
-   private:
-        /**
-         * Prevent use of default copy constructor.
-         */
-	   WideMessageBuffer(const WideMessageBuffer&);
-        /**
-         *   Prevent use of default assignment operator.  
-         */
-	   WideMessageBuffer& operator=(const WideMessageBuffer&);
-
-	   /**
-         * Encapsulated std::string.
-         */
-        std::basic_string<wchar_t> buf;
-        /**
-         *  Encapsulated stream, created on demand.
-         */
-        std::basic_ostringstream<wchar_t>* stream;
-   };
-
-template<class V>
-std::basic_ostream<wchar_t>& operator<<(WideMessageBuffer& os, const V& val) {
-	return ((std::basic_ostream<wchar_t>&) os) << val;
-}
-
-inline std::basic_ostream<wchar_t>& operator<<(WideMessageBuffer& os, std::ios_base& (*manip)(std::ios_base& s)) {
-	std::basic_ostream<wchar_t>& s = os;
-	(*manip)(s);
-	return s;
-}
-
-
-
+   /**
+    *   This class is designed to support insertion operations
+	*   in the message argument to the LOG4CXX_INFO and similar
+	*   macros and is not designed for general purpose use.
+	*/
+   class LOG4CXX_EXPORT WideMessageBuffer {
+   public:
+        /**
+         *  Creates a new instance.
+         */
+	    WideMessageBuffer();
+        /**
+         *  Destructor.
+         */
+        ~WideMessageBuffer();
+
+        
+        /**
+         *   Appends string to buffer.
+         *   @param msg string append.
+         *   @return this buffer.
+         */
+        WideMessageBuffer& operator<<(const std::basic_string<wchar_t>& msg);
+        /**
+         *   Appends string to buffer.
+         *   @param msg string to append.
+         *   @return this buffer.
+         */
+        WideMessageBuffer& operator<<(const wchar_t* msg);
+
+        /**
+         *   Appends character to buffer.
+         *   @param msg character to append.
+         *   @return this buffer.
+         */
+        WideMessageBuffer& operator<<(const wchar_t msg);
+
+		/**
+		 *  Cast to ostream.
+		 */
+		operator std::basic_ostream<wchar_t>&();
+
+		/**
+		 *   Get content of buffer.
+		 *   @param os used only to signal that
+		 *       the embedded stream was used.
+		 */
+		const std::basic_string<wchar_t>& str(std::basic_ostream<wchar_t>& os);
+
+		/**
+		 *   Get content of buffer.
+		 *   @param buf used only to signal that
+		 *       the embedded stream was not used.
+		 */
+		const std::basic_string<wchar_t>& str(WideMessageBuffer& buf);
+
+        /**
+         *  Returns true if buffer has an encapsulated STL stream.
+         *  @return true if STL stream was created.
+         */
+        bool hasStream() const;
+
+   private:
+        /**
+         * Prevent use of default copy constructor.
+         */
+	   WideMessageBuffer(const WideMessageBuffer&);
+        /**
+         *   Prevent use of default assignment operator.  
+         */
+	   WideMessageBuffer& operator=(const WideMessageBuffer&);
+
+	   /**
+         * Encapsulated std::string.
+         */
+        std::basic_string<wchar_t> buf;
+        /**
+         *  Encapsulated stream, created on demand.
+         */
+        std::basic_ostringstream<wchar_t>* stream;
+   };
+
+template<class V>
+std::basic_ostream<wchar_t>& operator<<(WideMessageBuffer& os, const V& val) {
+	return ((std::basic_ostream<wchar_t>&) os) << val;
+}
+
+inline std::basic_ostream<wchar_t>& operator<<(WideMessageBuffer& os, std::ios_base& (*manip)(std::ios_base& s)) {
+	std::basic_ostream<wchar_t>& s = os;
+	(*manip)(s);
+	return s;
+}
+
+
+
    /**
     *   This class is used by the LOG4CXX_INFO and similar
     *   macros to support insertion operators in the message parameter.
@@ -216,78 +228,78 @@
         /**
          *  Creates a new instance.
          */
-	   MessageBuffer();
+	   MessageBuffer();
 	   /**
          * Destructor.
          */
-	   ~MessageBuffer();
-
-		/**
-		 *  Cast to ostream.
-		 */
-		inline operator std::ostream&() {
-			return (std::ostream&) cbuf;
-        }
-
-	   /**
-         *   Appends a string into the buffer and
-         *   fixes the buffer to use char characters.
-         *   @param msg message to append.
-         *   @return encapsulated CharMessageBuffer.
-         */
-        inline CharMessageBuffer& operator<<(const std::string& msg) {
-			return cbuf.operator<<(msg);
-		}
-        /**
-         *   Appends a string into the buffer and
-         *   fixes the buffer to use char characters.
-         *   @param msg message to append.
-         *   @return encapsulated CharMessageBuffer.
-         */
-        inline CharMessageBuffer& operator<<(const char* msg) {
-			return cbuf.operator<<(msg);
-		}
-
-        /**
-         *   Appends a string into the buffer and
-         *   fixes the buffer to use char characters.
-         *   @param msg message to append.
-         *   @return encapsulated CharMessageBuffer.
-         */
-        inline CharMessageBuffer& operator<<(const char msg) {
-			return cbuf.operator<<(msg);
-		}
-
-		/**
-		 *   Get content of buffer.
-		 *   @param buf used only to signal
-		 *       the character type and that
-		 *       the embedded stream was not used.
-		 */
-		inline const std::string& str(CharMessageBuffer& buf) {
-			return cbuf.str(buf);
-		}
-
-		/**
-		 *   Get content of buffer.
-		 *   @param os used only to signal 
-		 *       the character type and that
-		 *       the embedded stream was used.
-		 */
-		inline const std::string& str(std::ostream& os) {
-			return cbuf.str(os);
-		}
-
+	   ~MessageBuffer();
+
+		/**
+		 *  Cast to ostream.
+		 */
+		inline operator std::ostream&() {
+			return (std::ostream&) cbuf;
+        }
+
 	   /**
          *   Appends a string into the buffer and
          *   fixes the buffer to use char characters.
          *   @param msg message to append.
          *   @return encapsulated CharMessageBuffer.
          */
-        inline WideMessageBuffer& operator<<(const std::wstring& msg) {
-			wbuf = new WideMessageBuffer();
-			return (*wbuf) << msg;
-		}
+        inline CharMessageBuffer& operator<<(const std::string& msg) {
+			return cbuf.operator<<(msg);
+		}
+        /**
+         *   Appends a string into the buffer and
+         *   fixes the buffer to use char characters.
+         *   @param msg message to append.
+         *   @return encapsulated CharMessageBuffer.
+         */
+        inline CharMessageBuffer& operator<<(const char* msg) {
+			return cbuf.operator<<(msg);
+		}
+
+        /**
+         *   Appends a string into the buffer and
+         *   fixes the buffer to use char characters.
+         *   @param msg message to append.
+         *   @return encapsulated CharMessageBuffer.
+         */
+        inline CharMessageBuffer& operator<<(const char msg) {
+			return cbuf.operator<<(msg);
+		}
+
+		/**
+		 *   Get content of buffer.
+		 *   @param buf used only to signal
+		 *       the character type and that
+		 *       the embedded stream was not used.
+		 */
+		inline const std::string& str(CharMessageBuffer& buf) {
+			return cbuf.str(buf);
+		}
+
+		/**
+		 *   Get content of buffer.
+		 *   @param os used only to signal 
+		 *       the character type and that
+		 *       the embedded stream was used.
+		 */
+		inline const std::string& str(std::ostream& os) {
+			return cbuf.str(os);
+		}
+
+	   /**
+         *   Appends a string into the buffer and
+         *   fixes the buffer to use char characters.
+         *   @param msg message to append.
+         *   @return encapsulated CharMessageBuffer.
+         */
+        inline WideMessageBuffer& operator<<(const std::wstring& msg) {
+			wbuf = new WideMessageBuffer();
+			return (*wbuf) << msg;
+		}
         /**
          *   Appends a string into the buffer and
          *   fixes the buffer to use char characters.
@@ -295,9 +307,9 @@
          *   @return encapsulated CharMessageBuffer.
          */
         inline WideMessageBuffer& operator<<(const wchar_t* msg) {
-			wbuf = new WideMessageBuffer();
-			return (*wbuf) << msg;
-		}
+			wbuf = new WideMessageBuffer();
+			return (*wbuf) << msg;
+		}
         /**
          *   Appends a string into the buffer and
          *   fixes the buffer to use char characters.
@@ -305,76 +317,81 @@
          *   @return encapsulated CharMessageBuffer.
          */
         inline WideMessageBuffer& operator<<(const wchar_t msg) {
-			wbuf = new WideMessageBuffer();
-			return (*wbuf) << msg;
-		}
-
-		/**
-		 *   Get content of buffer.
-		 *   @param buf used only to signal
-		 *       the character type and that
-		 *       the embedded stream was not used.
-		 */
-		inline const std::wstring& str(WideMessageBuffer& buf) {
-			return wbuf->str(buf);
-		}
-
-		/**
-		 *   Get content of buffer.
-		 *   @param os used only to signal 
-		 *       the character type and that
-		 *       the embedded stream was used.
-		 */
-		inline const std::wstring& str(std::wostream& os) {
-			return wbuf->str(os);
-		}
-
-
-   private:
-        /**
-         * Prevent use of default copy constructor.
-         */
-        MessageBuffer(const MessageBuffer&);
-        /**
-         *   Prevent use of default assignment operator.  
-         */
-        MessageBuffer& operator=(const MessageBuffer&);
-
-        /**
-         *  Character message buffer.
-         */
-        CharMessageBuffer cbuf;
-
+			wbuf = new WideMessageBuffer();
+			return (*wbuf) << msg;
+		}
+
+		/**
+		 *   Get content of buffer.
+		 *   @param buf used only to signal
+		 *       the character type and that
+		 *       the embedded stream was not used.
+		 */
+		inline const std::wstring& str(WideMessageBuffer& buf) {
+			return wbuf->str(buf);
+		}
+
+		/**
+		 *   Get content of buffer.
+		 *   @param os used only to signal 
+		 *       the character type and that
+		 *       the embedded stream was used.
+		 */
+		inline const std::wstring& str(std::wostream& os) {
+			return wbuf->str(os);
+		}
+
+        /**
+         *  Returns true if buffer has an encapsulated STL stream.
+         *  @return true if STL stream was created.
+         */
+        bool hasStream() const;
+
+   private:
+        /**
+         * Prevent use of default copy constructor.
+         */
+        MessageBuffer(const MessageBuffer&);
+        /**
+         *   Prevent use of default assignment operator.  
+         */
+        MessageBuffer& operator=(const MessageBuffer&);
+
+        /**
+         *  Character message buffer.
+         */
+        CharMessageBuffer cbuf;
+
         /**
          * Encapsulated wide message buffer, created on demand.
          */
         WideMessageBuffer* wbuf;        
    };
 
-template<class V>
-std::ostream& operator<<(MessageBuffer& os, const V& val) {
-	return ((std::ostream&) os) << val;
-}
-
-inline std::ostream& operator<<(MessageBuffer& os, std::ios_base& (*manip)(std::ios_base& s)) {
-	std::ostream& s = os;
-	(*manip)(s);
-	return s;
-}
-
-#if LOG4CXX_LOGCHAR_IS_UTF8
-typedef CharMessageBuffer LogCharMessageBuffer;
-#endif
-
-#if LOG4CXX_LOGCHAR_IS_WCHAR
-typedef WideMessageBuffer LogCharMessageBuffer;
-#endif
-
-#else
-typedef CharMessageBuffer MessageBuffer;
-typedef CharMessageBuffer LogCharMessageBuffer;
-#endif
+template<class V>
+std::ostream& operator<<(MessageBuffer& os, const V& val) {
+	return ((std::ostream&) os) << val;
+}
+
+inline std::ostream& operator<<(MessageBuffer& os, std::ios_base& (*manip)(std::ios_base& s)) {
+	std::ostream& s = os;
+	(*manip)(s);
+	return s;
+}
+
+#if LOG4CXX_LOGCHAR_IS_UTF8
+typedef CharMessageBuffer LogCharMessageBuffer;
+#endif
+
+#if LOG4CXX_LOGCHAR_IS_WCHAR
+typedef WideMessageBuffer LogCharMessageBuffer;
+#endif
+
+#else
+typedef CharMessageBuffer MessageBuffer;
+typedef CharMessageBuffer LogCharMessageBuffer;
+#endif
 
 }}
-#endif
+#endif
 

Modified: logging/log4cxx/trunk/src/test/cpp/helpers/messagebuffertest.cpp
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/test/cpp/helpers/messagebuffertest.cpp?rev=593580&r1=593579&r2=593580&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/test/cpp/helpers/messagebuffertest.cpp (original)
+++ logging/log4cxx/trunk/src/test/cpp/helpers/messagebuffertest.cpp Fri Nov  9 08:11:55 2007
@@ -45,39 +45,31 @@
         std::string greeting("Hello, World");
         CharMessageBuffer& retval = buf << "Hello, Worl" << 'd';
         CPPUNIT_ASSERT_EQUAL(greeting, buf.str(retval)); 
+        CPPUNIT_ASSERT_EQUAL(false, buf.hasStream());
     }
 
     void testInsertCStr() {
         MessageBuffer buf;
         std::string greeting("Hello, World");
-#if LOG4CXX_SUPPORTS_MULTIPLE_OP_RETVAL		
-        CharMessageBuffer& retval = buf << "Hello" << ", World";
-#else
-		std::ostream& retval = buf << "Hello" << ", World";
-#endif
+        CharMessageBuffer& retval = buf << "Hello" << ", World";
         CPPUNIT_ASSERT_EQUAL(greeting, buf.str(retval)); 
+        CPPUNIT_ASSERT_EQUAL(false, buf.hasStream());
     }
 
     void testInsertString() {
         MessageBuffer buf;
         std::string greeting("Hello, World");
-#if LOG4CXX_SUPPORTS_MULTIPLE_OP_RETVAL		
-        CharMessageBuffer& retval = buf << std::string("Hello") << std::string(", World");
-#else
-        std::ostream& retval = buf << std::string("Hello") << std::string(", World");
-#endif
+        CharMessageBuffer& retval = buf << std::string("Hello") << std::string(", World");
         CPPUNIT_ASSERT_EQUAL(greeting, buf.str(retval)); 
+        CPPUNIT_ASSERT_EQUAL(false, buf.hasStream());
     }
     
     void testInsertNull() {
         MessageBuffer buf;
         std::string greeting("Hello, null");
-#if LOG4CXX_SUPPORTS_MULTIPLE_OP_RETVAL		
         CharMessageBuffer& retval = buf << "Hello, " << (const char*) 0;
-#else
-        std::ostream& retval = buf << "Hello, " << (const char*) 0;
-#endif
         CPPUNIT_ASSERT_EQUAL(greeting, buf.str(retval)); 
+        CPPUNIT_ASSERT_EQUAL(false, buf.hasStream());
     }
     
     void testInsertInt() {
@@ -85,6 +77,7 @@
         std::string greeting("Hello, 5");
         std::ostream& retval = buf << "Hello, " << 5;
         CPPUNIT_ASSERT_EQUAL(greeting, buf.str(retval));
+        CPPUNIT_ASSERT_EQUAL(true, buf.hasStream());
     }
         
     void testInsertManipulator() {
@@ -92,6 +85,7 @@
         std::string greeting("pi=3.142");
         std::ostream& retval = buf << "pi=" << std::setprecision(4) << 3.1415926;
         CPPUNIT_ASSERT_EQUAL(greeting, buf.str(retval));
+        CPPUNIT_ASSERT_EQUAL(true, buf.hasStream());
     }