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