hexload.c
Author: cmaier@cmassoc.net

    /*====================================================================*
     *
     *   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

[PREV] [HOME] [NEXT]