#include #include #include "misc.h" #include "misc.m" PUBLIC ARRAY_OBJ::ARRAY_OBJ() { modified = 0; } PUBLIC VIRTUAL ARRAY_OBJ::~ARRAY_OBJ() { } /* Reset the modify flags of the element. */ PUBLIC void ARRAY_OBJ::rstmodified() { modified = 0; } /* Reset the modify flags of the element. This function is generally used with ARRAY::was_modified(). */ PUBLIC void ARRAY_OBJ::setmodified() { modified = 1; } /* Return true if the element was modified. */ PUBLIC VIRTUAL int ARRAY_OBJ::was_modified() { return modified; } /* Edit the object. Return 1 if the object must be deleted Return 0 if the modification are accepted Return -1 if the user has escape away. */ PUBLIC VIRTUAL int ARRAY_OBJ::edit() { return 0; } /* Manage the content of a hosts file (generally /etc/hosts */ PUBLIC ARRAY::ARRAY() { tb = NULL; nb = 0; maxtb = 0; modified = 0; increm = 100; is_owner = 1; } /* Instruct this array it is not allowed to delete objects. We use this function when we intend to share some object between several arrays. One array is the owner and the others represents various views of the original array (for example). */ PUBLIC void ARRAY::neverdelete() { is_owner = 0; } /* Record the new growth rate of the internal array. Each time the array overflow, a larger is realloced. It will be _increm item larger. */ PUBLIC void ARRAY::setgrowth(int _increm) { increm = _increm; } PUBLIC VIRTUAL ARRAY::~ARRAY() { if (is_owner) for (int i=0; i= 0){ nb--; modified = 1; ret = 0; for (int i=no; i= nb){ set (pos,pt); }else{ grow(); memmove (tb+pos+1,tb+pos,(nb-pos)*sizeof(tb[0])); tb[pos] = pt; nb++; } modified = 1; } } /* Replace one item in the table. The table is grown as needed, potentially holding NULL element. */ PUBLIC void ARRAY::set (int pos, ARRAY_OBJ *pt) { if (pt != NULL){ if (pos >= maxtb){ grow_realloc(pos+increm); } if (is_owner) delete tb[pos]; tb[pos] = pt; if (pos >= nb) nb = pos + 1; modified = 1; } } /* This function should be duplicate in each sub-class to allow proper casting. */ PROTECTED ARRAY_OBJ *ARRAY::getitem (int no) const { ARRAY_OBJ *ret = NULL; if (no >= 0 && no < nb) ret = tb[no]; return ret; } /* Reset the modify flags of all elements of the array. */ PUBLIC void ARRAY::rstmodified() { int nbo = getnb(); for (int i=0; irstmodified(); modified = 0; } /* Return != if the element was modified. */ PUBLIC VIRTUAL int ARRAY::was_modified() { int ret = modified; if (!ret){ int nbo = getnb(); for (int i=0; iwas_modified(); if (modif){ ret = true; break; } } } return ret; } static int (*user_cmp) (const ARRAY_OBJ *, const ARRAY_OBJ *); static int local_cmp (const void *pt1, const void *pt2) { return (*user_cmp)(*(ARRAY_OBJ**)pt1,*(ARRAY_OBJ**)pt2); } /* Sort the ARRAY with a user function working like the one for qsort. Use qsort() internally. */ PUBLIC void ARRAY::sort (int (*cmp) (const ARRAY_OBJ *, const ARRAY_OBJ *)) { user_cmp = cmp; qsort (tb,nb,sizeof(ARRAY_OBJ*),local_cmp); } /* Save the content of the array Return -1 if any error. The default behavior is to do nothing */ PUBLIC VIRTUAL int ARRAY::write() { return -1; } /* Behavior after the editing of one object */ PUBLIC int ARRAY::manage_edit (ARRAY_OBJ *e, int code, int insertpos) { if (code == 0){ int pos = lookup (e); if (pos == -1) add (e); if (insertpos != -1) moveto(e,insertpos); write(); }else if (code == 1){ if (remove_del (e)==-1) delete e; write(); } return code; } /* Behavior after the editing of one object */ PUBLIC int ARRAY::manage_edit (ARRAY_OBJ *e, int code) { return manage_edit (e,code,-1); } /* Edit one object or create a new one and manage the deletion if told by the edit function of the object. */ PUBLIC int ARRAY::editone(int no) { int ret = -1; if (no >= 0 && no < getnb()){ ARRAY_OBJ *e = getitem(no); ret = e->edit(); manage_edit (e,ret); } return ret; } /* Edit one object or create a new one and manage the deletion if told by the edit function of the object. */ PUBLIC int ARRAY::editone(ARRAY_OBJ *e) { int ret = e->edit(); manage_edit (e,ret); return ret; } /* Remove the last entries of the array, after the "cut" first items */ PUBLIC void ARRAY::remove_last(int cut) { while (getnb() > cut) remove_del(getnb()-1); } /* Reverse the order of the objects in the array */ PUBLIC void ARRAY::invert() { int nbo = getnb(); if (nbo > 0){ ARRAY_OBJ *tbtmp[nbo]; memcpy (tbtmp,tb,sizeof(ARRAY_OBJ*)*nbo); for (int i=nbo-1,j=0; i>=0; i--,j++){ tb[j] = tbtmp[i]; } } }