123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- /* iksemel (XML parser for Jabber)
- ** Copyright (C) 2000-2003 Gurer Ozen <madcat@e-kolay.net>
- ** This code is free software; you can redistribute it and/or
- ** modify it under the terms of GNU Lesser General Public License.
- */
- #include "common.h"
- #include "iksemel.h"
- #include "perf.h"
- #include <sys/stat.h>
- #ifdef HAVE_GETOPT_LONG
- #include <getopt.h>
- #endif
- #ifdef HAVE_GETOPT_LONG
- static struct option longopts[] = {
- { "all", 0, 0, 'a' },
- { "sax", 0, 0, 's' },
- { "dom", 0, 0, 'd' },
- { "serialize", 0, 0, 'e' },
- { "sha1", 0, 0, '1' },
- { "block", required_argument, 0, 'b' },
- { "memdbg", 0, 0, 'm' },
- { "help", 0, 0, 'h' },
- { "version", 0, 0, 'V' },
- { 0, 0, 0, 0 }
- };
- #endif
- static char *shortopts = "asde1b:mhV";
- static void
- print_usage (void)
- {
- puts ("Usage: iksperf [OPTIONS] FILE\n"
- "This tool measures the performance of the iksemel library.\n"
- " -a, --all Make all tests.\n"
- " -s, --sax Sax test.\n"
- " -d, --dom Tree generating test.\n"
- " -e, --serialize Tree serializing test.\n"
- " -1, --sha1 SHA1 hashing test.\n"
- " -b, --block SIZE Parse the file in SIZE byte blocks.\n"
- " -m, --memdbg Trace malloc and free calls.\n"
- " -h, --help Print this text and exit.\n"
- " -V, --version Print version and exit.\n"
- #ifndef HAVE_GETOPT_LONG
- "(long options are not supported on your system)\n"
- #endif
- "Report bugs to <iksemel-dev@jabberstudio.org>.");
- }
- /* if not 0, file is parsed in block_size byte blocks */
- int block_size;
- char *load_file (const char *fname, int *sizeptr)
- {
- FILE *f;
- char *buf;
- struct stat fs;
- size_t size, ret;
- if (stat (fname, &fs) != 0) {
- fprintf (stderr, "Cannot access file '%s'.\n", fname);
- exit (1);
- }
- size = fs.st_size;
- printf ("Test file '%s' (%d bytes):\n", fname, size);
- f = fopen (fname, "rb");
- if (!f) {
- fprintf (stderr, "Cannot open file.\n");
- exit (1);
- }
- buf = malloc (size);
- if (!buf) {
- fclose (f);
- fprintf (stderr, "Cannot allocate %d bytes for buffer.\n", size);
- exit (2);
- }
- ret = fread (buf, 1, size, f);
- if (ret < size) {
- fprintf (stderr, "Read error in file.\n");
- exit (1);
- }
- *sizeptr = size;
- fclose (f);
- return buf;
- }
- /* stats */
- int sax_tag;
- int sax_cdata;
- int
- tagHook (void *udata, char *name, char **atts, int type)
- {
- ++sax_tag;
- return IKS_OK;
- }
- int
- cdataHook (void *udata, char *data, size_t len)
- {
- ++sax_cdata;
- return IKS_OK;
- }
- void
- sax_test (char *buf, int len)
- {
- unsigned long time;
- iksparser *prs;
- int bs, i, err;
- bs = block_size;
- if (0 == bs) bs = len;
- sax_tag = 0;
- sax_cdata = 0;
- t_reset ();
- prs = iks_sax_new (NULL, tagHook, cdataHook);
- i = 0;
- while (i < len) {
- if (i + bs > len) bs = len - i;
- err = iks_parse (prs, buf + i, bs, 0);
- switch (err) {
- case IKS_OK:
- break;
- case IKS_NOMEM:
- exit (2);
- case IKS_BADXML:
- fprintf (stderr, "Invalid xml at byte %ld, line %ld\n",
- iks_nr_bytes (prs), iks_nr_lines (prs));
- exit (1);
- case IKS_HOOK:
- exit (1);
- }
- i += bs;
- }
- time = t_elapsed ();
- printf ("SAX: parsing took %ld milliseconds.\n", time);
- printf ("SAX: tag hook called %d, cdata hook called %d times.\n", sax_tag, sax_cdata);
- iks_parser_delete (prs);
- }
- void dom_test (char *buf, int len)
- {
- int bs, i, err;
- iksparser *prs;
- unsigned long time;
- iks *x;
- size_t allocated, used;
- bs = block_size;
- if (0 == bs) bs = len;
- t_reset ();
- prs = iks_dom_new (&x);
- iks_set_size_hint (prs, len);
- i = 0;
- while (i < len) {
- if (i + bs > len) bs = len - i;
- err = iks_parse (prs, buf + i, bs, 0);
- switch (err) {
- case IKS_OK:
- break;
- case IKS_NOMEM:
- exit (2);
- case IKS_BADXML:
- fprintf (stderr, "Invalid xml at byte %ld, line %ld\n",
- iks_nr_bytes (prs), iks_nr_lines (prs));
- exit (1);
- case IKS_HOOK:
- exit (1);
- }
- i += bs;
- }
- time = t_elapsed ();
- iks_stack_stat (iks_stack (x), &allocated, &used);
- printf ("DOM: parsing and building the tree took %ld milliseconds.\n", time);
- printf ("DOM: ikstack: %d bytes allocated, %d bytes used.\n", allocated, used);
- t_reset ();
- iks_delete (x);
- time = t_elapsed ();
- printf ("DOM: deleting the tree took %ld milliseconds.\n", time);
- iks_parser_delete (prs);
- }
- void
- serialize_test (char *buf, int len)
- {
- unsigned long time;
- iks *x;
- iksparser *prs;
- char *xml;
- int err;
- prs = iks_dom_new (&x);
- err = iks_parse (prs, buf, len, 1);
- switch (err) {
- case IKS_OK:
- break;
- case IKS_NOMEM:
- exit (2);
- case IKS_BADXML:
- fprintf (stderr, "Invalid xml at byte %ld, line %ld\n",
- iks_nr_bytes (prs), iks_nr_lines (prs));
- exit (1);
- case IKS_HOOK:
- exit (1);
- }
- iks_parser_delete (prs);
- t_reset ();
- xml = iks_string (iks_stack (x), x);
- time = t_elapsed ();
- printf ("Serialize: serializing the tree took %ld milliseconds.\n", time);
- iks_delete (x);
- }
- void
- sha_test (char *buf, int len)
- {
- unsigned long time;
- iksha *s;
- char out[41];
- t_reset ();
- s = iks_sha_new ();
- iks_sha_hash (s, buf, len, 1);
- iks_sha_print (s, out);
- out[40] = '\0';
- iks_sha_delete (s);
- time = t_elapsed ();
- printf ("SHA: hashing took %ld milliseconds.\n", time);
- printf ("SHA: hash [%s]\n", out);
- }
- int
- main (int argc, char *argv[])
- {
- int test_type = 0;
- int c;
- #ifdef HAVE_GETOPT_LONG
- int i;
- while ((c = getopt_long (argc, argv, shortopts, longopts, &i)) != -1) {
- #else
- while ((c = getopt (argc, argv, shortopts)) != -1) {
- #endif
- switch (c) {
- case 'a':
- test_type = 0xffff;
- break;
- case 's':
- test_type |= 1;
- break;
- case 'd':
- test_type |= 2;
- break;
- case 'e':
- test_type |= 4;
- break;
- case '1':
- test_type |= 8;
- break;
- case 'b':
- block_size = atoi (optarg);
- break;
- case 'm':
- m_trace ();
- break;
- case 'h':
- print_usage ();
- exit (0);
- case 'V':
- puts ("iksperf (iksemel) "VERSION);
- exit (0);
- }
- }
- for (; optind < argc; optind++) {
- char *buf;
- int len;
- buf = load_file (argv[optind], &len);
- if (test_type & 1) sax_test (buf, len);
- if (test_type == 0 || test_type & 2) dom_test (buf, len);
- if (test_type & 4) serialize_test (buf, len);
- if (test_type & 8) sha_test (buf, len);
- free (buf);
- }
- return 0;
- }
|