1/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2#include <stdlib.h>
3#include <getopt.h>
4#include <inttypes.h>
5#include <assert.h>
6#include <sys/stat.h>
7#include <string.h>
8#include <platform/platform.h>
9#include <cJSON.h>
10#include <stdio.h>
11#include <errno.h>
12
13static int spool(FILE *fp, char *dest, size_t size)
14{
15    size_t offset = 0;
16
17    clearerr(fp);
18    while (offset < size) {
19        offset += fread(dest + offset, 1, size - offset, fp);
20        if (ferror(fp)) {
21            return -1;
22        }
23    }
24
25    return 0;
26}
27
28static void *load_file(const char *file)
29{
30    FILE *fp;
31    struct stat st;
32    char *data;
33
34    if (stat(file, &st) == -1) {
35        fprintf(stderr, "Failed to lookup test file %s: %s", file,
36                strerror(errno));
37        exit(EXIT_FAILURE);
38    }
39
40    fp = fopen(file, "rb");
41    if (fp == NULL) {
42        fprintf(stderr, "Failed to open test file %s: %s", file,
43                strerror(errno));
44        exit(EXIT_FAILURE);
45    }
46
47    data = malloc(st.st_size + 1);
48    if (data == NULL) {
49        fclose(fp);
50        fprintf(stderr, "Failed to allocate memory\n");
51        exit(EXIT_FAILURE);
52    }
53
54    if (spool(fp, data, st.st_size) == -1) {
55        free(data);
56        fclose(fp);
57        fprintf(stderr, "Failed to open test file %s: %s", file,
58                strerror(errno));
59        exit(EXIT_FAILURE);
60    }
61
62    fclose(fp);
63    data[st.st_size] = 0;
64    return data;
65}
66
67static void report(hrtime_t time) {
68   const char * const extensions[] = { " ns", " usec", " ms", " s", NULL };
69   int id = 0;
70
71   while (time > 9999) {
72      ++id;
73      time /= 1000;
74      if (extensions[id + 1] == NULL) {
75         break;
76      }
77   }
78
79   assert(extensions[id] != NULL);
80   fprintf(stderr, "Parsing took an average of %"PRIu64"%s\n",
81           time, extensions[id]);
82}
83
84int main(int argc, char **argv) {
85    char *data = NULL;
86    const char *fname = "testdata.json";
87    int num = 1;
88    int cmd;
89    int ii;
90    hrtime_t start;
91    hrtime_t delta;
92
93    while ((cmd = getopt(argc, argv, "f:n:")) != -1) {
94        switch (cmd) {
95        case 'f' : fname = optarg; break;
96        case 'n' : num = atoi(optarg); break;
97        default:
98            fprintf(stderr, "usage: %s [-f fname] [-n num]\n", argv[0]);
99            exit(EXIT_FAILURE);
100        }
101    }
102
103    data = load_file(fname);
104
105    start = gethrtime();
106    for (ii = 0; ii < num; ++ii) {
107        cJSON *ptr = cJSON_Parse(data);
108        assert(ptr != NULL);
109        cJSON_Delete(ptr);
110    }
111    delta = gethrtime() - start;
112
113    report(delta / (hrtime_t)num);
114
115    exit(EXIT_SUCCESS);
116}
117