/*
 * $Header: /san01/cvs/ashpool/csrc/continuity/mecha/Attic/dic.c,v 1.1 2004/04/30 13:41:56 aleigh Exp $
 */

/*
 * Copyright (c) 2004 Alex Leigh, All Rights Reserved
 *
 * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF ALEX LEIGH The copyright
 * notice above does not evidence any actual or intended publication of such
 * source code.
 *
 * Use, disclosure, copying, distribution, or transmission of this code without
 * express permission is prohibited.
 */

#include "mecha.h"

/*
 * String values are copied into the dictionary so that they may be freed
 * by the calling program. They are free'd with the destruction of the
 * forward list; the reverse list does not destroy the keys.
 */
struct dicSdictionary {
        /* int -> name */
    hshTvoid_list *forward;
        /* name -> int */
    hshTvoid_list *reverse;
        /* int -> data */
    hshTvoid_list *userdata;

    void(*userdata_destructor)(void *);
};

dicTdictionary *dicFinit(void (*destructor) (void *),
                        int (*comparator) (const void *s1,
                                           const void *s2,
                                           size_t len)) {
    dicTdictionary *d;
    
    d=(dicTdictionary *)malloc(sizeof(dicTdictionary));
    
    assert(d!=NULL);

        /* The forward list will be responsible for destroying
         * the values placed into the dictionary, so we will
         * give it a destructor
         */
    d->forward=hshFvoid_int_init(destructor);
    assert(d->forward!=NULL);

    d->reverse=hshFvoid_raw_init(NULL,NULL,comparator,16);
    assert(d->reverse!=NULL);

    d->userdata=hshFvoid_int_init(NULL);
    assert(d->userdata!=NULL);

    return d;
}

void dicFuserdata_update (dicTdictionary *d, int idx, void *data) {
    hshFvoid_int_update(d->userdata,idx,data);
}

void *dicFuserdata_find(dicTdictionary *d, int idx) {
    return hshFvoid_int_find(d->userdata,idx);
}

void dicFuserdata_destructor_set(dicTdictionary *d, void (*destructor)(void *)) {
    assert(d!=NULL);
    hshFvalue_destructor_set(d->userdata,destructor);
}

void dicFfree(dicTdictionary *d) {
    hshFvoid_destroy(d->forward);
    hshFvoid_destroy(d->reverse);
    hshFvoid_destroy(d->userdata);
    free(d);
}

int dicFupdate(dicTdictionary *d, int idx, void *value, size_t value_len) {
    assert(d!=NULL);
    assert(value!=NULL);
    
    hshFvoid_int_update(d->forward,idx,value);
    hshFvoid_raw_add(d->reverse,value,value_len,(void *)idx,1);
    
    return 0;
}

void *dicFfind(dicTdictionary *d, int idx) {
    assert(d!=NULL);
    assert(d->forward!=NULL);
    
    return hshFvoid_int_find(d->forward,idx);
}

int docFfind_index(dicTdictionary *d, void *value, size_t value_len, int *idx) {
    void *p;
    
    assert(d!=NULL);
    assert(d->reverse!=NULL);
    assert(value!=NULL);

    p=hshFvoid_raw_find(d->reverse, value, value_len);

    if(p==NULL) {
        return -1;
    }

    *idx=(int)p;
    return 0;
}

char *dicFchar_find(dicTdictionary *d, int idx) {
    assert(d!=NULL);
    
    return (char *)hshFvoid_int_find(d->forward,idx);
}

int dicFchar_update(dicTdictionary *d, int idx, char *str, size_t str_len) {
    assert(d!=NULL);
    assert(str!=NULL);

    return dicFupdate(d,idx,(void *)strFncopy(str,str_len),str_len);
}

dicTdictionary *dicFchar_init(void) {
    return dicFinit(free,strncmp);
}

int dicFchar_find_index(dicTdictionary *d, char *value, size_t value_len, int *idx) {
    return docFfind_index(d,(void *)value,value_len,idx);
}

