Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
ex_avro.c
Go to the documentation of this file.
1/*
2 * Nilorea Library
3 * Copyright (C) 2005-2026 Castagnier Mickael
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14 * implied. See the License for the specific language governing
15 * permissions and limitations under the License.
16 *
17 * SPDX-License-Identifier: Apache-2.0
18 */
19
28#include "nilorea/n_common.h"
29#include "nilorea/n_log.h"
30#include "nilorea/n_str.h"
31#include "nilorea/n_avro.h"
32
33#include <stdio.h>
34#include <string.h>
35
36int main(int argc, char* argv[]) {
38
39 if (argc == 5) {
40 /* file-based mode: ex_avro <encode|decode> <schema.json> <input> <output> */
41 if (strcmp(argv[1], "encode") == 0) {
42 n_log(LOG_INFO, "Encoding JSON to Avro: %s + %s -> %s", argv[3], argv[2], argv[4]);
43 if (avro_json_to_file(argv[4], argv[2], argv[3]) == TRUE) {
44 n_log(LOG_INFO, "Success!");
45 } else {
46 n_log(LOG_ERR, "Encoding failed!");
47 return 1;
48 }
49 } else if (strcmp(argv[1], "decode") == 0) {
50 n_log(LOG_INFO, "Decoding Avro to JSON: %s + %s -> %s", argv[3], argv[2], argv[4]);
51 if (avro_file_to_json(argv[3], argv[2], argv[4]) == TRUE) {
52 n_log(LOG_INFO, "Success!");
53 } else {
54 n_log(LOG_ERR, "Decoding failed!");
55 return 1;
56 }
57 } else {
58 n_log(LOG_ERR, "Unknown command: %s (use 'encode' or 'decode')", argv[1]);
59 return 1;
60 }
61 return 0;
62 }
63
64 /* default: in-memory demo with embedded data */
65 n_log(LOG_INFO, "=== Avro In-Memory Demo ===");
66
67 /* define a schema */
68 const char* schema_json =
69 "{"
70 " \"type\": \"record\","
71 " \"name\": \"User\","
72 " \"namespace\": \"com.example\","
73 " \"fields\": ["
74 " {\"name\": \"name\", \"type\": \"string\"},"
75 " {\"name\": \"age\", \"type\": \"int\"},"
76 " {\"name\": \"email\", \"type\": [\"null\", \"string\"]},"
77 " {\"name\": \"score\", \"type\": \"double\"},"
78 " {\"name\": \"active\", \"type\": \"boolean\"}"
79 " ]"
80 "}";
81
82 /* define some JSON records */
83 const char* json_data =
84 "["
85 " {"
86 " \"name\": \"Alice\","
87 " \"age\": 30,"
88 " \"email\": \"alice@example.com\","
89 " \"score\": 95.5,"
90 " \"active\": true"
91 " },"
92 " {"
93 " \"name\": \"Bob\","
94 " \"age\": 25,"
95 " \"email\": null,"
96 " \"score\": 87.3,"
97 " \"active\": false"
98 " },"
99 " {"
100 " \"name\": \"Charlie\","
101 " \"age\": 35,"
102 " \"email\": \"charlie@example.com\","
103 " \"score\": 92.1,"
104 " \"active\": true"
105 " }"
106 "]";
107
108 /* convert to N_STR for the N_STR-based API */
109 N_STR* schema_nstr = char_to_nstr(schema_json);
110 N_STR* json_nstr = char_to_nstr(json_data);
111
112 /* encode JSON -> Avro using N_STR API */
113 n_log(LOG_INFO, "Encoding JSON to Avro (in-memory)...");
114 N_STR* avro_nstr = avro_nstr_json_to_avro(schema_nstr, json_nstr);
115 if (!avro_nstr) {
116 n_log(LOG_ERR, "Encoding failed!");
117 free_nstr(&schema_nstr);
118 free_nstr(&json_nstr);
119 return 1;
120 }
121 n_log(LOG_INFO, "Avro data size: %zu bytes (from %zu bytes JSON)", avro_nstr->written, json_nstr->written);
122
123 /* decode Avro -> JSON using N_STR API */
124 n_log(LOG_INFO, "Decoding Avro to JSON (in-memory)...");
125 N_STR* result_json = avro_nstr_avro_to_json(schema_nstr, avro_nstr);
126 if (!result_json) {
127 n_log(LOG_ERR, "Decoding failed!");
128 free_nstr(&schema_nstr);
129 free_nstr(&json_nstr);
130 free_nstr(&avro_nstr);
131 return 1;
132 }
133
134 n_log(LOG_INFO, "Decoded JSON:\n%s", result_json->data);
135
136 /* also test the schema parse/serialize round-trip */
137 n_log(LOG_INFO, "--- Schema round-trip test ---");
138 AVRO_SCHEMA* schema = avro_schema_parse_nstr(schema_nstr);
139 if (schema) {
140 char* schema_back = avro_schema_to_json(schema);
141 if (schema_back) {
142 n_log(LOG_INFO, "Schema round-trip: %s", schema_back);
143 Free(schema_back);
144 }
145 avro_schema_free(&schema);
146 }
147
148 /* also demo the file-based round-trip */
149 n_log(LOG_INFO, "--- File-based round-trip test ---");
150 nstr_to_file(schema_nstr, (char*)"/tmp/test_avro_schema.json");
151 nstr_to_file(json_nstr, (char*)"/tmp/test_avro_input.json");
152
153 if (avro_json_to_file("/tmp/test_output.avro", "/tmp/test_avro_schema.json", "/tmp/test_avro_input.json") == TRUE) {
154 n_log(LOG_INFO, "File encoding succeeded");
155
156 if (avro_file_to_json("/tmp/test_output.avro", "/tmp/test_avro_schema.json", "/tmp/test_avro_output.json") == TRUE) {
157 n_log(LOG_INFO, "File decoding succeeded");
158 N_STR* output = file_to_nstr((char*)"/tmp/test_avro_output.json");
159 if (output) {
160 n_log(LOG_INFO, "File round-trip JSON:\n%s", output->data);
161 free_nstr(&output);
162 }
163 }
164 }
165
166 /* cleanup */
167 free_nstr(&schema_nstr);
168 free_nstr(&json_nstr);
169 free_nstr(&avro_nstr);
170 free_nstr(&result_json);
171
172 n_log(LOG_INFO, "=== Done ===");
173 return 0;
174}
int main(void)
N_STR * avro_nstr_json_to_avro(const N_STR *schema_nstr, const N_STR *json_nstr)
Convert JSON N_STR to Avro N_STR using schema N_STR (all in-memory)
Definition n_avro.c:1266
int avro_file_to_json(const char *avro_filename, const char *schema_filename, const char *json_filename)
Read an Avro object container file and produce a JSON file using a schema file.
Definition n_avro.c:1199
AVRO_SCHEMA * avro_schema_parse_nstr(const N_STR *schema_nstr)
Parse schema from N_STR.
Definition n_avro.c:1259
N_STR * avro_nstr_avro_to_json(const N_STR *schema_nstr, const N_STR *avro_nstr)
Convert Avro N_STR to JSON N_STR using schema N_STR (all in-memory)
Definition n_avro.c:1302
char * avro_schema_to_json(const AVRO_SCHEMA *schema)
Convert an Avro schema back to JSON string (caller must free)
Definition n_avro.c:257
void avro_schema_free(AVRO_SCHEMA **schema_ptr)
Free an Avro schema.
Definition n_avro.c:221
int avro_json_to_file(const char *avro_filename, const char *schema_filename, const char *json_filename)
Write an Avro object container file from a JSON file and schema file.
Definition n_avro.c:1135
Avro schema definition.
Definition n_avro.h:85
#define Free(__ptr)
Free Handler to get errors.
Definition n_common.h:263
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
Definition n_log.h:89
#define LOG_DEBUG
debug-level messages
Definition n_log.h:84
#define LOG_ERR
error conditions
Definition n_log.h:76
void set_log_level(const int log_level)
Set the global log level value ( static int LOG_LEVEL )
Definition n_log.c:121
#define LOG_INFO
informational
Definition n_log.h:82
size_t written
number of meaningful bytes in data, excluding the null terminator; the size including the null termin...
Definition n_str.h:68
char * data
the string
Definition n_str.h:63
#define free_nstr(__ptr)
free a N_STR structure and set the pointer to NULL
Definition n_str.h:203
int nstr_to_file(N_STR *str, char *filename)
Write a N_STR content into a file.
Definition n_str.c:424
N_STR * char_to_nstr(const char *src)
Convert a char into a N_STR, short version.
Definition n_str.c:255
N_STR * file_to_nstr(char *filename)
Load a whole file into a N_STR.
Definition n_str.c:288
A box including a string and his lenght.
Definition n_str.h:61
Avro binary format encoding/decoding with JSON conversion.
Common headers and low-level functions & define.
Generic log system.
N_STR and string function declaration.