Browse Source

Move hex I/O functions to the convenience library

master
Damien Goutte-Gattat 9 years ago
parent
commit
c13fe989de
  1. 3
      lib/Makefile.am
  2. 204
      lib/hexio.c
  3. 44
      lib/hexio.h
  4. 101
      src/asysex.c

3
lib/Makefile.am

@ -1,5 +1,6 @@
noinst_LIBRARIES = libcvasysex.a
libcvasysex_a_SOURCES = err.compat.h compat.h xmem.c xmem.h
libcvasysex_a_SOURCES = err.compat.h compat.h xmem.c xmem.h \
hexio.c hexio.h
libcvasysex_a_LIBADD = $(LIBOBJS)

204
lib/hexio.c

@ -0,0 +1,204 @@
/*
* 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>
#ifdef EXIT_ON_ENOMEM
#include <xmem.h>
#endif
#define BLOCK_SIZE 512
int
fprinthd(FILE *f, unsigned char *buffer, size_t len, unsigned offset)
{
int i, j, 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)
{
int i, 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;
}
size_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 ) {
#ifdef EXIT_ENOMEM
*len += BLOCK_SIZE;
*buffer = xrealloc(*buffer, *len);
#else
unsigned char *p;
if ( ! (p = realloc(*buffer, *len + BLOCK_SIZE)) )
return -1;
*buffer = p;
*len += BLOCK_SIZE;
#endif
}
memcpy(*buffer + m, buf, n);
m += n;
}
return m;
}

44
lib/hexio.h

@ -0,0 +1,44 @@
/*
* 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/>.
*/
#ifndef ICP20120404_HEXIO_H
#define ICP20120404_HEXIO_H
#include <stdio.h>
#ifdef __cpluscplus
extern "C" {
#endif
int
fprinthd(FILE *, unsigned char *, size_t, unsigned);
int
fprinth(FILE *, unsigned char *, size_t);
size_t
freadh(FILE *, unsigned char *, size_t);
ssize_t
freadha(FILE *, unsigned char **, size_t *);
#ifdef __cplusplus
}
#endif
#endif /* !ICP20120404_HEXIO_H */

101
src/asysex.c

@ -27,6 +27,7 @@
#include <sysex.h>
#include <xmem.h>
#include <hexio.h>
#define ASYSEX_MODE_QUERY 0x00
#define ASYSEX_MODE_INQUIRY 0x01
@ -95,80 +96,6 @@ cleanup(void)
}
}
static int
read_message_from_file(FILE *in, unsigned char **buffer, size_t *len)
{
int n, c;
size_t l;
char bytes[3];
enum { NEWLINE, NEWLINE_LOW, COMMENT, COMMENT_LOW, HIGHCHAR, LOWCHAR } state;
n = 0;
bytes[2] = 0;
state = NEWLINE;
if ( len == NULL )
len = &l;
if ( *buffer == NULL )
*len = 0;
while ( (c = fgetc(in)) != EOF ) {
switch ( state ) {
case COMMENT:
if ( c == '\n' )
state = NEWLINE;
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;
if ( n >= *len ) {
*len += 64;
*buffer = xrealloc(*buffer, *len);
}
*(*buffer + n++) = strtol(bytes, NULL, 16);
state = HIGHCHAR;
}
else if ( c == '\n' )
state = NEWLINE_LOW;
else if ( c == '#' )
state = COMMENT_LOW;
break;
case COMMENT_LOW:
if ( c == '\n' )
state = NEWLINE_LOW;
break;
}
}
return n;
}
/* MIDI output functions. */
@ -177,30 +104,10 @@ typedef void (*print_midi_fn_t)(FILE *, unsigned char *, size_t);
static void
print_midi_hex(FILE *out, unsigned char *buffer, size_t len)
{
int i, j;
static int n = 0;
for ( i = 0; i < len; i += 16, n += 16 ) {
fprintf(out, "%08x ", n);
for ( j = i; j < i + 8; j++ )
if ( j < len )
fprintf(out, " %02x", buffer[j]);
else
fprintf(out, " ");
fprintf(out, " ");
for ( ; j < i + 16; j++ )
if ( j < len )
fprintf(out, " %02x", buffer[j]);
else
fprintf(out, " ");
fprintf(out, " |");
for ( j = i; j < i + 16 && j < len; j++ )
fprintf(out, "%c", isprint(buffer[j]) ? buffer[j] : '.');
fprintf(out, "|\n");
}
fprinthd(out, buffer, len, n);
n += len;
}
static void
@ -220,7 +127,7 @@ do_query(midi_io_t *midi, FILE *in, FILE *out, print_midi_fn_t print_midi)
query = NULL;
n = read_message_from_file(in, &query, NULL);
n = freadha(in, &query, NULL);
if ( n < 2 || query[0] != 0xF0 || query[n-1] != 0xF7 )
errx(EXIT_FAILURE, "invalid SysEx input (%d)", n);

Loading…
Cancel
Save