From 98600f0033d82de1f880079d5a11168ec90b17db Mon Sep 17 00:00:00 2001
From: Tinny Ng <tng@apache.org>
Date: Mon, 3 Dec 2001 14:45:11 +0000
Subject: [PATCH] FreeBSD native transcoder (IconvFBSD) added by Max Gotlib.

git-svn-id: https://svn.apache.org/repos/asf/xerces/c/trunk@173336 13f79535-47bb-0310-9956-ffa450edef68
---
 doc/faq-parse.xml                             |  20 +-
 src/configure                                 |   8 +-
 src/configure.in                              |   3 +-
 src/runConfigure                              |   4 +-
 src/util/Makefile.in                          |   9 +-
 .../FreeBSD/FreeBSDPlatformUtils.cpp          |   7 +-
 .../IconvFBSD/IconvFBSDTransService.cpp       | 622 ++++++++++++++++++
 .../IconvFBSD/IconvFBSDTransService.hpp       | 213 ++++++
 src/util/Transcoders/IconvFBSD/Makefile.in    |  87 +++
 9 files changed, 947 insertions(+), 26 deletions(-)
 create mode 100644 src/util/Transcoders/IconvFBSD/IconvFBSDTransService.cpp
 create mode 100644 src/util/Transcoders/IconvFBSD/IconvFBSDTransService.hpp
 create mode 100644 src/util/Transcoders/IconvFBSD/Makefile.in

diff --git a/doc/faq-parse.xml b/doc/faq-parse.xml
index 909cd1182..e86092a1c 100644
--- a/doc/faq-parse.xml
+++ b/doc/faq-parse.xml
@@ -924,26 +924,10 @@ catch (const XMLException&amp; toCatch) {
     <q>Why do I get compilation error when compiling &XercesCName; on FreeBSD with native transcoder?</q>
 
     <a>
-       <p>You may get the following compilation errors when compiling &XercesCName; with native transcoder on
-          FreeBSD version 4.3 or below:
-       </p>
-       <p>
-          IconvTransService.cpp:68: wchar.h: No such file or directory<br/>
-          IconvTransService.cpp:70: wctype.h: No such file or directory<br/>
-          IconvTransService.cpp: In method 'int IconvTransService::compareIString(const XMLCh *, const XMLCh *)'<br/>
-          ...
-       </p>
-       <p>This is due to FreeBSD version 4.3 or below missing headers wchar.h and wctype.h,
-          missing the function towupper, and the functions wcstombs and mbstowcs are not conforming
-          to the standard.
-       </p>
-
-       <p>See <jump href="http://marc.theaimsgroup.com/?l=xerces-c-dev">Mail Archive "XercesC under
-          FreeBSD... Dated October 1, 2001"</jump> for earlier discussion and work around.
+       <p>Please make sure you configure with "-t IconvFBSD" to use FreeBSD specific native transcoder.
        </p>
 
-       <p>Or you can use ICU transcoder (configure with -t icu) instead of the native transcoder on FreeBSD.
-          Or try FreeBSD 4.4 or above.
+       <p>Or you can use ICU transcoder (configure with -t icu) instead of the native transcoder.
        </p>
 
     </a>
diff --git a/src/configure b/src/configure
index 0fb74d43f..b8953675a 100755
--- a/src/configure
+++ b/src/configure
@@ -1254,7 +1254,7 @@ case "${host}" in
         *-*-UnixWare*)  platform=UNIXWARE ;;
         *-*-unixware*)  platform=UNIXWARE ;;
         *-*-linux*)     platform=LINUX ;;
-	*-*-freebsd*)	platform=FREEBSD ;;
+        *-*-freebsd*)   platform=FREEBSD ;;
         *-*-irix*)      platform=IRIX ;;
         *-*-aix*)       platform=AIX
                       case "${host}" in
@@ -1440,6 +1440,7 @@ util/Transcoders/ICU/Makefile \
 util/Transcoders/Iconv/Makefile \
 util/Transcoders/Iconv390/Makefile \
 util/Transcoders/Iconv400/Makefile \
+util/Transcoders/IconvFBSD/Makefile \
 util/Transcoders/MacOSUnicodeConverter/Makefile \
 util/Platforms/Makefile \
 util/Platforms/Solaris/Makefile \
@@ -1582,6 +1583,7 @@ util/Transcoders/ICU/Makefile \
 util/Transcoders/Iconv/Makefile \
 util/Transcoders/Iconv390/Makefile \
 util/Transcoders/Iconv400/Makefile \
+util/Transcoders/IconvFBSD/Makefile \
 util/Transcoders/MacOSUnicodeConverter/Makefile \
 util/Platforms/Makefile \
 util/Platforms/Solaris/Makefile \
@@ -1679,10 +1681,10 @@ rm -f conftest.s*
 
 EOF
 cat >> $CONFIG_STATUS <<EOF
-
+chmod +x ./runConfigure
 EOF
 cat >> $CONFIG_STATUS <<\EOF
-
+chmod +x ./configure
 exit 0
 EOF
 chmod +x $CONFIG_STATUS
diff --git a/src/configure.in b/src/configure.in
index ea16dab17..2d674855b 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script
 AC_INIT(util/XercesDefs.hpp)
 dnl AC_CONFIG_HEADER(common/icucfg.h)
 
-AM_INIT_AUTOMAKE(xerces-c,1.5.1)
+dnl AM_INIT_AUTOMAKE(xerces-c,1.6.0)
 dnl Checks for programs
 AC_PROG_CC
 AC_PROG_CXX
@@ -106,6 +106,7 @@ util/Transcoders/ICU/Makefile \
 util/Transcoders/Iconv/Makefile \
 util/Transcoders/Iconv390/Makefile \
 util/Transcoders/Iconv400/Makefile \
+util/Transcoders/IconvFBSD/Makefile \
 util/Transcoders/MacOSUnicodeConverter/Makefile \
 util/Platforms/Makefile \
 util/Platforms/Solaris/Makefile \
diff --git a/src/runConfigure b/src/runConfigure
index 5fbe1ac75..86524dc98 100755
--- a/src/runConfigure
+++ b/src/runConfigure
@@ -85,7 +85,7 @@ usage()
     echo "       -d (specifies that you want to build debug version)"
     echo "       -m <message loader> can be 'inmem', 'icu', 'MsgFile' or 'iconv'"
     echo "       -n <net accessor> can be 'fileonly', 'libwww', 'socket' or 'native'"
-    echo "       -t <transcoder> can be 'icu', 'Iconv400', 'Iconv390' or 'native'"
+    echo "       -t <transcoder> can be 'icu', 'Iconv400', 'Iconv390', 'IconvFBSD' or 'native'"
     echo "       -r <thread option> can be 'pthread' or 'dce' (only used on aix, HP-11 and solaris) or 'sproc' (only on IRIX) or 'none'"
     echo "       -l <extra linker options>"
     echo "       -z <extra compiler options>"
@@ -363,6 +363,8 @@ case $transcoder in
    Iconv390)
        transcodingDefines="-DXML_USE_ICONV390_TRANSCODER" ;
        TRANSCODER=Iconv390 ;;
+   IconvFBSD)
+       TRANSCODER=IconvFBSD ;;
    native)
        ;;
 
diff --git a/src/util/Makefile.in b/src/util/Makefile.in
index 2fe4ebb64..bff20568e 100644
--- a/src/util/Makefile.in
+++ b/src/util/Makefile.in
@@ -55,6 +55,9 @@
 #
 #
 # $Log$
+# Revision 1.52  2001/12/03 14:45:11  tng
+# FreeBSD native transcoder (IconvFBSD) added by Max Gotlib.
+#
 # Revision 1.51  2001/11/19 21:59:00  peiyongz
 # Reorganization: Double/Float
 #
@@ -276,7 +279,11 @@ else
 		ifeq (${TRANSCODER},Iconv390)
 		   TRANSCODERMODULE=Iconv390
 		else
-		   TRANSCODERMODULE=Iconv
+		    ifeq (${TRANSCODER},IconvFBSD)
+			TRANSCODERMODULE=IconvFBSD
+		    else
+		        TRANSCODERMODULE=Iconv
+		    endif
 		endif
 	   endif
 	endif
diff --git a/src/util/Platforms/FreeBSD/FreeBSDPlatformUtils.cpp b/src/util/Platforms/FreeBSD/FreeBSDPlatformUtils.cpp
index 4d45a6870..d99133ff3 100644
--- a/src/util/Platforms/FreeBSD/FreeBSDPlatformUtils.cpp
+++ b/src/util/Platforms/FreeBSD/FreeBSDPlatformUtils.cpp
@@ -56,6 +56,9 @@
 
 /*
  * $Log$
+ * Revision 1.2  2001/12/03 14:45:11  tng
+ * FreeBSD native transcoder (IconvFBSD) added by Max Gotlib.
+ *
  * Revision 1.1  2001/11/29 18:25:18  tng
  * FreeBSD support by Michael Huedepohl.
  *
@@ -93,7 +96,7 @@
     #include <util/Transcoders/ICU/ICUTransService.hpp>
 #else
     // Use native transcoder. Same as -DXML_USE_NATIVE_TRANSCODER
-    #include <util/Transcoders/Iconv/IconvTransService.hpp>
+    #include <util/Transcoders/IconvFBSD/IconvFBSDTransService.hpp>
 #endif
 
 
@@ -310,7 +313,7 @@ XMLTransService* XMLPlatformUtils::makeTransService()
 #else
     // Use native transcoding services.
     // same as -DXML_USE_INMEM_MESSAGELOADER
-    return new IconvTransService;
+    return new IconvFBSDTransService;
 
 #endif
 }
diff --git a/src/util/Transcoders/IconvFBSD/IconvFBSDTransService.cpp b/src/util/Transcoders/IconvFBSD/IconvFBSDTransService.cpp
new file mode 100644
index 000000000..14688b252
--- /dev/null
+++ b/src/util/Transcoders/IconvFBSD/IconvFBSDTransService.cpp
@@ -0,0 +1,622 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Xerces" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written
+ *    permission, please contact apache\@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation, and was
+ * originally based on software copyright (c) 2001, International
+ * Business Machines, Inc., http://www.ibm.com .  For more information
+ * on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+/*
+ * $Log$
+ * Revision 1.1  2001/12/03 14:45:11  tng
+ * FreeBSD native transcoder (IconvFBSD) added by Max Gotlib.
+ *
+ */
+
+
+// ---------------------------------------------------------------------------
+//  Includes
+// ---------------------------------------------------------------------------
+#include <util/XMLUniDefs.hpp>
+#include <util/XMLUni.hpp>
+#include "IconvFBSDTransService.hpp"
+
+#include <ctype.h>
+
+#if __FreeBSD_cc_version > 430000
+# include <wchar.h>
+#else
+# define wint_t XMLCh
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+
+// ---------------------------------------------------------------------------
+//  Local, const data
+// ---------------------------------------------------------------------------
+static const int    gTempBuffArraySize = 1024;
+static const XMLCh  gMyServiceId[] =
+{
+    chLatin_I, chLatin_C, chLatin_o, chLatin_n, chLatin_v, chNull
+};
+
+
+// ---------------------------------------------------------------------------
+//  Local methods
+// ---------------------------------------------------------------------------
+static unsigned int getWideCharLength(const XMLCh* const src)
+{
+    if (!src)
+        return 0;
+
+    unsigned int len = 0;
+    const XMLCh* pTmp = src;
+    while (*pTmp++)
+        len++;
+    return len;
+}
+
+// ---------------------------------------------------------------------------
+// FreeBSD got the wide-characters support since 4.0 version. But (at least
+// up to the 4.4) this support differs from "others" in that the xxstoyys()
+// does not handle the NULL-dest argument properly. So the custom functions
+// are provided.
+// ---------------------------------------------------------------------------
+
+#define __TMP_ARRAY_SIZE__      4
+
+static size_t fbsd_wcstombs(char *dest, const wchar_t *src, size_t n)
+{
+    char        tarr[ __TMP_ARRAY_SIZE__ + 1 ];
+    size_t      len = 0, lent = 0;
+    char*       ptr;
+    size_t      slen;
+    wchar_t*    wptr;
+
+    if (dest)
+        return ::wcstombs(dest, src, n);
+    if (!src)
+        return 0;
+    for (wptr = (wchar_t *) src, slen = 0; *wptr; wptr++, slen++);
+    if (slen == 0)
+        return 0;
+    wptr = (wchar_t *) src;
+    ptr = dest;
+    while ( (len = ::wcstombs(tarr, wptr, __TMP_ARRAY_SIZE__)) > 0 ) {
+        wptr += len;
+        lent += len;
+    }
+    if (len == (unsigned) -1)
+        return 0;
+    return lent;
+}
+
+static size_t fbsd_mbstowcs(wchar_t *dest, const char *src, size_t n)
+{
+    wchar_t     tarr[ __TMP_ARRAY_SIZE__ + 1 ];
+    size_t      len = 0, lent = 0;
+    char*       ptr;
+
+    if (dest)
+        return ::mbstowcs(dest, src, n);
+    ptr = (char*) src;
+    if (!src || strlen(src) == 0)
+        return 0;
+    while ( (len = ::mbstowcs(tarr, ptr, __TMP_ARRAY_SIZE__)) > 0 ) {
+        ptr += len;
+        lent += len;
+    }
+    if (len == (unsigned) -1)
+        return 0;
+    return lent;
+}
+
+static wint_t fbsd_towupper(wint_t ch)
+{
+    char buf[16];
+    wcstombs(buf, (wchar_t*) &ch, 1);
+    return toupper(ch);
+}
+
+// ---------------------------------------------------------------------------
+//  IconvFBSDTransService: Constructors and Destructor
+// ---------------------------------------------------------------------------
+IconvFBSDTransService::IconvFBSDTransService()
+{
+}
+
+IconvFBSDTransService::~IconvFBSDTransService()
+{
+}
+
+
+// ---------------------------------------------------------------------------
+//  IconvFBSDTransService: The virtual transcoding service API
+// ---------------------------------------------------------------------------
+int IconvFBSDTransService::compareIString(  const   XMLCh* const    comp1
+                                        , const XMLCh* const    comp2)
+{
+    const XMLCh* cptr1 = comp1;
+    const XMLCh* cptr2 = comp2;
+
+    while ( (*cptr1 != 0) && (*cptr2 != 0) )
+    {
+        wint_t wch1 = fbsd_towupper(*cptr1);
+        wint_t wch2 = fbsd_towupper(*cptr2);
+        if (wch1 != wch2)
+            break;
+
+        cptr1++;
+        cptr2++;
+    }
+    return (int) ( fbsd_towupper(*cptr1) - fbsd_towupper(*cptr2) );
+}
+
+
+int IconvFBSDTransService::compareNIString( const   XMLCh* const    comp1
+                                        , const XMLCh* const    comp2
+                                        , const unsigned int    maxChars)
+{
+    unsigned int  n = 0;
+    const XMLCh* cptr1 = comp1;
+    const XMLCh* cptr2 = comp2;
+
+    while (true && maxChars)
+    {
+        wint_t wch1 = fbsd_towupper(*cptr1);
+        wint_t wch2 = fbsd_towupper(*cptr2);
+
+        if (wch1 != wch2)
+            return (int) (wch1 - wch2);
+
+        // If either ended, then both ended, so equal
+        if (!*cptr1 || !*cptr2)
+            break;
+
+        cptr1++;
+        cptr2++;
+
+        //  Bump the count of chars done. If it equals the count then we
+        //  are equal for the requested count, so break out and return
+        //  equal.
+        n++;
+        if (n == maxChars)
+            break;
+    }
+
+    return 0;
+}
+
+
+const XMLCh* IconvFBSDTransService::getId() const
+{
+    return gMyServiceId;
+}
+
+
+bool IconvFBSDTransService::isSpace(const XMLCh toCheck) const
+{
+    char buf[16];
+    mbstowcs( (wchar_t*) &toCheck, buf, 1 );
+    return (isspace(*buf) != 0);
+}
+
+
+XMLLCPTranscoder* IconvFBSDTransService::makeNewLCPTranscoder()
+{
+    // Just allocate a new transcoder of our type
+    return new IconvFBSDLCPTranscoder;
+}
+
+bool IconvFBSDTransService::supportsSrcOfs() const
+{
+    return true;
+}
+
+
+// ---------------------------------------------------------------------------
+//  IconvFBSDTransService: The protected virtual transcoding service API
+// ---------------------------------------------------------------------------
+XMLTranscoder*
+IconvFBSDTransService::makeNewXMLTranscoder(const   XMLCh* const            encodingName
+                                        ,       XMLTransService::Codes& resValue
+                                        , const unsigned int            )
+{
+    //
+    //  NOTE: We don't use the block size here
+    //
+    //  This is a minimalist transcoding service, that only supports a local
+    //  default transcoder. All named encodings return zero as a failure,
+    //  which means that only the intrinsic encodings supported by the parser
+    //  itself will work for XML data.
+    //
+    resValue = XMLTransService::UnsupportedEncoding;
+    return 0;
+}
+
+void IconvFBSDTransService::upperCase(XMLCh* const toUpperCase) const
+{
+    XMLCh* outPtr = toUpperCase;
+    while (*outPtr)
+    {
+        *outPtr = fbsd_towupper(*outPtr);
+        outPtr++;
+    }
+}
+
+
+
+// ---------------------------------------------------------------------------
+//  IconvFBSDLCPTranscoder: The virtual transcoder API
+// ---------------------------------------------------------------------------
+unsigned int IconvFBSDLCPTranscoder::calcRequiredSize(const char* const srcText)
+{
+    if (!srcText)
+        return 0;
+
+    const unsigned int retVal = fbsd_mbstowcs(NULL, srcText, 0);
+
+    if (retVal == ~0)
+        return 0;
+    return retVal;
+}
+
+
+unsigned int IconvFBSDLCPTranscoder::calcRequiredSize(const XMLCh* const srcText)
+{
+    if (!srcText)
+        return 0;
+
+    unsigned int  wLent = getWideCharLength(srcText);
+    wchar_t       tmpWideCharArr[gTempBuffArraySize];
+    wchar_t*      allocatedArray = 0;
+    wchar_t*      wideCharBuf = 0;
+
+    if (wLent >= gTempBuffArraySize)
+        wideCharBuf = allocatedArray = new wchar_t[wLent + 1];
+    else
+        wideCharBuf = tmpWideCharArr;
+
+    for (unsigned int i = 0; i < wLent; i++)
+    {
+        wideCharBuf[i] = srcText[i];
+    }
+    wideCharBuf[wLent] = 0x00;
+
+    const unsigned int retVal = fbsd_wcstombs(NULL, wideCharBuf, 0);
+    if (allocatedArray)
+        delete [] allocatedArray;
+
+    if (retVal == ~0)
+        return 0;
+    return retVal;
+}
+
+
+char* IconvFBSDLCPTranscoder::transcode(const XMLCh* const toTranscode)
+{
+    if (!toTranscode)
+        return 0;
+
+    char* retVal = 0;
+    if (*toTranscode)
+    {
+        unsigned int  wLent = getWideCharLength(toTranscode);
+
+        wchar_t       tmpWideCharArr[gTempBuffArraySize];
+        wchar_t*      allocatedArray = 0;
+        wchar_t*      wideCharBuf = 0;
+
+        if (wLent >= gTempBuffArraySize)
+            wideCharBuf = allocatedArray = new wchar_t[wLent + 1];
+        else
+            wideCharBuf = tmpWideCharArr;
+
+        for (unsigned int i = 0; i < wLent; i++)
+        {
+            wideCharBuf[i] = toTranscode[i];
+        }
+        wideCharBuf[wLent] = 0x00;
+
+        // Calc the needed size.
+        const size_t neededLen = fbsd_wcstombs(NULL, wideCharBuf, 0);
+        if (neededLen == -1)
+        {
+            if (allocatedArray)
+                delete [] allocatedArray;
+            return 0;
+        }
+
+        retVal = new char[neededLen + 1];
+        fbsd_wcstombs(retVal, wideCharBuf, neededLen);
+        retVal[neededLen] = 0;
+        if (allocatedArray)
+            delete [] allocatedArray;
+    }
+    else
+    {
+        retVal = new char[1];
+        retVal[0] = 0;
+    }
+    return retVal;
+}
+
+
+bool IconvFBSDLCPTranscoder::transcode( const   XMLCh* const    toTranscode
+                                    ,       char* const     toFill
+                                    , const unsigned int    maxBytes)
+{
+    // Watch for a couple of pyscho corner cases
+    if (!toTranscode || !maxBytes)
+    {
+        toFill[0] = 0;
+        return true;
+    }
+
+    if (!*toTranscode)
+    {
+        toFill[0] = 0;
+        return true;
+    }
+
+    unsigned int  wLent = getWideCharLength(toTranscode);
+    wchar_t       tmpWideCharArr[gTempBuffArraySize];
+    wchar_t*      allocatedArray = 0;
+    wchar_t*      wideCharBuf = 0;
+
+    if (wLent > maxBytes) {
+        wLent = maxBytes;
+    }
+
+    if (maxBytes >= gTempBuffArraySize)
+        wideCharBuf = allocatedArray = new wchar_t[maxBytes + 1];
+    else
+        wideCharBuf = tmpWideCharArr;
+
+    for (unsigned int i = 0; i < wLent; i++)
+    {
+        wideCharBuf[i] = toTranscode[i];
+    }
+    wideCharBuf[wLent] = 0x00;
+
+    // Ok, go ahead and try the transcoding. If it fails, then ...
+    if (fbsd_wcstombs(toFill, wideCharBuf, maxBytes) == -1)
+    {
+        if (allocatedArray)
+            delete [] allocatedArray;
+        return false;
+    }
+
+    // Cap it off just in case
+    toFill[wLent] = 0;
+    if (allocatedArray)
+        delete [] allocatedArray;
+    return true;
+}
+
+
+
+XMLCh* IconvFBSDLCPTranscoder::transcode(const char* const toTranscode)
+{
+    if (!toTranscode)
+        return 0;
+
+    XMLCh* retVal = 0;
+    if (*toTranscode)
+    {
+        const unsigned int len = calcRequiredSize(toTranscode);
+        if (len == 0)
+        {
+            retVal = new XMLCh[1];
+            retVal[0] = 0;
+            return retVal;
+        }
+
+        wchar_t       tmpWideCharArr[gTempBuffArraySize];
+        wchar_t*      allocatedArray = 0;
+        wchar_t*      wideCharBuf = 0;
+
+        if (len >= gTempBuffArraySize)
+            wideCharBuf = allocatedArray = new wchar_t[len + 1];
+        else
+            wideCharBuf = tmpWideCharArr;
+
+        fbsd_mbstowcs(wideCharBuf, toTranscode, len);
+        retVal = new XMLCh[len + 1];
+        for (unsigned int i = 0; i < len; i++)
+        {
+            retVal[i] = (XMLCh) wideCharBuf[i];
+        }
+        retVal[len] = 0x00;
+        if (allocatedArray)
+            delete [] allocatedArray;
+    }
+    else
+    {
+        retVal = new XMLCh[1];
+        retVal[0] = 0;
+    }
+    return retVal;
+}
+
+
+bool IconvFBSDLCPTranscoder::transcode( const   char* const     toTranscode
+                                    ,       XMLCh* const    toFill
+                                    , const unsigned int    maxChars)
+{
+    // Check for a couple of psycho corner cases
+    if (!toTranscode || !maxChars)
+    {
+        toFill[0] = 0;
+        return true;
+    }
+
+    if (!*toTranscode)
+    {
+        toFill[0] = 0;
+        return true;
+    }
+
+    unsigned int len = calcRequiredSize(toTranscode);
+    wchar_t       tmpWideCharArr[gTempBuffArraySize];
+    wchar_t*      allocatedArray = 0;
+    wchar_t*      wideCharBuf = 0;
+
+    if (len > maxChars) {
+        len = maxChars;
+    }
+
+    if (maxChars >= gTempBuffArraySize)
+        wideCharBuf = allocatedArray = new wchar_t[maxChars + 1];
+    else
+        wideCharBuf = tmpWideCharArr;
+
+    if (fbsd_mbstowcs(wideCharBuf, toTranscode, maxChars) == -1)
+    {
+        if (allocatedArray)
+            delete [] allocatedArray;
+        return false;
+    }
+
+    for (unsigned int i = 0; i < len; i++)
+    {
+        toFill[i] = (XMLCh) wideCharBuf[i];
+    }
+    toFill[len] = 0x00;
+    if (allocatedArray)
+        delete [] allocatedArray;
+    return true;
+}
+
+
+
+// ---------------------------------------------------------------------------
+//  IconvFBSDLCPTranscoder: Constructors and Destructor
+// ---------------------------------------------------------------------------
+IconvFBSDLCPTranscoder::IconvFBSDLCPTranscoder()
+{
+}
+
+IconvFBSDLCPTranscoder::~IconvFBSDLCPTranscoder()
+{
+}
+
+// ---------------------------------------------------------------------------
+//  IconvFBSDTranscoder: Constructors and Destructor
+// ---------------------------------------------------------------------------
+IconvFBSDTranscoder::IconvFBSDTranscoder(const  XMLCh* const    encodingName
+                                , const unsigned int    blockSize) :
+
+    XMLTranscoder(encodingName, blockSize)
+{
+}
+
+IconvFBSDTranscoder::~IconvFBSDTranscoder()
+{
+}
+
+
+// ---------------------------------------------------------------------------
+//  IconvFBSDTranscoder: Implementation of the virtual transcoder API
+// ---------------------------------------------------------------------------
+XMLCh IconvFBSDTranscoder::transcodeOne(const   XMLByte* const  srcData
+                                    , const unsigned int    srcBytes
+                                    ,       unsigned int&   bytesEaten)
+{
+    wchar_t  toFill;
+    int eaten = ::mbtowc(&toFill, (const char*)srcData, srcBytes);
+    if (eaten == -1)
+    {
+        bytesEaten = 0;
+        return 0;
+    }
+
+    // Return the bytes we ate and the resulting char.
+    bytesEaten = eaten;
+    return toFill;
+}
+
+
+unsigned int
+IconvFBSDTranscoder::transcodeXML(  const   XMLByte* const          srcData
+                                , const unsigned int            srcCount
+                                ,       XMLCh* const            toFill
+                                , const unsigned int            maxChars
+                                ,       unsigned int&           bytesEaten
+                                ,       unsigned char* const    charSizes)
+{
+    //
+    //  For this one, because we have to maintain the offset table, we have
+    //  to do them one char at a time until we run out of source data.
+    //
+    unsigned int countIn = 0;
+    unsigned int countOut = 0;
+    while (countOut < maxChars)
+    {
+        wchar_t   oneWideChar;
+        const int bytesEaten =
+            ::mbtowc(&oneWideChar, (const char*)&srcData[countIn], srcCount - countIn);
+
+        // We are done, so break out
+        if (bytesEaten == -1)
+            break;
+        toFill[countOut] = (XMLCh) oneWideChar;
+        countIn += (unsigned int) bytesEaten;
+        countOut++;
+    }
+
+    // Give back the counts of eaten and transcoded
+    bytesEaten = countIn;
+    return countOut;
+}
diff --git a/src/util/Transcoders/IconvFBSD/IconvFBSDTransService.hpp b/src/util/Transcoders/IconvFBSD/IconvFBSDTransService.hpp
new file mode 100644
index 000000000..ab97b9963
--- /dev/null
+++ b/src/util/Transcoders/IconvFBSD/IconvFBSDTransService.hpp
@@ -0,0 +1,213 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Xerces" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written
+ *    permission, please contact apache\@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation, and was
+ * originally based on software copyright (c) 2001, International
+ * Business Machines, Inc., http://www.ibm.com .  For more information
+ * on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+/*
+ * $Log$
+ * Revision 1.1  2001/12/03 14:45:11  tng
+ * FreeBSD native transcoder (IconvFBSD) added by Max Gotlib.
+ *
+ */
+
+#ifndef ICONVFBSDTRANSSERVICE_HPP
+#define ICONVFBSDTRANSSERVICE_HPP
+
+#include <util/TransService.hpp>
+
+class XMLUTIL_EXPORT IconvFBSDTransService : public XMLTransService
+{
+public :
+    // -----------------------------------------------------------------------
+    //  Constructors and Destructor
+    // -----------------------------------------------------------------------
+    IconvFBSDTransService();
+    ~IconvFBSDTransService();
+
+
+    // -----------------------------------------------------------------------
+    //  Implementation of the virtual transcoding service API
+    // -----------------------------------------------------------------------
+    virtual int compareIString
+    (
+        const   XMLCh* const    comp1
+        , const XMLCh* const    comp2
+    );
+
+    virtual int compareNIString
+    (
+        const   XMLCh* const    comp1
+        , const XMLCh* const    comp2
+        , const unsigned int    maxChars
+    );
+
+    virtual const XMLCh* getId() const;
+
+    virtual bool isSpace(const XMLCh toCheck) const;
+
+    virtual XMLLCPTranscoder* makeNewLCPTranscoder();
+
+    virtual bool supportsSrcOfs() const;
+
+    virtual void upperCase(XMLCh* const toUpperCase) const;
+
+protected :
+    // -----------------------------------------------------------------------
+    //  Protected virtual methods
+    // -----------------------------------------------------------------------
+    virtual XMLTranscoder* makeNewXMLTranscoder
+    (
+        const   XMLCh* const            encodingName
+        ,       XMLTransService::Codes& resValue
+        , const unsigned int            blockSize
+    );
+
+
+private :
+    // -----------------------------------------------------------------------
+    //  Unimplemented constructors and operators
+    // -----------------------------------------------------------------------
+    IconvFBSDTransService(const IconvFBSDTransService&);
+    void operator=(const IconvFBSDTransService&);
+};
+
+
+
+
+class XMLUTIL_EXPORT IconvFBSDTranscoder : public XMLTranscoder
+{
+public :
+    // -----------------------------------------------------------------------
+    //  Constructors and Destructor
+    // -----------------------------------------------------------------------
+    IconvFBSDTranscoder(const XMLCh* const encodingName, const unsigned int blockSize);
+    ~IconvFBSDTranscoder();
+
+
+    // -----------------------------------------------------------------------
+    //  Implementation of the virtual transcoder interface
+    // -----------------------------------------------------------------------
+    virtual XMLCh transcodeOne
+    (
+        const   XMLByte* const  srcData
+        , const unsigned int    srcBytes
+        ,       unsigned int&   bytesEaten
+    );
+
+    virtual unsigned int transcodeXML
+    (
+        const   XMLByte* const          srcData
+        , const unsigned int            srcCount
+        ,       XMLCh* const            toFill
+        , const unsigned int            maxChars
+        ,       unsigned int&           bytesEaten
+        ,       unsigned char* const    charSizes
+    );
+
+
+private :
+    // -----------------------------------------------------------------------
+    //  Unimplemented constructors and operators
+    // -----------------------------------------------------------------------
+    IconvFBSDTranscoder(const IconvFBSDTranscoder&);
+    void operator=(const IconvFBSDTranscoder&);
+};
+
+
+
+class XMLUTIL_EXPORT IconvFBSDLCPTranscoder : public XMLLCPTranscoder
+{
+public :
+    // -----------------------------------------------------------------------
+    //  Constructors and Destructor
+    // -----------------------------------------------------------------------
+    IconvFBSDLCPTranscoder();
+    ~IconvFBSDLCPTranscoder();
+
+
+    // -----------------------------------------------------------------------
+    //  Implementation of the virtual transcoder interface
+    // -----------------------------------------------------------------------
+    virtual unsigned int calcRequiredSize(const char* const srcText);
+
+    virtual unsigned int calcRequiredSize(const XMLCh* const srcText);
+
+    virtual char* transcode(const XMLCh* const toTranscode);
+
+    virtual bool transcode
+    (
+        const   XMLCh* const    toTranscode
+        ,       char* const     toFill
+        , const unsigned int    maxBytes
+    );
+
+    virtual XMLCh* transcode(const char* const toTranscode);
+
+    virtual bool transcode
+    (
+        const   char* const     toTranscode
+        ,       XMLCh* const    toFill
+        , const unsigned int    maxChars
+    );
+
+
+private :
+    // -----------------------------------------------------------------------
+    //  Unimplemented constructors and operators
+    // -----------------------------------------------------------------------
+    IconvFBSDLCPTranscoder(const IconvFBSDLCPTranscoder&);
+    void operator=(const IconvFBSDLCPTranscoder&);
+};
+
+#endif /* ICONVFBSDTRANSSERVICE */
diff --git a/src/util/Transcoders/IconvFBSD/Makefile.in b/src/util/Transcoders/IconvFBSD/Makefile.in
new file mode 100644
index 000000000..2cb11c546
--- /dev/null
+++ b/src/util/Transcoders/IconvFBSD/Makefile.in
@@ -0,0 +1,87 @@
+#
+# The Apache Software License, Version 1.1
+#
+# Copyright (c) 2001 The Apache Software Foundation.  All rights
+# reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in
+#    the documentation and/or other materials provided with the
+#    distribution.
+#
+# 3. The end-user documentation included with the redistribution,
+#    if any, must include the following acknowledgment:
+#       "This product includes software developed by the
+#        Apache Software Foundation (http://www.apache.org/)."
+#    Alternately, this acknowledgment may appear in the software itself,
+#    if and wherever such third-party acknowledgments normally appear.
+#
+# 4. The names "Xerces" and "Apache Software Foundation" must
+#    not be used to endorse or promote products derived from this
+#    software without prior written permission. For written
+#    permission, please contact apache\@apache.org.
+#
+# 5. Products derived from this software may not be called "Apache",
+#    nor may "Apache" appear in their name, without prior written
+#    permission of the Apache Software Foundation.
+#
+# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+# ====================================================================
+#
+# This software consists of voluntary contributions made by many
+# individuals on behalf of the Apache Software Foundation, and was
+# originally based on software copyright (c) 2001, International
+# Business Machines, Inc., http://www.ibm.com .  For more information
+# on the Apache Software Foundation, please see
+# <http://www.apache.org/>.
+#
+#
+# $Log$
+# Revision 1.1  2001/12/03 14:45:11  tng
+# FreeBSD native transcoder (IconvFBSD) added by Max Gotlib.
+#
+#
+
+PLATFORM = @platform@
+CC  = @cc@
+CXX = @cxx@
+CXXFLAGS = @cxxflags@
+CFLAGS = @cflags@
+PREFIX = @prefix@
+PREFIX_INCLUDE = @prefix_include@
+LDFLAGS = @ldflags@
+LIBS = @libs@
+OSVER = @osver@
+USELIBWWW = @uselibwww@
+MESSAGELOADER = @messageloader@
+TRANSCODER = @transcoder@
+THREADS = @threads@
+
+MODULE = util
+SUBMODULE = Transcoders/IconvFBSD
+
+include ../../../Makefile.incl
+
+CPP_PUBHEADERS = IconvFBSDTransService.hpp
+
+CPP_OBJECTS = IconvFBSDTransService.$(TO)
+
+include ../../Makefile.util.submodule
-- 
GitLab