bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: new module: iconvstring


From: Simon Josefsson
Subject: Re: new module: iconvstring
Date: Tue, 25 Apr 2006 11:14:56 +0200
User-agent: Gnus/5.110005 (No Gnus v0.5) Emacs/22.0.50 (gnu/linux)

Bruno Haible <address@hidden> writes:

> Hi,
>
> This module 'iconvstring' is in use in GNU gettext in 4 places. It is an
> easy-to-use iconv() wrapper, like the 'iconvme' module. The difference is
> that 'iconvstring' uses an iconv_t descriptor, rather than two encoding names,
> and is therefore suitable for converting a whole lot of strings, without 
> needing
> to re-open a conversion descriptor for each string.
>
> Nothing against Simon's 'iconvme' module - it is very nice. It is just that
> sometimes you need one, sometimes the other.

Did you see iconv_alloc in iconvme?  There is some overlap here.
Perhaps iconvme could simply be re-written to use iconvstring, to
avoid slightly duplicated code.  Your module seem more general, but I
still find the iconvme API easier to understand and use for
non-experts.

> Bruno
>
> ================================= modules/iconvstring 
> ===============================
> Description:
> Character set conversion of strings made easy and fast, uses iconv.
>
> Files:
> lib/iconvstring.h
> lib/iconvstring.c
> m4/iconvstring.m4
>
> Depends-on:
> iconv
> xalloc
>
> configure.ac:
> gl_ICONVSTRING
>
> Makefile.am:
> lib_SOURCES += iconvstring.h iconvstring.c
> lib_LIBADD += $(LTLIBICONV)
>
> Include:
> "iconvstring.h"
>
> License:
> GPL
>
> Maintainer:
> Bruno Haible
>
> ================================= lib/iconvstring.h 
> ===============================
> /* Charset conversion.
>    Copyright (C) 2001-2003, 2006 Free Software Foundation, Inc.
>    Written by Bruno Haible <address@hidden>, 2001.
>
>    This program is free software; you can redistribute it and/or modify
>    it under the terms of the GNU General Public License as published by
>    the Free Software Foundation; either version 2, or (at your option)
>    any later version.
>
>    This program is distributed in the hope that it will be useful,
>    but WITHOUT ANY WARRANTY; without even the implied warranty of
>    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>    GNU General Public License for more details.
>
>    You should have received a copy of the GNU General Public License
>    along with this program; if not, write to the Free Software Foundation,
>    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
>
> #ifndef _ICONVSTRING_H
> #define _ICONVSTRING_H
>
> #include <stddef.h>
> #if HAVE_ICONV
> #include <iconv.h>
> #endif
>
>
> #ifdef __cplusplus
> extern "C" {
> #endif
>
>
> #if HAVE_ICONV
>
> /* Convert an entire string from one encoding to another, using iconv.
>    *RESULTP should initially contain NULL or malloced memory block.
>    Return value: 0 if successful, otherwise -1 and errno set.
>    If successful, the resulting string is stored in *RESULTP and its length
>    in *LENGTHP.  */
> extern int iconv_string (iconv_t cd, const char *start, const char *end,
>                        char **resultp, size_t *lengthp);
>
> #endif
>
>
> #ifdef __cplusplus
> }
> #endif
>
>
> #endif /* _ICONVSTRING_H */
> ================================= lib/iconvstring.c 
> ===============================
> /* Charset conversion.
>    Copyright (C) 2001-2003, 2006 Free Software Foundation, Inc.
>    Written by Bruno Haible <address@hidden>, 2001.
>
>    This program is free software; you can redistribute it and/or modify
>    it under the terms of the GNU General Public License as published by
>    the Free Software Foundation; either version 2, or (at your option)
>    any later version.
>
>    This program is distributed in the hope that it will be useful,
>    but WITHOUT ANY WARRANTY; without even the implied warranty of
>    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>    GNU General Public License for more details.
>
>    You should have received a copy of the GNU General Public License
>    along with this program; if not, write to the Free Software Foundation,
>    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
>
> #ifdef HAVE_CONFIG_H
> # include "config.h"
> #endif
>
> /* Specification.  */
> #include "iconvstring.h"
>
> #include <errno.h>
> #include <stdlib.h>
>
> #if HAVE_ICONV
> # include <iconv.h>
> #endif
>
> #include "xalloc.h"
>
>
> #if HAVE_ICONV
>
> /* Converts an entire string from one encoding to another, using iconv.
>    Return value: 0 if successful, otherwise -1 and errno set.  */
> int
> iconv_string (iconv_t cd, const char *start, const char *end,
>             char **resultp, size_t *lengthp)
> {
> #define tmpbufsize 4096
>   size_t length;
>   char *result;
>
>   /* Avoid glibc-2.1 bug and Solaris 2.7-2.9 bug.  */
> # if defined _LIBICONV_VERSION \
>     || !((__GLIBC__ - 0 == 2 && __GLIBC_MINOR__ - 0 <= 1) || defined __sun)
>   /* Set to the initial state.  */
>   iconv (cd, NULL, NULL, NULL, NULL);
> # endif
>
>   /* Determine the length we need.  */
>   {
>     size_t count = 0;
>     char tmpbuf[tmpbufsize];
>     const char *inptr = start;
>     size_t insize = end - start;
>
>     while (insize > 0)
>       {
>       char *outptr = tmpbuf;
>       size_t outsize = tmpbufsize;
>       size_t res = iconv (cd,
>                           (ICONV_CONST char **) &inptr, &insize,
>                           &outptr, &outsize);
>
>       if (res == (size_t)(-1))
>         {
>           if (errno == E2BIG)
>             ;
>           else if (errno == EINVAL)
>             break;
>           else
>             return -1;
>         }
> # if !defined _LIBICONV_VERSION && (defined sgi || defined __sgi)
>       /* Irix iconv() inserts a NUL byte if it cannot convert.  */
>       else if (res > 0)
>         return -1;
> # endif
>       count += outptr - tmpbuf;
>       }
>     /* Avoid glibc-2.1 bug and Solaris 2.7 bug.  */
> # if defined _LIBICONV_VERSION \
>     || !((__GLIBC__ - 0 == 2 && __GLIBC_MINOR__ - 0 <= 1) || defined __sun)
>     {
>       char *outptr = tmpbuf;
>       size_t outsize = tmpbufsize;
>       size_t res = iconv (cd, NULL, NULL, &outptr, &outsize);
>
>       if (res == (size_t)(-1))
>       return -1;
>       count += outptr - tmpbuf;
>     }
> # endif
>     length = count;
>   }
>
>   *lengthp = length;
>   *resultp = result = xrealloc (*resultp, length);
>   if (length == 0)
>     return 0;
>
>   /* Avoid glibc-2.1 bug and Solaris 2.7-2.9 bug.  */
> # if defined _LIBICONV_VERSION \
>     || !((__GLIBC__ - 0 == 2 && __GLIBC_MINOR__ - 0 <= 1) || defined __sun)
>   /* Return to the initial state.  */
>   iconv (cd, NULL, NULL, NULL, NULL);
> # endif
>
>   /* Do the conversion for real.  */
>   {
>     const char *inptr = start;
>     size_t insize = end - start;
>     char *outptr = result;
>     size_t outsize = length;
>
>     while (insize > 0)
>       {
>       size_t res = iconv (cd,
>                           (ICONV_CONST char **) &inptr, &insize,
>                           &outptr, &outsize);
>
>       if (res == (size_t)(-1))
>         {
>           if (errno == EINVAL)
>             break;
>           else
>             return -1;
>         }
> # if !defined _LIBICONV_VERSION && (defined sgi || defined __sgi)
>       /* Irix iconv() inserts a NUL byte if it cannot convert.  */
>       else if (res > 0)
>         return -1;
> # endif
>       }
>     /* Avoid glibc-2.1 bug and Solaris 2.7 bug.  */
> # if defined _LIBICONV_VERSION \
>     || !((__GLIBC__ - 0 == 2 && __GLIBC_MINOR__ - 0 <= 1) || defined __sun)
>     {
>       size_t res = iconv (cd, NULL, NULL, &outptr, &outsize);
>
>       if (res == (size_t)(-1))
>       return -1;
>     }
> # endif
>     if (outsize != 0)
>       abort ();
>   }
>
>   return 0;
> #undef tmpbufsize
> }
>
> #endif
> ================================= m4/iconvstring.m4 
> ===============================
> # iconvstring.m4 serial 1
> dnl Copyright (C) 2006 Free Software Foundation, Inc.
> dnl This file is free software; the Free Software Foundation
> dnl gives unlimited permission to copy and/or distribute it,
> dnl with or without modifications, as long as this notice is preserved.
>
> AC_DEFUN([gl_ICONVSTRING],
> [
>   gl_PREREQ_ICONVSTRING
> ])
>
> # Prerequisites of lib/iconvstring.h and lib/iconvstring.c.
> AC_DEFUN([gl_PREREQ_ICONVSTRING],
> [
>   AC_REQUIRE([AM_ICONV])
> ])




reply via email to

[Prev in Thread] Current Thread [Next in Thread]