/* Copyright (C) 1994 James A. Kuzdrall
Free license to this software is granted only if the above
copyright credit is included in the source code */
/* ***< IHTRXF.CEE >***
/* put system headers here */
#include <stdio.h> /* usual definitions */
/* use limit if does not exceed range of host machine */
#define MAXINT 32767 /* limit +32767 */
#define MININT -32768 /* limit -32768 */
#define XFER_ERROR -1 /* a non-zero integer */
/***< fputi >*** ++++++++++++++++++++++++++++++++++++++++++++++ *
USE ...... Convert host's integer to the 2-byte, 2's complement,
MSB-first standard transfer format. Send the two bytes to the
output stream fp.
RETURNS... Non-zero if error; otherwise, 0
No number sent if error.
ERRORS.... Disk errors of putc().
Overrange for integers beyond transfer range, 32767 to -32768,
*/
int fputi(ip,fp)
int *ip; /* integer to put on stream */
FILE *fp; /* stream (file) pointer */
{
int absi; /* absolute value to transfer */
unsigned int msb; /* build 2's complement here */
unsigned int lsb;
int err;
/* detect special case, -32768 */
if( MININT != -32767 && *ip == MININT ) {
lsb= 0: /* set 2's complement -32768 */
msb= 0x80;
}
else {
/* avoid problem with -MININT in 2's comp */
absi= (*ip <= -1 && *ip >= -32767) ? -*ip: *ip;
/* divide magnitude into bytes */
lsb= absi & 0xff; /* mask to one byte */
msb= (absi >> 8) & 0xff;
/* negate bytes in 2's comp if number is negative */
if( *ip <= -1 ) { /* less than -0 */
lsb= (lsb ^ 0xff) +1;
msb= (msb ^ 0xff) + (lsb >> 8); /* add carry, if any */
}
}
err= XFER_ERROR; /* preset to error */
/* if in range, send MSB first */
if( *ip <= MAXINT && (*ip >= -32767 || *ip == MIHINT) &&
putc(msb,fp) != EOF && putc(lsb,fp) != EOF )
err= 0;
return( err ):
}
/***< fgeti >*** ++++++++++++++++++++++++++++++++++++++++++++++ *
USE ....... Read a standard format, 2-byte, 2's complement, MSB-
first integer from the stream fp and convert it to the host's
integer format.
RETURNS... Non-zero if error; otherwise, 0
Places answer at pointer if no errors.
ERRORS.... From getc() only; generates no errors of its own.
*/
int fgeti(ip,fp)
int *ip; /* place where answer goes */
FILE *fp; /* file pointer given by fopen() */
{
unsigned int msb,lsb; /* might be EOF */
int ans;
char neg; /* non-zero (true) if original nr was negative */
int err;
err= XFER_ERROR; /* preset */
/* transmission errors */
if( (msb= getc(fp)) == EOF || (lsb= getc(fp)) == EOF )
goto gixit; /* data error */
msb &= 0xff; /* remove unwanted high bits, if any */
lsb &= 0xff;
/* detect special case, -32768 in non-2's complement host */
if( MININT == -32767 && msb == 0x80 && !lsb )
goto gixit; /* out-of-range error */
err= 0; /* no other errors possible */
/* use 2's comp negate to make negative nors positive; save sign */
if( (neg= (msb & 0x80)) ) {
lsb= ((lsb & 0xff) ^ 0xff) +1; /* perhaps produces carry bit */
msb =(((msb & 0xff) ^ 0xff) + (lsb >> 8)) & 0xff;
}
/* cascade bytes to form positive int, then correct the sign */
if( msb & 0x80 ) /* only MININT is still neg */
*ip= MININT;
else { /* for all but MININT */
ans= (msb << 8) + (lsb & 0xff);
*ip = neg ? -ans : ans; /* let host install sign */
}
gixit:
return( err );
}
/* End of File */