source: yaz/trunk/fuentes/src/icu_casemap.c @ 255

Last change on this file since 255 was 255, checked in by mabarracus, 4 years ago

added trusty code to xenial

File size: 4.0 KB
Line 
1/* This file is part of the YAZ toolkit.
2 * Copyright (C) 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
28struct icu_casemap
29{
30    char action;
31};
32
33struct 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
57struct icu_casemap *icu_casemap_clone(struct icu_casemap *old)
58{
59    struct icu_casemap * casemap
60        = (struct icu_casemap *) xmalloc(sizeof(struct icu_casemap));
61    casemap->action = old->action;
62    return casemap;
63}
64
65void icu_casemap_destroy(struct icu_casemap * casemap)
66{
67    xfree(casemap);
68}
69
70int icu_casemap_casemap(struct icu_casemap *casemap,
71                        struct icu_buf_utf16 *dest16,
72                        struct icu_buf_utf16 *src16,
73                        UErrorCode *status,
74                        const char *locale)
75{
76    if (!casemap)
77        return 0;
78
79    return icu_utf16_casemap(dest16, src16, locale,
80                             casemap->action, status);
81}
82
83
84static uint32_t icu_utf16_sub(struct icu_buf_utf16 *dest16,
85                          struct icu_buf_utf16 *src16,
86                          const char *locale, char action,
87                          UErrorCode *status)
88{
89    switch (action)
90    {
91    case 'l':
92    case 'L':
93        return u_strToLower(dest16->utf16, dest16->utf16_cap,
94                            src16->utf16, src16->utf16_len,
95                            locale, status);
96    case 'u':
97    case 'U':
98        return u_strToUpper(dest16->utf16, dest16->utf16_cap,
99                            src16->utf16, src16->utf16_len,
100                            locale, status);
101        break;
102    case 't':
103    case 'T':
104        return u_strToTitle(dest16->utf16, dest16->utf16_cap,
105                            src16->utf16, src16->utf16_len,
106                            0, locale, status);
107        break;
108    case 'f':
109    case 'F':
110        return u_strFoldCase(dest16->utf16, dest16->utf16_cap,
111                             src16->utf16, src16->utf16_len,
112                             U_FOLD_CASE_DEFAULT, status);
113        break;
114    default:
115        *status = U_UNSUPPORTED_ERROR;
116        break;
117    }
118    return 0;
119}
120
121
122int icu_utf16_casemap(struct icu_buf_utf16 *dest16,
123                      struct icu_buf_utf16 *src16,
124                      const char *locale, char action,
125                      UErrorCode *status)
126{
127    int32_t dest16_len = 0;
128
129    if (!src16->utf16_len)
130    {           /* guarding for empty source string */
131        if (dest16->utf16)
132            dest16->utf16[0] = (UChar) 0;
133        dest16->utf16_len = 0;
134        return U_ZERO_ERROR;
135    }
136
137    dest16_len = icu_utf16_sub(dest16, src16, locale, action, status);
138
139    /* check for buffer overflow, resize and retry */
140    if (*status == U_BUFFER_OVERFLOW_ERROR
141        && dest16 != src16)      /* do not resize if in-place conversion */
142    {
143        icu_buf_utf16_resize(dest16, dest16_len * 2);
144        *status = U_ZERO_ERROR;
145
146        icu_utf16_sub(dest16, src16, locale, action, status);
147    }
148
149    if (U_SUCCESS(*status) && dest16_len <= dest16->utf16_cap)
150        dest16->utf16_len = dest16_len;
151    else
152    {
153        if (dest16->utf16)
154            dest16->utf16[0] = (UChar) 0;
155        dest16->utf16_len = 0;
156    }
157
158    return *status;
159}
160
161
162#endif /* YAZ_HAVE_ICU */
163
164/*
165 * Local variables:
166 * c-basic-offset: 4
167 * c-file-style: "Stroustrup"
168 * indent-tabs-mode: nil
169 * End:
170 * vim: shiftwidth=4 tabstop=8 expandtab
171 */
172
Note: See TracBrowser for help on using the repository browser.