Logo Search packages:      
Sourcecode: netams version File versions  Download package

list.c

/*************************************************************************
***   Authentication, authorization, accounting + firewalling package
***   Copyright 1998-2002 Anton Vinokurov <anton@netams.com>
***   Copyright 2002-2008 NeTAMS Development Team
***   This code is GPL v3
***   For latest version and more info, visit this project web page
***   located at http://www.netams.com
***
*************************************************************************/
/* $Id: list.c,v 1.14 2009-08-01 09:23:55 anton Exp $ */

#include "netams.h"

/////////////////////////////////////////////////////////////////////////////////////
#ifndef WIPE_OPENSSL
oid OBJECT_hash(Object *obj) {
      return obj->id;
}
int OBJECT_cmp(Object *obj1, Object *obj2) {
      return  (obj1->id == obj2->id)?0:1;
}
/* Create the type-safe wrapper functions for use in the LHASH internals */
static IMPLEMENT_LHASH_HASH_FN(OBJECT_hash, Object *);
static IMPLEMENT_LHASH_COMP_FN(OBJECT_cmp, Object *);
#endif
/////////////////////////////////////////////////////////////////////////////////////
List::List(u_char init_hash) {
      root=last=NULL;
      num_objects=0;

      if(init_hash)
#ifndef WIPE_OPENSSL
            hash = lh_new(LHASH_HASH_FN(OBJECT_hash),
                              LHASH_COMP_FN(OBJECT_cmp));
#else
            hash = g_hash_table_new(g_int_hash, g_int_equal);
#endif
      else
            hash=NULL;

      netams_rwlock_init(&rwlock, NULL);
}

List::~List() {
      Object *tmp;

#ifndef WIPE_OPENSSL
      lh_free(hash);
#else
      g_hash_table_destroy(hash);
#endif

      while(root) {
            tmp=root;
            root=root->next;
            delete tmp;
      }
      netams_rwlock_destroy(&rwlock);
}

int List::Insert(Object *obj) {

      netams_rwlock_wrlock(&rwlock);
#ifndef WIPE_OPENSSL
      if(lh_insert(hash, obj))
#else
      gboolean replace;
      if(g_hash_table_lookup(hash, &obj->id))
            replace = true;
      else
            replace = false;
      g_hash_table_insert(hash, &obj->id, obj);
      if (replace)
#endif
      {
            netams_rwlock_unlock(&rwlock);
            return 0;
      }
      if(root == NULL) root = obj;
      else last->next = obj;
      last = obj;
      obj->next=NULL;

      num_objects++;
      netams_rwlock_unlock(&rwlock);
      
      return 1;
}

int List::Delete(Object *obj) {
      netams_rwlock_wrlock(&rwlock);
      
#ifndef WIPE_OPENSSL
      if(lh_delete(hash, obj) == NULL )
#else
      if(g_hash_table_remove(hash, &obj->id) == FALSE)
#endif
      {
            netams_rwlock_unlock(&rwlock);
            return 0;
      }

      Object *o, *p=NULL;
      for(o=root; o!=NULL; o=o->next) {
            if(o==obj) {
                  if (o==root && o==last ) root=last=NULL;
                  else if (o==root) root=o->next;
                  else if (o==last) { last=p; last->next=NULL; }
                  else p->next=o->next;

                  num_objects--;
                  
                  netams_rwlock_unlock(&rwlock);
                  return 1;
            }
            p=o;
      }
      netams_rwlock_unlock(&rwlock);
      return 0;
}

Object* List::getById(oid id) {
      Object *o;

      netams_rwlock_rdlock(&rwlock);
#ifndef WIPE_OPENSSL
      get.id = id;

      o=(Object*)lh_retrieve(hash, &get);
#else
      o=(Object*)g_hash_table_lookup(hash, &id);
#endif
      netams_rwlock_unlock(&rwlock);
      return o;
}
/////////////////////////////////////////////////////////////////////////////////////
void _elist_add(void ***ptr, void *obj) {
      void **table=*ptr;
      unsigned counter;
      
      if(table==NULL) {
            table=(void**)aMalloc(2*sizeof(void*));
            table[0]=obj;
            table[1]=(void*)table;  //this marks the end
            *ptr=table;
            return;
      }
      
      for(counter=0; table[counter]!=(void*)table; counter++) {
            if(table[counter]==obj)
                  return;
            if(table[counter]==NULL) {
                  table[counter]=obj;
                  return;
            }
      }
      
      //grow list
      //workaround to proper hanlde aMalloc statistic
      void **tmp=(void**)aMalloc((counter+2)*sizeof(void*));
      bcopy(table, tmp, counter*sizeof(void*));
      aFree(table);
      tmp[counter]=obj;
      tmp[counter+1]=(void*)tmp;
      
      *ptr=tmp;
      return;
}
                  
void _elist_remove(void **table, void *obj) {
      for(unsigned counter=0; table[counter]!=NULL && table[counter]!=(void*)table; counter++) {
            if(table[counter]==obj) {
                  //move all from there left 
                  for(;table[counter+1]!=NULL && table[counter+1]!=(void*)table; counter++) {
                        table[counter]=table[counter+1];
                  }     
                  table[counter]=NULL;
                  return;
            }
      }
}

void* _elist_search(void **table, void *arg) {
      for(unsigned counter=0; table[counter]!=NULL && table[counter]!=(void*)table; counter++) {
            if(table[counter] == arg)
                  return &table[counter];
      }
      return NULL;
}
/////////////////////////////////////////////////////////////////////////////////////

Generated by  Doxygen 1.6.0   Back to index