OK, looks like my first patch breaks the build... I should've compiled the
complete source before sending the patch in.
Looks like ut_iconv.h _is_ used by C files... so I shouldn't use C++ stuff
in there, like overloading or not using extern "C".

Anyway, here's an updated patch that works.
Use this one instead of the first one.

-- 
"They that can give up essential liberty to obtain a little temporary
safety deserve neither liberty nor safety."
                                                 -- Benjamin Franklin
Index: src/af/util/xp/ut_iconv.cpp
===================================================================
RCS file: /cvsroot/abi/src/af/util/xp/ut_iconv.cpp,v
retrieving revision 1.18
diff -u -r1.18 ut_iconv.cpp
--- src/af/util/xp/ut_iconv.cpp 2001/12/11 18:47:47     1.18
+++ src/af/util/xp/ut_iconv.cpp 2002/02/04 22:34:54
@@ -156,7 +156,7 @@
   //    while some (newer, conformant ones) do
 
   if ( !UT_iconv_isValid ( cd ) )
-    return -1;
+    return (size_t)-1;
 
   ICONV_CONST char ** buf = (ICONV_CONST char**)(inbuf);
   return iconv( cd, buf, inbytesleft, outbuf, outbytesleft );
@@ -210,6 +210,34 @@
                return NULL;
        }
 
+       UT_iconv_t cd = INVALID_ICONV_HANDLE;
+       UT_TRY
+         {
+           auto_iconv converter(from_codeset, to_codeset);
+           cd = converter.getHandle();
+           return UT_convert(str, len, cd, bytes_read_arg, bytes_written_arg);
+         }
+       UT_CATCH(UT_CATCH_ANY)
+         {
+           if (bytes_read_arg)
+               *bytes_read_arg = 0;
+           if (bytes_written_arg)
+               *bytes_written_arg = 0;
+           return NULL;
+         }
+       UT_END_CATCH
+}
+
+/*! This function is almost the same as the other UT_convert function,
+ * only that it takes an UT_iconv_t instead of a from and to codeset.
+ * This is useful if you need to do a conversion multiple times
+ */
+char * UT_convert(const char *str,
+                 UT_sint32 len,
+                 UT_iconv_t cd,
+                 UT_uint32 *bytes_read_arg,
+                 UT_uint32 *bytes_written_arg)
+{
        // The following two variables are used to be used in absence of given 
arguments
        // (to not have to check for NULL pointers upon assignment).
        UT_uint32 bytes_read_local;
@@ -218,114 +246,99 @@
        UT_uint32& bytes_read = bytes_read_arg ? *bytes_read_arg : bytes_read_local; 
        UT_uint32& bytes_written = bytes_written_arg ? *bytes_written_arg : 
bytes_written_local;
 
-       UT_iconv_t cd = INVALID_ICONV_HANDLE;
-
-       UT_TRY
+       if (len < 0)
          {
-           auto_iconv converter(from_codeset, to_codeset);
-           cd = converter.getHandle();
+           len = strlen(str);
+         }
 
-           if (len < 0)
-             {
-               len = strlen(str);
-             }
+       const char* p = str;
+       size_t inbytes_remaining = len;
 
-           const char* p = str;
-           size_t inbytes_remaining = len;
+       /* Due to a GLIBC bug, round outbuf_size up to a multiple of 4 */
+       /* + 1 for nul in case len == 1 */
+       size_t outbuf_size = ((len + 3) & ~3) + 15;
+       size_t outbytes_remaining = outbuf_size - 1; /* -1 for nul */
 
-           /* Due to a GLIBC bug, round outbuf_size up to a multiple of 4 */
-           /* + 1 for nul in case len == 1 */
-           size_t outbuf_size = ((len + 3) & ~3) + 15;
-           size_t outbytes_remaining = outbuf_size - 1; /* -1 for nul */
+       char* pDest = (char*)malloc(outbuf_size);
+       char* outp = pDest;
 
-           char* pDest = (char*)malloc(outbuf_size);
-           char* outp = pDest;
+       bool have_error = false;
+       bool bAgain = true;
 
-           bool have_error = false;
-           bool bAgain = true;
+       while (bAgain)
+         {
+           size_t err = UT_iconv(cd,
+                                 &p,
+                                 &inbytes_remaining,
+                                 &outp, &outbytes_remaining);
 
-           while (bAgain)
+           if (err == (size_t) -1)
              {
-               size_t err = UT_iconv(cd,
-                                     &p,
-                                     &inbytes_remaining,
-                                     &outp, &outbytes_remaining);
-
-               if (err == (size_t) -1)
-                 {
-                   switch (errno)
-                     {
-                     case EINVAL:
-                                   /* Incomplete text, do not report an error */
-                       bAgain = false;
-                       break;
-                     case E2BIG:
-                       {
-                         size_t used = outp - pDest;
-
-                         /* glibc's iconv can return E2BIG even if there is space
-                          * remaining if an internal buffer is exhausted. The
-                          * folllowing is a heuristic to catch this. The 16 is
-                          * pretty arbitrary.
-                          */
-                         if (used + 16 > outbuf_size)
-                           {
-                             outbuf_size = outbuf_size  + 15;
-                             pDest = (char*)realloc(pDest, outbuf_size);
-
-                             outp = pDest + used;
-                             outbytes_remaining = outbuf_size - used - 1; /* -1 for 
nul */
-                           }
-
-                         bAgain = true;
-                         break;
-                       }
-                     default:
-                       have_error = true;
-                       bAgain = false;
-                       break;
-                     }
-                 } 
-               else 
+               switch (errno)
                  {
+                 case EINVAL:
+                   /* Incomplete text, do not report an error */
+                   bAgain = false;
+                   break;
+                 case E2BIG:
+                   {
+                     size_t used = outp - pDest;
+
+                     /* glibc's iconv can return E2BIG even if there is space
+                      * remaining if an internal buffer is exhausted. The
+                      * folllowing is a heuristic to catch this. The 16 is
+                      * pretty arbitrary.
+                      */
+                     if (used + 16 > outbuf_size)
+                       {
+                         outbuf_size = outbuf_size  + 15;
+                         pDest = (char*)realloc(pDest, outbuf_size);
+
+                         outp = pDest + used;
+                         outbytes_remaining = outbuf_size - used - 1; /* -1 for nul */
+                       }
+
+                     bAgain = true;
+                     break;
+                   }
+                 default:
+                   have_error = true;
                    bAgain = false;
+                   break;
                  }
              }
-
-           *outp = '\0';
-
-           const size_t nNewLen = p - str;
-
-           if (bytes_read_arg)
-             {
-               bytes_read = nNewLen;
-             }
-           else
+           else 
              {
-               if (nNewLen != len) 
-                 {
-                   have_error = true;
-                 }
+               bAgain = false;
              }
+         }
+
+       *outp = '\0';
 
-           bytes_written = outp - pDest;       /* Doesn't include '\0' */
+       const size_t nNewLen = p - str;
 
-           if (have_error && pDest)
+       if (bytes_read_arg)
+         {
+           bytes_read = nNewLen;
+         }
+       else
+         {
+           if (nNewLen != len) 
              {
-               free(pDest);
+               have_error = true;
              }
+         }
 
-           if (have_error)
-             return NULL;
+       bytes_written = outp - pDest;   /* Doesn't include '\0' */
 
-           return pDest;
-         }
-       UT_CATCH(UT_CATCH_ANY)
+       if (have_error && pDest)
          {
-           bytes_read = 0;
-           bytes_written = 0;
-           return NULL;
+           free(pDest);
          }
-       UT_END_CATCH
+
+       if (have_error)
+         return NULL;
+
+       return pDest;
 }
 
Index: src/af/util/xp/ut_iconv.h
===================================================================
RCS file: /cvsroot/abi/src/af/util/xp/ut_iconv.h,v
retrieving revision 1.10
diff -u -r1.10 ut_iconv.h
--- src/af/util/xp/ut_iconv.h   2001/09/28 15:29:44     1.10
+++ src/af/util/xp/ut_iconv.h   2002/02/04 22:34:54
@@ -81,6 +81,16 @@
 
 UT_END_EXTERN_C
 
+#ifdef __cplusplus
+
+char *      UT_convert (const char *str,
+                       UT_sint32 len,
+                       UT_iconv_t cd,
+                       UT_uint32 *bytes_read,
+                       UT_uint32 *bytes_written);
+
+#endif
+
 #endif /* UT_ICONV_H */
 
 

Attachment: msg21868/pgp00000.pgp
Description: PGP signature

Reply via email to