aboutsummaryrefslogtreecommitdiff
path: root/3rdparty/dict
diff options
context:
space:
mode:
authorneonloop2021-10-20 14:54:27 +0000
committerneonloop2021-10-20 14:54:27 +0000
commitea1947ffcc606d757357398b24e74a3f4ecefa07 (patch)
tree2031b8d4fc4c61063c710a7148378f57e662efbd /3rdparty/dict
downloadbennugd-ea1947ffcc606d757357398b24e74a3f4ecefa07.tar.gz
bennugd-ea1947ffcc606d757357398b24e74a3f4ecefa07.tar.bz2
bennugd-ea1947ffcc606d757357398b24e74a3f4ecefa07.zip
Initial commit from steward-fu releasemain
Diffstat (limited to '3rdparty/dict')
-rw-r--r--3rdparty/dict/Makefile5
-rw-r--r--3rdparty/dict/dict-test.c88
-rw-r--r--3rdparty/dict/dict.c357
-rw-r--r--3rdparty/dict/dict.h98
4 files changed, 548 insertions, 0 deletions
diff --git a/3rdparty/dict/Makefile b/3rdparty/dict/Makefile
new file mode 100644
index 0000000..a80aa55
--- /dev/null
+++ b/3rdparty/dict/Makefile
@@ -0,0 +1,5 @@
+all: dict.c dict.h dict-test.c
+ gcc dict.c dict-test.c -o dict-test -I.
+
+clean:
+ rm dict-test
diff --git a/3rdparty/dict/dict-test.c b/3rdparty/dict/dict-test.c
new file mode 100644
index 0000000..80cf847
--- /dev/null
+++ b/3rdparty/dict/dict-test.c
@@ -0,0 +1,88 @@
+/* ******************************************** */
+/* File Name: dict-test.c */
+/* Author: (C) 2008-2009 - Juan José Ponteprino */
+/* Description: Dictionary API Headers */
+/* License: This code is licenced as LGPL */
+/* ******************************************** */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dict.h>
+
+int main( int argc, char * argv[] )
+{
+ DICT_T * main_dict = NULL;
+ char * val1 = "hello world";
+ char * val2 = "goodbye world";
+ char * val3 = "works!";
+
+ DICT_Init();
+
+ main_dict = DICT_Create( "main" );
+ if ( !main_dict )
+ {
+ fprintf( stderr, "Can't create dictionary\n" );
+ exit( -1 );
+ }
+
+ printf( "\n" );
+ printf( "Add a new entry... foo1... ret: %d\n", DICT_AddEntry( main_dict, "foo1", ( void * ) val1, strlen( val1 ) + 1, DICT_ENTRY_FLAG_NORMAL ));
+
+ printf( "\n" );
+ printf( "Get an exists entry... foo1... ret: [%s]\n", DICT_GetEntry( main_dict, "foo1", NULL ));
+ printf( "Get non exist entry... foo2... ret: [%s]\n", DICT_GetEntry( main_dict, "foo2", NULL ));
+
+ printf( "\n" );
+ printf( "Find an entry... foo1... ret: %p\n", DICT_FindEntry( main_dict, "foo1" ) );
+ printf( "Find non exists entry... foo2... ret: %p\n", DICT_FindEntry( main_dict, "foo2" ) );
+
+ printf( "\n" );
+ printf( "Update an exists entry... foo1... ret: %d\n", DICT_AddEntry( main_dict, "foo1", ( void * ) val2, strlen( val2 ) + 1, DICT_ENTRY_FLAG_NORMAL ));
+
+ printf( "\n" );
+ printf( "Get an exists entry (with a large value)... foo1... ret: [%s]\n", DICT_GetEntry( main_dict, "foo1", NULL ));
+ printf( "Find an entry... foo1... ret: %p\n", DICT_FindEntry( main_dict, "foo1" ) );
+
+ printf( "\n" );
+ printf( "Update an exists entry (with a short value)... foo1... ret: %d\n", DICT_AddEntry( main_dict, "foo1", ( void * ) val3, strlen( val3 ) + 1, DICT_ENTRY_FLAG_NORMAL ));
+
+ printf( "\n" );
+ printf( "Get an exists entry... foo1... ret: [%s]\n", DICT_GetEntry( main_dict, "foo1", NULL ));
+ printf( "Find an entry... foo1... ret: %p\n", DICT_FindEntry( main_dict, "foo1" ) );
+
+ printf( "\n" );
+ printf( "Delete an exists entry...\n" );
+ DICT_DelEntry( main_dict, "foo1" );
+
+ printf( "\n" );
+ printf( "Delete a non exists entry...\n" );
+ DICT_DelEntry( main_dict, "foo1" );
+
+ printf( "\n" );
+ printf( "Get a non exists entry... foo1... ret: %p\n", DICT_GetEntry( main_dict, "foo1", NULL ));
+ printf( "Find a non exists entry... foo1... ret: [%s]\n", DICT_FindEntry( main_dict, "foo1" ));
+
+ printf( "\n" );
+ printf( "Add a new entry... foo1... ret: %d\n", DICT_AddEntry( main_dict, "foo1", ( void * ) val1, strlen( val1 ) + 1, DICT_ENTRY_FLAG_NORMAL ));
+ printf( "Add a new entry... foo2... ret: %d\n", DICT_AddEntry( main_dict, "foo2", ( void * ) val2, strlen( val2 ) + 1, DICT_ENTRY_FLAG_NORMAL ));
+ printf( "Add a new entry... foo3... ret: %d\n", DICT_AddEntry( main_dict, "foo3", ( void * ) val3, strlen( val3 ) + 1, DICT_ENTRY_FLAG_NORMAL ));
+
+ printf( "\n" );
+ printf( "Display all Entries\n" );
+ DICT_ShowAllEntries( main_dict, stdout );
+
+ printf( "\n" );
+ printf( "Delete all Entries\n" );
+ DICT_DelAllEntries( main_dict );
+
+ printf( "\n" );
+ printf( "Display all Entries\n" );
+ DICT_ShowAllEntries( main_dict, stdout );
+
+ DICT_Destroy( main_dict );
+
+ DICT_Exit();
+
+ return 0;
+}
diff --git a/3rdparty/dict/dict.c b/3rdparty/dict/dict.c
new file mode 100644
index 0000000..ecd8f05
--- /dev/null
+++ b/3rdparty/dict/dict.c
@@ -0,0 +1,357 @@
+/* ******************************************** */
+/* File Name: dict.c */
+/* Author: (C) 2008-2009 - Juan José Ponteprino */
+/* Description: Dictionary API Headers */
+/* License: This code is licenced as LGPL */
+/* ******************************************** */
+
+/* --------------------------------------------------------------------------- */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+/* --------------------------------------------------------------------------- */
+
+#ifndef __GNUC__
+#define inline __inline
+#endif
+
+/* --------------------------------------------------------------------------- */
+
+#include "dict.h"
+
+/* --------------------------------------------------------------------------- */
+
+static DICT_T * _DICT_table = NULL;
+static DICT_T * _DICT_table_hashed[ DICT_HASH_MAX ] = { NULL } ;
+
+/* --------------------------------------------------------------------------- */
+
+static int make_hash8( char * key )
+{
+ int hash = 0, i;
+
+ for ( i = 0; key[i]; i++ )
+#ifdef USE_ALTERNATIVE_MODE
+ hash += key[i] ^( hash << DICT_HASH_SHIFT8 );
+#else
+ hash ^= key[i] + ( hash << DICT_HASH_SHIFT8 ); /* Best dispersion */
+#endif
+
+ return ( hash & DICT_HASH_MASK8 );
+}
+
+/* --------------------------------------------------------------------------- */
+
+static int make_hash16( char * key )
+{
+ int hash = 0, i;
+
+ for ( i = 0; key[i]; i++ )
+#ifdef USE_ALTERNATIVE_MODE
+ hash += key[i] ^( hash << DICT_HASH_SHIFT16 );
+#else
+ hash ^= key[i] + ( hash << DICT_HASH_SHIFT16 ); /* Best dispersion */
+#endif
+
+ return ( hash & DICT_HASH_MASK16 );
+}
+
+/* --------------------------------------------------------------------------- */
+
+#ifdef USE_HASH8
+#define make_hash make_hash8
+#else
+#define make_hash make_hash16
+#endif
+
+/* --------------------------------------------------------------------------- */
+
+#define ihash8(x) ((x)&0xff)
+
+/* --------------------------------------------------------------------------- */
+
+void DICT_Init()
+{
+}
+
+/* --------------------------------------------------------------------------- */
+
+void DICT_Exit()
+{
+}
+
+/* --------------------------------------------------------------------------- */
+
+DICT_T * DICT_Create( char * id )
+{
+ DICT_T * dict = calloc( 1, sizeof( DICT_T ) );
+
+ if ( dict )
+ {
+ int hash = make_hash( id );
+
+ /* Fill struct */
+
+ dict->id = strdup( id );
+ dict->hash = hash;
+
+ /* Insert dict in table */
+
+ dict->prev = NULL;
+ dict->next = _DICT_table;
+ if ( _DICT_table ) _DICT_table->prev = dict;
+ _DICT_table = dict;
+
+ /* Insert dict in hashed table */
+
+ dict->prev_hashed = NULL;
+ dict->next_hashed = _DICT_table_hashed[hash];
+ if ( _DICT_table_hashed[ hash ] ) _DICT_table_hashed[ hash ]->prev_hashed = dict;
+ _DICT_table_hashed[ hash ] = dict ;
+
+ /* Cleanup entries structs */
+
+ dict->entries = NULL;
+ memset( dict->entries_hashed, '\0', sizeof( dict->entries_hashed ) );
+ }
+
+ return ( dict );
+}
+
+/* --------------------------------------------------------------------------- */
+
+int DICT_Destroy( DICT_T * dict )
+{
+ if ( dict )
+ {
+ /* Remove dict from table */
+
+ if ( dict->next ) dict->next->prev = dict->prev ;
+ if ( dict->prev ) dict->prev->next = dict->next ;
+ else _DICT_table = dict->next ; /* No prev, then this is first _DICT_table element */
+
+ /* Remove dict from hashed table */
+
+ if ( dict->next_hashed ) dict->next_hashed->prev_hashed = dict->prev_hashed ;
+ if ( dict->prev_hashed ) dict->prev_hashed->next_hashed = dict->next_hashed ;
+ else _DICT_table_hashed[ dict->hash ] = dict->next_hashed ; /* No prev, then this is first _DICT_table_hashed element */
+
+ /* Destroy entries */
+
+ DICT_DelAllEntries( dict );
+
+ /* Free data */
+
+ free( dict->id );
+
+ free( dict );
+ }
+
+ return ( 0 );
+}
+
+/* --------------------------------------------------------------------------- */
+
+static inline DICT_ENTRY_T * __DICT_FINDENTRY( DICT_T * dict, char * key, int hash )
+{
+ DICT_ENTRY_T * entry = dict->entries_hashed[ hash ] ;
+
+ while ( entry )
+ {
+ if ( !strcmp( entry->key, key ) ) return ( entry );
+ entry = entry->next_hashed;
+ }
+
+ return ( NULL );
+}
+
+/* --------------------------------------------------------------------------- */
+
+#define __DICT_SET_DATA \
+ if ( flags & DICT_ENTRY_FLAG_DONT_ALLOC ) \
+ { \
+ entry->val = value; \
+ } \
+ else \
+ { \
+ entry->val = malloc( len ); \
+ memmove( entry->val, value, len ); \
+ } \
+ \
+ entry->flags = flags; \
+ entry->len = len;
+
+/* --------------------------------------------------------------------------- */
+
+int DICT_AddEntry( DICT_T * dict, char * key, void * value, int len, int flags )
+{
+ DICT_ENTRY_T * entry;
+
+ if ( dict && key )
+ {
+ int hash = make_hash( key );
+
+ if ( ( entry = __DICT_FINDENTRY( dict, key, hash ) ) )
+ {
+ if ( !( entry->flags & DICT_ENTRY_FLAG_DONT_ALLOC ) && entry->val ) free( entry->val );
+
+ __DICT_SET_DATA;
+
+ return 0;
+ }
+ else
+ {
+ if ( ( entry = malloc( sizeof( DICT_ENTRY_T ) ) ) )
+ {
+ if ( flags & DICT_ENTRY_FLAG_DONT_ALLOC )
+ {
+ entry->key = key;
+ }
+ else
+ {
+ if ( !( entry->key = strdup( key ) ) )
+ {
+ free( entry );
+ return -1;
+ }
+ }
+
+ __DICT_SET_DATA;
+
+ /* Insert entry in table */
+
+ entry->prev = NULL;
+ entry->next = dict->entries;
+ if ( dict->entries ) dict->entries->prev = entry;
+ dict->entries = entry;
+
+ /* Insert entry in hashed table */
+
+ entry->prev_hashed = NULL;
+ entry->next_hashed = dict->entries_hashed[ hash ];
+ if ( dict->entries_hashed[ hash ] ) dict->entries_hashed[ hash ]->prev_hashed = entry;
+ dict->entries_hashed[ hash ] = entry ;
+
+ return 0;
+ }
+ }
+ }
+
+ return -1;
+}
+
+/* --------------------------------------------------------------------------- */
+
+void * DICT_GetEntry( DICT_T * dict, char * key, int * len )
+{
+ DICT_ENTRY_T * entry;
+
+ if ( dict && key )
+ {
+ int hash = make_hash( key );
+ if (( entry = __DICT_FINDENTRY( dict, key, hash ) ) )
+ {
+ if ( len ) *len = entry->len ;
+ return ( entry->val );
+ }
+ }
+
+ return ( NULL );
+}
+
+/* --------------------------------------------------------------------------- */
+
+void DICT_DelEntry( DICT_T * dict, char * key )
+{
+ int hash = make_hash( key );
+ DICT_ENTRY_T * entry = __DICT_FINDENTRY( dict, key, hash ) ;
+
+ if ( !entry ) return ;
+
+ if ( !( entry->flags & DICT_ENTRY_FLAG_DONT_ALLOC ) && entry->val ) free( entry->val );
+
+ /* Remove entry from table */
+
+ if ( entry->next ) entry->next->prev = entry->prev ;
+ if ( entry->prev ) entry->prev->next = entry->next ;
+ else dict->entries = entry->next ; /* No prev */
+
+ /* Remove entry from hashed table */
+
+ if ( entry->next_hashed ) entry->next_hashed->prev_hashed = entry->prev_hashed ;
+ if ( entry->prev_hashed ) entry->prev_hashed->next_hashed = entry->next_hashed ;
+ else dict->entries_hashed[ hash ] = entry->next_hashed ; /* No prev */
+
+ free( entry->key );
+ free( entry );
+}
+
+/* --------------------------------------------------------------------------- */
+
+void DICT_DelAllEntries( DICT_T * dict )
+{
+ DICT_ENTRY_T * entry = NULL;
+ while (( entry = DICT_GetNextEntry( dict, NULL ) ) ) DICT_DelEntry( dict, entry->key );
+}
+
+/* --------------------------------------------------------------------------- */
+
+DICT_ENTRY_T * DICT_FindEntry( DICT_T * dict, char * key )
+{
+ int hash = make_hash( key );
+ return ( __DICT_FINDENTRY( dict, key, hash ) );
+}
+
+/* --------------------------------------------------------------------------- */
+
+int DICT_Merge( DICT_T * target, DICT_T * source )
+{
+ DICT_ENTRY_T * entry = NULL ;
+
+ while (( entry = DICT_GetNextEntry( source, entry ) ) )
+ {
+ DICT_AddEntry( target, entry->key, entry->val, entry->len, DICT_ENTRY_FLAG_NORMAL );
+ }
+
+ return 0;
+}
+
+/* --------------------------------------------------------------------------- */
+
+DICT_ENTRY_T * DICT_GetNextEntry( DICT_T * dict, DICT_ENTRY_T * current )
+{
+ if ( !current ) return ( dict->entries );
+ return ( current->next );
+}
+
+/* --------------------------------------------------------------------------- */
+
+DICT_ENTRY_T * DICT_GetPrevEntry( DICT_T * dict, DICT_ENTRY_T * current )
+{
+ if ( !current )
+ {
+ current = dict->entries;
+ while ( current->next ) current = current->next;
+ return ( current );
+ }
+
+ return ( current->prev );
+}
+
+/* --------------------------------------------------------------------------- */
+
+void DICT_ShowAllEntries( DICT_T * dict, FILE * fp )
+{
+ DICT_ENTRY_T * entry = NULL;
+
+ while (( entry = DICT_GetNextEntry( dict, entry ) ) )
+ {
+ fprintf( fp, "[%s]=[", entry->key );
+ fwrite( entry->val, 1, entry->len, fp );
+ fprintf( fp, "]\n" );
+ }
+}
+
+/* --------------------------------------------------------------------------- */
diff --git a/3rdparty/dict/dict.h b/3rdparty/dict/dict.h
new file mode 100644
index 0000000..424bc28
--- /dev/null
+++ b/3rdparty/dict/dict.h
@@ -0,0 +1,98 @@
+/* ******************************************** */
+/* File Name: dict.h */
+/* Author: (C) 2008-2009 - Juan José Ponteprino */
+/* Description: Dictionary API Headers */
+/* License: This code is licenced as LGPL */
+/* ******************************************** */
+
+#ifndef _DICT_H
+#define _DICT_H
+
+/* --------------------------------------------------------------------------- */
+
+// Hash 8
+#define DICT_HASH_MAX8 256
+#define DICT_HASH_MASK8 0xff
+#define DICT_HASH_SHIFT8 1
+
+// Hash 16 (default)
+#define DICT_HASH_MAX16 65536
+#define DICT_HASH_MASK16 0xffff
+#define DICT_HASH_SHIFT16 4
+
+#ifdef USE_HASH8
+// Hash 8
+#define DICT_HASH_MAX DICT_HASH_MAX8
+#define DICT_HASH_MASK DICT_HASH_MASK8
+#define DICT_HASH_SHIFT DICT_HASH_SHIFT8
+#else
+// Hash 16 (default)
+#define DICT_HASH_MAX DICT_HASH_MAX16
+#define DICT_HASH_MASK DICT_HASH_MASK16
+#define DICT_HASH_SHIFT DICT_HASH_SHIFT16
+#endif
+
+/* --------------------------------------------------------------------------- */
+
+#define DICT_ENTRY_FLAG_NORMAL 0x00000000
+#define DICT_ENTRY_FLAG_DONT_ALLOC 0x00000001
+
+/* --------------------------------------------------------------------------- */
+
+typedef struct DICT_ENTRY_T
+{
+ char * key;
+
+ long len;
+ void * val;
+
+ int flags;
+
+ struct DICT_ENTRY_T * prev;
+ struct DICT_ENTRY_T * next;
+
+ struct DICT_ENTRY_T * prev_hashed;
+ struct DICT_ENTRY_T * next_hashed;
+
+} DICT_ENTRY_T;
+
+typedef struct DICT_T
+{
+ char * id;
+ int hash;
+
+ DICT_ENTRY_T * entries;
+ DICT_ENTRY_T * entries_hashed[DICT_HASH_MAX];
+
+ struct DICT_T * prev;
+ struct DICT_T * next;
+
+ struct DICT_T * prev_hashed;
+ struct DICT_T * next_hashed;
+
+} DICT_T;
+
+/* --------------------------------------------------------------------------- */
+
+extern void DICT_Init();
+extern void DICT_Exit();
+
+extern DICT_T * DICT_Create( char * id );
+extern int DICT_Destroy( DICT_T * dict );
+
+extern int DICT_AddEntry( DICT_T * dict, char * key, void * value, int len, int flags );
+extern void * DICT_GetEntry( DICT_T * dict, char * key, int * len );
+extern DICT_ENTRY_T * DICT_FindEntry( DICT_T * dict, char * key );
+
+extern void DICT_DelEntry( DICT_T * dict, char * key );
+extern void DICT_DelAllEntries( DICT_T * dict );
+extern int DICT_Merge( DICT_T * target, DICT_T * source );
+
+extern DICT_ENTRY_T * DICT_GetNextEntry( DICT_T * dict, DICT_ENTRY_T * current );
+extern DICT_ENTRY_T * DICT_GetPrevEntry( DICT_T * dict, DICT_ENTRY_T * current );
+
+extern void DICT_ShowAllEntries( DICT_T * dict, FILE * fp );
+
+/* --------------------------------------------------------------------------- */
+
+#endif