00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "dthdr.h"
00018
00019 #ifdef DMALLOC
00020 #include "dmalloc.h"
00021 #endif
00022
00023
00024
00025
00026
00027
00028 #if __STD_C
00029 Dtmethod_t *dtmethod(Dt_t * dt, Dtmethod_t * meth)
00030 #else
00031 Dtmethod_t *dtmethod(dt, meth)
00032 Dt_t *dt;
00033 Dtmethod_t *meth;
00034 #endif
00035 {
00036 reg Dtlink_t *list, *r;
00037 reg Dtdisc_t *disc = dt->disc;
00038 reg Dtmethod_t *oldmeth = dt->meth;
00039
00040 if (!meth || meth->type == oldmeth->type)
00041 return oldmeth;
00042
00043 if (disc->eventf &&
00044 (*disc->eventf) (dt, DT_METH, (Void_t *) meth, disc) < 0)
00045 return NIL(Dtmethod_t *);
00046
00047
00048 list = dtflatten(dt);
00049
00050 if (dt->data->type & (DT_LIST | DT_STACK | DT_QUEUE))
00051 dt->data->head = NIL(Dtlink_t *);
00052 else if (dt->data->type & (DT_SET | DT_BAG)) {
00053 if (dt->data->ntab > 0)
00054 (*dt->memoryf) (dt, (Void_t *) dt->data->htab, 0, disc);
00055 dt->data->ntab = 0;
00056 dt->data->htab = NIL(Dtlink_t **);
00057 }
00058
00059 dt->data->here = NIL(Dtlink_t *);
00060 dt->data->type =
00061 (dt->data->type & ~(DT_METHODS | DT_FLATTEN)) | meth->type;
00062 dt->meth = meth;
00063 if (dt->searchf == oldmeth->searchf)
00064 dt->searchf = meth->searchf;
00065
00066 if (meth->type & (DT_LIST | DT_STACK | DT_QUEUE)) {
00067 if (!(oldmeth->type & (DT_LIST | DT_STACK | DT_QUEUE))) {
00068 if ((r = list)) {
00069 reg Dtlink_t *t;
00070 for (t = r->right; t; r = t, t = t->right)
00071 t->left = r;
00072 list->left = r;
00073 }
00074 }
00075 dt->data->head = list;
00076 } else if (meth->type & (DT_OSET | DT_OBAG)) {
00077 dt->data->size = 0;
00078 while (list) {
00079 r = list->right;
00080 (*meth->searchf) (dt, (Void_t *) list, DT_RENEW);
00081 list = r;
00082 }
00083 } else if (!((meth->type & DT_BAG) && (oldmeth->type & DT_SET))) {
00084 int rehash;
00085 if ((meth->type & (DT_SET | DT_BAG))
00086 && !(oldmeth->type & (DT_SET | DT_BAG)))
00087 rehash = 1;
00088 else
00089 rehash = 0;
00090
00091 dt->data->size = dt->data->loop = 0;
00092 while (list) {
00093 r = list->right;
00094 if (rehash) {
00095 reg Void_t *key = OBJ(list, disc->link);
00096 key = KEY(key, disc->key, disc->size);
00097 list->hash = HASH(dt, key, disc, disc->size);
00098 }
00099 (void) (*meth->searchf) (dt, (Void_t *) list, DT_RENEW);
00100 list = r;
00101 }
00102 }
00103
00104 return oldmeth;
00105 }