|
|
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.