Software APIs
ujson.h
1// Copyright lowRISC contributors (OpenTitan project).
2// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3// SPDX-License-Identifier: Apache-2.0
4
5#ifndef OPENTITAN_SW_DEVICE_LIB_UJSON_UJSON_H_
6#define OPENTITAN_SW_DEVICE_LIB_UJSON_UJSON_H_
7#include <stdint.h>
8
9#include "sw/device/lib/base/status.h"
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14/**
15 * Input/Output context for ujson.
16 */
17typedef struct ujson {
18 /** A generic pointer holding context for the IO routines. */
20 /** A pointer to an IO function for writing data to the output. */
21 status_t (*putbuf)(void *, const char *, size_t);
22 /** A pointer to an IO function for flusing buffered data to the output. */
23 status_t (*flushbuf)(void *);
24 /** A pointer to an IO function for reading data from the input. */
25 status_t (*getc)(void *);
26 /** An internal single character buffer for ungetting a character. */
27 int16_t buffer;
28 /** Holds the rolling CRC32 of characters that are sent and received.*/
29 uint32_t crc32;
30 /** Holds size counter for strings sent or received.*/
31 size_t str_size;
32} ujson_t;
33
34// clang-format off
35#define UJSON_INIT(context_, getc_, putbuf_, flushbuf_) \
36 { \
37 .io_context = (void *)(context_), \
38 .putbuf_ = (putbuf_), \
39 .flushbuf_ = (flushbuf_), \
40 .getc = (getc_), \
41 .buffer = -1, \
42 .crc32 = UINT32_MAX, \
43 }
44// clang-format on
45
46/**
47 * Initializes and returns a ujson context.
48 *
49 * @param context An IO context for the `getc` and `putbuf` functions.
50 * @param getc A function to read a character from the input.
51 * @param putbuf A function to write a buffer to the output.
52 * @return An initialized ujson_t context.
53 */
54ujson_t ujson_init(void *context, status_t (*getc)(void *),
55 status_t (*putbuf)(void *, const char *, size_t),
56 status_t (*flushbuf)(void *));
57
58/**
59 * Gets a single character from the input.
60 *
61 * @param uj A ujson IO context.
62 * @return The next character or an error.
63 */
64status_t ujson_getc(ujson_t *uj);
65
66/**
67 * Pushes a single character back to the input.
68 *
69 * @param uj A ujson IO context.
70 * @param ch The character to put back to the input buffer.
71 * @return OK or an error.
72 */
73status_t ujson_ungetc(ujson_t *uj, char ch);
74
75/**
76 * Writes a buffer to the output.
77 *
78 * @param uj A ujson IO context.
79 * @param buf The buffer to write to the output.
80 * @param len The length of the buffer.
81 * @return OK or an error.
82 */
83status_t ujson_putbuf(ujson_t *uj, const char *buf, size_t len);
84
85/**
86 * Flush a UJSON buffer to the output.
87 *
88 * Some console implementations e.g. the SPI console stage data in a
89 * software buffer before flushing it out to the low-level printf driver, as the
90 * driver code uses a framing protocol that is more efficient if used with bulk
91 * data transfers as opposed to being used with single character writes.
92 *
93 * @param uj A ujson IO context.
94 * @return OK or an error.
95 */
96status_t ujson_flushbuf(ujson_t *uj);
97
98/**
99 * Resets the CRC32 calculation to an initial state.
100 *
101 * @param uj A ujson IO context.
102 */
103void ujson_crc32_reset(ujson_t *uj);
104
105/**
106 * Returns the finished value of a CRC32 calculation.
107 *
108 * Note the state is un-altered by this function.
109 * One must reset before starting a new calculation.
110 *
111 * @param uj A ujson IO context.
112 * @return The final value for the CRC32 calculation.
113 */
114uint32_t ujson_crc32_finish(ujson_t *uj);
115
116/**
117 * Compares two strings for equality.
118 *
119 * @param a A string.
120 * @param b A string.
121 * @return true of the strings are equal; false otherwise.
122 */
123bool ujson_streq(const char *a, const char *b);
124
125/**
126 * Consumes a character from the input.
127 *
128 * Consume all whitespace until a non-whitespace character is found.
129 * The non-whitespace character must be `ch`.
130 *
131 * @param uj A ujson IO context.
132 * @param ch The character to consume.
133 * @return OK or an error.
134 */
135status_t ujson_consume(ujson_t *uj, char ch);
136
137/**
138 * Find and consume a character from the input.
139 *
140 * Consume all whitespace until a non-whitespace character is found.
141 * If the character is `ch`, return OK(1).
142 * If the character is not `ch`, unget the character and return OK(0).
143 *
144 * @param uj A ujson IO context.
145 * @param ch The character to consume.
146 * @return OK or an error.
147 */
148status_t ujson_consume_maybe(ujson_t *uj, char ch);
149
150/**
151 * Parse a JSON quoted string.
152 *
153 * Consume whitespace until finding a double-quote. Consume all characters
154 * (obeying json escape sequences) until the next double-quote. If the
155 * input string exceeds the length of the user buffer, the user
156 * buffer will contain a truncated string and the entire input json string
157 * will be consumed.
158 *
159 * @param uj A ujson IO context.
160 * @param str A buffer to write the string into.
161 * @param len The length of the target buffer.
162 * @return OK or an error.
163 */
164status_t ujson_parse_qs(ujson_t *uj, char *str, size_t len);
165
166/**
167 * Parse a JSON integer.
168 *
169 * @param uj A ujson IO context.
170 * @param result: The parsed integer.
171 * @param rsz: The size of the integer (in bytes).
172 * @return OK or an error.
173 */
174status_t ujson_parse_integer(ujson_t *uj, void *result, size_t rsz);
175
176/**
177 * The following functions parse integers of specific sizes.
178 */
179status_t ujson_deserialize_uint64_t(ujson_t *uj, uint64_t *value);
180status_t ujson_deserialize_uint32_t(ujson_t *uj, uint32_t *value);
181status_t ujson_deserialize_uint16_t(ujson_t *uj, uint16_t *value);
182status_t ujson_deserialize_uint8_t(ujson_t *uj, uint8_t *value);
183status_t ujson_deserialize_size_t(ujson_t *uj, size_t *value);
184status_t ujson_deserialize_int64_t(ujson_t *uj, int64_t *value);
185status_t ujson_deserialize_int32_t(ujson_t *uj, int32_t *value);
186status_t ujson_deserialize_int16_t(ujson_t *uj, int16_t *value);
187status_t ujson_deserialize_int8_t(ujson_t *uj, int8_t *value);
188
189/**
190 * Deserialize a boolean.
191 *
192 * @param uj A ujson IO context.
193 * @param value Pointer to the value to deserialize into.
194 * @return OK or an error.
195 */
196status_t ujson_deserialize_bool(ujson_t *uj, bool *value);
197
198/**
199 * Deserialize a status_t.
200 *
201 * @param uj A ujson IO context.
202 * @param value Pointer to the value to deserialize into.
203 * @return OK or an error.
204 */
205status_t ujson_deserialize_status_t(ujson_t *uj, status_t *value);
206
207/**
208 * Serialize a string.
209 *
210 * @param uj A ujson IO context.
211 * @param buf The string to serialize.
212 * @return OK or an error.
213 */
214status_t ujson_serialize_string(ujson_t *uj, const char *buf);
215
216/**
217 * Serialize an integer.
218 *
219 * @param uj A ujson IO context.
220 * @param value A pointer to the integer to serialize.
221 * @return OK or an error.
222 */
223status_t ujson_serialize_uint64_t(ujson_t *uj, const uint64_t *value);
224status_t ujson_serialize_uint32_t(ujson_t *uj, const uint32_t *value);
225status_t ujson_serialize_uint16_t(ujson_t *uj, const uint16_t *value);
226status_t ujson_serialize_uint8_t(ujson_t *uj, const uint8_t *value);
227status_t ujson_serialize_size_t(ujson_t *uj, const size_t *value);
228status_t ujson_serialize_int64_t(ujson_t *uj, const int64_t *value);
229status_t ujson_serialize_int32_t(ujson_t *uj, const int32_t *value);
230status_t ujson_serialize_int16_t(ujson_t *uj, const int16_t *value);
231status_t ujson_serialize_int8_t(ujson_t *uj, const int8_t *value);
232
233/**
234 * Serialize a boolean.
235 *
236 * @param uj A ujson IO context.
237 * @param value Pointer to the value to serialize.
238 * @return OK or an error.
239 */
240status_t ujson_serialize_bool(ujson_t *uj, const bool *value);
241
242/**
243 * Serialize a status_t.
244 *
245 * @param uj A ujson IO context.
246 * @param value Pointer to the value to serialize.
247 * @return OK or an error.
248 */
249status_t ujson_serialize_status_t(ujson_t *uj, const status_t *value);
250
251#ifdef __cplusplus
252}
253#endif
254#endif // OPENTITAN_SW_DEVICE_LIB_UJSON_UJSON_H_