HelenOS sources
This source file includes following definitions.
- nic_addr_key_equal
- addr_hash
- nic_addr_key_hash
- nic_addr_hash
- nic_addr_removed
- nic_addr_db_init
- nic_addr_db_clear
- nic_addr_db_destroy
- nic_addr_db_insert
- nic_addr_db_remove
- nic_addr_db_contains
- nic_addr_db_fe_helper
- nic_addr_db_foreach
#include "nic_addr_db.h"
#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>
#include <errno.h>
#include <mem.h>
#include <member.h>
#include <adt/hash_table.h>
#include <macros.h>
#include <stdint.h>
typedef struct nic_addr_entry {
ht_link_t link;
uint8_t len;
uint8_t addr[1];
} nic_addr_entry_t;
typedef struct {
size_t len;
const uint8_t *addr;
} addr_key_t;
static bool nic_addr_key_equal(const void *key_arg, const ht_link_t *item)
{
const addr_key_t *key = key_arg;
nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link);
return memcmp(entry->addr, key->addr, entry->len) == 0;
}
static size_t addr_hash(size_t len, const uint8_t *addr)
{
size_t hash = 0;
for (size_t i = 0; i < len; ++i) {
hash = (hash << 5) ^ addr[i];
}
return hash;
}
static size_t nic_addr_key_hash(const void *k)
{
const addr_key_t *key = k;
return addr_hash(key->len, key->addr);
}
static size_t nic_addr_hash(const ht_link_t *item)
{
nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link);
return addr_hash(entry->len, entry->addr);
}
static void nic_addr_removed(ht_link_t *item)
{
nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link);
free(entry);
}
static const hash_table_ops_t set_ops = {
.hash = nic_addr_hash,
.key_hash = nic_addr_key_hash,
.key_equal = nic_addr_key_equal,
.equal = NULL,
.remove_callback = nic_addr_removed
};
errno_t nic_addr_db_init(nic_addr_db_t *db, size_t addr_len)
{
assert(db);
if (addr_len > UCHAR_MAX)
return EINVAL;
if (!hash_table_create(&db->set, 0, 0, &set_ops))
return ENOMEM;
db->addr_len = addr_len;
return EOK;
}
void nic_addr_db_clear(nic_addr_db_t *db)
{
assert(db);
hash_table_clear(&db->set);
}
void nic_addr_db_destroy(nic_addr_db_t *db)
{
assert(db);
hash_table_destroy(&db->set);
}
errno_t nic_addr_db_insert(nic_addr_db_t *db, const uint8_t *addr)
{
assert(db && addr);
addr_key_t key = {
.len = db->addr_len,
.addr = addr
};
if (hash_table_find(&db->set, &key))
return EEXIST;
nic_addr_entry_t *entry = malloc(sizeof(nic_addr_entry_t) + db->addr_len - 1);
if (entry == NULL)
return ENOMEM;
entry->len = (uint8_t) db->addr_len;
memcpy(entry->addr, addr, db->addr_len);
hash_table_insert(&db->set, &entry->link);
return EOK;
}
errno_t nic_addr_db_remove(nic_addr_db_t *db, const uint8_t *addr)
{
assert(db && addr);
addr_key_t key = {
.len = db->addr_len,
.addr = addr
};
if (hash_table_remove(&db->set, &key))
return EOK;
else
return ENOENT;
}
bool nic_addr_db_contains(const nic_addr_db_t *db, const uint8_t *addr)
{
assert(db && addr);
addr_key_t key = {
.len = db->addr_len,
.addr = addr
};
return 0 != hash_table_find(&db->set, &key);
}
typedef struct {
void (*func)(const uint8_t *, void *);
void *arg;
} nic_addr_db_fe_arg_t;
static bool nic_addr_db_fe_helper(ht_link_t *item, void *arg)
{
nic_addr_db_fe_arg_t *hs = (nic_addr_db_fe_arg_t *) arg;
nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link);
hs->func(entry->addr, hs->arg);
return true;
}
void nic_addr_db_foreach(const nic_addr_db_t *db,
void (*func)(const uint8_t *, void *), void *arg)
{
nic_addr_db_fe_arg_t hs = { .func = func, .arg = arg };
hash_table_apply((hash_table_t *)&db->set, nic_addr_db_fe_helper, &hs);
}
HelenOS homepage, sources at GitHub