xref: /freebsd/contrib/libcbor/examples/streaming_parser.c (revision 5d3e7166f6a0187fa3f8831b16a06bd9955c21ff)
110ff414cSEd Maste /*
210ff414cSEd Maste  * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com>
310ff414cSEd Maste  *
410ff414cSEd Maste  * libcbor is free software; you can redistribute it and/or modify
510ff414cSEd Maste  * it under the terms of the MIT license. See LICENSE for details.
610ff414cSEd Maste  */
710ff414cSEd Maste 
810ff414cSEd Maste #include <stdio.h>
910ff414cSEd Maste #include <string.h>
1010ff414cSEd Maste #include "cbor.h"
1110ff414cSEd Maste 
12*5d3e7166SEd Maste #ifdef __GNUC__
13*5d3e7166SEd Maste #define UNUSED(x) __attribute__((__unused__)) x
14*5d3e7166SEd Maste #else
15*5d3e7166SEd Maste #define UNUSED(x) x
16*5d3e7166SEd Maste #endif
17*5d3e7166SEd Maste 
usage(void)18*5d3e7166SEd Maste void usage(void) {
1910ff414cSEd Maste   printf("Usage: streaming_parser [input file]\n");
2010ff414cSEd Maste   exit(1);
2110ff414cSEd Maste }
2210ff414cSEd Maste 
2310ff414cSEd Maste /*
2410ff414cSEd Maste  * Illustrates how one might skim through a map (which is assumed to have
2510ff414cSEd Maste  * string keys and values only), looking for the value of a specific key
2610ff414cSEd Maste  *
2710ff414cSEd Maste  * Use the examples/data/map.cbor input to test this.
2810ff414cSEd Maste  */
2910ff414cSEd Maste 
3010ff414cSEd Maste const char* key = "a secret key";
3110ff414cSEd Maste bool key_found = false;
3210ff414cSEd Maste 
find_string(void * UNUSED (_ctx),cbor_data buffer,uint64_t len)33*5d3e7166SEd Maste void find_string(void* UNUSED(_ctx), cbor_data buffer, uint64_t len) {
3410ff414cSEd Maste   if (key_found) {
3510ff414cSEd Maste     printf("Found the value: %.*s\n", (int)len, buffer);
3610ff414cSEd Maste     key_found = false;
3710ff414cSEd Maste   } else if (len == strlen(key)) {
3810ff414cSEd Maste     key_found = (memcmp(key, buffer, len) == 0);
3910ff414cSEd Maste   }
4010ff414cSEd Maste }
4110ff414cSEd Maste 
main(int argc,char * argv[])4210ff414cSEd Maste int main(int argc, char* argv[]) {
4310ff414cSEd Maste   if (argc != 2) usage();
4410ff414cSEd Maste   FILE* f = fopen(argv[1], "rb");
4510ff414cSEd Maste   if (f == NULL) usage();
4610ff414cSEd Maste   fseek(f, 0, SEEK_END);
4710ff414cSEd Maste   size_t length = (size_t)ftell(f);
4810ff414cSEd Maste   fseek(f, 0, SEEK_SET);
4910ff414cSEd Maste   unsigned char* buffer = malloc(length);
5010ff414cSEd Maste   fread(buffer, length, 1, f);
5110ff414cSEd Maste 
5210ff414cSEd Maste   struct cbor_callbacks callbacks = cbor_empty_callbacks;
5310ff414cSEd Maste   struct cbor_decoder_result decode_result;
5410ff414cSEd Maste   size_t bytes_read = 0;
5510ff414cSEd Maste   callbacks.string = find_string;
5610ff414cSEd Maste   while (bytes_read < length) {
5710ff414cSEd Maste     decode_result = cbor_stream_decode(buffer + bytes_read, length - bytes_read,
5810ff414cSEd Maste                                        &callbacks, NULL);
5910ff414cSEd Maste     bytes_read += decode_result.read;
6010ff414cSEd Maste   }
6110ff414cSEd Maste 
6210ff414cSEd Maste   free(buffer);
6310ff414cSEd Maste   fclose(f);
6410ff414cSEd Maste }
65