intl/icu/source/common/ustr_cnv.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /*
     2 *******************************************************************************
     3 *
     4 *   Copyright (C) 1998-2013, International Business Machines
     5 *   Corporation and others.  All Rights Reserved.
     6 *
     7 *******************************************************************************
     8 *   file name:  ustr_cnv.c
     9 *   encoding:   US-ASCII
    10 *   tab size:   8 (not used)
    11 *   indentation:4
    12 *
    13 *   created on: 2004aug24
    14 *   created by: Markus W. Scherer
    15 *
    16 *   Character conversion functions moved here from ustring.c
    17 */
    19 #include "unicode/utypes.h"
    21 #if !UCONFIG_NO_CONVERSION
    23 #include "unicode/ustring.h"
    24 #include "unicode/ucnv.h"
    25 #include "cstring.h"
    26 #include "cmemory.h"
    27 #include "cmutex.h"
    28 #include "ustr_cnv.h"
    30 /* mutexed access to a shared default converter ----------------------------- */
    32 static UConverter *gDefaultConverter = NULL;
    34 U_CAPI UConverter* U_EXPORT2
    35 u_getDefaultConverter(UErrorCode *status)
    36 {
    37     UConverter *converter = NULL;
    39     if (gDefaultConverter != NULL) {
    40         umtx_lock(NULL);
    42         /* need to check to make sure it wasn't taken out from under us */
    43         if (gDefaultConverter != NULL) {
    44             converter = gDefaultConverter;
    45             gDefaultConverter = NULL;
    46         }
    47         umtx_unlock(NULL);
    48     }
    50     /* if the cache was empty, create a converter */
    51     if(converter == NULL) {
    52         converter = ucnv_open(NULL, status);
    53         if(U_FAILURE(*status)) {
    54             ucnv_close(converter);
    55             converter = NULL;
    56         }
    57     }
    59     return converter;
    60 }
    62 U_CAPI void U_EXPORT2
    63 u_releaseDefaultConverter(UConverter *converter)
    64 {
    65     if(gDefaultConverter == NULL) {
    66         if (converter != NULL) {
    67             ucnv_reset(converter);
    68         }
    69         umtx_lock(NULL);
    71         if(gDefaultConverter == NULL) {
    72             gDefaultConverter = converter;
    73             converter = NULL;
    74         }
    75         umtx_unlock(NULL);
    76     }
    78     if(converter != NULL) {
    79         ucnv_close(converter);
    80     }
    81 }
    83 U_CAPI void U_EXPORT2
    84 u_flushDefaultConverter()
    85 {
    86     UConverter *converter = NULL;
    88     if (gDefaultConverter != NULL) {
    89         umtx_lock(NULL);
    91         /* need to check to make sure it wasn't taken out from under us */
    92         if (gDefaultConverter != NULL) {
    93             converter = gDefaultConverter;
    94             gDefaultConverter = NULL;
    95         }
    96         umtx_unlock(NULL);
    97     }
    99     /* if the cache was populated, flush it */
   100     if(converter != NULL) {
   101          ucnv_close(converter);
   102     }
   103 }
   106 /* conversions between char* and UChar* ------------------------------------- */
   108 /* maximum string length for u_uastrcpy() and u_austrcpy() implementations */
   109 #define MAX_STRLEN 0x0FFFFFFF
   111 /*
   112  returns the minimum of (the length of the null-terminated string) and n.
   113 */
   114 static int32_t u_astrnlen(const char *s1, int32_t n)
   115 {
   116     int32_t len = 0;
   118     if (s1)
   119     {
   120         while (n-- && *(s1++))
   121         {
   122             len++;
   123         }
   124     }
   125     return len;
   126 }
   128 U_CAPI UChar*  U_EXPORT2
   129 u_uastrncpy(UChar *ucs1,
   130            const char *s2,
   131            int32_t n)
   132 {
   133   UChar *target = ucs1;
   134   UErrorCode err = U_ZERO_ERROR;
   135   UConverter *cnv = u_getDefaultConverter(&err);
   136   if(U_SUCCESS(err) && cnv != NULL) {
   137     ucnv_reset(cnv);
   138     ucnv_toUnicode(cnv,
   139                    &target,
   140                    ucs1+n,
   141                    &s2,
   142                    s2+u_astrnlen(s2, n),
   143                    NULL,
   144                    TRUE,
   145                    &err);
   146     ucnv_reset(cnv); /* be good citizens */
   147     u_releaseDefaultConverter(cnv);
   148     if(U_FAILURE(err) && (err != U_BUFFER_OVERFLOW_ERROR) ) {
   149       *ucs1 = 0; /* failure */
   150     }
   151     if(target < (ucs1+n)) { /* U_BUFFER_OVERFLOW_ERROR isn't an err, just means no termination will happen. */
   152       *target = 0;  /* terminate */
   153     }
   154   } else {
   155     *ucs1 = 0;
   156   }
   157   return ucs1;
   158 }
   160 U_CAPI UChar*  U_EXPORT2
   161 u_uastrcpy(UChar *ucs1,
   162           const char *s2 )
   163 {
   164   UErrorCode err = U_ZERO_ERROR;
   165   UConverter *cnv = u_getDefaultConverter(&err);
   166   if(U_SUCCESS(err) && cnv != NULL) {
   167     ucnv_toUChars(cnv,
   168                     ucs1,
   169                     MAX_STRLEN,
   170                     s2,
   171                     (int32_t)uprv_strlen(s2),
   172                     &err);
   173     u_releaseDefaultConverter(cnv);
   174     if(U_FAILURE(err)) {
   175       *ucs1 = 0;
   176     }
   177   } else {
   178     *ucs1 = 0;
   179   }
   180   return ucs1;
   181 }
   183 /*
   184  returns the minimum of (the length of the null-terminated string) and n.
   185 */
   186 static int32_t u_ustrnlen(const UChar *ucs1, int32_t n)
   187 {
   188     int32_t len = 0;
   190     if (ucs1)
   191     {
   192         while (n-- && *(ucs1++))
   193         {
   194             len++;
   195         }
   196     }
   197     return len;
   198 }
   200 U_CAPI char*  U_EXPORT2
   201 u_austrncpy(char *s1,
   202         const UChar *ucs2,
   203         int32_t n)
   204 {
   205   char *target = s1;
   206   UErrorCode err = U_ZERO_ERROR;
   207   UConverter *cnv = u_getDefaultConverter(&err);
   208   if(U_SUCCESS(err) && cnv != NULL) {
   209     ucnv_reset(cnv);
   210     ucnv_fromUnicode(cnv,
   211                   &target,
   212                   s1+n,
   213                   &ucs2,
   214                   ucs2+u_ustrnlen(ucs2, n),
   215                   NULL,
   216                   TRUE,
   217                   &err);
   218     ucnv_reset(cnv); /* be good citizens */
   219     u_releaseDefaultConverter(cnv);
   220     if(U_FAILURE(err) && (err != U_BUFFER_OVERFLOW_ERROR) ) {
   221       *s1 = 0; /* failure */
   222     }
   223     if(target < (s1+n)) { /* U_BUFFER_OVERFLOW_ERROR isn't an err, just means no termination will happen. */
   224       *target = 0;  /* terminate */
   225     }
   226   } else {
   227     *s1 = 0;
   228   }
   229   return s1;
   230 }
   232 U_CAPI char*  U_EXPORT2
   233 u_austrcpy(char *s1,
   234          const UChar *ucs2 )
   235 {
   236   UErrorCode err = U_ZERO_ERROR;
   237   UConverter *cnv = u_getDefaultConverter(&err);
   238   if(U_SUCCESS(err) && cnv != NULL) {
   239     int32_t len = ucnv_fromUChars(cnv,
   240                   s1,
   241                   MAX_STRLEN,
   242                   ucs2,
   243                   -1,
   244                   &err);
   245     u_releaseDefaultConverter(cnv);
   246     s1[len] = 0;
   247   } else {
   248     *s1 = 0;
   249   }
   250   return s1;
   251 }
   253 #endif

mercurial