OLD | NEW |
(Empty) | |
| 1 /* |
| 2 ******************************************************************************* |
| 3 * |
| 4 * Copyright (C) 1998-2008, 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) & ~(0x
80 - 1)) |
| 29 |
| 30 void |
| 31 ustr_init(struct UString *s) |
| 32 { |
| 33 s->fChars = 0; |
| 34 s->fLength = s->fCapacity = 0; |
| 35 } |
| 36 |
| 37 void |
| 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 |
| 69 ustr_deinit(struct UString *s) |
| 70 { |
| 71 if (s) { |
| 72 uprv_free(s->fChars); |
| 73 s->fChars = 0; |
| 74 s->fLength = s->fCapacity = 0; |
| 75 } |
| 76 } |
| 77 |
| 78 void |
| 79 ustr_cpy(struct UString *dst, |
| 80 const struct UString *src, |
| 81 UErrorCode *status) |
| 82 { |
| 83 if(U_FAILURE(*status) || dst == src) |
| 84 return; |
| 85 |
| 86 if(dst->fCapacity < src->fLength) { |
| 87 ustr_resize(dst, ALLOCATION(src->fLength), status); |
| 88 if(U_FAILURE(*status)) |
| 89 return; |
| 90 } |
| 91 if(src->fChars == NULL || dst->fChars == NULL){ |
| 92 return; |
| 93 } |
| 94 uprv_memcpy(dst->fChars, src->fChars, sizeof(UChar) * src->fLength); |
| 95 dst->fLength = src->fLength; |
| 96 dst->fChars[dst->fLength] = 0x0000; |
| 97 } |
| 98 |
| 99 void |
| 100 ustr_setlen(struct UString *s, |
| 101 int32_t len, |
| 102 UErrorCode *status) |
| 103 { |
| 104 if(U_FAILURE(*status)) |
| 105 return; |
| 106 |
| 107 if(s->fCapacity < (len + 1)) { |
| 108 ustr_resize(s, ALLOCATION(len), status); |
| 109 if(U_FAILURE(*status)) |
| 110 return; |
| 111 } |
| 112 |
| 113 s->fLength = len; |
| 114 s->fChars[len] = 0x0000; |
| 115 } |
| 116 |
| 117 void |
| 118 ustr_cat(struct UString *dst, |
| 119 const struct UString *src, |
| 120 UErrorCode *status) |
| 121 { |
| 122 ustr_ncat(dst, src, src->fLength, status); |
| 123 } |
| 124 |
| 125 void |
| 126 ustr_ncat(struct UString *dst, |
| 127 const struct UString *src, |
| 128 int32_t n, |
| 129 UErrorCode *status) |
| 130 { |
| 131 if(U_FAILURE(*status) || dst == src) |
| 132 return; |
| 133 |
| 134 if(dst->fCapacity < (dst->fLength + n)) { |
| 135 ustr_resize(dst, ALLOCATION(dst->fLength + n), status); |
| 136 if(U_FAILURE(*status)) |
| 137 return; |
| 138 } |
| 139 |
| 140 uprv_memcpy(dst->fChars + dst->fLength, src->fChars, |
| 141 sizeof(UChar) * n); |
| 142 dst->fLength += src->fLength; |
| 143 dst->fChars[dst->fLength] = 0x0000; |
| 144 } |
| 145 |
| 146 void |
| 147 ustr_ucat(struct UString *dst, |
| 148 UChar c, |
| 149 UErrorCode *status) |
| 150 { |
| 151 if(U_FAILURE(*status)) |
| 152 return; |
| 153 |
| 154 if(dst->fCapacity < (dst->fLength + 1)) { |
| 155 ustr_resize(dst, ALLOCATION(dst->fLength + 1), status); |
| 156 if(U_FAILURE(*status)) |
| 157 return; |
| 158 } |
| 159 |
| 160 uprv_memcpy(dst->fChars + dst->fLength, &c, |
| 161 sizeof(UChar) * 1); |
| 162 dst->fLength += 1; |
| 163 dst->fChars[dst->fLength] = 0x0000; |
| 164 } |
| 165 void |
| 166 ustr_u32cat(struct UString *dst, UChar32 c, UErrorCode *status){ |
| 167 if(c > 0x10FFFF){ |
| 168 *status = U_ILLEGAL_CHAR_FOUND; |
| 169 return; |
| 170 } |
| 171 if(c >0xFFFF){ |
| 172 ustr_ucat(dst, U16_LEAD(c), status); |
| 173 ustr_ucat(dst, U16_TRAIL(c), status); |
| 174 }else{ |
| 175 ustr_ucat(dst, (UChar) c, status); |
| 176 } |
| 177 } |
| 178 void |
| 179 ustr_uscat(struct UString *dst, |
| 180 const UChar* src,int len, |
| 181 UErrorCode *status) |
| 182 { |
| 183 if(U_FAILURE(*status)) |
| 184 return; |
| 185 |
| 186 if(dst->fCapacity < (dst->fLength + len)) { |
| 187 ustr_resize(dst, ALLOCATION(dst->fLength + len), status); |
| 188 if(U_FAILURE(*status)) |
| 189 return; |
| 190 } |
| 191 |
| 192 uprv_memcpy(dst->fChars + dst->fLength, src, |
| 193 sizeof(UChar) * len); |
| 194 dst->fLength += len; |
| 195 dst->fChars[dst->fLength] = 0x0000; |
| 196 } |
| 197 |
| 198 /* Destroys data in the string */ |
| 199 static void |
| 200 ustr_resize(struct UString *s, |
| 201 int32_t len, |
| 202 UErrorCode *status) |
| 203 { |
| 204 if(U_FAILURE(*status)) |
| 205 return; |
| 206 |
| 207 /* +1 for trailing 0x0000 */ |
| 208 s->fChars = (UChar*) uprv_realloc(s->fChars, sizeof(UChar) * (len + 1)); |
| 209 if(s->fChars == 0) { |
| 210 *status = U_MEMORY_ALLOCATION_ERROR; |
| 211 s->fLength = s->fCapacity = 0; |
| 212 return; |
| 213 } |
| 214 |
| 215 s->fCapacity = len; |
| 216 } |
OLD | NEW |