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