view src/protocols/jabber/hashtable.c @ 5129:c19cc54f4df6

[gaim-migrate @ 5492] Stuff I did (in order from most important to least): -Made set away message and set profile count the number of bytes rather than the number of characters. This fixes the lack of a warning dialog when setting info that needs an encoding other than ascii or iso8859-1. (Because "hi" in UCS-2BE is 4 bytes but "hi" in utf8 is only 2.) -Created an oscar_encoding_to_utf8 function to convert from a given encoding to utf8. This is AIM/ICQ specific. -Added a "Profile:" and "Away Message:" line to the get info response window. Is it better this way or without it? I thought it would be good if there was a way for users to tell which text was the away message and which was the info, but I also think this solution could be nicer looking. -Added a little check for some server icon stuff because someone reported an obscure crash. -Shuffled some stuff around in oscar.c -Bouldered on the little wall outside of the gym today. It's much more difficult than climbing inside. I think my forearms are just a bit too weak. The holds are tiny, though. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Mon, 14 Apr 2003 04:52:42 +0000
parents 4e7cefc55971
children
line wrap: on
line source

/*
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in
csompliance with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/

Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
License for the specific language governing rights and limitations
under the License.

The Original Code is expat.

The Initial Developer of the Original Code is James Clark.
Portions created by James Clark are Copyright (C) 1998, 1999
James Clark. All Rights Reserved.

Contributor(s):

*/

#include "xmldef.h"

#ifdef XML_UNICODE_WCHAR_T
#ifndef XML_UNICODE
#define XML_UNICODE
#endif
#endif

#include "hashtable.h"

#define INIT_SIZE 64

static
int keyeq(KEY s1, KEY s2)
{
    for (; *s1 == *s2; s1++, s2++)
        if (*s1 == 0)
            return 1;
    return 0;
}

static
unsigned long hash(KEY s)
{
    unsigned long h = 0;
    while (*s)
        h = (h << 5) + h + (unsigned char)*s++;
    return h;
}

NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize)
{
    size_t i;
    if (table->size == 0) {
        if (!createSize)
            return 0;
        table->v = calloc(INIT_SIZE, sizeof(NAMED *));
        if (!table->v)
            return 0;
        table->size = INIT_SIZE;
        table->usedLim = INIT_SIZE / 2;
        i = hash(name) & (table->size - 1);
    }
    else {
        unsigned long h = hash(name);
        for (i = h & (table->size - 1);
                table->v[i];
                i == 0 ? i = table->size - 1 : --i) {
            if (keyeq(name, table->v[i]->name))
                return table->v[i];
        }
        if (!createSize)
            return 0;
        if (table->used == table->usedLim) {
            /* check for overflow */
            size_t newSize = table->size * 2;
            NAMED **newV = calloc(newSize, sizeof(NAMED *));
            if (!newV)
                return 0;
            for (i = 0; i < table->size; i++)
                if (table->v[i]) {
                    size_t j;
                    for (j = hash(table->v[i]->name) & (newSize - 1);
                            newV[j];
                            j == 0 ? j = newSize - 1 : --j)
                        ;
                    newV[j] = table->v[i];
                }
            free(table->v);
            table->v = newV;
            table->size = newSize;
            table->usedLim = newSize/2;
            for (i = h & (table->size - 1);
                    table->v[i];
                    i == 0 ? i = table->size - 1 : --i)
                ;
        }
    }
    table->v[i] = calloc(1, createSize);
    if (!table->v[i])
        return 0;
    table->v[i]->name = name;
    (table->used)++;
    return table->v[i];
}

void hashTableDestroy(HASH_TABLE *table)
{
    size_t i;
    for (i = 0; i < table->size; i++) {
        NAMED *p = table->v[i];
        if (p)
            free(p);
    }
    free(table->v);
}

void hashTableInit(HASH_TABLE *p)
{
    p->size = 0;
    p->usedLim = 0;
    p->used = 0;
    p->v = 0;
}

void hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
{
    iter->p = table->v;
    iter->end = iter->p + table->size;
}

NAMED *hashTableIterNext(HASH_TABLE_ITER *iter)
{
    while (iter->p != iter->end) {
        NAMED *tem = *(iter->p)++;
        if (tem)
            return tem;
    }
    return 0;
}