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 2005/04/28 22:53:45 UTC

cvs commit: logging-log4cxx/tests/src/helpers unicodehelpertestcase.cpp Makefile.am transcodertestcase.cpp

carnold     2005/04/28 13:53:45

  Modified:    .        aprutil-build.xml build.xml
               include/log4cxx/helpers bytebuffer.h charsetdecoder.h
                        charsetencoder.h
               src      Makefile.am charsetdecoder.cpp charsetencoder.cpp
                        transcoder.cpp
               tests/src shortsocketserver.cpp
               tests/src/helpers Makefile.am transcodertestcase.cpp
  Added:       include/log4cxx/helpers unicodehelper.h
               src      unicodehelper.cpp
               tests/src/helpers unicodehelpertestcase.cpp
  Log:
  LOGCXX-59: dropped use of apr-iconv
  
  Revision  Changes    Path
  1.15      +7 -21     logging-log4cxx/aprutil-build.xml
  
  Index: aprutil-build.xml
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/aprutil-build.xml,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- aprutil-build.xml	13 Mar 2005 06:20:45 -0000	1.14
  +++ aprutil-build.xml	28 Apr 2005 20:53:45 -0000	1.15
  @@ -31,7 +31,6 @@
   <property name="build.dir" location="${aprutil.dir}/build"/>
   <property name="include.dir" location="${aprutil.dir}/include"/>
   <property name="apr.lib.type" value="shared"/>
  -<property name="apriconv.lib.type" value="static"/>
   <property name="aprutil.lib.type" value="shared"/>
   
   
  @@ -41,8 +40,6 @@
   
   <property name="apr.dir" location="${aprutil.dir}/../apr-1.1.0"/>
   <property name="apr.include.dir" location="${apr.dir}/include"/>
  -<property name="apriconv.dir" location="${aprutil.dir}/../apr-iconv-1.0.1"/>
  -<property name="apriconv.include.dir" location="${apriconv.dir}/include"/>
   
   <target name="usage" description="Displays usage notes">
           <echo>
  @@ -99,10 +96,6 @@
       <condition property="with-apr" value="../${with-apr-base}">
           <os family="windows"/>
       </condition>
  -    <basename property="with-apr-iconv-base" file="${apriconv.dir}"/>
  -    <condition property="with-apr-iconv" value="../${with-apr-iconv-base}">
  -        <os family="windows"/>
  -    </condition>
   
   </target>
   
  @@ -133,9 +126,6 @@
           <condition property="is-apr-shared" value="true">
               <equals arg1="${apr.lib.type}" arg2="shared"/>
           </condition>
  -        <condition property="is-apriconv-shared" value="true">
  -            <equals arg1="${apriconv.lib.type}" arg2="shared"/>
  -        </condition>
           <condition property="is-aprutil-shared" value="true">
               <equals arg1="${aprutil.lib.type}" arg2="shared"/>
           </condition>
  @@ -149,7 +139,6 @@
           </condition>
   
           <property name="with-apr" value="${apr.dir}"/>
  -        <property name="with-apr-iconv" value="${apriconv.dir}"/>
   
   </target>
   
  @@ -174,6 +163,7 @@
   
   <target name="win-configure" depends="configure-check" if="is-windows" unless="config-available">
       <copy tofile="${include.dir}/apu.h" file="${include.dir}/apu.hw"/>
  +    <replaceregexp file="${include.dir}/apu.h" match="#define *APU_HAVE_APR_ICONV.*" replace="#define APU_HAVE_APR_ICONV 0"/>
       <copy tofile="${include.dir}/apu_want.h" file="${include.dir}/apu_want.hw"/>
       <copy tofile="${include.dir}/apr_ldap.h" file="${include.dir}/apr_ldap.hw"/>
       <replaceregexp file="${include.dir}/apr_ldap.h" match="#define APR_HAS_LDAP.*" replace="#define APR_HAS_LDAP 0"/>
  @@ -187,7 +177,6 @@
           <exec executable="sh" dir="${aprutil.dir}">
              <arg value="./configure"/>
              <arg value="--with-apr=${with-apr}"/>
  -           <arg value="--with-apr-iconv=${with-apr-iconv}"/>
           </exec>
           <exec executable="sh" dir="${aprutil.dir}/xml/expat">
               <arg value="./configure"/>
  @@ -227,24 +216,24 @@
           <includepath path="${include.dir}"/>
           <includepath path="${include.dir}/private"/>
           <includepath path="${apr.include.dir}"/>
  -        <includepath path="${apriconv.include.dir}"/>
           <includepath path="${aprutil.dir}/xml/expat/lib"/>
           <includepath path="${aprutil.dir}/xml/expat"/>
           <defineset define="APU_DECLARE_EXPORT" if="is-aprutil-shared"/>
           <defineset define="APU_DECLARE_STATIC" unless="is-aprutil-shared"/>
  -        <defineset define="API_DECLARE_STATIC" unless="is-apriconv-shared"/>
           <defineset define="APR_DECLARE_STATIC" unless="is-apr-shared"/>
           <defineset define="WIN32" if="is-windows"/>
           <defineset define="_HAVE_CONFIG_H _REENTRANT _GNU_SOURCE" if="is-gcc"/>
           <compilerarg value="${pic-option}" if="pic-option"/>
   
           <libset dir="${apr.lib.dir}" libs="apr-1${lib-suffix}"/>
  -        <libset dir="${apriconv.lib.dir}" libs="apriconv${lib-suffix}"/>
           <libset libs="cw32mt" if="is-bcc"/>
           <libset libs="pthread dl crypt" if="is-unix"/>
           <defineset if="is-bcc">
               <define name="EILSEQ" value="50"/>
           </defineset>
  +        <defineset>
  +			<define name="APU_HAVE_APR_ICONV" value="0"/>
  +        </defineset>
           <project type="${project.type}" outfile="${project.dir}/aprutil" if="project.if"/>
       </cc>
   </target>
  @@ -262,7 +251,6 @@
           <includepath path="${include.dir}"/>
           <includepath path="${apr.include.dir}"/>
           <defineset define="APU_DECLARE_STATIC" unless="is-aprutil-shared"/>
  -        <defineset define="API_DECLARE_STATIC" unless="is-apriconv-shared"/>
           <defineset define="APR_DECLARE_STATIC" unless="is-apr-shared"/>
           <defineset if="is-windows">
               <define name="WIN32" value="1"/>
  @@ -280,7 +268,6 @@
   <target name="copy-apr" if="is-windows">
       <copy todir="${aprutil.lib.dir}">
           <fileset dir="${apr.lib.dir}" includes="apr-1${lib-suffix}.dll"/>
  -        <fileset dir="${apriconv.lib.dir}" includes="*.dll"/>
       </copy>
   </target>
   
  @@ -289,11 +276,11 @@
             dir="${aprutil.lib.dir}"
             failonerror="true">
           <env key="DYLD_LIBRARY_PATH"
  -           value="${apr.lib.dir}:${aprutil.lib.dir}:${apriconv.lib.dir}:${env.DYLD_LIBRARY_PATH}"/>
  +           value="${apr.lib.dir}:${aprutil.lib.dir}:${env.DYLD_LIBRARY_PATH}"/>
           <env key="LD_LIBRARY_PATH"
  -           value="${apr.lib.dir}:${aprutil.lib.dir}:${apriconv.lib.dir}:${env.LD_LIBRARY_PATH}"/>
  +           value="${apr.lib.dir}:${aprutil.lib.dir}:${env.LD_LIBRARY_PATH}"/>
           <env key="Path"
  -           value="${apr.lib.dir}:${aprutil.lib.dir}:${apriconv.lib.dir}:${env.Path}"/>
  +           value="${apr.lib.dir}:${aprutil.lib.dir}:${env.Path}"/>
       </exec>
   </target>
   
  @@ -427,7 +414,6 @@
           <includepath path="${include.dir}"/>
           <includepath path="${apr.include.dir}"/>
           <defineset define="APU_DECLARE_STATIC" unless="is-aprutil-shared"/>
  -        <defineset define="API_DECLARE_STATIC" unless="is-apriconv-shared"/>
           <defineset define="APR_DECLARE_STATIC" unless="is-apr-shared"/>
           <defineset if="is-windows">
               <define name="WIN32" value="1"/>
  
  
  
  1.61      +18 -107   logging-log4cxx/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/build.xml,v
  retrieving revision 1.60
  retrieving revision 1.61
  diff -u -r1.60 -r1.61
  --- build.xml	22 Apr 2005 20:56:16 -0000	1.60
  +++ build.xml	28 Apr 2005 20:53:45 -0000	1.61
  @@ -3,10 +3,6 @@
   <!ENTITY libsets '
           <libset libs="${aprutil.lib.name}${lib-suffix}" dir="${aprutil.lib.dir}" if="aprutil.lib.dir"/>
           <libset libs="${aprutil.lib.name}${lib-suffix}" unless="aprutil.lib.dir"/>
  -        <libset libs="${apriconv.lib.name}${lib-suffix}"
  -               dir="${apriconv.lib.dir}" if="apriconv.lib.dir"/>
  -        <libset libs="${apriconv.lib.name}${lib-suffix}"
  -                unless="apriconv.lib.dir"/>
           <libset libs="${apr.lib.name}${lib-suffix}" dir="${apr.lib.dir}" if="apr.lib.dir"/>
           <libset libs="${apr.lib.name}${lib-suffix}" unless="apr.lib.dir"/>
           <libset libs="iconv" if="has-iconv"/>
  @@ -73,9 +69,6 @@
   <property name="aprutil.lib.name" value="aprutil-1"/>
   <property name="aprutil.lib.type" value="static"/>
   
  -<property name="apriconv.version" value="1.0.1"/>
  -<property name="apriconv.lib.name" value="apriconv"/>
  -<property name="apriconv.lib.type" value="static"/>
   
   <property name="cppunit.version" value="1.10.2"/>
   <property name="cppunit.lib.name" value="cppunit"/>
  @@ -252,15 +245,6 @@
           </condition>
   
   
  -        <condition property="apriconv.dir" value="${apr.dir}">
  -            <isset property="apr.dir"/>
  -        </condition>
  -        <condition property="apriconv.include.dir" value="${apriconv.dir}/include/apr-1">
  -            <isset property="apriconv.dir"/>
  -        </condition>
  -        <condition property="apriconv.lib.dir" value="${apriconv.dir}/lib">
  -            <isset property="apriconv.dir"/>
  -        </condition>
   
   
           <condition property="aprutil.dir" value="${apr.dir}">
  @@ -287,16 +271,13 @@
   
           <available property="apr-available" file="${apr.lib.dir}/${lib.prefix}apr-1${lib-suffix}${lib.extension}"/>
           <available property="aprutil-available" file="${aprutil.lib.dir}/${lib.prefix}aprutil-1${lib-suffix}${lib.extension}"/>
  -        <available property="apriconv-available" file="${apriconv.lib.dir}/${lib.prefix}apriconv${lib-suffix}${lib.extension}"/>
           <available property="cppunit-available" file="${cppunit.lib.dir}/${lib.prefix}cppunit${lib-suffix}${lib.extension}"/>
   
           <available property="apr-src-available" file="${lib.dir}/apr-${apr.version}.tar.gz"/>
  -        <available property="apriconv-src-available" file="${lib.dir}/apr-iconv-${apriconv.version}.tar.gz"/>
           <available property="aprutil-src-available" file="${lib.dir}/apr-util-${aprutil.version}.tar.gz"/>
           <available property="cppunit-src-available" file="${lib.dir}/cppunit-${cppunit.version}.tar.gz"/>
   
           <available property="apr-src-expanded" file="${lib.dir}/apr-${apr.version}"/>
  -        <available property="apriconv-src-expanded" file="${lib.dir}/apr-iconv-${apriconv.version}"/>
           <available property="aprutil-src-expanded" file="${lib.dir}/apr-util-${aprutil.version}"/>
           <available property="cppunit-src-expanded" file="${lib.dir}/cppunit-${cppunit.version}"/>
   
  @@ -312,10 +293,6 @@
                           <equals arg1="${aprutil.lib.type}" arg2="static"/>
                   </condition>
   
  -                <condition property="apriconv-static" value="true">
  -                        <equals arg1="${apriconv.lib.type}" arg2="static"/>
  -                </condition>
  -
                   <condition property="cppunit-static" value="true">
                           <equals arg1="${cppunit.lib.type}" arg2="static"/>
                   </condition>
  @@ -356,7 +333,6 @@
           <!-- exec executable="configure">
               <arg value="- -with-apr=${with-apr}"/>
               <arg value="- -with-aprutil=${aprutil.dir}"/>
  -            <arg value="- -with-apriconv=${apriconv.dir}"/>
               <arg value="- -with-cppunit=${cppunit.dir}"/>
           </exec-->
   </target>
  @@ -441,61 +417,6 @@
       <property name="with-apr" location="${apr.dir}/apr--config"/>
   </target>
   
  -<target name="get-apriconv-src" unless="apriconv-src-available">
  -    <antcall target="get-apr-module">
  -        <param name="module" value="apr-iconv"/>
  -        <param name="module.version" value="${apriconv.version}"/>
  -    </antcall>
  -</target>
  -
  -
  -<target name="untar-apriconv-src" depends="get-apriconv-src" unless="apriconv-src-expanded">
  -    <antcall target="untar-apr-module">
  -        <param name="module" value="apr-iconv"/>
  -        <param name="module.version" value="${apriconv.version}"/>
  -    </antcall>
  -    <patch patchfile="${base.dir}/apr-iconv-${apriconv.version}.patch"
  -           dir="${lib.dir}/apr-iconv-${apriconv.version}"
  -           strip="0"/>
  -    <delete file="${lib.dir}/apr-iconv-${apriconv.version}/lib/iconv_module.c"/>
  -    <copy todir="${lib.dir}/apr-iconv-${apriconv.version}/lib">
  -        <fileset dir="${src.dir}" includes="iconv_module.cpp"/>
  -    </copy>
  -</target>
  -
  -<target name="build-apriconv" depends="build-apr" unless="apriconv-available">
  -    <antcall target="untar-apriconv-src"/>
  -
  -    <property name="apriconv.dir" location="${lib.dir}/apr-iconv-${apriconv.version}"/>
  -    <property name="apriconv.include.dir" location="${apriconv.dir}/include"/>
  -    <property name="apriconv.lib.dir" location="${executable.dir}/${apriconv.lib.type}"/>
  -    <ant antfile="apriconv-build.xml" target="build-lib" inheritAll="false">
  -        <property name="version" value="${apriconv.version}"/>
  -        <property name="apriconv.dir" value="${apriconv.dir}"/>
  -        <property name="debug" value="${debug}"/>
  -        <property name="lib-suffix" value="${lib-suffix}"/>
  -        <property name="compiler" value="${compiler}"/>
  -        <property name="apr.include.dir" value="${apr.include.dir}"/>
  -        <property name="apr.lib.dir" value="${apr.lib.dir}"/>
  -        <property name="apriconv.lib.dir" value="${apriconv.lib.dir}"/>
  -        <property name="apr.lib.type" value="${apr.lib.type}"/>
  -        <property name="apriconv.lib.type" value="${apriconv.lib.type}"/>
  -        <property name="with-apr" value="${with-apr}"/>
  -        <property name="project.type" value="${project.type}"/>
  -        <property name="project.dir" value="${project.dir}"/>
  -        <property name="project.if.value" value="${project.if}"/>
  -        <property name="use-pic" value="${use-pic}"/>
  -        <property name="os.family" value="${os.family}"/>
  -    </ant>
  -
  -
  -    <!--  configure can't handle a Windows path   -->
  -    <condition property="with-apr-iconv" value="../apr-iconv-${apriconv.version}">
  -         <isset property="is-cygwin"/>
  -    </condition>
  -    <property name="with-apr-iconv" location="${apriconv.dir}"/>
  -
  -</target>
   
   <target name="get-aprutil-src" unless="aprutil-src-available">
       <antcall target="get-apr-module">
  @@ -515,7 +436,8 @@
   </target>
   
   
  -<target name="build-aprutil" depends="build-apriconv" unless="aprutil-available">
  +
  +<target name="build-aprutil" depends="build-apr" unless="aprutil-available">
       <antcall target="untar-aprutil-src"/>
   
       <property name="aprutil.dir" location="${lib.dir}/apr-util-${aprutil.version}"/>
  @@ -530,14 +452,10 @@
           <property name="compiler" value="${compiler}"/>
           <property name="apr.include.dir" value="${apr.include.dir}"/>
           <property name="apr.lib.dir" value="${apr.lib.dir}"/>
  -        <property name="apriconv.include.dir" value="${apriconv.include.dir}"/>
  -        <property name="apriconv.lib.dir" value="${apriconv.lib.dir}"/>
           <property name="aprutil.lib.dir" value="${aprutil.lib.dir}"/>
           <property name="apr.lib.type" value="${apr.lib.type}"/>
  -        <property name="apriconv.lib.type" value="${apriconv.lib.type}"/>
           <property name="aprutil.lib.type" value="${aprutil.lib.type}"/>
           <property name="with-apr" value="${with-apr}"/>
  -        <property name="with-apr-iconv" value="${with-apr-iconv}"/>
           <property name="project.type" value="${project.type}"/>
           <property name="project.dir" value="${project.dir}"/>
           <property name="project.if.value" value="${project.if}"/>
  @@ -655,12 +573,10 @@
           <includepath path="/usr/include/libxml2" if="is-unix"/>
           <includepath path="${apr.include.dir}"/>
           <includepath path="${aprutil.include.dir}"/>
  -        <includepath path="${apriconv.include.dir}"/>
           <defineset define="_USRDLL DLL_EXPORTS" if="is-windows"/>
           <defineset define="LOG4CXX"/>
           <defineset define="LOG4CXX_STATIC" if="is-static"/>
           <defineset define="APR_DECLARE_STATIC" if="apr-static"/>
  -        <defineset define="API_DECLARE_STATIC" if="apriconv-static"/>
           <defineset define="APU_DECLARE_STATIC" if="aprutil-static"/>
           <defineset define="WIN32" if="is-windows"/>
           <defineset if="is-utf8">
  @@ -699,7 +615,6 @@
           <defineset define="LOG4CXX_STATIC" if="is-static"/>
           <defineset define="APR_DECLARE_STATIC" if="apr-static"/>
           <defineset define="APU_DECLARE_STATIC" if="aprutil-static"/>
  -        <defineset define="API_DECLARE_STATIC" if="apriconv-static"/>
           <defineset if="is-utf8">
               <define name="LOG4CXX_LOGCHAR_IS_UTF8" value="1"/>
           </defineset>
  @@ -725,9 +640,9 @@
             dir="${log4cxx.lib.dir}"
             failonerror="true">
             <env key="DYLD_LIBRARY_PATH"
  -                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${apriconv.lib.dir}:${env.DYLD_LIBRARY_PATH}"/>
  +                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${env.DYLD_LIBRARY_PATH}"/>
               <env key="LD_LIBRARY_PATH"
  -                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${apriconv.lib.dir}:${env.LD_LIBRARY_PATH}"/>
  +                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${env.LD_LIBRARY_PATH}"/>
               <env key="Path" value="${env.Path}"/>
       </exec>
   </target>
  @@ -836,10 +751,8 @@
           <includepath path="${include.dir}"/>
           <includepath path="${apr.include.dir}"/>
           <includepath path="${aprutil.include.dir}"/>
  -        <includepath path="${apriconv.include.dir}"/>
           <defineset define="LOG4CXX_STATIC" if="is-static"/>
           <defineset define="APR_DECLARE_STATIC" if="apr-static"/>
  -        <defineset define="API_DECLARE_STATIC" if="apriconv-static"/>
           <defineset define="APU_DECLARE_STATIC" if="aprutil-static"/>
           <defineset define="WIN32" if="is-windows"/>
           <defineset if="is-utf8">
  @@ -882,10 +795,8 @@
           <includepath path="${include.dir}"/>
           <includepath path="${apr.include.dir}"/>
           <includepath path="${aprutil.include.dir}"/>
  -        <includepath path="${apriconv.include.dir}"/>
           <defineset define="LOG4CXX"/>
           <defineset define="APR_DECLARE_STATIC" if="apr-static"/>
  -        <defineset define="API_DECLARE_STATIC" if="apriconv-static"/>
           <defineset define="APU_DECLARE_STATIC" if="aprutil-static"/>
           <defineset define="WIN32" if="is-windows"/>
           <defineset if="is-utf8">
  @@ -927,9 +838,9 @@
               <env key="key1" value="value1"/>
               <env key="key2" value="value2"/>
               <env key="LD_LIBRARY_PATH"
  -                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${apriconv.lib.dir}:${cppunit.lib.dir}:${env.LD_LIBRARY_PATH}"/>
  +                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${cppunit.lib.dir}:${env.LD_LIBRARY_PATH}"/>
               <env key="DYLD_LIBRARY_PATH"
  -                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${apriconv.lib.dir}:${cppunit.lib.dir}:${env.DYLD_LIBRARY_PATH}"/>
  +                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${cppunit.lib.dir}:${env.DYLD_LIBRARY_PATH}"/>
               <env key="Path"
                      value="${log4cxx.lib.dir};${env.Path}"/>
       </exec>
  @@ -941,9 +852,9 @@
                 failonerror="true">
               <arg value="TestCase3"/>
               <env key="LD_LIBRARY_PATH"
  -                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${apriconv.lib.dir}:${cppunit.lib.dir}:${env.LD_LIBRARY_PATH}"/>
  +                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${cppunit.lib.dir}:${env.LD_LIBRARY_PATH}"/>
               <env key="DYLD_LIBRARY_PATH"
  -                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${apriconv.lib.dir}:${cppunit.lib.dir}:${env.DYLD_LIBRARY_PATH}"/>
  +                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${cppunit.lib.dir}:${env.DYLD_LIBRARY_PATH}"/>
               <env key="log4j.configuration"
                      value="${defaultInit3.properties}"/>
       </exec>
  @@ -953,9 +864,9 @@
                 failonerror="true">
               <arg value="TestCase3"/>
               <env key="LD_LIBRARY_PATH"
  -                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${apriconv.lib.dir}:${cppunit.lib.dir}:${env.LD_LIBRARY_PATH}"/>
  +                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${cppunit.lib.dir}:${env.LD_LIBRARY_PATH}"/>
               <env key="DYLD_LIBRARY_PATH"
  -                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${apriconv.lib.dir}:${cppunit.lib.dir}:${env.DYLD_LIBRARY_PATH}"/>
  +                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${cppunit.lib.dir}:${env.DYLD_LIBRARY_PATH}"/>
               <env key="LOG4CXX_CONFIGURATION"
                      value="${defaultInit3.properties}"/>
       </exec>
  @@ -970,9 +881,9 @@
                 failonerror="true">
               <arg value="TestCase3"/>
               <env key="DYLD_LIBRARY_PATH"
  -                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${apriconv.lib.dir}:${cppunit.lib.dir}:${env.DYLD_LIBRARY_PATH}"/>
  +                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${cppunit.lib.dir}:${env.DYLD_LIBRARY_PATH}"/>
               <env key="LD_LIBRARY_PATH"
  -                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${apriconv.lib.dir}:${cppunit.lib.dir}:${env.LD_LIBRARY_PATH}"/>
  +                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${cppunit.lib.dir}:${env.LD_LIBRARY_PATH}"/>
       </exec>
   
       <!-- modify log4j.properties so if it has precedence the test fails  -->
  @@ -983,9 +894,9 @@
                 failonerror="true">
               <arg value="TestCase3"/>
               <env key="DYLD_LIBRARY_PATH"
  -                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${apriconv.lib.dir}:${cppunit.lib.dir}:${env.DYLD_LIBRARY_PATH}"/>
  +                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${cppunit.lib.dir}:${env.DYLD_LIBRARY_PATH}"/>
               <env key="LD_LIBRARY_PATH"
  -                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${apriconv.lib.dir}:${cppunit.lib.dir}:${env.LD_LIBRARY_PATH}"/>
  +                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${cppunit.lib.dir}:${env.LD_LIBRARY_PATH}"/>
       </exec>
   
       <delete file="${log4cxx.lib.dir}/log4cxx.properties"/>
  @@ -1000,9 +911,9 @@
                 failonerror="true">
               <arg value="TestCase4"/>
               <env key="LD_LIBRARY_PATH"
  -                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${apriconv.lib.dir}:${cppunit.lib.dir}:${env.LD_LIBRARY_PATH}"/>
  +                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${cppunit.lib.dir}:${env.LD_LIBRARY_PATH}"/>
               <env key="DYLD_LIBRARY_PATH"
  -                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${apriconv.lib.dir}:${cppunit.lib.dir}:${env.DYLD_LIBRARY_PATH}"/>
  +                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${cppunit.lib.dir}:${env.DYLD_LIBRARY_PATH}"/>
       </exec>
   
   </target>
  @@ -1018,9 +929,9 @@
               <env key="key1" value="value1"/>
               <env key="key2" value="value2"/>
               <env key="DYLD_LIBRARY_PATH"
  -                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${apriconv.lib.dir}:${cppunit.lib.dir}:${env.DYLD_LIBRARY_PATH}"/>
  +                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${cppunit.lib.dir}:${env.DYLD_LIBRARY_PATH}"/>
               <env key="LD_LIBRARY_PATH"
  -                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${apriconv.lib.dir}:${cppunit.lib.dir}:${env.LD_LIBRARY_PATH}"/>
  +                   value="${log4cxx.lib.dir}:${apr.lib.dir}:${aprutil.lib.dir}:${cppunit.lib.dir}:${env.LD_LIBRARY_PATH}"/>
               <env key="Path"
                      value="${log4cxx.lib.dir};${env.Path}"/>
       </exec>
  
  
  
  1.2       +2 -0      logging-log4cxx/include/log4cxx/helpers/bytebuffer.h
  
  Index: bytebuffer.h
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/include/log4cxx/helpers/bytebuffer.h,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- bytebuffer.h	1 Apr 2005 02:02:33 -0000	1.1
  +++ bytebuffer.h	28 Apr 2005 20:53:45 -0000	1.2
  @@ -45,6 +45,8 @@
   
                     inline char* data() { return base; }
                     inline const char* data() const { return base; }
  +                  inline char* current() { return base + pos; }
  +                  inline const char* current() const { return base + pos; }
                     inline size_t limit() const { return lim; }
                     inline size_t position() const { return pos; }
                     inline size_t remaining() const { return lim - pos; }
  
  
  
  1.3       +41 -7     logging-log4cxx/include/log4cxx/helpers/charsetdecoder.h
  
  Index: charsetdecoder.h
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/include/log4cxx/helpers/charsetdecoder.h,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- charsetdecoder.h	22 Apr 2005 05:27:22 -0000	1.2
  +++ charsetdecoder.h	28 Apr 2005 20:53:45 -0000	1.3
  @@ -28,8 +28,8 @@
   
   
             /**
  -          *   An engine to transform a byte array in
  -          *     a character set to LogStrings.
  +          *   An abstract engine to transform a sequences of bytes in a specific charset
  +        *   into a LogString.
             */
             class LOG4CXX_EXPORT CharsetDecoder : public ObjectImpl
             {
  @@ -38,25 +38,59 @@
                     BEGIN_LOG4CXX_CAST_MAP()
                             LOG4CXX_CAST_ENTRY(CharsetDecoder)
                     END_LOG4CXX_CAST_MAP()
  -          protected:
  -                  CharsetDecoder();
  -          public:
  +          protected:
  +               /**
  +               *  Protected constructor.
  +               */
  +                  CharsetDecoder();
  +          public:
  +               /**
  +               *  Destructor.
  +               */
                     virtual ~CharsetDecoder();
  -                  static CharsetDecoderPtr getDefaultDecoder();
  +
  +              /**
  +               *   Get decoder for default charset.
  +               */
  +                  static CharsetDecoderPtr getDefaultDecoder();
  +
   #if LOG4CXX_HAS_WCHAR_T
  -                  static CharsetDecoderPtr getWideDecoder();
  +              /**
  +               *   Get decoder for a byte array containing wchar_t values.
  +                   */
  +                  static CharsetDecoderPtr getWideDecoder();
   #endif
   
  +              /**
  +               *  Decodes as many bytes as possible from the given
  +               *   input buffer, writing the results to the given output string.
  +               *  @param in input buffer.
  +               *  @param out output string.
  +               *  @return APR_SUCCESS if not encoding errors were found.
  +               */
                     virtual log4cxx_status_t decode(ByteBuffer& in,
                           LogString& out) = 0;
   
  +              /**
  +               *  Determins if status value indicates an invalid byte sequence.
  +               */
                     inline static bool isError(log4cxx_status_t stat) {
                        return (stat != 0);
                     }
   
             private:
  +               /**
  +               *  Private copy constructor.
  +               */
                     CharsetDecoder(const CharsetDecoder&);
  +               /**
  +               *  Private assignment operator.
  +               */
                     CharsetDecoder& operator=(const CharsetDecoder&);
  +              /**
  +               *  Creates a new decoder for the default charset.
  +               */
  +                  static CharsetDecoder* createDefaultDecoder();
             };
   
           } // namespace helpers
  
  
  
  1.3       +61 -5     logging-log4cxx/include/log4cxx/helpers/charsetencoder.h
  
  Index: charsetencoder.h
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/include/log4cxx/helpers/charsetencoder.h,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- charsetencoder.h	22 Apr 2005 05:27:22 -0000	1.2
  +++ charsetencoder.h	28 Apr 2005 20:53:45 -0000	1.3
  @@ -42,14 +42,45 @@
                     END_LOG4CXX_CAST_MAP()
   
             protected:
  -                  CharsetEncoder();
  -
  +               /**
  +               *  Protected constructor.
  +               */
  +                  CharsetEncoder();
  +
             public:
  +               /**
  +               * Destructor.
  +               */
                     virtual ~CharsetEncoder();
  +              /**
  +               *  Get encoder for default charset.
  +               */
                     static CharsetEncoderPtr getDefaultEncoder();
  -//                  static CharsetEncoderPtr getWideEncoder();
  -                  static CharsetEncoderPtr getEncoder(const std::wstring& charset);
  -                  static CharsetEncoderPtr getEncoder(const std::string& charset);
  +
  +              /**
  +               *  Get encoder for specified character set.
  +               *  @param charset, the following values should be recognized: 
  +               *     "US-ASCII", "ISO-8859-1", "UTF-8", 
  +               *     "UTF-16BE", "UTF-16LE".
  +               *  @return encoder, may be null if charset was not recognized.
  +               */
  +                  static CharsetEncoderPtr getEncoder(const std::string& charset);
  +
  +#if LOG4CXX_HAS_WCHAR_T
  +              /**
  +               *  Get encoder for wchar_t type.
  +               */
  +                  static CharsetEncoderPtr getWideEncoder();
  +
  +              /**
  +               *  Get encoder for specified character set.
  +               *  @param charset, the following values should be recognized: 
  +               *     "US-ASCII", "ISO-8859-1", "UTF-8", 
  +               *     "UTF-16BE", "UTF-16LE".
  +               *  @return encoder, may be null if charset was not recognized.
  +               */
  +              static CharsetEncoderPtr getEncoder(const std::wstring& charset);
  +#endif
   
                     /**
                     * Encodes a string replacing unmappable
  @@ -61,21 +92,46 @@
                         LogString::const_iterator& iter,
                         ByteBuffer& dst);
   
  +              /**
  +               * Encodes as many characters from the input string as possible
  +               *   to the output buffer.
  +                   *  @param in input string
  +               *  @param iter position in string to start.
  +               *  @param out output buffer.
  +               *  @return APR_SUCCESS unless a character can not be represented in
  +               *    the encoding.
  +               */
                     virtual log4cxx_status_t encode(const LogString& in,
                           LogString::const_iterator& iter,
                           ByteBuffer& out) = 0;
   
  +              /**
  +               *   Resets any internal state.
  +               */
                     virtual void reset();
   
  +              /**
  +               *   Flushes the encoder.
  +               */
                     virtual void flush(ByteBuffer& out);
   
  +              /**
  +               *   Determines if the return value from encode indicates
  +               *     an unconvertable character.
  +               */
                     inline static bool isError(log4cxx_status_t stat) {
                        return (stat != 0);
                     }
   
   
             private:
  +               /**
  +               *   Private copy constructor.
  +               */
                     CharsetEncoder(const CharsetEncoder&);
  +              /**
  +               *   Private assignment operator.
  +               */
                     CharsetEncoder& operator=(const CharsetEncoder&);
             };
   
  
  
  
  1.1                  logging-log4cxx/include/log4cxx/helpers/unicodehelper.h
  
  Index: unicodehelper.h
  ===================================================================
  /*
   * 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_UNICODEHELPER_H
  #define _LOG4CXX_HELPERS_UNICODEHELPER_H
  
  #include <string>
  #include <log4cxx/logstring.h>
  
  namespace log4cxx {
      namespace helpers {
            /**
             *   UnicodeHelper provides static methods for encoding and decoding
           *   UTF-8, UTF-16 and wchar_t from UCS-4 values.
             *
             */
            class UnicodeHelper {
            private:
                /**
                 * Inaccessible constructor.
                 */
                UnicodeHelper() {
                }
  
            public:
                /**
                 *   Decodes next character from a sequence of UTF-8 bytes.
                 *   @param src start of character, will be modified to point at next character.
                 *   @param srcEnd end of sequence. 
                 *   @return scalar value (UCS-4) or 0xFFFF if invalid sequence.
                 */
                static unsigned int decodeUTF8(const char*& src,
                    const char* srcEnd);
  
  
                /**
                 *   Encodes a character using UTF-8.
                 *   @param ch UCS-4 value.
                 *   @param dst buffer to receive UTF-8 encoding (must be at least 8 bytes)
                 *   @return number of bytes needed to represent character
                 */
                static int encodeUTF8(unsigned int ch, char* dst);
  
                /**
                 *   Encodes a character using UTF-16BE.
                 *   @param ch UCS-4 value.
                 *   @param dst buffer to receive UTF-16BE encoding (must be at least 4 bytes)
                 *   @return number of bytes needed to represent character
                 */
                static int encodeUTF16BE(unsigned int ch, char* dst);
  
                /**
                 *   Encodes a character using UTF-16LE.
                 *   @param ch UCS-4 value.
                 *   @param dst buffer to receive UTF-16BE encoding (must be at least 4 bytes)
                 *   @return number of bytes needed to represent character
                 */
                static int encodeUTF16LE(unsigned int ch, char* dst);
  
  
  #if LOG4CXX_HAS_WCHAR_T             
                /**
                 *   Decodes next character from a sequence of wchar_t values.
                 *   @param src start of character, will be modified to point at next character.
                 *   @param srcEnd end of sequence. 
                 *   @return scalar value (UCS-4) or 0xFFFF if invalid sequence.
                 */
                static unsigned int decodeWide(const wchar_t*& src, const wchar_t* srcEnd);
  
  
                /**
                 *   Encodes a character to wchar_t.
                 *   @param ch UCS-4 value.
                 *   @param dst buffer to receive wchar_t (must be at least 2 wchar_t)
                 *   @return number of wchar_t needed to represent character
                 */
                static int encodeWide(unsigned int ch, wchar_t* str);
  
             /**
              *   Determines the number of UTF-8 bytes required to express
              *   the wchar_t value.
              *   @param ch wchar_t value
              *   @return number of bytes required.
              */
                static int UnicodeHelper::lengthUTF8(wchar_t ch);
  
  #endif              
  
                /**
                 *   Decodes next character from a LogString.
                 *   @param in string from which the character is extracted.
                 *   @param iter iterator addressing start of character, will be
              *   advanced to next character if successful. 
                 *   @return scalar value (UCS-4) or 0xFFFF if invalid sequence.
                 */
                static unsigned int decode(const LogString& in,
                    LogString::const_iterator& iter);
  
            };
      }
  }
  #endif
  
  
  
  1.27      +1 -0      logging-log4cxx/src/Makefile.am
  
  Index: Makefile.am
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/src/Makefile.am,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- Makefile.am	11 Apr 2005 04:34:26 -0000	1.26
  +++ Makefile.am	28 Apr 2005 20:53:45 -0000	1.27
  @@ -100,6 +100,7 @@
           threadspecificdata.cpp \
           transcoder.cpp \
           ttcclayout.cpp \
  +        unicoderhelper.cpp \
           writer.cpp \
           writerappender.cpp \
           xmllayout.cpp\
  
  
  
  1.3       +272 -244  logging-log4cxx/src/charsetdecoder.cpp
  
  Index: charsetdecoder.cpp
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/src/charsetdecoder.cpp,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- charsetdecoder.cpp	22 Apr 2005 05:27:22 -0000	1.2
  +++ charsetdecoder.cpp	28 Apr 2005 20:53:45 -0000	1.3
  @@ -17,267 +17,295 @@
   #include <log4cxx/helpers/charsetdecoder.h>
   #include <log4cxx/helpers/bytebuffer.h>
   #include <log4cxx/helpers/exception.h>
  +#include <log4cxx/helpers/unicodehelper.h>
   #include <apr_xlate.h>
  +#if HAS_LANGINFO_CODESET
  +#include <langinfo.h>
  +#endif
   
   using namespace log4cxx;
   using namespace log4cxx::helpers;
   
  -IMPLEMENT_LOG4CXX_OBJECT(CharsetDecoder)
  -
  -
  -namespace log4cxx
  -{
  -        namespace helpers {
  -
  -#if !defined(_WIN32)
  -          /**
  -           *  Converts from an arbitrary encoding to LogString
  -           *    using apr_xlate.
  -           */
  -          class APRCharsetDecoder : public CharsetDecoder
  -          {
  -          public:
  -              APRCharsetDecoder(const char* frompage) {
  -#if LOG4CXX_LOGCHAR_IS_WCHAR
  -                const char* topage = "WCHAR_T";
  -#endif
  -#if LOG4CXX_LOGCHAR_IS_UTF8
  -                const char* topage = "UTF-8";
  -#endif
  -                apr_status_t stat = apr_pool_create(&pool, NULL);
  -                if (stat != APR_SUCCESS) {
  -                    throw PoolException(stat);
  -                }
  -                stat = apr_xlate_open(&convset,
  -                    topage,
  -                    frompage,
  -                    pool);
  -                if (stat != APR_SUCCESS) {
  -                    throw IllegalArgumentException(topage);
  -                }
  -              }
  -
  -              virtual ~APRCharsetDecoder() {
  -                apr_xlate_close(convset);
  -                apr_pool_destroy(pool);
  -              }
  -
  -              virtual log4cxx_status_t decode(ByteBuffer& in,
  -                  LogString& out) {
  -                  enum { BUFSIZE = 256 };
  -                  logchar buf[BUFSIZE];
  -                  const apr_size_t initial_outbytes_left = BUFSIZE * sizeof(logchar);
  -                  apr_status_t stat = APR_SUCCESS;
  -                  if (in.remaining() == 0) {
  -                    size_t outbytes_left = initial_outbytes_left;
  -                    stat = apr_xlate_conv_buffer((apr_xlate_t*) convset,
  -                        NULL, NULL, (char*) buf, &outbytes_left);
  -                    out.append(buf, (initial_outbytes_left - outbytes_left)/sizeof(logchar));
  -                  } else {
  -                    while(in.remaining() > 0 && stat == APR_SUCCESS) {
  -                      size_t inbytes_left = in.remaining();
  -                      size_t initial_inbytes_left = inbytes_left;
  -                      size_t pos = in.position();
  -                      apr_size_t outbytes_left = initial_outbytes_left;
  -                      stat = apr_xlate_conv_buffer((apr_xlate_t*) convset,
  -                           in.data() + pos,
  -                           &inbytes_left,
  -                           (char*) buf,
  -                           &outbytes_left);
  -                      out.append(buf, (initial_outbytes_left - outbytes_left)/sizeof(logchar));
  -                      in.position(pos + (initial_inbytes_left - inbytes_left));
  -                    }
  -                  }
  -                  return stat;
  -              }
  -
  -          private:
  -                  APRCharsetDecoder(const APRCharsetDecoder&);
  -                  APRCharsetDecoder& operator=(const APRCharsetDecoder&);
  -                  apr_pool_t* pool;
  -                  apr_xlate_t *convset;
  -          };
  -#endif
  -
  -
  -#if LOG4CXX_HAS_WCHAR_T || defined(_WIN32)
  -          /**
  -          *    Converts from the default multi-byte string to
  -          *        LogString using mbstowcs.
  -          *
  -          */
  -          class MbstowcsCharsetDecoder : public CharsetDecoder
  -          {
  -          public:
  -              MbstowcsCharsetDecoder() {
  -              }
  -
  -              virtual ~MbstowcsCharsetDecoder() {
  -              }
  -
  -              virtual log4cxx_status_t decode(ByteBuffer& in,
  -                  LogString& out) {
  -                  enum { BUFSIZE = 256 };
  -                  wchar_t buf[BUFSIZE];
  -
  -                  while(in.remaining() > 0) {
  -                      size_t requested = in.remaining();
  -                      if (requested > BUFSIZE - 1) {
  -                          requested = BUFSIZE - 1;
  -                      }
  -
  -                      for(; requested > 0; requested--) {
  -                        memset(buf, 0, BUFSIZE*sizeof(wchar_t));
  -                        size_t converted = mbstowcs(buf, in.data() + in.position(), requested);
  -                        if (converted != (size_t) -1) {
  -#if LOG4CXX_LOGCHAR_IS_WCHAR
  -                            out.append(buf);
  -#else
  -                            size_t wlen = wcslen(buf);
  -                            out.reserve(out.length() + wlen);
  -                            for(int i = 0; i < wlen; i++) {
  -                                encodeUTF8(buf[i], out);
  -                            }
  -#endif
  -                            in.position(in.position() + converted);
  -                            break;
  -                        }
  -                      }
  -                      if (requested == 0) {
  -                          return APR_BADARG;
  -                      }
  -                  }
  -                  return APR_SUCCESS;
  -              }
  -
  -
  -              static void encodeUTF8(unsigned short ch, std::string& out) {
  -                  if (ch <= 0x7F) {
  -                      out.append(1, (char) ch);
  -                  } else {
  -                      //
  -                      //   TODO
  -                      //
  -                      out.append(1, '?');
  -                  }
  -              }
  -
  -
  -
  -          private:
  -                  MbstowcsCharsetDecoder(const MbstowcsCharsetDecoder&);
  -                  MbstowcsCharsetDecoder& operator=(const MbstowcsCharsetDecoder&);
  -          };
  -#endif
  -
  -
  -#if LOG4CXX_LOGCHAR_IS_WCHAR
  -          /**
  -          *    Converts from the default multi-byte string to
  -          *        LogString using mbstowcs.
  -          *
  -          */
  -          class TrivialWideCharsetDecoder : public CharsetDecoder
  -          {
  -          public:
  -              TrivialWideCharsetDecoder() {
  -              }
  -
  -              virtual ~TrivialWideCharsetDecoder() {
  -              }
  -
  -              virtual log4cxx_status_t decode(ByteBuffer& in,
  -                  LogString& out) {
  -                  const wchar_t* src = (const wchar_t*) (in.data() + in.position());
  -                  size_t remaining = in.remaining();
  -                  size_t count = remaining / sizeof(wchar_t);
  -                  out.append(src, count);
  -                  in.position(in.position() + count * sizeof(wchar_t));
  -                  if (remaining & 1) {
  -                      return APR_BADARG;
  -                  }
  -                  return APR_SUCCESS;
  -              }
  -
  -
  -
  -          private:
  -                  TrivialWideCharsetDecoder(const TrivialWideCharsetDecoder&);
  -                  TrivialWideCharsetDecoder& operator=(const TrivialWideCharsetDecoder&);
  -          };
  -#endif
  -
  -#if LOG4CXX_LOGCHAR_IS_UTF8 && defined(_WIN32)
  -          /**
  -          *    Converts from the default multi-byte string to
  -          *        UTF-8 std::string
  -          *
  -          */
  -          class WideToUTF8CharsetDecoder : public CharsetDecoder
  -          {
  -          public:
  -              WideToUTF8CharsetDecoder() {
  -              }
  -
  -              virtual ~WideToUTF8CharsetDecoder() {
  -              }
  -
  -              virtual log4cxx_status_t decode(ByteBuffer& in,
  -                  LogString& out) {
  -                  const wchar_t* src = in.data() + in.position();
  -                  size_t remaining = in.remaining();
  -                  size_t count = remaining / sizeof(wchar_t);
  -                  out.reserve(out.length() + count;
  -                  for(int i = 0; i < count; i++, src++) {
  -                      MbstowcsCharsetDecoder::encodeUTF8(*src, out);
  -                  }
  -                  in.position(in.position() + count * sizeof(wchar_t));
  -                  if (remaining & 1) {
  -                      return APR_BADARG;
  -                  }
  -                  return APR_SUCCESS;
  -              }
  -
  -
  -
  -          private:
  -                  WideToUTF8CharsetDecoder(const WideToUTF8CharsetDecoder&);
  -                  WideToUTF8CharsetDecoder& operator=(const WideToUTF8CharsetDecoder&);
  -          };
  -#endif
  -
  -
  -        } // namespace helpers
  -
  -}  //namespace log4cxx
  +IMPLEMENT_LOG4CXX_OBJECT(CharsetDecoder)
  +
  +
  +namespace log4cxx
  +{
  +        namespace helpers {
  +
  +#if APR_HAS_XLATE
  +          /**
  +           *  Converts from an arbitrary encoding to LogString
  +           *    using apr_xlate.  Requires real iconv implementation,
  +         *    apr-iconv will crash in use.
  +           */
  +          class APRCharsetDecoder : public CharsetDecoder
  +          {
  +          public:
  +           /**
  +            *  Creates a new instance.
  +            *  @param frompage name of source encoding.
  +            */
  +              APRCharsetDecoder(const char* frompage) {
  +#if LOG4CXX_LOGCHAR_IS_WCHAR
  +                const char* topage = "WCHAR_T";
  +#endif
  +#if LOG4CXX_LOGCHAR_IS_UTF8
  +                const char* topage = "UTF-8";
  +#endif
  +                apr_status_t stat = apr_pool_create(&pool, NULL);
  +                if (stat != APR_SUCCESS) {
  +                    throw PoolException(stat);
  +                }
  +                stat = apr_xlate_open(&convset,
  +                    topage,
  +                    frompage,
  +                    pool);
  +                if (stat != APR_SUCCESS) {
  +                    throw IllegalArgumentException(topage);
  +                }
  +              }
  +
  +           /**
  +            *  Destructor.
  +            */
  +              virtual ~APRCharsetDecoder() {
  +                apr_xlate_close(convset);
  +                apr_pool_destroy(pool);
  +              }
  +
  +              virtual log4cxx_status_t decode(ByteBuffer& in,
  +                  LogString& out) {
  +                  enum { BUFSIZE = 256 };
  +                  logchar buf[BUFSIZE];
  +                  const apr_size_t initial_outbytes_left = BUFSIZE * sizeof(logchar);
  +                  apr_status_t stat = APR_SUCCESS;
  +                  if (in.remaining() == 0) {
  +                    size_t outbytes_left = initial_outbytes_left;
  +                    stat = apr_xlate_conv_buffer((apr_xlate_t*) convset,
  +                        NULL, NULL, (char*) buf, &outbytes_left);
  +                    out.append(buf, (initial_outbytes_left - outbytes_left)/sizeof(logchar));
  +                  } else {
  +                    while(in.remaining() > 0 && stat == APR_SUCCESS) {
  +                      size_t inbytes_left = in.remaining();
  +                      size_t initial_inbytes_left = inbytes_left;
  +                      size_t pos = in.position();
  +                      apr_size_t outbytes_left = initial_outbytes_left;
  +                      stat = apr_xlate_conv_buffer((apr_xlate_t*) convset,
  +                           in.data() + pos,
  +                           &inbytes_left,
  +                           (char*) buf,
  +                           &outbytes_left);
  +                      out.append(buf, (initial_outbytes_left - outbytes_left)/sizeof(logchar));
  +                      in.position(pos + (initial_inbytes_left - inbytes_left));
  +                    }
  +                  }
  +                  return stat;
  +              }
  +
  +          private:
  +                  APRCharsetDecoder(const APRCharsetDecoder&);
  +                  APRCharsetDecoder& operator=(const APRCharsetDecoder&);
  +                  apr_pool_t* pool;
  +                  apr_xlate_t *convset;
  +          };
  +#endif
  +
  +#if LOG4CXX_HAS_WCHAR_T
  +          /**
  +          *    Converts from the default multi-byte string to
  +          *        LogString using mbstowcs.
  +          *
  +          */
  +          class MbstowcsCharsetDecoder : public CharsetDecoder
  +          {
  +          public:
  +              MbstowcsCharsetDecoder() {
  +              }
  +
  +              virtual ~MbstowcsCharsetDecoder() {
  +              }
  +
  +          private:
  +#if LOG4CXX_LOGCHAR_IS_WCHAR
  +              inline log4cxx_status_t append(LogString& out, const wchar_t* buf) {
  +                  out.append(buf);
  +                  return APR_SUCCESS;
  +              }
  +#endif
  +
  +#if LOG4CXX_LOGCHAR_IS_UTF8
  +              log4cxx_status_t append(LogString& out, const wchar_t* buf) {
  +                  char utf8[8];
  +                  const wchar_t* current = buf;
  +                  const wchar_t* end = wcschr(buf, 0);
  +                  while(current < end) {
  +                      unsigned int sv = UnicodeHelper::decodeWide(current, end);
  +                      if (sv == 0xFFFF) {
  +                          return APR_BADARG;
  +                      }
  +                      int bytes = UnicodeHelper::encodeUTF8(sv, utf8);
  +                      out.append(utf8, bytes);
  +                  }
  +                  return APR_SUCCESS;
  +              }
  +#endif
  +
  +              virtual log4cxx_status_t decode(ByteBuffer& in,
  +                  LogString& out) {
  +                  log4cxx_status_t stat = APR_SUCCESS;
  +                  enum { BUFSIZE = 256 };
  +                  wchar_t buf[BUFSIZE];
  +
  +                  while(in.remaining() > 0) {
  +                      size_t requested = in.remaining();
  +                      if (requested > BUFSIZE - 1) {
  +                          requested = BUFSIZE - 1;
  +                      }
  +
  +                      for(; requested > 0; requested--) {
  +                        memset(buf, 0, BUFSIZE*sizeof(wchar_t));
  +                        size_t converted = mbstowcs(buf, in.data() + in.position(), requested);
  +                        if (converted != (size_t) -1) {
  +                            stat = append(out, buf);
  +                            in.position(in.position() + converted);
  +                            break;
  +                        }
  +                      }
  +                      if (requested == 0) {
  +                          return APR_BADARG;
  +                      }
  +                  }
  +                  return stat;
  +              }
  +
  +
  +
  +          private:
  +                  MbstowcsCharsetDecoder(const MbstowcsCharsetDecoder&);
  +                  MbstowcsCharsetDecoder& operator=(const MbstowcsCharsetDecoder&);
  +          };
  +#endif
  +
  +
  +          /**
  +          *    Decoder used when the external and internal charsets
  +        *    are the same.
  +          *
  +          */
  +          class TrivialCharsetDecoder : public CharsetDecoder
  +          {
  +          public:
  +              TrivialCharsetDecoder() {
  +              }
   
  +              virtual ~TrivialCharsetDecoder() {
  +              }
   
  -CharsetDecoder::CharsetDecoder() {
  -}
  +              virtual log4cxx_status_t decode(ByteBuffer& in,
  +                  LogString& out) {
  +                  size_t remaining = in.remaining();
  +              if( remaining > 0) {
  +               const logchar* src = (const logchar*) (in.data() + in.position());
  +               size_t count = remaining / sizeof(logchar);
  +               out.append(src, count);
  +               in.position(in.position() + remaining);
  +              }
  +                  return APR_SUCCESS;
  +              }
  +
  +
  +
  +          private:
  +                  TrivialCharsetDecoder(const TrivialCharsetDecoder&);
  +                  TrivialCharsetDecoder& operator=(const TrivialCharsetDecoder&);
  +          };
  +
  +#if LOG4CXX_LOGCHAR_IS_UTF8
  +          /**
  +          *    Decoder to convert array of wchar_t to UTF-8 bytes.
  +          *
  +          */
  +          class WideToUTF8CharsetDecoder : public CharsetDecoder
  +          {
  +          public:
  +              WideToUTF8CharsetDecoder() {
  +              }
  +
  +              virtual ~WideToUTF8CharsetDecoder() {
  +              }
  +
  +
  +              virtual log4cxx_status_t decode(ByteBuffer& in,
  +                  LogString& out) {
  +                  const wchar_t* src = (const wchar_t*) (in.data() + in.position());
  +                  const wchar_t* srcEnd = (const wchar_t*) (in.data() + in.limit());
  +                  out.reserve(out.length() + in.remaining()/sizeof(wchar_t));
  +                  char utf8[8];
  +                  while(src < srcEnd) {
  +                      unsigned int sv = UnicodeHelper::decodeWide(src, srcEnd);
  +                      if (sv == 0xFFFF) {
  +                          return APR_BADARG;
  +                      }
  +                      int bytes = UnicodeHelper::encodeUTF8(sv, utf8);
  +                      out.append(utf8, bytes);
  +                  }
  +                  in.position(((char*) src) - in.data());
  +                  return APR_SUCCESS;
  +              }
  +
  +
  +
  +          private:
  +                  WideToUTF8CharsetDecoder(const WideToUTF8CharsetDecoder&);
  +                  WideToUTF8CharsetDecoder& operator=(const WideToUTF8CharsetDecoder&);
  +          };
  +#endif
  +
  +
  +        } // namespace helpers
  +
  +}  //namespace log4cxx
  +
  +
  +CharsetDecoder::CharsetDecoder() {
  +}
   
   
   CharsetDecoder::~CharsetDecoder() {
   }
   
  -CharsetDecoderPtr CharsetDecoder::getDefaultDecoder() {
  -#if LOG4CXX_HAS_WCHAR_T || defined(_WIN32)
  -    static CharsetDecoderPtr decoder(new MbstowcsCharsetDecoder());
  -#else
  -    static CharsetDecoderPtr decoder(new APRCharsetDecoder(APR_LOCALE_CHARSET));
  -#endif
  +CharsetDecoder* CharsetDecoder::createDefaultDecoder() {
  +#if LOG4CXX_LOGCHAR_IS_UTF8 && HAS_LANGINFO_CODESET
  +    //
  +    //   detect if encoding is UTF-8
  +    //
  +    if(strcmp(nl_langinfo(CODESET), "UTF-8") == 0) {
  +        return new TrivialCharsetDecoder();
  +    }
  +#endif
  +#if LOG4CXX_HAS_WCHAR_T
  +    return new MbstowcsCharsetDecoder();
  +#else
  +    return new APRCharsetDecoder(APR_LOCALE_CHARSET);
  +#endif
  +}
  +
  +CharsetDecoderPtr CharsetDecoder::getDefaultDecoder() {
  +    static CharsetDecoderPtr decoder(createDefaultDecoder());
       return decoder;
   }
  -
  +
   #if LOG4CXX_HAS_WCHAR_T
  -CharsetDecoderPtr CharsetDecoder::getWideDecoder() {
  -#if LOG4CXX_LOGCHAR_IS_WCHAR
  -  static CharsetDecoderPtr decoder(new TrivialWideCharsetDecoder());
  -#elif defined(_WIN32)
  -  static CharsetDecoderPtr decoder(new WideToUTF8CharsetDecoder());
  +CharsetDecoderPtr CharsetDecoder::getWideDecoder() {
  +#if LOG4CXX_LOGCHAR_IS_WCHAR
  +  static CharsetDecoderPtr decoder(new TrivialCharsetDecoder());
  +#elif defined(_WIN32) || defined(__STDC_ISO_10646__)
  +  static CharsetDecoderPtr decoder(new WideToUTF8CharsetDecoder());
   #else
  -  static CharsetDecoderPtr decoder(new APRCharsetDecoder("WCHAR_T"));
  +  static CharsetDecoderPtr decoder(new APRCharsetDecoder("WCHAR_T"));
   #endif
     return decoder;
  -}
  +}
   #endif
   
  
  
  
  1.4       +195 -120  logging-log4cxx/src/charsetencoder.cpp
  
  Index: charsetencoder.cpp
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/src/charsetencoder.cpp,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- charsetencoder.cpp	22 Apr 2005 20:56:16 -0000	1.3
  +++ charsetencoder.cpp	28 Apr 2005 20:53:45 -0000	1.4
  @@ -19,6 +19,7 @@
   #include <log4cxx/helpers/exception.h>
   #include <apr_xlate.h>
   #include <log4cxx/helpers/stringhelper.h>
  +#include <log4cxx/helpers/unicodehelper.h>
   
   using namespace log4cxx;
   using namespace log4cxx::helpers;
  @@ -30,10 +31,9 @@
   
           namespace helpers {
   
  -#if !defined(_WIN32)
  +#if APR_HAS_XLATE
             /**
  -          *   An engine to transform LogStrings into bytes
  -          *     for the specific character set.
  +          * A character encoder implemented using apr_xlate.
             */
             class APRCharsetEncoder : public CharsetEncoder
             {
  @@ -97,19 +97,21 @@
             };
   #endif
   
  -#if LOG4CXX_LOGCHAR_IS_WCHAR
  +#if LOG4CXX_HAS_WCHAR_T
             /**
  -          *   An engine to transform LogStrings into bytes
  -          *     for the specific character set.
  -          */
  +           *  A character encoder implemented using wcstombs.
  +          */   
             class WcstombsCharsetEncoder : public CharsetEncoder
             {
             public:
                 WcstombsCharsetEncoder() {
                 }
   
  -              virtual log4cxx_status_t encode(const LogString& in,
  -                    LogString::const_iterator& iter,
  +           /**
  +            *   Converts a wchar_t to the default external multibyte encoding.
  +            */
  +              log4cxx_status_t encode(const std::wstring& in,
  +                  std::wstring::const_iterator& iter,
                       ByteBuffer& out) {
                         log4cxx_status_t stat = APR_SUCCESS;
   
  @@ -117,7 +119,7 @@
                            size_t outbytes_left = out.remaining();
                            size_t initial_outbytes_left = outbytes_left;
                            size_t position = out.position();
  -                         LogString::size_type inOffset = (iter - in.begin());
  +                         std::wstring::size_type inOffset = (iter - in.begin());
                            size_t inchars_left = (in.size() - inOffset);
                            apr_size_t initial_inchars_left = inchars_left;
                            enum { BUFSIZE = 256 };
  @@ -149,6 +151,7 @@
                                    if (converted != (size_t) -1) {
                                       iter += chunkSize;
                                       out.position(out.position() + converted);
  +                           break;
                                    }
                                }
                            } else {
  @@ -159,6 +162,48 @@
                         return stat;
                 }
   
  +#if LOG4CXX_LOGCHAR_IS_UTF8
  +           /**
  +            *    Performs encoding by converting UTF-8 LogString into a wstring
  +            *      and delegating to the other encode method.
  +            */
  +              virtual log4cxx_status_t encode(const std::string& in,
  +                  std::string::const_iterator& iter,
  +                  ByteBuffer& out) {
  +                  log4cxx_status_t stat = APR_SUCCESS;
  +                  if (iter != in.end()) {
  +                    std::wstring wideIn;
  +                    wideIn.reserve(in.length());
  +                    const char* src = in.data() + (iter - in.begin());
  +                    const char* srcEnd = in.data() + in.length();
  +                    wchar_t tmp[2];
  +                    while(src < srcEnd) {
  +                        unsigned int sv = UnicodeHelper::decodeUTF8(src, srcEnd);
  +                        if (sv == 0xFFFF) {
  +                            iter = in.begin() + (src - in.data());
  +                            return APR_BADARG;
  +                        }
  +
  +                        int wcharCount = UnicodeHelper::encodeWide(sv, tmp);
  +                        wideIn.append(tmp, wcharCount);
  +                    }
  +                    std::wstring::const_iterator wideIter(wideIn.begin());
  +                    stat = encode(wideIn, wideIter, out);
  +                    if (wideIter == wideIn.end()) {
  +                        iter = in.end();
  +                    } else {
  +                        for(std::wstring::const_iterator i = wideIn.begin();
  +                            i != wideIter;
  +                            i++) {
  +                            iter += UnicodeHelper::lengthUTF8(*i);
  +                        }
  +                    }
  +                  }
  +                  return stat;
  +              }
  +#endif
  +
  +
             private:
                     WcstombsCharsetEncoder(const WcstombsCharsetEncoder&);
                     WcstombsCharsetEncoder& operator=(const WcstombsCharsetEncoder&);
  @@ -166,10 +211,8 @@
   #endif
   
   
  -#if defined(_WIN32)
             /**
  -          *   An engine to transform LogStrings into bytes
  -          *     for the specific character set.
  +          *   Encodes a LogString to US-ASCII.
             */
             class USASCIICharsetEncoder : public CharsetEncoder
             {
  @@ -182,19 +225,17 @@
                       ByteBuffer& out) {
                     log4cxx_status_t stat = APR_SUCCESS;
                     if (iter != in.end()) {
  -                      char* dstEnd = out.data() + out.limit();
  -                      char* dst = out.data() + out.position();
  -                      for(;
  -                          dst < dstEnd && iter != in.end();
  -                          iter++, dst++) {
  -                          unsigned short ch = *iter;
  -                          if (0x7F < ch) {
  +                      while(out.remaining() > 0 && iter != in.end()) {
  +                    LogString::const_iterator prev(iter);
  +                          unsigned int sv = UnicodeHelper::decode(in, iter);
  +                          if (sv <= 0x7F) {
  +                              out.put((char) sv);
  +                          } else {
  +                       iter = prev;
                                 stat = APR_BADARG;
                                 break;
                             }
  -                          *dst = ch;
                         }
  -                      out.position(dst - out.data());
                     }
                     return stat;
                 }
  @@ -205,8 +246,7 @@
             };
   
             /**
  -          *   An engine to transform LogStrings into bytes
  -          *     for the specific character set.
  +          *   Converts a LogString to ISO-8859-1.
             */
             class ISOLatin1CharsetEncoder : public CharsetEncoder
             {
  @@ -214,125 +254,108 @@
                 ISOLatin1CharsetEncoder() {
                 }
   
  -#if LOG4CXX_LOGCHAR_IS_WCHAR
                 virtual log4cxx_status_t encode(const LogString& in,
                       LogString::const_iterator& iter,
                       ByteBuffer& out) {
                     log4cxx_status_t stat = APR_SUCCESS;
                     if (iter != in.end()) {
  -                      char* dstEnd = out.data() + out.limit();
  -                      char* dst = out.data() + out.position();
  -                      for(;
  -                          dst < dstEnd && iter != in.end();
  -                          iter++, dst++) {
  -                          unsigned short ch = *iter;
  -                          if (0xFF < ch) {
  +                      while(out.remaining() > 0 && iter != in.end()) {
  +                    LogString::const_iterator prev(iter);
  +                          unsigned int sv = UnicodeHelper::decode(in, iter);
  +                          if (sv <= 0xFF) {
  +                              out.put((char) sv);
  +                          } else {
  +                       iter = prev;
                                 stat = APR_BADARG;
                                 break;
                             }
  -                          *dst = ch;
                         }
  -                      out.position(dst - out.data());
                     }
                     return stat;
                 }
  -#endif
  -
  +          
             private:
                     ISOLatin1CharsetEncoder(const ISOLatin1CharsetEncoder&);
                     ISOLatin1CharsetEncoder& operator=(const ISOLatin1CharsetEncoder&);
             };
   
  -
             /**
  -          *   An engine to transform LogStrings into bytes
  -          *     for the specific character set.
  +          *   Encodes a LogString to a byte array when the encodings are indentical.
             */
  -          class UTF8CharsetEncoder : public CharsetEncoder
  +          class TrivialCharsetEncoder : public CharsetEncoder
             {
             public:
  -              UTF8CharsetEncoder() {
  +              TrivialCharsetEncoder() {
                 }
   
  -#if LOG4CXX_LOGCHAR_IS_UTF8
  +
                 virtual log4cxx_status_t encode(const LogString& in,
                       LogString::const_iterator& iter,
                       ByteBuffer& out) {
  -                  if (iter != in.end()) {
  -                      size_t inOffset = iter - in.begin();
  -                      char* dst = out.data() + out.position();
  -                      size_t count = in.length() - inOffset;
  -                      if (count > out.remaining()) {
  -                          count = out.remaining();
  -                      }
  -                      memcpy(out.data() + out.position(),
  -                             in.data() + inOffset,
  -                             count);
  -                      out.position(out.position() + count);
  -                      iter += count;
  -                  }
  +                  if(iter != in.end()) {
  +                 size_t requested = in.length() - (iter - in.begin());
  +                 if (requested > out.remaining()/sizeof(logchar)) {
  +                    requested = out.remaining()/sizeof(logchar);
  +                 }
  +                 memcpy(out.current(), 
  +                       (const char*) in.data() + (iter - in.begin()),
  +                      requested * sizeof(logchar));
  +                 iter += requested;
  +                 out.position(out.position() + requested * sizeof(logchar));
  +              }
                     return APR_SUCCESS;
                 }
  +
  +          private:
  +                  TrivialCharsetEncoder(const TrivialCharsetEncoder&);
  +                  TrivialCharsetEncoder& operator=(const TrivialCharsetEncoder&);
  +          };
  +
  +#if LOG4CXX_LOGCHAR_IS_UTF8
  +typedef TrivialCharsetEncoder UTF8CharsetEncoder;
   #endif
   
   #if LOG4CXX_LOGCHAR_IS_WCHAR
  +          /**
  +         *  Converts a wstring to UTF-8. 
  +          */
  +          class UTF8CharsetEncoder : public CharsetEncoder
  +          {
  +          public:
  +              UTF8CharsetEncoder() {
  +              }
  +
                 virtual log4cxx_status_t encode(const LogString& in,
                       LogString::const_iterator& iter,
                       ByteBuffer& out) {
  +              log4cxx_status_t stat = APR_SUCCESS;
                     if (iter != in.end()) {
  -                      size_t inOffset = iter - in.begin();
  -                      char* dst = out.data() + out.position();
  -                      char* dstEnd = out.data() + out.limit();
  -                      for(;
  -                           dst < dstEnd && iter != in.end();
  -                           iter++) {
  -                           unsigned short sv = *iter;
  -                           if (sv <= 0x7F) {
  -                               *(dst++) = sv;
  -                           } else if (sv <= 0x7FF) {
  -                               if(dst + 1 < dstEnd) {
  -                                   *(dst++) = 0xC0 | (sv >> 6);
  -                                   *(dst++) = 0x80 | (sv & 0x3F);
  -                               } else {
  -                                   break;
  -                               }
  -                           } else if (sv < 0xD800 || sv > 0xDFFF) {
  -                               if (dst + 2 < dstEnd) {
  -                                   *(dst++) = 0xE0 | (sv >> 12);
  -                                   *(dst++) = 0x80 | ((sv >> 6) & 0x3F);
  -                                   *(dst++) = 0x80 | (sv & 0x3F);
  -                               } else {
  -                                   break;
  -                               }
  -                           } else {
  -                               if (dst + 3 < dstEnd && (iter + 1) != in.end()) {
  -                                   *(dst++) = 0xF0 | ((sv >> 8) & 0x03);
  -                                   *(dst++) = 0x80 | ((sv >> 2) & 0x3F);
  -                                   unsigned short ls = *(++iter);
  -                                   *(dst++) = 0x80
  -                                               | ((sv & 0x03) << 4)
  -                                               | ((ls >> 6) & 0x0F);
  -                                   *(dst++) = 0x80 | (ls & 0x3F);
  -                               } else {
  -                                   break;
  -                               }
  +                      const logchar* const srcBase = in.data();
  +                      const logchar* const srcEnd = srcBase + in.length();
  +                      const logchar* src = in.data() + (iter - in.begin());
  +                      while(out.remaining() >= 8 && src < srcEnd) {
  +                           unsigned int sv = UnicodeHelper::decodeWide(src, srcEnd);
  +                           if (sv == 0xFFFF) {
  +                               stat = APR_BADARG;
  +                        break;
                              }
  -                       }
  -                       out.position(dst - out.data());
  +                           int bytes = UnicodeHelper::encodeUTF8(sv, out.data() + out.position());
  +                           out.position(out.position() + bytes);
  +                      }
  +                 iter = in.begin() + (src - srcBase);
                     }
                     return APR_SUCCESS;
                 }
  -#endif
   
             private:
                     UTF8CharsetEncoder(const UTF8CharsetEncoder&);
                     UTF8CharsetEncoder& operator=(const UTF8CharsetEncoder&);
             };
  +#endif
   
   
             /**
  -          *   An engine to transform LogStrings into bytes
  -          *     for the specific character set.
  +          *   Encodes a LogString to UTF16-BE.
             */
             class UTF16BECharsetEncoder : public CharsetEncoder
             {
  @@ -340,23 +363,21 @@
                 UTF16BECharsetEncoder() {
                 }
   
  -#if LOG4CXX_LOGCHAR_IS_WCHAR
                 virtual log4cxx_status_t encode(const LogString& in,
                       LogString::const_iterator& iter,
                       ByteBuffer& out) {
                     log4cxx_status_t stat = APR_SUCCESS;
  -                  char* dstEnd = out.data() + out.limit() - 1;
  -                  char* dst = out.data() + out.position();
  -                  for(;
  -                      dst < dstEnd && iter != in.end();
  -                      iter++) {
  -                      *(dst++) = (*iter & 0xFF00) >> 8;
  -                      *(dst++) = *iter & 0x00FF;
  +                  while(iter != in.end() && out.remaining() >= 4) {
  +                      unsigned int sv = UnicodeHelper::decode(in, iter);
  +                      if (sv == 0xFFFF) {
  +                          stat = APR_BADARG;
  +                          break;
  +                      }
  +                      int bytes = UnicodeHelper::encodeUTF16BE(sv, out.current());
  +                      out.position(out.position() + bytes);
                     }
  -                  out.position(dst - out.data());
                     return stat;
                 }
  -#endif
   
             private:
                     UTF16BECharsetEncoder(const UTF16BECharsetEncoder&);
  @@ -364,8 +385,7 @@
             };
   
             /**
  -          *   An engine to transform LogStrings into bytes
  -          *     for the specific character set.
  +          *   Encodes a LogString to UTF16-LE.
             */
             class UTF16LECharsetEncoder : public CharsetEncoder
             {
  @@ -373,31 +393,62 @@
                 UTF16LECharsetEncoder() {
                 }
   
  -#if LOG4CXX_LOGCHAR_IS_WCHAR
  +
                 virtual log4cxx_status_t encode(const LogString& in,
                       LogString::const_iterator& iter,
                       ByteBuffer& out) {
                     log4cxx_status_t stat = APR_SUCCESS;
  -                  char* dstEnd = out.data() + out.limit() - 1;
  -                  char* dst = out.data() + out.position();
  -                  for(;
  -                      dst < dstEnd && iter != in.end();
  -                      iter++) {
  -                      *(dst++) = *iter & 0x00FF;
  -                      *(dst++) = (*iter & 0xFF00) >> 8;
  +                  while(iter != in.end() && out.remaining() >= 4) {
  +                      unsigned int sv = UnicodeHelper::decode(in, iter);
  +                      if (sv == 0xFFFF) {
  +                          stat = APR_BADARG;
  +                          break;
  +                      }
  +                      int bytes = UnicodeHelper::encodeUTF16LE(sv, out.current());
  +                      out.position(out.position() + bytes);
                     }
  -                  out.position(dst - out.data());
                     return stat;
                 }
  -#endif
   
             private:
                     UTF16LECharsetEncoder(const UTF16LECharsetEncoder&);
                     UTF16LECharsetEncoder& operator=(const UTF16LECharsetEncoder&);
             };
   
  +#if LOG4CXX_HAS_WCHAR_T
  +          /**
  +          *   Converts a LogString to an array of wchar_t.
  +          */
  +          class WideCharsetEncoder : public CharsetEncoder
  +          {
  +          public:
  +              WideCharsetEncoder() {
  +              }
  +
  +
  +              virtual log4cxx_status_t encode(const LogString& in,
  +                    LogString::const_iterator& iter,
  +                    ByteBuffer& out) {
  +                  log4cxx_status_t stat = APR_SUCCESS;
  +                  while(iter != in.end() && out.remaining() >= 4) {
  +                      unsigned int sv = UnicodeHelper::decode(in, iter);
  +                      if (sv == 0xFFFF) {
  +                          stat = APR_BADARG;
  +                          break;
  +                      }
  +                      int count = UnicodeHelper::encodeWide(sv, (wchar_t*) out.current());
  +                      out.position(out.position() + count * sizeof(wchar_t));
  +                  }
  +                  return stat;
  +              }
  +
  +          private:
  +                  WideCharsetEncoder(const WideCharsetEncoder&);
  +                  WideCharsetEncoder& operator=(const WideCharsetEncoder&);
  +          };
   #endif
   
  +
           } // namespace helpers
   
   }  //namespace log4cxx
  @@ -411,7 +462,7 @@
   }
   
   CharsetEncoderPtr CharsetEncoder::getDefaultEncoder() {
  -#if LOG4CXX_HAS_WCHAR_T || defined(_WIN32)
  +#if LOG4CXX_HAS_WCHAR_T
     static CharsetEncoderPtr encoder(new WcstombsCharsetEncoder());
   #else
     static CharsetEncoderPtr encoder(new APRCharsetEncoder(APR_LOCALE_CHARSET));
  @@ -422,12 +473,28 @@
   
   CharsetEncoderPtr CharsetEncoder::getEncoder(const std::wstring& charset) {
      std::string cs(charset.size(), ' ');
  -   for(int i = 0; i < charset.size(); i++) {
  +   for(std::wstring::size_type i = 0; 
  +      i < charset.length(); 
  +     i++) {
         cs[i] = (char) charset[i];
      }
      return getEncoder(cs);
   }
   
  +
  +#if LOG4CXX_HAS_WCHAR_T
  +CharsetEncoderPtr CharsetEncoder::getWideEncoder() {
  +#if LOG4CXX_LOGCHAR_IS_WCHAR
  +  static CharsetEncoderPtr encoder(new TrivialCharsetEncoder());
  +#endif
  +#if LOG4CXX_LOGCHAR_IS_UTF8
  +  static CharsetEncoderPtr encoder(new WideCharsetEncoder());
  +#endif
  +   return encoder;
  +}
  +#endif
  +
  +
   CharsetEncoderPtr CharsetEncoder::getEncoder(const std::string& charset) {
   #if defined(_WIN32)
       if (StringHelper::equalsIgnoreCase(charset, "US-ASCII", "us-ascii") ||
  @@ -464,7 +531,15 @@
       ByteBuffer& dst) {
       log4cxx_status_t stat = enc->encode(src, iter, dst);
       if (stat != APR_SUCCESS && iter != src.end()) {
  +#if LOG4CXX_LOGCHAR_IS_WCHAR
         iter++;
  +#elif LOG4CXX_LOGCHAR_IS_UTF8
  +      //  advance past this character and all continuation characters
  +     while((*(++iter) & 0xC0) == 0x80);
  +#else
  +#error logchar is unrecognized
  +#endif
  +
         dst.put('?');
       }
   }
  
  
  
  1.16      +9 -9      logging-log4cxx/src/transcoder.cpp
  
  Index: transcoder.cpp
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/src/transcoder.cpp,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- transcoder.cpp	1 Apr 2005 02:02:33 -0000	1.15
  +++ transcoder.cpp	28 Apr 2005 20:53:45 -0000	1.16
  @@ -104,10 +104,11 @@
   void Transcoder::encode(const LogString& src, std::wstring& dst) {
     dst.append(src);
   }
  -#else
  -#if LOG4CXX_HAS_WCHAR_T
  +#endif
  +
  +#if LOG4CXX_LOGCHAR_IS_UTF8 && LOG4CXX_HAS_WCHAR_T
   void Transcoder::decode(const wchar_t* src, size_t len, LogString& dst) {
  -  static CharsetDecoderPtr encoder(CharsetDecoder::getWideDecoder());
  +  static CharsetDecoderPtr decoder(CharsetDecoder::getWideDecoder());
     if (len > 0) {
       ByteBuffer buf((char*) src, len * sizeof(wchar_t));
       while(buf.remaining() > 0) {
  @@ -126,18 +127,18 @@
     if (src.length() > 0) {
       char buf[BUFSIZE];
       ByteBuffer out(buf, BUFSIZE);
  -    LogString::const_iterator iter = src.begin();
  -    for(iter != src.end()) {
  +    LogString::const_iterator iter(src.begin());
  +    while(iter != src.end()) {
         log4cxx_status_t stat = encoder->encode(src, iter, out);
         out.flip();
  -      dst.append(out.data(), out.limit());
  +      dst.append((const wchar_t*)out.data(), out.limit()/sizeof(wchar_t));
         out.clear();
         if (CharsetEncoder::isError(stat)) {
           //
           //  represent character with an escape sequence
           //
  -        dst.append("\\u");
  -        const char* hexdigits = "0123456789ABCDEF";
  +        dst.append(L"\\u");
  +        const wchar_t* hexdigits = L"0123456789ABCDEF";
           unsigned short unencodable = *iter;
           dst.append(1, hexdigits[(unencodable >> 12) & 0x0F]);
           dst.append(1, hexdigits[(unencodable >> 8) & 0x0F]);
  @@ -150,7 +151,6 @@
     }
   }
   #endif
  -#endif
   
   
   
  
  
  
  1.1                  logging-log4cxx/src/unicodehelper.cpp
  
  Index: unicodehelper.cpp
  ===================================================================
  /*
   * 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/unicodehelper.h>
  #include <apr_errno.h>
  
  using namespace log4cxx;
  using namespace log4cxx::helpers;
  
  
  
  unsigned int UnicodeHelper::decodeUTF8(const char*& src, 
                                         const char* srcEnd) {
    const char* start = src;
    unsigned char ch1 = *(src++);
    if (ch1 <= 0x7F) {
        return ch1;
    }
    //
    //   should not have continuation character here
    //
    if ((ch1 & 0xC0) != 0x80 && src < srcEnd) {
        unsigned char ch2 = *(src++);
        //
        //   should be continuation
        if ((ch2 & 0xC0) != 0x80) {
          src = start;
            return 0xFFFF;
        }
        if((ch1 & 0xE0) == 0xC0) {
            if ((ch2 & 0xC0) == 0x80) {
                unsigned int rv = ((ch1 & 0x1F) << 6) + (ch2 & 0x3F);
                if (rv >= 0x80) {
                    return rv;
                }
            }
          src = start;
            return 0xFFFF;
        }
        if (src < srcEnd) {
            unsigned char ch3 = *(src++);
            //
            //   should be continuation
            //
            if ((ch3 & 0xC0) != 0x80) {
             src = start;
                return 0xFFFF;
            }
            if ((ch1 & 0xF0) == 0xE0) {
                unsigned rv = ((ch1 & 0x0F) << 12)
                + ((ch2 & 0x3F) << 6) 
                + (ch3 & 0x3F);
                if (rv <= 0x800) {
                src = start;
                    return 0xFFFF;
                }
                return rv;
            }
            if (src < srcEnd) {
                unsigned char ch4 = *(src++);
                if ((ch4 & 0xC0) != 0x80) {
                src = start;
                    return 0xFFFF;
                }
                unsigned int rv = ((ch1 & 0x07) << 18)
                       + ((ch2 & 0x3F) << 12)
                       + ((ch3 & 0x3F) << 6)
                       + (ch4 & 0x3F);
                if (rv > 0xFFFF) {
                    return rv;
                }
  
            }
        }
    }
    src = start;
    return 0xFFFF;
  }
  
  
  
  #if defined(_WIN32)
  unsigned int UnicodeHelper::decodeWide(const wchar_t*& src, const wchar_t* srcEnd) {
      unsigned int sv = *(src++);
      if (sv < 0xDC00 || sv >= 0xDC00) {
          return sv;
      }
      if (src < srcEnd) {
          unsigned short ls = *(src++);
          unsigned char w = (unsigned char) ((sv >> 6) & 0x0F);
          return ((w + 1) << 16) + ((sv & 0x3F) << 10) + (ls & 0x3FF);
      }
      return 0xFFFF;
  }
  
  
  int UnicodeHelper::encodeWide(unsigned int ch, wchar_t* dst) {
    if (ch <= 0xFFFF) {
        *dst = (wchar_t) ch;
        return 1;
    }
    unsigned char u = (unsigned char) (ch >> 16);
    unsigned char w = (unsigned char) (u - 1);
    wchar_t hs = (wchar_t) (0xD800 + ((w & 0xF) << 6) + ((ch & 0xFFFF) >> 10));
    wchar_t ls = (wchar_t) (0xDC00 + (ch && 0x3FF));
    dst[0] = hs;
    dst[1] = ls;
    return 2;
  }
  
  int UnicodeHelper::lengthUTF8(wchar_t ch) {
    if (ch <= 0x7F) {
        return 1;
    } 
    if(ch <= 0x7FF) {
        return 2;
    }
    //
    //   if low surrogate, only add 1 which in combination with
    //   three from high surrogate makes 4 total UTF-8 bytes
    if (ch >= 0xDC00 && ch <= 0xDFFF) {
        return 1;
    }
    return 3;
  }
  
  #endif
  
  
  #if LOG4CXX_HAS_WCHAR_T && defined(__STDC_ISO_10646__)
  int UnicodeHelper::encodeWide(unsigned int ch, wchar_t* dst) {
     *dst = ch;
     return 1;
  }
  
  unsigned int UnicodeHelper::decodeWide(const wchar_t*& src, const wchar_t* srcEnd) {
      return *(src++);
  }
  
  int UnicodeHelper::lengthUTF8(wchar_t ch) {
    if (ch <= 0x7F) {
        return 1;
    } 
    if(ch <= 0x7FF) {
        return 2;
    }
    if (ch <= 0xFFFF) {
        return 3;
    }
    return 4;
  }
  
  #endif
  
  
  
  int UnicodeHelper::encodeUTF8(unsigned int ch, char* dst) {
      if (ch < 0x80) {
          dst[0] = (char) ch;
          return 1;
      } else if (ch < 0x800) {
          dst[0] = (char) (0xC0 + (ch >> 6));
          dst[1] = (char) (0x80 + (ch & 0x3F));
          return 2;
      } else if (ch < 0x10000) {
          dst[0] = (char) (0xE0 + (ch >> 12));
          dst[1] = (char) (0x80 + ((ch >> 6) & 0x3F));
          dst[2] = (char) (0x80 + (ch & 0x3F));
          return 3;
      } else if (ch <= 0x10FFFF) {
          dst[0] = (char) (0xF0 + (ch >> 18));
          dst[1] = (char) (0x80 + ((ch >> 12) & 0x3F));
          dst[2] = (char) (0x80 + ((ch >> 6) & 0x3F));
          dst[3] = (char) (0x80 + (ch & 0x3F));
          return 4;
      } else {
          //
          //  output UTF-8 encoding of 0xFFFF
          //
          dst[0] = 0xEF;
          dst[1] = 0xBF;
          dst[2] = 0xBF;
          return 3;
      }
  }
  
  
  
  int UnicodeHelper::encodeUTF16BE(unsigned int ch, char* dst) {
      if (ch <= 0xFFFF) {
          dst[0] = (char) (ch >> 8);
          dst[1] = (char) (ch & 0xFF);
          return 2;
      }
      if (ch <= 0x10FFFF) {
          unsigned char w = (unsigned char) ((ch >> 16) - 1);
          dst[0] = (char) (0xD8 + (w >> 2));
          dst[1] = (char) (((w & 0x03) << 6) + ((ch >> 10) & 0x3F));
          dst[2] = (char) (0xDC + ((ch & 0x30) >> 4));
          dst[3] = (char) (ch & 0xFF);
          return 4;
      }
      dst[0] = dst[1] = 0xFF;
      return 2;
  }
  
  int UnicodeHelper::encodeUTF16LE(unsigned int ch, char* dst) {
      if (ch <= 0xFFFF) {
          dst[1] = (char) (ch >> 8);
          dst[0] = (char) (ch & 0xFF);
          return 2;
      }
      if (ch <= 0x10FFFF) {
          unsigned char w = (unsigned char) ((ch >> 16) - 1);
          dst[1] = (char) (0xD8 + (w >> 2));
          dst[0] = (char) (((w & 0x03) << 6) + ((ch >> 10) & 0x3F));
          dst[3] = (char) (0xDC + ((ch & 0x30) >> 4));
          dst[2] = (char) (ch & 0xFF);
          return 4;
      }
      dst[0] = dst[1] = 0xFF;
      return 2;
  }
  
  #if LOG4CXX_LOGCHAR_IS_WCHAR
  unsigned int UnicodeHelper::decode(const LogString& in, LogString::const_iterator& iter) {
      const wchar_t* src = in.data() + (iter - in.begin());
      const wchar_t* srcEnd = in.data() + in.length();
      unsigned int sv = decodeWide(src, srcEnd);
      iter = in.begin() + (src - in.data());
      return sv;
  }
  #endif
  
  
  #if LOG4CXX_LOGCHAR_IS_UTF8
  unsigned int UnicodeHelper::decode(const LogString& in, LogString::const_iterator& iter) {
      const char* src = in.data() + (iter - in.begin());
      const char* srcEnd = in.data() + in.length();
      unsigned int sv = decodeUTF8(src, srcEnd);
      iter = in.begin() + (src - in.data());
      return sv;
  }
  #endif
  
  
  
  
  1.8       +12 -9     logging-log4cxx/tests/src/shortsocketserver.cpp
  
  Index: shortsocketserver.cpp
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/tests/src/shortsocketserver.cpp,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- shortsocketserver.cpp	11 Mar 2005 06:34:49 -0000	1.7
  +++ shortsocketserver.cpp	28 Apr 2005 20:53:45 -0000	1.8
  @@ -25,7 +25,7 @@
   #include <log4cxx/net/socketnode.h>
   
   #include "net/socketservertestcase.h"
  -#include <log4cxx/stream.h>
  +#include <sstream>
   #include <iostream>
   #include <stdlib.h>
   
  @@ -61,23 +61,26 @@
         //
         //   using the stream interface since it knows
         //      numeric and encoding conversion
  -      logstream log(Logger::getLogger("shortsocketserver"), Level::DEBUG);
  +      LoggerPtr logger(Logger::getLogger("shortsocketserver"));
  +     std::ostringstream os("Listening on port ");
  +     os << PORT;
  +     LOG4CXX_INFO(logger, os.str());
   
  -      log << "Listening on port " << PORT << LOG4CXX_ENDMSG;
  -      ServerSocket serverSocket(PORT);
  +     ServerSocket serverSocket(PORT);
   
         MDC::put("hostID", "shortSocketServer");
   
         for (int i = 1; i <= totalTests; i++)
         {
  -                        std::ostringstream sbuf(prefix);
  +         std::ostringstream sbuf(prefix);
            sbuf <<  i  << ".properties";
            PropertyConfigurator::configure(sbuf.str());
  -         log << "Waiting to accept a new client." << LOG4CXX_ENDMSG;
  +         LOG4CXX_INFO(logger, "Waiting to accept a new client.");
            SocketPtr socket = serverSocket.accept();
  -                        log << "Connected to client at "
  -                            << socket->getInetAddress().toString() << LOG4CXX_ENDMSG;
  -         log << "Starting new socket node." << LOG4CXX_ENDMSG;
  +       LogString msg(socket->getInetAddress().toString());
  +       msg.insert(0, LOG4CXX_STR("Connected to client at "));
  +       LOG4CXX_INFO(logger, msg);
  +         LOG4CXX_INFO(logger, "Starting new socket node.");
            SocketNode sn(socket, LogManager::getLoggerRepository());
            sn.run();
         }
  
  
  
  1.10      +2 -1      logging-log4cxx/tests/src/helpers/Makefile.am
  
  Index: Makefile.am
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/tests/src/helpers/Makefile.am,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- Makefile.am	19 Feb 2005 01:59:37 -0000	1.9
  +++ Makefile.am	28 Apr 2005 20:53:45 -0000	1.10
  @@ -18,7 +18,8 @@
           relativetimedateformattestcase.cpp \
           stringtokenizertestcase.cpp \
           timezonetestcase.cpp \
  -        transcodertestcase.cpp
  +        transcodertestcase.cpp \
  +        unicodehelpertestcase.cpp 
   
   check: libhelpers.a
   
  
  
  
  1.3       +0 -71     logging-log4cxx/tests/src/helpers/transcodertestcase.cpp
  
  Index: transcodertestcase.cpp
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/tests/src/helpers/transcodertestcase.cpp,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- transcodertestcase.cpp	11 Mar 2005 06:34:50 -0000	1.2
  +++ transcodertestcase.cpp	28 Apr 2005 20:53:45 -0000	1.3
  @@ -36,11 +36,7 @@
   #if LOG4CXX_HAS_WCHAR_T
                   CPPUNIT_TEST(decode4);
   #endif
  -                CPPUNIT_TEST(decode5);
  -                CPPUNIT_TEST(decode6);
                   CPPUNIT_TEST(decode7);
  -                CPPUNIT_TEST(decode8);
  -                CPPUNIT_TEST(decode9);
   #if LOG4CXX_HAS_WCHAR_T
                   CPPUNIT_TEST(encode1);
   #endif
  @@ -89,34 +85,6 @@
           }
   #endif
   
  -        void decode5() {
  -            //
  -            //  copyright symbol on ISO-8859-1, bad sequence in UTF-8
  -            const char badUTF8[] = { 0xA9, 0 } ;
  -            LogString decoded(LOG4CXX_STR("foo"));
  -            Transcoder::decode(badUTF8, decoded);
  -            CPPUNIT_ASSERT_EQUAL((size_t) 4, decoded.length());
  -            CPPUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("foo"), decoded.substr(0, 3));
  -            if (decoded[3] != (logchar) 0x00A9) {
  -              CPPUNIT_ASSERT_EQUAL(LOG4CXX_STR('?'), decoded[3]);
  -            }
  -        }
  -
  -
  -        void decode6() {
  -            //
  -            //  copyright symbol on ISO-8859-1, bad sequence in UTF-8
  -            //    Followed by "Hello"
  -            const char badUTF8[] = { 0xA9, 'H', 'e', 'l', 'l', 'o', 0 } ;
  -            LogString decoded(LOG4CXX_STR("foo"));
  -            Transcoder::decode(badUTF8, decoded);
  -            CPPUNIT_ASSERT_EQUAL((size_t) 9, decoded.length());
  -            CPPUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("foo"), decoded.substr(0, 3));
  -            CPPUNIT_ASSERT_EQUAL((LogString) LOG4CXX_STR("Hello"), decoded.substr(4));
  -            if (decoded[3] != (logchar) 0x00A9) {
  -              CPPUNIT_ASSERT_EQUAL(LOG4CXX_STR('?'), decoded[3]);
  -            }
  -        }
   
           enum { BUFSIZE = 255 };
   
  @@ -135,45 +103,6 @@
                     decoded.substr(BUFSIZE -2 ));
           }
   
  -        void decode8() {
  -            //
  -            //   Bad UTF-8 striding over a buffer boundary
  -            //
  -            std::string longMsg(BUFSIZE - 1, 'A');
  -            longMsg.append(1, (char) 0xA9);
  -            LogString decoded;
  -            Transcoder::decode(longMsg, decoded);
  -            CPPUNIT_ASSERT_EQUAL((size_t) BUFSIZE, decoded.length());
  -            CPPUNIT_ASSERT_EQUAL(LogString(BUFSIZE - 1, LOG4CXX_STR('A')),
  -                  decoded.substr(0, BUFSIZE - 1));
  -            if (decoded[BUFSIZE - 1] != (logchar) 0x00A9) {
  -              CPPUNIT_ASSERT_EQUAL(LOG4CXX_STR('?'), decoded[BUFSIZE-1]);
  -            }
  -        }
  -
  -
  -        void decode9() {
  -            //
  -            //   Good UTF-8 multibyte sequqnce striding over a buffer boundary
  -            //
  -            std::string longMsg(BUFSIZE - 1, 'A');
  -            longMsg.append(1, (char) 0xC2);
  -            longMsg.append(1, (char) 0xA9);
  -            longMsg.append("Hello");
  -            LogString decoded;
  -            Transcoder::decode(longMsg, decoded);
  -            //
  -            //  starts with a lot of A's
  -            CPPUNIT_ASSERT_EQUAL(LogString(BUFSIZE - 1, LOG4CXX_STR('A')),
  -                  decoded.substr(0, BUFSIZE - 1));
  -            //
  -            //  ends with Hello
  -            CPPUNIT_ASSERT_EQUAL(LogString(LOG4CXX_STR("Hello")),
  -                  decoded.substr(decoded.length() - 5));
  -            //
  -            //  can't say what the middle should be
  -            //      typically copyright or an accented A + copyright
  -        }
   
   #if LOG4CXX_HAS_WCHAR_T
           void encode1() {
  
  
  
  1.1                  logging-log4cxx/tests/src/helpers/unicodehelpertestcase.cpp
  
  Index: unicodehelpertestcase.cpp
  ===================================================================
  /*
   * 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.
   */
  
  #if defined(LOG4CXX)
  #include <cppunit/TestFixture.h>
  #include <cppunit/extensions/HelperMacros.h>
  
  #include <log4cxx/helpers/unicodehelper.h>
  #include "../testchar.h"
  
  using namespace log4cxx;
  using namespace log4cxx::helpers;
  
  /**
   *   Tests for log4cxx::helpers::UnicodeHelper.
   *
   */
  class UnicodeHelperTestCase : public CppUnit::TestFixture
  {
          CPPUNIT_TEST_SUITE(UnicodeHelperTestCase);
                  CPPUNIT_TEST(testDecodeUTF8_1);
                  CPPUNIT_TEST(testDecodeUTF8_2);
                  CPPUNIT_TEST(testDecodeUTF8_3);
                  CPPUNIT_TEST(testDecodeUTF8_4);
  #if LOG4CXX_HAS_WCHAR_T
                  CPPUNIT_TEST(testDecodeWide_1);
  #endif
          CPPUNIT_TEST_SUITE_END();
  
  
  public:
  
      void testDecodeUTF8_1() {
          const char* const src = "a";
          const char* iter = src;
          unsigned int sv = UnicodeHelper::decodeUTF8(iter, src + 1);
          CPPUNIT_ASSERT_EQUAL((unsigned int) 0x61, sv);
          CPPUNIT_ASSERT(iter == src + 1);
  
      }
  
      void testDecodeUTF8_2() {
          const char src[] = { 0x80};
          const char* iter = src;
          unsigned int sv = UnicodeHelper::decodeUTF8(iter, src + 1);
          CPPUNIT_ASSERT_EQUAL((unsigned int) 0xFFFF, sv);
      }
  
      void testDecodeUTF8_3() {
          const char src[] = { 0xC2, 0xA9};
          const char* iter = src;
          unsigned int sv = UnicodeHelper::decodeUTF8(iter, src + 1);
          CPPUNIT_ASSERT_EQUAL((unsigned int) 0xFFFF, sv);
      }
  
      void testDecodeUTF8_4() {
          const char src[] = { 0xC2, 0xA9};
          const char* iter = src;
          unsigned int sv = UnicodeHelper::decodeUTF8(iter, src + 2);
          CPPUNIT_ASSERT_EQUAL((unsigned int) 0xA9, sv);
      }
  
  #if LOG4CXX_HAS_WCHAR_T
      void testDecodeWide_1() {
          const wchar_t* const src = L"a";
          const wchar_t* iter = src;
          unsigned int sv = UnicodeHelper::decodeWide(iter, src + 1);
          CPPUNIT_ASSERT_EQUAL((unsigned int) 0x61, sv);
          CPPUNIT_ASSERT(iter == src + 1);
  #endif
      }
  
  };
  
  CPPUNIT_TEST_SUITE_REGISTRATION(UnicodeHelperTestCase);
  
  #endif