tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ustr.c (5267B)


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