Logo Search packages:      
Sourcecode: icu version File versions  Download package

U_STABLE int32_t U_EXPORT2 uloc_getDisplayName ( const char *  localeID,
const char *  inLocaleID,
UChar *  result,
int32_t  maxResultSize,
UErrorCode err 
)

Gets the full name suitable for display for the specified locale.

Parameters:
localeID the locale to get the displayable name with. NULL may be used to specify the default.
inLocaleID Specifies the locale to be used to display the name. In other words, if the locale's language code is "en", passing Locale::getFrench() for inLocale would result in "Anglais", while passing Locale::getGerman() for inLocale would result in "Englisch". NULL may be used to specify the default.
result the displayable name for localeID
maxResultSize the size of the name buffer to store the displayable full name with
err error information if retrieving the displayable name failed
Returns:
the actual buffer size needed for the displayable name. If it's greater than maxResultSize, the returned displayable name will be truncated. ICU 2.0

Definition at line 431 of file locdispnames.cpp.

References NULL, U_BUFFER_OVERFLOW_ERROR, U_FAILURE, U_ILLEGAL_ARGUMENT_ERROR, and U_ZERO_ERROR.

{
    int32_t length, length2, length3 = 0;
    UBool hasLanguage, hasScript, hasCountry, hasVariant, hasKeywords;
    UEnumeration* keywordEnum = NULL;
    int32_t keywordCount = 0;
    const char *keyword = NULL;
    int32_t keywordLen = 0;
    char keywordValue[256];
    int32_t keywordValueLen = 0;

    int32_t locSepLen = 0;
    int32_t locPatLen = 0;
    int32_t p0Len = 0;
    int32_t defaultPatternLen = 9;
    const UChar *dispLocSeparator;
    const UChar *dispLocPattern;
    static const UChar defaultSeparator[3] = { 0x002c, 0x0020 , 0x0000 }; /* comma + space */
    static const UChar defaultPattern[10] = { 0x007b, 0x0030, 0x007d, 0x0020, 0x0028, 0x007b, 0x0031, 0x007d, 0x0029, 0x0000 }; /* {0} ({1}) */
    static const UChar pat0[4] = { 0x007b, 0x0030, 0x007d , 0x0000 } ; /* {0} */
    static const UChar pat1[4] = { 0x007b, 0x0031, 0x007d , 0x0000 } ; /* {1} */
    
    UResourceBundle *bundle = NULL;
    UResourceBundle *locdsppat = NULL;
    
    UErrorCode status = U_ZERO_ERROR;

    /* argument checking */
    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
        return 0;
    }

    if(destCapacity<0 || (destCapacity>0 && dest==NULL)) {
        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
        return 0;
    }

    bundle    = ures_open(U_ICUDATA_LANG, displayLocale, &status);

    locdsppat = ures_getByKeyWithFallback(bundle, _kLocaleDisplayPattern, NULL, &status);
    dispLocSeparator = ures_getStringByKeyWithFallback(locdsppat, _kSeparator, &locSepLen, &status);
    dispLocPattern = ures_getStringByKeyWithFallback(locdsppat, _kPattern, &locPatLen, &status);
        
    /*close the bundles */
    ures_close(locdsppat);
    ures_close(bundle);

    /* If we couldn't find any data, then use the defaults */
    if ( locSepLen == 0) {
       dispLocSeparator = defaultSeparator;
       locSepLen = 2;
    }

    if ( locPatLen == 0) {
       dispLocPattern = defaultPattern;
       locPatLen = 9;
    }

    /*
     * if there is a language, then write "language (country, variant)"
     * otherwise write "country, variant"
     */

    /* write the language */
    length=uloc_getDisplayLanguage(locale, displayLocale,
                                   dest, destCapacity,
                                   pErrorCode);
    hasLanguage= length>0;

    if(hasLanguage) {
        p0Len = length;

        /* append " (" */
        if(length<destCapacity) {
            dest[length]=0x20;
        }
        ++length;
        if(length<destCapacity) {
            dest[length]=0x28;
        }
        ++length;
    }

    if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) {
        /* keep preflighting */
        *pErrorCode=U_ZERO_ERROR;
    }

    /* append the script */
    if(length<destCapacity) {
        length2=uloc_getDisplayScript(locale, displayLocale,
                                       dest+length, destCapacity-length,
                                       pErrorCode);
    } else {
        length2=uloc_getDisplayScript(locale, displayLocale,
                                       NULL, 0,
                                       pErrorCode);
    }
    hasScript= length2>0;
    length+=length2;

    if(hasScript) {
        /* append separator */
        if(length+locSepLen<=destCapacity) {
            u_memcpy(dest+length,dispLocSeparator,locSepLen);
        }
        length+=locSepLen;
    }

    if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) {
        /* keep preflighting */
        *pErrorCode=U_ZERO_ERROR;
    }

    /* append the country */
    if(length<destCapacity) {
        length2=uloc_getDisplayCountry(locale, displayLocale,
                                       dest+length, destCapacity-length,
                                       pErrorCode);
    } else {
        length2=uloc_getDisplayCountry(locale, displayLocale,
                                       NULL, 0,
                                       pErrorCode);
    }
    hasCountry= length2>0;
    length+=length2;

    if(hasCountry) {
        /* append separator */
        if(length+locSepLen<=destCapacity) {
            u_memcpy(dest+length,dispLocSeparator,locSepLen);
        }
        length+=locSepLen;
    }

    if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) {
        /* keep preflighting */
        *pErrorCode=U_ZERO_ERROR;
    }

    /* append the variant */
    if(length<destCapacity) {
        length2=uloc_getDisplayVariant(locale, displayLocale,
                                       dest+length, destCapacity-length,
                                       pErrorCode);
    } else {
        length2=uloc_getDisplayVariant(locale, displayLocale,
                                       NULL, 0,
                                       pErrorCode);
    }
    hasVariant= length2>0;
    length+=length2;

    if(hasVariant) {
        /* append separator */
        if(length+locSepLen<=destCapacity) {
            u_memcpy(dest+length,dispLocSeparator,locSepLen);
        }
        length+=locSepLen;
    }

    keywordEnum = uloc_openKeywords(locale, pErrorCode);
    
    for(keywordCount = uenum_count(keywordEnum, pErrorCode); keywordCount > 0 ; keywordCount--){
          if(U_FAILURE(*pErrorCode)){
              break;
          }
          /* the uenum_next returns NUL terminated string */
          keyword = uenum_next(keywordEnum, &keywordLen, pErrorCode);
          if(length + length3 < destCapacity) {
            length3 += uloc_getDisplayKeyword(keyword, displayLocale, dest+length+length3, destCapacity-length-length3, pErrorCode);
          } else {
            length3 += uloc_getDisplayKeyword(keyword, displayLocale, NULL, 0, pErrorCode);
          }
          if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) {
              /* keep preflighting */
              *pErrorCode=U_ZERO_ERROR;
          }
          keywordValueLen = uloc_getKeywordValue(locale, keyword, keywordValue, 256, pErrorCode);
          if(keywordValueLen) {
            if(length + length3 < destCapacity) {
              dest[length + length3] = 0x3D;
            }
            length3++;
            if(length + length3 < destCapacity) {
              length3 += uloc_getDisplayKeywordValue(locale, keyword, displayLocale, dest+length+length3, destCapacity-length-length3, pErrorCode);
            } else {
              length3 += uloc_getDisplayKeywordValue(locale, keyword, displayLocale, NULL, 0, pErrorCode);
            }
            if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) {
                /* keep preflighting */
                *pErrorCode=U_ZERO_ERROR;
            }
          }
          if(keywordCount > 1) {
              if(length + length3 + locSepLen <= destCapacity && keywordCount) {
                  u_memcpy(dest+length+length3,dispLocSeparator,locSepLen);
                  length3+=locSepLen;
              }
          }
    }
    uenum_close(keywordEnum);

    hasKeywords = length3 > 0;
    length += length3;


    if ((hasScript && !hasCountry)
        || ((hasScript || hasCountry) && !hasVariant && !hasKeywords)
        || ((hasScript || hasCountry || hasVariant) && !hasKeywords)) {
        /* Remove separator  */
        length -= locSepLen;
    } else if (hasLanguage && !hasScript && !hasCountry && !hasVariant && !hasKeywords) {
        /* Remove " (" */
        length-=2;
    }

    if (hasLanguage && (hasScript || hasCountry || hasVariant || hasKeywords)) {
        /* append ")" */
        if(length<destCapacity) {
            dest[length]=0x29;
        }
        ++length;

        /* If the localized display pattern is something other than the default pattern of "{0} ({1})", then
         * then we need to do the formatting here.  It would be easier to use a messageFormat to do this, but we
         * can't since we don't have the APIs in the i18n library available to us at this point.
         */
        if (locPatLen != defaultPatternLen || u_strcmp(dispLocPattern,defaultPattern)) { /* Something other than the default pattern */
           UChar *p0 = u_strstr(dispLocPattern,pat0);
           UChar *p1 = u_strstr(dispLocPattern,pat1);
           u_terminateUChars(dest, destCapacity, length, pErrorCode);

           if ( p0 != NULL && p1 != NULL ) { /* The pattern is well formed */
              if ( dest ) {
                  int32_t destLen = 0;
                  UChar *result = (UChar *)uprv_malloc((length+1)*sizeof(UChar));
                  UChar *upos = (UChar *)dispLocPattern;
                  u_strcpy(result,dest);
                  dest[0] = 0;
                  while ( *upos ) {
                     if ( upos == p0 ) { /* Handle {0} substitution */
                         u_strncat(dest,result,p0Len);
                         destLen += p0Len;
                         dest[destLen] = 0; /* Null terminate */
                         upos += 3;
                     } else if ( upos == p1 ) { /* Handle {1} substitution */
                         UChar *p1Start = &result[p0Len+2];
                         u_strncat(dest,p1Start,length-p0Len-3);
                         destLen += (length-p0Len-3);
                         dest[destLen] = 0; /* Null terminate */
                         upos += 3;
                     } else { /* Something from the pattern not {0} or {1} */
                         u_strncat(dest,upos,1);
                         upos++;
                         destLen++;
                         dest[destLen] = 0; /* Null terminate */
                     }
                  }
                  length = destLen;
                  uprv_free(result);
              }
           }
        }
    }
    if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) {
        /* keep preflighting */
        *pErrorCode=U_ZERO_ERROR;
    }

    return u_terminateUChars(dest, destCapacity, length, pErrorCode);
}


Generated by  Doxygen 1.6.0   Back to index