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/21 01:39:06 UTC

svn commit: r596892 - in /logging/log4cxx/trunk/src: main/cpp/ main/include/log4cxx/helpers/ main/include/log4cxx/net/ main/include/log4cxx/spi/ main/include/log4cxx/spi/location/ test/cpp/ test/cpp/net/ test/cpp/rolling/ test/cpp/spi/ test/cpp/util/ t...

Author: carnold
Date: Tue Nov 20 16:38:44 2007
New Revision: 596892

URL: http://svn.apache.org/viewvc?rev=596892&view=rev
Log:
LOGCXX-7: SocketAppender binary format not compatible with Chainsaw

Added:
    logging/log4cxx/trunk/src/main/cpp/bytearrayoutputstream.cpp
    logging/log4cxx/trunk/src/main/cpp/objectoutputstream.cpp
    logging/log4cxx/trunk/src/main/include/log4cxx/helpers/bytearrayoutputstream.h
    logging/log4cxx/trunk/src/main/include/log4cxx/helpers/objectoutputstream.h
    logging/log4cxx/trunk/src/test/cpp/spi/
    logging/log4cxx/trunk/src/test/cpp/spi/loggingeventtest.cpp
    logging/log4cxx/trunk/src/test/cpp/util/serializationtesthelper.cpp
    logging/log4cxx/trunk/src/test/cpp/util/serializationtesthelper.h
    logging/log4cxx/trunk/src/test/resources/witness/serialization/
      - copied from r592094, logging/log4j/trunk/tests/witness/serialization/
Removed:
    logging/log4cxx/trunk/src/main/cpp/socketinputstream.cpp
    logging/log4cxx/trunk/src/main/cpp/socketnode.cpp
    logging/log4cxx/trunk/src/main/cpp/socketoutputstream.cpp
    logging/log4cxx/trunk/src/main/include/log4cxx/helpers/socketinputstream.h
    logging/log4cxx/trunk/src/main/include/log4cxx/helpers/socketoutputstream.h
    logging/log4cxx/trunk/src/main/include/log4cxx/net/socketnode.h
Modified:
    logging/log4cxx/trunk/src/main/cpp/Makefile.am
    logging/log4cxx/trunk/src/main/cpp/locationinfo.cpp
    logging/log4cxx/trunk/src/main/cpp/loggingevent.cpp
    logging/log4cxx/trunk/src/main/cpp/socket.cpp
    logging/log4cxx/trunk/src/main/cpp/socketappender.cpp
    logging/log4cxx/trunk/src/main/cpp/socketappenderskeleton.cpp
    logging/log4cxx/trunk/src/main/cpp/sockethubappender.cpp
    logging/log4cxx/trunk/src/main/cpp/telnetappender.cpp
    logging/log4cxx/trunk/src/main/cpp/xmlsocketappender.cpp
    logging/log4cxx/trunk/src/main/include/log4cxx/helpers/charsetencoder.h
    logging/log4cxx/trunk/src/main/include/log4cxx/helpers/socket.h
    logging/log4cxx/trunk/src/main/include/log4cxx/net/socketappender.h
    logging/log4cxx/trunk/src/main/include/log4cxx/net/socketappenderskeleton.h
    logging/log4cxx/trunk/src/main/include/log4cxx/net/sockethubappender.h
    logging/log4cxx/trunk/src/main/include/log4cxx/net/telnetappender.h
    logging/log4cxx/trunk/src/main/include/log4cxx/net/xmlsocketappender.h
    logging/log4cxx/trunk/src/main/include/log4cxx/spi/location/locationinfo.h
    logging/log4cxx/trunk/src/main/include/log4cxx/spi/loggingevent.h
    logging/log4cxx/trunk/src/test/cpp/Makefile.am
    logging/log4cxx/trunk/src/test/cpp/net/socketappendertestcase.cpp
    logging/log4cxx/trunk/src/test/cpp/net/telnetappendertestcase.cpp
    logging/log4cxx/trunk/src/test/cpp/rolling/filenamepatterntestcase.cpp

Modified: logging/log4cxx/trunk/src/main/cpp/Makefile.am
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/cpp/Makefile.am?rev=596892&r1=596891&r2=596892&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/cpp/Makefile.am (original)
+++ logging/log4cxx/trunk/src/main/cpp/Makefile.am Tue Nov 20 16:38:44 2007
@@ -27,6 +27,7 @@
         basicconfigurator.cpp \
         bufferedwriter.cpp \
         bytearrayinputstream.cpp \
+        bytearrayoutputstream.cpp \
         bytebuffer.cpp \
         cacheddateformat.cpp \
         charsetdecoder.cpp \
@@ -101,6 +102,7 @@
         nteventlogappender.cpp \
         objectimpl.cpp \
         objectptr.cpp \
+        objectoutputstream.cpp \
         obsoleterollingfileappender.cpp \
         odbcappender.cpp \
         onlyonceerrorhandler.cpp \
@@ -136,9 +138,6 @@
         socketappenderskeleton.cpp \
         sockethubappender.cpp \
         socketimpl.cpp \
-        socketinputstream.cpp \
-        socketnode.cpp \
-        socketoutputstream.cpp \
         strftimedateformat.cpp \
         stringhelper.cpp \
         stringmatchfilter.cpp \

Added: logging/log4cxx/trunk/src/main/cpp/bytearrayoutputstream.cpp
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/cpp/bytearrayoutputstream.cpp?rev=596892&view=auto
==============================================================================
--- logging/log4cxx/trunk/src/main/cpp/bytearrayoutputstream.cpp (added)
+++ logging/log4cxx/trunk/src/main/cpp/bytearrayoutputstream.cpp Tue Nov 20 16:38:44 2007
@@ -0,0 +1,52 @@
+/*
+ * 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/logstring.h>
+#include <log4cxx/helpers/bytearrayoutputstream.h>
+#include <log4cxx/helpers/exception.h>
+#include <log4cxx/helpers/bytebuffer.h>
+
+using namespace log4cxx;
+using namespace log4cxx::helpers;
+
+IMPLEMENT_LOG4CXX_OBJECT(ByteArrayOutputStream)
+
+ByteArrayOutputStream::ByteArrayOutputStream() {
+}
+
+ByteArrayOutputStream::~ByteArrayOutputStream() {
+}
+
+void ByteArrayOutputStream::close(Pool& /* p */) {
+}
+
+void ByteArrayOutputStream::flush(Pool& /* p */) {
+}
+
+void ByteArrayOutputStream::write(ByteBuffer& buf, Pool& /* p */ ) {
+  size_t sz = array.size();
+  array.resize(sz + buf.remaining());
+  memcpy(&array[sz], buf.current(), buf.remaining());
+  buf.position(buf.limit());
+}
+
+std::vector<unsigned char> ByteArrayOutputStream::toByteArray() const {
+  return array;
+}
+
+
+

Modified: logging/log4cxx/trunk/src/main/cpp/locationinfo.cpp
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/cpp/locationinfo.cpp?rev=596892&r1=596891&r2=596892&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/cpp/locationinfo.cpp (original)
+++ logging/log4cxx/trunk/src/main/cpp/locationinfo.cpp Tue Nov 20 16:38:44 2007
@@ -16,9 +16,13 @@
  */
 
 #include <log4cxx/spi/location/locationinfo.h>
-#include <sstream>
+#include <log4cxx/helpers/objectoutputstream.h>
+#include <log4cxx/helpers/pool.h>
+#include "apr_pools.h"
+#include "apr_strings.h"
 
 using namespace ::log4cxx::spi;
+using namespace log4cxx::helpers;
 
    /**
      When location information is not available the constant
@@ -139,4 +143,35 @@
         tmp.erase(0, tmp.length() );
         return tmp;
 }
+
+void LocationInfo::write(ObjectOutputStream& os, Pool& p) const {
+    if (lineNumber == -1 && fileName == NA && methodName == NA_METHOD) {
+         os.writeByte(ObjectOutputStream::TC_NULL, p);
+    } else {
+        char prolog[] = {
+			0x73, 0x72, 0x00, 0x21, 0x6F, 0x72, 0x67, 0x2E, 
+			0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2E, 0x6C, 
+			0x6F, 0x67, 0x34, 0x6A, 0x2E, 0x73, 0x70, 0x69, 
+			0x2E, 0x4C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 
+			0x6E, 0x49, 0x6E, 0x66, 0x6F, 0xED, 0x99, 0xBB, 
+			0xE1, 0x4A, 0x91, 0xA5, 0x7C, 0x02, 0x00, 0x01, 
+			0x4C, 0x00, 0x08, 0x66, 0x75, 0x6C, 0x6C, 0x49, 
+			0x6E, 0x66, 0x6F, 0x71, 0x00, 0x7E, 0x00, 0x01, 
+			0x78, 0x70, 0x74 };
+		os.writeBytes(prolog, sizeof(prolog), p);
+        char* line = apr_itoa((apr_pool_t*) p.getAPRPool(), lineNumber);
+        size_t len = strlen(methodName) + strlen(fileName) + 3 + strlen(line);
+        char lenBytes[2];
+        lenBytes[1] = len & 0xFF;
+        lenBytes[0] = (len >> 8) & 0xFF;
+        os.writeBytes(lenBytes, sizeof(lenBytes), p);
+        os.writeBytes(methodName, strlen(methodName), p);
+        os.writeByte('(', p);
+        os.writeBytes(fileName, strlen(fileName), p);
+        os.writeByte(':', p);
+        os.writeBytes(line, strlen(line), p);
+        os.writeByte(')', p); 
+    }
+}
+
 

Modified: logging/log4cxx/trunk/src/main/cpp/loggingevent.cpp
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/cpp/loggingevent.cpp?rev=596892&r1=596891&r2=596892&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/cpp/loggingevent.cpp (original)
+++ logging/log4cxx/trunk/src/main/cpp/loggingevent.cpp Tue Nov 20 16:38:44 2007
@@ -19,8 +19,6 @@
 #include <log4cxx/ndc.h>
 
 #include <log4cxx/level.h>
-#include <log4cxx/helpers/socketoutputstream.h>
-#include <log4cxx/helpers/socketinputstream.h>
 #include <log4cxx/helpers/loglog.h>
 #include <log4cxx/helpers/system.h>
 #include <log4cxx/helpers/socket.h>
@@ -32,6 +30,8 @@
 #include <apr_portable.h>
 #include <apr_strings.h>
 #include <log4cxx/helpers/stringhelper.h>
+#include <log4cxx/helpers/objectoutputstream.h>
+#include <log4cxx/helpers/bytebuffer.h>
 
 using namespace log4cxx;
 using namespace log4cxx::spi;
@@ -213,103 +213,6 @@
 #endif
 }
 
-void LoggingEvent::read(const helpers::SocketInputStreamPtr& /* is */)
-{
-#if 0
-        // fqnOfLoggerClass
-        is->read(fqnOfLoggerClass);
-
-        // name
-        LogString name;
-        is->read(name);
-        logger = Logger::getLogger(name);
-
-        // level
-        readLevel(is);
-
-        // message
-        is->read(message);
-
-        // timeStamp
-        is->read(&timeStamp, sizeof(timeStamp));
-
-        // file
-        String buffer;
-        is->read(buffer);
-
-        if (!buffer.empty())
-        {
-                USES_CONVERSION;
-                fileFromStream = T2A(buffer.c_str());
-                file = (char *)fileFromStream.c_str();
-        }
-
-        // line
-        is->read(line);
-
-        // ndc
-        is->read(ndc);
-        ndcLookupRequired = false;
-
-        // mdc
-        String key, value;
-        int n, size;
-        is->read(size);
-        for (n = 0; n < size; n++)
-        {
-                is->read(key);
-                is->read(value);
-                mdcCopy[key] = value;
-        }
-        mdcCopyLookupRequired = false;
-
-        // properties
-        is->read(size);
-        for (n = 0; n < size; n++)
-        {
-                is->read(key);
-                is->read(value);
-                setProperty(key, value);
-        }
-
-        // threadId
-        is->read(threadId);
-#endif
-}
-
-void LoggingEvent::readLevel(const helpers::SocketInputStreamPtr& /* is */)
-{
-  #if 0
-        int levelInt;
-        is->read(levelInt);
-
-    String className;
-        is->read(className);
-
-        if (className.empty())
-        {
-                level = Level::toLevel(levelInt);
-        }
-        else try
-        {
-                Level::LevelClass& levelClass =
-                        (Level::LevelClass&)Loader::loadClass(className);
-                level = levelClass.toLevel(levelInt);
-        }
-        catch (Exception& oops)
-        {
-                LogLog::warn(
-                        _T("Level deserialization failed, reverting to default."), oops);
-                level = Level::toLevel(levelInt);
-        }
-        catch (...)
-        {
-                LogLog::warn(
-                        _T("Level deserialization failed, reverting to default."));
-                level = Level::toLevel(levelInt);
-        }
-#endif
-}
 
 void LoggingEvent::setProperty(const LogString& key, const LogString& value)
 {
@@ -321,83 +224,86 @@
         (*properties)[key] = value;
 }
 
-void LoggingEvent::write(helpers::SocketOutputStreamPtr& /* os */) const
-{
-  #if 0
-        // fqnOfLoggerClass
-        os->write(fqnOfLoggerClass);
-
-        // name
-        os->write(logger->getName());
-
-        // level
-        writeLevel(os);
-
-        // message
-        os->write(message);
-
-        // timeStamp
-        os->write(&timeStamp, sizeof(timeStamp));
-
-        // file
-        String buffer;
-        if (file != 0)
-        {
-                USES_CONVERSION;
-                buffer = A2T(file);
-        }
-        os->write(buffer);
-
-        // line
-        os->write(line);
-
-        // ndc
-        os->write(getNDC());
-
-        // mdc
-        getMDCCopy();
-        os->write((int)mdcCopy.size());
-        MDC::Map::const_iterator it;
-        for (it = mdcCopy.begin(); it != mdcCopy.end(); it++)
-        {
-                os->write(it->first);
-                os->write(it->second);
-        }
-
-        // properties
-        int size = (properties != 0) ? (int)properties->size() : 0;
-        os->write(size);
-
-        if (size > 0)
-        {
-                std::map<String, String>::const_iterator it;
-                for (it = properties->begin(); it != properties->end(); it++)
-                {
-                        os->write(it->first);
-                        os->write(it->second);
-                }
-        }
-
-        // threadId
-        os->write(threadId);
-#endif
-}
-
-void LoggingEvent::writeLevel(helpers::SocketOutputStreamPtr& /* os */) const
-{
-#if 0
-        os->write(level->toInt());
 
-        const Class& clazz = level->getClass();
 
-        if (&clazz == &Level::getStaticClass())
-        {
-                os->write(String());
-        }
-        else
-        {
-                os->write(clazz.getName());
-        }
-#endif
+void LoggingEvent::writeClassDesc(ObjectOutputStream& os, Pool& p) {
+     char classDesc[] = {
+        0x72, 0x00, 0x21, 
+        0x6F, 0x72, 0x67, 0x2E, 0x61, 0x70, 0x61, 0x63, 
+        0x68, 0x65, 0x2E, 0x6C, 0x6F, 0x67, 0x34, 0x6A, 
+        0x2E, 0x73, 0x70, 0x69, 0x2E, 0x4C, 0x6F, 0x67, 
+        0x67, 0x69, 0x6E, 0x67, 0x45, 0x76, 0x65, 0x6E, 
+        0x74, 0xF3, 0xF2, 0xB9, 0x23, 0x74, 0x0B, 0xB5, 
+        0x3F, 0x03, 0x00, 0x0A, 0x5A, 0x00, 0x15, 0x6D, 
+        0x64, 0x63, 0x43, 0x6F, 0x70, 0x79, 0x4C, 0x6F, 
+        0x6F, 0x6B, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 
+        0x69, 0x72, 0x65, 0x64, 0x5A, 0x00, 0x11, 0x6E, 
+        0x64, 0x63, 0x4C, 0x6F, 0x6F, 0x6B, 0x75, 0x70, 
+        0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 
+        0x4A, 0x00, 0x09, 0x74, 0x69, 0x6D, 0x65, 0x53, 
+        0x74, 0x61, 0x6D, 0x70, 0x4C, 0x00, 0x0C, 0x63, 
+        0x61, 0x74, 0x65, 0x67, 0x6F, 0x72, 0x79, 0x4E, 
+        0x61, 0x6D, 0x65, 0x74, 0x00, 0x12, 0x4C, 0x6A, 
+        0x61, 0x76, 0x61, 0x2F, 0x6C, 0x61, 0x6E, 0x67, 
+        0x2F, 0x53, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x3B, 
+        0x4C, 0x00, 0x0C, 0x6C, 0x6F, 0x63, 0x61, 0x74, 
+        0x69, 0x6F, 0x6E, 0x49, 0x6E, 0x66, 0x6F, 0x74, 
+        0x00, 0x23, 0x4C, 0x6F, 0x72, 0x67, 0x2F, 0x61, 
+        0x70, 0x61, 0x63, 0x68, 0x65, 0x2F, 0x6C, 0x6F, 
+        0x67, 0x34, 0x6A, 0x2F, 0x73, 0x70, 0x69, 0x2F, 
+        0x4C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 
+        0x49, 0x6E, 0x66, 0x6F, 0x3B, 0x4C, 0x00, 0x07, 
+        0x6D, 0x64, 0x63, 0x43, 0x6F, 0x70, 0x79, 0x74, 
+        0x00, 0x15, 0x4C, 0x6A, 0x61, 0x76, 0x61, 0x2F, 
+        0x75, 0x74, 0x69, 0x6C, 0x2F, 0x48, 0x61, 0x73, 
+        0x68, 0x74, 0x61, 0x62, 0x6C, 0x65, 0x3B, 0x4C, 
+        0x00, 0x03, 0x6E, 0x64, 0x63, 0x71, 0x00, 0x7E, 
+        0x00, 0x01, 0x4C, 0x00, 0x0F, 0x72, 0x65, 0x6E, 
+        0x64, 0x65, 0x72, 0x65, 0x64, 0x4D, 0x65, 0x73, 
+        0x73, 0x61, 0x67, 0x65, 0x71, 0x00, 0x7E, 0x00, 
+        0x01, 0x4C, 0x00, 0x0A, 0x74, 0x68, 0x72, 0x65, 
+        0x61, 0x64, 0x4E, 0x61, 0x6D, 0x65, 0x71, 0x00, 
+        0x7E, 0x00, 0x01, 0x4C, 0x00, 0x0D, 0x74, 0x68, 
+        0x72, 0x6F, 0x77, 0x61, 0x62, 0x6C, 0x65, 0x49, 
+        0x6E, 0x66, 0x6F, 0x74, 0x00, 0x2B, 0x4C, 0x6F, 
+        0x72, 0x67, 0x2F, 0x61, 0x70, 0x61, 0x63, 0x68, 
+        0x65, 0x2F, 0x6C, 0x6F, 0x67, 0x34, 0x6A, 0x2F, 
+        0x73, 0x70, 0x69, 0x2F, 0x54, 0x68, 0x72, 0x6F, 
+        0x77, 0x61, 0x62, 0x6C, 0x65, 0x49, 0x6E, 0x66, 
+        0x6F, 0x72, 0x6D, 0x61, 0x74, 0x69, 0x6F, 0x6E, 
+        0x3B, 0x78, 0x70 }; 
+
+     os.writeBytes(classDesc, sizeof(classDesc), p);
+     
+}
+
+void LoggingEvent::write(helpers::ObjectOutputStream& os, Pool& p) const {
+      os.writeByte(ObjectOutputStream::TC_OBJECT, p);
+      writeClassDesc(os, p);
+      // mdc and ndc lookup required should always be false
+      char lookupsRequired[] = { 0, 0 };
+      os.writeBytes(lookupsRequired, sizeof(lookupsRequired), p);
+      os.writeLong(timeStamp/1000, p);
+      os.writeObject(logger->getName(), p);
+      locationInfo.write(os, p);
+      if (mdcCopy.size() == 0) {
+          os.writeByte(ObjectOutputStream::TC_NULL, p);
+      } else {
+          os.writeObject(mdcCopy, p);
+      }
+      if (ndc.size() == 0) {
+          os.writeByte(ObjectOutputStream::TC_NULL, p);
+      } else {
+          os.writeObject(ndc, p);
+      }
+      os.writeObject(message, p);
+      os.writeObject(threadName, p);
+      //  throwable
+      os.writeByte(ObjectOutputStream::TC_NULL, p);
+      os.writeByte(ObjectOutputStream::TC_BLOCKDATA, p);
+      os.writeByte(0x04, p);
+      os.writeInt(level->toInt(), p);
+      os.writeByte(ObjectOutputStream::TC_NULL, p);
+      os.writeByte(ObjectOutputStream::TC_ENDBLOCKDATA, p);
 }
 

Added: logging/log4cxx/trunk/src/main/cpp/objectoutputstream.cpp
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/cpp/objectoutputstream.cpp?rev=596892&view=auto
==============================================================================
--- logging/log4cxx/trunk/src/main/cpp/objectoutputstream.cpp (added)
+++ logging/log4cxx/trunk/src/main/cpp/objectoutputstream.cpp Tue Nov 20 16:38:44 2007
@@ -0,0 +1,144 @@
+/*
+ * 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/logstring.h>
+#include <log4cxx/helpers/objectoutputstream.h>
+#include <log4cxx/helpers/bytebuffer.h>
+#include <log4cxx/helpers/outputstream.h>
+#include <log4cxx/helpers/charsetencoder.h>
+#include "apr_pools.h"
+
+using namespace log4cxx;
+using namespace log4cxx::helpers;
+
+IMPLEMENT_LOG4CXX_OBJECT(ObjectOutputStream)
+
+ObjectOutputStream::ObjectOutputStream(OutputStreamPtr outputStream, Pool& p) : os(outputStream) 
+#if !LOG4CXX_LOGCHAR_IS_UTF8
+     , utf8Encoder(CharsetEncoder::getUTF8Encoder())
+#endif
+{
+   char start[] = { 0xAC, 0xED, 0x00, 0x05 };
+   ByteBuffer buf(start, sizeof(start));
+   os->write(buf, p);
+}
+
+ObjectOutputStream::~ObjectOutputStream() {
+}
+
+void ObjectOutputStream::close(Pool& p) {
+    os->close(p);
+}
+
+void ObjectOutputStream::writeObject(const LogString& val, Pool& p) {
+   writeByte(TC_STRING, p);
+   writeUTF(val, p);
+}
+
+
+void ObjectOutputStream::writeObject(const std::map<LogString, LogString>& val, Pool& p) {
+    //
+    //  TC_OBJECT and the classDesc for java.util.Hashtable
+    //
+    char prolog[] = {
+        0x73, 0x72, 0x00, 0x13, 0x6A, 0x61, 0x76, 0x61, 
+        0x2E, 0x75, 0x74, 0x69, 0x6C, 0x2E, 0x48, 0x61, 
+        0x73, 0x68, 0x74, 0x61, 0x62, 0x6C, 0x65, 0x13, 
+        0xBB, 0x0F, 0x25, 0x21, 0x4A, 0xE4, 0xB8, 0x03, 
+        0x00, 0x02, 0x46, 0x00, 0x0A, 0x6C, 0x6F, 0x61, 
+        0x64, 0x46, 0x61, 0x63, 0x74, 0x6F, 0x72, 0x49, 
+        0x00, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 
+        0x6F, 0x6C, 0x64, 0x78, 0x70  };
+    ByteBuffer prologBuf(prolog, sizeof(prolog));
+    os->write(prologBuf, p);
+    //
+    //   loadFactor = 0.75, threshold = 5, blockdata start, buckets.size = 7
+    char data[] = { 0x3F, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 
+        TC_BLOCKDATA, 0x08, 0x00, 0x00, 0x00, 0x07 };
+    ByteBuffer dataBuf(data, sizeof(data));
+    os->write(dataBuf, p);
+    char size[4];
+    size_t sz = val.size();
+    size[3] = sz & 0xFF;
+    size[2] = (sz >> 8) & 0xFF;
+    size[1] = (sz >> 16) & 0xFF;
+    size[0] = (sz >> 24) & 0xFF;
+    ByteBuffer sizeBuf(size, sizeof(size));
+    os->write(sizeBuf, p);
+    for(std::map<LogString, LogString>::const_iterator iter = val.begin();
+        iter != val.end();
+        iter++) {
+        writeObject(iter->first, p);
+        writeObject(iter->second, p);
+    }
+    writeByte(TC_ENDBLOCKDATA, p);
+}
+
+void ObjectOutputStream::writeUTF(const LogString& val, Pool& p) {
+    char bytes[2];
+#if LOG4CXX_LOGCHAR_IS_UTF8
+    size_t len = val.size();
+    ByteBuffer dataBuf(const_cast<char*>(val.data()), val.size()); 
+#else
+    size_t maxSize = 6 * val.size();
+    char* data = (char*) apr_palloc((apr_pool_t*) p.getAPRPool(), maxSize);
+    ByteBuffer dataBuf(data, maxSize);
+    LogString::const_iterator iter(val.begin());
+    utf8Encoder->encode(val, iter, dataBuf); 
+    dataBuf.flip();
+    size_t len = dataBuf.limit();
+#endif
+   bytes[1] = len & 0xFF;
+   bytes[0] = (len >> 8) & 0xFF;
+   ByteBuffer lenBuf(bytes, sizeof(bytes));
+   os->write(lenBuf, p);
+   os->write(dataBuf, p);
+}
+
+void ObjectOutputStream::writeByte(char val, Pool& p) {
+   ByteBuffer buf(&val, 1);
+   os->write(buf, p);
+}
+
+void ObjectOutputStream::writeInt(int val, Pool& p) {
+   char bytes[4];
+   bytes[3] = val & 0xFF;
+   bytes[2] = (val >> 8) & 0xFF;
+   bytes[1] = (val >> 16) & 0xFF;
+   bytes[0] = (val >> 24) & 0xFF;
+   ByteBuffer buf(bytes, sizeof(bytes));
+   os->write(buf, p);
+}
+
+void ObjectOutputStream::writeLong(log4cxx_time_t val, Pool& p) {
+   char bytes[8];
+   bytes[7] = val & 0xFF;
+   bytes[6] = (val >> 8) & 0xFF;
+   bytes[5] = (val >> 16) & 0xFF;
+   bytes[4] = (val >> 24) & 0xFF;
+   bytes[3] = (val >> 32) & 0xFF;
+   bytes[2] = (val >> 40) & 0xFF;
+   bytes[1] = (val >> 48) & 0xFF;
+   bytes[0] = (val >> 56) & 0xFF;
+   ByteBuffer buf(bytes, sizeof(bytes));
+   os->write(buf, p);
+}
+
+void ObjectOutputStream::writeBytes(const char* bytes, size_t len, Pool& p) {
+   ByteBuffer buf(const_cast<char*>(bytes), len);
+   os->write(buf, p);
+}

Modified: logging/log4cxx/trunk/src/main/cpp/socket.cpp
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/cpp/socket.cpp?rev=596892&r1=596891&r2=596892&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/cpp/socket.cpp (original)
+++ logging/log4cxx/trunk/src/main/cpp/socket.cpp Tue Nov 20 16:38:44 2007
@@ -17,8 +17,6 @@
 #include <log4cxx/logstring.h>
 #include <log4cxx/helpers/socket.h>
 #include <log4cxx/helpers/loglog.h>
-#include <log4cxx/helpers/socketoutputstream.h>
-#include <log4cxx/helpers/socketinputstream.h>
 
 using namespace log4cxx;
 using namespace log4cxx::helpers;
@@ -80,17 +78,4 @@
    socketImpl->connect(host, port);
    socketImpl->bind(localAddr, localPort);
 }
-
-/**  Returns an output stream for this socket. */
-SocketOutputStreamPtr Socket::getOutputStream()
-{
-   return new SocketOutputStream(this);
-}
-
-/**  Returns an input stream for this socket. */
-SocketInputStreamPtr Socket::getInputStream()
-{
-   return new SocketInputStream(this);
-}
-
 

Modified: logging/log4cxx/trunk/src/main/cpp/socketappender.cpp
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/cpp/socketappender.cpp?rev=596892&r1=596891&r2=596892&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/cpp/socketappender.cpp (original)
+++ logging/log4cxx/trunk/src/main/cpp/socketappender.cpp Tue Nov 20 16:38:44 2007
@@ -17,14 +17,15 @@
 
 #include <log4cxx/net/socketappender.h>
 #include <log4cxx/helpers/loglog.h>
-#include <log4cxx/helpers/socketoutputstream.h>
 #include <log4cxx/helpers/optionconverter.h>
 #include <log4cxx/helpers/stringhelper.h>
 #include <log4cxx/spi/loggingevent.h>
 #include <log4cxx/helpers/synchronized.h>
+#include <log4cxx/helpers/objectoutputstream.h>
 #include <apr_time.h>
 #include <apr_atomic.h>
 #include <apr_thread_proc.h>
+#include <log4cxx/helpers/bytearrayoutputstream.h>
 
 using namespace log4cxx;
 using namespace log4cxx::helpers;
@@ -63,10 +64,10 @@
 }
 
 void SocketAppender::renderEvent(const spi::LoggingEventPtr& event,
-     helpers::SocketOutputStreamPtr& os1,
-     Pool& /* p */)
-{
-        event->write(os1);
+     const helpers::OutputStreamPtr& os1,
+     Pool& p) {
+        ObjectOutputStream os(os1, p);
+        event->write(os, p);
 }
 
 #endif

Modified: logging/log4cxx/trunk/src/main/cpp/socketappenderskeleton.cpp
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/cpp/socketappenderskeleton.cpp?rev=596892&r1=596891&r2=596892&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/cpp/socketappenderskeleton.cpp (original)
+++ logging/log4cxx/trunk/src/main/cpp/socketappenderskeleton.cpp Tue Nov 20 16:38:44 2007
@@ -18,7 +18,6 @@
 #define __STDC_CONSTANT_MACROS
 #include <log4cxx/net/socketappenderskeleton.h>
 #include <log4cxx/helpers/loglog.h>
-#include <log4cxx/helpers/socketoutputstream.h>
 #include <log4cxx/helpers/optionconverter.h>
 #include <log4cxx/helpers/stringhelper.h>
 #include <log4cxx/spi/loggingevent.h>
@@ -27,6 +26,7 @@
 #include <apr_atomic.h>
 #include <apr_thread_proc.h>
 #include <log4cxx/helpers/transcoder.h>
+#include <log4cxx/helpers/bytearrayoutputstream.h>
 
 
 using namespace log4cxx;
@@ -36,11 +36,10 @@
 #if APR_HAS_THREADS
 
 SocketAppenderSkeleton::SocketAppenderSkeleton(int defaultPort, int reconnectionDelay1)
-:  pool(),
-   remoteHost(),
+:  remoteHost(),
    address(),
    port(defaultPort),
-   os(),
+   socket(),
    reconnectionDelay(reconnectionDelay1),
    locationInfo(false),
    thread() {
@@ -48,11 +47,10 @@
 
 SocketAppenderSkeleton::SocketAppenderSkeleton(InetAddressPtr address1, int port1, int delay)
 :
-   pool(),
    remoteHost(),
    address(address1),
    port(port1),
-   os(),
+   socket(),
    reconnectionDelay(delay),
    locationInfo(false),
    thread() {
@@ -60,11 +58,10 @@
 }
 
 SocketAppenderSkeleton::SocketAppenderSkeleton(const LogString& host, int port1, int delay)
-:   pool(),
-    remoteHost(host),
+:   remoteHost(host),
     address(InetAddress::getByName(host)),
         port(port1),
-    os(),
+    socket(),
     reconnectionDelay(delay),
         locationInfo(false),
         thread() {
@@ -115,23 +112,22 @@
                 return;
         }
 
-        if(os != 0) try
-        {
+        if(socket != 0) {
+            try {
+                ByteArrayOutputStreamPtr byteStream(new ByteArrayOutputStream());
+                OutputStreamPtr os(byteStream);
                 renderEvent(event, os, p);
-
-                // flush to socket
-                os->flush();
-        }
-        catch(SocketException& e)
-        {
-                os = 0;
+                std::vector<unsigned char> bytes(byteStream->toByteArray());
+                socket->write(&bytes[0], bytes.size());
+            }
+            catch(SocketException& e) {
+                socket = 0;
                 LogLog::warn(LOG4CXX_STR("Detected problem with connection: "), e);
 
-                if(reconnectionDelay > 0)
-                {
+                if(reconnectionDelay > 0) {
                         fireConnector();
                 }
-
+            }
         }
 }
 
@@ -147,18 +143,18 @@
 
 void SocketAppenderSkeleton::cleanUp()
 {
-        if(os != 0)
+        if(socket != 0)
         {
                 try
                 {
-                        os->close();
+                        socket->close();
                 }
                 catch(IOException& e)
                 {
                         LogLog::error(LOG4CXX_STR("Could not close socket :"), e);
                 }
 
-                os = 0;
+                socket = 0;
         }
 
         thread.join();
@@ -176,8 +172,7 @@
                 // First, close the previous connection if any.
                 cleanUp();
 
-                SocketPtr socket = new Socket(address, port);
-                os = socket->getOutputStream();
+                socket = new Socket(address, port);
         }
         catch(SocketException& e)
         {
@@ -220,7 +215,7 @@
 
                         synchronized sync(socketAppender->mutex);
                         {
-                                socketAppender->os = socket->getOutputStream();
+                                socketAppender->socket = socket;
                                 LogLog::debug(LOG4CXX_STR("Connection established. Exiting connector thread."));
                                 socketAppender->thread.ending();
                                 return NULL;

Modified: logging/log4cxx/trunk/src/main/cpp/sockethubappender.cpp
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/cpp/sockethubappender.cpp?rev=596892&r1=596891&r2=596892&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/cpp/sockethubappender.cpp (original)
+++ logging/log4cxx/trunk/src/main/cpp/sockethubappender.cpp Tue Nov 20 16:38:44 2007
@@ -18,7 +18,6 @@
 #include <log4cxx/net/sockethubappender.h>
 
 #include <log4cxx/helpers/loglog.h>
-#include <log4cxx/helpers/socketoutputstream.h>
 #include <log4cxx/helpers/optionconverter.h>
 #include <log4cxx/helpers/stringhelper.h>
 #include <log4cxx/helpers/serversocket.h>
@@ -26,6 +25,8 @@
 #include <log4cxx/helpers/synchronized.h>
 #include <apr_atomic.h>
 #include <apr_thread_proc.h>
+#include <log4cxx/helpers/objectoutputstream.h>
+#include <log4cxx/helpers/bytearrayoutputstream.h>
 
 using namespace log4cxx;
 using namespace log4cxx::helpers;
@@ -44,12 +45,12 @@
 }
 
 SocketHubAppender::SocketHubAppender()
- : port(DEFAULT_PORT), oosList(), locationInfo(false), thread()
+ : port(DEFAULT_PORT), sockets(), locationInfo(false), thread()
 {
 }
 
 SocketHubAppender::SocketHubAppender(int port1)
- : port(port1), oosList(), locationInfo(false), thread()
+ : port(port1), sockets(), locationInfo(false), thread()
 {
         startServer();
 }
@@ -96,57 +97,58 @@
         synchronized sync(mutex);
         // close all of the connections
         LogLog::debug(LOG4CXX_STR("closing client connections"));
-        for (std::vector<helpers::SocketOutputStreamPtr>::iterator iter = oosList.begin();
-             iter != oosList.end();
+        for (std::vector<helpers::SocketPtr>::iterator iter = sockets.begin();
+             iter != sockets.end();
                  iter++) {
                  if ( (*iter) != NULL) {
                          try {
                                 (*iter)->close();
                          } catch(SocketException& e) {
-                                LogLog::error(LOG4CXX_STR("could not close oos: "), e);
+                                LogLog::error(LOG4CXX_STR("could not close socket: "), e);
                          }
                  }
          }
-        oosList.erase(oosList.begin(), oosList.end());
+        sockets.erase(sockets.begin(), sockets.end());
 
 
         LogLog::debug(LOG4CXX_STR("SocketHubAppender ")
               + getName() + LOG4CXX_STR(" closed"));
 }
 
-void SocketHubAppender::append(const spi::LoggingEventPtr& event, Pool& /* p */ )
+void SocketHubAppender::append(const spi::LoggingEventPtr& event, Pool& p)
 {
 
         // if no open connections, exit now
-        if(oosList.empty())
+        if(sockets.empty())
         {
                 return;
         }
 
+        ByteArrayOutputStreamPtr os(new ByteArrayOutputStream());
+        ObjectOutputStream objStream(os, p);
+        event->write(objStream, p);
+        std::vector<unsigned char> bytes(os->toByteArray());
 
         // loop through the current set of open connections, appending the event to each
-        std::vector<SocketOutputStreamPtr>::iterator it = oosList.begin();
-        std::vector<SocketOutputStreamPtr>::iterator itEnd = oosList.end();
+        std::vector<SocketPtr>::iterator it = sockets.begin();
+        std::vector<SocketPtr>::iterator itEnd = sockets.end();
         while(it != itEnd)
         {
-                SocketOutputStreamPtr oos = *it;
-
                 // list size changed unexpectedly? Just exit the append.
-                if (oos == 0)
+                if (*it == 0)
                 {
                         break;
                 }
 
                 try
                 {
-                        event->write(oos);
-                        oos->flush();
+                        (*it)->write(&bytes[0], bytes.size());
                         it++;
                 }
                 catch(SocketException&)
                 {
                         // there was an io exception so just drop the connection
-                        it = oosList.erase(it);
+                        it = sockets.erase(it);
                         LogLog::debug(LOG4CXX_STR("dropped connection"));
                 }
         }
@@ -207,12 +209,9 @@
                                        + remoteAddress->getHostAddress()
                                        + LOG4CXX_STR(")"));
 
-                                // create an ObjectOutputStream
-                                SocketOutputStreamPtr oos = socket->getOutputStream();
-
                                 // add it to the oosList.
                                 synchronized sync(pThis->mutex);
-                                pThis->oosList.push_back(oos);
+                                pThis->sockets.push_back(socket);
                         }
                         catch (IOException& e)
                         {

Modified: logging/log4cxx/trunk/src/main/cpp/telnetappender.cpp
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/cpp/telnetappender.cpp?rev=596892&r1=596891&r2=596892&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/cpp/telnetappender.cpp (original)
+++ logging/log4cxx/trunk/src/main/cpp/telnetappender.cpp Tue Nov 20 16:38:44 2007
@@ -17,13 +17,14 @@
 
 #include <log4cxx/net/telnetappender.h>
 #include <log4cxx/helpers/loglog.h>
-#include <log4cxx/helpers/socketoutputstream.h>
 #include <log4cxx/helpers/optionconverter.h>
 #include <log4cxx/helpers/stringhelper.h>
 #include <log4cxx/helpers/synchronized.h>
 #include <apr_thread_proc.h>
 #include <apr_atomic.h>
 #include <apr_strings.h>
+#include <log4cxx/helpers/charsetencoder.h>
+#include <log4cxx/helpers/bytebuffer.h>
 
 using namespace log4cxx;
 using namespace log4cxx::helpers;
@@ -41,6 +42,8 @@
 
 TelnetAppender::TelnetAppender()
   : port(DEFAULT_PORT), connections(MAX_CONNECTIONS),
+    encoding(LOG4CXX_STR("UTF-8")), 
+    encoder(CharsetEncoder::getUTF8Encoder()), 
     serverSocket(NULL), sh()
 {
    synchronized sync(mutex);
@@ -68,12 +71,28 @@
         {
                 setPort(OptionConverter::toInt(value, DEFAULT_PORT));
         }
+        else if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("ENCODING"), LOG4CXX_STR("encoding")))
+        {
+                setEncoding(value);
+        }
         else
         {
                 AppenderSkeleton::setOption(option, value);
         }
 }
 
+LogString TelnetAppender::getEncoding() const {
+    synchronized sync(mutex);
+    return encoding;
+}
+
+void TelnetAppender::setEncoding(const LogString& value) {
+    synchronized sync(mutex);
+    encoder = CharsetEncoder::getEncoder(value);
+    encoding = value;
+}
+
+
 void TelnetAppender::close()
 {
         synchronized sync(mutex);
@@ -82,27 +101,18 @@
         sh.stop();
 
         SocketPtr nullSocket;
-        SocketOutputStreamPtr nullStream;
         for(ConnectionList::iterator iter = connections.begin();
             iter != connections.end();
-                iter++) {
-                if (iter->first != NULL) {
-                        try {
-                                iter->second->close();
-                        } catch(Exception& ex) {
-                        }
-                        iter->second = nullStream;
-                        try {
-                                iter->first->close();
-                        } catch(Exception& ex) {
-                        }
-                        iter->first = nullSocket;
-                }
+            iter++) {
+            if (*iter != 0) {
+                (*iter)->close();
+                *iter = nullSocket;
+            }
         }
 
         if (serverSocket != NULL) {
                 try {
-                        serverSocket->close();
+                    serverSocket->close();
                 } catch(Exception&) {
                 }
         }
@@ -110,35 +120,66 @@
         activeConnections = 0;
 }
 
-void TelnetAppender::append(const spi::LoggingEventPtr& event, Pool& /* p */)
-{
-        size_t count = activeConnections;
-        if (count > 0) {
-                LogString os;
 
-                this->layout->format(os, event, pool);
-                os.append(LOG4CXX_STR("\r\n"));
+void TelnetAppender::write(ByteBuffer& buf) {
+        for (ConnectionList::iterator iter = connections.begin();
+             iter != connections.end();
+             iter++) {
+             if (*iter != 0) {
+                try {
+                    (*iter)->write(buf.current(), buf.remaining());
+                } catch(Exception& ex) {
+                    // The client has closed the connection, remove it from our list:
+                    *iter = 0;
+                    activeConnections--;
+                }
+            }
+        }
+}
 
-                SocketPtr nullSocket;
-                SocketOutputStreamPtr nullStream;
+void TelnetAppender::writeStatus(const SocketPtr& socket, const LogString& msg, Pool& p) {
+        size_t bytesSize = msg.size() * 2;
+        void* bytes = apr_palloc((apr_pool_t*) p.getAPRPool(), bytesSize);
+                
+        LogString::const_iterator msgIter(msg.begin());
+        ByteBuffer buf((char*) bytes, bytesSize);
 
-                synchronized sync(this->mutex);
+        while(msgIter != msg.end()) {
+            encoder->encode(msg, msgIter, buf);
+            buf.flip();
+            socket->write(buf.current(), buf.remaining());
+            buf.clear();
+        }
+}
 
+void TelnetAppender::append(const spi::LoggingEventPtr& event, Pool& p)
+{
+        size_t count = activeConnections;
+        if (count > 0) {
+                LogString msg;
+                this->layout->format(msg, event, pool);
+                msg.append(LOG4CXX_STR("\r\n"));
+                size_t bytesSize = msg.size() * 2;
+                void* bytes = apr_palloc((apr_pool_t*) p.getAPRPool(), bytesSize);
+                
+                LogString::const_iterator msgIter(msg.begin());
+                ByteBuffer buf((char*) bytes, bytesSize);
 
-                for (ConnectionList::iterator iter = connections.begin();
-                         iter != connections.end();
-                         iter++) {
-                        if (iter->first != NULL) {
-                                try {
-                                        iter->second->writeRaw(os);
-                                        iter->second->flush();
-                                } catch(Exception& ex) {
-                                        // The client has closed the connection, remove it from our list:
-                                        iter->first = nullSocket;
-                                        iter->second = nullStream;
-                                        activeConnections--;
-                                }
-                        }
+                synchronized sync(this->mutex);
+                while(msgIter != msg.end()) {
+                    log4cxx_status_t stat = encoder->encode(msg, msgIter, buf);
+                    buf.flip();
+                    write(buf);
+                    buf.clear();
+                    if (CharsetEncoder::isError(stat)) {
+                        LogString unrepresented(1, LOG4CXX_STR('?'));
+                        LogString::const_iterator unrepresentedIter(unrepresented.begin());
+                        stat = encoder->encode(unrepresented, unrepresentedIter, buf);
+                        buf.flip();
+                        write(buf);
+                        buf.clear();
+                        msgIter++;
+                    }
                 }
         }
 }
@@ -152,19 +193,18 @@
         try
         {
                 SocketPtr newClient = pThis->serverSocket->accept();
-                SocketOutputStreamPtr os = newClient->getOutputStream();
                 bool done = pThis->closed;
                 if (done) {
-                        os->writeRaw(LOG4CXX_STR("Log closed.\r\n"));
-                        os->flush();
+                        Pool p;
+                        pThis->writeStatus(newClient, LOG4CXX_STR("Log closed.\r\n"), p);
                         newClient->close();
                         return NULL;
                 }
 
                 size_t count = pThis->activeConnections;
                 if (count >= pThis->connections.size()) {
-                        os->writeRaw(LOG4CXX_STR("Too many connections.\r\n"));
-                        os->flush();
+                        Pool p;
+                        pThis->writeStatus(newClient, LOG4CXX_STR("Too many connections.\r\n"), p);
                         newClient->close();
                 } else {
                         //
@@ -174,19 +214,18 @@
                         for(ConnectionList::iterator iter = pThis->connections.begin();
                                 iter != pThis->connections.end();
                                 iter++) {
-                                if (iter->first == NULL) {
-                                        iter->first = newClient;
-                                        iter->second = os;
-                                        pThis->activeConnections++;
-                                        break;
+                                if (*iter == NULL) {
+                                    *iter = newClient;
+                                    pThis->activeConnections++;
+                                    break;
                                 }
                         }
 
+                        Pool p;
                         LogString oss(LOG4CXX_STR("TelnetAppender v1.0 ("));
-                        oss += StringHelper::toString((int) count+1, pThis->pool);
+                        oss += StringHelper::toString((int) count+1, p);
                         oss += LOG4CXX_STR(" active connections)\r\n\r\n");
-                        os->writeRaw(oss);
-                        os->flush();
+                        pThis->writeStatus(newClient, oss, p);
                 }
         } catch(Exception& e) {
                 LogLog::error(LOG4CXX_STR("Encountered error while in SocketHandler loop."), e);

Modified: logging/log4cxx/trunk/src/main/cpp/xmlsocketappender.cpp
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/cpp/xmlsocketappender.cpp?rev=596892&r1=596891&r2=596892&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/cpp/xmlsocketappender.cpp (original)
+++ logging/log4cxx/trunk/src/main/cpp/xmlsocketappender.cpp Tue Nov 20 16:38:44 2007
@@ -17,7 +17,9 @@
 
 #include <log4cxx/net/xmlsocketappender.h>
 #include <log4cxx/helpers/loglog.h>
-#include <log4cxx/helpers/socketoutputstream.h>
+#include <log4cxx/helpers/bytearrayoutputstream.h>
+#include <log4cxx/helpers/bytebuffer.h>
+#include <log4cxx/helpers/charsetencoder.h>
 #include <log4cxx/helpers/optionconverter.h>
 #include <log4cxx/helpers/stringhelper.h>
 #include <log4cxx/xml/xmllayout.h>
@@ -46,24 +48,30 @@
 
 XMLSocketAppender::XMLSocketAppender()
 : SocketAppenderSkeleton(DEFAULT_PORT, DEFAULT_RECONNECTION_DELAY)
+#if !LOG4CXX_LOGCHAR_IS_UTF8
+    , utf8Encoder(CharsetEncoder::getUTF8Encoder())
+#endif
 {
         layout = new XMLLayout();
-        memset(zeroBuffer, 0, MAX_EVENT_LEN);
 }
 
 XMLSocketAppender::XMLSocketAppender(InetAddressPtr address1, int port1)
 : SocketAppenderSkeleton(address1, port1, DEFAULT_RECONNECTION_DELAY)
+#if !LOG4CXX_LOGCHAR_IS_UTF8
+    , utf8Encoder(CharsetEncoder::getUTF8Encoder())
+#endif
 {
         layout = new XMLLayout();
-        memset(zeroBuffer, 0, MAX_EVENT_LEN);
         connect();
 }
 
 XMLSocketAppender::XMLSocketAppender(const LogString& host, int port1)
 : SocketAppenderSkeleton(host, port1, DEFAULT_RECONNECTION_DELAY)
+#if !LOG4CXX_LOGCHAR_IS_UTF8
+    , utf8Encoder(CharsetEncoder::getUTF8Encoder())
+#endif
 {
         layout = new XMLLayout();
-        memset(zeroBuffer, 0, MAX_EVENT_LEN);
         connect();
 }
 
@@ -74,20 +82,27 @@
 
 void XMLSocketAppender::setLocationInfo(bool locationInfo1) {
         this->locationInfo = locationInfo1;
-        XMLLayoutPtr xmlLayout = layout;
+        XMLLayoutPtr xmlLayout(layout);
         xmlLayout->setLocationInfo(locationInfo1);
 }
 
 
 void XMLSocketAppender::renderEvent(const spi::LoggingEventPtr& event,
-    helpers::SocketOutputStreamPtr& os1, Pool& p)
+    const helpers::OutputStreamPtr& os1, Pool& p)
 {
         LogString output;
-
         layout->format(output, event, p);
-
-        LOG4CXX_ENCODE_CHAR(sz, output);
-        os1->write(sz.c_str(), sz.length());
+#if LOG4CXX_LOGCHAR_IS_UTF8
+        ByteBuffer buf(const_cast<char*>(output.data()), output.size());
+#else
+        size_t maxSize = output.size() * 6;
+        char* bytes = (char*) apr_palloc((apr_pool_t*) p.getAPRPool(), maxSize);
+        ByteBuffer buf(bytes, maxSize);
+        LogString::const_iterator iter(output.begin());
+        utf8Encoder->encode(output, iter, buf);
+        buf.flip();  
+#endif
+        os1->write(buf, p);
 }
 
 void XMLSocketAppender::setOption(const LogString& option,

Added: logging/log4cxx/trunk/src/main/include/log4cxx/helpers/bytearrayoutputstream.h
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/include/log4cxx/helpers/bytearrayoutputstream.h?rev=596892&view=auto
==============================================================================
--- logging/log4cxx/trunk/src/main/include/log4cxx/helpers/bytearrayoutputstream.h (added)
+++ logging/log4cxx/trunk/src/main/include/log4cxx/helpers/bytearrayoutputstream.h Tue Nov 20 16:38:44 2007
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+#ifndef _LOG4CXX_HELPERS_BYTEARRAYOUTPUTSTREAM_H
+#define _LOG4CXX_HELPERS_BYTEARRAYOUTPUTSTREAM_H
+
+#include <log4cxx/helpers/outputstream.h>
+#include <vector>
+
+
+namespace log4cxx
+{
+
+        namespace helpers {
+          class Pool;
+
+          /**
+          *   OutputStream implemented on top of std::vector
+          */
+          class LOG4CXX_EXPORT ByteArrayOutputStream : public OutputStream
+          {
+          private:
+                 std::vector<unsigned char> array;
+
+          public:
+                  DECLARE_ABSTRACT_LOG4CXX_OBJECT(ByteArrayOutputStream)
+                  BEGIN_LOG4CXX_CAST_MAP()
+                          LOG4CXX_CAST_ENTRY(ByteArrayOutputStream)
+                          LOG4CXX_CAST_ENTRY_CHAIN(OutputStream)
+                  END_LOG4CXX_CAST_MAP()
+
+                  ByteArrayOutputStream();
+                  virtual ~ByteArrayOutputStream();
+
+                  virtual void close(Pool& p);
+                  virtual void flush(Pool& p);
+                  virtual void write(ByteBuffer& buf, Pool& p);
+                  std::vector<unsigned char> toByteArray() const;
+
+          private:
+                  ByteArrayOutputStream(const ByteArrayOutputStream&);
+                  ByteArrayOutputStream& operator=(const ByteArrayOutputStream&);
+          };
+
+          typedef helpers::ObjectPtrT<ByteArrayOutputStream> ByteArrayOutputStreamPtr;
+        } // namespace helpers
+
+}  //namespace log4cxx
+
+#endif //_LOG4CXX_HELPERS_BYTEARRAYOUTPUTSTREAM_H

Modified: logging/log4cxx/trunk/src/main/include/log4cxx/helpers/charsetencoder.h
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/include/log4cxx/helpers/charsetencoder.h?rev=596892&r1=596891&r2=596892&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/include/log4cxx/helpers/charsetencoder.h (original)
+++ logging/log4cxx/trunk/src/main/include/log4cxx/helpers/charsetencoder.h Tue Nov 20 16:38:44 2007
@@ -85,6 +85,11 @@
               static CharsetEncoderPtr getEncoder(const std::wstring& charset);
 #endif
 
+              /**
+               *   Get encoder for UTF-8.
+               */
+                  static CharsetEncoderPtr getUTF8Encoder();
+
                   /**
                   * Encodes a string replacing unmappable
                   * characters with escape sequences.

Added: logging/log4cxx/trunk/src/main/include/log4cxx/helpers/objectoutputstream.h
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/include/log4cxx/helpers/objectoutputstream.h?rev=596892&view=auto
==============================================================================
--- logging/log4cxx/trunk/src/main/include/log4cxx/helpers/objectoutputstream.h (added)
+++ logging/log4cxx/trunk/src/main/include/log4cxx/helpers/objectoutputstream.h Tue Nov 20 16:38:44 2007
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+#ifndef _LOG4CXX_HELPERS_OBJECTOUTPUTSTREAM_H
+#define _LOG4CXX_HELPERS_OBJECTOUTPUTSTREAM_H
+
+#include <log4cxx/helpers/objectimpl.h>
+#include <map>
+
+namespace log4cxx
+{
+
+        namespace helpers {
+          class OutputStream;
+          typedef helpers::ObjectPtrT<OutputStream> OutputStreamPtr;
+          class ByteBuffer;
+          class CharsetEncoder;
+          typedef helpers::ObjectPtrT<CharsetEncoder> CharsetEncoderPtr;
+
+          /**
+          *  Emulates java serialization.
+          */
+          class LOG4CXX_EXPORT ObjectOutputStream : public ObjectImpl
+          {
+          public:
+                  DECLARE_ABSTRACT_LOG4CXX_OBJECT(ObjectOutputStream)
+                  BEGIN_LOG4CXX_CAST_MAP()
+                          LOG4CXX_CAST_ENTRY(ObjectOutputStream)
+                  END_LOG4CXX_CAST_MAP()
+
+                  ObjectOutputStream(OutputStreamPtr os, Pool& p);
+                  virtual ~ObjectOutputStream();
+
+                  void close(Pool& p);
+                  void writeUTF(const LogString&, Pool& p);
+                  void writeObject(const LogString&, Pool& p);
+                  void writeObject(const std::map<LogString, LogString>& mdc, Pool& p);
+                  void writeInt(int val, Pool& p);
+                  void writeLong(log4cxx_time_t val, Pool& p);
+                  void writeByte(char val, Pool& p);
+                  void writeBytes(const char* bytes, size_t len, Pool& p);
+
+                  enum { STREAM_MAGIC = 0xACED };
+                  enum { STREAM_VERSION = 5 };
+                  enum { TC_NULL = 0x70,
+                         TC_REFERENCE = 0x71,
+                         TC_CLASSDESC = 0x72,
+                         TC_OBJECT = 0x73,
+                         TC_STRING = 0x74,
+                         TC_ARRAY = 0x75,
+                         TC_CLASS = 0x76,
+                         TC_BLOCKDATA = 0x77,
+                         TC_ENDBLOCKDATA = 0x78 };
+                 enum {
+                     SC_WRITE_METHOD = 0x01,
+                     SC_SERIALIZABLE = 0x02 };
+
+          private:
+                  ObjectOutputStream(const ObjectOutputStream&);
+                  ObjectOutputStream& operator=(const ObjectOutputStream&);
+                     
+                  OutputStreamPtr os;
+#if !LOG4CXX_LOGCHAR_IS_UTF8
+                  log4cxx::helpers::CharsetEncoderPtr utf8Encoder;
+#endif                 
+          };
+
+        } // namespace helpers
+
+}  //namespace log4cxx
+
+#endif //_LOG4CXX_HELPERS_OUTPUTSTREAM_H
+

Modified: logging/log4cxx/trunk/src/main/include/log4cxx/helpers/socket.h
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/include/log4cxx/helpers/socket.h?rev=596892&r1=596891&r2=596892&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/include/log4cxx/helpers/socket.h (original)
+++ logging/log4cxx/trunk/src/main/include/log4cxx/helpers/socket.h Tue Nov 20 16:38:44 2007
@@ -20,8 +20,6 @@
 
 #include <log4cxx/logstring.h>
 #include <log4cxx/helpers/socketimpl.h>
-#include <log4cxx/helpers/socketinputstream.h>
-#include <log4cxx/helpers/socketoutputstream.h>
 
 namespace log4cxx
 {
@@ -29,14 +27,6 @@
         {
                 class ServerSocker;
 
-                class Socket;
-                typedef helpers::ObjectPtrT<Socket> SocketPtr;
-
-                class SocketOutputStream;
-                typedef helpers::ObjectPtrT<SocketOutputStream> SocketOutputStreamPtr;
-
-                class SocketInputStream;
-                typedef helpers::ObjectPtrT<SocketInputStream> SocketInputStreamPtr;
 
                 /**
                 <p>This class implements client sockets (also called just "sockets"). A socket
@@ -111,15 +101,16 @@
                         inline int getPort() const
                                 { return socketImpl->getPort(); }
 
-                        /**  Returns an output stream for this socket. */
-                        SocketOutputStreamPtr getOutputStream();
-
-                        /**  Returns an input stream for this socket. */
-                        SocketInputStreamPtr getInputStream();
-
-  protected:
+                private:
+                        Socket(const Socket&);
+                        Socket& operator=(const Socket&);
                         SocketImplPtr socketImpl;
                 };
+                
+                class Socket;
+                typedef helpers::ObjectPtrT<Socket> SocketPtr;
+
+                
         } // namespace helpers
 } // namespace log4cxx
 

Modified: logging/log4cxx/trunk/src/main/include/log4cxx/net/socketappender.h
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/include/log4cxx/net/socketappender.h?rev=596892&r1=596891&r2=596892&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/include/log4cxx/net/socketappender.h (original)
+++ logging/log4cxx/trunk/src/main/include/log4cxx/net/socketappender.h Tue Nov 20 16:38:44 2007
@@ -137,7 +137,7 @@
 
                 protected:
                         virtual void renderEvent(const spi::LoggingEventPtr& event,
-                                helpers::SocketOutputStreamPtr& os,
+                                const helpers::OutputStreamPtr& os,
                                 log4cxx::helpers::Pool& p);
 
 

Modified: logging/log4cxx/trunk/src/main/include/log4cxx/net/socketappenderskeleton.h
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/include/log4cxx/net/socketappenderskeleton.h?rev=596892&r1=596891&r2=596892&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/include/log4cxx/net/socketappenderskeleton.h (original)
+++ logging/log4cxx/trunk/src/main/include/log4cxx/net/socketappenderskeleton.h Tue Nov 20 16:38:44 2007
@@ -27,8 +27,8 @@
 {
         namespace helpers
         {
-                class SocketOutputStream;
-                typedef helpers::ObjectPtrT<SocketOutputStream> SocketOutputStreamPtr;
+                class OutputStream;
+                typedef helpers::ObjectPtrT<OutputStream> OutputStreamPtr;
         }
 
         namespace net
@@ -40,7 +40,6 @@
         class LOG4CXX_EXPORT SocketAppenderSkeleton : public AppenderSkeleton
         {
         private:
-                log4cxx::helpers::Pool pool;
                 /**
                 host name
                 */
@@ -52,7 +51,7 @@
                 helpers::InetAddressPtr address;
 
                 int port;
-                helpers::SocketOutputStreamPtr os;
+                helpers::SocketPtr socket;
                 int reconnectionDelay;
                 bool locationInfo;
 
@@ -174,7 +173,7 @@
                                 const LogString& value, int defaultPort, int defaultDelay);
 
                         virtual void renderEvent(const spi::LoggingEventPtr& event,
-                                helpers::SocketOutputStreamPtr& os,
+                                const helpers::OutputStreamPtr& os,
                                 log4cxx::helpers::Pool& p) = 0;
 
        private:

Modified: logging/log4cxx/trunk/src/main/include/log4cxx/net/sockethubappender.h
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/include/log4cxx/net/sockethubappender.h?rev=596892&r1=596891&r2=596892&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/include/log4cxx/net/sockethubappender.h (original)
+++ logging/log4cxx/trunk/src/main/include/log4cxx/net/sockethubappender.h Tue Nov 20 16:38:44 2007
@@ -27,12 +27,6 @@
 
 namespace log4cxx
 {
-        namespace helpers
-        {
-                class SocketOutputStream;
-                typedef helpers::ObjectPtrT<SocketOutputStream> SocketOutputStreamPtr;
-        }
-
         namespace net
         {
                 /**
@@ -103,14 +97,13 @@
                 class LOG4CXX_EXPORT SocketHubAppender : public AppenderSkeleton
                 {
                 private:
-                        log4cxx::helpers::Pool pool;
                         /**
                         The default port number of the ServerSocket will be created on.
                         */
                         static int DEFAULT_PORT;
 
                         int port;
-                        std::vector<helpers::SocketOutputStreamPtr> oosList;
+                        std::vector<helpers::SocketPtr> sockets;
                         bool locationInfo;
 
                 public:

Modified: logging/log4cxx/trunk/src/main/include/log4cxx/net/telnetappender.h
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/include/log4cxx/net/telnetappender.h?rev=596892&r1=596891&r2=596892&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/include/log4cxx/net/telnetappender.h (original)
+++ logging/log4cxx/trunk/src/main/include/log4cxx/net/telnetappender.h Tue Nov 20 16:38:44 2007
@@ -27,12 +27,11 @@
 
 namespace log4cxx
 {
-        namespace helpers
-        {
-                class SocketOutputStream;
-                typedef helpers::ObjectPtrT<SocketOutputStream> SocketOutputStreamPtr;
+        namespace helpers {
+             class CharsetEncoder;
+             typedef helpers::ObjectPtrT<CharsetEncoder> CharsetEncoderPtr;
+             class ByteBuffer;
         }
-
         namespace net
         {
 /**
@@ -65,7 +64,6 @@
                 class SocketHandler;
                 friend class SocketHandler;
                 private:
-                        log4cxx::helpers::Pool pool;
                         static const int DEFAULT_PORT;
                         static const int MAX_CONNECTIONS;
                         int port;
@@ -85,6 +83,10 @@
                         attached client(s). */
                         virtual bool requiresLayout() const
                                 { return true; }
+                                
+                        LogString getEncoding() const;
+                        void setEncoding(const LogString& value);
+        
 
                         /** all of the options have been set, create the socket handler and
                         wait for connections. */
@@ -120,14 +122,18 @@
                         //---------------------------------------------------------- SocketHandler:
 
                 private:
-                                                //   prevent copy and assignment statements
-                                                TelnetAppender(const TelnetAppender&);
-                                                TelnetAppender& operator=(const TelnetAppender&);
+                        //   prevent copy and assignment statements
+                        TelnetAppender(const TelnetAppender&);
+                        TelnetAppender& operator=(const TelnetAppender&);
 
-                        typedef std::pair<helpers::SocketPtr, helpers::SocketOutputStreamPtr> Connection;
+                        typedef log4cxx::helpers::SocketPtr Connection;
                         typedef std::vector<Connection> ConnectionList;
-
+                        
+                        void write(log4cxx::helpers::ByteBuffer&);
+                        void writeStatus(const log4cxx::helpers::SocketPtr& socket, const LogString& msg, log4cxx::helpers::Pool& p);
                         ConnectionList connections;
+                        LogString encoding;
+                        log4cxx::helpers::CharsetEncoderPtr encoder;
                         helpers::ServerSocket* serverSocket;
                         helpers::Thread sh;
                         size_t activeConnections;

Modified: logging/log4cxx/trunk/src/main/include/log4cxx/net/xmlsocketappender.h
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/include/log4cxx/net/xmlsocketappender.h?rev=596892&r1=596891&r2=596892&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/include/log4cxx/net/xmlsocketappender.h (original)
+++ logging/log4cxx/trunk/src/main/include/log4cxx/net/xmlsocketappender.h Tue Nov 20 16:38:44 2007
@@ -22,10 +22,12 @@
 
 namespace log4cxx
 {
+        namespace helpers {
+                class CharsetEncoder;
+                typedef helpers::ObjectPtrT<CharsetEncoder> CharsetEncoderPtr;
+        }
         namespace net
         {
-                class XMLSocketAppender;
-                typedef helpers::ObjectPtrT<XMLSocketAppender> XMLSocketAppenderPtr;
 
         /**
         Sends {@link spi::LoggingEvent LoggingEvent} objects in XML format
@@ -100,7 +102,6 @@
                 static int DEFAULT_RECONNECTION_DELAY;
 
                 bool locationInfo;
-                char zeroBuffer[1024];
 
                 /**
                 An event XML stream cannot exceed 1024 bytes.
@@ -149,7 +150,8 @@
 
       protected:
                 void renderEvent(const spi::LoggingEventPtr& event,
-                helpers::SocketOutputStreamPtr& os, log4cxx::helpers::Pool& p);
+                    const helpers::OutputStreamPtr& os, 
+                    log4cxx::helpers::Pool& p);
 
 
 
@@ -157,8 +159,15 @@
                 //  prevent copy and assignment statements
                 XMLSocketAppender(const XMLSocketAppender&);
                 XMLSocketAppender& operator=(const XMLSocketAppender&);
+                
+#if !LOG4CXX_LOGCHAR_IS_UTF8
+                log4cxx::helpers::CharsetEncoderPtr utf8Encoder;
+#endif                
 
         }; // class XMLSocketAppender
+        
+        typedef helpers::ObjectPtrT<XMLSocketAppender> XMLSocketAppenderPtr;
+        
     } // namespace net
 } // namespace log4cxx
 

Modified: logging/log4cxx/trunk/src/main/include/log4cxx/spi/location/locationinfo.h
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/include/log4cxx/spi/location/locationinfo.h?rev=596892&r1=596891&r2=596892&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/include/log4cxx/spi/location/locationinfo.h (original)
+++ logging/log4cxx/trunk/src/main/include/log4cxx/spi/location/locationinfo.h Tue Nov 20 16:38:44 2007
@@ -23,6 +23,10 @@
 
 namespace log4cxx
 {
+  namespace helpers {
+      class ObjectOutputStream;
+      class Pool;
+  }
   namespace spi
   {
       /**
@@ -96,6 +100,9 @@
         /** Returns the method name of the caller. */
         const std::string getMethodName() const;
 
+        void write(log4cxx::helpers::ObjectOutputStream& os, log4cxx::helpers::Pool& p) const;
+
+
         private:
         /** Caller's line number. */
         int lineNumber;
@@ -105,7 +112,7 @@
 
         /** Caller's method name. */
         const char * methodName;
-
+        
 
       };
   }

Modified: logging/log4cxx/trunk/src/main/include/log4cxx/spi/loggingevent.h
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/include/log4cxx/spi/loggingevent.h?rev=596892&r1=596891&r2=596892&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/include/log4cxx/spi/loggingevent.h (original)
+++ logging/log4cxx/trunk/src/main/include/log4cxx/spi/loggingevent.h Tue Nov 20 16:38:44 2007
@@ -36,11 +36,7 @@
 
         namespace helpers
         {
-                class SocketOutputStream;
-                typedef helpers::ObjectPtrT<SocketOutputStream> SocketOutputStreamPtr;
-
-                class SocketInputStream;
-                typedef helpers::ObjectPtrT<SocketInputStream> SocketInputStreamPtr;
+                class ObjectOutputStream;
         }
 
         namespace spi
@@ -128,15 +124,11 @@
                         * should <em>never</em> be called directly.  */
                         const LogString& getNDC() const;
 
-                        /** Write this event to a helpers::SocketOutputStream. */
-                        void write(helpers::SocketOutputStreamPtr& os) const;
-
-                        void writeLevel(helpers::SocketOutputStreamPtr& os) const;
-
-                        /** Read this event from a helpers::SocketOutputStream. */
-                        void read(const helpers::SocketInputStreamPtr& is);
-
-                        void readLevel(const helpers::SocketInputStreamPtr& is);
+                        /**
+                         *  Writes the content of the LoggingEvent 
+                         *  in a format compatible with log4j's serialized form.
+                         */ 
+                        void write(helpers::ObjectOutputStream& os, helpers::Pool& p) const;
 
                         /**
                         * Returns the the context corresponding to the <code>key</code> parameter.
@@ -253,6 +245,9 @@
                        LoggingEvent(const LoggingEvent&);
                        LoggingEvent& operator=(const LoggingEvent&);
                        static const LogString getCurrentThreadName();
+                       
+                       static void writeClassDesc(log4cxx::helpers::ObjectOutputStream& os, log4cxx::helpers::Pool& p);
+                       
                 };
         }
 }

Modified: logging/log4cxx/trunk/src/test/cpp/Makefile.am
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/test/cpp/Makefile.am?rev=596892&r1=596891&r2=596892&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/test/cpp/Makefile.am (original)
+++ logging/log4cxx/trunk/src/test/cpp/Makefile.am Tue Nov 20 16:38:44 2007
@@ -92,6 +92,7 @@
 	util/iso8601filter.cpp\
 	util/linenumberfilter.cpp\
 	util/relativetimefilter.cpp\
+    util/serializationtesthelper.cpp \
 	util/threadfilter.cpp\
 	util/transformer.cpp\
 	util/xmlfilenamefilter.cpp \

Modified: logging/log4cxx/trunk/src/test/cpp/net/socketappendertestcase.cpp
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/test/cpp/net/socketappendertestcase.cpp?rev=596892&r1=596891&r2=596892&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/test/cpp/net/socketappendertestcase.cpp (original)
+++ logging/log4cxx/trunk/src/test/cpp/net/socketappendertestcase.cpp Tue Nov 20 16:38:44 2007
@@ -47,4 +47,4 @@
 };
 
 CPPUNIT_TEST_SUITE_REGISTRATION(SocketAppenderTestCase);
-#endif
\ No newline at end of file
+#endif

Modified: logging/log4cxx/trunk/src/test/cpp/net/telnetappendertestcase.cpp
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/test/cpp/net/telnetappendertestcase.cpp?rev=596892&r1=596891&r2=596892&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/test/cpp/net/telnetappendertestcase.cpp (original)
+++ logging/log4cxx/trunk/src/test/cpp/net/telnetappendertestcase.cpp Tue Nov 20 16:38:44 2007
@@ -47,4 +47,4 @@
 };
 
 CPPUNIT_TEST_SUITE_REGISTRATION(TelnetAppenderTestCase);
-#endif
\ No newline at end of file
+#endif

Modified: logging/log4cxx/trunk/src/test/cpp/rolling/filenamepatterntestcase.cpp
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/test/cpp/rolling/filenamepatterntestcase.cpp?rev=596892&r1=596891&r2=596892&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/test/cpp/rolling/filenamepatterntestcase.cpp (original)
+++ logging/log4cxx/trunk/src/test/cpp/rolling/filenamepatterntestcase.cpp Tue Nov 20 16:38:44 2007
@@ -188,4 +188,4 @@
 //
 #if !defined(_MSC_VER) || _MSC_VER > 1200
 CPPUNIT_TEST_SUITE_REGISTRATION(FileNamePatternTestCase);
-#endif
\ No newline at end of file
+#endif

Added: logging/log4cxx/trunk/src/test/cpp/spi/loggingeventtest.cpp
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/test/cpp/spi/loggingeventtest.cpp?rev=596892&view=auto
==============================================================================
--- logging/log4cxx/trunk/src/test/cpp/spi/loggingeventtest.cpp (added)
+++ logging/log4cxx/trunk/src/test/cpp/spi/loggingeventtest.cpp Tue Nov 20 16:38:44 2007
@@ -0,0 +1,127 @@
+/*
+ * 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 <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <log4cxx/spi/loggingevent.h>
+#include "../util/serializationtesthelper.h"
+#include <log4cxx/logmanager.h>
+#include <log4cxx/ndc.h>
+#include <log4cxx/mdc.h>
+
+using namespace log4cxx;
+using namespace log4cxx::helpers;
+using namespace log4cxx::util;
+using namespace log4cxx::spi;
+using namespace std;
+
+
+/**
+   Unit tests for LoggingEvent
+ */
+class LoggingEventTest : public CppUnit::TestFixture
+{
+        CPPUNIT_TEST_SUITE(LoggingEventTest);
+                CPPUNIT_TEST(testSerializationSimple);
+                CPPUNIT_TEST(testSerializationWithLocation);
+                CPPUNIT_TEST(testSerializationNDC);
+                CPPUNIT_TEST(testSerializationMDC);
+			CPPUNIT_TEST_SUITE_END();
+
+public:
+        void setUp() {
+            NDC::clear();
+            MDC::clear();
+        }
+
+        void tearDown()
+        {
+            LogManager::shutdown();
+        }
+        
+        
+  
+        
+  /**
+   * Serialize a simple logging event and check it against
+   * a witness.
+   * @throws Exception if exception during test.
+   */
+  void testSerializationSimple() {
+    LoggerPtr root = Logger::getRootLogger();
+    LoggingEventPtr event =
+      new LoggingEvent(
+        root, Level::getInfo(), LOG4CXX_STR("Hello, world."), LocationInfo::getLocationUnavailable());
+        
+    CPPUNIT_ASSERT_EQUAL(true, SerializationTestHelper::compare(
+      "witness/serialization/simple.bin", event, 237));
+  }
+
+
+  /**
+   * Serialize a logging event with an exception and check it against
+   * a witness.
+   * @throws Exception if exception during test.
+   *
+   */
+  void testSerializationWithLocation() {
+    LoggerPtr root = Logger::getRootLogger();
+    LoggingEventPtr event =
+      new LoggingEvent(
+        root, Level::getInfo(), LOG4CXX_STR("Hello, world."), LOG4CXX_LOCATION);
+
+    CPPUNIT_ASSERT_EQUAL(true, SerializationTestHelper::compare(
+      "witness/serialization/location.bin", event, 237));
+  }
+
+  /**
+   * Serialize a logging event with ndc.
+   * @throws Exception if exception during test.
+   *
+   */
+  void testSerializationNDC() {
+    LoggerPtr root = Logger::getRootLogger();
+    NDC::push("ndc test");
+
+    LoggingEventPtr event =
+      new LoggingEvent(
+        root, Level::getInfo(), LOG4CXX_STR("Hello, world."), LocationInfo::getLocationUnavailable());
+
+    CPPUNIT_ASSERT_EQUAL(true, SerializationTestHelper::compare(
+      "witness/serialization/ndc.bin", event, 237));
+    }
+
+  /**
+   * Serialize a logging event with mdc.
+   * @throws Exception if exception during test.
+   *
+   */
+  void testSerializationMDC() {
+    LoggerPtr root = Logger::getRootLogger();
+    MDC::put("mdckey", "mdcvalue");
+ 
+    LoggingEventPtr event =
+      new LoggingEvent(
+        root, Level::getInfo(), LOG4CXX_STR("Hello, world."), LocationInfo::getLocationUnavailable());
+
+    CPPUNIT_ASSERT_EQUAL(true, SerializationTestHelper::compare(
+      "witness/serialization/mdc.bin", event, 237));
+  }
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(LoggingEventTest);

Added: logging/log4cxx/trunk/src/test/cpp/util/serializationtesthelper.cpp
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/test/cpp/util/serializationtesthelper.cpp?rev=596892&view=auto
==============================================================================
--- logging/log4cxx/trunk/src/test/cpp/util/serializationtesthelper.cpp (added)
+++ logging/log4cxx/trunk/src/test/cpp/util/serializationtesthelper.cpp Tue Nov 20 16:38:44 2007
@@ -0,0 +1,81 @@
+/*
+ * 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 "serializationtesthelper.h"
+#include <log4cxx/helpers/bytearrayoutputstream.h>
+#include <log4cxx/helpers/objectoutputstream.h>
+#include <log4cxx/helpers/fileinputstream.h>
+#include <log4cxx/helpers/bytebuffer.h>
+#include <log4cxx/file.h>
+#include "apr_pools.h"
+
+using namespace log4cxx;
+using namespace log4cxx::util;
+using namespace log4cxx::helpers;
+using namespace log4cxx::spi;
+
+
+
+bool SerializationTestHelper::compare(
+    const char* witness, const LoggingEventPtr& event, size_t endCompare)  {
+    ByteArrayOutputStreamPtr memOut = new ByteArrayOutputStream();
+    Pool p;
+    ObjectOutputStream objOut(memOut, p);
+    event->write(objOut, p);
+    objOut.close(p);
+    return compare(witness, memOut->toByteArray(), endCompare, p);
+  }
+
+  /**
+   * Asserts the serialized form of an object.
+   * @param witness file name of expected serialization.
+   * @param actual byte array of actual serialization.
+   * @param skip positions to skip comparison.
+   * @param endCompare position to stop comparison.
+   * @throws IOException thrown on IO or serialization exception.
+   */
+bool SerializationTestHelper::compare(
+    const char* witness, const std::vector<unsigned char>& actual, 
+    size_t endCompare, Pool& p) {
+    File witnessFile(witness);
+
+      char* expected = (char *) apr_palloc((apr_pool_t*) p.getAPRPool(), actual.size());
+      FileInputStreamPtr is(new FileInputStream(witnessFile));
+      ByteBuffer readBuffer(expected, actual.size());
+      int bytesRead = is->read(readBuffer);
+      is->close();
+
+      if(bytesRead < endCompare) {
+          puts("Witness file is shorter than expected");
+          return false;
+      }
+
+      int endScan = actual.size();
+
+      if (endScan > endCompare) {
+        endScan = endCompare;
+      }
+
+      for (int i = 0; i < endScan; i++) {
+          if (((unsigned char) expected[i]) != actual[i]) {
+            printf("Difference at offset %d, expected %x, actual %x\n", i, expected[i], actual[i]);
+            return false;
+          }
+        }
+    return true;
+  
+}

Added: logging/log4cxx/trunk/src/test/cpp/util/serializationtesthelper.h
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/test/cpp/util/serializationtesthelper.h?rev=596892&view=auto
==============================================================================
--- logging/log4cxx/trunk/src/test/cpp/util/serializationtesthelper.h (added)
+++ logging/log4cxx/trunk/src/test/cpp/util/serializationtesthelper.h Tue Nov 20 16:38:44 2007
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+#ifndef _LOG4CXX_TESTS_UTIL_SERIALIZATIONTESTHELPER_H
+#define _LOG4CXX_TESTS_UTIL_SERIALIZATIONTESTHELPER_H
+
+#include <log4cxx/spi/loggingevent.h>
+
+namespace log4cxx
+{
+       namespace util {
+            class SerializationTestHelper {
+            public:
+                static bool compare(const char* filename,
+                          const log4cxx::spi::LoggingEventPtr& event,
+                          size_t stopCompare);
+                static bool compare(const char* filename,
+                          const std::vector<unsigned char>& array,
+                          size_t stopCompare, log4cxx::helpers::Pool& p);
+            private:
+                SerializationTestHelper();
+                SerializationTestHelper(const SerializationTestHelper&);
+                SerializationTestHelper& operator=(SerializationTestHelper&);
+            };
+        }
+}
+
+#endif