Home | History | Annotate | Download | only in genrb
      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) & ~(0x80 - 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 }
    217