summaryrefslogtreecommitdiff
path: root/iconv
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1998-04-04 07:25:25 +0000
committerUlrich Drepper <drepper@redhat.com>1998-04-04 07:25:25 +0000
commit0d9f67937f0c9329c35c2c0d15848ab8316dc520 (patch)
treeee2b01470306f95f731e268aab1c0712f9e9d50c /iconv
parente62c19f12cfc377ac9ce7c037713ead5dc6b57d9 (diff)
Update.
1998-04-03 23:17 Ulrich Drepper <drepper@cygnus.com> * iconv/gconv.c: Rewrite of the low-level of gconv. * iconv/gconv.h: Likewise. * iconv/gconv_builtin.h: Likewise. * iconv/gconv_close.c: Likewise. * iconv/gconv_db.: Likewise. * iconv/gconv_dl.c: Likewise. * iconv/gconv_int.h: Likewise. * iconv/gconv_open.c: Likewise. * iconv/gconv_simple.c: Likewise. * iconvdata/8bit-gap.c: Adapt for rewrite. * iconvdata/8bit-generic.c: Likewise. * iconvdata/euckr.c: Likewise. * iconvdata/iso646.c: Likewise. * iconvdata/iso6937.c: Likewise. * iconvdata/iso8859-1.c: Likewise. * iconvdata/johab.c: Likewise. * iconvdata/sjis.c: Likewise. * iconvdata/t61.c: Likewise. * iconvdata/uhc.c: Likewise.
Diffstat (limited to 'iconv')
-rw-r--r--iconv/gconv.c1
-rw-r--r--iconv/gconv.h18
-rw-r--r--iconv/gconv_builtin.h16
-rw-r--r--iconv/gconv_close.c13
-rw-r--r--iconv/gconv_db.c87
-rw-r--r--iconv/gconv_dl.c85
-rw-r--r--iconv/gconv_int.h89
-rw-r--r--iconv/gconv_open.c34
-rw-r--r--iconv/gconv_simple.c42
9 files changed, 190 insertions, 195 deletions
diff --git a/iconv/gconv.c b/iconv/gconv.c
index 5df16354b6..71d87ae1f6 100644
--- a/iconv/gconv.c
+++ b/iconv/gconv.c
@@ -23,6 +23,7 @@
int
+internal_function
__gconv (gconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf,
size_t *outbytesleft, size_t *converted)
{
diff --git a/iconv/gconv.h b/iconv/gconv.h
index 76a719785e..f3f80f4c14 100644
--- a/iconv/gconv.h
+++ b/iconv/gconv.h
@@ -24,6 +24,7 @@
#define _GCONV_H 1
#include <features.h>
+#include <wchar.h>
#define __need_size_t
#include <stddef.h>
@@ -51,6 +52,7 @@ enum
/* Forward declarations. */
struct gconv_step;
struct gconv_step_data;
+struct gconv_loaded_object;
/* Type of a conversion function. */
@@ -59,15 +61,17 @@ typedef int (*gconv_fct) __P ((struct gconv_step *,
__const char *, size_t *, size_t *, int));
/* Constructor and destructor for local data for conversion step. */
-typedef int (*gconv_init_fct) __P ((struct gconv_step *,
- struct gconv_step_data *));
-typedef void (*gconv_end_fct) __P ((struct gconv_step_data *));
+typedef int (*gconv_init_fct) __P ((struct gconv_step *));
+typedef void (*gconv_end_fct) __P ((struct gconv_step *));
/* Description of a conversion step. */
struct gconv_step
{
- void *shlib_handle;
+ struct gconv_loaded_object *shlib_handle;
+ const char *modname;
+
+ int counter;
__const char *from_name;
__const char *to_name;
@@ -75,6 +79,8 @@ struct gconv_step
gconv_fct fct;
gconv_init_fct init_fct;
gconv_end_fct end_fct;
+
+ void *data; /* Pointer to step-local data. */
};
/* Additional data for steps in use of conversion descriptor. This is
@@ -87,7 +93,9 @@ struct gconv_step_data
int is_last;
- void *data; /* Pointer to step-local data. */
+ mbstate_t *statep;
+ mbstate_t __state; /* This element should not be used directly by
+ any module; always use STATEP! */
};
diff --git a/iconv/gconv_builtin.h b/iconv/gconv_builtin.h
index 8e5d692946..9c98c3513d 100644
--- a/iconv/gconv_builtin.h
+++ b/iconv/gconv_builtin.h
@@ -23,30 +23,22 @@ BUILTIN_ALIAS ("UTF-8//", "ISO-10646/UTF8/")
BUILTIN_TRANSFORMATION (NULL, "ISO-10646/UCS4/", 15,
"ISO-10646/UTF8/", 1, "=ucs4->utf8",
- __gconv_transform_ucs4_utf8,
- __gconv_transform_init_rstate,
- __gconv_transform_end_rstate)
+ __gconv_transform_ucs4_utf8, NULL, NULL)
BUILTIN_TRANSFORMATION ("ISO-10646/UTF-?8/", "ISO-10646/UTF", 13,
"ISO-10646/UCS4/", 1, "=utf8->ucs4",
- __gconv_transform_utf8_ucs4,
- __gconv_transform_init_rstate,
- __gconv_transform_end_rstate)
+ __gconv_transform_utf8_ucs4, NULL, NULL)
BUILTIN_ALIAS ("UCS2//", "ISO-10646/UCS2/")
BUILTIN_ALIAS ("UCS-2//", "ISO-10646/UCS2/")
BUILTIN_TRANSFORMATION (NULL, "ISO-10646/UCS2/", 15, "ISO-10646/UCS4/",
1, "=ucs2->ucs4",
- __gconv_transform_ucs2_ucs4,
- __gconv_transform_init_rstate,
- __gconv_transform_end_rstate)
+ __gconv_transform_ucs2_ucs4, NULL, NULL)
BUILTIN_TRANSFORMATION (NULL, "ISO-10646/UCS4/", 15, "ISO-10646/UCS2/",
1, "=ucs4->ucs2",
- __gconv_transform_ucs4_ucs2,
- __gconv_transform_init_rstate,
- __gconv_transform_end_rstate)
+ __gconv_transform_ucs4_ucs2, NULL, NULL)
BUILTIN_TRANSFORMATION ("(.*)", NULL, 0, "\\1", 1, "=dummy",
__gconv_transform_dummy, NULL, NULL)
diff --git a/iconv/gconv_close.c b/iconv/gconv_close.c
index b6d5fbcd9d..de0937d610 100644
--- a/iconv/gconv_close.c
+++ b/iconv/gconv_close.c
@@ -38,24 +38,11 @@ __gconv_close (gconv_t cd)
drunp = cd->data;
do
{
- /* Call destructor. */
- if (srunp->end_fct != NULL)
- (*srunp->end_fct) (drunp);
- else
- if (drunp->data != NULL)
- free (drunp->data);
-
if (!drunp->is_last && drunp->outbuf != NULL)
free (drunp->outbuf);
-
- /* Next step. */
- ++srunp;
}
while (!(drunp++)->is_last);
- /* Save the pointer, we need it below. */
- srunp = cd->steps;
-
/* Free the data allocated for the descriptor. */
free (cd->data);
free (cd);
diff --git a/iconv/gconv_db.c b/iconv/gconv_db.c
index 5a3932c601..e0a94e41c3 100644
--- a/iconv/gconv_db.c
+++ b/iconv/gconv_db.c
@@ -34,6 +34,9 @@ void *__gconv_alias_db;
size_t __gconv_nmodules;
struct gconv_module **__gconv_modules_db;
+/* We modify global data. */
+__libc_lock_define_initialized (static, lock)
+
/* Function for searching alias. */
int
@@ -128,9 +131,7 @@ add_derivation (const char *fromset, const char *toset,
malloc (sizeof (struct known_derivation) + fromset_len + toset_len);
if (new_deriv != NULL)
{
- new_deriv->from = memcpy ((char *) new_deriv
- + sizeof (struct known_derivation),
- fromset, fromset_len);
+ new_deriv->from = memcpy (new_deriv + 1, fromset, fromset_len);
new_deriv->to = memcpy ((char *) new_deriv->from + fromset_len,
toset, toset_len);
@@ -149,6 +150,11 @@ internal_function
free_derivation (void *p)
{
struct known_derivation *deriv = (struct known_derivation *) p;
+ size_t cnt;
+
+ for (cnt = 0; cnt < deriv->nsteps; ++cnt)
+ if (deriv->steps[cnt].end_fct)
+ (*deriv->steps[cnt].end_fct) (&deriv->steps[cnt]);
free ((struct gconv_step *) deriv->steps);
free (deriv);
@@ -189,7 +195,7 @@ gen_steps (struct derivation_step *best, const char *toset,
if (current->code->module_name[0] == '/')
{
/* Load the module, return handle for it. */
- void *shlib_handle =
+ struct gconv_loaded_object *shlib_handle =
__gconv_find_shlib (current->code->module_name);
if (shlib_handle == NULL)
@@ -199,27 +205,21 @@ gen_steps (struct derivation_step *best, const char *toset,
}
result[step_cnt].shlib_handle = shlib_handle;
-
- result[step_cnt].fct = __gconv_find_func (shlib_handle, "gconv");
- if (result[step_cnt].fct == NULL)
- {
- /* Argh, no conversion function. There is something
- wrong here. */
- __gconv_release_shlib (result[step_cnt].shlib_handle);
- failed = 1;
- break;
- }
-
- result[step_cnt].init_fct = __gconv_find_func (shlib_handle,
- "gconv_init");
- result[step_cnt].end_fct = __gconv_find_func (shlib_handle,
- "gconv_end");
+ result[step_cnt].modname = shlib_handle->name;
+ result[step_cnt].counter = 0;
+ result[step_cnt].fct = shlib_handle->fct;
+ result[step_cnt].init_fct = shlib_handle->init_fct;
+ result[step_cnt].end_fct = shlib_handle->end_fct;
}
else
/* It's a builtin transformation. */
__gconv_get_builtin_trans (current->code->module_name,
&result[step_cnt]);
+ /* Call the init function. */
+ if (result[step_cnt].init_fct != NULL)
+ (*result[step_cnt].init_fct) (&result[step_cnt]);
+
current = current->last;
}
@@ -227,7 +227,11 @@ gen_steps (struct derivation_step *best, const char *toset,
{
/* Something went wrong while initializing the modules. */
while (++step_cnt < *nsteps)
- __gconv_release_shlib (result[step_cnt].shlib_handle);
+ {
+ if (result[step_cnt].end_fct != NULL)
+ (*result[step_cnt].end_fct) (&result[step_cnt]);
+ __gconv_release_shlib (result[step_cnt].shlib_handle);
+ }
free (result);
*nsteps = 0;
status = GCONV_NOCONV;
@@ -273,7 +277,8 @@ find_derivation (const char *toset, const char *toset_expand,
/* ### TODO
For now we use a simple algorithm with quadratic runtime behaviour.
- The task is to match the `toset' with any of the available. */
+ The task is to match the `toset' with any of the available rules,
+ starting from FROMSET. */
if (fromset_expand != NULL)
{
first = NEW_STEP (fromset_expand, NULL, NULL);
@@ -495,6 +500,9 @@ __gconv_find_transform (const char *toset, const char *fromset,
/* Ensure that the configuration data is read. */
__libc_once (once, __gconv_read_conf);
+ /* Acquire the lock. */
+ __libc_lock_lock (lock);
+
/* If we don't have a module database return with an error. */
if (__gconv_modules_db == NULL)
return GCONV_NOCONV;
@@ -517,6 +525,33 @@ __gconv_find_transform (const char *toset, const char *fromset,
result = find_derivation (toset, toset_expand, fromset, fromset_expand,
handle, nsteps);
+ /* Increment the user counter. */
+ if (result == GCONV_OK)
+ {
+ size_t cnt = *nsteps;
+ struct gconv_step *steps = *handle;
+
+ do
+ if (steps[--cnt].counter++ == 0)
+ {
+ steps[--cnt].shlib_handle =
+ __gconv_find_shlib (steps[--cnt].modname);
+ if (steps[--cnt].shlib_handle == NULL)
+ {
+ /* Oops, this is the second time we use this module (after
+ unloading) and this time loading failed!? */
+ while (++cnt < *nsteps)
+ __gconv_release_shlib (steps[cnt].shlib_handle);
+ result = GCONV_NOCONV;
+ break;
+ }
+ }
+ while (cnt > 0);
+ }
+
+ /* Release the lock. */
+ __libc_lock_unlock (lock);
+
/* The following code is necessary since `find_derivation' will return
GCONV_OK even when no derivation was found but the same request
was processed before. I.e., negative results will also be cached. */
@@ -533,14 +568,22 @@ __gconv_close_transform (struct gconv_step *steps, size_t nsteps)
{
int result = GCONV_OK;
+ /* Acquire the lock. */
+ __libc_lock_lock (lock);
+
while (nsteps-- > 0)
- if (steps[nsteps].shlib_handle != NULL)
+ if (steps[nsteps].shlib_handle != NULL
+ && --steps[nsteps].counter == 0)
{
result = __gconv_release_shlib (steps[nsteps].shlib_handle);
if (result != GCONV_OK)
break;
+ steps[nsteps].shlib_handle = NULL;
}
+ /* Release the lock. */
+ __libc_lock_unlock (lock);
+
return result;
}
diff --git a/iconv/gconv_dl.c b/iconv/gconv_dl.c
index 2a7cc92a3d..b11e156a03 100644
--- a/iconv/gconv_dl.c
+++ b/iconv/gconv_dl.c
@@ -40,27 +40,9 @@
#define TRIES_BEFORE_UNLOAD 2
-/* Structure describing one loaded shared object. This normally are
- objects to perform conversation but as a special case the db shared
- object is also handled. */
-struct loaded_object
-{
- /* Name of the object. */
- const char *name;
-
- /* Reference counter for the db functionality. If no conversion is
- needed we unload the db library. */
- int counter;
-
- /* The handle for the shared object. */
- void *handle;
-};
-
-
/* Array of loaded objects. This is shared by all threads so we have
to use semaphores to access it. */
static void *loaded;
-__libc_lock_define_initialized (static, lock)
@@ -68,8 +50,10 @@ __libc_lock_define_initialized (static, lock)
static int
known_compare (const void *p1, const void *p2)
{
- const struct loaded_object *s1 = (const struct loaded_object *) p1;
- const struct loaded_object *s2 = (const struct loaded_object *) p2;
+ const struct gconv_loaded_object *s1 =
+ (const struct gconv_loaded_object *) p1;
+ const struct gconv_loaded_object *s2 =
+ (const struct gconv_loaded_object *) p2;
return (intptr_t) s1->handle - (intptr_t) s2->handle;
}
@@ -78,7 +62,7 @@ known_compare (const void *p1, const void *p2)
static void
do_open (void *a)
{
- struct loaded_object *args = (struct loaded_object *) a;
+ struct gconv_loaded_object *args = (struct gconv_loaded_object *) a;
/* Open and relocate the shared object. */
args->handle = _dl_open (args->name, RTLD_LAZY);
}
@@ -124,9 +108,9 @@ get_sym (void *a)
}
-void *
+static void *
internal_function
-__gconv_find_func (void *handle, const char *name)
+find_func (void *handle, const char *name)
{
struct get_sym_args args;
@@ -141,15 +125,11 @@ __gconv_find_func (void *handle, const char *name)
/* Open the gconv database if necessary. A non-negative return value
means success. */
-void *
+struct gconv_loaded_object *
internal_function
__gconv_find_shlib (const char *name)
{
- void *result = NULL;
- struct loaded_object *found;
-
- /* Acquire the lock. */
- __libc_lock_lock (lock);
+ struct gconv_loaded_object *found;
/* Search the tree of shared objects previously requested. Data in
the tree are `loaded_object' structures, whose first member is a
@@ -164,7 +144,7 @@ __gconv_find_shlib (const char *name)
if (found == NULL)
{
/* This name was not known before. */
- found = malloc (sizeof (struct loaded_object));
+ found = malloc (sizeof (struct gconv_loaded_object));
if (found != NULL)
{
/* Point the tree node at this new structure. */
@@ -189,35 +169,50 @@ __gconv_find_shlib (const char *name)
if (found->counter < -TRIES_BEFORE_UNLOAD)
{
if (dlerror_run (do_open, found) == 0)
- found->counter = 1;
+ {
+ found->fct = find_func (found->handle, "gconv");
+ if (found->fct == NULL)
+ {
+ /* Argh, no conversion function. There is something
+ wrong here. */
+ __gconv_release_shlib (found);
+ found = NULL;
+ }
+ else
+ {
+ found->init_fct = find_func (found->handle, "gconv_init");
+ found->end_fct = find_func (found->handle, "gconv_end");
+
+ /* We have succeeded in loading the shared object. */
+ found->counter = 1;
+ }
+ }
+ else
+ /* Error while loading the shared object. */
+ found = NULL;
}
else if (found->handle != NULL)
found->counter = MAX (found->counter + 1, 1);
-
- result = found->handle;
}
- /* Release the lock. */
- __libc_lock_unlock (lock);
-
- return result;
+ return found;
}
/* This is very ugly but the tsearch functions provide no way to pass
information to the walker function. So we use a global variable.
It is MT safe since we use a lock. */
-static void *release_handle;
+static struct gconv_loaded_object *release_handle;
static void
do_release_shlib (const void *nodep, VISIT value, int level)
{
- struct loaded_object *obj = *(struct loaded_object **) nodep;
+ struct gconv_loaded_object *obj = *(struct gconv_loaded_object **) nodep;
if (value != preorder && value != leaf)
return;
- if (obj->handle == release_handle)
+ if (obj == release_handle)
/* This is the object we want to unload. Now set the release
counter to zero. */
obj->counter = 0;
@@ -228,7 +223,7 @@ do_release_shlib (const void *nodep, VISIT value, int level)
/* Unload the shared object. We don't use the trick to
catch errors since in the case an error is signalled
something is really wrong. */
- _dl_close ((struct link_map *) obj->handle);
+ _dl_close (obj->handle);
obj->handle = NULL;
}
@@ -239,11 +234,8 @@ do_release_shlib (const void *nodep, VISIT value, int level)
/* Notify system that a shared object is not longer needed. */
int
internal_function
-__gconv_release_shlib (void *handle)
+__gconv_release_shlib (struct gconv_loaded_object *handle)
{
- /* Acquire the lock. */
- __libc_lock_lock (lock);
-
/* Urgh, this is ugly but we have no other possibility. */
release_handle = handle;
@@ -252,8 +244,5 @@ __gconv_release_shlib (void *handle)
if necessary. */
__twalk (loaded, do_release_shlib);
- /* Release the lock. */
- __libc_lock_unlock (lock);
-
return GCONV_OK;
}
diff --git a/iconv/gconv_int.h b/iconv/gconv_int.h
index 5261284d7f..5e0723ed34 100644
--- a/iconv/gconv_int.h
+++ b/iconv/gconv_int.h
@@ -29,8 +29,8 @@ __BEGIN_DECLS
/* Structure for alias definition. Simply to strings. */
struct gconv_alias
{
- __const char *fromname;
- __const char *toname;
+ const char *fromname;
+ const char *toname;
};
@@ -38,19 +38,41 @@ struct gconv_alias
#define GCONV_DEFAULT_BUFSIZE 8160
+/* Structure describing one loaded shared object. This normally are
+ objects to perform conversation but as a special case the db shared
+ object is also handled. */
+struct gconv_loaded_object
+{
+ /* Name of the object. */
+ const char *name;
+
+ /* Reference counter for the db functionality. If no conversion is
+ needed we unload the db library. */
+ int counter;
+
+ /* The handle for the shared object. */
+ struct link_map *handle;
+
+ /* Pointer to the functions the module defines. */
+ gconv_fct fct;
+ gconv_init_fct init_fct;
+ gconv_end_fct end_fct;
+};
+
+
/* Description for an available conversion module. */
struct gconv_module
{
- __const char *from_pattern;
- __const char *from_constpfx;
+ const char *from_pattern;
+ const char *from_constpfx;
size_t from_constpfx_len;
- __const regex_t *from_regex;
+ const regex_t *from_regex;
- __const char *to_string;
+ const char *to_string;
int cost;
- __const char *module_name;
+ const char *module_name;
};
@@ -65,65 +87,56 @@ extern struct gconv_module **__gconv_modules_db;
/* Return in *HANDLE decriptor for transformation from FROMSET to TOSET. */
-extern int __gconv_open __P ((__const char *__toset, __const char *__fromset,
- gconv_t *__handle))
+extern int __gconv_open (const char *__toset, const char *__fromset,
+ gconv_t *__handle)
internal_function;
/* Free resources associated with transformation descriptor CD. */
-extern int __gconv_close __P ((gconv_t cd))
+extern int __gconv_close (gconv_t cd)
internal_function;
/* Transform at most *INBYTESLEFT bytes from buffer starting at *INBUF
according to rules described by CD and place up to *OUTBYTESLEFT
bytes in buffer starting at *OUTBUF. Return number of written
characters in *CONVERTED if this pointer is not null. */
-extern int __gconv __P ((gconv_t __cd,
- __const char **__inbuf, size_t *__inbytesleft,
- char **__outbuf, size_t *__outbytesleft,
- size_t *__converted))
+extern int __gconv (gconv_t __cd, const char **__inbuf, size_t *__inbytesleft,
+ char **__outbuf, size_t *__outbytesleft,
+ size_t *__converted)
internal_function;
/* Return in *HANDLE a pointer to an array with *NSTEPS elements describing
the single steps necessary for transformation from FROMSET to TOSET. */
-extern int __gconv_find_transform __P ((__const char *__toset,
- __const char *__fromset,
- struct gconv_step **__handle,
- size_t *__nsteps))
+extern int __gconv_find_transform (const char *__toset, const char *__fromset,
+ struct gconv_step **__handle,
+ size_t *__nsteps)
internal_function;
/* Read all the configuration data and cache it. */
-extern void __gconv_read_conf __P ((void))
+extern void __gconv_read_conf (void)
internal_function;
/* Comparison function to search alias. */
-extern int __gconv_alias_compare __P ((__const void *__p1,
- __const void *__p2));
+extern int __gconv_alias_compare (const void *__p1, const void *__p2);
/* Clear reference to transformation step implementations which might
cause the code to be unloaded. */
-extern int __gconv_close_transform __P ((struct gconv_step *__steps,
- size_t __nsteps))
- internal_function;
-
-
-/* Find in the shared object associated with HANDLE for a function with
- name NAME. Return function pointer or NULL. */
-extern void *__gconv_find_func __P ((void *__handle, __const char *__name))
+extern int __gconv_close_transform (struct gconv_step *__steps,
+ size_t __nsteps)
internal_function;
/* Load shared object named by NAME. If already loaded increment reference
count. */
-extern void *__gconv_find_shlib __P ((__const char *__name))
+extern struct gconv_loaded_object *__gconv_find_shlib (const char *__name)
internal_function;
/* Release shared object. If no further reference is available unload
the object. */
-extern int __gconv_release_shlib __P ((void *__handle))
+extern int __gconv_release_shlib (struct gconv_loaded_object *__handle)
internal_function;
/* Fill STEP with information about builtin module with NAME. */
-extern void __gconv_get_builtin_trans __P ((__const char *__name,
- struct gconv_step *__step))
+extern void __gconv_get_builtin_trans (const char *__name,
+ struct gconv_step *__step)
internal_function;
@@ -131,9 +144,9 @@ extern void __gconv_get_builtin_trans __P ((__const char *__name,
/* Builtin transformations. */
#ifdef _LIBC
# define __BUILTIN_TRANS(Name) \
- extern int Name __P ((struct gconv_step *__step, \
- struct gconv_step_data *__data, __const char *__inbuf,\
- size_t *__inlen, size_t *__written, int __do_flush))
+ extern int Name (struct gconv_step *__step, struct gconv_step_data *__data, \
+ const char *__inbuf, size_t *__inlen, size_t *__written, \
+ int __do_flush)
__BUILTIN_TRANS (__gconv_transform_dummy);
__BUILTIN_TRANS (__gconv_transform_ucs4_utf8);
@@ -142,10 +155,6 @@ __BUILTIN_TRANS (__gconv_transform_ucs2_ucs4);
__BUILTIN_TRANS (__gconv_transform_ucs4_ucs2);
# undef __BUITLIN_TRANS
-extern int __gconv_transform_init_rstate __P ((struct gconv_step *__step,
- struct gconv_step_data *__data));
-extern void __gconv_transform_end_rstate __P ((struct gconv_step_data *__data));
-
#endif
__END_DECLS
diff --git a/iconv/gconv_open.c b/iconv/gconv_open.c
index ea7b3653af..d82dcfee48 100644
--- a/iconv/gconv_open.c
+++ b/iconv/gconv_open.c
@@ -65,25 +65,18 @@ __gconv_open (const char *toset, const char *fromset, gconv_t *handle)
buffer. Signal this to the initializer. */
data[cnt].is_last = cnt == nsteps - 1;
- if (steps[cnt].init_fct != NULL)
- {
- res = (steps[cnt].init_fct) (&steps[cnt], &data[cnt]);
- if (res != GCONV_OK)
- break;
- }
+ /* We use the `mbstate_t' member in DATA. */
+ data[cnt].statep = &data[cnt].__state;
- if (!data[cnt].is_last && data[cnt].outbuf == NULL)
+ /* Allocate the buffer. */
+ data[cnt].outbufsize = GCONV_DEFAULT_BUFSIZE;
+ data[cnt].outbuf = (char *) malloc (data[cnt].outbufsize);
+ if (data[cnt].outbuf == NULL)
{
- data[cnt].outbufsize = GCONV_DEFAULT_BUFSIZE;
- data[cnt].outbuf =
- (char *) malloc (data[cnt].outbufsize);
- if (data[cnt].outbuf == NULL)
- {
- res = GCONV_NOMEM;
- break;
- }
- data[cnt].outbufavail = 0;
+ res = GCONV_NOMEM;
+ break;
}
+ data[cnt].outbufavail = 0;
}
}
}
@@ -99,14 +92,7 @@ __gconv_open (const char *toset, const char *fromset, gconv_t *handle)
if (result->data != NULL)
{
while (cnt-- > 0)
- if (steps[cnt].end_fct != NULL)
- (*steps[cnt].end_fct) (&result->data[cnt]);
- else
- {
- free (result->data[cnt].outbuf);
- if (result->data[cnt].data != NULL)
- free (result->data[cnt].data);
- }
+ free (result->data[cnt].outbuf);
free (result->data);
}
diff --git a/iconv/gconv_simple.c b/iconv/gconv_simple.c
index 280ecf57b5..7fbdfbacf3 100644
--- a/iconv/gconv_simple.c
+++ b/iconv/gconv_simple.c
@@ -59,26 +59,6 @@ __gconv_transform_dummy (struct gconv_step *step, struct gconv_step_data *data,
int
-__gconv_transform_init_rstate (struct gconv_step *step,
- struct gconv_step_data *data)
-{
- /* We have to provide the transformation function an correctly initialized
- object of type `mbstate_t'. This must be dynamically allocated. */
- data->data = calloc (1, sizeof (mbstate_t));
-
- return data->data == NULL ? GCONV_NOMEM : GCONV_OK;
-}
-
-
-void
-__gconv_transform_end_rstate (struct gconv_step_data *data)
-{
- if (data->data != NULL)
- free (data->data);
-}
-
-
-int
__gconv_transform_ucs4_utf8 (struct gconv_step *step,
struct gconv_step_data *data, const char *inbuf,
size_t *inlen, size_t *written, int do_flush)
@@ -95,7 +75,7 @@ __gconv_transform_ucs4_utf8 (struct gconv_step *step,
if (do_flush)
{
/* Clear the state. */
- memset (data->data, '\0', sizeof (mbstate_t));
+ memset (data->statep, '\0', sizeof (mbstate_t));
do_write = 0;
/* Call the steps down the chain if there are any. */
@@ -127,7 +107,7 @@ __gconv_transform_ucs4_utf8 (struct gconv_step *step,
(const wchar_t **) &newinbuf,
*inlen / sizeof (wchar_t),
data->outbufsize - data->outbufavail,
- (mbstate_t *) data->data);
+ data->statep);
/* Remember how much we converted. */
do_write += newinbuf - inbuf;
@@ -200,7 +180,7 @@ __gconv_transform_utf8_ucs4 (struct gconv_step *step,
if (do_flush)
{
/* Clear the state. */
- memset (data->data, '\0', sizeof (mbstate_t));
+ memset (data->statep, '\0', sizeof (mbstate_t));
do_write = 0;
/* Call the steps down the chain if there are any. */
@@ -229,7 +209,7 @@ __gconv_transform_utf8_ucs4 (struct gconv_step *step,
&newinbuf, *inlen,
((data->outbufsize
- data->outbufavail) / sizeof (wchar_t)),
- (mbstate_t *) data->data);
+ data->statep);
/* Remember how much we converted. */
do_write += actually;
@@ -244,7 +224,7 @@ __gconv_transform_utf8_ucs4 (struct gconv_step *step,
break;
}
- if (*inlen == 0 && !mbsinit ((mbstate_t *) data->data))
+ if (*inlen == 0 && !mbsinit (data->statep))
{
/* We have an incomplete character at the end. */
result = GCONV_INCOMPLETE_INPUT;
@@ -309,7 +289,7 @@ __gconv_transform_ucs2_ucs4 (struct gconv_step *step,
if (do_flush)
{
/* Clear the state. */
- memset (data->data, '\0', sizeof (mbstate_t));
+ memset (data->statep, '\0', sizeof (mbstate_t));
do_write = 0;
/* Call the steps down the chain if there are any. */
@@ -347,7 +327,7 @@ __gconv_transform_ucs2_ucs4 (struct gconv_step *step,
if (*inlen != 1)
{
/* We have an incomplete input character. */
- mbstate_t *state = (mbstate_t *) data->data;
+ mbstate_t *state = data->statep;
state->count = 1;
state->value = *(uint8_t *) newinbuf;
--*inlen;
@@ -363,7 +343,7 @@ __gconv_transform_ucs2_ucs4 (struct gconv_step *step,
break;
}
- if (*inlen == 0 && !mbsinit ((mbstate_t *) data->data))
+ if (*inlen == 0 && !mbsinit (data->statep))
{
/* We have an incomplete character at the end. */
result = GCONV_INCOMPLETE_INPUT;
@@ -428,7 +408,7 @@ __gconv_transform_ucs4_ucs2 (struct gconv_step *step,
if (do_flush)
{
/* Clear the state. */
- memset (data->data, '\0', sizeof (mbstate_t));
+ memset (data->statep, '\0', sizeof (mbstate_t));
do_write = 0;
/* Call the steps down the chain if there are any. */
@@ -474,7 +454,7 @@ __gconv_transform_ucs4_ucs2 (struct gconv_step *step,
if (*inlen < 4)
{
/* We have an incomplete input character. */
- mbstate_t *state = (mbstate_t *) data->data;
+ mbstate_t *state = data->statep;
state->count = *inlen;
state->value = 0;
while (*inlen > 0)
@@ -495,7 +475,7 @@ __gconv_transform_ucs4_ucs2 (struct gconv_step *step,
break;
}
- if (*inlen == 0 && !mbsinit ((mbstate_t *) data->data))
+ if (*inlen == 0 && !mbsinit (data->statep))
{
/* We have an incomplete character at the end. */
result = GCONV_INCOMPLETE_INPUT;