blob: 34c1760b0ee8e05652ad10e204986e95c30ea1f5 [file] [log] [blame] [raw]
/*
* Reads sysex data from a SYX file, and returns a sysex binary string
* This file is part of the DOSMid project. Copyright (C) Mateusz Viste.
*/
#include <stdio.h>
#include "syx.h" /* include self for control */
/* fetch the next sysex event from file *fd, and copies it into *buff, up to
* bufflen bytes. returns the length of the sysex string on success, 0 on
* end of file, and a negative value on error. */
int syx_fetchnext(FILE *fd, unsigned char *buff, int bufflen) {
int bytebuff, reslen = 0;
/* quit immediately if any of the arguments is invalid */
if ((fd == NULL) || (buff == NULL) || (bufflen < 1)) return(SYXERR_INVALIDPARAM);
/* */
for (;;) {
bytebuff = fgetc(fd);
/* check for eof or i/o error */
if (bytebuff < 0) {
if (reslen == 0) return(0); /* clean end of file */
return(SYXERR_UNEXPECTEDEOF); /* error - I expect sysex data to be terminated with F0 */
}
/* check for buffer overrun */
if (reslen >= bufflen) return(SYXERR_BUFFEROVERRUN);
/* if first byte, then it MUST be 0xF0 */
if ((reslen == 0) && (bytebuff != 0xF0)) return(SYXERR_INVALIDHEADER);
/* was it an invalid char? */
if ((reslen != 0) && ((bytebuff & 128) != 0) && (bytebuff != 0xF7)) return(SYXERR_INVALIDFORMAT);
/* copy the byte to buff */
buff[reslen++] = bytebuff;
/* was it the sysex terminator? */
if (bytebuff == 0xF7) return(reslen);
}
}