KORG microX utility.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

288 lines
6.2 KiB

/*
* hexio - Incenp.org Notch Library: hexadecimal I/O module
* Copyright (C) 2012 Damien Goutte-Gattat
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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 GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <hexio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#define BLOCK_SIZE 512
int
fprinthd(FILE *f, unsigned char *buffer, size_t len, unsigned offset)
{
unsigned int i, j;
int n;
if ( ! f || ! buffer ) {
errno = EINVAL;
return -1;
}
for ( i = 0, n = 0; i < len; i += 16, offset += 16 ) {
n += fprintf(f, "%08x ", offset);
for ( j = i; j < i + 8; j++ )
if ( j < len )
n += fprintf(f, " %02x", buffer[j]);
else
n += fprintf(f, " ");
n += fprintf(f, " ");
for ( ; j < i + 16; j++ )
if ( j < len )
n += fprintf(f, " %02x", buffer[j]);
else
n += fprintf(f, " ");
n += fprintf(f, " |");
for ( j = i; j < i + 16 && j < len; j++ )
n += fprintf(f, "%c", isprint(buffer[j]) ? buffer[j] : '.');
n += fprintf(f, "|\n");
}
return n;
}
int
fprinth(FILE *f, unsigned char *buffer, size_t len)
{
unsigned int i;
int n;
if ( ! f || ! buffer ) {
errno = EINVAL;
return -1;
}
for ( i = 0; i < len; i++ ) {
if ( i % 24 == 0 ) {
if ( i > 0 )
n += fprintf(f, "\n%02x", buffer[i]);
else
n += fprintf(f, "%02x", buffer[i]);
}
else if ( i % 8 == 0 )
n += fprintf(f, " %02x", buffer[i]);
else
n += fprintf(f, " %02x", buffer[i]);
}
fputc('\n', f);
return n + 1;
}
ssize_t
freadh(FILE *f, unsigned char *buffer, size_t len)
{
int c;
size_t n;
char bytes[3];
enum { NEWLINE, NEWLINE_LOW, COMMENT, COMMENT_LOW, HIGHCHAR, LOWCHAR } state;
if ( ! f || ! buffer ) {
errno = EINVAL;
return -1;
}
n = 0;
bytes[2] = 0;
state = NEWLINE;
while ( (c = fgetc(f)) != EOF && n < len ) {
switch ( state ) {
case COMMENT:
if ( c == '\n' )
state = NEWLINE;
break;
case COMMENT_LOW:
if ( c == '\n' )
state = NEWLINE_LOW;
break;
case NEWLINE:
if ( c == '#' )
state = COMMENT;
/* Fall through */
case HIGHCHAR:
if ( isxdigit(c)) {
bytes[0] = c;
state = LOWCHAR;
}
else if ( c == '\n' )
state = NEWLINE;
else if ( c == '#' )
state = COMMENT;
break;
case NEWLINE_LOW:
if ( c == '#' )
state = COMMENT_LOW;
/* Fall through */
case LOWCHAR:
if ( isxdigit(c) ) {
bytes[1] = c;
buffer[n++] = strtol(bytes, NULL, 16);
state = HIGHCHAR;
}
else if ( c == '\n' )
state = NEWLINE_LOW;
else if ( c == '#' )
state = COMMENT_LOW;
break;
}
}
return n;
}
ssize_t
freadha(FILE *f, unsigned char **buffer, size_t *len)
{
unsigned char buf[BLOCK_SIZE];
size_t n, m, l;
if ( ! f || ! buffer ) {
errno = EINVAL;
return -1;
}
if ( ! len )
len = &l;
if ( ! *buffer )
*len = 0;
n = m = 0;
while ( (n = freadh(f, buf, sizeof(buf))) > 0 ) {
if ( *len < m + n ) {
unsigned char *p;
if ( ! (p = realloc(*buffer, *len + BLOCK_SIZE)) )
return -1;
*buffer = p;
*len += BLOCK_SIZE;
}
memcpy(*buffer + m, buf, n);
m += n;
}
return m;
}
ssize_t
freadhd(FILE *f, unsigned char *buffer, size_t len, int *intext)
{
int c;
size_t n;
char bytes[3];
enum { OFFSET, HIGHCHAR, LOWCHAR, TEXT } state;
if ( ! f || ! buffer ) {
errno = EINVAL;
return -1;
}
n = 0;
bytes[2] = 0;
state = ( intext && *intext ) ? TEXT : OFFSET;
while ( (c = fgetc(f)) != EOF && n < len ) {
switch ( state ) {
case OFFSET:
if ( c == ' ' )
state = HIGHCHAR;
break;
case HIGHCHAR:
if ( isxdigit(c) ) {
bytes[0] = c;
state = LOWCHAR;
}
else if ( c == '|' )
state = TEXT;
break;
case LOWCHAR:
if ( isxdigit(c) ) {
bytes[1] = c;
buffer[n++] = strtol(bytes, NULL, 16);
}
state = HIGHCHAR;
break;
case TEXT:
if ( c == '\n' )
state = OFFSET;
break;
}
}
if ( intext )
*intext = state == TEXT;
return n;
}
ssize_t
freadhda(FILE *f, unsigned char **buffer, size_t *len)
{
unsigned char buf[BLOCK_SIZE];
size_t n, m, l;
int s;
if ( ! f || ! buffer ) {
errno = EINVAL;
return -1;
}
if ( ! len )
len = &l;
if ( ! *buffer )
*len = 0;
n = m = s = 0;
while ( (n = freadhd(f, buf, sizeof(buf), &s)) > 0 ) {
if ( *len < m + n ) {
unsigned char *p;
if ( ! (p = realloc(*buffer, *len + BLOCK_SIZE)) )
return -1;
*buffer = p;
*len += BLOCK_SIZE;
}
memcpy(*buffer + m, buf, n);
m += n;
}
return m;
}