/*
   <p>Area dump function.</p>

   <kbd>
   <b>environ - C programming support functions</b><br>
   Copyright (C) 2005  Martin C Gregorie
   
   This program is free software; you can redistribute it and/or
   modify it under the terms of the Lesser GNU General Public License.
   
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
  
   You should have received a copy of the Lesser GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
   </kbd>
  
   <p>Contact Martin Gregorie at <i>martin@gregorie.org</i></p>
*/

#include <stdio.h>
#include <ctype.h>
#include "environ.h" 

#define LINE_LIM 16

/*
   Write a hex and ASCII dump of <u>lth</u> bytes from <u>*buff</u>
   to the FILE <u>f</u>. Each line of the output displays the content
   of 16 bytes of data. The line format is:
   <pre>
   111 aaaaaaaaaaaaaaa : hh hh hh hh hh hh hh hh hh hh hh hh hh hh hh hh :
   </pre>
   where 111 is the offset of the start of the line from the start of
   <u>buff</u>. 'a' is the characters in ASCII. These must be valid
   printable ASCII characters that are not control characters. Those
   that do not meet this criterion are repaced with a full stop (.).
   hh is the same character represented as hexadecimal. If the final line
   would extend past the end of <u>buff</u> the overflow characters are left
   blank in both representations. The output line is 72 characters wide.

   <i>dumphex()</i> does not output any form of heading line.
   It is intended for diagnostic displays.
*/  
void dumphex(FILE *f, char *buff, int lth)
{
    int             line;
    int             linebase;
    int             pos;
    int             lines;
    unsigned char   c;

    lines = lth/LINE_LIM;
    if (lth > lines * LINE_LIM)
        lines++;

    for (line = 0; line < lines; line++)
    {
        linebase = line * LINE_LIM;
        fprintf(f,"%3d: ", linebase);
        for (pos = 0; pos < LINE_LIM; pos++)
        {
            if (linebase+pos >= lth)
                fprintf(f, " ");
            else
            {
                c = buff[linebase+pos];
                if (isascii(c) && isprint(c) && !iscntrl(c))
                    fprintf(f, "%c", c);
                else
                    fprintf(f, ".");
            }
        }

        fprintf(f, " : ");

        for (pos = 0; pos < LINE_LIM; pos++)
        {
            if (linebase+pos >= lth)
                fprintf(f, "   ");
            else
            {
                c = buff[linebase+pos];
                fprintf(f, "%02x ", c);
            }
        }

        fprintf(f, ":\n");
    }
}
