\section{cmml-parse.c}
{\bf 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 \doxyref{cmml.h}{p.}{cmml_8h}.

The general sequence of API calls is the following:

\begin{itemize}
\item open a CMML object using \doxyref{cmml\_\-open()}{p.}{cmml_8h_5fa5ea94668c910aa42b17e87dba823f} on a local file or \doxyref{cmml\_\-new()}{p.}{cmml_8h_9972b602ec7f5ab979940787d5be294d} with a FILE pointer to an already opened file.\item attach read callbacks using \doxyref{cmml\_\-set\_\-read\_\-callbacks()}{p.}{cmml_8h_f8219117da4dc4bfe24e7646e76862b3}\item call \doxyref{cmml\_\-read()}{p.}{cmml_8h_ca01f6d6824a31128ce8b2d9aa691c1f} repeatedly until it returns 0 or -1.\item close the CMML object with \doxyref{cmml\_\-destroy()}{p.}{cmml_8h_1c4b86c80a10c0008d5253c8b1c539d2} returning the FILE pointer or use \doxyref{cmml\_\-close()}{p.}{cmml_8h_636131e3ade9aa216ddee09537214bb3} to close both the object and the open file.\end{itemize}


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



\begin{DocInclude}\begin{verbatim}
#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);
}
\end{verbatim}
\end{DocInclude}
 