Ok, I would like to retry this one ;-)

I added an InputStreamReader to split the reader and stream
hierarchy. The classes should now be similar to java.
InputStreamReader converts from char to LogString.

Thanks,

        Andreas

On Jan 30, 2006, at 9:12 AM, Andreas Fester wrote:

> This patch fixes the localized logging which was still #if 0'ed out.
>
> To read the resource files, a FileInputStream class was added.
> This aligns the class structure better with the java world,
> instead of having read/write methods directly on the File class.
>


log4cxx::InputStream and log4cxx::FileInputStream in the patch work
on characters and are therefore really aligned with java.io.Reader
and java.io.FileReader, not their java.io namesakes.  If there is to
be a log4cxx::InputStream its methods should be using
std::vector<unsigned char> instead of LogString.

I'd support either simply renaming the InputStream and
FileInputStream classes to Reader and FileReader and accepting the
patch as a basis for further work or let you try to split out the raw
byte-level IO classes from the character based classes.

Index: include/log4cxx/helpers/properties.h
===================================================================
--- include/log4cxx/helpers/properties.h        (Revision 384298)
+++ include/log4cxx/helpers/properties.h        (Arbeitskopie)
@@ -20,6 +20,7 @@
 #include <log4cxx/logstring.h>
 #include <log4cxx/helpers/objectptr.h>
 #include <log4cxx/helpers/objectimpl.h>
+#include <log4cxx/helpers/inputstream.h>
 #include <map>
 #include <vector>
 #include <istream>
@@ -112,7 +113,7 @@
                         @throw IOException if an error occurred when reading 
from the input
                         stream.
                         */
-                        void load(LogString& inStream);
+                        void load(InputStreamPtr inStream);
 
                         /**
                         Calls the Hashtable method put. Provided for 
parallelism with the
Index: include/log4cxx/helpers/loader.h
===================================================================
--- include/log4cxx/helpers/loader.h    (Revision 384298)
+++ include/log4cxx/helpers/loader.h    (Arbeitskopie)
@@ -20,6 +20,7 @@
 #include <log4cxx/helpers/objectptr.h>
 #include <log4cxx/logstring.h>
 #include <log4cxx/helpers/exception.h>
+#include <log4cxx/helpers/inputstream.h>
 
 
 namespace log4cxx
@@ -34,8 +35,9 @@
                         static const Class& loadClass(const LogString& clazz);
 //  TODO
 //       static LogString getResource(const LogString& name);
-//       static void* getResourceAsStream(const LogString& name,
-//                            apr_size_t* size, log4cxx::helpers::Pool& pool);
+
+                        static InputStreamPtr getResourceAsStream(
+                                                         const LogString& 
name);
                 };
         }  // namespace helpers
 } // namespace log4cxx
Index: include/log4cxx/helpers/fileinputstream.h
===================================================================
--- include/log4cxx/helpers/fileinputstream.h   (Revision 0)
+++ include/log4cxx/helpers/fileinputstream.h   (Revision 0)
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2003,2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LOG4CXX_HELPERS_FILEINPUTSTREAM_H
+#define _LOG4CXX_HELPERS_FILEINPUTSTREAM_H
+
+#include <log4cxx/helpers/inputstream.h>
+#include <log4cxx/file.h>
+#include <log4cxx/helpers/pool.h>
+
+
+namespace log4cxx
+{
+
+        namespace helpers {
+
+          /**
+           * InputStream implemented on top of APR file IO.
+           * @since 0.9.8
+           */
+          class LOG4CXX_EXPORT FileInputStream : public InputStream
+          {
+          private:
+                  Pool pool;
+                  void* fileptr;
+
+          public:
+                  DECLARE_ABSTRACT_LOG4CXX_OBJECT(FileInputStream)
+                  BEGIN_LOG4CXX_CAST_MAP()
+                          LOG4CXX_CAST_ENTRY(FileInputStream)
+                          LOG4CXX_CAST_ENTRY_CHAIN(InputStream)
+                  END_LOG4CXX_CAST_MAP()
+
+                  FileInputStream(const LogString& filename);
+
+                  FileInputStream(const File& aFile);
+
+                  virtual ~FileInputStream();
+
+                  virtual void close();
+
+                  virtual int read(char* buf, int off, int len) const;
+
+          private:
+
+                  FileInputStream(const FileInputStream&);
+
+                  FileInputStream& operator=(const FileInputStream&);
+
+          };
+
+          typedef helpers::ObjectPtrT<FileInputStream> FileInputStreamPtr;
+        } // namespace helpers
+
+}  //namespace log4cxx
+
+#endif //_LOG4CXX_HELPERS_FILEINPUTSTREAM_H
Index: include/log4cxx/helpers/propertyresourcebundle.h
===================================================================
--- include/log4cxx/helpers/propertyresourcebundle.h    (Revision 384298)
+++ include/log4cxx/helpers/propertyresourcebundle.h    (Arbeitskopie)
@@ -19,6 +19,7 @@
 
 #include <log4cxx/helpers/resourcebundle.h>
 #include <log4cxx/helpers/properties.h>
+#include <log4cxx/helpers/inputstream.h>
 
 namespace log4cxx
 {
@@ -47,7 +48,7 @@
                         @throw IOException if an error occurred when reading 
from the
                         input stream.
                         */
-                        PropertyResourceBundle(LogString& inStream);
+                        PropertyResourceBundle(InputStreamPtr inStream);
 
                         virtual LogString getString(const LogString& key) 
const;
 
Index: include/log4cxx/helpers/stringhelper.h
===================================================================
--- include/log4cxx/helpers/stringhelper.h      (Revision 384298)
+++ include/log4cxx/helpers/stringhelper.h      (Arbeitskopie)
@@ -18,7 +18,7 @@
 #define _LOG4CXX_HELPERS_STRING_HELPER_H
 
 #include <log4cxx/logstring.h>
-#include <stdarg.h>
+#include <vector>
 
 
 namespace log4cxx
@@ -57,6 +57,8 @@
 
             static bool getline(std::string& buf, std::string& line);
 
+            static LogString format(const LogString& pattern, const 
std::vector<LogString>& params);
+
 #if LOG4CXX_HAS_WCHAR_T
             static std::wstring trim(const std::wstring& s);
             static bool startsWith(const std::wstring& s, const std::wstring& 
suffix);
Index: include/log4cxx/helpers/fileoutputstream.h
===================================================================
--- include/log4cxx/helpers/fileoutputstream.h  (Revision 384298)
+++ include/log4cxx/helpers/fileoutputstream.h  (Arbeitskopie)
@@ -43,7 +43,7 @@
                           LOG4CXX_CAST_ENTRY_CHAIN(OutputStream)
                   END_LOG4CXX_CAST_MAP()
 
-                  FileOutputStream(const LogString& filename, bool append);
+                  FileOutputStream(const LogString& filename, bool append = 
false);
                   virtual ~FileOutputStream();
 
                   virtual void close(Pool& p);
Index: include/log4cxx/helpers/reader.h
===================================================================
--- include/log4cxx/helpers/reader.h    (Revision 0)
+++ include/log4cxx/helpers/reader.h    (Revision 0)
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2003,2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LOG4CXX_HELPERS_READER_H
+#define _LOG4CXX_HELPERS_READER_H
+
+#include <log4cxx/helpers/objectimpl.h>
+
+namespace log4cxx
+{
+
+        namespace helpers {
+
+          /**
+          *   Abstract class for reading from character streams.
+          */
+          class LOG4CXX_EXPORT Reader : public ObjectImpl
+          {
+          public:
+                  DECLARE_ABSTRACT_LOG4CXX_OBJECT(Reader)
+                  BEGIN_LOG4CXX_CAST_MAP()
+                          LOG4CXX_CAST_ENTRY(Reader)
+                  END_LOG4CXX_CAST_MAP()
+
+          protected:
+                  Reader();
+                  virtual ~Reader();
+
+          public:
+                  virtual void close(Pool& p) = 0;
+                  virtual LogString read(Pool& p) = 0;
+
+          private:
+                  Reader(const Reader&);
+                  Reader& operator=(const Reader&);
+          };
+
+          typedef helpers::ObjectPtrT<Reader> ReaderPtr;
+        } // namespace helpers
+
+}  //namespace log4cxx
+
+#endif //_LOG4CXX_HELPERS_READER_H
Index: include/log4cxx/helpers/inputstreamreader.h
===================================================================
--- include/log4cxx/helpers/inputstreamreader.h (Revision 0)
+++ include/log4cxx/helpers/inputstreamreader.h (Revision 0)
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2003,2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LOG4CXX_HELPERS_INPUTSTREAMREADER_H
+#define _LOG4CXX_HELPERS_INPUTSTREAMREADER_H
+
+#include <log4cxx/helpers/reader.h>
+#include <log4cxx/helpers/inputstream.h>
+#include <log4cxx/helpers/charsetdecoder.h>
+
+namespace log4cxx
+{
+
+        namespace helpers {
+
+          /**
+           *   Class for reading from character streams.
+           *   Decorates a byte based InputStream and provides appropriate 
+           *   conversion to characters.
+           */
+          class LOG4CXX_EXPORT InputStreamReader : public Reader
+          {
+          private:
+                  InputStreamPtr in;
+                  CharsetDecoderPtr dec;
+
+          public:
+                  DECLARE_ABSTRACT_LOG4CXX_OBJECT(InputStreamReader)
+                  BEGIN_LOG4CXX_CAST_MAP()
+                          LOG4CXX_CAST_ENTRY(InputStreamReader)
+                          LOG4CXX_CAST_ENTRY_CHAIN(Reader)
+                  END_LOG4CXX_CAST_MAP()
+
+                  InputStreamReader(InputStreamPtr& in);
+                  InputStreamReader(InputStreamPtr& in, CharsetDecoderPtr 
&enc);
+                  ~InputStreamReader();
+
+                  virtual void close(Pool& p);
+                  virtual LogString read(Pool& p);
+                  LogString getEncoding() const;
+
+          private:
+                  InputStreamReader(const InputStreamReader&);
+                  InputStreamReader& operator=(const InputStreamReader&);
+          };
+
+          typedef helpers::ObjectPtrT<InputStreamReader> InputStreamReaderPtr;
+        } // namespace helpers
+
+}  //namespace log4cxx
+
+#endif //_LOG4CXX_HELPERS_INPUTSTREAMREADER_H
Index: include/log4cxx/logger.h
===================================================================
--- include/log4cxx/logger.h    (Revision 384298)
+++ include/log4cxx/logger.h    (Arbeitskopie)
@@ -452,23 +452,44 @@
         First, the user supplied
         <code>key</code> is searched in the resource bundle. Next, the 
resulting
         pattern is formatted using helpers::StringHelper::format method with 
the user
-        supplied object array <code>params</code>.
+        supplied string array <code>params</code>.
 
         @param level The level of the logging request.
-        @param key The key to be searched in the #resourceBundle.
-        @param file The source file of the logging request, may be null.
-        @param line The number line of the logging request.
+        @param key The key to be searched in the #ResourceBundle.
+        @param locationInfo The location info of the logging request.
+        @param values The values for the placeholders <code>{0}</code>,
+                      <code>{1}</code> etc. within the pattern.
 
         @see #setResourceBundle
         */
+        void l7dlog(const LevelPtr& level, const LogString& key,
+                    const log4cxx::spi::LocationInfo& locationInfo,
+                    const std::vector<LogString>& values);
+
 #if LOG4CXX_HAS_WCHAR_T
         void l7dlog(const LevelPtr& level, const std::wstring& key,
-                                const log4cxx::spi::LocationInfo& locationInfo,
-                                ...);
+                    const log4cxx::spi::LocationInfo& locationInfo);
+        void l7dlog(const LevelPtr& level, const std::wstring& key,
+                    const log4cxx::spi::LocationInfo& locationInfo,
+                    const std::wstring& val1);
+        void l7dlog(const LevelPtr& level, const std::wstring& key,
+                    const log4cxx::spi::LocationInfo& locationInfo,
+                    const std::wstring& val1, const std::wstring& val2);
+        void l7dlog(const LevelPtr& level, const std::wstring& key,
+                    const log4cxx::spi::LocationInfo& locationInfo,
+                    const std::wstring& val1, const std::wstring& val2, const 
std::wstring& val3);
 #endif
         void l7dlog(const LevelPtr& level, const std::string& key,
-                                const log4cxx::spi::LocationInfo& locationInfo,
-                                ...);
+                    const log4cxx::spi::LocationInfo& locationInfo);
+        void l7dlog(const LevelPtr& level, const std::string& key,
+                    const log4cxx::spi::LocationInfo& locationInfo,
+                    const std::string& val1);
+        void l7dlog(const LevelPtr& level, const std::string& key,
+                    const log4cxx::spi::LocationInfo& locationInfo,
+                    const std::string& val1, const std::string& val2);
+        void l7dlog(const LevelPtr& level, const std::string& key,
+                    const log4cxx::spi::LocationInfo& locationInfo,
+                    const std::string& val1, const std::string& val2, const 
std::string& val3);
 
           /**
         This is the most generic printing method. It is intended to be
Index: include/log4cxx/file.h
===================================================================
--- include/log4cxx/file.h      (Revision 384298)
+++ include/log4cxx/file.h      (Arbeitskopie)
@@ -57,8 +57,7 @@
                        return osName;
                     }
 
-                    LogString read(log4cxx::helpers::Pool& pool) const;
-
+                    // @deprecated Use FileOutputStream instead
                     log4cxx_status_t write(const LogString& src, 
log4cxx::helpers::Pool& p) const;
 
                     log4cxx_status_t open(apr_file_t** file, int flags,
Index: src/file.cpp
===================================================================
--- src/file.cpp        (Revision 384298)
+++ src/file.cpp        (Arbeitskopie)
@@ -133,57 +133,6 @@
 //   Current implementation is limited to MBCS files
 //
 //
-LogString File::read(Pool& p) const {
-  LogString output;
-  apr_file_t* f = NULL;
-  apr_status_t rv = open(&f, APR_READ, APR_OS_DEFAULT, p);
-  if (rv != APR_SUCCESS) {
-      throw IOException(rv);
-  } else {
-    const size_t BUFSIZE = 4096;
-    char* buf = p.palloc(BUFSIZE);
-    char* contents = buf;
-    apr_size_t contentLength = 0;
-    do {
-      apr_size_t bytesRead = BUFSIZE;
-      rv = apr_file_read(f, buf, &bytesRead);
-      contentLength += bytesRead;
-      if (APR_STATUS_IS_EOF(rv)  || (rv == APR_SUCCESS && bytesRead < 
BUFSIZE)) {
-          //
-          //     finished file
-          //        transcode and exit
-          Transcoder::decode(contents, contentLength, output);
-//
-//          TODO - assertion here when called from Compare
-//
-//          rv = apr_file_close(f);
-//          assert(rv == APR_SUCCESS);
-          return output;
-      } else if (rv == APR_SUCCESS) {
-         //
-         //   file was larger than the buffer
-         //      realloc a bigger buffer
-         char* newContents = p.palloc(contentLength + BUFSIZE);
-         buf = newContents + contentLength;
-         memcpy(newContents, contents, contentLength);
-         //
-         //   we would free contents here if you did that sort of thing
-         //
-         contents = newContents;
-      }
-    } while(rv == APR_SUCCESS);
-    rv = apr_file_close(f);
-    assert(rv == APR_SUCCESS);
-  }
-  return output;
-}
-
-
-
-//
-//   Current implementation is limited to MBCS files
-//
-//
 log4cxx_status_t File::write(const LogString& src, Pool& p) const {
   LogString output;
   apr_file_t* f = NULL;
Index: src/reader.cpp
===================================================================
--- src/reader.cpp      (Revision 0)
+++ src/reader.cpp      (Revision 0)
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2003,2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <log4cxx/helpers/reader.h>
+
+using namespace log4cxx::helpers;
+
+IMPLEMENT_LOG4CXX_OBJECT(Reader)
+
+Reader::Reader() {
+}
+
+Reader::~Reader() {
+}
Index: src/fileinputstream.cpp
===================================================================
--- src/fileinputstream.cpp     (Revision 0)
+++ src/fileinputstream.cpp     (Revision 0)
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2003,2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <log4cxx/helpers/fileinputstream.h>
+#include <log4cxx/helpers/exception.h>
+#include <log4cxx/helpers/bytebuffer.h>
+#include <apr_file_io.h>
+#include <log4cxx/helpers/transcoder.h>
+#include <log4cxx/helpers/aprinitializer.h>
+
+using namespace log4cxx;
+using namespace log4cxx::helpers;
+
+IMPLEMENT_LOG4CXX_OBJECT(FileInputStream)
+
+FileInputStream::FileInputStream(const LogString& filename) {
+    apr_fileperms_t perm = APR_OS_DEFAULT;
+    apr_int32_t flags = APR_READ;
+    LOG4CXX_ENCODE_CHAR(fn, filename);
+    apr_status_t stat = apr_file_open((apr_file_t**) &fileptr,
+        fn.c_str(), flags, perm, (apr_pool_t*) pool.getAPRPool());
+    if (stat != APR_SUCCESS) {
+      throw IOException(stat);
+    }
+}
+
+
+FileInputStream::FileInputStream(const File& aFile) {
+    apr_fileperms_t perm = APR_OS_DEFAULT;
+    apr_int32_t flags = APR_READ;
+    LOG4CXX_ENCODE_CHAR(fn, aFile.getName());
+    apr_status_t stat = apr_file_open((apr_file_t**) &fileptr,
+        fn.c_str(), flags, perm, (apr_pool_t*) pool.getAPRPool());
+    if (stat != APR_SUCCESS) {
+      throw IOException(stat);
+    }
+}
+
+
+FileInputStream::~FileInputStream() {
+  if (fileptr != NULL && !APRInitializer::isDestructed) {
+    apr_file_close((apr_file_t*) fileptr);
+  }
+}
+
+
+void FileInputStream::close() {
+  apr_status_t stat = apr_file_close((apr_file_t*) fileptr);
+  if (stat == APR_SUCCESS) {
+    fileptr = NULL;
+  } else {
+    throw IOException(stat);
+  }
+}
+
+
+int FileInputStream::read(char* buf, int off, int len) const {
+  apr_size_t bytesRead = len;
+  apr_status_t stat = apr_file_read((apr_file_t*) fileptr, buf + off, 
&bytesRead); 
+  if (APR_STATUS_IS_EOF(stat)) {
+    bytesRead = -1;
+  } else {
+    if (stat != APR_SUCCESS) {
+      throw IOException(stat);
+    }
+  }
+
+  return bytesRead;
+}
Index: src/inputstreamreader.cpp
===================================================================
--- src/inputstreamreader.cpp   (Revision 0)
+++ src/inputstreamreader.cpp   (Revision 0)
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2003,2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <log4cxx/helpers/exception.h>
+#include <log4cxx/helpers/inputstreamreader.h>
+#include <log4cxx/helpers/pool.h>
+#include <log4cxx/helpers/bytebuffer.h>
+
+using namespace log4cxx;
+using namespace log4cxx::helpers;
+
+IMPLEMENT_LOG4CXX_OBJECT(InputStreamReader)
+
+InputStreamReader::InputStreamReader(InputStreamPtr& in)
+   : in(in), dec(CharsetDecoder::getDefaultDecoder()) {
+   if (in == 0) {
+      throw NullPointerException("in parameter may not be null.");
+   }
+}
+
+InputStreamReader::InputStreamReader(InputStreamPtr& in, CharsetDecoderPtr 
&dec) 
+    : in(in), dec(dec) {
+    if (in == 0) {
+       throw NullPointerException("in parameter may not be null.");
+    }
+    if (dec == 0) {
+       throw NullPointerException("dec parameter may not be null.");
+    }
+}
+
+InputStreamReader::~InputStreamReader() {
+}
+
+void InputStreamReader::close(Pool& ) {
+  in->close();
+}
+
+LogString InputStreamReader::read(Pool& p) {
+    const size_t BUFSIZE = 4096;
+    char* buf = p.palloc(BUFSIZE);
+    char* contents = buf;
+    int contentLength = 0;
+    int bytesRead = 0;
+
+    // read whole file
+    do {
+      bytesRead = in->read(buf, 0, BUFSIZE);
+      if (bytesRead > 0) {
+        contentLength += bytesRead;
+      }
+      if (bytesRead < BUFSIZE) {
+        bytesRead = -1;
+      }
+
+      if (bytesRead != -1) {
+         //
+         //   file was larger than the buffer
+         //      realloc a bigger buffer
+         char* newContents = p.palloc(contentLength + BUFSIZE);
+         buf = newContents + contentLength;
+         memcpy(newContents, contents, contentLength);
+         //
+         //   we would free contents here if you did that sort of thing
+         //
+         contents = newContents;
+      }
+    } while(bytesRead != -1);
+
+    //
+    //     finished file
+    //        transcode and exit
+    LogString output;
+    ByteBuffer input(contents, contentLength);
+    dec->decode(input, output);
+    return output;
+}
+
+/*
+LogString InputStreamReader::getEncoding() const {
+}
+*/
Index: src/loader.cpp
===================================================================
--- src/loader.cpp      (Revision 384298)
+++ src/loader.cpp      (Arbeitskopie)
@@ -30,6 +30,7 @@
 #include <sys/stat.h>
 #include <fstream>
 #include <log4cxx/helpers/transcoder.h>
+#include <log4cxx/helpers/fileinputstream.h>
 
 using namespace log4cxx;
 using namespace log4cxx::helpers;
@@ -80,29 +81,20 @@
 }
 #endif
 
-#if 0
-istream * Loader::getResourceAsStream(const LogString& name)
-{
-   String path = getResource(name);
-   if (path.empty())
-   {
-      return 0;
-   }
 
-#ifdef LOG4CXX_UNICODE
-      std::wifstream * stream = new std::wifstream();
-#else
-      std::ifstream * stream = new std::ifstream();
+InputStreamPtr Loader::getResourceAsStream(const LogString& name) {
+#if 0
+  String path = getResource(name);
+  if (path.empty())
+  {
+    return 0;
+  }
 #endif
 
-   USES_CONVERSION;
-   stream->open(T2A(name.c_str()));
-   if (stream->fail())
-   {
-      delete stream;
-      return 0;
-   }
+  try {
+    return new FileInputStream(name);
+  } catch(const IOException& ioex) {
+  }
 
-   return stream;
+  return 0;
 }
-#endif
Index: src/propertyconfigurator.cpp
===================================================================
--- src/propertyconfigurator.cpp        (Revision 384298)
+++ src/propertyconfigurator.cpp        (Arbeitskopie)
@@ -35,6 +35,7 @@
 #include <apr_file_info.h>
 #include <apr_pools.h>
 #include <log4cxx/helpers/transcoder.h>
+#include <log4cxx/helpers/fileinputstream.h>
 
 
 using namespace log4cxx;
@@ -80,22 +81,23 @@
         spi::LoggerRepositoryPtr& hierarchy)
 {
        hierarchy->setConfigured(true);
-        Pool pool;
-        LogString config(configFileName.read(pool));
-        if (config.length() == 0) {
-            LogLog::error(((LogString) LOG4CXX_STR("Could not read 
configuration file ["))
-                + configFileName.getName() + LOG4CXX_STR("]."));
-        } else {
-            // If we reach here, then the config file is alright.
-            Properties props;
-            props.load(config);
-            try {
-              doConfigure(props, hierarchy);
-            } catch(const std::exception& ex) {
-              LogLog::error(((LogString) LOG4CXX_STR("Could not parse 
configuration file ["))
-                  + configFileName.getName() + LOG4CXX_STR("]."), ex);
-            }
-        }
+
+       Properties props;
+       try {
+          InputStreamPtr inputStream = new FileInputStream(configFileName);
+          props.load(inputStream);
+       } catch(const IOException& ie) {
+          LogLog::error(((LogString) LOG4CXX_STR("Could not read configuration 
file ["))
+                        + configFileName.getName() + LOG4CXX_STR("]."));
+          return;
+       }
+
+       try {
+          doConfigure(props, hierarchy);
+       } catch(const std::exception& ex) {
+          LogLog::error(((LogString) LOG4CXX_STR("Could not parse 
configuration file ["))
+                        + configFileName.getName() + LOG4CXX_STR("]."), ex);
+       }
 }
 
 void PropertyConfigurator::configure(const File& configFilename)
Index: src/resourcebundle.cpp
===================================================================
--- src/resourcebundle.cpp      (Revision 384298)
+++ src/resourcebundle.cpp      (Arbeitskopie)
@@ -56,19 +56,16 @@
    }
 
    bundlesNames.push_back(baseName);
-        Pool pool;
 
    for (std::vector<LogString>::iterator it = bundlesNames.begin();
       it != bundlesNames.end(); it++)
    {
-#if 0
-// TODO
 
-                LogString bundleStream;
       bundleName = *it;
 
       PropertyResourceBundlePtr current;
 
+      // Try loading a class which implements ResourceBundle
       try
       {
          const Class& classObj = Loader::loadClass(bundleName);
@@ -79,29 +76,27 @@
          current = 0;
       }
 
+      // No class found, then try to create a PropertyResourceBundle from a 
file
       if (current == 0)
       {
-                        apr_size_t bytes = 0;
-                        void* buf = Loader::getResourceAsStream(
-                           bundleName + LOG4CXX_STR(".properties"),
-                           &bytes, pool);
-                        if (bytes == 0 || buf == NULL) {
-                          continue;
-                        }
-                        log4cxx::helpers::Transcoder::decode(buf, bytes, pool, 
bundleStream);
-      }
+        InputStreamPtr bundleStream =
+                  Loader::getResourceAsStream(
+                                bundleName + LOG4CXX_STR(".properties"));
+        if (bundleStream == 0) {
+          continue;
+        }
 
-      try
-      {
-         current = new PropertyResourceBundle(bundleStream);
+        try
+        {
+          current = new PropertyResourceBundle(bundleStream);
+        }
+        catch(Exception&)
+        {
+          throw;
+        }
       }
-      catch(Exception&)
-      {
-         throw;
-      }
 
-      bundleStream.erase(bundleStream.begin(), bundleStream.end());
-
+      // Add the new resource bundle to the hierarchy
       if (resourceBundle == 0)
       {
          resourceBundle = current;
@@ -112,9 +107,9 @@
          previous->setParent(current);
          previous = current;
       }
-#endif
    }
 
+   // no resource bundle found at all, then throw exception
    if (resourceBundle == 0)
    {
       throw MissingResourceException(
Index: src/Makefile.am
===================================================================
--- src/Makefile.am     (Revision 384298)
+++ src/Makefile.am     (Arbeitskopie)
@@ -37,6 +37,7 @@
         file.cpp \
         fileappender.cpp \
         filedatepatternconverter.cpp \
+        fileinputstream.cpp \
         filelocationpatternconverter.cpp \
         fileoutputstream.cpp \
         filerenameaction.cpp \
@@ -48,6 +49,8 @@
         hierarchy.cpp \
         htmllayout.cpp \
         inetaddress.cpp \
+        inputstream.cpp \
+        inputstreamreader.cpp \
         integer.cpp \
         integerpatternconverter.cpp \
         layout.cpp\
@@ -96,6 +99,7 @@
         propertyconfigurator.cpp \
         propertyresourcebundle.cpp \
         propertysetter.cpp \
+        reader.cpp \
         relativetimedateformat.cpp \
         relativetimepatternconverter.cpp \
         resourcebundle.cpp \
Index: src/stringhelper.cpp
===================================================================
--- src/stringhelper.cpp        (Revision 384298)
+++ src/stringhelper.cpp        (Arbeitskopie)
@@ -279,3 +279,23 @@
   toString((log4cxx_int64_t) n, pool, ws);
 }
 #endif
+
+
+LogString StringHelper::format(const LogString& pattern, const 
std::vector<LogString>& params) {
+
+  LogString result;
+  int i = 0;
+  while(pattern[i] != LOG4CXX_STR('\0')) {
+    if (pattern[i] == LOG4CXX_STR('{') && pattern[i + 1] >= LOG4CXX_STR('0') &&
+        pattern[i + 1] <= LOG4CXX_STR('9') && pattern[i + 2] == 
LOG4CXX_STR('}')) {
+      int arg = pattern[i + 1] - LOG4CXX_STR('0');
+      result = result + params[arg];
+      i += 3;
+    } else {
+      result = result + pattern[i];
+      i++;
+    }
+  }
+
+  return result;
+}
Index: src/properties.cpp
===================================================================
--- src/properties.cpp  (Revision 384298)
+++ src/properties.cpp  (Arbeitskopie)
@@ -15,7 +15,9 @@
  */
 
 #include <log4cxx/helpers/properties.h>
+#include <log4cxx/helpers/inputstreamreader.h>
 #include <log4cxx/helpers/exception.h>
+#include <log4cxx/helpers/pool.h>
 
 using namespace log4cxx;
 using namespace log4cxx::helpers;
@@ -324,11 +326,13 @@
         return (it != properties.end()) ? it->second : LogString();
 }
 
-void Properties::load(LogString& inStream)
-{
+void Properties::load(InputStreamPtr inStream) {
+        Pool pool;
+        InputStreamReaderPtr lineReader = new InputStreamReader(inStream);
+        LogString contents = lineReader->read(pool);
         properties.clear();
         PropertyParser parser;
-        parser.parse(inStream, *this);
+        parser.parse(contents, *this);
 }
 
 std::vector<LogString> Properties::propertyNames() const
Index: src/logger.cpp
===================================================================
--- src/logger.cpp      (Revision 384298)
+++ src/logger.cpp      (Arbeitskopie)
@@ -25,7 +25,6 @@
 #include <log4cxx/helpers/stringhelper.h>
 #include <log4cxx/helpers/synchronized.h>
 #include <log4cxx/helpers/transcoder.h>
-#include <stdarg.h>
 #include <log4cxx/helpers/appenderattachableimpl.h>
 #include <log4cxx/helpers/exception.h>
 #include <log4cxx/helpers/aprinitializer.h>
@@ -208,8 +207,8 @@
         return 0;
 }
 
-#if 0
-String Logger::getResourceBundleString(const String& key) const
+
+LogString Logger::getResourceBundleString(const LogString& key) const
 {
         ResourceBundlePtr rb = getResourceBundle();
 
@@ -217,7 +216,7 @@
         // to report errors from within log4j.
         if (rb == 0)
         {
-                return String();
+                return LogString();
         }
         else
         {
@@ -227,15 +226,15 @@
                 }
                 catch (MissingResourceException&)
                 {
-                        ((Logger *)this)->error(LOG4CXX_WSTR("No resource is 
associated with key \"") +
-                                key + LOG4CXX_WSTR("\"."));
+                        ((Logger *)this)->error(LOG4CXX_STR("No resource is 
associated with key \"") +
+                                key + LOG4CXX_STR("\"."));
 
-                        return String();
+                        return LogString();
                 }
         }
 }
-#endif
 
+
 const LoggerPtr& Logger::getParent() const
 {
         return parent;
@@ -345,8 +344,9 @@
         }
 }*/
 
-void Logger::l7dlog(const LevelPtr& level, const std::string& key,
-                        const LocationInfo& location, ...)
+
+void Logger::l7dlog(const LevelPtr& level, const LogString& key,
+                    const LocationInfo& location, const 
std::vector<LogString>& params)
 {
         if (repository == 0 || repository->isDisabled(level->toInt()))
         {
@@ -355,10 +355,8 @@
 
         if (level->isGreaterOrEqual(getEffectiveLevel()))
         {
-#if 0
-//    TODO
-                String pattern = getResourceBundleString(key);
-                String msg;
+                LogString pattern = getResourceBundleString(key);
+                LogString msg;
 
                 if (pattern.empty())
                 {
@@ -366,47 +364,119 @@
                 }
                 else
                 {
-                        va_list params;
-                        va_start (params, line);
                         msg = StringHelper::format(pattern, params);
-                        va_end (params);
                 }
-#endif
-                forcedLog(level, key, location);
+
+                forcedLog(level, msg, location);
         }
 }
 
+void Logger::l7dlog(const LevelPtr& level, const std::string& key,
+                    const LocationInfo& location) {
+  LogString lkey;
+  Transcoder::decode(key.c_str(), strlen(key.c_str()), lkey);
+
+  std::vector<LogString> values(0);
+  l7dlog(level, lkey, location, values);
+}
+
+void Logger::l7dlog(const LevelPtr& level, const std::string& key,
+                    const LocationInfo& location, const std::string& val1) {
+  LogString lval1;
+  Transcoder::decode(val1.c_str(), strlen(val1.c_str()), lval1);
+  LogString lkey;
+  Transcoder::decode(key.c_str(), strlen(key.c_str()), lkey);
+
+  std::vector<LogString> values(1);
+  values[0] = lval1;
+  l7dlog(level, lkey, location, values);
+}
+
+void Logger::l7dlog(const LevelPtr& level, const std::string& key,
+                    const LocationInfo& location, 
+                    const std::string& val1, const std::string& val2) {
+  LogString lval1;
+  LogString lval2;
+  Transcoder::decode(val1.c_str(), strlen(val1.c_str()), lval1);
+  Transcoder::decode(val2.c_str(), strlen(val2.c_str()), lval2);
+  LogString lkey;
+  Transcoder::decode(key.c_str(), strlen(key.c_str()), lkey);
+
+  std::vector<LogString> values(2);
+  values[0] = lval1;
+  values[1] = lval2;
+  l7dlog(level, lkey, location, values);
+}
+
+void Logger::l7dlog(const LevelPtr& level, const std::string& key,
+                    const LocationInfo& location, 
+                    const std::string& val1, const std::string& val2, const 
std::string& val3) {
+  LogString lval1;
+  LogString lval2;
+  LogString lval3;
+  Transcoder::decode(val1.c_str(), strlen(val1.c_str()), lval1);
+  Transcoder::decode(val2.c_str(), strlen(val2.c_str()), lval2);
+  Transcoder::decode(val3.c_str(), strlen(val3.c_str()), lval3);
+  LogString lkey;
+  Transcoder::decode(key.c_str(), strlen(key.c_str()), lkey);
+
+  std::vector<LogString> values(3);
+  values[0] = lval1;
+  values[1] = lval2;
+  values[3] = lval3;
+  l7dlog(level, lkey, location, values);
+}
+
+
 #if LOG4CXX_HAS_WCHAR_T
+
 void Logger::l7dlog(const LevelPtr& level, const std::wstring& key,
-                        const LocationInfo& location, ...)
-{
-        if (repository == 0 || repository->isDisabled(level->toInt()))
-        {
-                return;
-        }
+                    const LocationInfo& location) {
+  LOG4CXX_DECODE_WCHAR(lkey, key);
 
-        if (level->isGreaterOrEqual(getEffectiveLevel()))
-        {
-#if 0
-//    TODO
-                String pattern = getResourceBundleString(key);
-                String msg;
+  std::vector<LogString> values(0);
+  l7dlog(level, lkey, location, values);
+}
 
-                if (pattern.empty())
-                {
-                        msg = key;
-                }
-                else
-                {
-                        va_list params;
-                        va_start (params, line);
-                        msg = StringHelper::format(pattern, params);
-                        va_end (params);
-                }
-#endif
-                forcedLog(level, key, location);
-        }
+void Logger::l7dlog(const LevelPtr& level, const std::wstring& key,
+                    const LocationInfo& location,
+                    const std::wstring& val1) {
+  LOG4CXX_DECODE_WCHAR(lval1, val1);
+  LOG4CXX_DECODE_WCHAR(lkey, key);
+
+  std::vector<LogString> values(1);
+  values[0] = lval1;
+  l7dlog(level, lkey, location, values);
 }
+
+void Logger::l7dlog(const LevelPtr& level, const std::wstring& key,
+                    const LocationInfo& location,
+                    const std::wstring& val1, const std::wstring& val2) {
+  LOG4CXX_DECODE_WCHAR(lval1, val1);
+  LOG4CXX_DECODE_WCHAR(lval2, val2);
+  LOG4CXX_DECODE_WCHAR(lkey, key);
+
+  std::vector<LogString> values(2);
+  values[0] = lval1;
+  values[1] = lval2;
+  l7dlog(level, lkey, location, values);
+}
+
+void Logger::l7dlog(const LevelPtr& level, const std::wstring& key,
+                    const LocationInfo& location,
+                    const std::wstring& val1, const std::wstring& val2, const 
std::wstring& val3) {
+  LOG4CXX_DECODE_WCHAR(lval1, val1);
+  LOG4CXX_DECODE_WCHAR(lval2, val2);
+  LOG4CXX_DECODE_WCHAR(lval3, val3);
+  LOG4CXX_DECODE_WCHAR(lkey, key);
+
+  std::vector<LogString> values(3);
+  values[0] = lval1;
+  values[1] = lval2;
+  values[2] = lval3;
+  l7dlog(level, lkey, location, values);
+}
+
 #endif
 
 void Logger::removeAllAppenders()
Index: src/propertyresourcebundle.cpp
===================================================================
--- src/propertyresourcebundle.cpp      (Revision 384298)
+++ src/propertyresourcebundle.cpp      (Arbeitskopie)
@@ -23,7 +23,8 @@
 
 IMPLEMENT_LOG4CXX_OBJECT(PropertyResourceBundle)
 
-PropertyResourceBundle::PropertyResourceBundle(LogString& inStream)
+
+PropertyResourceBundle::PropertyResourceBundle(InputStreamPtr inStream)
 {
    properties.load(inStream);
 }
Index: tests/src/filetestcase.cpp
===================================================================
--- tests/src/filetestcase.cpp  (Revision 384298)
+++ tests/src/filetestcase.cpp  (Arbeitskopie)
@@ -20,7 +20,13 @@
 #include <log4cxx/helpers/pool.h>
 #include <apr_errno.h>
 #include <log4cxx/helpers/exception.h>
+#include <log4cxx/helpers/fileinputstream.h>
 
+#include <log4cxx/helpers/outputstreamwriter.h>
+#include <log4cxx/helpers/fileoutputstream.h>
+#include <log4cxx/helpers/inputstreamreader.h>
+#include <log4cxx/helpers/fileinputstream.h>
+
 using namespace log4cxx;
 using namespace log4cxx::helpers;
 
@@ -57,18 +63,20 @@
           CPPUNIT_ASSERT_EQUAL(false, exists);
         }
 
-
+        // check default constructor. read() throws an exception
+        // if no file name was given.
         void defaultRead() {
           File defFile;
           Pool pool;
           try {
-            LogString contents(defFile.read(pool));
+            InputStreamPtr defInput = new FileInputStream(defFile);
+            InputStreamReaderPtr inputReader = new InputStreamReader(defInput);
+            LogString contents(inputReader->read(pool));
             CPPUNIT_ASSERT(false);
           } catch(IOException &ex) {
           }
         }
 
-
         void defaultWrite() {
           File defFile;
           Pool pool;
@@ -106,7 +114,9 @@
         void propertyRead() {
           File propFile("input/patternLayout1.properties");
           Pool pool;
-          LogString props(propFile.read(pool));
+          InputStreamPtr propStream = new FileInputStream(propFile);
+          InputStreamReaderPtr propReader = new InputStreamReader(propStream);
+          LogString props(propReader->read(pool));
           LogString line1(LOG4CXX_STR("log4j.rootCategory=DEBUG, 
testAppender"));
           CPPUNIT_ASSERT_EQUAL(line1, props.substr(0, line1.length()));
           LogString tail(LOG4CXX_STR("%-5p - %m%n"));
@@ -120,18 +130,23 @@
           CPPUNIT_ASSERT_EQUAL(true, exists);
         }
 
+        void fileWrite1() {
+          OutputStreamPtr fos = 
+                      new 
FileOutputStream(LOG4CXX_STR("output/fileWrite1.txt"));
+          OutputStreamWriterPtr osw = new OutputStreamWriter(fos);
 
-        void fileWrite1() {
-          File outFile("output/fileWrite1.txt");
           Pool pool;
           LogString greeting(LOG4CXX_STR("Hello, World") LOG4CXX_EOL);
-          apr_status_t stat = outFile.write(greeting, pool);
-          CPPUNIT_ASSERT_EQUAL(0, stat);
+          osw->write(greeting, pool);
 
-          LogString reply(outFile.read(pool));
+          InputStreamPtr is = 
+                      new 
FileInputStream(LOG4CXX_STR("output/fileWrite1.txt"));
+          InputStreamReaderPtr isr = new InputStreamReader(is);
+          LogString reply = isr->read(pool);
+
           CPPUNIT_ASSERT_EQUAL(greeting, reply);
         }
-        
+
         /**
          *  Tests conversion of backslash containing file names.  
          *  Would cause infinite loop due to bug LOGCXX-105. 
Index: tests/src/helpers/propertiestestcase.cpp
===================================================================
--- tests/src/helpers/propertiestestcase.cpp    (Revision 384298)
+++ tests/src/helpers/propertiestestcase.cpp    (Arbeitskopie)
@@ -16,6 +16,7 @@
 
 #include <cppunit/extensions/HelperMacros.h>
 #include <log4cxx/helpers/properties.h>
+#include <log4cxx/helpers/fileinputstream.h>
 #include "../insertwide.h"
 
 using namespace log4cxx;
@@ -31,10 +32,11 @@
 public:
         void testLoad1() {
           //
-          //    line from patternLayout1.properties
-          LogString 
line(LOG4CXX_STR("log4j.appender.testAppender.layout.ConversionPattern=%-5p - 
%m%n"));
+          //    read patternLayout1.properties
+          FileInputStreamPtr propFile = 
+            new 
FileInputStream(LOG4CXX_STR("input/patternLayout1.properties"));
           Properties properties;
-          properties.load(line);
+          properties.load(propFile);
           LogString 
pattern(properties.getProperty(LOG4CXX_STR("log4j.appender.testAppender.layout.ConversionPattern")));
           CPPUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("%-5p - %m%n"), 
pattern);
         }
Index: tests/src/l7dtestcase.cpp
===================================================================
--- tests/src/l7dtestcase.cpp   (Revision 384298)
+++ tests/src/l7dtestcase.cpp   (Arbeitskopie)
@@ -103,4 +103,4 @@
 
 };
 
-//CPPUNIT_TEST_SUITE_REGISTRATION(L7dTestCase);
+CPPUNIT_TEST_SUITE_REGISTRATION(L7dTestCase);
Index: tests/src/util/compare.cpp
===================================================================
--- tests/src/util/compare.cpp  (Revision 384298)
+++ tests/src/util/compare.cpp  (Arbeitskopie)
@@ -21,6 +21,8 @@
 #include <log4cxx/helpers/pool.h>
 #include <log4cxx/file.h>
 #include <log4cxx/helpers/stringhelper.h>
+#include <log4cxx/helpers/fileinputstream.h>
+#include <log4cxx/helpers/inputstreamreader.h>
 
 using namespace log4cxx;
 using namespace log4cxx::helpers;
@@ -28,10 +30,14 @@
 bool Compare::compare(const File& file1, const File& file2)
 {
     Pool pool;
+    InputStreamPtr fileIn1 = new FileInputStream(file1);
+    InputStreamReaderPtr reader1 = new InputStreamReader(fileIn1);
+    LogString in1(reader1->read(pool));
 
-    LogString in1(file1.read(pool));
     Pool pool2;
-    LogString in2(file2.read(pool2));
+    InputStreamPtr fileIn2 = new FileInputStream(file2);
+    InputStreamReaderPtr reader2 = new InputStreamReader(fileIn2);
+    LogString in2(reader2->read(pool2));
 
     LogString back1(in1);
     LogString back2(in2);

Reply via email to