#include #include #include #include #include "oidseq.h" #include "structfill.h" Assoc::Assoc(const char *oidstr,Assoc *nxt):next(nxt){ assert(oid=new BerOid(NOCONSTCAST oidstr,strlen(oidstr))); assert(str=strdup(oidstr)); } Assoc::Assoc(const char *oidstr,BerOid *newone,Assoc *nxt):next(nxt), oid(newone){ assert(str=strdup(oidstr)); assert(oid); } OidSeq::OidSeq(TableEntry *table):index(NULL),seq(NULL){ for(;table;table=table->next) append(table->oidstr); } void OidSeq::remove(const char *oidstr){ assert(index); /* trying to delete from an empty list */ if(!strcmp(oidstr,index->str)){ Assoc *nextone=index->next; delete index; index=nextone; } else { char test=0; for(Assoc *cur=index;cur->next;cur=cur->next){ if(*cur->next==oidstr){ Assoc *doomed=cur->next; cur->next=doomed->next; delete doomed; test=1; break; } } assert(test); /* item being deleted doesn't exist on list */ } assert(seq); /* should never happen -- problem with seq and index being out of sync */ // char buf[10240]; // print(buf,10240); // fprintf(stderr,"%s\n",buf); BerOid standard(NOCONSTCAST oidstr,strlen(oidstr)); BerBase *testcase; unsigned int i=0; while(testcase=seq->peek(i)){ testcase=((BerSequence*)testcase)->peek(0); //move into the oid if(*(BerOid*)testcase==standard){ seq->extract(i); // memset(buf,0,10240); // print(buf,10240); // fprintf(stderr,"i=%d\n%s\n",i,buf); return; } i++; } assert(0); /* oid wasn't found */ } void OidSeq::append(const char *oidstr){ assert(index=new Assoc(oidstr,index)); if(seq==NULL) seq=new BerSequence(SEQUENCE_TAG,1, new BerSequence(SEQUENCE_TAG,2,index->oid, new BerNull())); else seq->append(1,new BerSequence(SEQUENCE_TAG,2,index->oid,new BerNull())); } void OidSeq::append(CONST char *oidstr, Tags type, void *data, unsigned int len){ assert(index=new Assoc(oidstr,index)); BerBase *newone; switch(type){ case STRING_TAG: assert(newone=new BerString((char*)data,len)); break; case OID_TAG: assert(newone=new BerOid((char*)data,len)); break; case IPADDR_TAG: assert(newone=new BerIPAddr((char*)data,len)); break; default: assert(0); //bad type passed into append } if(seq==NULL) seq=new BerSequence(SEQUENCE_TAG,1, new BerSequence(SEQUENCE_TAG,2,index->oid,newone)); else seq->append(1,new BerSequence(SEQUENCE_TAG,2,index->oid,newone)); } void OidSeq::append(const char *oidstr, Tags type, long data){ assert(index=new Assoc(oidstr,index)); BerBase *newone; assert(type==INT_TAG || type==COUNTER_TAG); /* used the wrong version of append */ assert(newone=new BerInt(data)); // printf("val=%ld\n",((BerInt*)newone)->value()); if(seq==NULL) seq=new BerSequence(SEQUENCE_TAG,1, new BerSequence(SEQUENCE_TAG,2,index->oid,newone)); else seq->append(1,new BerSequence(SEQUENCE_TAG,2,index->oid,newone)); } OidSeq::OidSeq(unsigned int num...):index(NULL),seq(NULL){ va_list oidstrs; va_start(oidstrs,num); for(;num>0;num--) append(va_arg(oidstrs,char*)); va_end(oidstrs); } OidSeq::~OidSeq(){ delete seq; while(index){ Assoc *tmp=index->next; delete index; index=tmp; } } /* the fact that these are implemented using serial searches should not be a problem due to the fact that the list of oids should be rather small. */ BerBase *OidSeq::value(const char *oid){ for(Assoc *cur=index;cur;cur=cur->next) if(!strcmp(oid,cur->str)) return cur->oid->next; return NULL; } BerBase *OidSeq::value(BerOid &oid){ for(Assoc *cur=index;cur;cur=cur->next) if(oid==*(cur->oid)) return cur->oid->next; return NULL; } BerBase *OidSeq::child(const char *oid){ for(Assoc *cur=index;cur;cur=cur->next) if(!strncmp(oid,cur->str,strlen(oid))) return cur->oid->next; return NULL; } BerOid *OidSeq::key(const char *oid){ for(Assoc *cur=index;cur;cur=cur->next) if(!strcmp(oid,cur->str)) return cur->oid; return NULL; } OidSeq::OidSeq(BerSequence *valseq):seq(valseq),index(NULL){ for(BerBase *cur=valseq->peek(0);cur!=NULL;cur=cur->next){ char buf[256]; //max oid length assert(cur->type()==SEQUENCE_TAG); BerSequence *curseq=(BerSequence*)cur; int len; assert(curseq->peek(0)->type()==OID_TAG); assert((len=curseq->peek(0)->print(buf,256))!=-1); buf[len]=0; assert(index=new Assoc(buf,(BerOid*)curseq->peek(0),index)); } }