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

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: }

unix.superglobalmegacorp.com

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