diff options
author | Ulrich Drepper <drepper@redhat.com> | 1998-04-04 07:25:25 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 1998-04-04 07:25:25 +0000 |
commit | 0d9f67937f0c9329c35c2c0d15848ab8316dc520 (patch) | |
tree | ee2b01470306f95f731e268aab1c0712f9e9d50c /iconv | |
parent | e62c19f12cfc377ac9ce7c037713ead5dc6b57d9 (diff) | |
download | glibc-0d9f67937f0c9329c35c2c0d15848ab8316dc520.tar.gz |
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.c | 1 | ||||
-rw-r--r-- | iconv/gconv.h | 18 | ||||
-rw-r--r-- | iconv/gconv_builtin.h | 16 | ||||
-rw-r--r-- | iconv/gconv_close.c | 13 | ||||
-rw-r--r-- | iconv/gconv_db.c | 87 | ||||
-rw-r--r-- | iconv/gconv_dl.c | 85 | ||||
-rw-r--r-- | iconv/gconv_int.h | 89 | ||||
-rw-r--r-- | iconv/gconv_open.c | 34 | ||||
-rw-r--r-- | iconv/gconv_simple.c | 42 |
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; |