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