180ad94fcSkasunath #pragma once
280ad94fcSkasunath 
30aa36d82Skasunath #include "bej_common.h"
480ad94fcSkasunath 
580ad94fcSkasunath #include <stdbool.h>
680ad94fcSkasunath #include <stddef.h>
780ad94fcSkasunath #include <stdint.h>
880ad94fcSkasunath 
980ad94fcSkasunath #ifdef __cplusplus
1080ad94fcSkasunath extern "C"
1180ad94fcSkasunath {
1280ad94fcSkasunath #endif
1380ad94fcSkasunath 
1480ad94fcSkasunath /**
1580ad94fcSkasunath  * @brief Indicates whether a new BEJ section falls inside a BEJ array or a
1680ad94fcSkasunath  * BEJ set or none of those.
1780ad94fcSkasunath  */
1880ad94fcSkasunath enum BejSectionType
1980ad94fcSkasunath {
2080ad94fcSkasunath     bejSectionNoType,
2180ad94fcSkasunath     bejSectionSet,
2280ad94fcSkasunath     bejSectionArray,
2380ad94fcSkasunath };
2480ad94fcSkasunath 
2580ad94fcSkasunath /**
2680ad94fcSkasunath  * @brief These stack entries are needed to implement the decoding
2780ad94fcSkasunath  * non-recursively.
2880ad94fcSkasunath  */
2980ad94fcSkasunath struct BejStackProperty
3080ad94fcSkasunath {
3180ad94fcSkasunath     // Indicates whether we are inside an array or a set or an annotation.
3280ad94fcSkasunath     enum BejSectionType sectionType;
3380ad94fcSkasunath     // Indicate whether we have property names for properties.
3480ad94fcSkasunath     bool addPropertyName;
3580ad94fcSkasunath     // Offset to the parent property in schema dictionary.
3680ad94fcSkasunath     uint16_t mainDictPropOffset;
3780ad94fcSkasunath     // Offset to the parent property in annotation dictionary.
3880ad94fcSkasunath     uint16_t annoDictPropOffset;
3980ad94fcSkasunath     // Offset to the end of the array or set or annotation.
4080ad94fcSkasunath     uint32_t streamEndOffset;
4180ad94fcSkasunath };
4280ad94fcSkasunath 
4380ad94fcSkasunath /**
4480ad94fcSkasunath  * @brief Holds the information related to the current bejTuple being
4580ad94fcSkasunath  * decoded.
4680ad94fcSkasunath  */
4780ad94fcSkasunath struct BejDecoderStates
4880ad94fcSkasunath {
4980ad94fcSkasunath     bool addPropertyName;
5080ad94fcSkasunath     uint16_t mainDictPropOffset;
5180ad94fcSkasunath     uint16_t annoDictPropOffset;
5280ad94fcSkasunath     uint32_t encodedStreamOffset;
5380ad94fcSkasunath     const uint8_t* encodedSubStream;
5480ad94fcSkasunath };
5580ad94fcSkasunath 
5680ad94fcSkasunath /**
5780ad94fcSkasunath  * @brief Callbacks for decoded data.
5880ad94fcSkasunath  *
5980ad94fcSkasunath  * dataPtr in the callback functions can be used for extra arguments.
6080ad94fcSkasunath  */
6180ad94fcSkasunath struct BejDecodedCallback
6280ad94fcSkasunath {
6380ad94fcSkasunath     /**
6480ad94fcSkasunath      * @brief Calls when a Set is detected.
6580ad94fcSkasunath      */
6680ad94fcSkasunath     int (*callbackSetStart)(const char* propertyName, void* dataPtr);
6780ad94fcSkasunath 
6880ad94fcSkasunath     /**
6980ad94fcSkasunath      * @brief Calls when an end of a Set is found.
7080ad94fcSkasunath      */
7180ad94fcSkasunath     int (*callbackSetEnd)(void* dataPtr);
7280ad94fcSkasunath 
7380ad94fcSkasunath     /**
7480ad94fcSkasunath      * @brief Calls when an array is detected.
7580ad94fcSkasunath      */
7680ad94fcSkasunath     int (*callbackArrayStart)(const char* propertyName, void* dataPtr);
7780ad94fcSkasunath 
7880ad94fcSkasunath     /**
7980ad94fcSkasunath      * @brief Calls when an end of an array is found.
8080ad94fcSkasunath      */
8180ad94fcSkasunath     int (*callbackArrayEnd)(void* dataPtr);
8280ad94fcSkasunath 
8380ad94fcSkasunath     /**
8480ad94fcSkasunath      * @brief Calls after a property is finished unless this is the last
8580ad94fcSkasunath      * property in a Set or an array. In that case appropriate
8680ad94fcSkasunath      * callbackSetEnd or callbackArrayEnd will be called.
8780ad94fcSkasunath      */
8880ad94fcSkasunath     int (*callbackPropertyEnd)(void* dataPtr);
8980ad94fcSkasunath 
9080ad94fcSkasunath     /**
9180ad94fcSkasunath      * @brief Calls when a Null property is found or the property length is
9280ad94fcSkasunath      * 0.
9380ad94fcSkasunath      */
9480ad94fcSkasunath     int (*callbackNull)(const char* propertyName, void* dataPtr);
9580ad94fcSkasunath 
9680ad94fcSkasunath     /**
9780ad94fcSkasunath      * @brief Calls when an Integer property is found.
9880ad94fcSkasunath      */
9980ad94fcSkasunath     int (*callbackInteger)(const char* propertyName, int64_t value,
10080ad94fcSkasunath                            void* dataPtr);
10180ad94fcSkasunath 
10280ad94fcSkasunath     /**
10380ad94fcSkasunath      * @brief Calls when an Enum property is found.
10480ad94fcSkasunath      */
10580ad94fcSkasunath     int (*callbackEnum)(const char* propertyName, const char* value,
10680ad94fcSkasunath                         void* dataPtr);
10780ad94fcSkasunath 
10880ad94fcSkasunath     /**
10980ad94fcSkasunath      * @brief Calls when a String property is found.
11080ad94fcSkasunath      */
11180ad94fcSkasunath     int (*callbackString)(const char* propertyName, const char* value,
11280ad94fcSkasunath                           void* dataPtr);
11380ad94fcSkasunath 
11480ad94fcSkasunath     /**
11580ad94fcSkasunath      * @brief Calls when a Real value property is found.
11680ad94fcSkasunath      */
117*6f3082eaSPatrick Williams     int (*callbackReal)(const char* propertyName, const struct BejReal* value,
118*6f3082eaSPatrick Williams                         void* dataPtr);
11980ad94fcSkasunath 
12080ad94fcSkasunath     /**
12180ad94fcSkasunath      * @brief Calls when a Bool property is found.
12280ad94fcSkasunath      */
123*6f3082eaSPatrick Williams     int (*callbackBool)(const char* propertyName, bool value, void* dataPtr);
12480ad94fcSkasunath 
12580ad94fcSkasunath     /**
12680ad94fcSkasunath      * @brief Calls when an Annotated property is found.
12780ad94fcSkasunath      */
12880ad94fcSkasunath     int (*callbackAnnotation)(const char* propertyName, void* dataPtr);
12980ad94fcSkasunath 
13080ad94fcSkasunath     /**
13180ad94fcSkasunath      * @brief Calls when a read only property is found.
13280ad94fcSkasunath      */
13380ad94fcSkasunath     int (*callbackReadonlyProperty)(uint32_t sequenceNumber, void* dataPtr);
13480ad94fcSkasunath };
13580ad94fcSkasunath 
13680ad94fcSkasunath /**
13780ad94fcSkasunath  * @brief Stack for holding BejStackProperty types. Decoder core is not
13880ad94fcSkasunath  * responsible for creating or deleting stack memory. User of the decoder
13980ad94fcSkasunath  * core is responsible for creating and deleting stack memory.
14080ad94fcSkasunath  *
14180ad94fcSkasunath  * dataPtr in the callback functions can be used for extra arguments.
14280ad94fcSkasunath  */
14380ad94fcSkasunath struct BejStackCallback
14480ad94fcSkasunath {
14580ad94fcSkasunath     /**
14680ad94fcSkasunath      * @brief Return true if the stack is empty.
14780ad94fcSkasunath      */
14880ad94fcSkasunath     bool (*stackEmpty)(void* dataPtr);
14980ad94fcSkasunath 
15080ad94fcSkasunath     /**
15180ad94fcSkasunath      * @brief View the object at the top of the stack. If the stack is
15280ad94fcSkasunath      * empty, this will return NULL.
15380ad94fcSkasunath      */
15480ad94fcSkasunath     const struct BejStackProperty* (*stackPeek)(void* dataPtr);
15580ad94fcSkasunath 
15680ad94fcSkasunath     /**
15780ad94fcSkasunath      * @brief Removes the top most object from the stack. Client of the
15880ad94fcSkasunath      * decoder core is responsible for destroying the memory for the removed
15980ad94fcSkasunath      * object.
16080ad94fcSkasunath      */
16180ad94fcSkasunath     void (*stackPop)(void* dataPtr);
16280ad94fcSkasunath 
16380ad94fcSkasunath     /**
16480ad94fcSkasunath      * @brief Push an object into the stack. Returns 0 if the operation is
16580ad94fcSkasunath      * successfull. Client of the decoder core is responsible for allocating
16680ad94fcSkasunath      * memory for the new object.
16780ad94fcSkasunath      */
16880ad94fcSkasunath     int (*stackPush)(const struct BejStackProperty* const property,
16980ad94fcSkasunath                      void* dataPtr);
17080ad94fcSkasunath };
17180ad94fcSkasunath 
17280ad94fcSkasunath /**
17380ad94fcSkasunath  * @brief Used to pass parameters to BEJ decoding local functions.
17480ad94fcSkasunath  */
17580ad94fcSkasunath struct BejHandleTypeFuncParam
17680ad94fcSkasunath {
17780ad94fcSkasunath     struct BejDecoderStates state;
17880ad94fcSkasunath     struct BejSFLV sflv;
17980ad94fcSkasunath     const uint8_t* mainDictionary;
18080ad94fcSkasunath     const uint8_t* annotDictionary;
18180ad94fcSkasunath     const struct BejDecodedCallback* decodedCallback;
18280ad94fcSkasunath     const struct BejStackCallback* stackCallback;
18380ad94fcSkasunath     void* callbacksDataPtr;
18480ad94fcSkasunath     void* stackDataPtr;
18580ad94fcSkasunath };
18680ad94fcSkasunath 
18780ad94fcSkasunath /**
18880ad94fcSkasunath  * @brief Decodes a PLDM block. Maximum encoded stream size the decoder
18980ad94fcSkasunath  * supports is 32bits.
19080ad94fcSkasunath  *
19180ad94fcSkasunath  * @param[in] dictionaries - dictionaries needed for decoding.
19280ad94fcSkasunath  * @param[in] encodedPldmBlock - encoded PLDM block.
19380ad94fcSkasunath  * @param[in] blockLength - length of the PLDM block.
19480ad94fcSkasunath  * @param[in] stackCallback - callbacks for stack handlers. callbacks in
19580ad94fcSkasunath  * stackCallback struct should be set to valid functions.
19680ad94fcSkasunath  * @param[in] decodedCallback - callbacks for extracting decoded
19780ad94fcSkasunath  * properties. callbacks in decodedCallback struct should be set to
19880ad94fcSkasunath  * NULL or valid functions.
19980ad94fcSkasunath  * @param[in] callbacksDataPtr - data pointer to pass to decoded callbacks.
20080ad94fcSkasunath  * This can be used pass additional data.
20180ad94fcSkasunath  * @param[in] stackDataPtr - data pointer to pass to stack callbacks. This
20280ad94fcSkasunath  * can be used pass additional data.
20380ad94fcSkasunath  *
20480ad94fcSkasunath  * @return 0 if successful.
20580ad94fcSkasunath  */
20680ad94fcSkasunath int bejDecodePldmBlock(const struct BejDictionaries* dictionaries,
207*6f3082eaSPatrick Williams                        const uint8_t* encodedPldmBlock, uint32_t blockLength,
20880ad94fcSkasunath                        const struct BejStackCallback* stackCallback,
20980ad94fcSkasunath                        const struct BejDecodedCallback* decodedCallback,
21080ad94fcSkasunath                        void* callbacksDataPtr, void* stackDataPtr);
21180ad94fcSkasunath 
21280ad94fcSkasunath #ifdef __cplusplus
21380ad94fcSkasunath }
21480ad94fcSkasunath #endif
215