111 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			111 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| /* INTIO.C - Routines to read and write integers one byte at a time. */
 | |
| 
 | |
| /* Copyright (c) 1995-2012 by Radford M. Neal.
 | |
|  *
 | |
|  * Permission is granted for anyone to copy, use, modify, and distribute
 | |
|  * these programs and accompanying documents for any purpose, provided
 | |
|  * this copyright notice is retained and prominently displayed, and note
 | |
|  * is made of any changes made to these programs.  These programs and
 | |
|  * documents are distributed without any warranty, express or implied.
 | |
|  * As the programs were written for research purposes only, they have not
 | |
|  * been tested to the degree that would be advisable in any important
 | |
|  * application.  All use of these programs is entirely at the user's own
 | |
|  * risk.
 | |
|  */
 | |
| 
 | |
| #include <stdlib.h>
 | |
| #include <stdio.h>
 | |
| 
 | |
| #include "intio.h"
 | |
| 
 | |
| 
 | |
| /* READ AN INTEGER ONE BYTE AT A TIME.  Four bytes are read, ordered from
 | |
|    low to high order.  These are considered to represent a signed integer,
 | |
|    in two's complement form.  The value returned is this integer, converted 
 | |
|    to whatever a C "int" is.  The conversion should work as long as an "int" 
 | |
|    is at least four bytes, even if it's not in two's complement representation 
 | |
|    (except for the largest two's complement negative integer).
 | |
| 
 | |
|    If an error or eof is encountered, zero is returned.  The caller can
 | |
|    check for these events using feof and ferror.  
 | |
| 
 | |
|    The file read from should have been opened as "binary".
 | |
| */
 | |
| 
 | |
| int intio_read
 | |
| ( FILE *f   /* File to read from */
 | |
| )
 | |
| { 
 | |
|   unsigned char b[4];
 | |
|   int top;
 | |
|   int i;
 | |
| 
 | |
|   for (i = 0; i<4; i++)
 | |
|   { if (fread(&b[i],1,1,f) != 1) return 0;
 | |
|   }
 | |
| 
 | |
|   top = b[3]>127 ? (int)b[3] - 256 : b[3];
 | |
|   
 | |
|   return (top<<24) + (b[2]<<16) + (b[1]<<8) + b[0];
 | |
| }
 | |
| 
 | |
| 
 | |
| /* WRITE AN INTEGER ONE BYTE AT A TIME.  Four bytes are written, ordered from
 | |
|    low to high order.  These are considered to represent a signed integer,
 | |
|    in two's complement form.  This should work as long as the integer passed
 | |
|    can be represented in four bytes, even if a C "int" is longer than this.
 | |
| 
 | |
|    The file written to should have been opened as "binary".
 | |
| */
 | |
| 
 | |
| void intio_write
 | |
| ( FILE *f,  /* File to write to */
 | |
|   int v     /* Value to write to file */
 | |
| )
 | |
| { 
 | |
|   unsigned char b;
 | |
|   int i;
 | |
| 
 | |
|   for (i = 0; i<3; i++)
 | |
|   { b = v&0xff;
 | |
|     fwrite(&b,1,1,f);
 | |
|     v >>= 8;
 | |
|   }
 | |
| 
 | |
|   b = v>0 ? v : v+256;
 | |
|   fwrite(&b,1,1,f);
 | |
| }
 | |
| 
 | |
| 
 | |
| /* TEST PROGRAM. */
 | |
| 
 | |
| #ifdef TEST_INTIO
 | |
| 
 | |
| main(void)
 | |
| { 
 | |
|   FILE *f;
 | |
|   f = fopen("test","wb");
 | |
|   intio_write(f,334);
 | |
|   intio_write(f,-40000);
 | |
|   intio_write(f,0x8fffffff);
 | |
|   intio_write(f,-0x8fffffff);
 | |
|   fclose(f);
 | |
|   f = fopen("test","rb");
 | |
|   if (intio_read(f)!=334
 | |
|    || intio_read(f)!=-40000
 | |
|    || intio_read(f)!=0x8fffffff
 | |
|    || intio_read(f)!=-0x8fffffff)
 | |
|   { fprintf(stderr,"got back bad data\n");
 | |
|     exit(1);
 | |
|   }
 | |
|   if (intio_read(f)!=0 || !feof(f) || ferror(f))
 | |
|   { fprintf(stderr,"eof not handled correctly\n");
 | |
|     exit(1);
 | |
|   }
 | |
|   fclose(f);
 | |
|   fprintf(stderr,"OK\n");
 | |
|   exit(0);
 | |
| }
 | |
| 
 | |
| #endif
 | 
