|
|
1.1 ! root 1: /* ! 2: * osread( mode,recsiz,ioptr,scptr ) reads the next record from ! 3: * the designated input file into the scblk. recsiz determines ! 4: * whether the read should be line or raw mode. line mode records ! 5: * are teminated with a new-line character (the new-line is not ! 6: * put in the scblk though). raw records are simply the next recsiz ! 7: * characters. ! 8: */ ! 9: ! 10: #include "spitblks.h" ! 11: #include "spitio.h" ! 12: ! 13: int osread( mode, recsiz, ioptr, scptr ) ! 14: ! 15: int mode; ! 16: int recsiz; ! 17: struct ioblk *ioptr; ! 18: struct scblk *scptr; ! 19: ! 20: { ! 21: register struct bfblk *bfptr = ioptr -> buf; ! 22: register char *cp = scptr -> str; ! 23: register char *bp; ! 24: register int cnt = 0; ! 25: int fdn = ioptr -> fdn; ! 26: register int n; ! 27: ! 28: /* ! 29: * Handle unbuffered reads. ! 30: */ ! 31: ! 32: if ( ioptr -> flg & IO_WRC ) { ! 33: ! 34: /* no line mode with unbuffered */ ! 35: if ( mode > 0 ) ! 36: return -2; ! 37: ! 38: /* attempt to read in scblk */ ! 39: n = read( fdn,cp,recsiz ); ! 40: ! 41: /* if read error then take action */ ! 42: if ( n < 0 ) ! 43: return -2; ! 44: ! 45: /* check for eof */ ! 46: if ( n == 0 ) ! 47: return -1; ! 48: ! 49: /* everything ok, so return */ ! 50: return n; ! 51: } ! 52: ! 53: /* ! 54: * Handle buffered reads. ! 55: */ ! 56: ! 57: if ( mode > 0 ) { ! 58: ! 59: /* line mode */ ! 60: register char *savecp; ! 61: char savechar; ! 62: ! 63: /* ! 64: * First phase: copy characters to the result ! 65: * buffer either until recsiz is exhausted or ! 66: * we have copied the last character of a line. ! 67: * This loop is speeded up by pretending that ! 68: * the input line is no longer than the result. ! 69: */ ! 70: ! 71: do { ! 72: char *oldbp; ! 73: ! 74: /* if the buffer is empty, try to fill it */ ! 75: if ( bfptr -> rem == 0 ) { ! 76: n = read ( fdn, bfptr -> buf, bfptr -> siz ); ! 77: ! 78: /* eof is only ok at the beginning of a line */ ! 79: if ( n == 0 ) ! 80: return cnt > 0? -2: -1; ! 81: ! 82: /* input errors are never ok */ ! 83: if ( n < 0 ) ! 84: return -2; ! 85: ! 86: bfptr -> off = 0; ! 87: bfptr -> rem = n; ! 88: } ! 89: ! 90: /* set n to max # chars we can process this time */ ! 91: n = recsiz - cnt; ! 92: if ( n > bfptr -> rem ) ! 93: n = bfptr -> rem; ! 94: ! 95: /* point bp and oldbp at the first char to be copied */ ! 96: oldbp = bp = bfptr -> buf + bfptr -> off; ! 97: ! 98: /* plant a newline at the end of the valid input */ ! 99: savecp = bp + n; ! 100: savechar = *savecp; ! 101: *savecp = '\n'; ! 102: ! 103: /* copy characters until we hit a newline */ ! 104: while ( *bp != '\n' ) ! 105: *cp++ = *bp++; ! 106: ! 107: /* restore the stolen character */ ! 108: *savecp = savechar; ! 109: ! 110: /* calculate how many characters were moved */ ! 111: n = bp - oldbp; ! 112: cnt += n; ! 113: bfptr -> off += n; ! 114: bfptr -> rem -= n; ! 115: ! 116: } while ( bp == savecp && cnt < recsiz ); ! 117: /* loop until we hit a real \n or recsiz is exhausted */ ! 118: ! 119: /* ! 120: * Second phase: discard characters up to and ! 121: * including the next newline in the input. ! 122: * This loop is optimized to miminize startup ! 123: * overhead, because it will usually be executed ! 124: * only once (but never less than once!) ! 125: */ ! 126: do { ! 127: /* ! 128: * decrement count of characters remaining ! 129: * in the buffer, check for buffer underflow ! 130: */ ! 131: if ( --bfptr -> rem < 0 ) { ! 132: n = read ( fdn, bfptr -> buf, bfptr -> siz ); ! 133: ! 134: /* eof and input errors are never ok */ ! 135: if ( n < 0 ) ! 136: return -2; ! 137: ! 138: bfptr -> off = 0; ! 139: bfptr -> rem = n - 1; ! 140: } ! 141: ! 142: /* ! 143: * The buffer is guaranteed non-empty, ! 144: * and the count of characters remaining ! 145: * has already been decremented by 1. ! 146: * Pick up a character and bump the offset. ! 147: */ ! 148: n = bfptr -> buf [bfptr -> off++]; ! 149: } while (n != '\n'); ! 150: /* loop until we see a newline */ ! 151: ! 152: } else { ! 153: /* raw mode, try to read exactly "recsiz" characters */ ! 154: while ( recsiz > 0 ) { ! 155: /* if the buffer is empty, try to fill it */ ! 156: if ( bfptr -> rem == 0 ) { ! 157: n = read ( fdn, bfptr -> buf, bfptr -> siz ); ! 158: ! 159: /* input error, no good */ ! 160: if ( n < 0 ) ! 161: return -2; ! 162: ! 163: /* eof, return what we got so far */ ! 164: if ( n == 0 ) ! 165: break; ! 166: ! 167: bfptr -> rem = n; ! 168: bfptr -> off = 0; ! 169: } ! 170: ! 171: /* calculate how many chars we can move */ ! 172: n = bfptr -> rem; ! 173: if ( n > recsiz ) ! 174: n = recsiz; ! 175: bp = bfptr -> buf + bfptr -> off; ! 176: ! 177: /* update pointers to move n characters */ ! 178: cnt += n; ! 179: recsiz -= n; ! 180: bfptr -> off += n; ! 181: bfptr -> rem -= n; ! 182: ! 183: /* move n characters from bp to cp */ ! 184: if ( n & 1 ) ! 185: *cp++ = *bp++; ! 186: n >>= 1; ! 187: if ( n > 0 ) { ! 188: do { ! 189: *cp++ = *bp++; ! 190: *cp++ = *bp++; ! 191: } while ( --n > 0 ); ! 192: } ! 193: } ! 194: ! 195: /* if we couldn't make any progress, signal end of file */ ! 196: if ( cnt == 0 ) ! 197: return -1; ! 198: } ! 199: ! 200: return cnt; ! 201: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.