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