testSAX.c
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:16k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /*
  2.  * tester.c : a small tester program for parsing using the SAX API.
  3.  *
  4.  * See Copyright for the status of this software.
  5.  *
  6.  * Daniel.Veillard@w3.org
  7.  */
  8. #ifdef WIN32
  9. #include "win32config.h"
  10. #else
  11. #include "config.h"
  12. #endif
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <stdarg.h>
  16. #ifdef HAVE_SYS_TYPES_H
  17. #include <sys/types.h>
  18. #endif
  19. #ifdef HAVE_SYS_STAT_H
  20. #include <sys/stat.h>
  21. #endif
  22. #ifdef HAVE_FCNTL_H
  23. #include <fcntl.h>
  24. #endif
  25. #ifdef HAVE_UNISTD_H
  26. #include <unistd.h>
  27. #endif
  28. #ifdef HAVE_STDLIB_H
  29. #include <stdlib.h>
  30. #endif
  31. #ifdef HAVE_STRING_H
  32. #include <string.h>
  33. #endif
  34. #include <libxml/parser.h>
  35. #include <libxml/parserInternals.h> /* only for xmlNewInputFromFile() */
  36. #include <libxml/tree.h>
  37. #include <libxml/debugXML.h>
  38. #include <libxml/xmlmemory.h>
  39. static int debug = 0;
  40. static int copy = 0;
  41. static int recovery = 0;
  42. static int push = 0;
  43. static int speed = 0;
  44. xmlSAXHandler emptySAXHandlerStruct = {
  45.     NULL, /* internalSubset */
  46.     NULL, /* isStandalone */
  47.     NULL, /* hasInternalSubset */
  48.     NULL, /* hasExternalSubset */
  49.     NULL, /* resolveEntity */
  50.     NULL, /* getEntity */
  51.     NULL, /* entityDecl */
  52.     NULL, /* notationDecl */
  53.     NULL, /* attributeDecl */
  54.     NULL, /* elementDecl */
  55.     NULL, /* unparsedEntityDecl */
  56.     NULL, /* setDocumentLocator */
  57.     NULL, /* startDocument */
  58.     NULL, /* endDocument */
  59.     NULL, /* startElement */
  60.     NULL, /* endElement */
  61.     NULL, /* reference */
  62.     NULL, /* characters */
  63.     NULL, /* ignorableWhitespace */
  64.     NULL, /* processingInstruction */
  65.     NULL, /* comment */
  66.     NULL, /* xmlParserWarning */
  67.     NULL, /* xmlParserError */
  68.     NULL, /* xmlParserError */
  69.     NULL, /* getParameterEntity */
  70.     NULL, /* cdataBlock; */
  71. };
  72. xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
  73. extern xmlSAXHandlerPtr debugSAXHandler;
  74. /************************************************************************
  75.  * *
  76.  * Debug Handlers *
  77.  * *
  78.  ************************************************************************/
  79. /**
  80.  * isStandaloneDebug:
  81.  * @ctxt:  An XML parser context
  82.  *
  83.  * Is this document tagged standalone ?
  84.  *
  85.  * Returns 1 if true
  86.  */
  87. int
  88. isStandaloneDebug(void *ctx)
  89. {
  90.     fprintf(stdout, "SAX.isStandalone()n");
  91.     return(0);
  92. }
  93. /**
  94.  * hasInternalSubsetDebug:
  95.  * @ctxt:  An XML parser context
  96.  *
  97.  * Does this document has an internal subset
  98.  *
  99.  * Returns 1 if true
  100.  */
  101. int
  102. hasInternalSubsetDebug(void *ctx)
  103. {
  104.     fprintf(stdout, "SAX.hasInternalSubset()n");
  105.     return(0);
  106. }
  107. /**
  108.  * hasExternalSubsetDebug:
  109.  * @ctxt:  An XML parser context
  110.  *
  111.  * Does this document has an external subset
  112.  *
  113.  * Returns 1 if true
  114.  */
  115. int
  116. hasExternalSubsetDebug(void *ctx)
  117. {
  118.     fprintf(stdout, "SAX.hasExternalSubset()n");
  119.     return(0);
  120. }
  121. /**
  122.  * hasInternalSubsetDebug:
  123.  * @ctxt:  An XML parser context
  124.  *
  125.  * Does this document has an internal subset
  126.  */
  127. void
  128. internalSubsetDebug(void *ctx, const xmlChar *name,
  129.        const xmlChar *ExternalID, const xmlChar *SystemID)
  130. {
  131.     /* xmlDtdPtr externalSubset; */
  132.     fprintf(stdout, "SAX.internalSubset(%s, %s, %s)n",
  133.             name, ExternalID, SystemID);
  134. /***********
  135.     if ((ExternalID != NULL) || (SystemID != NULL)) {
  136.         externalSubset = xmlParseDTD(ExternalID, SystemID);
  137. if (externalSubset != NULL) {
  138.     xmlFreeDtd(externalSubset);
  139. }
  140.     }
  141.  ***********/
  142. }
  143. /**
  144.  * resolveEntityDebug:
  145.  * @ctxt:  An XML parser context
  146.  * @publicId: The public ID of the entity
  147.  * @systemId: The system ID of the entity
  148.  *
  149.  * Special entity resolver, better left to the parser, it has
  150.  * more context than the application layer.
  151.  * The default behaviour is to NOT resolve the entities, in that case
  152.  * the ENTITY_REF nodes are built in the structure (and the parameter
  153.  * values).
  154.  *
  155.  * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
  156.  */
  157. xmlParserInputPtr
  158. resolveEntityDebug(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
  159. {
  160.     /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
  161.     
  162.     fprintf(stdout, "SAX.resolveEntity(");
  163.     if (publicId != NULL)
  164. fprintf(stdout, "%s", (char *)publicId);
  165.     else
  166. fprintf(stdout, " ");
  167.     if (systemId != NULL)
  168. fprintf(stdout, ", %s)n", (char *)systemId);
  169.     else
  170. fprintf(stdout, ", )n");
  171. /*********
  172.     if (systemId != NULL) {
  173.         return(xmlNewInputFromFile(ctxt, (char *) systemId));
  174.     }
  175.  *********/
  176.     return(NULL);
  177. }
  178. /**
  179.  * getEntityDebug:
  180.  * @ctxt:  An XML parser context
  181.  * @name: The entity name
  182.  *
  183.  * Get an entity by name
  184.  *
  185.  * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
  186.  */
  187. xmlEntityPtr
  188. getEntityDebug(void *ctx, const xmlChar *name)
  189. {
  190.     fprintf(stdout, "SAX.getEntity(%s)n", name);
  191.     return(NULL);
  192. }
  193. /**
  194.  * getParameterEntityDebug:
  195.  * @ctxt:  An XML parser context
  196.  * @name: The entity name
  197.  *
  198.  * Get a parameter entity by name
  199.  *
  200.  * Returns the xmlParserInputPtr
  201.  */
  202. xmlEntityPtr
  203. getParameterEntityDebug(void *ctx, const xmlChar *name)
  204. {
  205.     fprintf(stdout, "SAX.getParameterEntity(%s)n", name);
  206.     return(NULL);
  207. }
  208. /**
  209.  * entityDeclDebug:
  210.  * @ctxt:  An XML parser context
  211.  * @name:  the entity name 
  212.  * @type:  the entity type 
  213.  * @publicId: The public ID of the entity
  214.  * @systemId: The system ID of the entity
  215.  * @content: the entity value (without processing).
  216.  *
  217.  * An entity definition has been parsed
  218.  */
  219. void
  220. entityDeclDebug(void *ctx, const xmlChar *name, int type,
  221.           const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
  222. {
  223.     fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)n",
  224.             name, type, publicId, systemId, content);
  225. }
  226. /**
  227.  * attributeDeclDebug:
  228.  * @ctxt:  An XML parser context
  229.  * @name:  the attribute name 
  230.  * @type:  the attribute type 
  231.  *
  232.  * An attribute definition has been parsed
  233.  */
  234. void
  235. attributeDeclDebug(void *ctx, const xmlChar *elem, const xmlChar *name,
  236.               int type, int def, const xmlChar *defaultValue,
  237.       xmlEnumerationPtr tree)
  238. {
  239.     fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)n",
  240.             elem, name, type, def, defaultValue);
  241. }
  242. /**
  243.  * elementDeclDebug:
  244.  * @ctxt:  An XML parser context
  245.  * @name:  the element name 
  246.  * @type:  the element type 
  247.  * @content: the element value (without processing).
  248.  *
  249.  * An element definition has been parsed
  250.  */
  251. void
  252. elementDeclDebug(void *ctx, const xmlChar *name, int type,
  253.     xmlElementContentPtr content)
  254. {
  255.     fprintf(stdout, "SAX.elementDecl(%s, %d, ...)n",
  256.             name, type);
  257. }
  258. /**
  259.  * notationDeclDebug:
  260.  * @ctxt:  An XML parser context
  261.  * @name: The name of the notation
  262.  * @publicId: The public ID of the entity
  263.  * @systemId: The system ID of the entity
  264.  *
  265.  * What to do when a notation declaration has been parsed.
  266.  */
  267. void
  268. notationDeclDebug(void *ctx, const xmlChar *name,
  269.      const xmlChar *publicId, const xmlChar *systemId)
  270. {
  271.     fprintf(stdout, "SAX.notationDecl(%s, %s, %s)n",
  272.             (char *) name, (char *) publicId, (char *) systemId);
  273. }
  274. /**
  275.  * unparsedEntityDeclDebug:
  276.  * @ctxt:  An XML parser context
  277.  * @name: The name of the entity
  278.  * @publicId: The public ID of the entity
  279.  * @systemId: The system ID of the entity
  280.  * @notationName: the name of the notation
  281.  *
  282.  * What to do when an unparsed entity declaration is parsed
  283.  */
  284. void
  285. unparsedEntityDeclDebug(void *ctx, const xmlChar *name,
  286.    const xmlChar *publicId, const xmlChar *systemId,
  287.    const xmlChar *notationName)
  288. {
  289.     fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)n",
  290.             (char *) name, (char *) publicId, (char *) systemId,
  291.     (char *) notationName);
  292. }
  293. /**
  294.  * setDocumentLocatorDebug:
  295.  * @ctxt:  An XML parser context
  296.  * @loc: A SAX Locator
  297.  *
  298.  * Receive the document locator at startup, actually xmlDefaultSAXLocator
  299.  * Everything is available on the context, so this is useless in our case.
  300.  */
  301. void
  302. setDocumentLocatorDebug(void *ctx, xmlSAXLocatorPtr loc)
  303. {
  304.     fprintf(stdout, "SAX.setDocumentLocator()n");
  305. }
  306. /**
  307.  * startDocumentDebug:
  308.  * @ctxt:  An XML parser context
  309.  *
  310.  * called when the document start being processed.
  311.  */
  312. void
  313. startDocumentDebug(void *ctx)
  314. {
  315.     fprintf(stdout, "SAX.startDocument()n");
  316. }
  317. /**
  318.  * endDocumentDebug:
  319.  * @ctxt:  An XML parser context
  320.  *
  321.  * called when the document end has been detected.
  322.  */
  323. void
  324. endDocumentDebug(void *ctx)
  325. {
  326.     fprintf(stdout, "SAX.endDocument()n");
  327. }
  328. /**
  329.  * startElementDebug:
  330.  * @ctxt:  An XML parser context
  331.  * @name:  The element name
  332.  *
  333.  * called when an opening tag has been processed.
  334.  */
  335. void
  336. startElementDebug(void *ctx, const xmlChar *name, const xmlChar **atts)
  337. {
  338.     int i;
  339.     fprintf(stdout, "SAX.startElement(%s", (char *) name);
  340.     if (atts != NULL) {
  341.         for (i = 0;(atts[i] != NULL);i++) {
  342.     fprintf(stdout, ", %s='", atts[i++]);
  343.     fprintf(stdout, "%s'", atts[i]);
  344. }
  345.     }
  346.     fprintf(stdout, ")n");
  347. }
  348. /**
  349.  * endElementDebug:
  350.  * @ctxt:  An XML parser context
  351.  * @name:  The element name
  352.  *
  353.  * called when the end of an element has been detected.
  354.  */
  355. void
  356. endElementDebug(void *ctx, const xmlChar *name)
  357. {
  358.     fprintf(stdout, "SAX.endElement(%s)n", (char *) name);
  359. }
  360. /**
  361.  * charactersDebug:
  362.  * @ctxt:  An XML parser context
  363.  * @ch:  a xmlChar string
  364.  * @len: the number of xmlChar
  365.  *
  366.  * receiving some chars from the parser.
  367.  * Question: how much at a time ???
  368.  */
  369. void
  370. charactersDebug(void *ctx, const xmlChar *ch, int len)
  371. {
  372.     int i;
  373.     fprintf(stdout, "SAX.characters(");
  374.     for (i = 0;(i < len) && (i < 30);i++)
  375. fprintf(stdout, "%c", ch[i]);
  376.     fprintf(stdout, ", %d)n", len);
  377. }
  378. /**
  379.  * referenceDebug:
  380.  * @ctxt:  An XML parser context
  381.  * @name:  The entity name
  382.  *
  383.  * called when an entity reference is detected. 
  384.  */
  385. void
  386. referenceDebug(void *ctx, const xmlChar *name)
  387. {
  388.     fprintf(stdout, "SAX.reference(%s)n", name);
  389. }
  390. /**
  391.  * ignorableWhitespaceDebug:
  392.  * @ctxt:  An XML parser context
  393.  * @ch:  a xmlChar string
  394.  * @start: the first char in the string
  395.  * @len: the number of xmlChar
  396.  *
  397.  * receiving some ignorable whitespaces from the parser.
  398.  * Question: how much at a time ???
  399.  */
  400. void
  401. ignorableWhitespaceDebug(void *ctx, const xmlChar *ch, int len)
  402. {
  403.     fprintf(stdout, "SAX.ignorableWhitespace(%.30s, %d)n",
  404.             (char *) ch, len);
  405. }
  406. /**
  407.  * processingInstructionDebug:
  408.  * @ctxt:  An XML parser context
  409.  * @target:  the target name
  410.  * @data: the PI data's
  411.  * @len: the number of xmlChar
  412.  *
  413.  * A processing instruction has been parsed.
  414.  */
  415. void
  416. processingInstructionDebug(void *ctx, const xmlChar *target,
  417.                       const xmlChar *data)
  418. {
  419.     fprintf(stdout, "SAX.processingInstruction(%s, %s)n",
  420.             (char *) target, (char *) data);
  421. }
  422. /**
  423.  * cdataBlockDebug:
  424.  * @ctx: the user data (XML parser context)
  425.  * @value:  The pcdata content
  426.  * @len:  the block length
  427.  *
  428.  * called when a pcdata block has been parsed
  429.  */
  430. void
  431. cdataBlockDebug(void *ctx, const xmlChar *value, int len)
  432. {
  433.     fprintf(stderr, "SAX.pcdata(%.20s, %d)n",
  434.     (char *) value, len);
  435. }
  436. /**
  437.  * commentDebug:
  438.  * @ctxt:  An XML parser context
  439.  * @value:  the comment content
  440.  *
  441.  * A comment has been parsed.
  442.  */
  443. void
  444. commentDebug(void *ctx, const xmlChar *value)
  445. {
  446.     fprintf(stdout, "SAX.comment(%s)n", value);
  447. }
  448. /**
  449.  * warningDebug:
  450.  * @ctxt:  An XML parser context
  451.  * @msg:  the message to display/transmit
  452.  * @...:  extra parameters for the message display
  453.  *
  454.  * Display and format a warning messages, gives file, line, position and
  455.  * extra parameters.
  456.  */
  457. void
  458. warningDebug(void *ctx, const char *msg, ...)
  459. {
  460.     va_list args;
  461.     va_start(args, msg);
  462.     fprintf(stdout, "SAX.warning: ");
  463.     vfprintf(stdout, msg, args);
  464.     va_end(args);
  465. }
  466. /**
  467.  * errorDebug:
  468.  * @ctxt:  An XML parser context
  469.  * @msg:  the message to display/transmit
  470.  * @...:  extra parameters for the message display
  471.  *
  472.  * Display and format a error messages, gives file, line, position and
  473.  * extra parameters.
  474.  */
  475. void
  476. errorDebug(void *ctx, const char *msg, ...)
  477. {
  478.     va_list args;
  479.     va_start(args, msg);
  480.     fprintf(stdout, "SAX.error: ");
  481.     vfprintf(stdout, msg, args);
  482.     va_end(args);
  483. }
  484. /**
  485.  * fatalErrorDebug:
  486.  * @ctxt:  An XML parser context
  487.  * @msg:  the message to display/transmit
  488.  * @...:  extra parameters for the message display
  489.  *
  490.  * Display and format a fatalError messages, gives file, line, position and
  491.  * extra parameters.
  492.  */
  493. void
  494. fatalErrorDebug(void *ctx, const char *msg, ...)
  495. {
  496.     va_list args;
  497.     va_start(args, msg);
  498.     fprintf(stdout, "SAX.fatalError: ");
  499.     vfprintf(stdout, msg, args);
  500.     va_end(args);
  501. }
  502. xmlSAXHandler debugSAXHandlerStruct = {
  503.     internalSubsetDebug,
  504.     isStandaloneDebug,
  505.     hasInternalSubsetDebug,
  506.     hasExternalSubsetDebug,
  507.     resolveEntityDebug,
  508.     getEntityDebug,
  509.     entityDeclDebug,
  510.     notationDeclDebug,
  511.     attributeDeclDebug,
  512.     elementDeclDebug,
  513.     unparsedEntityDeclDebug,
  514.     setDocumentLocatorDebug,
  515.     startDocumentDebug,
  516.     endDocumentDebug,
  517.     startElementDebug,
  518.     endElementDebug,
  519.     referenceDebug,
  520.     charactersDebug,
  521.     ignorableWhitespaceDebug,
  522.     processingInstructionDebug,
  523.     commentDebug,
  524.     warningDebug,
  525.     errorDebug,
  526.     fatalErrorDebug,
  527.     getParameterEntityDebug,
  528.     cdataBlockDebug
  529. };
  530. xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
  531. /************************************************************************
  532.  * *
  533.  * Debug *
  534.  * *
  535.  ************************************************************************/
  536. void parseAndPrintFile(char *filename) {
  537.     int res;
  538.     if (push) {
  539. FILE *f;
  540. /*
  541.  * Empty callbacks for checking
  542.  */
  543. f = fopen(filename, "r");
  544. if (f != NULL) {
  545.     int res;
  546.     char chars[10];
  547.     xmlParserCtxtPtr ctxt;
  548.     res = fread(chars, 1, 4, f);
  549.     if (res > 0) {
  550. ctxt = xmlCreatePushParserCtxt(emptySAXHandler, NULL,
  551.     chars, res, filename);
  552. while ((res = fread(chars, 1, 3, f)) > 0) {
  553.     xmlParseChunk(ctxt, chars, res, 0);
  554. }
  555. xmlParseChunk(ctxt, chars, 0, 1);
  556. xmlFreeParserCtxt(ctxt);
  557.     }
  558.     fclose(f);
  559. } else {
  560.     fprintf(stderr, "Cannot read file %sn", filename);
  561. }
  562. /*
  563.  * Debug callback
  564.  */
  565. f = fopen(filename, "r");
  566. if (f != NULL) {
  567.     int res;
  568.     char chars[10];
  569.     xmlParserCtxtPtr ctxt;
  570.     res = fread(chars, 1, 4, f);
  571.     if (res > 0) {
  572. ctxt = xmlCreatePushParserCtxt(debugSAXHandler, NULL,
  573.     chars, res, filename);
  574. while ((res = fread(chars, 1, 3, f)) > 0) {
  575.     xmlParseChunk(ctxt, chars, res, 0);
  576. }
  577. res = xmlParseChunk(ctxt, chars, 0, 1);
  578. xmlFreeParserCtxt(ctxt);
  579. if (res != 0) {
  580.     fprintf(stdout,
  581.             "xmlSAXUserParseFile returned error %dn", res);
  582. }
  583.     }
  584.     fclose(f);
  585. }
  586.     } else {
  587. if (!speed) {
  588.     /*
  589.      * Empty callbacks for checking
  590.      */
  591.     res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
  592.     if (res != 0) {
  593. fprintf(stdout, "xmlSAXUserParseFile returned error %dn", res);
  594.     }
  595.     /*
  596.      * Debug callback
  597.      */
  598.     res = xmlSAXUserParseFile(debugSAXHandler, NULL, filename);
  599.     if (res != 0) {
  600. fprintf(stdout, "xmlSAXUserParseFile returned error %dn", res);
  601.     }
  602. } else {
  603.     /*
  604.      * test 100x the SAX parse
  605.      */
  606.     int i;
  607.     for (i = 0; i<100;i++)
  608. res = xmlSAXUserParseFile(emptySAXHandler, NULL, filename);
  609.     if (res != 0) {
  610. fprintf(stdout, "xmlSAXUserParseFile returned error %dn", res);
  611.     }
  612. }
  613.     }
  614. }
  615. int main(int argc, char **argv) {
  616.     int i;
  617.     int files = 0;
  618.     for (i = 1; i < argc ; i++) {
  619. if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
  620.     debug++;
  621. else if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
  622.     copy++;
  623. else if ((!strcmp(argv[i], "-recover")) ||
  624.          (!strcmp(argv[i], "--recover")))
  625.     recovery++;
  626. else if ((!strcmp(argv[i], "-push")) ||
  627.          (!strcmp(argv[i], "--push")))
  628.     push++;
  629. else if ((!strcmp(argv[i], "-speed")) ||
  630.          (!strcmp(argv[i], "--speed")))
  631.     speed++;
  632.     }
  633.     for (i = 1; i < argc ; i++) {
  634. if (argv[i][0] != '-') {
  635.     parseAndPrintFile(argv[i]);
  636.     files ++;
  637. }
  638.     }
  639.     xmlCleanupParser();
  640.     xmlMemoryDump();
  641.     return(0);
  642. }