/* riff.c - Don Yang (uguu.org) RIFF parser. 08/18/02 */ #include #include #include #include #include #include #include #include #include static int ParseChunk(char *data, size_t size, size_t *offset, int ident); static int ParseList(char *data, size_t size, size_t *offset, int ident); static int ParseRIFF(char *data, size_t size); /******************************************************************** main */ int main(int argc, char **argv) { struct stat info; int infile; size_t size; char *data; if( argc < 2 ) printf("%s \n", *argv); if( stat(argv[1], &info) == -1 ) { printf("Can not stat %s: %d\n", argv[1], errno); return 1; } if( (infile = open(argv[1], O_RDONLY)) == -1 ) { printf("Can not open %s: %d\n", argv[1], errno); return 1; } size = (int)(info.st_size); if( (int)(data = mmap(NULL, size, PROT_READ, MAP_SHARED, infile, 0)) == -1 ) { printf("Can not map %s: %d\n", argv[1], errno); close(infile); return 1; } ParseRIFF(data, size); munmap((void*)data, size); close(infile); return 0; } /* main() */ /************************************************************** ParseChunk */ static int ParseChunk(char *data, size_t size, size_t *offset, int ident) { size_t chunksize; char *chunk; int i; if( *offset & 1 ) (*offset)++; chunk = data + *offset; chunksize = *((size_t*)(chunk + 4)); if( memcmp(data + *offset, "LIST", 4) == 0 ) return ParseList(data, size, offset, ident); printf("%08x: ", *offset); for(i = 0; i < ident; i++) printf(" "); printf("chunk = '%c%c%c%c', %u bytes\n", chunk[0], chunk[1], chunk[2], chunk[3], chunksize); *offset += chunksize + 8; return (chunksize + 8 > size); } /* ParseChunk() */ /*************************************************************** ParseList */ static int ParseList(char *data, size_t size, size_t *offset, int ident) { size_t i, listsize, startoffset; char *list; list = (char*)(data + *offset); listsize = *((size_t*)(list + 4)); printf("%08x: ", *offset); for(i = 0; i < ident; i++) printf(" "); printf("list = '%c%c%c%c', %u bytes\n", list[8], list[9], list[10], list[11], listsize); *offset += 12; for(startoffset = *offset; *offset - startoffset < listsize;) { if( ParseChunk(data, size, offset, ident + 1) ) return 1; } return 0; } /* ParseList() */ /*************************************************************** ParseRIFF */ static int ParseRIFF(char *data, size_t size) { size_t d, offset; char *p; p = data; if( memcmp(p, "RIFF", 4) ) { puts("Signature missing"); return 1; } d = *((size_t*)(p += 4)); if( d != size - 8 ) printf("00000004: size = %u (%u expected)\n", d, size - 8); else printf("00000004: size = %u\n", d); printf("00000008: form = '%c%c%c%c'\n", p[4], p[5], p[6], p[7]); offset = 12; while( offset < size ) { if( ParseChunk(data, size, &offset, 0) ) break; } printf("%u/%u bytes parsed\n", offset, size); return 0; } /* ParseRIFF() */