示例#1
0
文件: usprep.cpp 项目: Botyto/Core
static int32_t
usprep_internal_flushCache(UBool noRefCount)
{
	UStringPrepProfile * profile = NULL;
	UStringPrepKey * key  = NULL;
	int32_t pos = -1;
	int32_t deletedNum = 0;
	const UHashElement * e;

	/*
	 * if shared data hasn't even been lazy evaluated yet
	 * return 0
	 */
	umtx_lock(&usprepMutex);
	if (SHARED_DATA_HASHTABLE == NULL)
	{
		umtx_unlock(&usprepMutex);
		return 0;
	}

	/*creates an enumeration to iterate through every element in the table */
	while ((e = uhash_nextElement(SHARED_DATA_HASHTABLE, &pos)) != NULL)
	{
		profile = (UStringPrepProfile *) e->value.pointer;
		key  = (UStringPrepKey *) e->key.pointer;

		if ((noRefCount == FALSE && profile->refCount == 0) ||
		    noRefCount == TRUE)
		{
			deletedNum++;
			uhash_removeElement(SHARED_DATA_HASHTABLE, e);

			/* unload the data */
			usprep_unload(profile);

			if (key->name != NULL)
			{
				uprv_free(key->name);
				key->name = NULL;
			}
			if (key->path != NULL)
			{
				uprv_free(key->path);
				key->path = NULL;
			}
			uprv_free(profile);
			uprv_free(key);
		}

	}
	umtx_unlock(&usprepMutex);

	return deletedNum;
}
示例#2
0
文件: usprep.cpp 项目: basti1302/node
static UStringPrepProfile*
usprep_getProfile(const char* path,
                  const char* name,
                  UErrorCode *status){

    UStringPrepProfile* profile = NULL;

    initCache(status);

    if(U_FAILURE(*status)){
        return NULL;
    }

    UStringPrepKey stackKey;
    /*
     * const is cast way to save malloc, strcpy and free calls
     * we use the passed in pointers for fetching the data from the
     * hash table which is safe
     */
    stackKey.name = (char*) name;
    stackKey.path = (char*) path;

    /* fetch the data from the cache */
    umtx_lock(usprepMutex());
    profile = (UStringPrepProfile*) (uhash_get(SHARED_DATA_HASHTABLE,&stackKey));
    if(profile != NULL) {
        profile->refCount++;
    }
    umtx_unlock(usprepMutex());

    if(profile == NULL) {
        /* else load the data and put the data in the cache */
        LocalMemory<UStringPrepProfile> newProfile;
        if(newProfile.allocateInsteadAndReset() == NULL) {
            *status = U_MEMORY_ALLOCATION_ERROR;
            return NULL;
        }

        /* load the data */
        if(!loadData(newProfile.getAlias(), path, name, _SPREP_DATA_TYPE, status) || U_FAILURE(*status) ){
            return NULL;
        }

        /* get the options */
        newProfile->doNFKC = (UBool)((newProfile->indexes[_SPREP_OPTIONS] & _SPREP_NORMALIZATION_ON) > 0);
        newProfile->checkBiDi = (UBool)((newProfile->indexes[_SPREP_OPTIONS] & _SPREP_CHECK_BIDI_ON) > 0);

        LocalMemory<UStringPrepKey> key;
        LocalMemory<char> keyName;
        LocalMemory<char> keyPath;
        if( key.allocateInsteadAndReset() == NULL ||
            keyName.allocateInsteadAndCopy(static_cast<int32_t>(uprv_strlen(name)+1)) == NULL ||
            (path != NULL &&
             keyPath.allocateInsteadAndCopy(static_cast<int32_t>(uprv_strlen(path)+1)) == NULL)
         ) {
            *status = U_MEMORY_ALLOCATION_ERROR;
            usprep_unload(newProfile.getAlias());
            return NULL;
        }

        umtx_lock(usprepMutex());
        // If another thread already inserted the same key/value, refcount and cleanup our thread data
        profile = (UStringPrepProfile*) (uhash_get(SHARED_DATA_HASHTABLE,&stackKey));
        if(profile != NULL) {
            profile->refCount++;
            usprep_unload(newProfile.getAlias());
        }
        else {
            /* initialize the key members */
            key->name = keyName.orphan();
            uprv_strcpy(key->name, name);
            if(path != NULL){
                key->path = keyPath.orphan();
                uprv_strcpy(key->path, path);
            }
            profile = newProfile.orphan();

            /* add the data object to the cache */
            profile->refCount = 1;
            uhash_put(SHARED_DATA_HASHTABLE, key.orphan(), profile, status);
        }
        umtx_unlock(usprepMutex());
    }

    return profile;
}
示例#3
0
static UStringPrepProfile*
usprep_getProfile(const char* path,
                  const char* name,
                  UErrorCode *status){

    UStringPrepProfile* profile = NULL;

    initCache(status);

    if(U_FAILURE(*status)){
        return NULL;
    }

    UStringPrepKey stackKey;
    /*
     * const is cast way to save malloc, strcpy and free calls
     * we use the passed in pointers for fetching the data from the
     * hash table which is safe
     */
    stackKey.name = (char*) name;
    stackKey.path = (char*) path;

    /* fetch the data from the cache */
    profile = (UStringPrepProfile*) (uhash_get(SHARED_DATA_HASHTABLE,&stackKey));

    if(profile == NULL){
        UStringPrepKey* key   = (UStringPrepKey*) uprv_malloc(sizeof(UStringPrepKey));
        if(key == NULL){
            *status = U_MEMORY_ALLOCATION_ERROR;
            return NULL;
        }
        /* else load the data and put the data in the cache */
        profile = (UStringPrepProfile*) uprv_malloc(sizeof(UStringPrepProfile));
        if(profile == NULL){
            *status = U_MEMORY_ALLOCATION_ERROR;
            uprv_free(key);
            return NULL;
        }

        /* initialize the data struct members */
        uprv_memset(profile->indexes,0,sizeof(profile->indexes));
        profile->mappingData = NULL;
        profile->sprepData   = NULL;
        profile->refCount    = 0;

        /* initialize the  key memebers */
        key->name  = (char*) uprv_malloc(uprv_strlen(name)+1);
        if(key->name == NULL){
            *status = U_MEMORY_ALLOCATION_ERROR;
            uprv_free(key);
            uprv_free(profile);
            return NULL;
        }

        uprv_strcpy(key->name, name);

        key->path=NULL;

        if(path != NULL){
            key->path      = (char*) uprv_malloc(uprv_strlen(path)+1);
            if(key->path == NULL){
                *status = U_MEMORY_ALLOCATION_ERROR;
                uprv_free(key->path);
                uprv_free(key);
                uprv_free(profile);
                return NULL;
            }
            uprv_strcpy(key->path, path);
        }

        /* load the data */
        if(!loadData(profile, path, name, _SPREP_DATA_TYPE, status) || U_FAILURE(*status) ){
            return NULL;
        }

        /* get the options */
        profile->doNFKC            = (UBool)((profile->indexes[_SPREP_OPTIONS] & _SPREP_NORMALIZATION_ON) > 0);
        profile->checkBiDi         = (UBool)((profile->indexes[_SPREP_OPTIONS] & _SPREP_CHECK_BIDI_ON) > 0);

        if(profile->checkBiDi) {
            profile->bdp = ubidi_getSingleton(status);
            if(U_FAILURE(*status)) {
                usprep_unload(profile);
                uprv_free(key->path);
                uprv_free(key);
                uprv_free(profile);
                return NULL;
            }
        } else {
            profile->bdp = NULL;
        }

        umtx_lock(&usprepMutex);
        /* add the data object to the cache */
        uhash_put(SHARED_DATA_HASHTABLE, key, profile, status);
        umtx_unlock(&usprepMutex);
    }
    umtx_lock(&usprepMutex);
    /* increment the refcount */
    profile->refCount++;
    umtx_unlock(&usprepMutex);

    return profile;
}