/* mp5.c * a Standard I/O replacement (input only) * by Douglas Jones */ #include #include /* #include */ #include "myio.h" #define BUFSIZE 31 /************************************************************** * global variables * **************************************************************/ struct myfile { int fd; /* file descriptor for this stream */ char * buf; /* this stream's buffer */ int pos; /* position in buffer */ int count; /* characters remaining in buffer */ long int bpos; /* position of buffer in file */ }; MYFILE * myfdopen( int fd, const char * mode ) { /* identical specification to fdopen() */ MYFILE * f = malloc( sizeof(MYFILE) ); f->fd = fd; f->buf = malloc( BUFSIZE ); f->pos = 0; /* we are at the start of the buffer */ f->count = 0; /* the buffer is empty */ f->bpos = 0; /* we start at the beginning of file */ return f; } int mygetc( MYFILE * f ) { /* identical specification to fgetc */ if (f->pos >= f->count) { f->bpos = f->bpos + f->count; f->count = read( f->fd, f->buf, BUFSIZE ); f->pos = 0; } if (f->count == 0) { return -1; /* that is FEOF */ } else { char ch = f->buf[f->pos]; f->pos = f->pos + 1; return ch; } } long int myseek( MYFILE * f, long int pos ) { /* equivalent to fseek( ... SEEK_SET ) */ int ercode; /* record of any errors in lseek */ int newpos = pos % BUFSIZE; int newbpos = pos - newpos; ercode = lseek( f->fd, newbpos, SEEK_SET ); if (ercode < 0) { return -1; } else if (newbpos == f->bpos) { /* seek within curreent buffer */ f->pos = newpos; return 0; } else { /* seek must read new buffer */ f->pos = newpos; f->bpos = newbpos; f->count = read( f->fd, f->buf, BUFSIZE ); return 0; } return lseek( f->fd, pos, SEEK_SET ); } long int mytell( MYFILE * f ) { /* identical specification to ftell */ return f->bpos + f->pos; }