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