diff options
author | Liong Sauw Ming <ming@teluu.com> | 2012-07-18 07:52:33 +0000 |
---|---|---|
committer | Liong Sauw Ming <ming@teluu.com> | 2012-07-18 07:52:33 +0000 |
commit | c1eabb7ee738b17cf6fd66e761a9269cb7582434 (patch) | |
tree | d23bc2d4b3616f8ff55fb193b4a44d452e34e152 /pjlib/src/pj/hash.c | |
parent | bf66ba19d4ad1a3ccfd3e8a5e68c62b82a56a037 (diff) |
Fixed #1556: Fix From/To tag and Via branch comparison to be case insensitive
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4208 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjlib/src/pj/hash.c')
-rw-r--r-- | pjlib/src/pj/hash.c | 96 |
1 files changed, 65 insertions, 31 deletions
diff --git a/pjlib/src/pj/hash.c b/pjlib/src/pj/hash.c index d22bf421..7ad339be 100644 --- a/pjlib/src/pj/hash.c +++ b/pjlib/src/pj/hash.c @@ -79,16 +79,21 @@ PJ_DEF(pj_uint32_t) pj_hash_calc_tolower( pj_uint32_t hval, #if defined(PJ_HASH_USE_OWN_TOLOWER) && PJ_HASH_USE_OWN_TOLOWER != 0 for (i=0; i<key->slen; ++i) { pj_uint8_t c = key->ptr[i]; + char lower; if (c & 64) - result[i] = (char)(c | 32); + lower = (char)(c | 32); else - result[i] = (char)c; - hval = hval * PJ_HASH_MULTIPLIER + result[i]; + lower = (char)c; + if (result) + result[i] = lower; + hval = hval * PJ_HASH_MULTIPLIER + lower; } #else for (i=0; i<key->slen; ++i) { - result[i] = (char)pj_tolower(key->ptr[i]); - hval = hval * PJ_HASH_MULTIPLIER + result[i]; + char lower = (char)pj_tolower(key->ptr[i]); + if (result) + result[i] = lower; + hval = hval * PJ_HASH_MULTIPLIER + lower; } #endif @@ -128,7 +133,7 @@ PJ_DEF(pj_hash_table_t*) pj_hash_create(pj_pool_t *pool, unsigned size) static pj_hash_entry **find_entry( pj_pool_t *pool, pj_hash_table_t *ht, const void *key, unsigned keylen, void *val, pj_uint32_t *hval, - void *entry_buf) + void *entry_buf, pj_bool_t lower) { pj_uint32_t hash; pj_hash_entry **p_entry, *entry; @@ -146,14 +151,20 @@ static pj_hash_entry **find_entry( pj_pool_t *pool, pj_hash_table_t *ht, if (keylen==PJ_HASH_KEY_STRING) { const pj_uint8_t *p = (const pj_uint8_t*)key; for ( ; *p; ++p ) { - hash = hash * PJ_HASH_MULTIPLIER + *p; + if (lower) + hash = hash * PJ_HASH_MULTIPLIER + pj_tolower(*p); + else + hash = hash * PJ_HASH_MULTIPLIER + *p; } keylen = p - (const unsigned char*)key; } else { const pj_uint8_t *p = (const pj_uint8_t*)key, *end = p + keylen; for ( ; p!=end; ++p) { - hash = hash * PJ_HASH_MULTIPLIER + *p; + if (lower) + hash = hash * PJ_HASH_MULTIPLIER + pj_tolower(*p); + else + hash = hash * PJ_HASH_MULTIPLIER + *p; } } @@ -167,8 +178,15 @@ static pj_hash_entry **find_entry( pj_pool_t *pool, pj_hash_table_t *ht, entry; p_entry = &entry->next, entry = *p_entry) { + pj_str_t str; + + if (lower) { + str.ptr = (char *)entry->key; + str.slen = keylen; + } if (entry->hash==hash && entry->keylen==keylen && - pj_memcmp(entry->key, key, keylen)==0) + ((lower && pj_strnicmp2(&str, (const char *)key, keylen)==0) || + (!lower && pj_memcmp(entry->key, key, keylen)==0))) { break; } @@ -214,17 +232,27 @@ PJ_DEF(void *) pj_hash_get( pj_hash_table_t *ht, pj_uint32_t *hval) { pj_hash_entry *entry; - entry = *find_entry( NULL, ht, key, keylen, NULL, hval, NULL); + entry = *find_entry( NULL, ht, key, keylen, NULL, hval, NULL, PJ_FALSE); return entry ? entry->value : NULL; } -PJ_DEF(void) pj_hash_set( pj_pool_t *pool, pj_hash_table_t *ht, - const void *key, unsigned keylen, pj_uint32_t hval, - void *value ) +PJ_DEF(void *) pj_hash_get_lower( pj_hash_table_t *ht, + const void *key, unsigned keylen, + pj_uint32_t *hval) +{ + pj_hash_entry *entry; + entry = *find_entry( NULL, ht, key, keylen, NULL, hval, NULL, PJ_TRUE); + return entry ? entry->value : NULL; +} + +static void hash_set( pj_pool_t *pool, pj_hash_table_t *ht, + const void *key, unsigned keylen, pj_uint32_t hval, + void *value, void *entry_buf, pj_bool_t lower ) { pj_hash_entry **p_entry; - p_entry = find_entry( pool, ht, key, keylen, value, &hval, NULL); + p_entry = find_entry( pool, ht, key, keylen, value, &hval, entry_buf, + lower); if (*p_entry) { if (value == NULL) { /* delete entry */ @@ -241,29 +269,35 @@ PJ_DEF(void) pj_hash_set( pj_pool_t *pool, pj_hash_table_t *ht, } } +PJ_DEF(void) pj_hash_set( pj_pool_t *pool, pj_hash_table_t *ht, + const void *key, unsigned keylen, pj_uint32_t hval, + void *value ) +{ + hash_set(pool, ht, key, keylen, hval, value, NULL, PJ_FALSE); +} + +PJ_DEF(void) pj_hash_set_lower( pj_pool_t *pool, pj_hash_table_t *ht, + const void *key, unsigned keylen, + pj_uint32_t hval, void *value ) +{ + hash_set(pool, ht, key, keylen, hval, value, NULL, PJ_TRUE); +} + PJ_DEF(void) pj_hash_set_np( pj_hash_table_t *ht, const void *key, unsigned keylen, pj_uint32_t hval, pj_hash_entry_buf entry_buf, void *value) { - pj_hash_entry **p_entry; + hash_set(NULL, ht, key, keylen, hval, value, (void *)entry_buf, PJ_FALSE); +} - p_entry = find_entry( NULL, ht, key, keylen, value, &hval, - (void*)entry_buf ); - if (*p_entry) { - if (value == NULL) { - /* delete entry */ - PJ_LOG(6, ("hashtbl", "%p: p_entry %p deleted", ht, *p_entry)); - *p_entry = (*p_entry)->next; - --ht->count; - - } else { - /* overwrite */ - (*p_entry)->value = value; - PJ_LOG(6, ("hashtbl", "%p: p_entry %p value set to %p", ht, - *p_entry, value)); - } - } +PJ_DEF(void) pj_hash_set_np_lower( pj_hash_table_t *ht, + const void *key, unsigned keylen, + pj_uint32_t hval, + pj_hash_entry_buf entry_buf, + void *value) +{ + hash_set(NULL, ht, key, keylen, hval, value, (void *)entry_buf, PJ_TRUE); } PJ_DEF(unsigned) pj_hash_count( pj_hash_table_t *ht ) |