-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexample_parser.c
122 lines (94 loc) · 2.91 KB
/
example_parser.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
//
// Example of binary data parsing.
//
#include <stdio.h>
#include <stdlib.h>
#include "cppdata.h"
//
// Since it is expected that no more than 2-3 levels of nesting I prefer
// recursive function :-P
//
static void print_dirs(const struct cppd_t* handle, const struct Node* node, unsigned int level) {
struct cppd_dirent_t de;
for (unsigned int i = 0;; ++i) {
if (!cppd_readdir(handle, node, i, &de)) {
for (unsigned int t = 0; t < level; ++t) {
printf("\t");
}
switch (de.type) {
case CPPD_FOLDER:
printf("folder '%s':\r\n", de.name);
break;
case CPPD_NUMBER:
printf(
"number '%s' value=(%ld)\r\n",
de.name,
*(uint64_t*)cppd_dataptr(handle, de.data, 0)
);
break;
case CPPD_STRING:
printf(
"string '%s' value=(%s) length=%ld bytes\r\n",
de.name,
(const char*)cppd_dataptr(handle, de.data, 0), de.size
);
break;
case CPPD_BLOB:
printf(
"binary blob '%s' (%ld bytes)\r\n",
de.name,
de.size
);
break;
default: break;
}
if (de.type == CPPD_FOLDER) {
print_dirs(handle, de.data, level + 1);
}
} else {
break;
}
}
}
int main(int argc, const char *argv[]) {
static uint64_t buf[1000];
if (argc < 2) {
perror("Please specify input file");
return EXIT_FAILURE;
}
const char* fname = argv[1];
FILE* const fp = fopen(fname, "rb");
if (!fp) {
perror("File opening failed");
return EXIT_FAILURE;
}
fseek(fp, 0, SEEK_END);
const size_t siz = ftell(fp);
rewind(fp);
if (siz > sizeof(buf)) {
perror("Too big binary data file.");
return EXIT_FAILURE;
}
const size_t read_bytes = fread(buf, 1, siz, fp);
printf("Read %ld bytes\r\n", read_bytes);
struct cppd_t handle;
if (cppd_init(&handle, buf)) {
perror("Wrong binary data file.");
return EXIT_FAILURE;
}
const struct Node* node = cppd_open(&handle, "/");
print_dirs(&handle, node, 0);
const char* const test_path = "/folder/nested/three";
const struct Node* const value_node = cppd_open(&handle, test_path);
if (value_node == 0) {
perror("Can't find the path specified.");
return EXIT_FAILURE;
}
struct cppd_dirent_t de;
const uint64_t* const num_ptr = cppd_dataptr(&handle, value_node, 0);
if (num_ptr) {
printf("value at %s = (%ld)\r\n", test_path, *num_ptr);
}
fclose(fp);
return EXIT_SUCCESS;
}