All pastes #880828 Raw Edit

Stuff

public diff v1 · immutable
#880828 ·published 2008-01-29 21:23 UTC
rendered paste body
diff --git a/src/lib/lightmediascanner_charset_conv.c b/src/lib/lightmediascanner_charset_conv.cindex 77b82aa..cfe3148 100644--- a/src/lib/lightmediascanner_charset_conv.c+++ b/src/lib/lightmediascanner_charset_conv.c@@ -26,7 +26,6 @@ #include <errno.h>  struct lms_charset_conv {-    iconv_t check;     iconv_t fallback;     unsigned int size;     iconv_t *convs;@@ -53,16 +52,10 @@ lms_charset_conv_new(void)         return NULL;     } -    lcc->check = iconv_open("UTF-8", "UTF-8");-    if (lcc->check == (iconv_t)-1) {-        perror("ERROR: could not create conversion checker");-        goto error_check;-    }-     lcc->fallback = iconv_open("UTF-8//IGNORE", "UTF-8");     if (lcc->fallback == (iconv_t)-1) {         perror("ERROR: could not create conversion fallback");-        goto error_fallback;+        goto error;     }      lcc->size = 0;@@ -70,9 +63,7 @@ lms_charset_conv_new(void)     lcc->names = NULL;     return lcc; -  error_fallback:-    iconv_close(lcc->check);-  error_check:+  error:     free(lcc);      return NULL;@@ -91,7 +82,6 @@ lms_charset_conv_free(lms_charset_conv_t *lcc)     if (!lcc)         return; -    iconv_close(lcc->check);     iconv_close(lcc->fallback);      for (i = 0; i < lcc->size; i++) {@@ -224,51 +214,58 @@ lms_charset_conv_del(lms_charset_conv_t *lcc, const char *charset) }  static int-_check(lms_charset_conv_t *lcc, const char *istr, unsigned int ilen, char *ostr, unsigned int olen)-{-    char *inbuf, *outbuf;-    size_t r, inlen, outlen;--    inbuf = (char *)istr;-    inlen = ilen;-    outbuf = ostr;-    outlen = olen;--    iconv(lcc->check, NULL, NULL, NULL, NULL);-    r = iconv(lcc->check, &inbuf, &inlen, &outbuf, &outlen);-    if (r == (size_t)-1)-        return -1;-    else-        return 0;-}--static int-_conv(iconv_t cd, char **p_str, unsigned int *p_len, char *ostr, unsigned int olen)+_conv(iconv_t cd, char **in, unsigned int *inlen, char **out, unsigned int *outlen) {-    char *inbuf, *outbuf;-    size_t r, inlen, outlen;--    inbuf = *p_str;-    inlen = *p_len;-    outbuf = ostr;-    outlen = olen;+    char *inp, *outp;+    size_t inremain, outremain, outsize, r, used;+    int done = 0, have_error = 0;++    inp = *in;+    inremain = *inlen;+    outp = *out;+    outremain = *outlen;+    outsize = *outlen;++    while (!done && !have_error) {+        r = iconv(cd, &inp, &inremain, &outp, &outremain);+        if (r == (size_t)-1) {+            switch (errno) {+            case EINVAL:+                done = 1;+                break;+            case E2BIG:+                used = outp - *out;+                outsize *= 2;+                out = realloc(*out, outsize);+                if (!out) {+                    perror("realloc");+                    return -1;+                }+                outp = *out + used;+                outremain = outsize - used - 1;+                break;+            case EILSEQ:+            default:+                have_error = 1;+                break;+            }+            return -1;+        }+        else {+            break;+        }+    } -    iconv(cd, NULL, NULL, NULL, NULL);-    r = iconv(cd, &inbuf, &inlen, &outbuf, &outlen);-    if (r == (size_t)-1)+    if (have_error)         return -1; -    *p_len = olen - outlen;-    free(*p_str);-    *p_str = ostr;+    *outp = '\0';+    *outlen = outp - *out; -    outbuf = realloc(*p_str, *p_len + 1);-    if (!outbuf)-        perror("realloc");-    else-        *p_str = outbuf;+    free(*in); -    (*p_str)[*p_len] = '\0';+    *inlen = inp - *in;+    *in = *out;      return 0; }@@ -277,81 +274,44 @@ _conv(iconv_t cd, char **p_str, unsigned int *p_len, char *ostr, unsigned int ol  * If required, do charset conversion to UTF-8.  *  * @param lcc existing Light Media Scanner charset conversion.- * @param p_str string to be converted.- * @param p_len string size.+ * @param in string to be converted.+ * @param inlen string size.  *  * @return On success 0 is returned.  */ int-lms_charset_conv(lms_charset_conv_t *lcc, char **p_str, unsigned int *p_len)+lms_charset_conv(lms_charset_conv_t *lcc, char **in, unsigned int *inlen) {-    char *outstr;+    char *out;     int i, outlen;      if (!lcc)         return -1;-    if (!p_str)+    if (!in)         return -2;-    if (!p_len)+    if (!inlen)         return -3;-    if (!*p_str || !*p_len)+    if (!*in || !*inlen)         return 0; -    outlen = 2 * *p_len;-    outstr = malloc(outlen + 1);-    if (!outstr) {+    outlen = 2 * *inlen;+    out = malloc(outlen + 1);+    if (!out) {         perror("malloc");         return -4;     } -    if (_check(lcc, *p_str, *p_len, outstr, outlen) == 0) {-        free(outstr);-        return 0;-    }-     for (i = 0; i < lcc->size; i++)-        if (_conv(lcc->convs[i], p_str, p_len, outstr, outlen) == 0)+        if (_conv(lcc->convs[i], in, inlen, &out, &outlen) == 0)             return 0;      fprintf(stderr,             "WARNING: could not convert '%*s' to any charset, use fallback\n",-            *p_len, *p_str);-    i = _conv(lcc->fallback, p_str, p_len, outstr, outlen);+            *inlen, *in);+    i = _conv(lcc->fallback, in, inlen, &out, &outlen);     if (i < 0) {-        memset(*p_str, '?', *p_len);-        free(outstr);+        memset(*in, '?', *inlen);+        free(out);     }     return i; }--/**- * Check if strings is not UTF-8 and conversion is required.- *- * @param lcc existing Light Media Scanner charset conversion.- * @param str string to be analysed.- * @param len string size.- *- * @return 0 if string is already UTF-8.- */-int-lms_charset_conv_check(lms_charset_conv_t *lcc, const char *str, unsigned int len)-{-    char *outstr;-    int r, outlen;--    if (!lcc)-        return -1;-    if (!str || !len)-        return 0;--    outlen = 2 * len;-    outstr = malloc(outlen);-    if (!outstr) {-        perror("malloc");-        return -2;-    }--    r = _check(lcc, str, len, outstr, outlen);-    free(outstr);-    return r;-}