xref: /freebsd/contrib/libcbor/examples/streaming_parser.c (revision e6bfd18d21b225af6a0ed67ceeaf1293b7b9eba5)
1 /*
2  * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com>
3  *
4  * libcbor is free software; you can redistribute it and/or modify
5  * it under the terms of the MIT license. See LICENSE for details.
6  */
7 
8 #include <stdio.h>
9 #include <string.h>
10 #include "cbor.h"
11 
12 #ifdef __GNUC__
13 #define UNUSED(x) __attribute__((__unused__)) x
14 #else
15 #define UNUSED(x) x
16 #endif
17 
18 void usage(void) {
19   printf("Usage: streaming_parser [input file]\n");
20   exit(1);
21 }
22 
23 /*
24  * Illustrates how one might skim through a map (which is assumed to have
25  * string keys and values only), looking for the value of a specific key
26  *
27  * Use the examples/data/map.cbor input to test this.
28  */
29 
30 const char* key = "a secret key";
31 bool key_found = false;
32 
33 void find_string(void* UNUSED(_ctx), cbor_data buffer, uint64_t len) {
34   if (key_found) {
35     printf("Found the value: %.*s\n", (int)len, buffer);
36     key_found = false;
37   } else if (len == strlen(key)) {
38     key_found = (memcmp(key, buffer, len) == 0);
39   }
40 }
41 
42 int main(int argc, char* argv[]) {
43   if (argc != 2) usage();
44   FILE* f = fopen(argv[1], "rb");
45   if (f == NULL) usage();
46   fseek(f, 0, SEEK_END);
47   size_t length = (size_t)ftell(f);
48   fseek(f, 0, SEEK_SET);
49   unsigned char* buffer = malloc(length);
50   fread(buffer, length, 1, f);
51 
52   struct cbor_callbacks callbacks = cbor_empty_callbacks;
53   struct cbor_decoder_result decode_result;
54   size_t bytes_read = 0;
55   callbacks.string = find_string;
56   while (bytes_read < length) {
57     decode_result = cbor_stream_decode(buffer + bytes_read, length - bytes_read,
58                                        &callbacks, NULL);
59     bytes_read += decode_result.read;
60   }
61 
62   free(buffer);
63   fclose(f);
64 }
65