YAZ  5.23.1
icu_casemap.c
Go to the documentation of this file.
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) Index Data
3  * See the file LICENSE for details.
4  */
5 
11 #if HAVE_CONFIG_H
12 #include "config.h"
13 #endif
14 
15 #if YAZ_HAVE_ICU
16 #include <yaz/xmalloc.h>
17 
18 #include <yaz/icu_I18N.h>
19 
20 #include <yaz/log.h>
21 
22 #include <string.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 
26 #include <unicode/ustring.h>
27 
28 struct icu_casemap
29 {
30  char action;
31 };
32 
33 struct icu_casemap *icu_casemap_create(char action, UErrorCode *status)
34 {
35  struct icu_casemap *casemap
36  = (struct icu_casemap *) xmalloc(sizeof(struct icu_casemap));
37  casemap->action = action;
38 
39  switch (casemap->action)
40  {
41  case 'l':
42  case 'L':
43  case 'u':
44  case 'U':
45  case 't':
46  case 'T':
47  case 'f':
48  case 'F':
49  break;
50  default:
51  icu_casemap_destroy(casemap);
52  return 0;
53  }
54  return casemap;
55 }
56 
57 struct icu_casemap *icu_casemap_clone(struct icu_casemap *old)
58 {
59  struct icu_casemap * casemap
60  = (struct icu_casemap *) xmalloc(sizeof(struct icu_casemap));
61  casemap->action = old->action;
62  return casemap;
63 }
64 
65 void icu_casemap_destroy(struct icu_casemap * casemap)
66 {
67  xfree(casemap);
68 }
69 
70 int icu_casemap_casemap(struct icu_casemap *casemap,
71  struct icu_buf_utf16 *dest16,
72  struct icu_buf_utf16 *src16,
73  UErrorCode *status,
74  const char *locale)
75 {
76  if (!casemap)
77  return 0;
78 
79  return icu_utf16_casemap(dest16, src16, locale,
80  casemap->action, status);
81 }
82 
83 
84 static uint32_t icu_utf16_sub(struct icu_buf_utf16 *dest16,
85  struct icu_buf_utf16 *src16,
86  const char *locale, char action,
87  UErrorCode *status)
88 {
89  switch (action)
90  {
91  case 'l':
92  case 'L':
93  return u_strToLower(dest16->utf16, dest16->utf16_cap,
94  src16->utf16, src16->utf16_len,
95  locale, status);
96  case 'u':
97  case 'U':
98  return u_strToUpper(dest16->utf16, dest16->utf16_cap,
99  src16->utf16, src16->utf16_len,
100  locale, status);
101  break;
102  case 't':
103  case 'T':
104  return u_strToTitle(dest16->utf16, dest16->utf16_cap,
105  src16->utf16, src16->utf16_len,
106  0, locale, status);
107  break;
108  case 'f':
109  case 'F':
110  return u_strFoldCase(dest16->utf16, dest16->utf16_cap,
111  src16->utf16, src16->utf16_len,
112  U_FOLD_CASE_DEFAULT, status);
113  break;
114  default:
115  *status = U_UNSUPPORTED_ERROR;
116  break;
117  }
118  return 0;
119 }
120 
121 
122 int icu_utf16_casemap(struct icu_buf_utf16 *dest16,
123  struct icu_buf_utf16 *src16,
124  const char *locale, char action,
125  UErrorCode *status)
126 {
127  int32_t dest16_len = 0;
128 
129  if (!src16->utf16_len)
130  { /* guarding for empty source string */
131  if (dest16->utf16)
132  dest16->utf16[0] = (UChar) 0;
133  dest16->utf16_len = 0;
134  return U_ZERO_ERROR;
135  }
136 
137  dest16_len = icu_utf16_sub(dest16, src16, locale, action, status);
138 
139  /* check for buffer overflow, resize and retry */
140  if (*status == U_BUFFER_OVERFLOW_ERROR
141  && dest16 != src16) /* do not resize if in-place conversion */
142  {
143  icu_buf_utf16_resize(dest16, dest16_len * 2);
144  *status = U_ZERO_ERROR;
145 
146  icu_utf16_sub(dest16, src16, locale, action, status);
147  }
148 
149  if (U_SUCCESS(*status) && dest16_len <= dest16->utf16_cap)
150  dest16->utf16_len = dest16_len;
151  else
152  {
153  if (dest16->utf16)
154  dest16->utf16[0] = (UChar) 0;
155  dest16->utf16_len = 0;
156  }
157 
158  return *status;
159 }
160 
161 
162 #endif /* YAZ_HAVE_ICU */
163 
164 /*
165  * Local variables:
166  * c-basic-offset: 4
167  * c-file-style: "Stroustrup"
168  * indent-tabs-mode: nil
169  * End:
170  * vim: shiftwidth=4 tabstop=8 expandtab
171  */
172 
struct icu_casemap * icu_casemap_clone(struct icu_casemap *old)
void icu_casemap_destroy(struct icu_casemap *casemap)
int icu_casemap_casemap(struct icu_casemap *casemap, struct icu_buf_utf16 *dest16, struct icu_buf_utf16 *src16, UErrorCode *status, const char *locale)
UChar * utf16
Definition: icu_I18N.h:54
Internal header for ICU utilities.
#define xfree(x)
utility macro which calls xfree_f
Definition: xmalloc.h:53
struct icu_casemap * icu_casemap_create(char action, UErrorCode *status)
int32_t utf16_len
Definition: icu_I18N.h:55
struct icu_buf_utf16 * icu_buf_utf16_resize(struct icu_buf_utf16 *buf16, size_t capacity)
int32_t utf16_cap
Definition: icu_I18N.h:56
#define xmalloc(x)
utility macro which calls malloc_f
Definition: xmalloc.h:49
Header for memory handling functions.
Logging utility.
int icu_utf16_casemap(struct icu_buf_utf16 *dest16, struct icu_buf_utf16 *src16, const char *locale, char action, UErrorCode *status)