Beispiel #1
0
U_CAPI void U_EXPORT2
ucol_prepareShortStringOpen( const char *definition,
                          UBool,
                          UParseError *parseError,
                          UErrorCode *status)
{
    if(U_FAILURE(*status)) return;

    UParseError internalParseError;

    if(!parseError) {
        parseError = &internalParseError;
    }
    parseError->line = 0;
    parseError->offset = 0;
    parseError->preContext[0] = 0;
    parseError->postContext[0] = 0;


    // first we want to pick stuff out of short string.
    // we'll end up with an UCA version, locale and a bunch of
    // settings

    // analyse the string in order to get everything we need.
    CollatorSpec s;
    ucol_sit_initCollatorSpecs(&s);
    ucol_sit_readSpecs(&s, definition, parseError, status);
    ucol_sit_calculateWholeLocale(&s);

    char buffer[internalBufferSize];
    uprv_memset(buffer, 0, internalBufferSize);
    uloc_canonicalize(s.locale, buffer, internalBufferSize, status);

    UResourceBundle *b = ures_open(U_ICUDATA_COLL, buffer, status);
    /* we try to find stuff from keyword */
    UResourceBundle *collations = ures_getByKey(b, "collations", NULL, status);
    UResourceBundle *collElem = NULL;
    char keyBuffer[256];
    // if there is a keyword, we pick it up and try to get elements
    if(!uloc_getKeywordValue(buffer, "collation", keyBuffer, 256, status)) {
      // no keyword. we try to find the default setting, which will give us the keyword value
      UResourceBundle *defaultColl = ures_getByKeyWithFallback(collations, "default", NULL, status);
      if(U_SUCCESS(*status)) {
        int32_t defaultKeyLen = 0;
        const UChar *defaultKey = ures_getString(defaultColl, &defaultKeyLen, status);
        u_UCharsToChars(defaultKey, keyBuffer, defaultKeyLen);
        keyBuffer[defaultKeyLen] = 0;
      } else {
        *status = U_INTERNAL_PROGRAM_ERROR;
        return;
      }
      ures_close(defaultColl);
    }
    collElem = ures_getByKeyWithFallback(collations, keyBuffer, collElem, status);
    ures_close(collElem);
    ures_close(collations);
    ures_close(b);
}
Beispiel #2
0
/* {{{ ResourceBundle_extract_value */
void resourcebundle_extract_value( zval *return_value, ResourceBundle_object *source )
{
	UResType               restype;
	const UChar*           ufield;
	const uint8_t*         bfield;
	const int32_t*         vfield;
	int32_t                ilen;
	int                    i;
	zend_long              lfield;
	ResourceBundle_object* newrb;

	restype = ures_getType( source->child );
	switch (restype)
	{
		case URES_STRING:
			ufield = ures_getString( source->child, &ilen, &INTL_DATA_ERROR_CODE(source) );
			INTL_METHOD_CHECK_STATUS(source, "Failed to retrieve string value");
			INTL_METHOD_RETVAL_UTF8(source, (UChar *)ufield, ilen, 0);
			break;

		case URES_BINARY:
			bfield = ures_getBinary( source->child, &ilen, &INTL_DATA_ERROR_CODE(source) );
			INTL_METHOD_CHECK_STATUS(source, "Failed to retrieve binary value");
			ZVAL_STRINGL( return_value, (char *) bfield, ilen );
			break;

		case URES_INT:
			lfield = ures_getInt( source->child, &INTL_DATA_ERROR_CODE(source) );
			INTL_METHOD_CHECK_STATUS(source, "Failed to retrieve integer value");
			ZVAL_LONG( return_value, lfield );
			break;

		case URES_INT_VECTOR:
			vfield = ures_getIntVector( source->child, &ilen, &INTL_DATA_ERROR_CODE(source) );
			INTL_METHOD_CHECK_STATUS(source, "Failed to retrieve vector value");
			array_init( return_value );
			for (i=0; i<ilen; i++) {
				add_next_index_long( return_value, vfield[i] );
			}
			break;

		case URES_ARRAY:
		case URES_TABLE:
			object_init_ex( return_value, ResourceBundle_ce_ptr );
			newrb = Z_INTL_RESOURCEBUNDLE_P(return_value);
			newrb->me = source->child;
			source->child = NULL;
			intl_errors_reset(INTL_DATA_ERROR_P(source));
			break;

		default:
			intl_errors_set(INTL_DATA_ERROR_P(source), U_ILLEGAL_ARGUMENT_ERROR, "Unknown resource type", 0);
			RETURN_FALSE;
			break;
	}
}
Beispiel #3
0
static UBool getString(
        const UResourceBundle *resource,
        UnicodeString &result,
        UErrorCode &status) {
    int32_t len = 0;
    const UChar *resStr = ures_getString(resource, &len, &status);
    if (U_FAILURE(status)) {
        return FALSE;
    }
    result.setTo(TRUE, resStr, len);
    return TRUE;
}
Beispiel #4
0
const CompactTrieDictionary *
ICULanguageBreakFactory::loadDictionaryFor(UScriptCode script, int32_t /*breakType*/) {
    UErrorCode status = U_ZERO_ERROR;
    // Open root from brkitr tree.
    char dictnbuff[256];
    char ext[4]={'\0'};

    UResourceBundle *b = ures_open(U_ICUDATA_BRKITR, "", &status);
    b = ures_getByKeyWithFallback(b, "dictionaries", b, &status);
    b = ures_getByKeyWithFallback(b, uscript_getShortName(script), b, &status);
    int32_t dictnlength = 0;
    const UChar *dictfname = ures_getString(b, &dictnlength, &status);
    if (U_SUCCESS(status) && (size_t)dictnlength >= sizeof(dictnbuff)) {
        dictnlength = 0;
        status = U_BUFFER_OVERFLOW_ERROR;
    }
    if (U_SUCCESS(status) && dictfname) {
        UChar* extStart=u_strchr(dictfname, 0x002e);
        int len = 0;
        if(extStart!=NULL){
            len = extStart-dictfname;
            u_UCharsToChars(extStart+1, ext, sizeof(ext)); // nul terminates the buff
            u_UCharsToChars(dictfname, dictnbuff, len);
        }
        dictnbuff[len]=0; // nul terminate
    }
    ures_close(b);
    UDataMemory *file = udata_open(U_ICUDATA_BRKITR, ext, dictnbuff, &status);
    if (U_SUCCESS(status)) {
        const CompactTrieDictionary *dict = new CompactTrieDictionary(
            file, status);
        if (U_SUCCESS(status) && dict == NULL) {
            status = U_MEMORY_ALLOCATION_ERROR;
        }
        if (U_FAILURE(status)) {
            delete dict;
            dict = NULL;
        }
        return dict;
    } else if (dictfname != NULL){
        //create dummy dict if dictionary filename not valid
        UChar c = 0x0020;
        status = U_ZERO_ERROR;
        MutableTrieDictionary *mtd = new MutableTrieDictionary(c, status, TRUE);
        mtd->addWord(&c, 1, status, 1);
        return new CompactTrieDictionary(*mtd, status);  
    }
    return NULL;
}
Beispiel #5
0
static jstring getCurrencyCodeNative(JNIEnv* env, jclass clazz, jstring key) {
    UErrorCode status = U_ZERO_ERROR;
    ScopedResourceBundle supplData(ures_openDirect(NULL, "supplementalData", &status));
    if (U_FAILURE(status)) {
        return NULL;
    }

    ScopedResourceBundle currencyMap(ures_getByKey(supplData.get(), "CurrencyMap", NULL, &status));
    if (U_FAILURE(status)) {
        return NULL;
    }

    const char* keyChars = env->GetStringUTFChars(key, NULL);
    ScopedResourceBundle currency(ures_getByKey(currencyMap.get(), keyChars, NULL, &status));
    env->ReleaseStringUTFChars(key, keyChars);
    if (U_FAILURE(status)) {
        return NULL;
    }

    ScopedResourceBundle currencyElem(ures_getByIndex(currency.get(), 0, NULL, &status));
    if (U_FAILURE(status)) {
        return env->NewStringUTF("None");
    }

    // check if there is a 'to' date. If there is, the currency isn't used anymore.
    ScopedResourceBundle currencyTo(ures_getByKey(currencyElem.get(), "to", NULL, &status));
    if (!U_FAILURE(status)) {
        // return and let the caller throw an exception
        return NULL;
    }
    // We need to reset 'status'. It works like errno in that ICU doesn't set it
    // to U_ZERO_ERROR on success: it only touches it on error, and the test
    // above means it now holds a failure code.
    status = U_ZERO_ERROR;

    ScopedResourceBundle currencyId(ures_getByKey(currencyElem.get(), "id", NULL, &status));
    if (U_FAILURE(status)) {
        // No id defined for this country
        return env->NewStringUTF("None");
    }

    int length;
    const jchar* id = ures_getString(currencyId.get(), &length, &status);
    if (U_FAILURE(status) || length == 0) {
        return env->NewStringUTF("None");
    }
    return env->NewString(id, length);
}
// TODO: rewrite this with int32_t ucurr_forLocale(const char* locale, UChar* buff, int32_t buffCapacity, UErrorCode* ec)...
static jstring ICU_getCurrencyCode(JNIEnv* env, jclass, jstring javaCountryCode) {
    UErrorCode status = U_ZERO_ERROR;
    ScopedResourceBundle supplData(ures_openDirect(U_ICUDATA_CURR, "supplementalData", &status));
    if (U_FAILURE(status)) {
        return NULL;
    }

    ScopedResourceBundle currencyMap(ures_getByKey(supplData.get(), "CurrencyMap", NULL, &status));
    if (U_FAILURE(status)) {
        return NULL;
    }

    ScopedUtfChars countryCode(env, javaCountryCode);
    ScopedResourceBundle currency(ures_getByKey(currencyMap.get(), countryCode.c_str(), NULL, &status));
    if (U_FAILURE(status)) {
        return NULL;
    }

    ScopedResourceBundle currencyElem(ures_getByIndex(currency.get(), 0, NULL, &status));
    if (U_FAILURE(status)) {
        return env->NewStringUTF("XXX");
    }

    // Check if there's a 'to' date. If there is, the currency isn't used anymore.
    ScopedResourceBundle currencyTo(ures_getByKey(currencyElem.get(), "to", NULL, &status));
    if (!U_FAILURE(status)) {
        return NULL;
    }
    // Ignore the failure to find a 'to' date.
    status = U_ZERO_ERROR;

    ScopedResourceBundle currencyId(ures_getByKey(currencyElem.get(), "id", NULL, &status));
    if (U_FAILURE(status)) {
        // No id defined for this country
        return env->NewStringUTF("XXX");
    }

    int32_t charCount;
    const jchar* chars = ures_getString(currencyId.get(), &charCount, &status);
    return (charCount == 0) ? env->NewStringUTF("XXX") : env->NewString(chars, charCount);
}
void RelativeDateFormat::loadDates(UErrorCode &status) {
    CalendarData calData(fLocale, "gregorian", status);

    UErrorCode tempStatus = status;
    UResourceBundle *dateTimePatterns = calData.getByKey(DT_DateTimePatternsTag, tempStatus);
    if(U_SUCCESS(tempStatus)) {
        int32_t patternsSize = ures_getSize(dateTimePatterns);
        if (patternsSize > kDateTime) {
            int32_t resStrLen = 0;

            int32_t glueIndex = kDateTime;
            if (patternsSize >= (DateFormat::kDateTimeOffset + DateFormat::kShort + 1)) {
                // Get proper date time format
                switch (fDateStyle) {
                case kFullRelative:
                case kFull:
                    glueIndex = kDateTimeOffset + kFull;
                    break;
                case kLongRelative:
                case kLong:
                    glueIndex = kDateTimeOffset + kLong;
                    break;
                case kMediumRelative:
                case kMedium:
                    glueIndex = kDateTimeOffset + kMedium;
                    break;
                case kShortRelative:
                case kShort:
                    glueIndex = kDateTimeOffset + kShort;
                    break;
                default:
                    break;
                }
            }

            const UChar *resStr = ures_getStringByIndex(dateTimePatterns, glueIndex, &resStrLen, &tempStatus);
            fCombinedFormat = new MessageFormat(UnicodeString(TRUE, resStr, resStrLen), fLocale, tempStatus);
        }
    }

    UResourceBundle *strings = calData.getByKey3("fields", "day", "relative", status);
    // set up min/max
    fDayMin=-1;
    fDayMax=1;

    if(U_FAILURE(status)) {
        fDatesLen=0;
        return;
    }

    fDatesLen = ures_getSize(strings);
    fDates = (URelativeString*) uprv_malloc(sizeof(fDates[0])*fDatesLen);

    // Load in each item into the array...
    int n = 0;

    UResourceBundle *subString = NULL;

    while(ures_hasNext(strings) && U_SUCCESS(status)) {  // iterate over items
        subString = ures_getNextResource(strings, subString, &status);

        if(U_FAILURE(status) || (subString==NULL)) break;

        // key = offset #
        const char *key = ures_getKey(subString);

        // load the string and length
        int32_t aLen;
        const UChar* aString = ures_getString(subString, &aLen, &status);

        if(U_FAILURE(status) || aString == NULL) break;

        // calculate the offset
        int32_t offset = atoi(key);

        // set min/max
        if(offset < fDayMin) {
            fDayMin = offset;
        }
        if(offset > fDayMax) {
            fDayMax = offset;
        }

        // copy the string pointer
        fDates[n].offset = offset;
        fDates[n].string = aString;
        fDates[n].len = aLen;

        n++;
    }
    ures_close(subString);

    // the fDates[] array could be sorted here, for direct access.
}
Beispiel #8
0
static void
TestTable32(void) {
    static const struct {
        const char *key;
        int32_t number;
    } testcases[]={
        { "ooooooooooooooooo", 0 },
        { "oooooooooooooooo1", 1 },
        { "ooooooooooooooo1o", 2 },
        { "oo11ooo1ooo11111o", 25150 },
        { "oo11ooo1ooo111111", 25151 },
        { "o1111111111111111", 65535 },
        { "1oooooooooooooooo", 65536 },
        { "1ooooooo11o11ooo1", 65969 },
        { "1ooooooo11o11oo1o", 65970 },
        { "1ooooooo111oo1111", 65999 }
    };

    /* ### TODO UResourceBundle staticItem={ 0 }; - need to know the size */
    UResourceBundle *res, *item;
    const UChar *s;
    const char *key;
    UErrorCode errorCode;
    int32_t i, j, number, parsedNumber, length, count;

    errorCode=U_ZERO_ERROR;
    res=ures_open(loadTestData(&errorCode), "testtable32", &errorCode);
    if(U_FAILURE(errorCode)) {
        log_data_err("unable to open testdata/testtable32.res - %s\n", u_errorName(errorCode));
        return;
    }
    if(ures_getType(res)!=URES_TABLE) {
        log_data_err("testdata/testtable32.res has type %d instead of URES_TABLE\n", ures_getType(res));
    }

    count=ures_getSize(res);
    if(count!=66000) {
        log_err("testdata/testtable32.res should have 66000 entries but has %d\n", count);
    }

    /* get the items by index */
    item=NULL;
    for(i=0; i<count; ++i) {
        item=ures_getByIndex(res, i, item, &errorCode);
        if(U_FAILURE(errorCode)) {
            log_err("unable to get item %d of %d in testdata/testtable32.res - %s\n",
                    i, count, u_errorName(errorCode));
            break;
        }

        key=ures_getKey(item);
        parsedNumber=parseTable32Key(key);

        switch(ures_getType(item)) {
        case URES_STRING:
            s=ures_getString(item, &length, &errorCode);
            if(U_FAILURE(errorCode) || s==NULL) {
                log_err("unable to access the string \"%s\" at %d in testdata/testtable32.res - %s\n",
                        key, i, u_errorName(errorCode));
                number=-1;
            } else {
                j=0;
                U16_NEXT(s, j, length, number);
            }
            break;
        case URES_INT:
            number=ures_getInt(item, &errorCode);
            if(U_FAILURE(errorCode)) {
                log_err("unable to access the integer \"%s\" at %d in testdata/testtable32.res - %s\n",
                        key, i, u_errorName(errorCode));
                number=-1;
            }
            break;
        default:
            log_err("unexpected resource type %d for \"%s\" at %d in testdata/testtable32.res - %s\n",
                    ures_getType(item), key, i, u_errorName(errorCode));
            number=-1;
            break;
        }

        if(number>=0 && number!=parsedNumber) {
            log_err("\"%s\" at %d in testdata/testtable32.res has a string/int value of %d, expected %d\n",
                    key, i, number, parsedNumber);
        }
    }

    /* search for some items by key */
    for(i=0; i<UPRV_LENGTHOF(testcases); ++i) {
        item=ures_getByKey(res, testcases[i].key, item, &errorCode);
        if(U_FAILURE(errorCode)) {
            log_err("unable to find the key \"%s\" in testdata/testtable32.res - %s\n",
                    testcases[i].key, u_errorName(errorCode));
            continue;
        }

        switch(ures_getType(item)) {
        case URES_STRING:
            s=ures_getString(item, &length, &errorCode);
            if(U_FAILURE(errorCode) || s==NULL) {
                log_err("unable to access the string \"%s\" in testdata/testtable32.res - %s\n",
                        testcases[i].key, u_errorName(errorCode));
                number=-1;
            } else {
                j=0;
                U16_NEXT(s, j, length, number);
            }
            break;
        case URES_INT:
            number=ures_getInt(item, &errorCode);
            if(U_FAILURE(errorCode)) {
                log_err("unable to access the integer \"%s\" in testdata/testtable32.res - %s\n",
                        testcases[i].key, u_errorName(errorCode));
                number=-1;
            }
            break;
        default:
            log_err("unexpected resource type %d for \"%s\" in testdata/testtable32.res - %s\n",
                    ures_getType(item), testcases[i].key, u_errorName(errorCode));
            number=-1;
            break;
        }

        if(number>=0 && number!=testcases[i].number) {
            log_err("\"%s\" in testdata/testtable32.res has a string/int value of %d, expected %d\n",
                    testcases[i].key, number, testcases[i].number);
        }

        key=ures_getKey(item);
        if(0!=uprv_strcmp(key, testcases[i].key)) {
            log_err("\"%s\" in testdata/testtable32.res claims to have the key \"%s\"\n",
                    testcases[i].key, key);
        }
    }

    ures_close(item);
    ures_close(res);
}
Beispiel #9
0
void printOutBundle(UFILE *out, UResourceBundle *resource, int32_t indent, UErrorCode *status) {
    int32_t i = 0;
    const char *key = ures_getKey(resource);

    switch(ures_getType(resource)) {
    case URES_STRING :
        {
            int32_t len=0;
            const UChar*thestr = ures_getString(resource, &len, status);
            UChar *string = quotedString(thestr);

            /* TODO: String truncation */
            /*
            if(trunc && len > truncsize) {
                printIndent(out, indent);
                u_fprintf(out, "// WARNING: this string, size %d is truncated to %d\n", len, truncsize/2);
                len = truncsize/2;
            }
            */
            printIndent(out, indent);
            if(key != NULL) {
                u_fprintf(out, "%s { \"%S\" } ", key, string);
            } else {
                u_fprintf(out, "\"%S\",", string);
            }
            if(VERBOSE) {
                u_fprintf(out, " // STRING");
            }
            u_fprintf(out, "\n");
            free(string);
        }
        break;
    case URES_INT :
        printIndent(out, indent);
        if(key != NULL) {
            u_fprintf(out, "%s", key);
        }
        u_fprintf(out, ":int { %li } ", ures_getInt(resource, status));
        
        if(VERBOSE) {
            u_fprintf(out, " // INT");
        }
        u_fprintf(out, "\n");
        break;
    case URES_BINARY :
        {
            int32_t len = 0;
            const int8_t *data = (const int8_t *)ures_getBinary(resource, &len, status);
            if(trunc && len > truncsize) {
                printIndent(out, indent);
                u_fprintf(out, "// WARNING: this resource, size %li is truncated to %li\n", len, truncsize/2);
                len = truncsize/2;
            }
            if(U_SUCCESS(*status)) {
                printIndent(out, indent);
                if(key != NULL) {
                    u_fprintf(out, "%s", key);
                }
                u_fprintf(out, ":binary { ");
                for(i = 0; i<len; i++) {
                    printHex(out, data++);
                }
                u_fprintf(out, " }");
                if(VERBOSE) {
                    u_fprintf(out, " // BINARY");
                }
                u_fprintf(out, "\n");
                
            } else {
                reportError(status);
            }
        }
        break;
    case URES_INT_VECTOR :
      {
          int32_t len = 0;
          const int32_t *data = ures_getIntVector(resource, &len, status);
          if(U_SUCCESS(*status)) {
              printIndent(out, indent);
              if(key != NULL) {
                  u_fprintf(out, "%s", key);
              } 
              u_fprintf(out, ":intvector { ");
              for(i = 0; i<len-1; i++) {
                  u_fprintf(out, "%d, ", data[i]);
              }
              if(len > 0) {
                  u_fprintf(out, "%d ", data[len-1]);
              }
              u_fprintf(out, "}");
              if(VERBOSE) {
                  u_fprintf(out, " // INTVECTOR");
              }
              u_fprintf(out, "\n");
              
          } else {
              reportError(status);
          }
      }
      break;
    case URES_TABLE :
    case URES_ARRAY :
        {
            UResourceBundle *t = NULL;
            ures_resetIterator(resource);
            printIndent(out, indent);
            if(key != NULL) {
                u_fprintf(out, "%s ", key);
            }
            u_fprintf(out, "{");
            if(VERBOSE) {
                if(ures_getType(resource) == URES_TABLE) {
                    u_fprintf(out, " // TABLE");
                } else {
                    u_fprintf(out, " // ARRAY");
                }
            }
            u_fprintf(out, "\n");

            while(ures_hasNext(resource)) {
                t = ures_getNextResource(resource, t, status);
                printOutBundle(out, t, indent+indentsize, status);
            }

            printIndent(out, indent);
            u_fprintf(out, "}\n");
            ures_close(t);
        }
        break;
    default:
        break;
    }

}
U_CDECL_END


static void U_CALLCONV
initFromResourceBundle(UErrorCode& sts) {
    U_NAMESPACE_USE
    ucln_common_registerCleanup(UCLN_COMMON_LOCALE_KEY_TYPE, uloc_key_type_cleanup);

    gLocExtKeyMap = uhash_open(uhash_hashIChars, uhash_compareIChars, NULL, &sts);

    LocalUResourceBundlePointer keyTypeDataRes(ures_openDirect(NULL, "keyTypeData", &sts));
    LocalUResourceBundlePointer keyMapRes(ures_getByKey(keyTypeDataRes.getAlias(), "keyMap", NULL, &sts));
    LocalUResourceBundlePointer typeMapRes(ures_getByKey(keyTypeDataRes.getAlias(), "typeMap", NULL, &sts));

    if (U_FAILURE(sts)) {
        return;
    }

    UErrorCode tmpSts = U_ZERO_ERROR;
    LocalUResourceBundlePointer typeAliasRes(ures_getByKey(keyTypeDataRes.getAlias(), "typeAlias", NULL, &tmpSts));
    tmpSts = U_ZERO_ERROR;
    LocalUResourceBundlePointer bcpTypeAliasRes(ures_getByKey(keyTypeDataRes.getAlias(), "bcpTypeAlias", NULL, &tmpSts));

    // initialize vectors storing dynamically allocated objects
    gKeyTypeStringPool = new UVector(uloc_deleteKeyTypeStringPoolEntry, NULL, sts);
    if (gKeyTypeStringPool == NULL) {
        if (U_SUCCESS(sts)) {
            sts = U_MEMORY_ALLOCATION_ERROR;
        }
    }
    if (U_FAILURE(sts)) {
        return;
    }
    gLocExtKeyDataEntries = new UVector(uloc_deleteKeyDataEntry, NULL, sts);
    if (gLocExtKeyDataEntries == NULL) {
        if (U_SUCCESS(sts)) {
            sts = U_MEMORY_ALLOCATION_ERROR;
        }
    }
    if (U_FAILURE(sts)) {
        return;
    }
    gLocExtTypeEntries = new UVector(uloc_deleteTypeEntry, NULL, sts);
    if (gLocExtTypeEntries == NULL) {
        if (U_SUCCESS(sts)) {
            sts = U_MEMORY_ALLOCATION_ERROR;
        }
    }
    if (U_FAILURE(sts)) {
        return;
    }

    // iterate through keyMap resource
    LocalUResourceBundlePointer keyMapEntry;

    while (ures_hasNext(keyMapRes.getAlias())) {
        keyMapEntry.adoptInstead(ures_getNextResource(keyMapRes.getAlias(), keyMapEntry.orphan(), &sts));
        if (U_FAILURE(sts)) {
            break;
        }
        const char* legacyKeyId = ures_getKey(keyMapEntry.getAlias());
        int32_t bcpKeyIdLen = 0;
        const UChar* uBcpKeyId = ures_getString(keyMapEntry.getAlias(), &bcpKeyIdLen, &sts);
        if (U_FAILURE(sts)) {
            break;
        }

        // empty value indicates that BCP key is same with the legacy key.
        const char* bcpKeyId = legacyKeyId;
        if (bcpKeyIdLen > 0) {
            char* bcpKeyIdBuf = (char*)uprv_malloc(bcpKeyIdLen + 1);
            if (bcpKeyIdBuf == NULL) {
                sts = U_MEMORY_ALLOCATION_ERROR;
                break;
            }
            u_UCharsToChars(uBcpKeyId, bcpKeyIdBuf, bcpKeyIdLen);
            bcpKeyIdBuf[bcpKeyIdLen] = 0;
            gKeyTypeStringPool->addElement(bcpKeyIdBuf, sts);
            if (U_FAILURE(sts)) {
                break;
            }
            bcpKeyId = bcpKeyIdBuf;
        }

        UBool isTZ = uprv_strcmp(legacyKeyId, "timezone") == 0;

        UHashtable* typeDataMap = uhash_open(uhash_hashIChars, uhash_compareIChars, NULL, &sts);
        if (U_FAILURE(sts)) {
            break;
        }
        uint32_t specialTypes = SPECIALTYPE_NONE;

        LocalUResourceBundlePointer typeAliasResByKey;
        LocalUResourceBundlePointer bcpTypeAliasResByKey;

        if (typeAliasRes.isValid()) {
            tmpSts = U_ZERO_ERROR;
            typeAliasResByKey.adoptInstead(ures_getByKey(typeAliasRes.getAlias(), legacyKeyId, NULL, &tmpSts));
            if (U_FAILURE(tmpSts)) {
                typeAliasResByKey.orphan();
            }
        }
        if (bcpTypeAliasRes.isValid()) {
            tmpSts = U_ZERO_ERROR;
            bcpTypeAliasResByKey.adoptInstead(ures_getByKey(bcpTypeAliasRes.getAlias(), bcpKeyId, NULL, &tmpSts));
            if (U_FAILURE(tmpSts)) {
                bcpTypeAliasResByKey.orphan();
            }
        }

        // look up type map for the key, and walk through the mapping data
        tmpSts = U_ZERO_ERROR;
        LocalUResourceBundlePointer typeMapResByKey(ures_getByKey(typeMapRes.getAlias(), legacyKeyId, NULL, &tmpSts));
        if (U_FAILURE(tmpSts)) {
            // type map for each key must exist
            U_ASSERT(FALSE);
        } else {
            LocalUResourceBundlePointer typeMapEntry;

            while (ures_hasNext(typeMapResByKey.getAlias())) {
                typeMapEntry.adoptInstead(ures_getNextResource(typeMapResByKey.getAlias(), typeMapEntry.orphan(), &sts));
                if (U_FAILURE(sts)) {
                    break;
                }
                const char* legacyTypeId = ures_getKey(typeMapEntry.getAlias());

                // special types
                if (uprv_strcmp(legacyTypeId, "CODEPOINTS") == 0) {
                    specialTypes |= SPECIALTYPE_CODEPOINTS;
                    continue;
                }
                if (uprv_strcmp(legacyTypeId, "REORDER_CODE") == 0) {
                    specialTypes |= SPECIALTYPE_REORDER_CODE;
                    continue;
                }
                if (uprv_strcmp(legacyTypeId, "RG_KEY_VALUE") == 0) {
                    specialTypes |= SPECIALTYPE_RG_KEY_VALUE;
                    continue;
                }

                if (isTZ) {
                    // a timezone key uses a colon instead of a slash in the resource.
                    // e.g. America:Los_Angeles
                    if (uprv_strchr(legacyTypeId, ':') != NULL) {
                        int32_t legacyTypeIdLen = uprv_strlen(legacyTypeId);
                        char* legacyTypeIdBuf = (char*)uprv_malloc(legacyTypeIdLen + 1);
                        if (legacyTypeIdBuf == NULL) {
                            sts = U_MEMORY_ALLOCATION_ERROR;
                            break;
                        }
                        const char* p = legacyTypeId;
                        char* q = legacyTypeIdBuf;
                        while (*p) {
                            if (*p == ':') {
                                *q++ = '/';
                            } else {
                                *q++ = *p;
                            }
                            p++;
                        }
                        *q = 0;

                        gKeyTypeStringPool->addElement(legacyTypeIdBuf, sts);
                        if (U_FAILURE(sts)) {
                            break;
                        }
                        legacyTypeId = legacyTypeIdBuf;
                    }
                }

                int32_t bcpTypeIdLen = 0;
                const UChar* uBcpTypeId = ures_getString(typeMapEntry.getAlias(), &bcpTypeIdLen, &sts);
                if (U_FAILURE(sts)) {
                    break;
                }

                // empty value indicates that BCP type is same with the legacy type.
                const char* bcpTypeId = legacyTypeId;
                if (bcpTypeIdLen > 0) {
                    char* bcpTypeIdBuf = (char*)uprv_malloc(bcpTypeIdLen + 1);
                    if (bcpTypeIdBuf == NULL) {
                        sts = U_MEMORY_ALLOCATION_ERROR;
                        break;
                    }
                    u_UCharsToChars(uBcpTypeId, bcpTypeIdBuf, bcpTypeIdLen);
                    bcpTypeIdBuf[bcpTypeIdLen] = 0;
                    gKeyTypeStringPool->addElement(bcpTypeIdBuf, sts);
                    if (U_FAILURE(sts)) {
                        break;
                    }
                    bcpTypeId = bcpTypeIdBuf;
                }

                // Note: legacy type value should never be
                // equivalent to bcp type value of a different
                // type under the same key. So we use a single
                // map for lookup.
                LocExtType* t = (LocExtType*)uprv_malloc(sizeof(LocExtType));
                if (t == NULL) {
                    sts = U_MEMORY_ALLOCATION_ERROR;
                    break;
                }
                t->bcpId = bcpTypeId;
                t->legacyId = legacyTypeId;
                gLocExtTypeEntries->addElement((void*)t, sts);
                if (U_FAILURE(sts)) {
                    break;
                }

                uhash_put(typeDataMap, (void*)legacyTypeId, t, &sts);
                if (bcpTypeId != legacyTypeId) {
                    // different type value
                    uhash_put(typeDataMap, (void*)bcpTypeId, t, &sts);
                }
                if (U_FAILURE(sts)) {
                    break;
                }

                // also put aliases in the map
                if (typeAliasResByKey.isValid()) {
                    LocalUResourceBundlePointer typeAliasDataEntry;

                    ures_resetIterator(typeAliasResByKey.getAlias());
                    while (ures_hasNext(typeAliasResByKey.getAlias()) && U_SUCCESS(sts)) {
                        int32_t toLen;
                        typeAliasDataEntry.adoptInstead(ures_getNextResource(typeAliasResByKey.getAlias(), typeAliasDataEntry.orphan(), &sts));
                        const UChar* to = ures_getString(typeAliasDataEntry.getAlias(), &toLen, &sts);
                        if (U_FAILURE(sts)) {
                            break;
                        }
                        // check if this is an alias of canoncal legacy type
                        if (uprv_compareInvWithUChar(NULL, legacyTypeId, -1, to, toLen) == 0) {
                            const char* from = ures_getKey(typeAliasDataEntry.getAlias());
                            if (isTZ) {
                                // replace colon with slash if necessary
                                if (uprv_strchr(from, ':') != NULL) {
                                    int32_t fromLen = uprv_strlen(from);
                                    char* fromBuf = (char*)uprv_malloc(fromLen + 1);
                                    if (fromBuf == NULL) {
                                        sts = U_MEMORY_ALLOCATION_ERROR;
                                        break;
                                    }
                                    const char* p = from;
                                    char* q = fromBuf;
                                    while (*p) {
                                        if (*p == ':') {
                                            *q++ = '/';
                                        } else {
                                            *q++ = *p;
                                        }
                                        p++;
                                    }
                                    *q = 0;

                                    gKeyTypeStringPool->addElement(fromBuf, sts);
                                    if (U_FAILURE(sts)) {
                                        break;
                                    }
                                    from = fromBuf;
                                }
                            }
                            uhash_put(typeDataMap, (void*)from, t, &sts);
                        }
                    }
                    if (U_FAILURE(sts)) {
                        break;
                    }
                }

                if (bcpTypeAliasResByKey.isValid()) {
                    LocalUResourceBundlePointer bcpTypeAliasDataEntry;

                    ures_resetIterator(bcpTypeAliasResByKey.getAlias());
                    while (ures_hasNext(bcpTypeAliasResByKey.getAlias()) && U_SUCCESS(sts)) {
                        int32_t toLen;
                        bcpTypeAliasDataEntry.adoptInstead(ures_getNextResource(bcpTypeAliasResByKey.getAlias(), bcpTypeAliasDataEntry.orphan(), &sts));
                        const UChar* to = ures_getString(bcpTypeAliasDataEntry.getAlias(), &toLen, &sts);
                        if (U_FAILURE(sts)) {
                            break;
                        }
                        // check if this is an alias of bcp type
                        if (uprv_compareInvWithUChar(NULL, bcpTypeId, -1, to, toLen) == 0) {
                            const char* from = ures_getKey(bcpTypeAliasDataEntry.getAlias());
                            uhash_put(typeDataMap, (void*)from, t, &sts);
                        }
                    }
                    if (U_FAILURE(sts)) {
                        break;
                    }
                }
            }
        }
        if (U_FAILURE(sts)) {
            break;
        }

        LocExtKeyData* keyData = (LocExtKeyData*)uprv_malloc(sizeof(LocExtKeyData));
        if (keyData == NULL) {
            sts = U_MEMORY_ALLOCATION_ERROR;
            break;
        }
        keyData->bcpId = bcpKeyId;
        keyData->legacyId = legacyKeyId;
        keyData->specialTypes = specialTypes;
        keyData->typeMap = typeDataMap;

        gLocExtKeyDataEntries->addElement((void*)keyData, sts);
        if (U_FAILURE(sts)) {
            break;
        }

        uhash_put(gLocExtKeyMap, (void*)legacyKeyId, keyData, &sts);
        if (legacyKeyId != bcpKeyId) {
            // different key value
            uhash_put(gLocExtKeyMap, (void*)bcpKeyId, keyData, &sts);
        }
        if (U_FAILURE(sts)) {
            break;
        }
    }
}
U_CFUNC UCollator*
ucol_open_internal(const char *loc,
                   UErrorCode *status)
{
    const UCollator* UCA = ucol_initUCA(status);

    /* New version */
    if(U_FAILURE(*status)) return 0;



    UCollator *result = NULL;
    UResourceBundle *b = ures_open(U_ICUDATA_COLL, loc, status);

    /* we try to find stuff from keyword */
    UResourceBundle *collations = ures_getByKey(b, "collations", NULL, status);
    UResourceBundle *collElem = NULL;
    char keyBuffer[256];
    // if there is a keyword, we pick it up and try to get elements
    if(!uloc_getKeywordValue(loc, "collation", keyBuffer, 256, status)) {
        // no keyword. we try to find the default setting, which will give us the keyword value
        UErrorCode intStatus = U_ZERO_ERROR;
        // finding default value does not affect collation fallback status
        UResourceBundle *defaultColl = ures_getByKeyWithFallback(collations, "default", NULL, &intStatus);
        if(U_SUCCESS(intStatus)) {
            int32_t defaultKeyLen = 0;
            const UChar *defaultKey = ures_getString(defaultColl, &defaultKeyLen, &intStatus);
            u_UCharsToChars(defaultKey, keyBuffer, defaultKeyLen);
            keyBuffer[defaultKeyLen] = 0;
        } else {
            *status = U_INTERNAL_PROGRAM_ERROR;
            return NULL;
        }
        ures_close(defaultColl);
    }
    collElem = ures_getByKeyWithFallback(collations, keyBuffer, collElem, status);

    UResourceBundle *binary = NULL;

    if(*status == U_MISSING_RESOURCE_ERROR) { /* We didn't find the tailoring data, we fallback to the UCA */
        *status = U_USING_DEFAULT_WARNING;
        result = ucol_initCollator(UCA->image, result, UCA, status);
        // if we use UCA, real locale is root
        result->rb = ures_open(U_ICUDATA_COLL, "", status);
        result->elements = ures_open(U_ICUDATA_COLL, "", status);
        if(U_FAILURE(*status)) {
            goto clean;
        }
        ures_close(b);
        result->hasRealData = FALSE;
    } else if(U_SUCCESS(*status)) {
        int32_t len = 0;
        UErrorCode binaryStatus = U_ZERO_ERROR;

        binary = ures_getByKey(collElem, "%%CollationBin", NULL, &binaryStatus);

        if(binaryStatus == U_MISSING_RESOURCE_ERROR) { /* we didn't find the binary image, we should use the rules */
            binary = NULL;
            result = tryOpeningFromRules(collElem, status);
            if(U_FAILURE(*status)) {
                goto clean;
            }
        } else if(U_SUCCESS(*status)) { /* otherwise, we'll pick a collation data that exists */
            const uint8_t *inData = ures_getBinary(binary, &len, status);
            UCATableHeader *colData = (UCATableHeader *)inData;
            if(uprv_memcmp(colData->UCAVersion, UCA->image->UCAVersion, sizeof(UVersionInfo)) != 0 ||
                uprv_memcmp(colData->UCDVersion, UCA->image->UCDVersion, sizeof(UVersionInfo)) != 0 ||
                colData->version[0] != UCOL_BUILDER_VERSION)
            {
                *status = U_DIFFERENT_UCA_VERSION;
                result = tryOpeningFromRules(collElem, status);
            } else {
                if(U_FAILURE(*status)){
                    goto clean;
                }
                if((uint32_t)len > (paddedsize(sizeof(UCATableHeader)) + paddedsize(sizeof(UColOptionSet)))) {
                    result = ucol_initCollator((const UCATableHeader *)inData, result, UCA, status);
                    if(U_FAILURE(*status)){
                        goto clean;
                    }
                    result->hasRealData = TRUE;
                } else {
                    result = ucol_initCollator(UCA->image, result, UCA, status);
                    ucol_setOptionsFromHeader(result, (UColOptionSet *)(inData+((const UCATableHeader *)inData)->options), status);
                    if(U_FAILURE(*status)){
                        goto clean;
                    }
                    result->hasRealData = FALSE;
                }
                result->freeImageOnClose = FALSE;
            }
        }
        result->rb = b;
        result->elements = collElem;
        len = 0;
        binaryStatus = U_ZERO_ERROR;
        result->rules = ures_getStringByKey(result->elements, "Sequence", &len, &binaryStatus);
        result->rulesLength = len;
        result->freeRulesOnClose = FALSE;
    } else { /* There is another error, and we're just gonna clean up */
        goto clean;
    }

    result->validLocale = NULL; // default is to use rb info

    if(loc == NULL) {
        loc = ures_getLocale(result->rb, status);
    }
    result->requestedLocale = (char *)uprv_malloc((uprv_strlen(loc)+1)*sizeof(char));
    /* test for NULL */
    if (result->requestedLocale == NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        goto clean;
    }
    uprv_strcpy(result->requestedLocale, loc);

    ures_close(binary);
    ures_close(collations); //??? we have to decide on that. Probably affects something :)
    result->resCleaner = ucol_prv_closeResources;
    return result;

clean:
    ures_close(b);
    ures_close(collElem);
    ures_close(collations);
    ures_close(binary);
    return NULL;
}
Beispiel #12
0
EraRules* EraRules::createInstance(const char *calType, UBool includeTentativeEra, UErrorCode& status) {
    if(U_FAILURE(status)) {
        return nullptr;
    }
    LocalUResourceBundlePointer rb(ures_openDirect(nullptr, "supplementalData", &status));
    ures_getByKey(rb.getAlias(), "calendarData", rb.getAlias(), &status);
    ures_getByKey(rb.getAlias(), calType, rb.getAlias(), &status);
    ures_getByKey(rb.getAlias(), "eras", rb.getAlias(), &status);

    if (U_FAILURE(status)) {
        return nullptr;
    }

    int32_t numEras = ures_getSize(rb.getAlias());
    int32_t firstTentativeIdx = MAX_INT32;

    LocalMemory<int32_t> startDates(static_cast<int32_t *>(uprv_malloc(numEras * sizeof(int32_t))));
    if (startDates.isNull()) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return nullptr;
    }
    uprv_memset(startDates.getAlias(), 0 , numEras * sizeof(int32_t));

    while (ures_hasNext(rb.getAlias())) {
        LocalUResourceBundlePointer eraRuleRes(ures_getNextResource(rb.getAlias(), nullptr, &status));
        if (U_FAILURE(status)) {
            return nullptr;
        }
        const char *eraIdxStr = ures_getKey(eraRuleRes.getAlias());
        char *endp;
        int32_t eraIdx = (int32_t)strtol(eraIdxStr, &endp, 10);
        if ((size_t)(endp - eraIdxStr) != uprv_strlen(eraIdxStr)) {
            status = U_INVALID_FORMAT_ERROR;
            return nullptr;
        }
        if (eraIdx < 0 || eraIdx >= numEras) {
            status = U_INVALID_FORMAT_ERROR;
            return nullptr;
        }
        if (isSet(startDates[eraIdx])) {
            // start date of the index was already set
            status = U_INVALID_FORMAT_ERROR;
            return nullptr;
        }

        UBool hasName = TRUE;
        UBool hasEnd = TRUE;
        int32_t len;
        while (ures_hasNext(eraRuleRes.getAlias())) {
            LocalUResourceBundlePointer res(ures_getNextResource(eraRuleRes.getAlias(), nullptr, &status));
            if (U_FAILURE(status)) {
                return nullptr;
            }
            const char *key = ures_getKey(res.getAlias());
            if (uprv_strcmp(key, "start") == 0) {
                const int32_t *fields = ures_getIntVector(res.getAlias(), &len, &status);
                if (U_FAILURE(status)) {
                    return nullptr;
                }
                if (len != 3 || !isValidRuleStartDate(fields[0], fields[1], fields[2])) {
                    status = U_INVALID_FORMAT_ERROR;
                    return nullptr;
                }
                startDates[eraIdx] = encodeDate(fields[0], fields[1], fields[2]);
            } else if (uprv_strcmp(key, "named") == 0) {
                const UChar *val = ures_getString(res.getAlias(), &len, &status);
                if (u_strncmp(val, VAL_FALSE, VAL_FALSE_LEN) == 0) {
                    hasName = FALSE;
                }
            } else if (uprv_strcmp(key, "end") == 0) {
                hasEnd = TRUE;
            }
        }

        if (isSet(startDates[eraIdx])) {
            if (hasEnd) {
                // This implementation assumes either start or end is available, not both.
                // For now, just ignore the end rule.
            }
        } else {
            if (hasEnd) {
                if (eraIdx != 0) {
                    // This implementation does not support end only rule for eras other than
                    // the first one.
                    status = U_INVALID_FORMAT_ERROR;
                    return nullptr;
                }
                U_ASSERT(eraIdx == 0);
                startDates[eraIdx] = MIN_ENCODED_START;
            } else {
                status = U_INVALID_FORMAT_ERROR;
                return nullptr;
            }
        }

        if (hasName) {
            if (eraIdx >= firstTentativeIdx) {
                status = U_INVALID_FORMAT_ERROR;
                return nullptr;
            }
        } else {
            if (eraIdx < firstTentativeIdx) {
                firstTentativeIdx = eraIdx;
            }
        }
    }

    EraRules *result;
    if (firstTentativeIdx < MAX_INT32 && !includeTentativeEra) {
        result = new EraRules(startDates, firstTentativeIdx);
    } else {
        result = new EraRules(startDates, numEras);
    }

    if (result == nullptr) {
        status = U_MEMORY_ALLOCATION_ERROR;
    }
    return result;
}
Beispiel #13
0
static void printOutBundle(FILE *out, UConverter *converter, UResourceBundle *resource, int32_t indent, const char *pname, UErrorCode *status)
{
    static const UChar cr[] = { '\n' };

/*    int32_t noOfElements = ures_getSize(resource);*/
    int32_t i = 0;
    const char *key = ures_getKey(resource);

    switch(ures_getType(resource)) {
    case RES_STRING :
        {
            int32_t len=0;
            const UChar* thestr = ures_getString(resource, &len, status);
            UChar *string = quotedString(thestr);

            /* TODO: String truncation */
            if(trunc && len > truncsize) {
                char msg[128];
                printIndent(out, converter, indent);
                sprintf(msg, "// WARNING: this resource, size %li is truncated to %li\n",
                        (long)len, (long)(truncsize/2));
                printCString(out, converter, msg, -1);
                len = truncsize/2;
            }
            printIndent(out, converter, indent);
            if(key != NULL) {
                static const UChar openStr[] = { 0x0020, 0x007B, 0x0020, 0x0022 }; /* " { \"" */
                static const UChar closeStr[] = { 0x0022, 0x0020, 0x007D }; /* "\" }" */
                printCString(out, converter, key, (int32_t)uprv_strlen(key));
                printString(out, converter, openStr, (int32_t)(sizeof(openStr)/sizeof(*openStr)));
                printString(out, converter, string, len);
                printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr)));
            } else {
                static const UChar openStr[] = { 0x0022 }; /* "\"" */
                static const UChar closeStr[] = { 0x0022, 0x002C }; /* "\"," */

                printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(*openStr)));
                printString(out, converter, string, (int32_t)(u_strlen(string)));
                printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr)));
            }

            if(verbose) {
                printCString(out, converter, "// STRING", -1);
            }
            printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*cr)));

            uprv_free(string);
        }
        break;

    case RES_INT :
        {
            static const UChar openStr[] = { 0x003A, 0x0069, 0x006E, 0x0074, 0x0020, 0x007B, 0x0020 }; /* ":int { " */
            static const UChar closeStr[] = { 0x0020, 0x007D }; /* " }" */
            UChar num[20];

            printIndent(out, converter, indent);
            if(key != NULL) {
                printCString(out, converter, key, -1);
            }
            printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(*openStr)));
            uprv_itou(num, 20, ures_getInt(resource, status), 10, 0);
            printString(out, converter, num, u_strlen(num));
            printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr)));

            if(verbose) {
                printCString(out, converter, "// INT", -1);
            }
            printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*cr)));
            break;
        }
    case RES_BINARY :
        {
            int32_t len = 0;
            const int8_t *data = (const int8_t *)ures_getBinary(resource, &len, status);
            if(trunc && len > truncsize) {
                char msg[128];
                printIndent(out, converter, indent);
                sprintf(msg, "// WARNING: this resource, size %li is truncated to %li\n",
                        (long)len, (long)(truncsize/2));
                printCString(out, converter, msg, -1);
                len = truncsize;
            }
            if(U_SUCCESS(*status)) {
                static const UChar openStr[] = { 0x003A, 0x0062, 0x0069, 0x006E, 0x0061, 0x0072, 0x0079, 0x0020, 0x007B, 0x0020 }; /* ":binary { " */
                static const UChar closeStr[] = { 0x0020, 0x007D, 0x0020 }; /* " } " */
                printIndent(out, converter, indent);
                if(key != NULL) {
                    printCString(out, converter, key, -1);
                }
                printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(*openStr)));
                for(i = 0; i<len; i++) {
                    printHex(out, converter, *data++);
                }
                printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr)));
                if(verbose) {
                    printCString(out, converter, " // BINARY", -1);
                }
                printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*cr)));
            } else {
                reportError(pname, status, "getting binary value");
            }
        }
        break;
    case RES_INT_VECTOR :
        {
            int32_t len = 0;
            const int32_t *data = ures_getIntVector(resource, &len, status);
            if(U_SUCCESS(*status)) {
                static const UChar openStr[] = { 0x003A, 0x0069, 0x006E, 0x0074, 0x0076, 0x0065, 0x0063, 0x0074, 0x006F, 0x0072, 0x0020, 0x007B, 0x0020 }; /* ":intvector { " */
                static const UChar closeStr[] = { 0x0020, 0x007D, 0x0020 }; /* " } " */
                UChar num[20];

                printIndent(out, converter, indent);
                if(key != NULL) {
                    printCString(out, converter, key, -1);
                }
                printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(*openStr)));
                for(i = 0; i < len - 1; i++) {
                    int32_t numLen =  uprv_itou(num, 20, data[i], 10, 0);
                    num[numLen++] = 0x002C; /* ',' */
                    num[numLen++] = 0x0020; /* ' ' */
                    num[numLen] = 0;
                    printString(out, converter, num, u_strlen(num));
                }
                if(len > 0) {
                    uprv_itou(num, 20, data[len - 1], 10, 0);
                    printString(out, converter, num, u_strlen(num));
                }
                printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr)));
                if(verbose) {
                    printCString(out, converter, "// INTVECTOR", -1);
                }
                printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*cr)));
            } else {
                reportError(pname, status, "getting int vector");
            }
      }
      break;
    case RES_TABLE :
    case RES_ARRAY :
        {
            static const UChar openStr[] = { 0x007B }; /* "{" */
            static const UChar closeStr[] = { 0x007D, '\n' }; /* "}\n" */

            UResourceBundle *t = NULL;
            ures_resetIterator(resource);
            printIndent(out, converter, indent);
            if(key != NULL) {
                printCString(out, converter, key, -1);
            }
            printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(*openStr)));
            if(verbose) {
                if(ures_getType(resource) == RES_TABLE) {
                    printCString(out, converter, "// TABLE", -1);
                } else {
                    printCString(out, converter, "// ARRAY", -1);
                }
            }
            printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*cr)));

            if(suppressAliases == FALSE) {
              while(U_SUCCESS(*status) && ures_hasNext(resource)) {
                  t = ures_getNextResource(resource, t, status);
                  if(U_SUCCESS(*status)) {
                    printOutBundle(out, converter, t, indent+indentsize, pname, status);
                  } else {
                    reportError(pname, status, "While processing table");
                    *status = U_ZERO_ERROR;
                  }
              }
            } else { /* we have to use low level access to do this */
              Resource r = RES_BOGUS;
              for(i = 0; i < ures_getSize(resource); i++) {
                /* need to know if it's an alias */
                if(ures_getType(resource) == RES_TABLE) {
                  r = derb_getTableItem(resource->fResData.pRoot, resource->fRes, (int16_t)i);
                  key = derb_getTableKey(resource->fResData.pRoot, resource->fRes, (int16_t)i);
                } else {
                  r = derb_getArrayItem(resource->fResData.pRoot, resource->fRes, i);
                }
                if(U_SUCCESS(*status)) {
                  if(RES_GET_TYPE(r) == RES_ALIAS) {
                    printOutAlias(out, converter, resource, r, key, indent+indentsize, pname, status);
                  } else {
                    t = ures_getByIndex(resource, i, t, status);
                    printOutBundle(out, converter, t, indent+indentsize, pname, status);
                  }
                } else {
                  reportError(pname, status, "While processing table");
                  *status = U_ZERO_ERROR;
                }
              }
            }

            printIndent(out, converter, indent);
            printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr)));
            ures_close(t);
        }
        break;
    default:
        break;
    }

}
Beispiel #14
0
UBool Transliterator::initializeRegistry(UErrorCode &status) {
    if (registry != 0) {
        return TRUE;
    }

    registry = new TransliteratorRegistry(status);
    if (registry == 0 || U_FAILURE(status)) {
        delete registry;
        registry = 0;
        return FALSE; // can't create registry, no recovery
    }

    /* The following code parses the index table located in
     * icu/data/translit/root.txt.  The index is an n x 4 table
     * that follows this format:
     *  <id>{
     *      file{
     *          resource{"<resource>"}
     *          direction{"<direction>"}
     *      }
     *  }
     *  <id>{
     *      internal{
     *          resource{"<resource>"}
     *          direction{"<direction"}
     *       }
     *  }
     *  <id>{
     *      alias{"<getInstanceArg"}
     *  }
     * <id> is the ID of the system transliterator being defined.  These
     * are public IDs enumerated by Transliterator.getAvailableIDs(),
     * unless the second field is "internal".
     * 
     * <resource> is a ResourceReader resource name.  Currently these refer
     * to file names under com/ibm/text/resources.  This string is passed
     * directly to ResourceReader, together with <encoding>.
     * 
     * <direction> is either "FORWARD" or "REVERSE".
     * 
     * <getInstanceArg> is a string to be passed directly to
     * Transliterator.getInstance().  The returned Transliterator object
     * then has its ID changed to <id> and is returned.
     *
     * The extra blank field on "alias" lines is to make the array square.
     */
    //static const char translit_index[] = "translit_index";

    UResourceBundle *bundle, *transIDs, *colBund;
    bundle = ures_open(U_ICUDATA_TRANSLIT, NULL/*open default locale*/, &status);
    transIDs = ures_getByKey(bundle, RB_RULE_BASED_IDS, 0, &status);

    int32_t row, maxRows;
    if (U_SUCCESS(status)) {
        maxRows = ures_getSize(transIDs);
        for (row = 0; row < maxRows; row++) {
            colBund = ures_getByIndex(transIDs, row, 0, &status);
            if (U_SUCCESS(status)) {
                UnicodeString id(ures_getKey(colBund), -1, US_INV);
                UResourceBundle* res = ures_getNextResource(colBund, NULL, &status);
                const char* typeStr = ures_getKey(res);
                UChar type;
                u_charsToUChars(typeStr, &type, 1);

                if (U_SUCCESS(status)) {
                    int32_t len = 0;
                    const UChar *resString;
                    switch (type) {
                    case 0x66: // 'f'
                    case 0x69: // 'i'
                        // 'file' or 'internal';
                        // row[2]=resource, row[3]=direction
                        {
                            
                            resString = ures_getStringByKey(res, "resource", &len, &status);
                            UBool visible = (type == 0x0066 /*f*/);
                            UTransDirection dir = 
                                (ures_getUnicodeStringByKey(res, "direction", &status).charAt(0) ==
                                 0x0046 /*F*/) ?
                                UTRANS_FORWARD : UTRANS_REVERSE;
                            registry->put(id, UnicodeString(TRUE, resString, len), dir, TRUE, visible, status);
                        }
                        break;
                    case 0x61: // 'a'
                        // 'alias'; row[2]=createInstance argument
                        resString = ures_getString(res, &len, &status);
                        registry->put(id, UnicodeString(TRUE, resString, len), TRUE, TRUE, status);
                        break;
                    }
                }
                ures_close(res);
            }
            ures_close(colBund);
        }
    }

    ures_close(transIDs);
    ures_close(bundle);

    // Manually add prototypes that the system knows about to the
    // cache.  This is how new non-rule-based transliterators are
    // added to the system.
    
    // This is to allow for null pointer check
    NullTransliterator* tempNullTranslit = new NullTransliterator();
    LowercaseTransliterator* tempLowercaseTranslit = new LowercaseTransliterator();
    UppercaseTransliterator* tempUppercaseTranslit = new UppercaseTransliterator();
    TitlecaseTransliterator* tempTitlecaseTranslit = new TitlecaseTransliterator();
    UnicodeNameTransliterator* tempUnicodeTranslit = new UnicodeNameTransliterator();
    NameUnicodeTransliterator* tempNameUnicodeTranslit = new NameUnicodeTransliterator();
#if !UCONFIG_NO_BREAK_ITERATION
     // TODO: could or should these transliterators be referenced polymorphically once constructed?
     BreakTransliterator* tempBreakTranslit         = new BreakTransliterator();
#endif
    // Check for null pointers
    if (tempNullTranslit == NULL || tempLowercaseTranslit == NULL || tempUppercaseTranslit == NULL ||
        tempTitlecaseTranslit == NULL || tempUnicodeTranslit == NULL || 
#if !UCONFIG_NO_BREAK_ITERATION
        tempBreakTranslit == NULL ||
#endif
        tempNameUnicodeTranslit == NULL )
    {
        delete tempNullTranslit;
        delete tempLowercaseTranslit;
        delete tempUppercaseTranslit;
        delete tempTitlecaseTranslit;
        delete tempUnicodeTranslit;
        delete tempNameUnicodeTranslit;
#if !UCONFIG_NO_BREAK_ITERATION
        delete tempBreakTranslit;
#endif
        // Since there was an error, remove registry
        delete registry;
        registry = NULL;

        status = U_MEMORY_ALLOCATION_ERROR;
        return 0;
    }

    registry->put(tempNullTranslit, TRUE, status);
    registry->put(tempLowercaseTranslit, TRUE, status);
    registry->put(tempUppercaseTranslit, TRUE, status);
    registry->put(tempTitlecaseTranslit, TRUE, status);
    registry->put(tempUnicodeTranslit, TRUE, status);
    registry->put(tempNameUnicodeTranslit, TRUE, status);
#if !UCONFIG_NO_BREAK_ITERATION
    registry->put(tempBreakTranslit, FALSE, status);   // FALSE means invisible.
#endif

    RemoveTransliterator::registerIDs(); // Must be within mutex
    EscapeTransliterator::registerIDs();
    UnescapeTransliterator::registerIDs();
    NormalizationTransliterator::registerIDs();
    AnyTransliterator::registerIDs();

    _registerSpecialInverse(UNICODE_STRING_SIMPLE("Null"),
                            UNICODE_STRING_SIMPLE("Null"), FALSE);
    _registerSpecialInverse(UNICODE_STRING_SIMPLE("Upper"),
                            UNICODE_STRING_SIMPLE("Lower"), TRUE);
    _registerSpecialInverse(UNICODE_STRING_SIMPLE("Title"),
                            UNICODE_STRING_SIMPLE("Lower"), FALSE);

    ucln_i18n_registerCleanup(UCLN_I18N_TRANSLITERATOR, utrans_transliterator_cleanup);

    return TRUE;
}
Beispiel #15
0
U_CFUNC const char* U_EXPORT2
uprv_detectWindowsTimeZone() {
    UErrorCode status = U_ZERO_ERROR;
    UResourceBundle* bundle = NULL;
    char* icuid = NULL;

    LONG result;
    TZI tziKey;
    TZI tziReg;
    TIME_ZONE_INFORMATION apiTZI;

    /* Obtain TIME_ZONE_INFORMATION from the API, and then convert it
       to TZI.  We could also interrogate the registry directly; we do
       this below if needed. */
    uprv_memset(&apiTZI, 0, sizeof(apiTZI));
    uprv_memset(&tziKey, 0, sizeof(tziKey));
    uprv_memset(&tziReg, 0, sizeof(tziReg));
    GetTimeZoneInformation(&apiTZI);
    tziKey.bias = apiTZI.Bias;
    uprv_memcpy((char *)&tziKey.standardDate, (char*)&apiTZI.StandardDate,
           sizeof(apiTZI.StandardDate));
    uprv_memcpy((char *)&tziKey.daylightDate, (char*)&apiTZI.DaylightDate,
           sizeof(apiTZI.DaylightDate));

    bundle = ures_openDirect(NULL, "supplementalData", &status);
    bundle = ures_getByKey(bundle, "mapTimezones", bundle, &status);
    bundle = ures_getByKey(bundle, "windows", bundle, &status);

    /* Note: We get the winid not from static tables but from resource bundle. */
    while (U_SUCCESS(status) && ures_hasNext(bundle)) {
        const char* winid;
        int32_t len;
        UResourceBundle* winTZ = ures_getNextResource(bundle, NULL, &status);
        if (U_FAILURE(status)) {
            break;
        }
        winid = ures_getKey(winTZ);
        result = getTZI(winid, &tziReg);

        if (result == ERROR_SUCCESS) {
            /* Windows alters the DaylightBias in some situations.
               Using the bias and the rules suffices, so overwrite
               these unreliable fields. */
            tziKey.standardBias = tziReg.standardBias;
            tziKey.daylightBias = tziReg.daylightBias;

            if (uprv_memcmp((char *)&tziKey, (char*)&tziReg, sizeof(tziKey)) == 0) {
                const UChar* icuTZ = ures_getString(winTZ, &len, &status);
                if (U_SUCCESS(status)) {
                    icuid = (char*)uprv_malloc(sizeof(char) * (len + 1));
                    uprv_memset(icuid, 0, len + 1);
                    u_austrncpy(icuid, icuTZ, len);
                }
            }
        }
        ures_close(winTZ);
        if (icuid != NULL) {
            break;
        }
    }

    ures_close(bundle);

    return icuid;
}
// populatePower10 grabs data for a particular power of 10 from CLDR.
// The loaded data is stored in result.
static void populatePower10(const UResourceBundle* power10Bundle, CDFLocaleStyleData* result, UErrorCode& status) {
  if (U_FAILURE(status)) {
    return;
  }
  char* endPtr = NULL;
  double power10 = uprv_strtod(ures_getKey(power10Bundle), &endPtr);
  if (*endPtr != 0) {
    status = U_INTERNAL_PROGRAM_ERROR;
    return;
  }
  int32_t log10Value = computeLog10(power10, FALSE);
  // Silently ignore divisors that are too big.
  if (log10Value == MAX_DIGITS) {
    return;
  }
  int32_t size = ures_getSize(power10Bundle);
  int32_t numZeros = 0;
  UBool otherVariantDefined = FALSE;
  UResourceBundle* variantBundle = NULL;
  // Iterate over all the plural variants for the power of 10
  for (int32_t i = 0; i < size; ++i) {
    variantBundle = ures_getByIndex(power10Bundle, i, variantBundle, &status);
    if (U_FAILURE(status)) {
      ures_close(variantBundle);
      return;
    }
    const char* variant = ures_getKey(variantBundle);
    int32_t resLen;
    const UChar* formatStrP = ures_getString(variantBundle, &resLen, &status);
    if (U_FAILURE(status)) {
      ures_close(variantBundle);
      return;
    }
    UnicodeString formatStr(false, formatStrP, resLen);
    if (uprv_strcmp(variant, gOther) == 0) {
      otherVariantDefined = TRUE;
    }
    int32_t nz = populatePrefixSuffix(
        variant, log10Value, formatStr, result->unitsByVariant, status);
    if (U_FAILURE(status)) {
      ures_close(variantBundle);
      return;
    }
    if (nz != numZeros) {
      // We expect all format strings to have the same number of 0's
      // left of the decimal point.
      if (numZeros != 0) {
        status = U_INTERNAL_PROGRAM_ERROR;
        ures_close(variantBundle);
        return;
      }
      numZeros = nz;
    }
  }
  ures_close(variantBundle);
  // We expect to find an OTHER variant for each power of 10.
  if (!otherVariantDefined) {
    status = U_INTERNAL_PROGRAM_ERROR;
    return;
  }
  double divisor = power10;
  for (int32_t i = 1; i < numZeros; ++i) {
    divisor /= 10.0;
  }
  result->divisors[log10Value] = divisor;
}
Beispiel #17
0
/* Test whether apps and ICU can each have their own root.res */
static void TestAppData()
{
  UResourceBundle *icu, *app;
  UResourceBundle *tmp = NULL;
  UResourceBundle *tmp2 = NULL;
  
  const UChar *appString;
  const UChar *icuString;

  int32_t len;

  UErrorCode status = U_ZERO_ERROR;
  char testMsgBuf[256];

  const char* testPath=loadTestData(&status);

  icu = ures_open(NULL, "root", &status);
  if(U_FAILURE(status))
  { 
     log_err("%s:%d: Couldn't open root ICU bundle- %s", __FILE__, __LINE__, u_errorName(status));
     return;
  }
  /*  log_info("Open icu root: %s size_%d\n", u_errorName(status), ures_getSize(icu)); */
  status = U_ZERO_ERROR;
  
  app = ures_open(testPath, "root", &status);
  if(U_FAILURE(status))
  { 
     log_err("%s:%d: Couldn't open app ICU bundle [%s]- %s", __FILE__, __LINE__, testPath, u_errorName(status));
     return;
  }
  /* log_info("Open  app: %s, size %d\n", u_errorName(status), ures_getSize(app)); */

  tmp = ures_getByKey(icu, "Version", tmp, &status);
  if(U_FAILURE(status))
  { 
     log_err("%s:%d: Couldn't get Version string from ICU root bundle- %s", __FILE__, __LINE__, u_errorName(status));
     return;
  }

  icuString =  ures_getString(tmp,  &len, &status);
  if(U_FAILURE(status))
  { 
     log_err("%s:%d: Couldn't get string from Version string from ICU root bundle- %s", __FILE__, __LINE__, u_errorName(status));
     return;
  }
  /* log_info("icuString=%p - %s\n", icuString, austrdup(icuString)); */


  tmp2 = ures_getByKey(app, "Version", tmp2, &status);
  if(U_FAILURE(status))
  { 
    log_err("%s:%d: Couldn't get Version string from App root bundle- %s", __FILE__, __LINE__, u_errorName(status));
     return;
  }

  appString =  ures_getString(tmp2,  &len, &status);
  if(U_FAILURE(status))
  { 
     log_err("%s:%d: Couldn't get string from Version string from App root bundle- %s", __FILE__, __LINE__, u_errorName(status));
     return;
  }

  /* log_info("appString=%p - %s\n", appString, austrdup(appString)); */


  if(!u_strcmp(icuString, appString))
  {
    log_err("%s:%d: Error! Expected ICU and App root version strings to be DIFFERENT but they are both %s and %s\n", __FILE__, __LINE__, austrdup(icuString),
    austrdup(appString));
  }
  else
  {
    log_verbose("%s:%d:  appstr=%s, icustr=%s\n", __FILE__,
      __LINE__, u_austrcpy(testMsgBuf, appString), u_austrcpy(testMsgBuf, icuString));
  }

  ures_close(tmp);
  ures_close(tmp2);
  ures_close(icu);
  ures_close(app);
}
static jstring getCurrencyCodeNative(JNIEnv* env, jclass clazz, 
        jstring key) {
    // LOGI("ENTER getCurrencyCodeNative");

    UErrorCode status = U_ZERO_ERROR;

    UResourceBundle *supplData = ures_openDirect(NULL, "supplementalData", &status);
    if(U_FAILURE(status)) {
        return NULL;
    }

    UResourceBundle *currencyMap = ures_getByKey(supplData, "CurrencyMap", NULL, &status);
    if(U_FAILURE(status)) {
        ures_close(supplData);
        return NULL;
    }

    const char *keyChars = env->GetStringUTFChars(key, NULL);
    UResourceBundle *currency = ures_getByKey(currencyMap, keyChars, NULL, &status);
    env->ReleaseStringUTFChars(key, keyChars);
    if(U_FAILURE(status)) {
        ures_close(currencyMap);
        ures_close(supplData);
        return NULL;
    }

    UResourceBundle *currencyElem = ures_getByIndex(currency, 0, NULL, &status);
    if(U_FAILURE(status)) {
        ures_close(currency);
        ures_close(currencyMap);
        ures_close(supplData);
        return NULL;
    }

    UResourceBundle *currencyId = ures_getByKey(currencyElem, "id", NULL, &status);
    if(U_FAILURE(status)) {
        ures_close(currencyElem);
        ures_close(currency);
        ures_close(currencyMap);
        ures_close(supplData);
        return NULL;
    }

    int length;
    const jchar *id = ures_getString(currencyId, &length, &status);
    if(U_FAILURE(status)) {
        ures_close(currencyId);
        ures_close(currencyElem);
        ures_close(currency);
        ures_close(currencyMap);
        ures_close(supplData);
        return NULL;
    }

    ures_close(currencyId);
    ures_close(currencyElem);
    ures_close(currency);
    ures_close(currencyMap);
    ures_close(supplData);

    if(length == 0) {
        return NULL;
    }
    return env->NewString(id, length);
}
Beispiel #19
0
U_NAMESPACE_BEGIN

// -------------------------------------

BreakIterator*
BreakIterator::buildInstance(const Locale& loc, const char *type, int32_t kind, UErrorCode &status)
{
    char fnbuff[256];
    char ext[4]={'\0'};
    char actualLocale[ULOC_FULLNAME_CAPACITY];
    int32_t size;
    const UChar* brkfname = NULL;
    UResourceBundle brkRulesStack;
    UResourceBundle brkNameStack;
    UResourceBundle *brkRules = &brkRulesStack;
    UResourceBundle *brkName  = &brkNameStack;
    RuleBasedBreakIterator *result = NULL;

    if (U_FAILURE(status))
        return NULL;

    ures_initStackObject(brkRules);
    ures_initStackObject(brkName);

    // Get the locale
    UResourceBundle *b = ures_open(U_ICUDATA_BRKITR, loc.getName(), &status);
    /* this is a hack for now. Should be fixed when the data is fetched from
        brk_index.txt */
    if(status==U_USING_DEFAULT_WARNING){
        status=U_ZERO_ERROR;
        ures_openFillIn(b, U_ICUDATA_BRKITR, "", &status);
    }

    // Get the "boundaries" array.
    if (U_SUCCESS(status)) {
        brkRules = ures_getByKeyWithFallback(b, "boundaries", brkRules, &status);
        // Get the string object naming the rules file
        brkName = ures_getByKeyWithFallback(brkRules, type, brkName, &status);
        // Get the actual string
        brkfname = ures_getString(brkName, &size, &status);
        U_ASSERT((size_t)size<sizeof(fnbuff));
        if ((size_t)size>=sizeof(fnbuff)) {
            size=0;
            if (U_SUCCESS(status)) {
                status = U_BUFFER_OVERFLOW_ERROR;
            }
        }

        // Use the string if we found it
        if (U_SUCCESS(status) && brkfname) {
            uprv_strncpy(actualLocale,
                ures_getLocale(brkName, &status),
                sizeof(actualLocale)/sizeof(actualLocale[0]));

            UChar* extStart=u_strchr(brkfname, 0x002e);
            int len = 0;
            if(extStart!=NULL){
                len = (int)(extStart-brkfname);
                u_UCharsToChars(extStart+1, ext, sizeof(ext)); // nul terminates the buff
                u_UCharsToChars(brkfname, fnbuff, len);
            }
            fnbuff[len]=0; // nul terminate
        }
    }

    ures_close(brkRules);
    ures_close(brkName);

    UDataMemory* file = udata_open(U_ICUDATA_BRKITR, ext, fnbuff, &status);
    if (U_FAILURE(status)) {
        ures_close(b);
        return NULL;
    }

    // Create a RuleBasedBreakIterator
    result = new RuleBasedBreakIterator(file, status);

    // If there is a result, set the valid locale and actual locale, and the kind
    if (U_SUCCESS(status) && result != NULL) {
        U_LOCALE_BASED(locBased, *(BreakIterator*)result);
        locBased.setLocaleIDs(ures_getLocaleByType(b, ULOC_VALID_LOCALE, &status), actualLocale);
        result->setBreakType(kind);
    }

    ures_close(b);

    if (U_FAILURE(status) && result != NULL) {  // Sometimes redundant check, but simple
        delete result;
        return NULL;
    }

    if (result == NULL) {
        udata_close(file);
        if (U_SUCCESS(status)) {
            status = U_MEMORY_ALLOCATION_ERROR;
        }
    }

    return result;
}
UnicodeString ResourceBundle::getString(UErrorCode& status) const {
    int32_t len = 0;
    const UChar *r = ures_getString(fResource, &len, &status);
    return UnicodeString(TRUE, r, len);
}