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/13 22:54:15 UTC

svn commit: r594658 - in /logging/log4cxx/trunk/src/main/cpp: charsetdecoder.cpp charsetencoder.cpp

Author: carnold
Date: Tue Nov 13 13:54:14 2007
New Revision: 594658

URL: http://svn.apache.org/viewvc?rev=594658&view=rev
Log:
LOGCXX-167: Follow changes to default encoding

Modified:
    logging/log4cxx/trunk/src/main/cpp/charsetdecoder.cpp
    logging/log4cxx/trunk/src/main/cpp/charsetencoder.cpp

Modified: logging/log4cxx/trunk/src/main/cpp/charsetdecoder.cpp
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/cpp/charsetdecoder.cpp?rev=594658&r1=594657&r2=594658&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/cpp/charsetdecoder.cpp (original)
+++ logging/log4cxx/trunk/src/main/cpp/charsetdecoder.cpp Tue Nov 13 13:54:14 2007
@@ -52,6 +52,12 @@
             *  @param frompage name of source encoding.
             */
               APRCharsetDecoder(const char* frompage) : pool(), mutex(pool) {
+                if (frompage == APR_LOCALE_CHARSET) {
+                    throw IllegalArgumentException("APRCharsetDecoder does not support APR_LOCALE_CHARSET.");
+                }
+                if (frompage == APR_DEFAULT_CHARSET) {
+                    throw IllegalArgumentException("APRCharsetDecoder does not support APR_DEFAULT_CHARSET.");
+                }
 #if LOG4CXX_LOGCHAR_IS_WCHAR
                 const char* topage = "WCHAR_T";
 #endif
@@ -63,25 +69,7 @@
                     frompage,
                     (apr_pool_t*) pool.getAPRPool());
                 if (stat != APR_SUCCESS) {
-                     if (frompage == APR_DEFAULT_CHARSET) {
-                         throw IllegalArgumentException("APR_DEFAULT_CHARSET");
-                     } else if (frompage == APR_LOCALE_CHARSET) {
-                         Pool subpool;
-                         const char* localeEncoding = 
-                            apr_os_locale_encoding((apr_pool_t*) subpool.getAPRPool());
-                         // Solaris likes returning 646 if nl_langinfo has not been called
-                         if(localeEncoding != NULL && strcmp("646", localeEncoding) == 0) {
-                             stat = apr_xlate_open(&convset,
-                                 topage, 
-                                 "ASCII",
-                                 (apr_pool_t*) pool.getAPRPool());
-                         }
-                         if (stat != APR_SUCCESS) {
-                            throw IllegalArgumentException("APR_LOCALE_CHARSET");
-                         } 
-                     } else {
-                         throw IllegalArgumentException(frompage);
-                     }
+                    throw IllegalArgumentException(frompage);
                 }
               }
 
@@ -133,6 +121,7 @@
                   Mutex mutex;
                   apr_xlate_t *convset;
           };
+          
 #endif
 
 #if LOG4CXX_LOGCHAR_IS_WCHAR && !defined(_WIN32_WCE)
@@ -372,6 +361,65 @@
         USASCIICharsetDecoder& operator=(const USASCIICharsetDecoder&);
 };
 
+#if APR_HAS_XLATE
+          /**
+           *    Charset decoder that uses an embedded APRCharsetDecoder consistent
+           *     with current locale settings.
+           */
+          class APRLocaleCharsetDecoder : public CharsetDecoder {
+          public:
+               APRLocaleCharsetDecoder() : pool(), mutex(pool), decoder(), encoding() {
+               }
+               virtual ~APRLocaleCharsetDecoder() {
+               }
+               virtual log4cxx_status_t decode(ByteBuffer& in,
+                  LogString& out) {
+                  //
+                  //   assuming that all default locales are US-ASCII based (sorry no EBCDIC for now)
+                  //     scan byte array for any non US-ASCII
+                  const char* p = in.current();
+                  size_t i = in.position();
+                  for (; i < in.limit(); i++, p++) {
+                      if (*((unsigned char*) p) > 127) {
+                           Pool subpool;
+                           const char* enc = apr_os_locale_encoding((apr_pool_t*) subpool.getAPRPool());
+                           {
+                                synchronized sync(mutex);
+                                if (encoding != enc) {
+                                    encoding = enc;
+                                    try {
+                                        decoder = new APRCharsetDecoder(enc);
+                                    } catch(IllegalArgumentException ex) {
+                                        decoder = new USASCIICharsetDecoder();
+                                    }
+                                }
+                            }
+                            return decoder->decode(in, out);        
+                      }
+                  }
+                  //
+                  //    Straight US-ASCII, append bytes as characters.
+                  //
+#if LOG4CXX_LOGCHAR_IS_UTF8
+                  out.append(in.current(), in.remaining());
+#else
+                  p = in.current();
+                  i = in.position();
+                  for (; i < in.limit(); i++, p++) {
+                      out.append(1, *p);
+                  }                  
+#endif                               
+                  in.position(in.limit());   
+                  return APR_SUCCESS;  
+               }
+          private:
+               Pool pool;
+               Mutex mutex;
+               CharsetDecoderPtr decoder;
+               std::string encoding;
+          };
+#endif
+
 
 #if LOG4CXX_LOGCHAR_IS_UTF8 && LOG4CXX_HAS_WCHAR_T && (defined(_WIN32) || defined(__STDC_ISO_10646__))
           /**
@@ -457,7 +505,7 @@
 #elif LOG4CXX_LOGCHAR_IS_WCHAR
     return new MbstowcsCharsetDecoder();
 #elif APR_HAS_XLATE
-    return new APRCharsetDecoder(APR_LOCALE_CHARSET);
+    return new APRLocaleCharsetDecoder();
 #else
 #error No default charset decoder available
 #endif

Modified: logging/log4cxx/trunk/src/main/cpp/charsetencoder.cpp
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/main/cpp/charsetencoder.cpp?rev=594658&r1=594657&r2=594658&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/main/cpp/charsetencoder.cpp (original)
+++ logging/log4cxx/trunk/src/main/cpp/charsetencoder.cpp Tue Nov 13 13:54:14 2007
@@ -44,6 +44,12 @@
           {
           public:
               APRCharsetEncoder(const char* topage) : pool(), mutex(pool) {
+                if (topage == APR_LOCALE_CHARSET) {
+                    throw IllegalArgumentException("APRCharsetEncoder does not support APR_LOCALE_CHARSET.");
+                }
+                if (topage == APR_DEFAULT_CHARSET) {
+                    throw IllegalArgumentException("APRCharsetEncoder does not support APR_DEFAULT_CHARSET.");
+                }
 #if LOG4CXX_LOGCHAR_IS_WCHAR
                   const char* frompage = "WCHAR_T";
 #endif
@@ -55,24 +61,7 @@
                      frompage,
                      (apr_pool_t*) pool.getAPRPool());
                   if (stat != APR_SUCCESS) {
-                     if (topage == APR_DEFAULT_CHARSET) {
-                         throw IllegalArgumentException("APR_DEFAULT_CHARSET");
-                     } else if (topage == APR_LOCALE_CHARSET) {
-                         const char* localeEncoding = 
-                            apr_os_locale_encoding((apr_pool_t*) pool.getAPRPool());
-                         // Solaris likes returning 646 if nl_langinfo has not been called
-                         if(localeEncoding != NULL && strcmp("646", localeEncoding) == 0) {
-                             stat = apr_xlate_open(&convset,
-                                 "ASCII", 
-                                 frompage,
-                                 (apr_pool_t*) pool.getAPRPool());
-                         }
-                         if (stat != APR_SUCCESS) {
-                            throw IllegalArgumentException("APR_LOCALE_CHARSET");
-                         } 
-                     } else {
-                         throw IllegalArgumentException(topage);
-                     }
+                     throw IllegalArgumentException(topage);
                   }
               }
 
@@ -258,7 +247,7 @@
           };
 
           /**
-          *   Encodes a LogString to a byte array when the encodings are indentical.
+          *   Encodes a LogString to a byte array when the encodings are identical.
           */
           class TrivialCharsetEncoder : public CharsetEncoder
           {
@@ -474,6 +463,67 @@
           };
 #endif
 
+#if APR_HAS_XLATE
+          /**
+           *    Charset encoder that uses an embedded APRCharsetEncoder consistent
+           *     with current locale settings.
+           */
+          class APRLocaleCharsetEncoder : public CharsetEncoder {
+          public:
+               APRLocaleCharsetEncoder() : pool(), mutex(pool), encoder(), encoding() {
+               }
+               virtual ~APRLocaleCharsetEncoder() {
+               }
+              virtual log4cxx_status_t encode(const LogString& in,
+                    LogString::const_iterator& iter,
+                    ByteBuffer& out) {
+                  log4cxx_status_t stat = APR_SUCCESS;
+                  if (iter != in.end()) {  
+                    for(LogString::const_iterator i(iter);
+                        i != in.end();
+                        i++) {
+                        //
+                        //    non-ASCII character, delegate to APRCharsetEncoder.
+                        //
+#if LOG4CXX_LOGCHAR_IS_UTF8
+                       if (((unsigned char) *i) > 127) {
+#else
+                       if (*i > 127) {
+#endif                        
+                           Pool subpool;
+                           const char* enc = apr_os_locale_encoding((apr_pool_t*) subpool.getAPRPool());
+                           {
+                                synchronized sync(mutex);
+                                if (encoding != enc) {
+                                    encoding = enc;
+                                    try {
+                                        encoder = new APRCharsetEncoder(enc);
+                                    } catch(IllegalArgumentException ex) {
+                                        encoder = new USASCIICharsetEncoder();
+                                    }
+                                }
+                            }
+                            return encoder->encode(in, iter, out);        
+                      }
+                 }
+                 size_t limit = out.limit();
+                 size_t pos = out.position();
+                 char* current = out.current();
+                 for (; iter != in.end() && pos < limit; pos++, iter++, current++) {
+                     *current = (char) *iter;
+                 }
+                 out.position(pos);
+                 }
+                 return stat;  
+               }
+          private:
+               Pool pool;
+               Mutex mutex;
+               CharsetEncoderPtr encoder;
+               std::string encoding;
+          };
+#endif
+
 
         } // namespace helpers
 
@@ -510,7 +560,7 @@
 #elif LOG4CXX_LOGCHAR_IS_WCHAR
   return new WcstombsCharsetEncoder();
 #elif APR_HAS_XLATE
-  return new APRCharsetEncoder(APR_LOCALE_CHARSET);
+  return new APRLocaleCharsetEncoder();
 #else
 #error No default encoder available
 #endif