summaryrefslogtreecommitdiff
path: root/pjlib
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2013-02-27 10:11:59 +0000
committerNanang Izzuddin <nanang@teluu.com>2013-02-27 10:11:59 +0000
commit0989c73839be15a18033ef0573f775dc86d39e06 (patch)
tree1c6b9e6c38eb5eb8fe73d3fad55811d4ffb1c2af /pjlib
parent9134f8d06dacc0f72475c70259bee5570319984f (diff)
Re #1556: backported to 1.x
git-svn-id: http://svn.pjsip.org/repos/pjproject/branches/1.x@4385 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjlib')
-rw-r--r--pjlib/include/pj/guid.h19
-rw-r--r--pjlib/include/pj/hash.h38
-rw-r--r--pjlib/src/pj/guid.c21
-rw-r--r--pjlib/src/pj/hash.c93
4 files changed, 137 insertions, 34 deletions
diff --git a/pjlib/include/pj/guid.h b/pjlib/include/pj/guid.h
index 96a5849e..7b24dd51 100644
--- a/pjlib/include/pj/guid.h
+++ b/pjlib/include/pj/guid.h
@@ -83,6 +83,17 @@ PJ_DECL(unsigned) pj_GUID_STRING_LENGTH(void);
PJ_DECL(pj_str_t*) pj_generate_unique_string(pj_str_t *str);
/**
+ * Create a globally unique string in lowercase, which length is
+ * PJ_GUID_STRING_LENGTH characters. Caller is responsible for preallocating
+ * the storage used in the string.
+ *
+ * @param str The string to store the result.
+ *
+ * @return The string.
+ */
+PJ_DECL(pj_str_t*) pj_generate_unique_string_lower(pj_str_t *str);
+
+/**
* Generate a unique string.
*
* @param pool Pool to allocate memory from.
@@ -90,6 +101,14 @@ PJ_DECL(pj_str_t*) pj_generate_unique_string(pj_str_t *str);
*/
PJ_DECL(void) pj_create_unique_string(pj_pool_t *pool, pj_str_t *str);
+/**
+ * Generate a unique string in lowercase.
+ *
+ * @param pool Pool to allocate memory from.
+ * @param str The string.
+ */
+PJ_DECL(void) pj_create_unique_string_lower(pj_pool_t *pool, pj_str_t *str);
+
/**
* @}
diff --git a/pjlib/include/pj/hash.h b/pjlib/include/pj/hash.h
index 7b9f6df3..35c34137 100644
--- a/pjlib/include/pj/hash.h
+++ b/pjlib/include/pj/hash.h
@@ -75,8 +75,8 @@ PJ_DECL(pj_uint32_t) pj_hash_calc(pj_uint32_t hval,
* string is stored in \c result.
*
* @param hval The initial hash value, normally zero.
- * @param result Buffer to store the result, which must be enough to hold
- * the string.
+ * @param result Optional. Buffer to store the result, which must be enough
+ * to hold the string.
* @param key The input key to be converted and calculated.
*
* @return The hash value.
@@ -116,6 +116,17 @@ PJ_DECL(void *) pj_hash_get( pj_hash_table_t *ht,
/**
+ * Variant of #pj_hash_get() with the key being converted to lowercase when
+ * calculating the hash value.
+ *
+ * @see pj_hash_get()
+ */
+PJ_DECL(void *) pj_hash_get_lower( pj_hash_table_t *ht,
+ const void *key, unsigned keylen,
+ pj_uint32_t *hval );
+
+
+/**
* Associate/disassociate a value with the specified key. If value is not
* NULL and entry already exists, the entry's value will be overwritten.
* If value is not NULL and entry does not exist, a new one will be created
@@ -142,6 +153,17 @@ PJ_DECL(void) pj_hash_set( pj_pool_t *pool, pj_hash_table_t *ht,
/**
+ * Variant of #pj_hash_set() with the key being converted to lowercase when
+ * calculating the hash value.
+ *
+ * @see pj_hash_set()
+ */
+PJ_DECL(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 );
+
+
+/**
* Associate/disassociate a value with the specified key. This function works
* like #pj_hash_set(), except that it doesn't use pool (hence the np -- no
* pool suffix). If new entry needs to be allocated, it will use the entry_buf.
@@ -165,6 +187,18 @@ PJ_DECL(void) pj_hash_set_np(pj_hash_table_t *ht,
void *value);
/**
+ * Variant of #pj_hash_set_np() with the key being converted to lowercase
+ * when calculating the hash value.
+ *
+ * @see pj_hash_set_np()
+ */
+PJ_DECL(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);
+
+/**
* Get the total number of entries in the hash table.
*
* @param ht the hash table.
diff --git a/pjlib/src/pj/guid.c b/pjlib/src/pj/guid.c
index 1ed9515c..c16a7ce0 100644
--- a/pjlib/src/pj/guid.c
+++ b/pjlib/src/pj/guid.c
@@ -17,11 +17,32 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <pj/ctype.h>
#include <pj/guid.h>
#include <pj/pool.h>
+PJ_DEF(pj_str_t*) pj_generate_unique_string_lower(pj_str_t *str)
+{
+ int i;
+
+ pj_generate_unique_string(str);
+ for (i = 0; i < str->slen; i++)
+ str->ptr[i] = (char)pj_tolower(str->ptr[i]);
+
+ return str;
+}
+
PJ_DEF(void) pj_create_unique_string(pj_pool_t *pool, pj_str_t *str)
{
str->ptr = (char*)pj_pool_alloc(pool, PJ_GUID_STRING_LENGTH);
pj_generate_unique_string(str);
}
+
+PJ_DEF(void) pj_create_unique_string_lower(pj_pool_t *pool, pj_str_t *str)
+{
+ int i;
+
+ pj_create_unique_string(pool, str);
+ for (i = 0; i < str->slen; i++)
+ str->ptr[i] = (char)pj_tolower(str->ptr[i]);
+}
diff --git a/pjlib/src/pj/hash.c b/pjlib/src/pj/hash.c
index d22bf421..7bce8b6e 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;
}
}
@@ -168,9 +179,11 @@ static pj_hash_entry **find_entry( pj_pool_t *pool, pj_hash_table_t *ht,
p_entry = &entry->next, entry = *p_entry)
{
if (entry->hash==hash && entry->keylen==keylen &&
- pj_memcmp(entry->key, key, keylen)==0)
+ ((lower && pj_ansi_strnicmp((const char*)entry->key,
+ (const char*)key, keylen)==0) ||
+ (!lower && pj_memcmp(entry->key, key, keylen)==0)))
{
- break;
+ break;
}
}
@@ -214,17 +227,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 +264,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 )