• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 *******************************************************************************
3 *
4 *   Copyright (C) 1998-2006, International Business Machines
5 *   Corporation and others.  All Rights Reserved.
6 *
7 *******************************************************************************
8 *
9 * File ustr.c
10 *
11 * Modification History:
12 *
13 *   Date        Name        Description
14 *   05/28/99    stephen     Creation.
15 *******************************************************************************
16 */
17 
18 #include "ustr.h"
19 #include "cmemory.h"
20 #include "cstring.h"
21 #include "unicode/ustring.h"
22 #include "unicode/putil.h"
23 
24 /* Protos */
25 static void ustr_resize(struct UString *s, int32_t len, UErrorCode *status);
26 
27 /* Macros */
28 #define ALLOCATION(minSize) (minSize < 0x80 ? 0x80 : (2 * minSize + 0x80) & ~(0x80 - 1))
29 
30 void
ustr_init(struct UString * s)31 ustr_init(struct UString *s)
32 {
33     s->fChars = 0;
34     s->fLength = s->fCapacity = 0;
35 }
36 
37 void
ustr_initChars(struct UString * s,const char * source,int32_t length,UErrorCode * status)38 ustr_initChars(struct UString *s, const char* source, int32_t length, UErrorCode *status)
39 {
40     int i = 0;
41     if (U_FAILURE(*status)) return;
42     s->fChars = 0;
43     s->fLength = s->fCapacity = 0;
44     if (length == -1) {
45         length = (int32_t)uprv_strlen(source);
46     }
47     if(s->fCapacity < length) {
48       ustr_resize(s, ALLOCATION(length), status);
49       if(U_FAILURE(*status)) return;
50     }
51     for (; i < length; i++)
52     {
53       UChar charToAppend;
54       u_charsToUChars(source+i, &charToAppend, 1);
55       ustr_ucat(s, charToAppend, status);
56       /*
57 #if U_CHARSET_FAMILY==U_ASCII_FAMILY
58         ustr_ucat(s, (UChar)(uint8_t)(source[i]), status);
59 #elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY
60         ustr_ucat(s, (UChar)asciiFromEbcdic[(uint8_t)(*cs++)], status);
61 #else
62 #   error U_CHARSET_FAMILY is not valid
63 #endif
64       */
65     }
66 }
67 
68 void
ustr_deinit(struct UString * s)69 ustr_deinit(struct UString *s)
70 {
71     uprv_free(s->fChars);
72     s->fChars = 0;
73     s->fLength = s->fCapacity = 0;
74 }
75 
76 void
ustr_cpy(struct UString * dst,const struct UString * src,UErrorCode * status)77 ustr_cpy(struct UString *dst,
78      const struct UString *src,
79      UErrorCode *status)
80 {
81     if(U_FAILURE(*status) || dst == src)
82         return;
83 
84     if(dst->fCapacity < src->fLength) {
85         ustr_resize(dst, ALLOCATION(src->fLength), status);
86         if(U_FAILURE(*status))
87             return;
88     }
89     if(src->fChars == NULL || dst->fChars == NULL){
90         return;
91     }
92     uprv_memcpy(dst->fChars, src->fChars, sizeof(UChar) * src->fLength);
93     dst->fLength = src->fLength;
94     dst->fChars[dst->fLength] = 0x0000;
95 }
96 
97 void
ustr_setlen(struct UString * s,int32_t len,UErrorCode * status)98 ustr_setlen(struct UString *s,
99         int32_t len,
100         UErrorCode *status)
101 {
102     if(U_FAILURE(*status))
103         return;
104 
105     if(s->fCapacity < (len + 1)) {
106         ustr_resize(s, ALLOCATION(len), status);
107         if(U_FAILURE(*status))
108             return;
109     }
110 
111     s->fLength = len;
112     s->fChars[len] = 0x0000;
113 }
114 
115 void
ustr_cat(struct UString * dst,const struct UString * src,UErrorCode * status)116 ustr_cat(struct UString *dst,
117      const struct UString *src,
118      UErrorCode *status)
119 {
120     ustr_ncat(dst, src, src->fLength, status);
121 }
122 
123 void
ustr_ncat(struct UString * dst,const struct UString * src,int32_t n,UErrorCode * status)124 ustr_ncat(struct UString *dst,
125       const struct UString *src,
126       int32_t n,
127       UErrorCode *status)
128 {
129     if(U_FAILURE(*status) || dst == src)
130         return;
131 
132     if(dst->fCapacity < (dst->fLength + n)) {
133         ustr_resize(dst, ALLOCATION(dst->fLength + n), status);
134         if(U_FAILURE(*status))
135             return;
136     }
137 
138     uprv_memcpy(dst->fChars + dst->fLength, src->fChars,
139                 sizeof(UChar) * n);
140     dst->fLength += src->fLength;
141     dst->fChars[dst->fLength] = 0x0000;
142 }
143 
144 void
ustr_ucat(struct UString * dst,UChar c,UErrorCode * status)145 ustr_ucat(struct UString *dst,
146       UChar c,
147       UErrorCode *status)
148 {
149     if(U_FAILURE(*status))
150         return;
151 
152     if(dst->fCapacity < (dst->fLength + 1)) {
153         ustr_resize(dst, ALLOCATION(dst->fLength + 1), status);
154         if(U_FAILURE(*status))
155             return;
156     }
157 
158     uprv_memcpy(dst->fChars + dst->fLength, &c,
159         sizeof(UChar) * 1);
160     dst->fLength += 1;
161     dst->fChars[dst->fLength] = 0x0000;
162 }
163 void
ustr_u32cat(struct UString * dst,UChar32 c,UErrorCode * status)164 ustr_u32cat(struct UString *dst, UChar32 c, UErrorCode *status){
165     if(c > 0x10FFFF){
166         *status = U_ILLEGAL_CHAR_FOUND;
167         return;
168     }
169     if(c >0xFFFF){
170         ustr_ucat(dst, U16_LEAD(c), status);
171         ustr_ucat(dst, U16_TRAIL(c), status);
172     }else{
173         ustr_ucat(dst, (UChar) c, status);
174     }
175 }
176 void
ustr_uscat(struct UString * dst,const UChar * src,int len,UErrorCode * status)177 ustr_uscat(struct UString *dst,
178       const UChar* src,int len,
179       UErrorCode *status)
180 {
181     if(U_FAILURE(*status))
182         return;
183 
184     if(dst->fCapacity < (dst->fLength + len)) {
185         ustr_resize(dst, ALLOCATION(dst->fLength + len), status);
186         if(U_FAILURE(*status))
187             return;
188     }
189 
190     uprv_memcpy(dst->fChars + dst->fLength, src,
191         sizeof(UChar) * len);
192     dst->fLength += len;
193     dst->fChars[dst->fLength] = 0x0000;
194 }
195 
196 /* Destroys data in the string */
197 static void
ustr_resize(struct UString * s,int32_t len,UErrorCode * status)198 ustr_resize(struct UString *s,
199         int32_t len,
200         UErrorCode *status)
201 {
202     if(U_FAILURE(*status))
203         return;
204 
205     /* +1 for trailing 0x0000 */
206     s->fChars = (UChar*) uprv_realloc(s->fChars, sizeof(UChar) * (len + 1));
207     if(s->fChars == 0) {
208         *status = U_MEMORY_ALLOCATION_ERROR;
209         s->fLength = s->fCapacity = 0;
210         return;
211     }
212 
213     s->fCapacity = len;
214 }
215