header list functionality
authorJosh Coalson <jcoalson@users.sourceforce.net>
Fri, 23 Feb 2001 22:03:52 +0000 (22:03 +0000)
committerJosh Coalson <jcoalson@users.sourceforce.net>
Fri, 23 Feb 2001 22:03:52 +0000 (22:03 +0000)
src/metaflac/main.c

index aa86122..a811da4 100644 (file)
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
+/* 
+ * WATCHOUT - this is meant to be very lightweight an not even dependent
+ * on libFLAC, so there are a couple places where FLAC__* variables are
+ * duplicated here.  Look for 'DUPLICATE:' in comments.
+ */
+
 #include <assert.h>
 #include <ctype.h>
 #include <stdarg.h>
 #include <string.h>
 #include "FLAC/all.h"
 
+static const char *sync_string_ = "fLaC"; /* DUPLICATE:FLAC__STREAM_SYNC_STRING */
+
 static int usage(const char *message, ...);
+static bool list(FILE *f, bool verbose);
 
 int main(int argc, char *argv[])
 {
-       bool verbose, list_mode;
+       int i;
+       bool verbose = false, list_mode = true;
 
        if(argc <= 1)
                return usage(0);
@@ -50,6 +60,20 @@ int main(int argc, char *argv[])
        if(i + (list_mode? 1:2) != argc)
                return usage("ERROR: invalid arguments (more/less than %d filename%s?)\n", (list_mode? 1:2), (list_mode? "":"s"));
 
+       if(list_mode) {
+               FILE *f = fopen(argv[i], "r");
+
+               if(0 == f) {
+                       fprintf(stderr, "ERROR opening %s\n", argv[i]);
+                       return 1;
+               }
+
+               if(!list(f, verbose))
+                       return 1;
+
+               fclose(f);
+       }
+
        return 0;
 }
 
@@ -93,3 +117,37 @@ int usage(const char *message, ...)
 
        return 1;
 }
+
+bool list(FILE *f, bool verbose)
+{
+       static byte buf[65536];
+       FLAC__StreamMetaData metadata;
+
+       /* read the stream sync code */
+       if(fread(buf, 1, 4, f) < 4 || memcmp(buf, sync_string_, 4)) {
+               fprintf(stderr, "ERROR: not a FLAC file (no '%s' header)\n", sync_string_);
+               return false;
+       }
+
+       /* read the metadata blocks */
+       do {
+               /* read the metadata block header */
+               if(fread(buf, 1, 4, f) < 4) {
+                       fprintf(stderr, "ERROR: short count reading metadata block header\n");
+                       return false;
+               }
+               metadata.is_last = (buf[0] & 0x80)? true:false;
+               metadata.type = (FLAC__MetaDataType)(buf[0] & 0x7f);
+               metadata.length = (((unsigned)buf[1]) << 16) | (((unsigned)buf[2]) << 8) | ((unsigned)buf[3]);
+
+               /* read the metadata block data */
+
+               /* print it */
+               printf("METADATA block:\n");    
+               printf("\ttype: %u\n", (unsigned)metadata.type);
+               printf("\tis last: %s\n", metadata.is_last? "true":"false");
+               printf("\tlength: %u\n", metadata.length);
+       } while (!metadata.is_last);
+
+       return true;
+}