/*====================================================================*
*
* size_t hexload (void * memory, size_t extent, FILE * fp);
*
* memory.h
*
* read a file and convert hexadecimal octets to binary bytes then
* store them in consecutive memory locations up to a given length;
* return the actual number of bytes stored;
*
* digits may be consecutive or separated by white space or comment
* text; a colon terminates a frame, to allow multiple frames in a
* on one file;
*
* Motley Tools by Charles Maier <cmaier@cmassoc.net>;
* Copyright (c) 2001-2006 by Charles Maier Associates;
* Licensed under the Internet Software Consortium License;
*
*--------------------------------------------------------------------*/
#ifndef HEXLOAD_SOURCE
#define HEXLOAD_SOURCE
#include <stdio.h>
#include <ctype.h>
#include <stdint.h>
#include <errno.h>
#include "../tools/memory.h"
#include "../tools/error.h"
#include "../tools/chars.h"
/*====================================================================*
* private variables;
*--------------------------------------------------------------------*/
static unsigned row = 1;
static unsigned col = 1;
/*====================================================================*
*
* signed fpgetc (FILE * fp)
*
* return the next input character after updating the file cursor
* position;
*
* Motley Tools by Charles Maier <cmaier@cmassoc.net>;
* Copyright (c) 2001-2006 by Charles Maier Associates;
* Licensed under the Internet Software Consortium License;
*
*--------------------------------------------------------------------*/
static signed fpgetc (FILE * fp)
{
extern unsigned row;
extern unsigned col;
signed c = getc (fp);
if (c == '\n')
{
row++;
col = 0;
}
else
{
col++;
}
return (c);
}
/*====================================================================*
*
* size_t hexload (void * memory, size_t extent, FILE * fp);
*
* memory.h
*
* read a file and convert hexadecimal octets to binary bytes then
* store them in consecutive memory locations up to a given length;
* return the actual number of bytes stored;
*
* digits may be consecutive or separated by white space or comment
* text; a colon terminates a frame, to allow multiple frames in a
* on one file;
*
* Motley Tools by Charles Maier <cmaier@cmassoc.net>;
* Copyright (c) 2001-2006 by Charles Maier Associates;
* Licensed under the Internet Software Consortium License;
*
*--------------------------------------------------------------------*/
size_t hexload (void * memory, size_t extent, FILE * fp)
{
extern unsigned row;
extern unsigned col;
byte * origin = (uint8_t *)(memory);
byte * offset = (uint8_t *)(memory);
unsigned digits = sizeof (* offset) << 1;
unsigned digit = 0;
signed c = EOF;
while ((extent) && ((c = fpgetc (fp)) != EOF) && (c != ';'))
{
if (isspace (c))
{
continue;
}
if (c == '#')
{
do
{
c = fpgetc (fp);
}
while (nobreak (c));
continue;
}
if (c == '/')
{
c = fpgetc (fp);
if (c == '/')
{
do
{
c = fpgetc (fp);
}
while (nobreak (c));
continue;
}
if (c == '*')
{
while ((c != '/') && (c != EOF))
{
while ((c != '*') && (c != EOF))
{
c = fpgetc (fp);
}
c = fpgetc (fp);
}
continue;
}
continue;
}
if ((c >= '0') && (c <= '9'))
{
*offset *= 16;
*offset += c - '0';
if (!(++digit % digits))
{
offset++;
extent--;
}
continue;
}
if ((c >= 'A') && (c <= 'F'))
{
*offset *= 16;
*offset += 10;
*offset += c - 'A';
if (!(++digit % digits))
{
offset++;
extent--;
}
continue;
}
if ((c >= 'a') && (c <= 'f'))
{
*offset *= 16;
*offset += 10;
*offset += c - 'a';
if (!(++digit % digits))
{
offset++;
extent--;
}
continue;
}
#if 1
error (1, ENOTSUP, "Unexpected character '%c': row %d: col %d", c, row, col);
#else
return ((size_t)(-1));
#endif
}
if (digit & 1)
{
#if 1
error (1, ENOTSUP, "Odd digit count (%d) in source", digit);
#else
return ((size_t)(-1));
#endif
}
return (offset - origin);
}
#endif