LCOV - code coverage report
Current view: top level - intl/icu/source/common - ustr_cnv.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 106 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 9 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13