1 /*
2  * This file has been copied from the zcbor library.
3  * Commit zcbor 0.8.1
4  */
5 
6 /*
7  * Copyright (c) 2020 Nordic Semiconductor ASA
8  *
9  * SPDX-License-Identifier: Apache-2.0
10  */
11 
12 #ifndef ZCBOR_DECODE_H__
13 #define ZCBOR_DECODE_H__
14 
15 #include <stdint.h>
16 #include <stdbool.h>
17 #include <stddef.h>
18 #include "zcbor_common.h"
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 
24 /** The zcbor_decode library provides functions for decoding CBOR data elements.
25  *
26  * See The README for an introduction to CBOR, including the meaning of pint,
27  * nint, bstr etc.
28  */
29 
30 
31 /** See @ref zcbor_new_state() */
32 void zcbor_new_decode_state(zcbor_state_t *state_array, size_t n_states,
33 		const uint8_t *payload, size_t payload_len, size_t elem_count,
34 		uint8_t *elem_state, size_t elem_state_bytes);
35 
36 /** Convenience macro for declaring and initializing a decoding state with backups.
37  *
38  *  This gives you a state variable named @p name. The variable functions like
39  *  a pointer.
40  *
41  *  @param[in]  name          The name of the new state variable.
42  *  @param[in]  num_backups   The number of backup slots to keep in the state.
43  *  @param[in]  payload       The payload to work on.
44  *  @param[in]  payload_size  The size (in bytes) of @p payload.
45  *  @param[in]  elem_count    The starting elem_count (typically 1).
46  *  @param[in]  n_flags       For use if ZCBOR_MAP_SMART_SEARCH is enabled, ignored otherwise.
47  *                            The total number of unordered map search flags needed.
48  *                            I.e. the largest number of elements expected in an unordered map,
49  *                            including elements in nested unordered maps.
50  */
51 #define ZCBOR_STATE_D(name, num_backups, payload, payload_size, elem_count, n_flags) \
52 zcbor_state_t name[((num_backups) + 2 + ZCBOR_FLAG_STATES(n_flags))]; \
53 do { \
54 	zcbor_new_decode_state(name, ZCBOR_ARRAY_SIZE(name), payload, payload_size, elem_count, \
55 			(uint8_t *)&name[(num_backups) + 1], ZCBOR_FLAG_STATES(n_flags) * sizeof(zcbor_state_t)); \
56 } while(0)
57 
58 
59 /** The following applies to all _decode() functions listed directly below.
60  *
61  * @param[inout] state        The current state of the decoding.
62  * @param[out]   result       Where to place the decoded value.
63  * @param[in]    result_size  (if present) Size in bytes of the memory at @p result
64  *
65  * @retval true   If the value was decoded correctly.
66  * @retval false  If the value has the wrong type, the payload overflowed, the
67  *                element count was exhausted, or the value was larger than can
68  *                fit in the result variable.
69  *                Use zcbor_peek_error() to see the error code.
70  */
71 bool zcbor_int32_decode(zcbor_state_t *state, int32_t *result); /* pint/nint */
72 bool zcbor_int64_decode(zcbor_state_t *state, int64_t *result); /* pint/nint */
73 bool zcbor_uint32_decode(zcbor_state_t *state, uint32_t *result); /* pint */
74 bool zcbor_uint64_decode(zcbor_state_t *state, uint64_t *result); /* pint */
75 bool zcbor_size_decode(zcbor_state_t *state, size_t *result); /* pint */
76 bool zcbor_int_decode(zcbor_state_t *state, void *result, size_t result_size); /* pint/nint */
77 bool zcbor_uint_decode(zcbor_state_t *state, void *result, size_t result_size); /* pint */
78 bool zcbor_bstr_decode(zcbor_state_t *state, struct zcbor_string *result); /* bstr */
79 bool zcbor_tstr_decode(zcbor_state_t *state, struct zcbor_string *result); /* tstr */
80 bool zcbor_tag_decode(zcbor_state_t *state, uint32_t *result);  /* CBOR tag */
81 bool zcbor_simple_decode(zcbor_state_t *state, uint8_t *result); /* CBOR simple value */
82 bool zcbor_bool_decode(zcbor_state_t *state, bool *result); /* boolean CBOR simple value */
83 bool zcbor_float16_decode(zcbor_state_t *state, float *result); /* IEEE754 float16 */
84 bool zcbor_float16_bytes_decode(zcbor_state_t *state, uint16_t *result); /* IEEE754 float16 raw bytes */
85 bool zcbor_float16_32_decode(zcbor_state_t *state, float *result); /* IEEE754 float16 or float32 */
86 bool zcbor_float32_decode(zcbor_state_t *state, float *result); /* IEEE754 float32 */
87 bool zcbor_float32_64_decode(zcbor_state_t *state, double *result); /* IEEE754 float32 or float64 */
88 bool zcbor_float64_decode(zcbor_state_t *state, double *result); /* IEEE754 float64 */
89 bool zcbor_float_decode(zcbor_state_t *state, double *result); /* IEEE754 float16, float32, or float64 */
90 
91 /** The following applies to all _expect() and _pexpect() functions listed directly below.
92  *
93  * @param[inout] state     The current state of the decoding.
94  * @param[in]    expected  The expected value.
95  *
96  * @retval true   If the result was decoded correctly and has the expected value.
97  * @retval false  If the decoding failed or the result doesn't have the
98  *                expected value.
99  *                Use zcbor_peek_error() to see the error code.
100  */
101 bool zcbor_int32_expect(zcbor_state_t *state, int32_t expected); /* pint/nint */
102 bool zcbor_int64_expect(zcbor_state_t *state, int64_t expected); /* pint/nint */
103 bool zcbor_uint32_expect(zcbor_state_t *state, uint32_t expected); /* pint */
104 bool zcbor_uint64_expect(zcbor_state_t *state, uint64_t expected); /* pint */
105 bool zcbor_size_expect(zcbor_state_t *state, size_t expected); /* pint */
106 bool zcbor_bstr_expect(zcbor_state_t *state, struct zcbor_string *expected); /* bstr */
107 bool zcbor_tstr_expect(zcbor_state_t *state, struct zcbor_string *expected); /* tstr */
108 bool zcbor_tag_expect(zcbor_state_t *state, uint32_t expected); /* CBOR tag */
109 bool zcbor_simple_expect(zcbor_state_t *state, uint8_t expected); /* CBOR simple value */
110 bool zcbor_bool_expect(zcbor_state_t *state, bool expected); /* boolean CBOR simple value */
111 bool zcbor_nil_expect(zcbor_state_t *state, void *unused); /* 'nil' CBOR simple value */
112 bool zcbor_undefined_expect(zcbor_state_t *state, void *unused); /* 'undefined' CBOR simple value */
113 bool zcbor_float16_expect(zcbor_state_t *state, float expected); /* IEEE754 float16 */
114 bool zcbor_float16_bytes_expect(zcbor_state_t *state, uint16_t expected); /* IEEE754 float16 raw bytes */
115 bool zcbor_float16_32_expect(zcbor_state_t *state, float expected); /* IEEE754 float16 or float32 */
116 bool zcbor_float32_expect(zcbor_state_t *state, float expected); /* IEEE754 float32 */
117 bool zcbor_float32_64_expect(zcbor_state_t *state, double expected); /* IEEE754 float32 or float64 */
118 bool zcbor_float64_expect(zcbor_state_t *state, double expected); /* IEEE754 float64 */
119 bool zcbor_float_expect(zcbor_state_t *state, double expected); /* IEEE754 float16, float32, or float64 */
120 
121 /** Like the _expect() functions but the value is passed through a pointer.
122  * (for use as a zcbor_decoder_t function) */
123 bool zcbor_int32_pexpect(zcbor_state_t *state, int32_t *expected); /* pint/nint */
124 bool zcbor_int64_pexpect(zcbor_state_t *state, int64_t *expected); /* pint/nint */
125 bool zcbor_uint32_pexpect(zcbor_state_t *state, uint32_t *expected); /* pint */
126 bool zcbor_uint64_pexpect(zcbor_state_t *state, uint64_t *expected); /* pint */
127 bool zcbor_size_pexpect(zcbor_state_t *state, size_t *expected); /* pint */
128 bool zcbor_tag_pexpect(zcbor_state_t *state, uint32_t *expected); /* CBOR tag */
129 bool zcbor_simple_pexpect(zcbor_state_t *state, uint8_t *expected); /* CBOR simple value */
130 bool zcbor_bool_pexpect(zcbor_state_t *state, bool *expected); /* boolean CBOR simple value */
131 bool zcbor_float16_pexpect(zcbor_state_t *state, float *expected); /* IEEE754 float16 */
132 bool zcbor_float16_bytes_pexpect(zcbor_state_t *state, uint16_t *expected); /* IEEE754 float16 raw bytes */
133 bool zcbor_float16_32_pexpect(zcbor_state_t *state, float *expected); /* IEEE754 float16 or float32 */
134 bool zcbor_float32_pexpect(zcbor_state_t *state, float *expected); /* IEEE754 float32 */
135 bool zcbor_float32_64_pexpect(zcbor_state_t *state, double *expected); /* IEEE754 float32 or float64 */
136 bool zcbor_float64_pexpect(zcbor_state_t *state, double *expected); /* IEEE754 float64 */
137 bool zcbor_float_pexpect(zcbor_state_t *state, double *expected); /* IEEE754 float16, float32, or float64 */
138 
139 /** Consume and expect a pint/nint with a certain value, within a union.
140  *
141  * Calls @ref zcbor_union_elem_code then @ref zcbor_[u]int[32|64]_expect.
142  */
143 bool zcbor_int32_expect_union(zcbor_state_t *state, int32_t expected);
144 bool zcbor_int64_expect_union(zcbor_state_t *state, int64_t expected);
145 bool zcbor_uint32_expect_union(zcbor_state_t *state, uint32_t expected);
146 bool zcbor_uint64_expect_union(zcbor_state_t *state, uint64_t expected);
147 
148 /** Decode and consume a list/map header.
149  *
150  * The contents of the list can be decoded via subsequent function calls.
151  * A state backup is created to keep track of the element count.
152  * Call @ref zcbor_list_end_decode / @ref zcbor_map_end_decode when done
153  * decoding the contents of the list/map
154  *
155  * @retval true   Header decoded correctly
156  * @retval false  Header decoded incorrectly, or backup failed.
157  */
158 bool zcbor_list_start_decode(zcbor_state_t *state);
159 bool zcbor_map_start_decode(zcbor_state_t *state);
160 bool zcbor_unordered_map_start_decode(zcbor_state_t *state);
161 
162 /** Search for a key in a map.
163  *
164  * The CBOR spec allows elements (key-value pairs) in maps to appear in any order.
165  * This function should be used when the order of elements is unknown.
166  *
167  * This must only be used while inside a map that has been entered via
168  * @ref zcbor_unordered_map_start_decode. Use @ref zcbor_unordered_map_end_decode
169  * when leaving the map.
170  *
171  * This function searches for keys. When this function returns successfully,
172  * the @p state is pointing to the value corresponding to the found key.
173  * Therefore, to be able to call this function again, the value must first be
174  * decoded or skipped.
175  *
176  * When searching unordered maps, the found elements must be kept track of.
177  * By default, this function automatically keeps track, which means it keeps a
178  * running count of the number of found elements, which is checked when exiting
179  * the map. You can do this manually instead, see @ref zcbor_elem_processed and
180  * @ref manually_process_elem. If ZCBOR_MAP_SMART_SEARCH is defined, a flag is
181  * kept for each element, instead of a rolling count.
182  *
183  * @note Unless ZCBOR_MAP_SMART_SEARCH is defined,
184  *       elements are not individually marked as processed, so they may
185  *       be returned again in a subsequent call to this function, if it is
186  *       matched by the @p key_decoder of that call. Because of this, you should
187  *       only use this function when you know the @p key_decoder matches no more
188  *       than one of the keys. Typically this means all keys are known strings
189  *       or integers, i.e. the @p key_decoder is typically a _pexpect() function.
190  *
191  * When searching for strings, there are convenience functions available,
192  * see the zcbor_search_key_* functions.
193  *
194  * @param[in] key_decoder  A decoding function that will be tried against all
195  *                         keys in the map until it returns true, at which point
196  *                         @ref zcbor_unordered_map_search will return true.
197  *                         For example, a zcbor_*_pexpect() function.
198  * @param[inout] state  The current state of decoding. Must be currently decoding
199  *                      the contents of a map, and pointing to one (any) of the
200  *                      keys, not one of the values. If successful, the @p state
201  *                      will be pointing to the value corresponding to the
202  *                      matched key. If unsuccessful, the @p state will be
203  *                      unchanged.
204  * @param[inout] key_result  This will be passed as the second argument to the
205  *                           @p key_decoder.
206  *
207  * @retval true   If the key was found, i.e. @p key_decoder returned true.
208  * @retval false  If the key was not found after searching all map elements.
209  *                Or the map was pointing to a value (not a key).
210  *                Or an unexpected error happened while skipping elements or
211  *                jumping from the end of the map to the start.
212  */
213 bool zcbor_unordered_map_search(zcbor_decoder_t key_decoder, zcbor_state_t *state, void *key_result);
214 
215 /** Find a specific bstr/tstr key as part of a map with unknown element order.
216  *
217  * Uses @ref zcbor_unordered_map_search under the hood. Please refer to those docs
218  * for the conditions under which this can be called.
219  * Refer to the docs for zcbor_(t|b)str_expect_* (e.g. @ref zcbor_bstr_expect_ptr)
220  * for parameter docs.
221  */
222 bool zcbor_search_key_bstr_ptr(zcbor_state_t *state, char const *ptr, size_t len);
223 bool zcbor_search_key_tstr_ptr(zcbor_state_t *state, char const *ptr, size_t len);
224 bool zcbor_search_key_bstr_term(zcbor_state_t *state, char const *str, size_t maxlen);
225 bool zcbor_search_key_tstr_term(zcbor_state_t *state, char const *str, size_t maxlen);
226 #define zcbor_search_key_bstr_lit(state, str) zcbor_search_key_bstr_ptr(state, str, sizeof(str) - 1)
227 #define zcbor_search_key_tstr_lit(state, str) zcbor_search_key_tstr_ptr(state, str, sizeof(str) - 1)
228 #define zcbor_search_key_bstr_arr(state, str) zcbor_search_key_bstr_ptr(state, str, (sizeof(str)))
229 #define zcbor_search_key_tstr_arr(state, str) zcbor_search_key_tstr_ptr(state, str, (sizeof(str)))
230 
231 /** (Optional) Call this function to mark an (unordered map) element as processed.
232  *
233  * @note This should not be called unless the @ref manually_process_elem flag is set.
234  *       By default, i.e. when @ref manually_process_elem is not set, this function is
235  *       called internally by @ref zcbor_unordered_map_search whenever a key is found.
236  *
237  * By default, this function increments the internal count @ref map_elems_processed.
238  *
239  * If ZCBOR_MAP_SMART_SEARCH is defined, this function instead clears a flag for the
240  * element (key-value pair) that is currently being processed, or that has just been
241  * processed, meaning the element won't be found again via @ref zcbor_unordered_map_search.
242  *
243  * @ref zcbor_unordered_map_end_decode will fail if @ref map_elems_processed does not
244  * match the number of elements in the map, or if any of the map element's flag is set.
245  */
246 bool zcbor_elem_processed(zcbor_state_t *state);
247 
248 /** Finalize decoding a list/map
249  *
250  * Check that the list/map had the correct number of elements, and restore the
251  * previous element count from the backup.
252  *
253  * Use @ref zcbor_list_map_end_force_decode to forcibly consume the backup if
254  * something has gone wrong.
255  *
256  * In all successful cases, the state is returned pointing to the byte/element
257  * after the list/map in the payload.
258  *
259  * @retval true   Everything ok.
260  * @retval false  Element count not correct.
261  */
262 bool zcbor_list_end_decode(zcbor_state_t *state);
263 bool zcbor_map_end_decode(zcbor_state_t *state);
264 bool zcbor_unordered_map_end_decode(zcbor_state_t *state);
265 bool zcbor_list_map_end_force_decode(zcbor_state_t *state);
266 
267 /** Find whether the state is at the end of a list or map.
268  */
269 bool zcbor_array_at_end(zcbor_state_t *state);
270 
271 /** Skip a single element, regardless of type and value.
272  *
273  * This means if the element is a map or list, this function will recursively
274  * skip all its contents.
275  * This function will also skip any tags preceeding the element.
276  *
277  * @param[inout] state   The current state of the decoding.
278  * @param[in]    unused  Unused parameter to maintain signature parity with
279  *                       @ref zcbor_decoder_t.
280  */
281 bool zcbor_any_skip(zcbor_state_t *state, void *unused);
282 
283 /** Decode 0 or more elements with the same type and constraints.
284  *
285  * The decoded values will appear consecutively in the @p result array.
286  *
287  * The following is an example of decoding a list containing 3 INTS followed by
288  * 0 to 2 bstrs:
289  *
290  * @code{c}
291  *     uint32_t ints[3];
292  *     struct zcbor_string bstrs[2];
293  *     uint32_t num_decode;
294  *     bool res;
295  *
296  *     res = zcbor_list_start_decode(state);
297  *     res = res && zcbor_multi_decode(3, 3, &num_decode, zcbor_uint32_decode,
298  *                  state, ints, sizeof(ints[0]));
299  *     res = res && zcbor_multi_decode(0, 2, &num_decode, zcbor_bstr_decode,
300  *                  state, bstrs, sizeof(bstrs[0]));
301  *     res = res && zcbor_list_end_decode(state);
302  *     // check res
303  * @endcode
304  *
305  * The @ref zcbor_decoder_t type is designed to be compatible with all single-
306  * value decoder functions in this library, e.g. @ref zcbor_uint32_decode,
307  * @ref zcbor_tstr_expect, @ref zcbor_nil_expect, etc. For _expect() functions,
308  * @p result will be used as a value instead of an array/pointer, so
309  * @p result_len will determine how much the value changes for each call.
310  * To decode the same value multiple times, use a @p result_len of 0.
311  * This function can also be used with custom decoder functions, such as those
312  * generated by the zcbor.py script, which for example decodes larger chunks of
313  * the data at once.
314  *
315  * @param[in]  min_decode    The minimum acceptable number of elements.
316  * @param[in]  max_decode    The maximum acceptable number of elements.
317  * @param[out] num_decode    The actual number of elements decoded.
318  * @param[in]  decoder       The decoder function to call under the hood. This
319  *                           function will be called with the provided arguments
320  *                           repeatedly until the function fails (returns false)
321  *                           or until it has been called @p max_decode times.
322  *                           The result pointer is moved @p result_len bytes for
323  *                           each call to @p decoder, i.e. @p result refers to
324  *                           an array of result variables.
325  *                           Should not be an _expect() function, use
326  *                           _pexpect() instead.
327  * @param[out] result        Where to place the decoded values. Must be an array
328  *                           of at least @p max_decode elements.
329  * @param[in]  result_len    The length of each result variable. Must be the
330  *                           length of the individual elements of @p result.
331  *
332  * @retval true   If at least @p min_decode variables were correctly decoded.
333  * @retval false  If @p decoder failed before having decoded @p min_decode
334  *                values.
335  */
336 bool zcbor_multi_decode(size_t min_decode, size_t max_decode, size_t *num_decode,
337 		zcbor_decoder_t decoder, zcbor_state_t *state, void *result,
338 		size_t result_len);
339 
340 /** Attempt to decode a value that might not be present in the data.
341  *
342  * Works like @ref zcbor_multi_decode, with @p present as num_decode.
343  * Will return true, even if the data is not present.
344  *
345  * @param[out] present  Whether or not the data was present and successfully decoded.
346  * @param[in]  decoder  The decoder to attempt.
347  * @param[out] result   The result, if present.
348  *
349  * @return Should always return true.
350  */
351 bool zcbor_present_decode(bool *present,
352 		zcbor_decoder_t decoder,
353 		zcbor_state_t *state,
354 		void *result);
355 
356 
357 /** Supplementary string (bstr/tstr) decoding functions: */
358 
359 /** Consume and expect a bstr/tstr with the value of the provided char/uint8_t array.
360  *
361  * @param[inout] state   The current state of the decoding.
362  * @param[in]    str     The value to expect. A pointer to the string/array.
363  *                       _term() uses strnlen(), so @p str must be null-terminated.
364  *                       _lit() uses sizeof()-1, so @p str must be a (null-terminated) string literal.
365  *                       _arr() uses sizeof(), so @p str must be a uint8_t array (not null-terminated).
366  * @param[in]    len     (if present) The length of the string pointed to by @p str
367  * @param[in]    maxlen  (if present) The maximum length of the string pointed to by @p str.
368  *                       This value is passed to strnlen.
369  */
370 bool zcbor_bstr_expect_ptr(zcbor_state_t *state, char const *ptr, size_t len);
371 bool zcbor_tstr_expect_ptr(zcbor_state_t *state, char const *ptr, size_t len);
372 bool zcbor_bstr_expect_term(zcbor_state_t *state, char const *str, size_t maxlen);
373 bool zcbor_tstr_expect_term(zcbor_state_t *state, char const *str, size_t maxlen);
374 #define zcbor_bstr_expect_lit(state, str) zcbor_bstr_expect_ptr(state, str, sizeof(str) - 1)
375 #define zcbor_tstr_expect_lit(state, str) zcbor_tstr_expect_ptr(state, str, sizeof(str) - 1)
376 #define zcbor_bstr_expect_arr(state, str) zcbor_bstr_expect_ptr(state, str, sizeof(str))
377 #define zcbor_tstr_expect_arr(state, str) zcbor_tstr_expect_ptr(state, str, sizeof(str))
378 
379 /** Decode and consume a bstr header.
380  *
381  * The rest of the string can be decoded as CBOR.
382  * A state backup is created to keep track of the element count.
383  * Call @ref zcbor_bstr_end_decode when done decoding the contents of the bstr.
384  *
385  * @param[inout] state   The current state of the decoding.
386  * @param[out]   result  The resulting string, for reference. The string should be decoded via
387  *                       functions from this API since state is pointing to the start of the string,
388  *                       not the end.
389  *
390  * @retval true   Header decoded correctly
391  * @retval false  Header decoded incorrectly, or backup failed, or payload is not large enough
392  *                to contain the contents of the string. Use @ref zcbor_bstr_start_decode_fragment
393  *                for decoding fragmented payloads.
394  */
395 bool zcbor_bstr_start_decode(zcbor_state_t *state, struct zcbor_string *result);
396 
397 /** Finalize decoding a CBOR-encoded bstr.
398  *
399  * Restore element count from backup.
400  */
401 bool zcbor_bstr_end_decode(zcbor_state_t *state);
402 
403 
404 /** Supplementary string (bstr/tstr) decoding functions for fragmented payloads: */
405 
406 /** Start decoding a bstr/tstr, even if the payload contains only part of it.
407  *
408  * This must be followed by a call to @ref zcbor_update_state, which can be
409  * followed by a call to @ref zcbor_next_fragment. Do not call this function
410  * again on subsequent fragments of the same string.
411  *
412  * This consumes the remaining payload as long as it belongs to the string.
413  */
414 bool zcbor_bstr_decode_fragment(zcbor_state_t *state, struct zcbor_string_fragment *result);
415 bool zcbor_tstr_decode_fragment(zcbor_state_t *state, struct zcbor_string_fragment *result);
416 
417 /** Extract the next fragment of a string.
418  *
419  * Use this function to extract all but the first fragment.
420  */
421 void zcbor_next_fragment(zcbor_state_t *state,
422 	struct zcbor_string_fragment *prev_fragment,
423 	struct zcbor_string_fragment *result);
424 
425 /** Decode and consume a bstr header, assuming the payload does not contain the whole bstr.
426  *
427  * The rest of the string can be decoded as CBOR.
428  * A state backup is created to keep track of the element count.
429  * Call @ref zcbor_update_state followed by @ref zcbor_bstr_next_fragment when
430  * the current payload has been exhausted.
431  * Call @ref zcbor_bstr_end_decode when done decoding the contents of the bstr.
432  */
433 bool zcbor_bstr_start_decode_fragment(zcbor_state_t *state,
434 	struct zcbor_string_fragment *result);
435 
436 /** Start decoding the next fragment of a string.
437  *
438  * Use this function to extract all but the first fragment of a CBOR-encoded
439  * bstr.
440  */
441 void zcbor_bstr_next_fragment(zcbor_state_t *state,
442 	struct zcbor_string_fragment *prev_fragment,
443 	struct zcbor_string_fragment *result);
444 
445 /** Can be used on any fragment to tell if it is the final fragment of the string. */
446 bool zcbor_is_last_fragment(const struct zcbor_string_fragment *fragment);
447 
448 #ifdef __cplusplus
449 }
450 #endif
451 
452 #endif /* ZCBOR_DECODE_H__ */
453