#include #include #include #include #include #include #include "myc_err.h" #include "myc_str.h" #include "myc_buf.h" char *StrNGet(StrBuf *buf, char *result, int reslen, int sep) { char *b, *f, *e, quote; int res, l, ll; if (buf->rdpos < 0 || buf->rdpos >= buf->dsize || buf->buf==NULL) ERR_MSG("buffer corrupt"); b=buf->buf + buf->rdpos; if (*b=='"' || *b=='\'') { /* take string within quotes (single or double) */ quote=*b; b++; f=strchr(b, quote); if (f==NULL) ERR_MSG("missing '""'"); l=f-b; if (sep == StrNONE) { buf->rdpos=f - buf->buf + 1; buf->seen = 0; } else { e=strchr(f+1, sep); if (e==NULL) { buf->rdpos = f - buf->buf + 1 + strlen(f+1); buf->seen=0; } else { buf->rdpos = e - buf->buf + 1; buf->seen=1; } } } else { f=strchr(b, sep); if (f==NULL) { l=strlen(b); f=b+l; buf->rdpos+=l; buf->seen=0; } else { l=f-b; buf->rdpos+=l+1; buf->seen=1; } } if (result==NULL) { if (reslen==-1) { /* special case for StrGetBuf */ return(f); } *f='\0'; return(b); } else { if (l>=reslen) l=reslen-1; /* ERR_MSG("result too short"); */ strncpy(result, b, l); result[l]='\0'; return(result); } OnError: buf->rdpos=buf->dsize; /* illegal value */ return(NULL); } int StrGetBuf(StrBuf *buf, StrBuf *res, int sep) { char *b, *f; b = buf->buf + buf->rdpos; ERR_P(f=StrNGet(buf, NULL, -1, sep)); res->buf = b; res->wrpos = f-b; res->rdpos = 0; res->dsize = f-b; return(0); OnError: buf->rdpos=buf->dsize; /* illegal value */ return(-1); } int StrGetInt(StrBuf *buf, int *res, int sep) { char num[32]; int i, l, p; p=buf->rdpos; ERR_P(StrGet(buf, num, sep)); i=sscanf(num, "%d%n", res, &l); if (i==0) ERR_MSG("illegal number"); if (sep==StrNONE) { buf->rdpos=p+l; } return(0); OnError: buf->rdpos=buf->dsize; /* illegal value */ return(0); } int StrGetFloat(StrBuf *buf, float *res, int sep) { char num[32]; int i, l, p; p=buf->rdpos; ERR_P(StrGet(buf, num, sep)); if (num[0]=='N' && num[1]=='a' && num[2]=='N') { l=3; *res = MYC_NAN; } else { i=sscanf(num, "%f%n", res, &l); if (i==0) { ERR_MSG("illegal number"); } } if (sep==StrNONE) { buf->rdpos=p+l; } return(0); OnError: buf->rdpos=buf->dsize; /* illegal value */ return(-1); } int StrGetEnd(StrBuf *buf) { if (buf->buf!=NULL) { if (buf->rdpos < 0 || buf->rdpos >= buf->dsize) ERR_MSG("buffer corrupt"); if (buf->rdpos != buf->wrpos) ERR_MSG("superflous content in buffer"); } return(0); OnError: return(-1); } int StrPut(StrBuf *buf, const char *str, int sep) { int l, pos; char quote; pos=buf->wrpos; if (pos < 0 || pos >= buf->dsize || buf->buf==NULL) ERR_MSG("buffer corrupt"); l=strlen(str); quote='\0'; if (sep>0) { if (strchr(str, sep)!=NULL) { if (strchr(str, '"')!=NULL) { quote='"'; l+=2; } if (strchr(str, '\'')!=NULL) { if (quote!='\0') ERR_MSG("str must not contain separator and both kind of quotes"); quote='\''; l+=2; } } } if (pos+l >= buf->dsize) { ERR_MSG("buffer too short"); } if (quote!='\0') { buf->buf[pos]=quote; pos++; strcpy(buf->buf + pos, str); buf->buf[pos]=quote; pos++; } else { strcpy(buf->buf + pos, str); } pos+=l; if (sep!=StrNONE) { buf->buf[pos]=sep; pos++; } else { buf->buf[pos]='\0'; } buf->wrpos=pos; return(0); OnError: buf->wrpos=-1; return(-1); } int StrPutInt(StrBuf *buf, int val, int sep) { char num[32]; sprintf(num, "%d", val); ERR_I(StrPut(buf, num, sep)); return(0); OnError: return(-1); } int StrPutFloat(StrBuf *buf, float val, int sep) { char num[32]; int l; if (val == MYC_NAN) { ERR_I(StrPut(buf, "NaN", sep)); } else { sprintf(num, "%g", val); ERR_I(StrPut(buf, num, sep)); } return(0); OnError: return(-1); } void StrReset(StrBuf *buf) { buf->rdpos=0; } void StrClear(StrBuf *buf) { buf->rdpos=0; buf->wrpos=0; } void StrNLink(StrBuf *buf, char *str, int length) { int l; buf->buf=str; buf->rdpos=0; l=strlen(str); if (lwrpos=l; buf->dsize=buf->wrpos; } #define TWO_23 8388608 #define EXP_OFFS 128 void flt_to_char4(double f, char buf[4]) { double m; int e, res, ir; m=frexp(f, &e); e=e+EXP_OFFS; if (e<0 || m==0) { res=0; m=0; } else { if (e>255) { res=255*TWO_23+(TWO_23-1); /* max. representable number */ } else { res=e*TWO_23+(int)(0.5+(fabs(m*2)-1.0)*TWO_23); } } buf[0]=res % 256; res=res/256; buf[1]=res % 256; res=res/256; buf[2]=res % 256; res=res/256; if (m<0) { buf[3]=res-128; } else { buf[3]=res; } } double flt_from_char4(char buf[4]) { int s, i, b0, b1, b2, b3; b0=buf[0]; if (b0<0) b0+=256; b1=buf[1]; if (b1<0) b1+=256; b2=buf[2]; if (b2<0) b2+=256; b3=buf[3]; if (b3<0) b3+=256; if (b3>=128) { i=(b3-128)*(256*65536)+b2*65536+b1*256+b0; if (i==0) return 0.0; return -ldexp((i % TWO_23)*1.0/(TWO_23)*0.5+0.5, i/TWO_23-EXP_OFFS); } else { i=b3*(256*65536)+b2*65536+b1*256+b0; if (i==0) return 0.0; return ldexp((i % TWO_23)*1.0/(TWO_23)*0.5+0.5, i/TWO_23-EXP_OFFS); } } int StrPutArray(StrBuf *buf, float val[], int size) { int i, pos; char *b; pos=buf->wrpos; if (pos < 0 || pos >= buf->dsize || buf->buf==NULL) ERR_MSG("buffer corrupt"); if (pos+4*size >= buf->dsize) ERR_MSG("buffer too short"); b=buf->buf+pos; flt_to_char4((float)size, b); b+=4; for (i=0; iwrpos=b - buf->buf; return(0); OnError: buf->wrpos=-1; return(-1); } int StrGetArray(StrBuf *buf, float val[], int maxsize) { int size, i; char *b; double gg; if (buf->rdpos < 0 || buf->rdpos >= buf->dsize || buf->buf==NULL) ERR_MSG("buffer corrupt"); b=buf->buf + buf->rdpos; size=flt_from_char4(b); b+=4; buf->rdpos+=4*(size+1); if (maxsizerdpos=buf->dsize; /* illegal value */ return(-1); }