ICU transform: init ICU status
[yaz-moved-to-github.git] / src / icu_transform.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 transforms - using utrans_-functions from ICU
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 <assert.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26
27 #include <unicode/utrans.h>
28
29 struct icu_transform
30 {
31     char action;
32     UParseError parse_error;
33     UTransliterator * trans;
34 };
35
36 struct icu_transform *icu_transform_clone(struct icu_transform *old)
37 {
38     struct icu_transform *transform
39         = (struct icu_transform *) xmalloc(sizeof(struct icu_transform));
40     UErrorCode status = U_ZERO_ERROR;
41     assert(old);
42     transform->action = old->action;
43     assert(old->trans);
44     transform->trans = utrans_clone(old->trans, &status);
45     assert(transform->trans);
46     return transform;
47 }
48
49 struct icu_transform * icu_transform_create(const char *id, char action,
50                                             const char *rules, 
51                                             UErrorCode *status)
52 {
53     struct icu_buf_utf16 *id16 = icu_buf_utf16_create(0);
54     struct icu_buf_utf16 *rules16 = icu_buf_utf16_create(0);
55
56     struct icu_transform *transform
57         = (struct icu_transform *) xmalloc(sizeof(struct icu_transform));
58
59     transform->action = action;
60     transform->trans = 0;
61
62     if (id)
63         icu_utf16_from_utf8_cstr(id16, id, status);
64     if (rules)
65         icu_utf16_from_utf8_cstr(rules16, rules, status);
66
67     switch (transform->action)
68     {
69     case 'f':
70     case 'F':
71         transform->trans
72             = utrans_openU(id16->utf16, 
73                            id16->utf16_len,
74                            UTRANS_FORWARD,
75                            rules16->utf16, 
76                            rules16->utf16_len,
77                            &transform->parse_error, status);
78         break;
79     case 'r':
80     case 'R':
81         transform->trans
82             = utrans_openU(id16->utf16,
83                            id16->utf16_len,
84                            UTRANS_REVERSE ,
85                            rules16->utf16, 
86                            rules16->utf16_len,
87                            &transform->parse_error, status);
88         break;
89     default:
90         *status = U_UNSUPPORTED_ERROR;
91         break;
92     }
93     icu_buf_utf16_destroy(rules16);
94     icu_buf_utf16_destroy(id16);
95     
96     if (U_SUCCESS(*status))
97         return transform;
98
99     /* freeing if failed */
100     icu_transform_destroy(transform);
101     return 0;
102 }
103
104 void icu_transform_destroy(struct icu_transform * transform)
105 {
106     if (transform)
107     {
108         if (transform->trans)
109             utrans_close(transform->trans);
110         xfree(transform);
111     }
112 }
113
114 int icu_transform_trans(struct icu_transform * transform,
115                         struct icu_buf_utf16 * dest16,
116                         const struct icu_buf_utf16 * src16,
117                         UErrorCode *status)
118 {
119     if (!transform || !transform->trans 
120         || !src16  || !dest16)
121         return 0;
122
123     if (!src16->utf16_len)
124     {           /* guarding for empty source string */
125         icu_buf_utf16_clear(dest16);
126         return 0;
127     }
128
129     if (!icu_buf_utf16_copy(dest16, src16))
130         return 0;
131
132     utrans_transUChars (transform->trans, 
133                         dest16->utf16, &(dest16->utf16_len),
134                         dest16->utf16_cap,
135                         0, &(dest16->utf16_len), status);
136
137     if (U_FAILURE(*status))
138         icu_buf_utf16_clear(dest16);
139     
140     return dest16->utf16_len;
141 }
142
143
144 #endif /* YAZ_HAVE_ICU */
145
146 /*
147  * Local variables:
148  * c-basic-offset: 4
149  * c-file-style: "Stroustrup"
150  * indent-tabs-mode: nil
151  * End:
152  * vim: shiftwidth=4 tabstop=8 expandtab
153  */
154