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
11 extern "C" {
12 #endif
13 
14 /**
15  * Input/Output context for ujson.
16  */
17 typedef struct ujson {
18  /** A generic pointer holding context for the IO routines. */
19  void *io_context;
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  */
49 ujson_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  */
58 status_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  */
67 status_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  */
77 status_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  */
84 void 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  */
95 uint32_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  */
104 bool 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  */
116 status_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  */
129 status_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  */
145 status_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  */
155 status_t ujson_parse_integer(ujson_t *uj, void *result, size_t rsz);
156 
157 /**
158  * The following functions parse integers of specific sizes.
159  */
160 status_t ujson_deserialize_uint64_t(ujson_t *uj, uint64_t *value);
161 status_t ujson_deserialize_uint32_t(ujson_t *uj, uint32_t *value);
162 status_t ujson_deserialize_uint16_t(ujson_t *uj, uint16_t *value);
163 status_t ujson_deserialize_uint8_t(ujson_t *uj, uint8_t *value);
164 status_t ujson_deserialize_size_t(ujson_t *uj, size_t *value);
165 status_t ujson_deserialize_int64_t(ujson_t *uj, int64_t *value);
166 status_t ujson_deserialize_int32_t(ujson_t *uj, int32_t *value);
167 status_t ujson_deserialize_int16_t(ujson_t *uj, int16_t *value);
168 status_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  */
177 status_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  */
186 status_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  */
195 status_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  */
204 status_t ujson_serialize_uint64_t(ujson_t *uj, const uint64_t *value);
205 status_t ujson_serialize_uint32_t(ujson_t *uj, const uint32_t *value);
206 status_t ujson_serialize_uint16_t(ujson_t *uj, const uint16_t *value);
207 status_t ujson_serialize_uint8_t(ujson_t *uj, const uint8_t *value);
208 status_t ujson_serialize_size_t(ujson_t *uj, const size_t *value);
209 status_t ujson_serialize_int64_t(ujson_t *uj, const int64_t *value);
210 status_t ujson_serialize_int32_t(ujson_t *uj, const int32_t *value);
211 status_t ujson_serialize_int16_t(ujson_t *uj, const int16_t *value);
212 status_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  */
221 status_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  */
230 status_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_