LCOV - code coverage report
Current view: top level - intl/icu/source/i18n - numsys.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 161 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 27 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             : * Copyright (C) 2010-2015, International Business Machines Corporation and
       6             : * others. All Rights Reserved.
       7             : *******************************************************************************
       8             : *
       9             : *
      10             : * File NUMSYS.CPP
      11             : *
      12             : * Modification History:*
      13             : *   Date        Name        Description
      14             : *
      15             : ********************************************************************************
      16             : */
      17             : 
      18             : #include "unicode/utypes.h"
      19             : #include "unicode/localpointer.h"
      20             : #include "unicode/uchar.h"
      21             : #include "unicode/unistr.h"
      22             : #include "unicode/ures.h"
      23             : #include "unicode/ustring.h"
      24             : #include "unicode/uloc.h"
      25             : #include "unicode/schriter.h"
      26             : #include "unicode/numsys.h"
      27             : #include "cstring.h"
      28             : #include "uresimp.h"
      29             : #include "numsys_impl.h"
      30             : 
      31             : #if !UCONFIG_NO_FORMATTING
      32             : 
      33             : U_NAMESPACE_BEGIN
      34             : 
      35             : // Useful constants
      36             : 
      37             : #define DEFAULT_DIGITS UNICODE_STRING_SIMPLE("0123456789");
      38             : static const char gNumberingSystems[] = "numberingSystems";
      39             : static const char gNumberElements[] = "NumberElements";
      40             : static const char gDefault[] = "default";
      41             : static const char gNative[] = "native";
      42             : static const char gTraditional[] = "traditional";
      43             : static const char gFinance[] = "finance";
      44             : static const char gDesc[] = "desc";
      45             : static const char gRadix[] = "radix";
      46             : static const char gAlgorithmic[] = "algorithmic";
      47             : static const char gLatn[] = "latn";
      48             : 
      49             : 
      50           0 : UOBJECT_DEFINE_RTTI_IMPLEMENTATION(NumberingSystem)
      51           0 : UOBJECT_DEFINE_RTTI_IMPLEMENTATION(NumsysNameEnumeration)
      52             : 
      53             :     /**
      54             :      * Default Constructor.
      55             :      *
      56             :      * @draft ICU 4.2
      57             :      */
      58             : 
      59           0 : NumberingSystem::NumberingSystem() {
      60           0 :      radix = 10;
      61           0 :      algorithmic = FALSE;
      62           0 :      UnicodeString defaultDigits = DEFAULT_DIGITS;
      63           0 :      desc.setTo(defaultDigits);
      64           0 :      uprv_strcpy(name,gLatn);
      65           0 : }
      66             : 
      67             :     /**
      68             :      * Copy constructor.
      69             :      * @draft ICU 4.2
      70             :      */
      71             : 
      72           0 : NumberingSystem::NumberingSystem(const NumberingSystem& other) 
      73           0 : :  UObject(other) {
      74           0 :     *this=other;
      75           0 : }
      76             : 
      77             : NumberingSystem* U_EXPORT2
      78           0 : NumberingSystem::createInstance(int32_t radix_in, UBool isAlgorithmic_in, const UnicodeString & desc_in, UErrorCode &status) {
      79             : 
      80           0 :     if (U_FAILURE(status)) {
      81           0 :         return NULL;
      82             :     }
      83             : 
      84           0 :     if ( radix_in < 2 ) {
      85           0 :         status = U_ILLEGAL_ARGUMENT_ERROR;
      86           0 :         return NULL;
      87             :     }
      88             : 
      89           0 :     if ( !isAlgorithmic_in ) {
      90           0 :        if ( desc_in.countChar32() != radix_in ) {
      91           0 :            status = U_ILLEGAL_ARGUMENT_ERROR;
      92           0 :            return NULL;
      93             :        }
      94             :     }
      95             : 
      96           0 :     NumberingSystem *ns = new NumberingSystem();
      97             : 
      98           0 :     ns->setRadix(radix_in);
      99           0 :     ns->setDesc(desc_in);
     100           0 :     ns->setAlgorithmic(isAlgorithmic_in);
     101           0 :     ns->setName(NULL);
     102           0 :     return ns;
     103             :     
     104             : }
     105             : 
     106             : 
     107             : NumberingSystem* U_EXPORT2
     108           0 : NumberingSystem::createInstance(const Locale & inLocale, UErrorCode& status) {
     109             : 
     110           0 :     if (U_FAILURE(status)) {
     111           0 :         return NULL;
     112             :     }
     113             : 
     114           0 :     UBool nsResolved = TRUE;
     115           0 :     UBool usingFallback = FALSE;
     116             :     char buffer[ULOC_KEYWORDS_CAPACITY];
     117           0 :     int32_t count = inLocale.getKeywordValue("numbers",buffer, sizeof(buffer),status);
     118           0 :     if ( count > 0 ) { // @numbers keyword was specified in the locale
     119           0 :         buffer[count] = '\0'; // Make sure it is null terminated.
     120           0 :         if ( !uprv_strcmp(buffer,gDefault) || !uprv_strcmp(buffer,gNative) || 
     121           0 :              !uprv_strcmp(buffer,gTraditional) || !uprv_strcmp(buffer,gFinance)) {
     122           0 :             nsResolved = FALSE;
     123             :         }
     124             :     } else {
     125           0 :         uprv_strcpy(buffer,gDefault);
     126           0 :         nsResolved = FALSE;
     127             :     }
     128             : 
     129           0 :     if (!nsResolved) { // Resolve the numbering system ( default, native, traditional or finance ) into a "real" numbering system
     130           0 :         UErrorCode localStatus = U_ZERO_ERROR;
     131           0 :         UResourceBundle *resource = ures_open(NULL, inLocale.getName(), &localStatus);
     132           0 :         UResourceBundle *numberElementsRes = ures_getByKey(resource,gNumberElements,NULL,&localStatus);
     133           0 :         while (!nsResolved) {
     134           0 :             localStatus = U_ZERO_ERROR;
     135           0 :             count = 0;
     136           0 :             const UChar *nsName = ures_getStringByKeyWithFallback(numberElementsRes, buffer, &count, &localStatus);
     137           0 :             if ( count > 0 && count < ULOC_KEYWORDS_CAPACITY ) { // numbering system found
     138           0 :                 u_UCharsToChars(nsName,buffer,count); 
     139           0 :                 buffer[count] = '\0'; // Make sure it is null terminated.
     140           0 :                 nsResolved = TRUE;
     141             :             } 
     142             : 
     143           0 :             if (!nsResolved) { // Fallback behavior per TR35 - traditional falls back to native, finance and native fall back to default
     144           0 :                 if (!uprv_strcmp(buffer,gNative) || !uprv_strcmp(buffer,gFinance)) { 
     145           0 :                     uprv_strcpy(buffer,gDefault);
     146           0 :                 } else if (!uprv_strcmp(buffer,gTraditional)) {
     147           0 :                     uprv_strcpy(buffer,gNative);
     148             :                 } else { // If we get here we couldn't find even the default numbering system
     149           0 :                     usingFallback = TRUE;
     150           0 :                     nsResolved = TRUE;
     151             :                 }
     152             :             }
     153             :         }
     154           0 :         ures_close(numberElementsRes);
     155           0 :         ures_close(resource);
     156             :     }
     157             : 
     158           0 :     if (usingFallback) {
     159           0 :         status = U_USING_FALLBACK_WARNING;
     160           0 :         NumberingSystem *ns = new NumberingSystem();
     161           0 :         return ns;
     162             :     } else {
     163           0 :         return NumberingSystem::createInstanceByName(buffer,status);
     164             :     }
     165             :  }
     166             : 
     167             : NumberingSystem* U_EXPORT2
     168           0 : NumberingSystem::createInstance(UErrorCode& status) {
     169           0 :     return NumberingSystem::createInstance(Locale::getDefault(), status);
     170             : }
     171             : 
     172             : NumberingSystem* U_EXPORT2
     173           0 : NumberingSystem::createInstanceByName(const char *name, UErrorCode& status) {
     174           0 :     UResourceBundle *numberingSystemsInfo = NULL;
     175             :     UResourceBundle *nsTop, *nsCurrent;
     176           0 :     int32_t radix = 10;
     177           0 :     int32_t algorithmic = 0;
     178             : 
     179           0 :     numberingSystemsInfo = ures_openDirect(NULL,gNumberingSystems, &status);
     180           0 :     nsCurrent = ures_getByKey(numberingSystemsInfo,gNumberingSystems,NULL,&status);
     181           0 :     nsTop = ures_getByKey(nsCurrent,name,NULL,&status);
     182           0 :     UnicodeString nsd = ures_getUnicodeStringByKey(nsTop,gDesc,&status);
     183             : 
     184           0 :     ures_getByKey(nsTop,gRadix,nsCurrent,&status);
     185           0 :     radix = ures_getInt(nsCurrent,&status);
     186             : 
     187           0 :     ures_getByKey(nsTop,gAlgorithmic,nsCurrent,&status);
     188           0 :     algorithmic = ures_getInt(nsCurrent,&status);
     189             : 
     190           0 :     UBool isAlgorithmic = ( algorithmic == 1 );
     191             : 
     192           0 :     ures_close(nsCurrent);
     193           0 :     ures_close(nsTop);
     194           0 :     ures_close(numberingSystemsInfo);
     195             : 
     196           0 :     if (U_FAILURE(status)) {
     197           0 :         status = U_UNSUPPORTED_ERROR;
     198           0 :         return NULL;
     199             :     }
     200             : 
     201           0 :     NumberingSystem* ns = NumberingSystem::createInstance(radix,isAlgorithmic,nsd,status);
     202           0 :     ns->setName(name);
     203           0 :     return ns;
     204             : }
     205             : 
     206             :     /**
     207             :      * Destructor.
     208             :      * @draft ICU 4.2
     209             :      */
     210           0 : NumberingSystem::~NumberingSystem() {
     211           0 : }
     212             : 
     213           0 : int32_t NumberingSystem::getRadix() const {
     214           0 :     return radix;
     215             : }
     216             : 
     217           0 : UnicodeString NumberingSystem::getDescription() const {
     218           0 :     return desc;
     219             : }
     220             : 
     221           0 : const char * NumberingSystem::getName() const {
     222           0 :     return name;
     223             : }
     224             : 
     225           0 : void NumberingSystem::setRadix(int32_t r) {
     226           0 :     radix = r;
     227           0 : }
     228             : 
     229           0 : void NumberingSystem::setAlgorithmic(UBool c) {
     230           0 :     algorithmic = c;
     231           0 : }
     232             : 
     233           0 : void NumberingSystem::setDesc(const UnicodeString &d) {
     234           0 :     desc.setTo(d);
     235           0 : }
     236           0 : void NumberingSystem::setName(const char *n) {
     237           0 :     if ( n == NULL ) {
     238           0 :         name[0] = (char) 0;
     239             :     } else {
     240           0 :         uprv_strncpy(name,n,NUMSYS_NAME_CAPACITY);
     241           0 :         name[NUMSYS_NAME_CAPACITY] = (char)0; // Make sure it is null terminated.
     242             :     }
     243           0 : }
     244           0 : UBool NumberingSystem::isAlgorithmic() const {
     245           0 :     return ( algorithmic );
     246             : }
     247             : 
     248           0 : StringEnumeration* NumberingSystem::getAvailableNames(UErrorCode &status) {
     249             :     // TODO(ticket #11908): Init-once static cache, with u_cleanup() callback.
     250             :     static StringEnumeration* availableNames = NULL;
     251             : 
     252           0 :     if (U_FAILURE(status)) {
     253           0 :         return NULL;
     254             :     }
     255             : 
     256           0 :     if ( availableNames == NULL ) {
     257             :         // TODO: Simple array of UnicodeString objects, based on length of table resource?
     258           0 :         LocalPointer<UVector> numsysNames(new UVector(uprv_deleteUObject, NULL, status), status);
     259           0 :         if (U_FAILURE(status)) {
     260           0 :             return NULL;
     261             :         }
     262             :         
     263           0 :         UErrorCode rbstatus = U_ZERO_ERROR;
     264           0 :         UResourceBundle *numberingSystemsInfo = ures_openDirect(NULL, "numberingSystems", &rbstatus);
     265           0 :         numberingSystemsInfo = ures_getByKey(numberingSystemsInfo,"numberingSystems",numberingSystemsInfo,&rbstatus);
     266           0 :         if(U_FAILURE(rbstatus)) {
     267           0 :             status = U_MISSING_RESOURCE_ERROR;
     268           0 :             ures_close(numberingSystemsInfo);
     269           0 :             return NULL;
     270             :         }
     271             : 
     272           0 :         while ( ures_hasNext(numberingSystemsInfo) ) {
     273           0 :             UResourceBundle *nsCurrent = ures_getNextResource(numberingSystemsInfo,NULL,&rbstatus);
     274           0 :             const char *nsName = ures_getKey(nsCurrent);
     275           0 :             numsysNames->addElement(new UnicodeString(nsName, -1, US_INV),status);
     276           0 :             ures_close(nsCurrent);
     277             :         }
     278             : 
     279           0 :         ures_close(numberingSystemsInfo);
     280           0 :         if (U_FAILURE(status)) {
     281           0 :             return NULL;
     282             :         }
     283           0 :         availableNames = new NumsysNameEnumeration(numsysNames.getAlias(), status);
     284           0 :         if (availableNames == NULL) {
     285           0 :             status = U_MEMORY_ALLOCATION_ERROR;
     286           0 :             return NULL;
     287             :         }
     288           0 :         numsysNames.orphan();  // The names got adopted.
     289             :     }
     290             : 
     291           0 :     return availableNames;
     292             : }
     293             : 
     294           0 : NumsysNameEnumeration::NumsysNameEnumeration(UVector *numsysNames, UErrorCode& /*status*/) {
     295           0 :     pos=0;
     296           0 :     fNumsysNames = numsysNames;
     297           0 : }
     298             : 
     299             : const UnicodeString*
     300           0 : NumsysNameEnumeration::snext(UErrorCode& status) {
     301           0 :     if (U_SUCCESS(status) && pos < fNumsysNames->size()) {
     302           0 :         return (const UnicodeString*)fNumsysNames->elementAt(pos++);
     303             :     }
     304           0 :     return NULL;
     305             : }
     306             : 
     307             : void
     308           0 : NumsysNameEnumeration::reset(UErrorCode& /*status*/) {
     309           0 :     pos=0;
     310           0 : }
     311             : 
     312             : int32_t
     313           0 : NumsysNameEnumeration::count(UErrorCode& /*status*/) const {
     314           0 :     return (fNumsysNames==NULL) ? 0 : fNumsysNames->size();
     315             : }
     316             : 
     317           0 : NumsysNameEnumeration::~NumsysNameEnumeration() {
     318           0 :     delete fNumsysNames;
     319           0 : }
     320             : U_NAMESPACE_END
     321             : 
     322             : #endif /* #if !UCONFIG_NO_FORMATTING */
     323             : 
     324             : //eof

Generated by: LCOV version 1.13