[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
new module: iconvstring
From: |
Bruno Haible |
Subject: |
new module: iconvstring |
Date: |
Mon, 24 Apr 2006 22:41:32 +0200 |
User-agent: |
KMail/1.5 |
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.
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])
])
- new module: iconvstring,
Bruno Haible <=