Sflong_t sfgetl(reg Sfio_t * f) { Sflong_t v; reg uchar *s, *ends, c; reg int p; SFMTXSTART(f, (Sflong_t) (-1)); if (f->mode != SF_READ && _sfmode(f, SF_READ, 0) < 0) SFMTXRETURN(f, (Sflong_t) (-1)); SFLOCK(f, 0); for (v = 0;;) { if (SFRPEEK(f, s, p) <= 0) { f->flags |= SF_ERROR; v = (Sflong_t) (-1); goto done; } for (ends = s + p; s < ends;) { c = *s++; if (c & SF_MORE) v = ((Sfulong_t) v << SF_UBITS) | SFUVALUE(c); else { /* special translation for this byte */ v = ((Sfulong_t) v << SF_SBITS) | SFSVALUE(c); f->next = s; v = (c & SF_SIGN) ? -v - 1 : v; goto done; } } f->next = s; } done: SFOPEN(f, 0); SFMTXRETURN(f, v); }
ssize_t getdelim(char** sp, size_t* np, int delim, Sfio_t* f) { ssize_t m; ssize_t n; ssize_t k; ssize_t p; uchar* s; uchar* ps; SFMTXDECL(f); STDIO_INT(f, "getdelim", ssize_t, (char**, size_t*, int, Sfio_t*), (sp, np, delim, f)) SFMTXENTER(f, -1); if(delim < 0 || delim > 255 || !sp || !np) /* bad parameters */ SFMTXRETURN(f, -1); if(f->mode != SF_READ && _sfmode(f,SF_READ,0) < 0) SFMTXRETURN(f, -1); SFLOCK(f,0); if(!(s = (uchar*)(*sp)) || (n = *np) < 0) { s = NIL(uchar*); n = 0; }
/* Get the size of a stream. ** ** Written by Kiem-Phong Vo. */ Sfoff_t sfsize(reg Sfio_t * f) { Sfdisc_t *disc; reg int mode; Sfoff_t s; SFMTXSTART(f, (Sfoff_t) (-1)); if ((mode = f->mode & SF_RDWR) != (int) f->mode && _sfmode(f, mode, 0) < 0) SFMTXRETURN(f, (Sfoff_t) (-1)); if (f->flags & SF_STRING) { SFSTRSIZE(f); SFMTXRETURN(f, f->extent); } SFLOCK(f, 0); s = f->here; if (f->extent >= 0) { if (f->flags & (SF_SHARE | SF_APPENDWR)) { for (disc = f->disc; disc; disc = disc->disc) if (disc->seekf) break; if (!HAVE_SYS_STAT_H || disc) { Sfoff_t e; if ((e = SFSK(f, 0, SEEK_END, disc)) >= 0) f->extent = e; if (SFSK(f, f->here, SEEK_SET, disc) != f->here) f->here = SFSK(f, (Sfoff_t) 0, SEEK_CUR, disc); } #ifdef HAVE_SYS_STAT_H else { Stat_t st; if (fstat(f->file, &st) < 0) f->extent = -1; else if ((f->extent = st.st_size) < f->here) f->here = SFSK(f, (Sfoff_t) 0, SEEK_CUR, disc); } #endif } if ((f->flags & (SF_SHARE | SF_PUBLIC)) == (SF_SHARE | SF_PUBLIC)) f->here = SFSK(f, (Sfoff_t) 0, SEEK_CUR, f->disc); } if (f->here != s && (f->mode & SF_READ)) { /* buffered data is known to be invalid */ f->next = f->endb = f->endr = f->endw = f->data; } if (f->here < 0) f->extent = -1; else if (f->extent < f->here) f->extent = f->here; if ((s = f->extent) >= 0) { if (f->flags & SF_APPENDWR) s += (f->next - f->data); else if (f->mode & SF_WRITE) { s = f->here + (f->next - f->data); if (s < f->extent) s = f->extent; } } SFOPEN(f, 0); SFMTXRETURN(f, s); }
/** * @param f stream where the exception happened * @param type type that was performed * @param io return value that indicated exception * @param disc discipline in use */ int _sfexcept(Sfio_t * f, int type, ssize_t io, Sfdisc_t * disc) { reg int ev, local, lock; reg ssize_t size; reg uchar *data; SFMTXSTART(f, -1); GETLOCAL(f, local); lock = f->mode & SF_LOCK; if (local && io <= 0) f->flags |= io < 0 ? SF_ERROR : SF_EOF; if (disc && disc->exceptf) { /* let the stream be generally accessible for this duration */ if (local && lock) SFOPEN(f, 0); /* so that exception handler knows what we are asking for */ _Sfi = f->val = io; ev = (*(disc->exceptf)) (f, type, &io, disc); /* relock if necessary */ if (local && lock) SFLOCK(f, 0); if (io > 0 && !(f->flags & SF_STRING)) SFMTXRETURN(f, ev); if (ev < 0) SFMTXRETURN(f, SF_EDONE); if (ev > 0) SFMTXRETURN(f, SF_EDISC); } if (f->flags & SF_STRING) { if (type == SF_READ) goto chk_stack; else if (type != SF_WRITE && type != SF_SEEK) SFMTXRETURN(f, SF_EDONE); if (local && io >= 0) { if (f->size >= 0 && !(f->flags & SF_MALLOC)) goto chk_stack; /* extend buffer */ if ((size = f->size) < 0) size = 0; if ((io -= size) <= 0) io = SF_GRAIN; size = ((size + io + SF_GRAIN - 1) / SF_GRAIN) * SF_GRAIN; if (f->size > 0) data = (uchar *) realloc((char *) f->data, size); else data = (uchar *) malloc(size); if (!data) goto chk_stack; f->endb = data + size; f->next = data + (f->next - f->data); f->endr = f->endw = f->data = data; f->size = size; } SFMTXRETURN(f, SF_EDISC); } if (errno == EINTR) { if (_Sfexiting || (f->bits & SF_ENDING)) /* stop being a hero */ SFMTXRETURN(f, SF_EDONE); /* a normal interrupt, we can continue */ errno = 0; f->flags &= ~(SF_EOF | SF_ERROR); SFMTXRETURN(f, SF_ECONT); } chk_stack: if (local && f->push && ((type == SF_READ && f->next >= f->endb) || (type == SF_WRITE && f->next <= f->data))) { /* pop the stack */ reg Sfio_t *pf; if (lock) SFOPEN(f, 0); /* pop and close */ pf = (*_Sfstack) (f, NIL(Sfio_t *)); if ((ev = sfclose(pf)) < 0) /* can't close, restack */ (*_Sfstack) (f, pf); if (lock) SFLOCK(f, 0); ev = ev < 0 ? SF_EDONE : SF_ESTACK; } else
int _sfputd(Sfio_t * f, Sfdouble_t v) { #define N_ARRAY (16*sizeof(Sfdouble_t)) reg ssize_t n, w; reg uchar *s, *ends; int exp; uchar c[N_ARRAY]; double x; SFMTXSTART(f, -1); if (f->mode != SF_WRITE && _sfmode(f, SF_WRITE, 0) < 0) SFMTXRETURN(f, -1); SFLOCK(f, 0); /* get the sign of v */ if (v < 0.) { v = -v; n = 1; } else n = 0; /* make the magnitude of v < 1 */ if (v != 0.) v = frexp(v, &exp); else exp = 0; /* code the sign of v and exp */ if ((w = exp) < 0) { n |= 02; w = -w; } /* write out the signs and the exp */ SFOPEN(f, 0); if (sfputc(f, n) < 0 || (w = sfputu(f, w)) < 0) SFMTXRETURN(f, -1); SFLOCK(f, 0); w += 1; s = (ends = &c[0]) + sizeof(c); while (s > ends) { /* get 2^SF_PRECIS precision at a time */ n = (int) (x = ldexp(v, SF_PRECIS)); *--s = n | SF_MORE; v = x - n; if (v <= 0.) break; } /* last byte is not SF_MORE */ ends = &c[0] + sizeof(c) - 1; *ends &= ~SF_MORE; /* write out coded bytes */ n = ends - s + 1; w = SFWRITE(f, (void *) s, n) == n ? w + n : -1; SFOPEN(f, 0); SFMTXRETURN(f, w); }