[FFmpeg-soc] [soc]: r4623 - concat/libavformat/datanode.c
gkovacs
subversion at mplayerhq.hu
Mon Jul 6 01:58:37 CEST 2009
Author: gkovacs
Date: Mon Jul 6 01:58:37 2009
New Revision: 4623
Log:
added xml parser
Modified:
concat/libavformat/datanode.c
Modified: concat/libavformat/datanode.c
==============================================================================
--- concat/libavformat/datanode.c Sun Jul 5 22:42:36 2009 (r4622)
+++ concat/libavformat/datanode.c Mon Jul 6 01:58:37 2009 (r4623)
@@ -111,6 +111,157 @@ DataNode *ff_datanode_tree_from_ini(Byte
DataNode *ff_datanode_tree_from_xml(ByteIOContext *p)
{
+ int c;
+ char *s;
+ char tag;
+ // tag:
+ // 0 = awaiting opening tag
+ // 1 = either in the opening tag or closing parent
+ // 2 = awaiting closing tag
+ // 3 = either in the closing tag or opening child
+ char ncn; // no closing needed if true
+ char quo; // text is in quotes if true
+ char ctg; // this is the closing tag if true
+ int i, b;
+ DataNode *o;
+ DataNode *d;
+ int ctgidx; // current index in ctgbuf
+ int ctgbuflen; // buffer length of ctgbuf
+ char *ctgbuf = 0;
+ // ctgbuf: used to verify that closing tag matches opening tag name
+ d = av_malloc(sizeof(*d));
+ memset(d, 0, sizeof(*d));
+ o = d;
+ s = d->name;
+ tag = ncn = quo = ctg = ctgidx = ctgbuflen = i = b = 0;
+ while (1) {
+ c = url_fgetc(p);
+ if (c == 0 || c == EOF)
+ break;
+
+ parsetag:
+
+ if (quo) { // we're in quoted text, tag changes don't matter
+ if (c == '"') { // quote closed
+ quo = 0;
+ }
+ goto writeoutput;
+ }
+ else if (c == '"') { // quote opened
+ quo = 1;
+ goto writeoutput;
+ }
+ if (tag == 0) { // awaiting opening tag
+ if (c == '<') { // opening tag
+ tag = 1;
+ d = ff_datanode_mknext(d);
+ i = b = 0;
+ s = d->name;
+ continue;
+ }
+ }
+ else if (tag == 1) { // in the opening tag
+ if (c == '>') { // opening tag closed
+ if (ncn) { // no closing tag needed
+ ncn = 0;
+ tag = 0;
+ }
+ else
+ tag = 2;
+ i = b = 0;
+ s = d->value;
+ continue;
+ }
+ else if (c == '/') {
+ if (d->name) { // tag closed, no closing tag needed
+ ncn = 1;
+ continue;
+ }
+ else { // closing parent
+ tag = 3;
+ ctg = 1;
+ ctgidx = 0;
+ memset(ctgbuf, 0, ctgbuflen);
+ d = d->parent;
+ s = d->name;
+ continue;
+ }
+ }
+ else if (c == ' ') { // no longer tag name but attributes
+ // ignore attributes by null-terminating string
+ c = 0;
+ }
+ }
+ else if (tag == 2) { // awaiting closing tag
+ if (c == '<') { // closing tag
+ tag = 3;
+ i = b = 0;
+ s = d->name;
+ continue;
+ }
+ }
+ else if (tag == 3) { // either in the closing tag or opening a new one
+ if (ctg) {
+ if (ctgidx >= ctgbuflen-1) {
+ ctgbuflen += DATANODE_STR_BUFSIZE;
+ ctgbuf = av_realloc(ctgbuf, ctgbuflen);
+ }
+ if (c == '>') {
+ if (strncmp(d->name, ctgbuf, strlen(d->name)) ||
+ strlen(d->name) != ctgidx) {
+ fprintf(stderr, "malformed closing tag for %s\n", d->name);
+ // closing anyways
+ }
+ // closing tag closed
+ ctg = 0;
+ memset(ctgbuf, 0, ctgbuflen);
+ ctgidx = 0;
+ tag = 0;
+ }
+ else if (c == ' ') { // ignore spaces and material afterwards
+ ctgbuf[ctgidx++] = 0;
+ ctgbuf[ctgidx] = 0;
+ }
+ else {
+ ctgbuf[ctgidx++] = c;
+ ctgbuf[ctgidx] = 0;
+ }
+ continue;
+ }
+ if (c == '/') { // closing tag
+ ctg = 1;
+ continue;
+ }
+ else { // opening child tag
+ tag = 1;
+ d = ff_datanode_mkchild(d);
+ i = b = 0;
+ s = d->name;
+ goto parsetag;
+ }
+ }
+
+ writeoutput:
+
+ if (i >= b-1) {
+ b += DATANODE_STR_BUFSIZE;
+ if (s == d->name) {
+ s = av_realloc(s, b);
+ d->name = s;
+ }
+ else if (s == d->value) {
+ s = av_realloc(s, b);
+ d->value = s;
+ }
+ }
+ s[i++] = c;
+ s[i] = 0;
+ }
+ return o;
+}
+
+DataNode *ff_datanode_tree_from_xml(ByteIOContext *p)
+{
// TODO
return NULL;
}
More information about the FFmpeg-soc
mailing list