/* * FILEIO.C MODULE for MS-DOS. */ /* * The routines in this file read and write ASCII files from the disk. All of * the knowledge about files are here. A better message writing scheme should * be used. */ /* Notes: * I've implemented a caching read/write for MS-DOS. It speeds up reads * and writes about 3x on my 286 system. * blkmov() is in speed.asm and os.c. * blkccpy() is in speed.asm. * This was written with Lattice C 3.20. If you don't have the d routines * (dopen(), dcreat(), ...) in your C, they are just the DOS routines. */ /* Copyright 1990, 1991 Craig Durland * Distributed under the terms of the GNU General Public License. * Distributed "as is", without warranties of any kind, but comments, * suggestions and bug reports are welcome. */ #include #include #include #include "me2.h" #define WRITING 1 #define READING 2 #define CBLOCK 1024 /* cache block size */ extern char beol; /* in speed.asm */ static char cache[CBLOCK], *ptr; static int used, space, oper, fh; /* Open a file for reading */ ffropen(fn) char *fn; { if ((fh = dopen(fn,O_RDONLY)) == -1) return FIOFNF; oper = READING; used = 0; beol = 0; return FIOSUC; } /* Open a file for writing */ ffwopen(fn) char *fn; { if ((fh = dcreat(fn,0)) == -1) { mlwrite("Cannot open file for writing"); return FIOERR; } oper = WRITING; space = CBLOCK; ptr = cache; return FIOSUC; } /* Close a file */ ffclose() { /* flush the cache if not empty */ if (oper == WRITING && (used = CBLOCK-space) && dwrite(fh,cache,used) != used) { dclose(fh); mlwrite("Write I/O error"); return FIOERR; } if (dclose(fh)) { mlwrite("Error closing file"); return FIOERR; } return FIOSUC; } /* * Write a line to the already opened file. n is the line length, * less the free newline. Return the status. * Check for errors. */ ffputline(buf,n) char *buf; int n; { int s = FALSE; do { if (n <= space) /* buf will fit in cache */ { blkmov(ptr,buf,n); ptr += n; space -= n; if (s) break; buf = "\r\n"; n = 2; s = TRUE; /* add a CR LF to end of line */ } else /* buf won't fit in cache */ { blkmov(ptr,buf,space); buf += space; n -= space; ptr = cache; space = CBLOCK; if (dwrite(fh,cache,CBLOCK) != CBLOCK) { mlwrite("Write I/O error"); return FIOERR; } } } while (n > 0); return FIOSUC; } /* * Read a line from a file and store the bytes in the supplied buffer. * n is the length of the buffer, counting the '\0'. * Check for I/O errors. */ ffgetline(buf,n) char *buf; int n; { int z,s; s = FALSE; n--; /* leave room for '\0' */ while (TRUE) { if (used <= 0) /* the cache is empty */ { ptr = cache; used = dread(fh,cache,CBLOCK); if (used <= 0 || used > CBLOCK) /* end of file or error reading */ return s ? FIOSUC : FIOEOF; if (beol == 2) /* \r was the last character in the cache */ if (*ptr == '\n') { ptr++; used--; return FIOSUC; } else { *buf++ = '\r'; n--; } } s = TRUE; z = blkccpy(buf,ptr,n,used); ptr += z; used -= z; if (beol == 0) return FIOSUC; /* EoL or filled buf */ used = 0; n -= z; buf += z; } }