(root)/
glibc-2.38/
iconv/
gconv_int.h
       1  /* Copyright (C) 1997-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #ifndef _GCONV_INT_H
      19  #define _GCONV_INT_H	1
      20  
      21  #include "gconv.h"
      22  #include <stdlib.h>		/* For alloca used in macro below.  */
      23  #include <ctype.h>		/* For __toupper_l used in macro below.  */
      24  #include <string.h>		/* For strlen et al used in macro below.  */
      25  #include <libc-lock.h>
      26  
      27  __BEGIN_DECLS
      28  
      29  /* We have to provide support for machines which are not able to handled
      30     unaligned memory accesses.  Some of the character encodings have
      31     representations with a fixed width of 2 or 4 bytes.  */
      32  #define get16(addr)							\
      33  ({									\
      34    const struct { uint16_t r; } __attribute__ ((__packed__)) *__ptr	\
      35      = (__typeof(__ptr))(addr);						\
      36    __ptr->r;								\
      37  })
      38  #define get32(addr)							\
      39  ({									\
      40    const struct { uint32_t r; } __attribute__ ((__packed__)) *__ptr	\
      41      = (__typeof(__ptr))(addr);						\
      42    __ptr->r;								\
      43  })
      44  
      45  #define put16(addr, val)						\
      46  do {									\
      47     struct { uint16_t r; } __attribute__ ((__packed__)) *__ptr		\
      48      = (__typeof(__ptr))(addr);						\
      49     __ptr->r = val;							\
      50  } while (0)
      51  #define put32(addr, val)						\
      52  do {									\
      53     struct { uint32_t r; } __attribute__ ((__packed__)) *__ptr		\
      54      = (__typeof(__ptr))(addr);						\
      55     __ptr->r = val;							\
      56  } while (0)
      57  
      58  /* Structure for alias definition.  Simply two strings.  */
      59  struct gconv_alias
      60  {
      61    char *fromname;
      62    char *toname;
      63  };
      64  
      65  
      66  /* Structure describing one loaded shared object.  This normally are
      67     objects to perform conversation but as a special case the db shared
      68     object is also handled.  */
      69  struct __gconv_loaded_object
      70  {
      71    /* Name of the object.  It must be the first structure element.  */
      72    const char *name;
      73  
      74    /* Reference counter for the db functionality.  If no conversion is
      75       needed we unload the db library.  */
      76    int counter;
      77  
      78    /* The handle for the shared object.  */
      79    void *handle;
      80  
      81    /* Pointer to the functions the module defines.  */
      82    __gconv_fct fct;
      83    __gconv_init_fct init_fct;
      84    __gconv_end_fct end_fct;
      85  };
      86  
      87  
      88  /* Description for an available conversion module.  */
      89  struct gconv_module
      90  {
      91    const char *from_string;
      92    const char *to_string;
      93  
      94    int cost_hi;
      95    int cost_lo;
      96  
      97    const char *module_name;
      98  
      99    struct gconv_module *left;	/* Prefix smaller.  */
     100    struct gconv_module *same;	/* List of entries with identical prefix.  */
     101    struct gconv_module *right;	/* Prefix larger.  */
     102  };
     103  
     104  
     105  /* The specification of the conversion that needs to be performed.  */
     106  struct gconv_spec
     107  {
     108    char *fromcode;
     109    char *tocode;
     110    bool translit;
     111    bool ignore;
     112  };
     113  
     114  /* Flags for `gconv_open'.  */
     115  enum
     116  {
     117    GCONV_AVOID_NOCONV = 1 << 0
     118  };
     119  
     120  /* When GCONV_AVOID_NOCONV is set and no conversion is needed,
     121     __GCONV_NULCONV should be returned.  */
     122  enum
     123  {
     124    __GCONV_NULCONV = -1
     125  };
     126  
     127  /* Global variables.  */
     128  
     129  /* Database of alias names.  */
     130  extern void *__gconv_alias_db attribute_hidden;
     131  
     132  /* Array with available modules.  */
     133  extern struct gconv_module *__gconv_modules_db attribute_hidden;
     134  
     135  /* Value of the GCONV_PATH environment variable.  */
     136  extern const char *__gconv_path_envvar attribute_hidden;
     137  
     138  /* Lock for the conversion database content.  */
     139  __libc_lock_define (extern, __gconv_lock attribute_hidden)
     140  
     141  
     142  /* The gconv functions expects the name to be in upper case and complete,
     143     including the trailing slashes if necessary.  */
     144  #define norm_add_slashes(str,suffix) \
     145    ({									      \
     146      const char *cp = (str);						      \
     147      char *result;							      \
     148      char *tmp;								      \
     149      size_t cnt = 0;							      \
     150      const size_t suffix_len = strlen (suffix);				      \
     151  									      \
     152      while (*cp != '\0')							      \
     153        if (*cp++ == '/')							      \
     154  	++cnt;								      \
     155  									      \
     156      tmp = result = __alloca (cp - (str) + 3 + suffix_len);		      \
     157      cp = (str);								      \
     158      while (*cp != '\0')							      \
     159        *tmp++ = __toupper_l (*cp++, _nl_C_locobj_ptr);			      \
     160      if (cnt < 2)							      \
     161        {									      \
     162  	*tmp++ = '/';							      \
     163  	if (cnt < 1)							      \
     164  	  {								      \
     165  	    *tmp++ = '/';						      \
     166  	    if (suffix_len != 0)					      \
     167  	      tmp = __mempcpy (tmp, suffix, suffix_len);		      \
     168  	  }								      \
     169        }									      \
     170      *tmp = '\0';							      \
     171      result;								      \
     172    })
     173  
     174  
     175  /* Return in *HANDLE, a descriptor for the transformation.  The function expects
     176     the specification of the transformation in the structure pointed to by
     177     CONV_SPEC.  It only reads *CONV_SPEC and does not take ownership of it.  */
     178  extern int __gconv_open (struct gconv_spec *conv_spec,
     179                           __gconv_t *handle, int flags);
     180  libc_hidden_proto (__gconv_open)
     181  
     182  /* This function accepts the charset names of the source and destination of the
     183     conversion and populates *conv_spec with an equivalent conversion
     184     specification that may later be used by __gconv_open.  The charset names
     185     might contain options in the form of suffixes that alter the conversion,
     186     e.g. "ISO-10646/UTF-8/TRANSLIT".  It processes the charset names, ignoring
     187     and truncating any suffix options in fromcode, and processing and truncating
     188     any suffix options in tocode.  Supported suffix options ("TRANSLIT" or
     189     "IGNORE") when found in tocode lead to the corresponding flag in *conv_spec
     190     to be set to true.  Unrecognized suffix options are silently discarded.  If
     191     the function succeeds, it returns conv_spec back to the caller.  It returns
     192     NULL upon failure.  */
     193  extern struct gconv_spec *
     194  __gconv_create_spec (struct gconv_spec *conv_spec, const char *fromcode,
     195                       const char *tocode);
     196  libc_hidden_proto (__gconv_create_spec)
     197  
     198  /* This function frees all heap memory allocated by __gconv_create_spec.  */
     199  extern void
     200  __gconv_destroy_spec (struct gconv_spec *conv_spec);
     201  libc_hidden_proto (__gconv_destroy_spec)
     202  
     203  /* Free resources associated with transformation descriptor CD.  */
     204  extern int __gconv_close (__gconv_t cd)
     205       attribute_hidden;
     206  
     207  /* Transform at most *INBYTESLEFT bytes from buffer starting at *INBUF
     208     according to rules described by CD and place up to *OUTBYTESLEFT
     209     bytes in buffer starting at *OUTBUF.  Return number of non-identical
     210     conversions in *IRREVERSIBLE if this pointer is not null.  */
     211  extern int __gconv (__gconv_t cd, const unsigned char **inbuf,
     212  		    const unsigned char *inbufend, unsigned char **outbuf,
     213  		    unsigned char *outbufend, size_t *irreversible)
     214       attribute_hidden;
     215  
     216  /* Return in *HANDLE a pointer to an array with *NSTEPS elements describing
     217     the single steps necessary for transformation from FROMSET to TOSET.  */
     218  extern int __gconv_find_transform (const char *toset, const char *fromset,
     219  				   struct __gconv_step **handle,
     220  				   size_t *nsteps, int flags)
     221       attribute_hidden;
     222  
     223  /* Search for transformation in cache data.  */
     224  extern int __gconv_lookup_cache (const char *toset, const char *fromset,
     225  				 struct __gconv_step **handle, size_t *nsteps,
     226  				 int flags)
     227       attribute_hidden;
     228  
     229  /* Compare the two name for whether they are after alias expansion the
     230     same.  This function uses the cache and fails if none is
     231     loaded.  */
     232  extern int __gconv_compare_alias_cache (const char *name1, const char *name2,
     233  					int *result)
     234       attribute_hidden;
     235  
     236  /* Free data associated with a step's structure.  */
     237  extern void __gconv_release_step (struct __gconv_step *step)
     238       attribute_hidden;
     239  
     240  /* Read all the configuration data and cache it if not done so already.  */
     241  extern void __gconv_load_conf (void) attribute_hidden;
     242  
     243  /* Try to read module cache file.  */
     244  extern int __gconv_load_cache (void) attribute_hidden;
     245  
     246  /* Retrieve pointer to internal cache.  */
     247  extern void *__gconv_get_cache (void);
     248  
     249  /* Retrieve pointer to internal module database.  */
     250  extern struct gconv_module *__gconv_get_modules_db (void);
     251  
     252  /* Retrieve pointer to internal alias database.  */
     253  extern void *__gconv_get_alias_db (void);
     254  
     255  /* Comparison function to search alias.  */
     256  extern int __gconv_alias_compare (const void *p1, const void *p2)
     257       attribute_hidden;
     258  
     259  /* Clear reference to transformation step implementations which might
     260     cause the code to be unloaded.  */
     261  extern int __gconv_close_transform (struct __gconv_step *steps,
     262  				    size_t nsteps)
     263       attribute_hidden;
     264  
     265  /* Free all resources allocated for the transformation record when
     266     using the cache.  */
     267  extern void __gconv_release_cache (struct __gconv_step *steps, size_t nsteps)
     268       attribute_hidden;
     269  
     270  /* Load shared object named by NAME.  If already loaded increment reference
     271     count.  */
     272  extern struct __gconv_loaded_object *__gconv_find_shlib (const char *name)
     273       attribute_hidden;
     274  
     275  /* Release shared object.  If no further reference is available unload
     276     the object.  */
     277  extern void __gconv_release_shlib (struct __gconv_loaded_object *handle)
     278       attribute_hidden;
     279  
     280  /* Fill STEP with information about builtin module with NAME.  */
     281  extern void __gconv_get_builtin_trans (const char *name,
     282  				       struct __gconv_step *step)
     283       attribute_hidden;
     284  
     285  /* Transliteration using the locale's data.  */
     286  extern int __gconv_transliterate (struct __gconv_step *step,
     287                                    struct __gconv_step_data *step_data,
     288                                    const unsigned char *inbufstart,
     289                                    const unsigned char **inbufp,
     290                                    const unsigned char *inbufend,
     291                                    unsigned char **outbufstart,
     292                                    size_t *irreversible);
     293  libc_hidden_proto (__gconv_transliterate)
     294  
     295  /* If NAME is an codeset alias expand it.  */
     296  extern int __gconv_compare_alias (const char *name1, const char *name2)
     297       attribute_hidden;
     298  
     299  
     300  /* Builtin transformations.  */
     301  #ifdef _LIBC
     302  # define __BUILTIN_TRANSFORM(Name) \
     303    extern int Name (struct __gconv_step *step,				      \
     304  		   struct __gconv_step_data *data,			      \
     305  		   const unsigned char **inbuf,				      \
     306  		   const unsigned char *inbufend,			      \
     307  		   unsigned char **outbufstart, size_t *irreversible,	      \
     308  		   int do_flush, int consume_incomplete)
     309  
     310  __BUILTIN_TRANSFORM (__gconv_transform_ascii_internal);
     311  __BUILTIN_TRANSFORM (__gconv_transform_internal_ascii);
     312  __BUILTIN_TRANSFORM (__gconv_transform_utf8_internal);
     313  __BUILTIN_TRANSFORM (__gconv_transform_internal_utf8);
     314  __BUILTIN_TRANSFORM (__gconv_transform_ucs2_internal);
     315  __BUILTIN_TRANSFORM (__gconv_transform_internal_ucs2);
     316  __BUILTIN_TRANSFORM (__gconv_transform_ucs2reverse_internal);
     317  __BUILTIN_TRANSFORM (__gconv_transform_internal_ucs2reverse);
     318  __BUILTIN_TRANSFORM (__gconv_transform_internal_ucs4);
     319  __BUILTIN_TRANSFORM (__gconv_transform_ucs4_internal);
     320  __BUILTIN_TRANSFORM (__gconv_transform_internal_ucs4le);
     321  __BUILTIN_TRANSFORM (__gconv_transform_ucs4le_internal);
     322  __BUILTIN_TRANSFORM (__gconv_transform_internal_utf16);
     323  __BUILTIN_TRANSFORM (__gconv_transform_utf16_internal);
     324  # undef __BUITLIN_TRANSFORM
     325  
     326  /* Specialized conversion function for a single byte to INTERNAL, recognizing
     327     only ASCII characters.  */
     328  extern wint_t __gconv_btwoc_ascii (struct __gconv_step *step, unsigned char c);
     329  
     330  #endif
     331  
     332  __END_DECLS
     333  
     334  #endif /* gconv_int.h */