1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
|
#include <stdarg.h>
#include <string.h>
#include <assert.h>
#include <stdio.h>
#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));
}
}
|