From 7e0f021a9aec35fd8e6725e87e3313b101d26f5e Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sun, 27 Jan 2008 11:37:44 +0100 Subject: Initial import (2.0.2-6) --- reference/C/CONTRIB/SNIP/fscanbin.c | 115 ++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100755 reference/C/CONTRIB/SNIP/fscanbin.c (limited to 'reference/C/CONTRIB/SNIP/fscanbin.c') diff --git a/reference/C/CONTRIB/SNIP/fscanbin.c b/reference/C/CONTRIB/SNIP/fscanbin.c new file mode 100755 index 0000000..9efa1c0 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/fscanbin.c @@ -0,0 +1,115 @@ +/* fscanbin.c -- scan binary fields via format string +** +** public domain by Ray Gardner Englewood, Colorado 11/29/89 +** +** Usage: fscanbin(FILE *fp, char *format, ...) +** +** where format string contains specifiers: +** -ddd means skip ddd bytes +** i means read a 16-bit int +** l means read a 32-bit int +** sddd means read a character string of up to ddd bytes +** reads up to a nul byte if ddd is zero or missing +** cnnn means read a character field of nnn bytes (not nul-terminated) +** reads one byte if nnn is zero or missing +*/ + +#include +#include +#include +#include + +typedef unsigned short int16; +typedef unsigned long int32; + +#define int16swap(n) (*n = (*n << 8) | (*n >> 8)) + +#define int32swap(n) (\ + int16swap(&((int16 *)n)[0]),\ + int16swap(&((int16 *)n)[1]),\ + *n = (*n << 16) | (*n >> 16)\ + ) + +#define maxk 32767 + +int fscanbin (FILE *fp, char *format, ...) +{ + va_list argp; + unsigned char *p; + unsigned k; + int c; + char *charp; + int16 *int16p; + int32 *int32p; + int bytes_read; + + bytes_read = 0; + va_start(argp, format); + for ( p = (unsigned char *)format; *p; ) + { + switch( *p & 0xFF ) + { + case '-': + for ( k = 0, c = *++p; isdigit(c); c = *++p ) + k = 10 * k + c - '0'; + if ( k == 0 ) + k = 1; + if ( fseek(fp, (long)k, SEEK_CUR) ) + return -2; /* i/o error */ + bytes_read += k; + break; + + case 'i': + int16p = va_arg(argp, int16 *); + if ( fread((void *)int16p, sizeof(int16), 1, fp) != 1 ) + return -2; /* i/o error */ +#if SWAP16 + int16swap(int16p); +#endif + p++; + bytes_read += sizeof(int16); + break; + + case 'l': + int32p = va_arg(argp, int32 *); + if ( fread((void *)int32p, sizeof(int32), 1, fp) != 1 ) + return -2; /* i/o error */ +#if SWAP32 + int32swap(int32p); +#endif + p++; + bytes_read += sizeof(int32); + break; + + case 's': + charp = va_arg(argp, char *); + for ( k = 0, c = *++p; isdigit(c); c = *++p ) + k = 10 * k + c - '0'; + do + { + c = getc(fp); + if ( c == EOF ) + return -2; + *charp++ = (char)c; + bytes_read++; + } while ( c && (k == 0 || --k) ); + break; + + case 'c': + charp = va_arg(argp, char *); + for ( k = 0, c = *++p; isdigit(c); c = *++p ) + k = 10 * k + c - '0'; + if ( k == 0 ) + k = 1; + if ( fread((void *)charp, sizeof(char), k, fp) != k ) + return -2; /* i/o error */ + bytes_read += k; + break; + + default: + return -1; /* bad format */ + } + } + va_end(argp); + return bytes_read; +} -- cgit v1.2.3-54-g00ecf