home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / snip9707.zip / FSCANBIN.C < prev    next >
C/C++ Source or Header  |  1997-07-05  |  3KB  |  108 lines

  1. /* +++Date last modified: 05-Jul-1997 */
  2.  
  3. /* fscanbin.c -- scan binary fields via format string
  4. **
  5. **  public domain by Ray Gardner   Englewood, Colorado   11/29/89
  6. **
  7. **  Usage: fscanbin(FILE *fp, char *format, ...)
  8. **
  9. **  where format string contains specifiers:
  10. **   -ddd  means skip ddd bytes
  11. **   i     means read a 16-bit int
  12. **   l     means read a 32-bit int
  13. **   sddd  means read a character string of up to ddd bytes
  14. **           reads up to a nul byte if ddd is zero or missing
  15. **   cnnn  means read a character field of nnn bytes (not nul-terminated)
  16. **           reads one byte if nnn is zero or missing
  17. */
  18.  
  19. #include <stdlib.h>
  20. #include <stdarg.h>
  21. #include <ctype.h>
  22. #include "fscanbin.h"
  23.  
  24. #define SWAP16 0
  25. #define SWAP32 0
  26.  
  27. int fscanbin (FILE *fp, char *format, ...)
  28. {
  29.       va_list argp;
  30.       unsigned char *p;
  31.       unsigned k;
  32.       int c;
  33.       char *charp;
  34.       WORD *WORDp;
  35.       DWORD *DWORDp;
  36.       int bytes_read;
  37.  
  38.       bytes_read = 0;
  39.       va_start(argp, format);
  40.       for ( p = (unsigned char *)format; *p; )
  41.       {
  42.             switch( *p & 0xFF )
  43.             {
  44.             case '-':
  45.                   for ( k = 0, c = *++p; isdigit(c); c = *++p )
  46.                         k = 10 * k + c - '0';
  47.                   if ( k == 0 )
  48.                         k = 1;
  49.                   if ( fseek(fp, (long)k, SEEK_CUR) )
  50.                         return -2;     /* i/o error */
  51.                   bytes_read += k;
  52.                   break;
  53.  
  54.             case 'i':
  55.                   WORDp = va_arg(argp, WORD *);
  56.                   if ( fread((void *)WORDp, sizeof(WORD), 1, fp) != 1 )
  57.                         return -2;     /* i/o error */
  58. #if SWAP16
  59.                   WORDswap(WORDp);
  60. #endif
  61.                   p++;
  62.                   bytes_read += sizeof(WORD);
  63.                   break;
  64.  
  65.             case 'l':
  66.                   DWORDp = va_arg(argp, DWORD *);
  67.                   if ( fread((void *)DWORDp, sizeof(DWORD), 1, fp) != 1 )
  68.                         return -2;     /* i/o error */
  69. #if SWAP32
  70.                   DWORDswap(DWORDp);
  71. #endif
  72.                   p++;
  73.                   bytes_read += sizeof(DWORD);
  74.                   break;
  75.  
  76.             case 's':
  77.                   charp = va_arg(argp, char *);
  78.                   for ( k = 0, c = *++p; isdigit(c); c = *++p )
  79.                         k = 10 * k + c - '0';
  80.                   do
  81.                   {
  82.                         c = getc(fp);
  83.                         if ( c == EOF )
  84.                               return -2;
  85.                         *charp++ = (char)c;
  86.                         bytes_read++;
  87.                   } while ( c && (k == 0 || --k) );
  88.                   break;
  89.  
  90.             case 'c':
  91.                   charp = va_arg(argp, char *);
  92.                   for ( k = 0, c = *++p; isdigit(c); c = *++p )
  93.                         k = 10 * k + c - '0';
  94.                   if ( k == 0 )
  95.                         k = 1;
  96.                   if ( fread((void *)charp, sizeof(char), k, fp) != k )
  97.                         return -2;     /* i/o error */
  98.                   bytes_read += k;
  99.                   break;
  100.  
  101.             default:
  102.                   return -1; /* bad format */
  103.             }
  104.       }
  105.       va_end(argp);
  106.       return bytes_read;
  107. }
  108.