Version 5.0.8
[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_len = 0;
36     buf16->utf16_cap = capacity;
37     if (capacity > 0)
38     {
39         buf16->utf16 = (UChar *) xmalloc(sizeof(UChar) * capacity);
40         buf16->utf16[0] = (UChar) 0;
41     }
42     else
43         buf16->utf16 = 0;
44     return buf16;
45 }
46
47 struct icu_buf_utf16 *icu_buf_utf16_clear(struct icu_buf_utf16 *buf16)
48 {
49     assert(buf16);
50     if (buf16->utf16)
51         buf16->utf16[0] = (UChar) 0;
52     buf16->utf16_len = 0;
53     return buf16;
54 }
55
56 struct icu_buf_utf16 *icu_buf_utf16_resize(struct icu_buf_utf16 *buf16,
57                                            size_t capacity)
58 {
59     assert(buf16);
60     if (capacity > 0)
61     {
62         if (0 == buf16->utf16)
63             buf16->utf16 = (UChar *) xmalloc(sizeof(UChar) * capacity);
64         else
65             buf16->utf16
66                 = (UChar *) xrealloc(buf16->utf16, sizeof(UChar) * capacity);
67         buf16->utf16_cap = capacity;
68     }
69     return buf16;
70 }
71
72
73 struct icu_buf_utf16 *icu_buf_utf16_copy(struct icu_buf_utf16 *dest16,
74                                          const struct icu_buf_utf16 *src16)
75 {
76     if (!dest16 || !src16 || dest16 == src16)
77         return 0;
78
79     if (dest16->utf16_cap < src16->utf16_len)
80         icu_buf_utf16_resize(dest16, src16->utf16_len * 2);
81
82     u_strncpy(dest16->utf16, src16->utf16, src16->utf16_len);
83     dest16->utf16_len = src16->utf16_len;
84
85     return dest16;
86 }
87
88
89 struct icu_buf_utf16 *icu_buf_utf16_append(struct icu_buf_utf16 *dest16,
90                                            const struct icu_buf_utf16 *src16)
91 {
92     assert(dest16);
93     if (!src16)
94         return dest16;
95     if (dest16 == src16)
96         return 0;
97
98     if (dest16->utf16_cap <= src16->utf16_len + dest16->utf16_len)
99         icu_buf_utf16_resize(dest16, dest16->utf16_len + src16->utf16_len * 2);
100
101     u_strncpy(dest16->utf16 + dest16->utf16_len,
102               src16->utf16, src16->utf16_len);
103     dest16->utf16_len += src16->utf16_len;
104
105     return dest16;
106 }
107
108
109 void icu_buf_utf16_destroy(struct icu_buf_utf16 *buf16)
110 {
111     if (buf16)
112         xfree(buf16->utf16);
113     xfree(buf16);
114 }
115
116 void icu_buf_utf16_log(const char *lead, struct icu_buf_utf16 *src16)
117 {
118     if (src16)
119     {
120         struct icu_buf_utf8 *dst8 = icu_buf_utf8_create(0);
121         UErrorCode status = U_ZERO_ERROR;
122         icu_utf16_to_utf8(dst8, src16, &status);
123         yaz_log(YLOG_LOG, "%s=%s", lead, dst8->utf8);
124         icu_buf_utf8_destroy(dst8);
125     }
126     else
127     {
128         yaz_log(YLOG_LOG, "%s=NULL", lead);
129     }
130 }
131
132 #endif /* YAZ_HAVE_ICU */
133
134 /*
135  * Local variables:
136  * c-basic-offset: 4
137  * c-file-style: "Stroustrup"
138  * indent-tabs-mode: nil
139  * End:
140  * vim: shiftwidth=4 tabstop=8 expandtab
141  */
142