Annotation of researchv10no/cmd/spitbol/cint/osread.c, revision 1.1.1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.