packaging: Enable memcpy in sysdeps/arm/memcpy.S for ARM
[platform/upstream/glibc.git] / iconv / gconv_int.h
1 /* Copyright (C) 1997-2024 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 */