maint: update copyright
[gnulib.git] / lib / uniconv / u8-conv-from-enc.c
index 09eba1e..6136e4b 100644 (file)
@@ -1,5 +1,5 @@
 /* Conversion to UTF-8 from legacy encodings.
-   Copyright (C) 2002, 2006-2007, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2006-2007, 2009-2014 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify it
    under the terms of the GNU Lesser General Public License as published
 #include "striconveha.h"
 #include "unistr.h"
 
-int
+uint8_t *
 u8_conv_from_encoding (const char *fromcode,
-                      enum iconv_ilseq_handler handler,
-                      const char *src, size_t srclen,
-                      size_t *offsets,
-                      uint8_t **resultp, size_t *lengthp)
+                       enum iconv_ilseq_handler handler,
+                       const char *src, size_t srclen,
+                       size_t *offsets,
+                       uint8_t *resultbuf, size_t *lengthp)
 {
   if (STRCASEEQ (fromcode, "UTF-8", 'U','T','F','-','8',0,0,0,0))
     {
@@ -42,47 +42,64 @@ u8_conv_from_encoding (const char *fromcode,
       uint8_t *result;
 
       if (u8_check ((const uint8_t *) src, srclen))
-       {
-         errno = EILSEQ;
-         return -1;
-       }
+        {
+          errno = EILSEQ;
+          return NULL;
+        }
 
       if (offsets != NULL)
-       {
-         size_t i;
-
-         for (i = 0; i < srclen; )
-           {
-             int count = u8_mblen ((const uint8_t *) src + i, srclen - i);
-             /* We can rely on count > 0 because of the previous u8_check.  */
-             if (count <= 0)
-               abort ();
-             offsets[i] = i;
-             i++;
-             while (--count > 0)
-               offsets[i++] = (size_t)(-1);
-           }
-       }
+        {
+          size_t i;
+
+          for (i = 0; i < srclen; )
+            {
+              int count = u8_mblen ((const uint8_t *) src + i, srclen - i);
+              /* We can rely on count > 0 because of the previous u8_check.  */
+              if (count <= 0)
+                abort ();
+              offsets[i] = i;
+              i++;
+              while (--count > 0)
+                offsets[i++] = (size_t)(-1);
+            }
+        }
 
       /* Memory allocation.  */
-      if ((*resultp != NULL && *lengthp >= srclen) || srclen == 0)
-       result = *resultp;
+      if (resultbuf != NULL && *lengthp >= srclen)
+        result = resultbuf;
       else
-       {
-         result = (uint8_t *) malloc (srclen);
-         if (result == NULL)
-           {
-             errno = ENOMEM;
-             return -1;
-           }
-       }
+        {
+          result = (uint8_t *) malloc (srclen > 0 ? srclen : 1);
+          if (result == NULL)
+            {
+              errno = ENOMEM;
+              return NULL;
+            }
+        }
 
       memcpy ((char *) result, src, srclen);
-      *resultp = result;
       *lengthp = srclen;
-      return 0;
+      return result;
     }
   else
-    return mem_iconveha (src, srclen, fromcode, "UTF-8", true, handler,
-                        offsets, (char **) resultp, lengthp);
+    {
+      char *result = (char *) resultbuf;
+      size_t length = *lengthp;
+
+      if (mem_iconveha (src, srclen, fromcode, "UTF-8", true, handler,
+                        offsets, &result, &length) < 0)
+        return NULL;
+
+      if (result == NULL) /* when (resultbuf == NULL && length == 0)  */
+        {
+          result = (char *) malloc (1);
+          if (result == NULL)
+            {
+              errno = ENOMEM;
+              return NULL;
+            }
+        }
+      *lengthp = length;
+      return (uint8_t *) result;
+    }
 }