466f7af80ec73d5871d46f5cc39a99b6275361a3
[yaz-moved-to-github.git] / src / icu_utf16.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) 1995-2013 Index Data
3  * See the file LICENSE for details.
4  */
5
6 /**
7  * \file
8  * \brief UTF-16 string utilities for 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 #include <assert.h>
26
27 #include <unicode/ustring.h>  /* some more string fcns*/
28 #include <unicode/uchar.h>    /* char names           */
29
30 struct icu_buf_utf16 * icu_buf_utf16_create(size_t capacity)
31 {
32     struct icu_buf_utf16 * buf16
33         = (struct icu_buf_utf16 *) xmalloc(sizeof(struct icu_buf_utf16));
34
35     buf16->utf16 = 0;
36     buf16->utf16_len = 0;
37     buf16->utf16_cap = 0;
38
39     if (capacity > 0)
40     {
41         buf16->utf16 = (UChar *) xmalloc(sizeof(UChar) * capacity);
42         buf16->utf16[0] = (UChar) 0;
43         buf16->utf16_cap = capacity;
44     }
45     return buf16;
46 }
47
48 struct icu_buf_utf16 * icu_buf_utf16_clear(struct icu_buf_utf16 * buf16)
49 {
50     if (buf16)
51     {
52         if (buf16->utf16)
53             buf16->utf16[0] = (UChar) 0;
54         buf16->utf16_len = 0;
55     }
56     return buf16;
57 }
58
59 struct icu_buf_utf16 * icu_buf_utf16_resize(struct icu_buf_utf16 * buf16,
60                                             size_t capacity)
61 {
62     if (!buf16)
63         return 0;
64
65     if (capacity > 0)
66     {
67         if (0 == buf16->utf16)
68             buf16->utf16 = (UChar *) xmalloc(sizeof(UChar) * capacity);
69         else
70             buf16->utf16
71                 = (UChar *) xrealloc(buf16->utf16, sizeof(UChar) * capacity);
72     }
73     else
74     {
75         xfree(buf16->utf16);
76         buf16->utf16 = 0;
77         buf16->utf16_len = 0;
78     }
79     buf16->utf16_cap = capacity;
80     return buf16;
81 }
82
83
84 struct icu_buf_utf16 * icu_buf_utf16_copy(struct icu_buf_utf16 * dest16,
85                                           const struct icu_buf_utf16 * src16)
86 {
87     if (!dest16 || !src16 || dest16 == src16)
88         return 0;
89
90     if (dest16->utf16_cap < src16->utf16_len)
91         icu_buf_utf16_resize(dest16, src16->utf16_len * 2);
92
93     u_strncpy(dest16->utf16, src16->utf16, src16->utf16_len);
94     dest16->utf16_len = src16->utf16_len;
95
96     return dest16;
97 }
98
99
100 struct icu_buf_utf16 *icu_buf_utf16_append(struct icu_buf_utf16 *dest16,
101                                            const struct icu_buf_utf16 * src16)
102 {
103     assert(dest16);
104     if (!src16)
105         return dest16;
106     if (dest16 == src16)
107         return 0;
108
109     if (dest16->utf16_cap <= src16->utf16_len + dest16->utf16_len)
110         icu_buf_utf16_resize(dest16, dest16->utf16_len + src16->utf16_len * 2);
111
112     u_strncpy(dest16->utf16 + dest16->utf16_len,
113               src16->utf16, src16->utf16_len);
114     dest16->utf16_len += src16->utf16_len;
115
116     return dest16;
117 }
118
119
120 void icu_buf_utf16_destroy(struct icu_buf_utf16 * buf16)
121 {
122     if (buf16)
123         xfree(buf16->utf16);
124     xfree(buf16);
125 }
126
127 void icu_buf_utf16_log(const char *lead, struct icu_buf_utf16 *src16)
128 {
129     if (src16)
130     {
131         struct icu_buf_utf8 *dst8 = icu_buf_utf8_create(0);
132         UErrorCode status = U_ZERO_ERROR;
133         icu_utf16_to_utf8(dst8, src16, &status);
134         yaz_log(YLOG_LOG, "%s=%s", lead, dst8->utf8);
135         icu_buf_utf8_destroy(dst8);
136     }
137     else
138     {
139         yaz_log(YLOG_LOG, "%s=NULL", lead);
140     }
141 }
142
143 #endif /* YAZ_HAVE_ICU */
144
145 /*
146  * Local variables:
147  * c-basic-offset: 4
148  * c-file-style: "Stroustrup"
149  * indent-tabs-mode: nil
150  * End:
151  * vim: shiftwidth=4 tabstop=8 expandtab
152  */
153