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