Bump copyright year
[yaz-moved-to-github.git] / src / icu_casemap.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) 1995-2010 Index Data
3  * See the file LICENSE for details.
4  */
5
6 /**
7  * \file
8  * \brief ICU character case (u_strToUpper, etc)
9  */
10
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 void icu_casemap_destroy(struct icu_casemap * casemap)
58 {
59     xfree(casemap);
60 }
61
62 int icu_casemap_casemap(struct icu_casemap * casemap,
63                         struct icu_buf_utf16 * dest16,
64                         struct icu_buf_utf16 * src16,
65                         UErrorCode *status,
66                         const char *locale)
67 {
68     if(!casemap)
69         return 0;
70     
71     return icu_utf16_casemap(dest16, src16, locale,
72                              casemap->action, status);
73 }
74
75 int icu_utf16_casemap(struct icu_buf_utf16 * dest16,
76                       struct icu_buf_utf16 * src16,
77                       const char *locale, char action,
78                       UErrorCode *status)
79 {
80     int32_t dest16_len = 0;
81
82     if (!src16->utf16_len)
83     {           /* guarding for empty source string */
84         if (dest16->utf16)
85             dest16->utf16[0] = (UChar) 0;
86         dest16->utf16_len = 0;
87         return U_ZERO_ERROR;
88     }
89     
90     switch (action)
91     {
92     case 'l':    
93     case 'L':    
94         dest16_len = u_strToLower(dest16->utf16, dest16->utf16_cap,
95                                   src16->utf16, src16->utf16_len, 
96                                   locale, status);
97         break;
98     case 'u':    
99     case 'U':    
100         dest16_len = u_strToUpper(dest16->utf16, dest16->utf16_cap,
101                                   src16->utf16, src16->utf16_len, 
102                                   locale, status);
103         break;
104     case 't':    
105     case 'T':    
106         dest16_len = u_strToTitle(dest16->utf16, dest16->utf16_cap,
107                                   src16->utf16, src16->utf16_len,
108                                   0, locale, status);
109         break;
110     case 'f':    
111     case 'F':    
112         dest16_len = u_strFoldCase(dest16->utf16, dest16->utf16_cap,
113                                    src16->utf16, src16->utf16_len,
114                                    U_FOLD_CASE_DEFAULT, status);
115         break;
116         
117     default:
118         return U_UNSUPPORTED_ERROR;
119         break;
120     }
121
122     /* check for buffer overflow, resize and retry */
123     if (*status == U_BUFFER_OVERFLOW_ERROR
124         && dest16 != src16        /* do not resize if in-place conversion */
125         )
126     {
127         icu_buf_utf16_resize(dest16, dest16_len * 2);
128         *status = U_ZERO_ERROR;
129
130         switch (action) {    
131         case 'l':    
132         case 'L':    
133             dest16_len = u_strToLower(dest16->utf16, dest16->utf16_cap,
134                                       src16->utf16, src16->utf16_len, 
135                                       locale, status);
136             break;
137         case 'u':    
138         case 'U':    
139             dest16_len = u_strToUpper(dest16->utf16, dest16->utf16_cap,
140                                       src16->utf16, src16->utf16_len, 
141                                       locale, status);
142             break;
143         case 't':    
144         case 'T':    
145             dest16_len = u_strToTitle(dest16->utf16, dest16->utf16_cap,
146                                       src16->utf16, src16->utf16_len,
147                                       0, locale, status);
148             break;
149         case 'f':    
150         case 'F':    
151             dest16_len = u_strFoldCase(dest16->utf16, dest16->utf16_cap,
152                                        src16->utf16, src16->utf16_len,
153                                        U_FOLD_CASE_DEFAULT, status);
154             break;
155         
156         default:
157             return U_UNSUPPORTED_ERROR;
158             break;
159         }
160     }
161     
162     if (U_SUCCESS(*status)
163         && dest16_len <= dest16->utf16_cap)
164         dest16->utf16_len = dest16_len;
165     else
166     {
167         if (dest16->utf16)
168             dest16->utf16[0] = (UChar) 0;
169         dest16->utf16_len = 0;
170     }
171   
172     return *status;
173 }
174
175
176 #endif /* YAZ_HAVE_ICU */
177
178 /*
179  * Local variables:
180  * c-basic-offset: 4
181  * c-file-style: "Stroustrup"
182  * indent-tabs-mode: nil
183  * End:
184  * vim: shiftwidth=4 tabstop=8 expandtab
185  */
186