/* * lists.cc - simple list class */ #ifdef AIX4 #include #else #include #endif #include #include "lists.h" #include "wildmat.h" int filenamecmp(char *s1,char *s2,int *noslashflag); /*external*/ Item::Item(void){ prev=NULL; next=NULL; list=NULL; charvalue=NULL; longvalue=0; charvaluelength=0; allocatedcharvalue=0; } /* Item::Item(char *xvalue,int allocatevalue,long xlongvalue){ int l; prev=NULL; next=NULL; list=NULL; charvalue=NULL; longvalue=xlongvalue; charvaluelength=0; allocatedcharvalue=0; if(xvalue){ if(allocatevalue){ charvaluelength=strlen(xvalue); charvalue=(char*)malloc(charvaluelength+1); if(charvalue){ memcpy(charvalue,xvalue,charvaluelength+1); allocatedcharvalue=1; }else charvaluelength=0; }else{ charvaluelength=strlen(xvalue); charvalue=xvalue; } } if(charvalue){ }else{ } } */ Item::~Item(void){ if(list) list->Remove(this); if(allocatedcharvalue&&charvalue) free(charvalue); } List::List(void){ start=NULL; count=0; last=&start; } List::~List(void){ while(start){ delete start; } } int List::Add(Item *item){ if(last){ if(item->list) item->list->Remove(item); count++; item->prev=last; *last=item; last=&(item->next); item->next=NULL; item->list=this; return 0; } return -1; } int List::Remove(Item *item){ if(last&&count&&item->list==this){ count--; *(item->prev)=item->next; if(item->next){ item->next->prev=item->prev; }else{ last=item->prev; } item->list=NULL; return 0; } return -1; } Item *List::Find(char *value){ int l; if(!value) return NULL; l=strlen(value); Item *curritem=start; while(curritem){ if(l==curritem->charvaluelength){ if(!memcmp(value,curritem->charvalue,l)) return curritem; } curritem=curritem->next; } return NULL; } Item *List::Find(char *value,long longvalue){ int l; if(!value) return NULL; l=strlen(value); Item *curritem=start; while(curritem){ if(l==curritem->charvaluelength &&(curritem->longvalue==-1||longvalue==curritem->longvalue)){ if(!memcmp(value,curritem->charvalue,l)) return curritem; } curritem=curritem->next; } return NULL; } Item *List::FindPath(char *value,long longvalue,int *noslashflag){ Item *retval=NULL; if(!value) return NULL; Item *curritem=start; while(curritem){ if((curritem->longvalue==-1||longvalue==curritem->longvalue)){ if(noslashflag) *noslashflag=0; if(curritem->charvalue){ if(!filenamecmp(value,curritem->charvalue,noslashflag)){ if(!noslashflag) return curritem; if(!*noslashflag) return curritem; else retval=curritem; } } } curritem=curritem->next; } if(retval){ if(noslashflag) *noslashflag=1; return retval; } return NULL; } Item *List::FindWildMatch(char *value){ if(!value) return NULL; Item *curritem=start; while(curritem){ if(curritem->charvalue){ if(wildmat(value,curritem->charvalue)) return curritem; } curritem=curritem->next; } return NULL; } Item *List::FindWildMatch(char *value,long longvalue){ if(!value) return NULL; Item *curritem=start; while(curritem){ if(curritem->charvalue){ if(curritem->longvalue==-1||longvalue==curritem->longvalue){ if(wildmat(value,curritem->charvalue)) return curritem; } } curritem=curritem->next; } return NULL; } HashTable::HashTable(unsigned xhashsize,int xpathnames){ hashsize=xhashsize; pathnames=xpathnames; table=new List[hashsize]; } HashTable::~HashTable(void){ delete table; } void HashTable::DeleteAll(void){ unsigned i; if(!table) return; for(i=0;icharvalue){ if(pathnames) return table[pathhashfunction(item->charvalue)].Add(item); else return table[hashfunction(item->charvalue)].Add(item); } return -1; } int HashTable::Remove(Item *item){ if(item->list) return item->list->Remove(item); return -1; } Item *HashTable::Find(char *value){ if(table&&value){ return table[hashfunction(value)].Find(value); } return NULL; } Item *HashTable::Find(char *value,long longvalue){ if(table&&value){ return table[hashfunction(value)].Find(value,longvalue); } return NULL; } Item *HashTable::FindPath(char *value,long longvalue,int *noslashflag){ if(table&&value){ return table[pathhashfunction(value)].FindPath(value,longvalue,noslashflag); } return NULL; } unsigned HashTable::hashfunction(char *arg){ if(!arg) return 0; unsigned i=0; while(*arg){ i*=9; i+=*arg; arg++; } return i%hashsize; } unsigned HashTable::pathhashfunction(char *arg){ /* for pathnames that may belong to directories*/ if(!arg) return 0; unsigned i=0; char *zeroedslash=NULL; char *p1; p1=strrchr(arg,'/'); if(p1){ if(!p1[1]||!strcmp(p1,"/file_index.html")||!strcmp(p1,"/index.html")){ zeroedslash=p1; *zeroedslash=0; } } while(*arg){ i*=9; i+=*arg; arg++; } if(zeroedslash) *zeroedslash='/'; return i%hashsize; }