50 #include "tdelibs_export.h"
58 #if defined HAVE_STRING_H
64 #include <sys/types.h>
68 #if defined HAVE_UNISTD_H
72 #if (defined HAVE_MMAP && defined HAVE_MUNMAP)
73 # include <sys/mman.h>
77 # define W(flag, data) ((flag) ? SWAP (data) : (data))
80 typedef TQ_UINT32 nls_uint32;
85 #if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP)
91 struct string_desc *orig_tab;
92 struct string_desc *trans_tab;
97 struct kde_loaded_l10nfile
104 kde_loaded_l10nfile() : filename(0), decided(0), data(0) {}
107 void k_nl_load_domain(
struct kde_loaded_l10nfile *__domain);
109 static inline nls_uint32
112 return (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24);
118 #define _MAGIC 0x950412de
119 #define _MAGIC_SWAPPED 0xde120495
122 #define MO_REVISION_NUMBER 0
128 static inline unsigned long hash_string (
const char *__str_param);
133 struct mo_file_header
142 nls_uint32 orig_tab_offset;
144 nls_uint32 trans_tab_offset;
146 nls_uint32 hash_tab_size;
148 nls_uint32 hash_tab_offset;
160 char *k_nl_find_msg (
struct kde_loaded_l10nfile *domain_file,
164 k_nl_find_msg (
struct kde_loaded_l10nfile *domain_file,
const char *msgid)
166 size_t top, act, bottom;
167 struct loaded_domain *domain;
169 if (domain_file->decided == 0)
170 k_nl_load_domain (domain_file);
172 if (domain_file->data == NULL)
175 domain = (
struct loaded_domain *) domain_file->data;
178 if (domain->hash_size > 2 && domain->hash_tab != NULL)
181 nls_uint32 len = strlen (msgid);
182 nls_uint32 hash_val = hash_string (msgid);
183 nls_uint32 idx = hash_val % domain->hash_size;
184 nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2));
185 nls_uint32 nstr = W (domain->must_swap, domain->hash_tab[idx]);
191 if (W (domain->must_swap, domain->orig_tab[nstr - 1].length) == len
193 domain->data + W (domain->must_swap,
194 domain->orig_tab[nstr - 1].offset)) == 0)
195 return (
char *) domain->data + W (domain->must_swap,
196 domain->trans_tab[nstr - 1].offset);
200 if (idx >= domain->hash_size - incr)
201 idx -= domain->hash_size - incr;
205 nstr = W (domain->must_swap, domain->hash_tab[idx]);
210 if (W (domain->must_swap, domain->orig_tab[nstr - 1].length) == len
212 domain->data + W (domain->must_swap,
213 domain->orig_tab[nstr - 1].offset))
215 return (
char *) domain->data
216 + W (domain->must_swap, domain->trans_tab[nstr - 1].offset);
224 top = domain->nstrings;
230 act = (bottom + top) / 2;
231 cmp_val = strcmp (msgid, domain->data
232 + W (domain->must_swap,
233 domain->orig_tab[act].offset));
236 else if (cmp_val > 0)
243 return bottom >= top ? NULL : (
char *) domain->data
244 + W (domain->must_swap,
245 domain->trans_tab[act].offset);
250 #define HASHWORDBITS 32
252 static inline unsigned long
253 hash_string (
const char *str_param)
255 unsigned long int hval, g;
256 const char *str = str_param;
263 hval += (
unsigned char) *str++;
264 g = hval & ((
unsigned long int) 0xf << (HASHWORDBITS - 4));
267 hval ^= g >> (HASHWORDBITS - 8);
277 k_nl_load_domain (
struct kde_loaded_l10nfile *domain_file)
281 struct mo_file_header *data = (
struct mo_file_header *) -1;
282 #if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP)
285 struct loaded_domain *domain;
287 domain_file->decided = 1;
288 domain_file->data = NULL;
294 if (domain_file->filename == NULL)
298 fd = KDE_open (domain_file->filename, O_RDONLY);
303 if (fstat (fd, &st) != 0
304 || st.st_size < (off_t) sizeof (
struct mo_file_header))
311 #if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP)
314 data = (
struct mo_file_header *) mmap (NULL, st.st_size, PROT_READ,
317 if (data != (
struct mo_file_header *) -1)
327 if (data == (
struct mo_file_header *) -1)
332 data = (
struct mo_file_header *) malloc (st.st_size);
336 to_read = st.st_size;
337 read_ptr = (
char *) data;
340 long int nb = (
long int) read (fd, read_ptr, to_read);
357 if (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED)
360 #if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP)
362 munmap ((
char *) data, st.st_size);
370 = (
struct loaded_domain *) malloc (
sizeof (
struct loaded_domain));
371 if (domain_file->data == NULL)
374 domain = (
struct loaded_domain *) domain_file->data;
375 domain->data = (
char *) data;
376 #if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP)
377 domain->use_mmap = use_mmap;
378 domain->mmap_size = st.st_size;
380 domain->must_swap = data->magic != _MAGIC;
383 switch (W (domain->must_swap, data->revision))
386 domain->nstrings = W (domain->must_swap, data->nstrings);
387 domain->orig_tab = (
struct string_desc *)
388 ((
char *) data + W (domain->must_swap, data->orig_tab_offset));
389 domain->trans_tab = (
struct string_desc *)
390 ((
char *) data + W (domain->must_swap, data->trans_tab_offset));
391 domain->hash_size = W (domain->must_swap, data->hash_tab_size);
392 domain->hash_tab = (nls_uint32 *)
393 ((
char *) data + W (domain->must_swap, data->hash_tab_offset));
397 #if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP)
399 munmap ((
char *) data, st.st_size);
404 domain_file->data = NULL;
410 k_nl_unload_domain (
struct loaded_domain *domain)
412 #if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP)
413 if (domain->use_mmap)
414 munmap ((caddr_t) domain->data, domain->mmap_size);
417 free ((
void *) domain->data);
TDEAction * close(const TQObject *recvr, const char *slot, TDEActionCollection *parent, const char *name=0)