Annotation of 43BSD/contrib/dipress/src/lib/libip/literal.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *  Interpress utilities
                      3:  *
                      4:  *  Written for Xerox Corporation by William LeFebvre
                      5:  *  24-May-1984
                      6:  *
                      7:  * Copyright (c) 1984, 1985 Xerox Corp.
                      8:  *
                      9:  * HISTORY
                     10:  * 15-Jan-86  lee at Xerox, WRC
                     11:  *     Removed the rest of the Vax dependencies.
                     12:  *
                     13:  *     10-sep-85  lee moore    Removed some dependencies on the Vax.
                     14:  *                             Plenty more to be removed
                     15:  *     29-apr-85  ed flint     add conditional compilation for vax-11 c (vms)
                     16:  */
                     17: 
                     18: /*
                     19:  *  Subroutines to help build interpress files:
                     20:  *
                     21:  *  literal interface level - these routines produce interpress output at
                     22:  *                           the token level.
                     23:  */
                     24: 
                     25: /*
                     26:  *  NOTE:  Some of these "subroutines" are one-liners, so they are written
                     27:  *        as macros for better efficiency.
                     28:  */
                     29: 
                     30: # define Rational_max  1073741824
                     31: # define ip_Buffsize   1024
                     32: 
                     33: #ifndef vax11c
                     34: # include <sys/param.h>
                     35: # include <math.h>
                     36: # include <stdio.h>
                     37: #endif
                     38: 
                     39: # include "iptokens.h"
                     40: # include "literal.h"          /* macro definitions for some routines */
                     41: 
                     42: # ifndef NULL
                     43: # define NULL (char *)0
                     44: # endif
                     45: 
                     46: #ifdef vax11c
                     47: # define NOFILE 20
                     48: #endif
                     49: 
                     50: # define   No  0
                     51: # define   Yes 1
                     52: 
                     53: static int  ip_fd = -1;                        /* current Interpress file */
                     54: static char ip_filebuff[ip_Buffsize];  /* file buffer */
                     55: static char *ip_buffptr = NULL;                /* points in to ip_filebuff */
                     56: static int  ip_bytecnt;                        /* number of bytes in ip_filebuff */
                     57: static char ip_files[NOFILE] = { 0 };  /* marks which files are ip files */
                     58: 
                     59: /*
                     60:  *  Definitions for the primitives suggested in the Interpress standard
                     61:  *  (XSIS 048302).  The following primitives are defined with macros in
                     62:  *  "literal.h":
                     63:  *
                     64:  *     AppendComment
                     65:  *     AppendIdentifier
                     66:  *     AppendInsertFile
                     67:  *     AppendString
                     68:  *
                     69:  *  Currently, AppendString will only handle byte values -- it will not
                     70:  *  try to insert any escape characters.  The rationale for this is that
                     71:  *  ASCII (which is what this system uses) doesn't have character codes that
                     72:  *  high.
                     73:  */
                     74: 
                     75: AppendOp(opcode)
                     76: 
                     77: int opcode;
                     78: 
                     79: {
                     80:     if (opcode > SHORT_OP_LIMIT)
                     81:     {
                     82:        /* has to be coded as a long op */
                     83:        append_word((unsigned short)((LONG_OP << 8) | opcode));
                     84:     }
                     85:     else
                     86:     {
                     87:        /* small enough to be a short op */
                     88:        append_byte((unsigned char)(SHORT_OP | opcode));
                     89:     }
                     90: }
                     91: 
                     92: AppendNumber(number)
                     93: 
                     94: double number;
                     95: 
                     96: {
                     97:     long d;
                     98:     double r;
                     99:     
                    100:     if (number == (double)(d = (long)number))
                    101:     {
                    102:        AppendInteger(d);
                    103:     }
                    104:     else
                    105:     {
                    106:        d = 1;
                    107:        while ((fabs(r = number * d) < Rational_max) &&
                    108:               (d < Rational_max) &&
                    109:               (r != (float)((int)(r))))
                    110:        {
                    111:            d <<= 1;
                    112:        }
                    113:        AppendRational((long)r, d);
                    114:     }
                    115: }
                    116: 
                    117: 
                    118: /*
                    119:  * note that although the routine is called AppendInteger, it is really
                    120:  * AppendLong.  This is because alot of code wants to use 32 bit numbers.
                    121:  * If you want to pass it a 16bit int, that will work too.
                    122:  */
                    123: 
                    124: AppendInteger(number)
                    125: 
                    126: long number;
                    127: 
                    128: {
                    129:     if (number < INTEGER_MIN || number > INTEGER_MAX)
                    130:     {
                    131:        append_integer_sequence(number);
                    132:     }
                    133:     else
                    134:     {
                    135:        append_short_number((short) number);
                    136:     }
                    137: }
                    138: 
                    139: AppendRational(value, divisor)
                    140: 
                    141: long value, divisor;
                    142: 
                    143: {
                    144:     int len_value, len_divisor, len;
                    145: 
                    146:     len_value = bytes_in_int(value);
                    147:     len_divisor = bytes_in_int(divisor);
                    148: 
                    149:     len = len_value > len_divisor ? len_value : len_divisor;
                    150:     append_Sequence(sequenceRational, len << 1, (unsigned char *)NULL);
                    151:     append_n_byte_int(value, len);
                    152:     append_n_byte_int(divisor, len);
                    153: }
                    154: 
                    155: #ifdef notdef
                    156: AppendIntegerVector(vector, num)
                    157: 
                    158: int *vector;   /* ??? */
                    159: int  number;
                    160: 
                    161: {
                    162:     
                    163: }
                    164: #endif
                    165: 
                    166: /*
                    167:  *  The remainder of this file contains lower level primitives:
                    168:  */
                    169: 
                    170: /*
                    171:  *  append_Sequence(type, length, buff)
                    172:  *
                    173:  *  Append a sequence descriptor and its data bytes.  The descriptor is of
                    174:  *  type "type" and length "length".  "Buff" points to the buffer containing
                    175:  *  the data.  If "length" is negative, then bytes from "buffer" are written
                    176:  *  back to front (this makes writing integers easy).
                    177:  */
                    178: 
                    179: append_Sequence(type, length, buff)
                    180: 
                    181: int  type;
                    182: int  length;
                    183: unsigned char *buff;
                    184: 
                    185: {
                    186: # ifdef notnow
                    187:     /* some day, we should make this check, but not today */
                    188:     if ((length & 0x7f000000) != 0)
                    189:     {
                    190:        /* too big to fit in a long ... */
                    191:     }
                    192: # endif
                    193: 
                    194:     /* check for swapped byte correction */
                    195:     if (length < 0)
                    196:     {
                    197:        fprintf(stderr, "negative sequence!\n");
                    198:        abort();
                    199:     }
                    200: 
                    201:     if ((length & 0x7fffff00) != 0)
                    202:     {
                    203:        /* too big to fit in a short sequence */
                    204:        append_byte((unsigned char) (LONG_SEQUENCE | type));
                    205:        append_n_byte_int((long) length, 3);
                    206:     }
                    207:     else
                    208:     {
                    209:        append_byte((unsigned char) (SHORT_SEQUENCE | type));
                    210:        append_byte((unsigned char) length);
                    211:     }
                    212: 
                    213:     /* tack on data, if any */
                    214:     if (buff != NULL)
                    215:         append_bytes(length, buff);
                    216: }
                    217: 
                    218: 
                    219: /*
                    220:  * append_integer_sequence(number)
                    221:  *     A special version of append_sequence that handles integers.  Integers
                    222:  *     must be treated differently because the natural representation of an
                    223:  *     integer for a particular machine maybe byte swapped relative to the
                    224:  *     Xerox standard.
                    225:  */
                    226: append_integer_sequence(number)
                    227: 
                    228: long number;
                    229: 
                    230: {
                    231:     int length = bytes_in_int(number);
                    232: 
                    233:     append_byte((unsigned char) (SHORT_SEQUENCE | sequenceInteger));
                    234:     append_byte((unsigned char) length);
                    235:     append_n_byte_int(number, length);
                    236: }
                    237: 
                    238: /*
                    239:  * append_n_byte_int(number, length)
                    240:  *     Append N bytes of an integer to the interpress master.
                    241:  */
                    242: 
                    243: append_n_byte_int(number, length)
                    244: 
                    245: long number;
                    246: int length;    /* measured in bytes */
                    247: 
                    248: {
                    249:     int shift;
                    250: 
                    251: #ifdef notdef
                    252:     switch( length ) {
                    253:        case 4:
                    254:                append_byte((unsigned char) (number >> 24));
                    255:        case 3:
                    256:                append_byte((unsigned char) (number >> 16));
                    257:        case 2:
                    258:                append_byte((unsigned char) (number >>  8));
                    259:        case 1:
                    260:                append_byte((unsigned char) number);
                    261:                break;
                    262:        default:
                    263:                fprintf(stderr, "append_n_byte_int: asked to append %d bytes\n", length);
                    264:        }
                    265: #else
                    266:     if( length > sizeof(long) )
                    267:        fprintf(stderr, "append_n_byte_int: asked to append %d bytes\n", length);
                    268: 
                    269:     for( shift = (length - 1)*8; shift >= 0; shift -= 8 )
                    270:        append_byte((unsigned char) (number >> shift));
                    271: #endif
                    272: }
                    273:        
                    274: 
                    275: /*
                    276:  *  append_word(value) - write the two byte (word) value "value"
                    277:  */
                    278: 
                    279: append_word(value)
                    280: 
                    281: unsigned short value;
                    282: 
                    283: {
                    284: #ifdef notdef
                    285:     append_n_byte_int(value, 2);
                    286: #else
                    287:     append_byte((unsigned char) (value >> 8));
                    288:     append_byte((unsigned char) value);
                    289: #endif
                    290: }
                    291: 
                    292: /*
                    293:  *  append_byte(value) - write out a byte
                    294:  */
                    295: 
                    296: append_byte(value)
                    297: 
                    298: unsigned char value;
                    299: 
                    300: {
                    301:     *ip_buffptr++ = value;
                    302:     if (++ip_bytecnt == ip_Buffsize)
                    303:     {
                    304:        write(ip_fd, ip_filebuff, ip_Buffsize);
                    305:        ip_bytecnt = 0;
                    306:        ip_buffptr = ip_filebuff;
                    307:     }
                    308: }
                    309: 
                    310: /*
                    311:  *  append_bytes(length, buff) - write the buffer of bytes pointed to by
                    312:  *                              "buff" with length "length".
                    313:  */
                    314: 
                    315: append_bytes(length, buff)
                    316: 
                    317: int length;
                    318: unsigned char *buff;
                    319: 
                    320: {
                    321:     while (length-- > 0)
                    322:     {
                    323:        append_byte(*buff++);
                    324:     }
                    325: }
                    326: 
                    327: 
                    328: /* this routine assumes 4 bytes in an int and two's complement notation */
                    329: /* this routine should be replaced! -lee */
                    330: /* this routine sometime over estimates the size of an integer. why? */
                    331: 
                    332: bytes_in_int(value)
                    333: 
                    334: long value;
                    335: 
                    336: {
                    337:     int i;
                    338:     long mask;
                    339: 
                    340:     if (value < 0)
                    341:     {
                    342:        /* takes the same space as its one's complemented value */
                    343:        value = ~value;
                    344:     }
                    345:     if (value == 0)
                    346:     {
                    347:        /* avoids infinite looping */
                    348:        return(1);
                    349:     }
                    350:     for (i = 4, mask = 0xff800000; (value & mask) == 0; i--, mask >>= 8)
                    351:        ;
                    352:     return(i);
                    353: }
                    354: 
                    355: /*
                    356:  *  ip_select(fd) - select file descriptor "fd" as the Interpress file for
                    357:  *                 later use by the i/o routines supplied in this library.
                    358:  */
                    359: 
                    360: ip_select(fd)
                    361: 
                    362: int fd;
                    363: 
                    364: {
                    365:     if (ip_fd != -1)
                    366:     {
                    367:        ip_flush();
                    368:     }
                    369: 
                    370:     /* set our idea of current file descriptor and initialize the buffer */
                    371:     ip_fd = fd;
                    372:     ip_buffptr = ip_filebuff;
                    373:     ip_bytecnt = 0;
                    374: 
                    375:     /* check for initialization */
                    376:     if (!ip_files[fd])
                    377:     {
                    378:        /* not an Intepress file -- initialize it */
                    379:        append_bytes(strlen(IP_Header), (unsigned char *) IP_Header);
                    380:        ip_files[fd] = Yes;
                    381:     }
                    382: }
                    383: 
                    384: /*
                    385:  *  ip_raw_select(fd) - same as ip_select, but no header is placed at the
                    386:  *                     front of the file.
                    387:  */
                    388: 
                    389: ip_raw_select(fd)
                    390: 
                    391: int fd;
                    392: 
                    393: {
                    394:     /* trick ip_select into thinking that it is already initialized */
                    395:     ip_files[fd] = Yes;
                    396: 
                    397:     /* do a normal select */
                    398:     ip_select(fd);
                    399: }
                    400: 
                    401: ip_close()
                    402: 
                    403: {
                    404:     if (ip_fd != -1)
                    405:     {
                    406:        ip_flush();
                    407:        ip_files[ip_fd] = No;
                    408:        close(ip_fd);
                    409:        ip_fd = -1;
                    410:     }
                    411: }
                    412: 
                    413: ip_flush()
                    414: 
                    415: {
                    416:     /* flush the buffer */
                    417:     if (ip_Buffsize - ip_bytecnt > 0)
                    418:     {
                    419:        write(ip_fd, ip_filebuff, ip_bytecnt);
                    420:     }
                    421: }

unix.superglobalmegacorp.com

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