1 #pragma once
2 
3 #include "bej_common.h"
4 
5 #include <stdbool.h>
6 #include <stddef.h>
7 #include <stdint.h>
8 
9 #ifdef __cplusplus
10 extern "C"
11 {
12 #endif
13 
14     /**
15      * @brief Indicates whether a new BEJ section falls inside a BEJ array or a
16      * BEJ set or none of those.
17      */
18     enum BejSectionType
19     {
20         bejSectionNoType,
21         bejSectionSet,
22         bejSectionArray,
23     };
24 
25     /**
26      * @brief These stack entries are needed to implement the decoding
27      * non-recursively.
28      */
29     struct BejStackProperty
30     {
31         // Indicates whether we are inside an array or a set or an annotation.
32         enum BejSectionType sectionType;
33         // Indicate whether we have property names for properties.
34         bool addPropertyName;
35         // Offset to the parent property in schema dictionary.
36         uint16_t mainDictPropOffset;
37         // Offset to the parent property in annotation dictionary.
38         uint16_t annoDictPropOffset;
39         // Offset to the end of the array or set or annotation.
40         uint32_t streamEndOffset;
41     };
42 
43     /**
44      * @brief Holds the information related to the current bejTuple being
45      * decoded.
46      */
47     struct BejDecoderStates
48     {
49         bool addPropertyName;
50         uint16_t mainDictPropOffset;
51         uint16_t annoDictPropOffset;
52         uint32_t encodedStreamOffset;
53         const uint8_t* encodedSubStream;
54     };
55 
56     /**
57      * @brief Callbacks for decoded data.
58      *
59      * dataPtr in the callback functions can be used for extra arguments.
60      */
61     struct BejDecodedCallback
62     {
63         /**
64          * @brief Calls when a Set is detected.
65          */
66         int (*callbackSetStart)(const char* propertyName, void* dataPtr);
67 
68         /**
69          * @brief Calls when an end of a Set is found.
70          */
71         int (*callbackSetEnd)(void* dataPtr);
72 
73         /**
74          * @brief Calls when an array is detected.
75          */
76         int (*callbackArrayStart)(const char* propertyName, void* dataPtr);
77 
78         /**
79          * @brief Calls when an end of an array is found.
80          */
81         int (*callbackArrayEnd)(void* dataPtr);
82 
83         /**
84          * @brief Calls after a property is finished unless this is the last
85          * property in a Set or an array. In that case appropriate
86          * callbackSetEnd or callbackArrayEnd will be called.
87          */
88         int (*callbackPropertyEnd)(void* dataPtr);
89 
90         /**
91          * @brief Calls when a Null property is found or the property length is
92          * 0.
93          */
94         int (*callbackNull)(const char* propertyName, void* dataPtr);
95 
96         /**
97          * @brief Calls when an Integer property is found.
98          */
99         int (*callbackInteger)(const char* propertyName, int64_t value,
100                                void* dataPtr);
101 
102         /**
103          * @brief Calls when an Enum property is found.
104          */
105         int (*callbackEnum)(const char* propertyName, const char* value,
106                             void* dataPtr);
107 
108         /**
109          * @brief Calls when a String property is found.
110          */
111         int (*callbackString)(const char* propertyName, const char* value,
112                               void* dataPtr);
113 
114         /**
115          * @brief Calls when a Real value property is found.
116          */
117         int (*callbackReal)(const char* propertyName,
118                             const struct BejReal* value, void* dataPtr);
119 
120         /**
121          * @brief Calls when a Bool property is found.
122          */
123         int (*callbackBool)(const char* propertyName, bool value,
124                             void* dataPtr);
125 
126         /**
127          * @brief Calls when an Annotated property is found.
128          */
129         int (*callbackAnnotation)(const char* propertyName, void* dataPtr);
130 
131         /**
132          * @brief Calls when a read only property is found.
133          */
134         int (*callbackReadonlyProperty)(uint32_t sequenceNumber, void* dataPtr);
135     };
136 
137     /**
138      * @brief Stack for holding BejStackProperty types. Decoder core is not
139      * responsible for creating or deleting stack memory. User of the decoder
140      * core is responsible for creating and deleting stack memory.
141      *
142      * dataPtr in the callback functions can be used for extra arguments.
143      */
144     struct BejStackCallback
145     {
146         /**
147          * @brief Return true if the stack is empty.
148          */
149         bool (*stackEmpty)(void* dataPtr);
150 
151         /**
152          * @brief View the object at the top of the stack. If the stack is
153          * empty, this will return NULL.
154          */
155         const struct BejStackProperty* (*stackPeek)(void* dataPtr);
156 
157         /**
158          * @brief Removes the top most object from the stack. Client of the
159          * decoder core is responsible for destroying the memory for the removed
160          * object.
161          */
162         void (*stackPop)(void* dataPtr);
163 
164         /**
165          * @brief Push an object into the stack. Returns 0 if the operation is
166          * successfull. Client of the decoder core is responsible for allocating
167          * memory for the new object.
168          */
169         int (*stackPush)(const struct BejStackProperty* const property,
170                          void* dataPtr);
171     };
172 
173     /**
174      * @brief Used to pass parameters to BEJ decoding local functions.
175      */
176     struct BejHandleTypeFuncParam
177     {
178         struct BejDecoderStates state;
179         struct BejSFLV sflv;
180         const uint8_t* mainDictionary;
181         const uint8_t* annotDictionary;
182         const struct BejDecodedCallback* decodedCallback;
183         const struct BejStackCallback* stackCallback;
184         void* callbacksDataPtr;
185         void* stackDataPtr;
186     };
187 
188     /**
189      * @brief Decodes a PLDM block. Maximum encoded stream size the decoder
190      * supports is 32bits.
191      *
192      * @param[in] dictionaries - dictionaries needed for decoding.
193      * @param[in] encodedPldmBlock - encoded PLDM block.
194      * @param[in] blockLength - length of the PLDM block.
195      * @param[in] stackCallback - callbacks for stack handlers. callbacks in
196      * stackCallback struct should be set to valid functions.
197      * @param[in] decodedCallback - callbacks for extracting decoded
198      * properties. callbacks in decodedCallback struct should be set to
199      * NULL or valid functions.
200      * @param[in] callbacksDataPtr - data pointer to pass to decoded callbacks.
201      * This can be used pass additional data.
202      * @param[in] stackDataPtr - data pointer to pass to stack callbacks. This
203      * can be used pass additional data.
204      *
205      * @return 0 if successful.
206      */
207     int bejDecodePldmBlock(const struct BejDictionaries* dictionaries,
208                            const uint8_t* encodedPldmBlock,
209                            uint32_t blockLength,
210                            const struct BejStackCallback* stackCallback,
211                            const struct BejDecodedCallback* decodedCallback,
212                            void* callbacksDataPtr, void* stackDataPtr);
213 
214 #ifdef __cplusplus
215 }
216 #endif
217