示例#1
0
    virtual void put(const char *key, ResourceValue &value, UBool, UErrorCode &errorCode) {
        ResourceTable dayPeriodData = value.getTable(errorCode);
        if (U_FAILURE(errorCode)) { return; }

        for (int32_t i = 0; dayPeriodData.getKeyAndValue(i, key, value); ++i) {
            if (uprv_strcmp(key, "locales") == 0) {
                ResourceTable locales = value.getTable(errorCode);
                if (U_FAILURE(errorCode)) { return; }

                for (int32_t j = 0; locales.getKeyAndValue(j, key, value); ++j) {
                    UnicodeString setNum_str = value.getUnicodeString(errorCode);
                    int32_t setNum = parseSetNum(setNum_str, errorCode);
                    uhash_puti(data->localeToRuleSetNumMap, const_cast<char *>(key), setNum, &errorCode);
                }
            } else if (uprv_strcmp(key, "rules") == 0) {
                // Allocate one more than needed to skip [0]. See comment in parseSetNum().
                data->rules = new DayPeriodRules[data->maxRuleSetNum + 1];
                if (data->rules == NULL) {
                    errorCode = U_MEMORY_ALLOCATION_ERROR;
                    return;
                }
                ResourceTable rules = value.getTable(errorCode);
                processRules(rules, key, value, errorCode);
                if (U_FAILURE(errorCode)) { return; }
            }
        }
    }
示例#2
0
StringTrieBuilder::Node *
StringTrieBuilder::registerFinalValue(int32_t value, UErrorCode &errorCode) {
    if(U_FAILURE(errorCode)) {
        return NULL;
    }
    FinalValueNode key(value);
    const UHashElement *old=uhash_find(nodes, &key);
    if(old!=NULL) {
        return (Node *)old->key.pointer;
    }
    Node *newNode=new FinalValueNode(value);
    if(newNode==NULL) {
        errorCode=U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }
    // If uhash_puti() returns a non-zero value from an equivalent, previously
    // registered node, then uhash_find() failed to find that and we will leak newNode.
#if !U_RELEASE
    int32_t oldValue=  // Only in debug mode to avoid a compiler warning about unused oldValue.
#endif
    uhash_puti(nodes, newNode, 1, &errorCode);
    U_ASSERT(oldValue==0);
    if(U_FAILURE(errorCode)) {
        delete newNode;
        return NULL;
    }
    return newNode;
}
示例#3
0
        virtual void put(const char *key, const ResourceValue &value, UErrorCode &errorCode) {
            if (U_FAILURE(errorCode)) { return; }

            UnicodeString setNum_str = value.getUnicodeString(errorCode);
            int32_t setNum = parseSetNum(setNum_str, errorCode);
            uhash_puti(data->localeToRuleSetNumMap, const_cast<char *>(key), setNum, &errorCode);
        }
示例#4
0
static void _put(UHashtable* hash,
          const char* key,
          int32_t value,
          int32_t expectedOldValue) {
    UErrorCode status = U_ZERO_ERROR;
    int32_t oldValue =
        uhash_puti(hash, (void*) key, value, &status);
    if (U_FAILURE(status)) {
        log_err("FAIL: uhash_put(%s) failed with %s and returned %ld\n",
                key, u_errorName(status), oldValue);
    } else if (oldValue != expectedOldValue) {
        log_err("FAIL: uhash_put(%s) returned old value %ld; expected %ld\n",
                key, oldValue, expectedOldValue);
    } else {
        log_verbose("Ok: uhash_put(%s, %d) returned old value %ld\n",
                    key, value, oldValue);
    }
}
示例#5
0
 int32_t writeValueAliases(const Value &value, UErrorCode &errorCode) {
     int32_t nameOffset=uhash_geti(nameGroupToOffset, (void *)value.joinedAliases);
     if(nameOffset!=0) {
         // The same list of aliases has been written already.
         return nameOffset-1;  // Was incremented to reserve 0 for "not found".
     }
     // Write this not-yet-seen list of aliases.
     nameOffset=nameGroups.length();
     uhash_puti(nameGroupToOffset, (void *)value.joinedAliases,
                nameOffset+1, &errorCode);
     // The first byte tells us how many aliases there are.
     // We use only values 0..0x1f in the first byte because when we write
     // the name groups as an invariant-character string into a source file,
     // those values (C0 control codes) are written as numbers rather than as characters.
     int32_t count=value.count;
     if(count>=0x20) {
         fprintf(stderr, "Error: Too many aliases in \"%s\"\n", value.joinedAliases);
         exit(U_INDEX_OUTOFBOUNDS_ERROR);
     }
     nameGroups.append((char)count, errorCode);
     // There is at least a short name (sometimes empty) and a long name. (count>=2)
     // Note: Sometimes the short and long names are the same.
     // In such a case, we could set a flag and omit the duplicate,
     // but that would save only about 1.35% of total data size (Unicode 6.0/ICU 4.6)
     // which is not worth the trouble.
     // Note: In Unicode 6.1, there are more duplicates due to newly added
     // short names for blocks and other properties.
     // It might now be worth changing the data structure.
     for(int32_t i=0; i<count; ++i) {
         const char *s=value.aliases[i];
         int32_t sLength=uprv_strlen(s)+1;
         if(sLength>maxNameLength) {
             maxNameLength=sLength;
         }
         nameGroups.append(s, sLength, errorCode);  // including NUL
     }
     return nameOffset;
 }
示例#6
0
IdentifierInfo &IdentifierInfo::setIdentifier(const UnicodeString &identifier, UErrorCode &status) {
    if (U_FAILURE(status)) {
        return *this;
    }
    *fIdentifier = identifier;
    clear();
    ScriptSet scriptsForCP;
    UChar32 cp;
    for (int32_t i = 0; i < identifier.length(); i += U16_LENGTH(cp)) {
        cp = identifier.char32At(i);
        // Store a representative character for each kind of decimal digit
        if (u_charType(cp) == U_DECIMAL_DIGIT_NUMBER) {
            // Just store the zero character as a representative for comparison. Unicode guarantees it is cp - value
            fNumerics->add(cp - (UChar32)u_getNumericValue(cp));
        }
        UScriptCode extensions[500];
        int32_t extensionsCount = uscript_getScriptExtensions(cp, extensions, UPRV_LENGTHOF(extensions), &status);
        if (U_FAILURE(status)) {
            return *this;
        }
        scriptsForCP.resetAll();
        for (int32_t j=0; j<extensionsCount; j++) {
            scriptsForCP.set(extensions[j], status);
        }
        scriptsForCP.reset(USCRIPT_COMMON, status);
        scriptsForCP.reset(USCRIPT_INHERITED, status);
        switch (scriptsForCP.countMembers()) {
          case 0: break;
          case 1:
            // Single script, record it.
            fRequiredScripts->Union(scriptsForCP);
            break;
          default:
            if (!fRequiredScripts->intersects(scriptsForCP) 
                    && !uhash_geti(fScriptSetSet, &scriptsForCP)) {
                // If the set hasn't been added already, add it
                //    (Add a copy, fScriptSetSet takes ownership of the copy.)
                uhash_puti(fScriptSetSet, new ScriptSet(scriptsForCP), 1, &status);
            }
            break;
        }
    }
    // Now make a final pass through ScriptSetSet to remove alternates that came before singles.
    // [Kana], [Kana Hira] => [Kana]
    // This is relatively infrequent, so doesn't have to be optimized.
    // We also compute any commonalities among the alternates.
    if (uhash_count(fScriptSetSet) > 0) {
        fCommonAmongAlternates->setAll();
        for (int32_t it = UHASH_FIRST;;) {
            const UHashElement *nextHashEl = uhash_nextElement(fScriptSetSet, &it);
            if (nextHashEl == NULL) {
                break;
            }
            ScriptSet *next = static_cast<ScriptSet *>(nextHashEl->key.pointer);
            // [Kana], [Kana Hira] => [Kana]
            if (fRequiredScripts->intersects(*next)) {
                uhash_removeElement(fScriptSetSet, nextHashEl);
            } else {
                fCommonAmongAlternates->intersect(*next);
                // [[Arab Syrc Thaa]; [Arab Syrc]] => [[Arab Syrc]]
                for (int32_t otherIt = UHASH_FIRST;;) {
                    const UHashElement *otherHashEl = uhash_nextElement(fScriptSetSet, &otherIt);
                    if (otherHashEl == NULL) {
                        break;
                    }
                    ScriptSet *other = static_cast<ScriptSet *>(otherHashEl->key.pointer);
                    if (next != other && next->contains(*other)) {
                        uhash_removeElement(fScriptSetSet, nextHashEl);
                        break;
                    }
                }
            }
        }
    }
    if (uhash_count(fScriptSetSet) == 0) {
        fCommonAmongAlternates->resetAll();
    }
    return *this;
}
示例#7
0
//--------------------------------------------------------------------------
//
//    Assignment Operator
//
//--------------------------------------------------------------------------
RegexPattern &RegexPattern::operator = (const RegexPattern &other) {
    if (this == &other) {
        // Source and destination are the same.  Don't do anything.
        return *this;
    }

    // Clean out any previous contents of object being assigned to.
    zap();

    // Give target object a default initialization
    init();

    // Copy simple fields
    fDeferredStatus   = other.fDeferredStatus;

    if (U_FAILURE(fDeferredStatus)) {
        return *this;
    }

    if (other.fPatternString == NULL) {
        fPatternString = NULL;
        fPattern = utext_clone(fPattern, other.fPattern, FALSE, TRUE, &fDeferredStatus);
    } else {
        fPatternString = new UnicodeString(*(other.fPatternString));
        if (fPatternString == NULL) {
            fDeferredStatus = U_MEMORY_ALLOCATION_ERROR;
        } else {
            fPattern = utext_openConstUnicodeString(NULL, fPatternString, &fDeferredStatus);
        }
    }
    if (U_FAILURE(fDeferredStatus)) {
        return *this;
    }

    fFlags            = other.fFlags;
    fLiteralText      = other.fLiteralText;
    fMinMatchLen      = other.fMinMatchLen;
    fFrameSize        = other.fFrameSize;
    fDataSize         = other.fDataSize;
    fStaticSets       = other.fStaticSets;
    fStaticSets8      = other.fStaticSets8;

    fStartType        = other.fStartType;
    fInitialStringIdx = other.fInitialStringIdx;
    fInitialStringLen = other.fInitialStringLen;
    *fInitialChars    = *other.fInitialChars;
    fInitialChar      = other.fInitialChar;
    *fInitialChars8   = *other.fInitialChars8;
    fNeedsAltInput    = other.fNeedsAltInput;

    //  Copy the pattern.  It's just values, nothing deep to copy.
    fCompiledPat->assign(*other.fCompiledPat, fDeferredStatus);
    fGroupMap->assign(*other.fGroupMap, fDeferredStatus);

    //  Copy the Unicode Sets.
    //    Could be made more efficient if the sets were reference counted and shared,
    //    but I doubt that pattern copying will be particularly common.
    //    Note:  init() already added an empty element zero to fSets
    int32_t i;
    int32_t  numSets = other.fSets->size();
    fSets8 = new Regex8BitSet[numSets];
    if (fSets8 == NULL) {
    	fDeferredStatus = U_MEMORY_ALLOCATION_ERROR;
    	return *this;
    }
    for (i=1; i<numSets; i++) {
        if (U_FAILURE(fDeferredStatus)) {
            return *this;
        }
        UnicodeSet *sourceSet = (UnicodeSet *)other.fSets->elementAt(i);
        UnicodeSet *newSet    = new UnicodeSet(*sourceSet);
        if (newSet == NULL) {
            fDeferredStatus = U_MEMORY_ALLOCATION_ERROR;
            break;
        }
        fSets->addElement(newSet, fDeferredStatus);
        fSets8[i] = other.fSets8[i];
    }

    // Copy the named capture group hash map.
    int32_t hashPos = UHASH_FIRST;
    while (const UHashElement *hashEl = uhash_nextElement(other.fNamedCaptureMap, &hashPos)) {
        if (U_FAILURE(fDeferredStatus)) {
            break;
        }
        const UnicodeString *name = (const UnicodeString *)hashEl->key.pointer;
        UnicodeString *key = new UnicodeString(*name);
        int32_t val = hashEl->value.integer;
        if (key == NULL) {
            fDeferredStatus = U_MEMORY_ALLOCATION_ERROR;
        } else {
            uhash_puti(fNamedCaptureMap, key, val, &fDeferredStatus);
        }
    }
    return *this;
}
示例#8
0
static void TestOtherAPI(void){
    
    UErrorCode status = U_ZERO_ERROR;
    UHashtable *hash;

    /* Use the correct type when cast to void * */
    const UChar one[4]   = {0x006F, 0x006E, 0x0065, 0}; /* L"one" */
    const UChar one2[4]  = {0x006F, 0x006E, 0x0065, 0}; /* Get around compiler optimizations */
    const UChar two[4]   = {0x0074, 0x0077, 0x006F, 0}; /* L"two" */
    const UChar two2[4]  = {0x0074, 0x0077, 0x006F, 0}; /* L"two" */
    const UChar three[6] = {0x0074, 0x0068, 0x0072, 0x0065, 0x0065, 0}; /* L"three" */
    const UChar four[6]  = {0x0066, 0x006F, 0x0075, 0x0072, 0}; /* L"four" */
    const UChar five[6]  = {0x0066, 0x0069, 0x0076, 0x0065, 0}; /* L"five" */
    const UChar five2[6] = {0x0066, 0x0069, 0x0076, 0x0065, 0}; /* L"five" */

    hash = uhash_open(uhash_hashUChars, uhash_compareUChars,  &status);
    if (U_FAILURE(status)) {
        log_err("FAIL: uhash_open failed with %s and returned 0x%08x\n",
                u_errorName(status), hash);
        return;
    }
    if (hash == NULL) {
        log_err("FAIL: uhash_open returned NULL\n");
        return;
    }
    log_verbose("Ok: uhash_open returned 0x%08X\n", hash);

    uhash_puti(hash, (void*)one, 1, &status);
    if(uhash_count(hash) != 1){
         log_err("FAIL: uhas_count() failed. Expected: 1, Got: %d\n", uhash_count(hash));
     }
    uhash_puti(hash, (void*)two, 2, &status);
    uhash_puti(hash, (void*)three, 3, &status);
    uhash_puti(hash, (void*)four, 4, &status);
    uhash_puti(hash, (void*)five, 5, &status);
    
    if(uhash_count(hash) != 5){
        log_err("FAIL: uhas_count() failed. Expected: 5, Got: %d\n", uhash_count(hash));
    }
    
    if(uhash_geti(hash, (void*)two2) != 2){
        log_err("FAIL: uhash_geti failed\n");
    }
    
    if(uhash_removei(hash, (void*)five2) != 5){
        log_err("FAIL: uhash_remove() failed\n");
    }
    if(uhash_count(hash) != 4){
        log_err("FAIL: uhas_count() failed. Expected: 4, Got: %d\n", uhash_count(hash));
    }

    uhash_put(hash, (void*)one, NULL, &status);
    if(uhash_count(hash) != 3){
        log_err("FAIL: uhash_put() with value=NULL didn't remove the key value pair\n");
    }
    status=U_ILLEGAL_ARGUMENT_ERROR;
    uhash_puti(hash, (void*)one, 1, &status);
    if(uhash_count(hash) != 3){
        log_err("FAIL: uhash_put() with value!=NULL should fail when status != U_ZERO_ERROR \n");
    }
    
    status=U_ZERO_ERROR;
    uhash_puti(hash, (void*)one, 1, &status);
    if(uhash_count(hash) != 4){
        log_err("FAIL: uhash_put() with value!=NULL didn't replace the key value pair\n");
    }

    if(_compareUChars((void*)one, (void*)two) == TRUE ||
        _compareUChars((void*)one, (void*)one) != TRUE ||
        _compareUChars((void*)one, (void*)one2) != TRUE ||
        _compareUChars((void*)one, NULL) == TRUE  )  {
        log_err("FAIL: compareUChars failed\n");
    }
   
    uhash_removeAll(hash);
    if(uhash_count(hash) != 0){
        log_err("FAIL: uhas_count() failed. Expected: 0, Got: %d\n", uhash_count(hash));
    }

    uhash_setKeyComparator(hash, uhash_compareLong);
    uhash_setKeyHasher(hash, uhash_hashLong);
    uhash_iputi(hash, 1001, 1, &status);
    uhash_iputi(hash, 1002, 2, &status);
    uhash_iputi(hash, 1003, 3, &status);
    if(_compareLong(1001, 1002) == TRUE ||
        _compareLong(1001, 1001) != TRUE ||
        _compareLong(1001, 0) == TRUE  )  {
        log_err("FAIL: compareLong failed\n");
    }
    /*set the resize policy to just GROW and SHRINK*/
         /*how to test this??*/
    uhash_setResizePolicy(hash, U_GROW_AND_SHRINK);
    uhash_iputi(hash, 1004, 4, &status);
    uhash_iputi(hash, 1005, 5, &status);
    uhash_iputi(hash, 1006, 6, &status);
    if(uhash_count(hash) != 6){
        log_err("FAIL: uhash_count() failed. Expected: 6, Got: %d\n", uhash_count(hash));
    }
    if(uhash_iremovei(hash, 1004) != 4){
        log_err("FAIL: uhash_remove failed\n");
    }
    if(uhash_iremovei(hash, 1004) != 0){
        log_err("FAIL: uhash_remove failed\n");
    }
    uhash_close(hash);

}
void PluralRulesTest::testAvailbleLocales() {
    
    // Hash set of (char *) strings.
    UErrorCode status = U_ZERO_ERROR;
    UHashtable *localeSet = uhash_open(uhash_hashUnicodeString, uhash_compareUnicodeString, uhash_compareLong, &status);
    uhash_setKeyDeleter(localeSet, uprv_deleteUObject);
    if (U_FAILURE(status)) {
        errln("file %s,  line %d: Error status = %s", __FILE__, __LINE__, u_errorName(status));
        return;
    }

    // Check that each locale returned by the iterator is unique.
    StringEnumeration *localesEnum = PluralRules::getAvailableLocales(status);
    int localeCount = 0;
    for (;;) {
        const char *locale = localesEnum->next(NULL, status);
        if (U_FAILURE(status)) {
            dataerrln("file %s,  line %d: Error status = %s", __FILE__, __LINE__, u_errorName(status));
            return;
        }
        if (locale == NULL) {
            break;
        }
        localeCount++;
        int32_t oldVal = uhash_puti(localeSet, new UnicodeString(locale), 1, &status);
        if (oldVal != 0) {
            errln("file %s,  line %d: locale %s was seen before.", __FILE__, __LINE__, locale);
        }
    }

    // Reset the iterator, verify that we get the same count.
    localesEnum->reset(status);
    int32_t localeCount2 = 0;
    while (localesEnum->next(NULL, status) != NULL) {
        if (U_FAILURE(status)) {
            errln("file %s,  line %d: Error status = %s", __FILE__, __LINE__, u_errorName(status));
            break;
        }
        localeCount2++;
    }
    if (localeCount != localeCount2) {
        errln("file %s,  line %d: locale counts differ. They are (%d, %d)", 
            __FILE__, __LINE__, localeCount, localeCount2);
    }

    // Instantiate plural rules for each available locale.
    localesEnum->reset(status);
    for (;;) {
        status = U_ZERO_ERROR;
        const char *localeName = localesEnum->next(NULL, status);
        if (U_FAILURE(status)) {
            errln("file %s,  line %d: Error status = %s, locale = %s",
                __FILE__, __LINE__, u_errorName(status), localeName);
            return;
        }
        if (localeName == NULL) {
            break;
        }
        Locale locale = Locale::createFromName(localeName);
        PluralRules *pr = PluralRules::forLocale(locale, status);
        if (U_FAILURE(status)) {
            errln("file %s,  line %d: Error %s creating plural rules for locale %s", 
                __FILE__, __LINE__, u_errorName(status), localeName);
            continue;
        }
        if (pr == NULL) {
            errln("file %s, line %d: Null plural rules for locale %s", __FILE__, __LINE__, localeName);
            continue;
        }

        // Pump some numbers through the plural rules.  Can't check for correct results, 
        // mostly this to tickle any asserts or crashes that may be lurking.
        for (double n=0; n<120.0; n+=0.5) {
            UnicodeString keyword = pr->select(n);
            if (keyword.length() == 0) {
                errln("file %s, line %d, empty keyword for n = %g, locale %s",
                    __FILE__, __LINE__, n, localeName);
            }
        }
        delete pr;
    }

    uhash_close(localeSet);
    delete localesEnum;

}