libcmml: cmml-parse.c

# cmml-parse.c

Reading from a CMML file

libcmml provides a convenient callback based framework for reading CMML files. After opening a CMML file for reading, you can attach various callbacks relevant to the parts of the file you are interested in, including the stream element, head element, and clip elements. Then, as bytes are read, libcmml will call your callbacks as appropriate.

The functions that need to be called and the respective data structures are defined in cmml.h.

The general sequence of API calls is the following:

- open a CMML object using cmml_open() on a local file or cmml_new() with a FILE pointer to an already opened file.
- attach read callbacks using cmml_set_read_callbacks()
- call cmml_read() repeatedly until it returns 0 or -1.
- close the CMML object with cmml_destroy() returning the FILE pointer or use cmml_close() to close both the object and the open file.

This procedure is illustrated in cmml-parse.c, which prints the title attribute of a CMML tag :

    #include <stdio.h>

    #include <cmml.h>

    #define BUFSIZE 100000

    static int
    read_head (CMML * cmml, const CMML_Head * head, void * user_data) {
      puts(head->title);
      return 0;
    }

    int main(int argc, char *argv[])
    {
      char *filename = NULL;
      FILE * cmml_file;
      CMML * doc;
      long n = 0;

      if (argc != 2) {
        fprintf (stderr, "Usage: %s <CMMLfile>\n", argv[0]);
        exit (1);
      }
      filename = argv[1];

      cmml_file = fopen(filename, "r");
      doc = cmml_new(cmml_file);

      /* alternatively use:
       *  doc = cmml_open(filename);
       */

      cmml_set_read_callbacks (doc, NULL, read_head, NULL, NULL);

      while (((n = cmml_read (doc, BUFSIZE)) > 0));

      cmml_file = cmml_destroy(doc);
      fclose(cmml_file);

      /* alternatively use:
       *  cmml_close(doc);
       */

      exit(0);
    }