beginnings of cuesheet file parser

This commit is contained in:
Josh Coalson
2002-11-20 06:35:42 +00:00
parent e5302200e7
commit 7efa6e7da0

View File

@@ -35,3 +35,156 @@ GRABBAG_API void grabbag__cuesheet_frame_to_msf(unsigned frame, unsigned *minute
frame /= 60;
*minutes = frame;
}
/* since we only care about values >= 0 or error, returns < 0 for any illegal int, else value */
static int local__parse_int_(const char *s)
{
int ret = 0;
char c;
if(*s == '\0')
return -1;
while('\0' != (c = *s++))
if(c >= '0' && c <= '9')
ret = ret * 10 + (c - '0');
else
return -1;
return ret;
}
static char *local__get_field_(char **s)
{
char *p;
FLAC__ASSERT(0 != s);
if(0 == *s)
return 0;
/* skip leading whitespace */
while(**s && 0 != strchr(" \t\r\n", **s))
(*s)++;
if(**s == 0)
*s = 0;
p = *s;
if(p) {
while(**s && 0 == strchr(" \t\r\n", **s))
(*s)++;
if(**s)
**s = '\0';
else
*s = 0;
}
return p;
}
static FLAC__bool local__cuesheet_parse_(FILE *file, const char **error_message, unsigned *last_line_read, FLAC__StreamMetadata *cuesheet, FLAC__bool check_cd_da_subset)
{
#if defined _MSC_VER || defined __MINGW32__
#define FLAC__STRCASECMP stricmp
#else
#define FLAC__STRCASECMP strcasecmp
#endif
char buffer[4096], *line, *field;
unsigned linelen;
int in_track = -1, in_index = -1;
while(0 != fgets(buffer, sizeof(buffer), file)) {
*last_line_read++;
line = buffer;
linelen = strlen(line);
if(line[linelen-1] != '\n') {
*error_message = "line too long";
return false;
}
if(0 != (field = local__get_field_(&line))) {
if(0 == FLAC__STRCASECMP(field, "CATALOG")) {
/*@@@@ error if already encountered CATALOG */
/*@@@@ check_cd_da_subset: 13 digits ['0'..'9'] */
}
else if(0 == FLAC__STRCASECMP(field, "FLAGS")) {
/*@@@@ error if already encountered FLAGS in this track */
if(in_track < 0) {
/*@@@@*/
}
if(in_index >= 0) {
/*@@@@*/
}
/*@@@@ search for PRE flag only */
}
else if(0 == FLAC__STRCASECMP(field, "INDEX")) {
if(in_track < 0) {
*error_message = "found INDEX before any TRACK";
return false;
}
/*@@@@ check_cd_da_subset: 0..99 */
/*@@@@ check_cd_da_subset: first index of first track is 00:00:00 */
/*@@@@ check first is 0 or 1 */
/*@@@@ check sequential */
/*@@@@ parse msf (or sample offset if !check_cd_da_subset)
}
else if(0 == FLAC__STRCASECMP(field, "ISRC")) {
/*@@@@ error if already encountered ISRC in this track */
if(in_track < 0) {
/*@@@@*/
}
if(in_index >= 0) {
/*@@@@*/
}
}
else if(0 == FLAC__STRCASECMP(field, "TRACK")) {
if(0 == (field = local__get_field_(&line))) {
*error_message = "TRACK is missing track number";
return false;
}
in_track = local__parse_int_(field);
in_index = -1;
if(in_track <= 0) {
*error_message = "TRACK has invalid track number";
return false;
}
/*@@@@ check_cd_da_subset: 1..99 */
/*@@@@ check_cd_da_subset: sequential */
}
}
}
if(!feof(file)) {
*error_message = "read error";
return false;
}
return true;
#undef FLAC__STRCASECMP
}
GRABBAG_API FLAC__StreamMetadata *grabbag__cuesheet_parse(FILE *file, const char **error_message, unsigned *last_line_read, FLAC__bool check_cd_da_subset)
{
FLAC__StreamMetadata *cuesheet;
FLAC__ASSERT(0 != file);
FLAC__ASSERT(0 != error_message);
FLAC__ASSERT(0 != last_line_read);
*last_line_read = 0;
cuesheet = FLAC__metadata_object_new(FLAC__METADATA_TYPE_CUESHEET);
if(0 == cuesheet) {
*error_message = "memory allocation error";
return 0;
}
if(!local__cuesheet_parse_(file, error_message, last_line_read, cuesheet, check_cd_da_subset)) {
FLAC__metadata_object_delete(cuesheet);
return 0;
}
return cuesheet;
}