xref: /freebsd/contrib/libcbor/examples/cbor_sequence.c (revision b5b9517bfe394e55088f5a05882eabae7e9b7b29)
1*b5b9517bSEd Maste /*
2*b5b9517bSEd Maste  * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com>
3*b5b9517bSEd Maste  *
4*b5b9517bSEd Maste  * libcbor is free software; you can redistribute it and/or modify
5*b5b9517bSEd Maste  * it under the terms of the MIT license. See LICENSE for details.
6*b5b9517bSEd Maste  */
7*b5b9517bSEd Maste 
8*b5b9517bSEd Maste #include <stdio.h>
9*b5b9517bSEd Maste #include <string.h>
10*b5b9517bSEd Maste 
11*b5b9517bSEd Maste #include "cbor.h"
12*b5b9517bSEd Maste 
13*b5b9517bSEd Maste void write_cbor_sequence(const char* filename) {
14*b5b9517bSEd Maste   FILE* file = fopen(filename, "wb");
15*b5b9517bSEd Maste   if (!file) {
16*b5b9517bSEd Maste     fprintf(stderr, "Error: Could not open file %s for writing\n", filename);
17*b5b9517bSEd Maste     return;
18*b5b9517bSEd Maste   }
19*b5b9517bSEd Maste 
20*b5b9517bSEd Maste   // Create example CBOR items
21*b5b9517bSEd Maste   cbor_item_t* int_item = cbor_build_uint32(42);
22*b5b9517bSEd Maste   cbor_item_t* string_item = cbor_build_string("Hello, CBOR!");
23*b5b9517bSEd Maste   cbor_item_t* array_item = cbor_new_definite_array(2);
24*b5b9517bSEd Maste   assert(cbor_array_push(array_item, cbor_build_uint8(1)));
25*b5b9517bSEd Maste   assert(cbor_array_push(array_item, cbor_build_uint8(2)));
26*b5b9517bSEd Maste 
27*b5b9517bSEd Maste   // Serialize and write items to the file
28*b5b9517bSEd Maste   unsigned char* buffer;
29*b5b9517bSEd Maste   size_t buffer_size;
30*b5b9517bSEd Maste 
31*b5b9517bSEd Maste   cbor_serialize_alloc(int_item, &buffer, &buffer_size);
32*b5b9517bSEd Maste   fwrite(buffer, 1, buffer_size, file);
33*b5b9517bSEd Maste   free(buffer);
34*b5b9517bSEd Maste   cbor_decref(&int_item);
35*b5b9517bSEd Maste 
36*b5b9517bSEd Maste   cbor_serialize_alloc(string_item, &buffer, &buffer_size);
37*b5b9517bSEd Maste   fwrite(buffer, 1, buffer_size, file);
38*b5b9517bSEd Maste   free(buffer);
39*b5b9517bSEd Maste   cbor_decref(&string_item);
40*b5b9517bSEd Maste 
41*b5b9517bSEd Maste   cbor_serialize_alloc(array_item, &buffer, &buffer_size);
42*b5b9517bSEd Maste   fwrite(buffer, 1, buffer_size, file);
43*b5b9517bSEd Maste   free(buffer);
44*b5b9517bSEd Maste   cbor_decref(&array_item);
45*b5b9517bSEd Maste 
46*b5b9517bSEd Maste   fclose(file);
47*b5b9517bSEd Maste   printf("CBOR sequence written to %s\n", filename);
48*b5b9517bSEd Maste }
49*b5b9517bSEd Maste 
50*b5b9517bSEd Maste void read_cbor_sequence(const char* filename) {
51*b5b9517bSEd Maste   FILE* file = fopen(filename, "rb");
52*b5b9517bSEd Maste   if (!file) {
53*b5b9517bSEd Maste     fprintf(stderr, "Error: Could not open file %s\n", filename);
54*b5b9517bSEd Maste     return;
55*b5b9517bSEd Maste   }
56*b5b9517bSEd Maste 
57*b5b9517bSEd Maste   fseek(file, 0, SEEK_END);
58*b5b9517bSEd Maste   size_t file_size = ftell(file);
59*b5b9517bSEd Maste   fseek(file, 0, SEEK_SET);
60*b5b9517bSEd Maste 
61*b5b9517bSEd Maste   unsigned char* buffer = malloc(file_size);
62*b5b9517bSEd Maste   if (!buffer) {
63*b5b9517bSEd Maste     fprintf(stderr, "Error: Could not allocate memory\n");
64*b5b9517bSEd Maste     fclose(file);
65*b5b9517bSEd Maste     return;
66*b5b9517bSEd Maste   }
67*b5b9517bSEd Maste 
68*b5b9517bSEd Maste   fread(buffer, 1, file_size, file);
69*b5b9517bSEd Maste   fclose(file);
70*b5b9517bSEd Maste 
71*b5b9517bSEd Maste   struct cbor_load_result result;
72*b5b9517bSEd Maste   size_t offset = 0;
73*b5b9517bSEd Maste 
74*b5b9517bSEd Maste   while (offset < file_size) {
75*b5b9517bSEd Maste     cbor_item_t* item = cbor_load(buffer + offset, file_size - offset, &result);
76*b5b9517bSEd Maste     if (result.error.code != CBOR_ERR_NONE) {
77*b5b9517bSEd Maste       fprintf(stderr, "Error: Failed to parse CBOR item at offset %zu\n",
78*b5b9517bSEd Maste               offset);
79*b5b9517bSEd Maste       break;
80*b5b9517bSEd Maste     }
81*b5b9517bSEd Maste 
82*b5b9517bSEd Maste     cbor_describe(item, stdout);
83*b5b9517bSEd Maste     printf("\n");
84*b5b9517bSEd Maste 
85*b5b9517bSEd Maste     offset += result.read;
86*b5b9517bSEd Maste     cbor_decref(&item);
87*b5b9517bSEd Maste   }
88*b5b9517bSEd Maste 
89*b5b9517bSEd Maste   free(buffer);
90*b5b9517bSEd Maste }
91*b5b9517bSEd Maste 
92*b5b9517bSEd Maste int main(int argc, char* argv[]) {
93*b5b9517bSEd Maste   if (argc != 3) {
94*b5b9517bSEd Maste     fprintf(stderr, "Usage: %s <r|w> <file>\n", argv[0]);
95*b5b9517bSEd Maste     return 1;
96*b5b9517bSEd Maste   }
97*b5b9517bSEd Maste 
98*b5b9517bSEd Maste   if (strcmp(argv[1], "w") == 0) {
99*b5b9517bSEd Maste     write_cbor_sequence(argv[2]);
100*b5b9517bSEd Maste   } else if (strcmp(argv[1], "r") == 0) {
101*b5b9517bSEd Maste     read_cbor_sequence(argv[2]);
102*b5b9517bSEd Maste   } else {
103*b5b9517bSEd Maste     fprintf(stderr,
104*b5b9517bSEd Maste             "Error: First argument must be 'r' (read) or 'w' (write)\n");
105*b5b9517bSEd Maste     return 1;
106*b5b9517bSEd Maste   }
107*b5b9517bSEd Maste 
108*b5b9517bSEd Maste   return 0;
109*b5b9517bSEd Maste }
110