Add the framework needed for BEJ encoding

This change adds the framework needed for BEJ encoding. Inorder to keep
the patch smaller, I only added the basic framework needed to understand
how the encoding is done. Rest of the functionality and testing will
be added in the later patches.

Signed-off-by: Kasun Athukorala <kasunath@google.com>
Change-Id: If2bd315fe5a3e6c7afff2af1750434042517790b
diff --git a/include/libbej/bej_common.h b/include/libbej/bej_common.h
index a0ec526..96f1a66 100644
--- a/include/libbej/bej_common.h
+++ b/include/libbej/bej_common.h
@@ -1,5 +1,6 @@
 #pragma once
 
+#include <stdbool.h>
 #include <stdint.h>
 
 #ifdef __cplusplus
@@ -8,6 +9,12 @@
 #endif
 
 /**
+ * @brief Use this value to indicate that the dictonary needs to be traversed
+ * starting at the first property of the dictionary.
+ */
+#define BEJ_DICTIONARY_START_AT_HEAD 0
+
+/**
  * @brief If expr is non zero, return with that value.
  */
 #ifndef RETURN_IF_IERROR
@@ -22,6 +29,20 @@
     } while (0)
 #endif
 
+/**
+ * @brief Check a given varable is NULL. If it is NULL, this will return with
+ * bejErrorNullParameter. If the variable is not NULL, this will not return.
+ */
+#define NULL_CHECK(param, structStr)                                           \
+    do                                                                         \
+    {                                                                          \
+        if ((param) == NULL)                                                   \
+        {                                                                      \
+            fprintf(stderr, "nullCheck: %s cannot be null\n", structStr);      \
+            return bejErrorNullParameter;                                      \
+        }                                                                      \
+    } while (0)
+
     /**
      * @brief RDE BEJ decoding errors.
      */
@@ -145,6 +166,58 @@
     } __attribute__((__packed__));
 
     /**
+     * @brief Points to dictionaries used for encoding and decoding.
+     */
+    struct BejDictionaries
+    {
+        const uint8_t* schemaDictionary;
+        const uint8_t* annotationDictionary;
+        const uint8_t* errorDictionary;
+    };
+
+    /**
+     * @brief Callbacks to a stack that can store pointers.
+     */
+    struct BejPointerStackCallback
+    {
+        /**
+         * @brief A context for the stack.
+         */
+        void* stackContext;
+
+        /**
+         * @brief Return true if the stack is empty.
+         */
+        bool (*stackEmpty)(void* stackContext);
+
+        /**
+         * @brief View the pointer at the top of the stack. If the stack is
+         * empty, this will return NULL.
+         */
+        void* (*stackPeek)(void* stackContext);
+
+        /**
+         * @brief Returns and removes the top most pointer from the stack. The
+         * Client of the libbej is responsible for destroying the memory used
+         * for storing the removed pointer (not the memory pointed by the
+         * pointer).
+         */
+        void* (*stackPop)(void* stackContext);
+
+        /**
+         * @brief Push a pointer into the stack. Returns 0 if the operation is
+         * successful. Client of this API is responsible for allocating memory
+         * for storing the new pointer.
+         */
+        int (*stackPush)(void* p, void* stackContext);
+
+        /**
+         * @brief Delete the stack.
+         */
+        void (*deleteStack)(void* stackContext);
+    };
+
+    /**
      * @brief Get the unsigned integer value from provided bytes.
      *
      * @param[in] bytes - valid pointer to a byte stream in little-endian
@@ -172,6 +245,23 @@
      */
     uint8_t bejGetNnintSize(const uint8_t* nnint);
 
+    /**
+     * @brief Get the total bytes needed to encode an unsigned value using nnint
+     * format.
+     *
+     * @param[in] val - unsigned value needed to encode.
+     * @return size of the nnint value.
+     */
+    uint8_t bejNnintEncodingSizeOfUInt(uint64_t val);
+
+    /**
+     * @brief Get the length field value of the unsigned value nnint encoding.
+     *
+     * @param val - unsigned value needed to encode.
+     * @return value of the length field in the encoded nnint.
+     */
+    uint8_t bejNnintLengthFieldOfUInt(uint64_t val);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/libbej/bej_decoder_core.h b/include/libbej/bej_decoder_core.h
index 044d691..5e226c1 100644
--- a/include/libbej/bej_decoder_core.h
+++ b/include/libbej/bej_decoder_core.h
@@ -40,13 +40,6 @@
         uint32_t streamEndOffset;
     };
 
-    struct BejDictionaries
-    {
-        const uint8_t* schemaDictionary;
-        const uint8_t* annotationDictionary;
-        const uint8_t* errorDictionary;
-    };
-
     /**
      * @brief Holds the information related to the current bejTuple being
      * decoded.
diff --git a/include/libbej/bej_encoder_core.h b/include/libbej/bej_encoder_core.h
new file mode 100644
index 0000000..6088eef
--- /dev/null
+++ b/include/libbej/bej_encoder_core.h
@@ -0,0 +1,51 @@
+#pragma once
+
+#include "bej_tree.h"
+
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define BEJ_VERSION 0xF1F0F000
+
+    /**
+     * @brief A struct for storing output information for the encoder.
+     */
+    struct BejEncoderOutputHandler
+    {
+        // A user provided context to be passed to the recvOutput() callback.
+        void* handlerContext;
+        // A callback function that will be invoked by the encoder whenever it
+        // has output data.
+        int (*recvOutput)(const void* data, size_t data_size,
+                          void* handlerContext);
+    };
+
+    /**
+     * @brief Perform BEJ encoding.
+     *
+     * @param dictionaries - dictionaries used for encoding.
+     * @param majorSchemaStartingOffset - starting dictionary offset for
+     * endcoding. Use BEJ_DICTIONARY_START_AT_HEAD to encode a complete
+     * resource. Use the correct offset when encoding a subsection of a redfish
+     * resource.
+     * @param schemaClass - schema class for the resource.
+     * @param root - root node of the resource to be encoded. Root node has to
+     * be a bejSet.
+     * @param output - An intialized BejEncoderOutputHandler struct.
+     * @param stack - An initialized BejPointerStackCallback struct.
+     * @return 0 if successful.
+     */
+    int bejEncode(const struct BejDictionaries* dictionaries,
+                  uint16_t majorSchemaStartingOffset,
+                  enum BejSchemaClass schemaClass,
+                  struct RedfishPropertyParent* root,
+                  struct BejEncoderOutputHandler* output,
+                  struct BejPointerStackCallback* stack);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/include/libbej/bej_encoder_metadata.h b/include/libbej/bej_encoder_metadata.h
new file mode 100644
index 0000000..55b6f10
--- /dev/null
+++ b/include/libbej/bej_encoder_metadata.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include "bej_common.h"
+#include "bej_tree.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+    /**
+     * @brief Update the node metadata used during encoding process.
+     *
+     * This function will visit the entire JSON tree and update metdata
+     * properties of each node.
+     *
+     * @param dictionaries - dictionaries used for encoding.
+     * @param majorSchemaStartingOffset - starting dictionary offset for
+     * endcoding. Use BEJ_DICTIONARY_START_AT_HEAD to encode a complete
+     * resource. Use the correct offset when encoding a subsection of a redfish
+     * resource.
+     * @param root - root node of the resource to be encoded. Root node has to
+     * be a bejSet.
+     * @param stack - An intialized BejEncoderOutputHandler struct.
+     * @return 0 if successful.
+     */
+    int bejUpdateNodeMetadata(const struct BejDictionaries* dictionaries,
+                              uint16_t majorSchemaStartingOffset,
+                              struct RedfishPropertyParent* root,
+                              struct BejPointerStackCallback* stack);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/include/libbej/bej_tree.h b/include/libbej/bej_tree.h
index 8250e85..5b502db 100644
--- a/include/libbej/bej_tree.h
+++ b/include/libbej/bej_tree.h
@@ -278,6 +278,20 @@
                                 bool deferredBinding, bool readOnlyProperty,
                                 bool nullableProperty);
 
+    /**
+     * @brief Get the next child node to be processed.
+     *
+     * This function returns the next child node of the parent node. This also
+     * updates the parent node's next child properties.
+     *
+     * @param parent - parent node.
+     * @param currentChild - current child node being processed.
+     * @return pointer to the next child node to be processed. NULL if there is
+     * no next child or one of the params are NULL.
+     */
+    void* bejParentGoToNextChild(struct RedfishPropertyParent* parent,
+                                 struct RedfishPropertyNode* currentChild);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/libbej/meson.build b/include/libbej/meson.build
index c2c834b..ba8afc5 100644
--- a/include/libbej/meson.build
+++ b/include/libbej/meson.build
@@ -2,7 +2,9 @@
   'bej_decoder_core.h',
   'bej_decoder_json.hpp',
   'bej_dictionary.h',
-  'bej_common.h'
+  'bej_common.h',
+  'bej_encoder_core.h',
+  'bej_encoder_metadata.h'
 )
 
 install_headers(
diff --git a/src/bej_common.c b/src/bej_common.c
index 1d3be07..0e1cf10 100644
--- a/src/bej_common.c
+++ b/src/bej_common.c
@@ -23,3 +23,22 @@
     // In nnint, first byte indicate how many bytes are there.
     return *nnint + sizeof(uint8_t);
 }
+
+uint8_t bejNnintEncodingSizeOfUInt(uint64_t val)
+{
+    uint8_t bytes = 0;
+    do
+    {
+        // Even if the value is 0, we need a byte for that.
+        ++bytes;
+        val = val >> 8;
+    } while (val != 0);
+    // Need 1 byte to add the nnint length.
+    return bytes + 1;
+}
+
+uint8_t bejNnintLengthFieldOfUInt(uint64_t val)
+{
+    // From the size of the encoded value, we need 1 byte for the length field.
+    return bejNnintEncodingSizeOfUInt(val) - 1;
+}
diff --git a/src/bej_decoder_core.c b/src/bej_decoder_core.c
index efed4fc..fe6dad6 100644
--- a/src/bej_decoder_core.c
+++ b/src/bej_decoder_core.c
@@ -30,21 +30,6 @@
     } while (0)
 
 /**
- * @brief Check a given varable is NULL. If it is NULL, this will return with
- * bejErrorNullParameter. If the variable is not NULL, this will will not
- * return.
- */
-#define NULL_CHECK(param, structStr)                                           \
-    do                                                                         \
-    {                                                                          \
-        if ((param) == NULL)                                                   \
-        {                                                                      \
-            fprintf(stderr, "nullCheck: %s cannot be null\n", structStr);      \
-            return bejErrorNullParameter;                                      \
-        }                                                                      \
-    } while (0)
-
-/**
  * @brief Get the integer value from BEJ byte stream.
  *
  * @param[in] bytes - valid pointer to a byte stream in little-endian format.
diff --git a/src/bej_encoder_core.c b/src/bej_encoder_core.c
new file mode 100644
index 0000000..e289032
--- /dev/null
+++ b/src/bej_encoder_core.c
@@ -0,0 +1,208 @@
+#include "bej_encoder_core.h"
+
+#include "bej_common.h"
+#include "bej_encoder_metadata.h"
+
+#include <stdio.h>
+#include <string.h>
+
+/**
+ * @brief Encode a unsigned value with nnint format.
+ */
+static int bejEncodeNnint(uint64_t value,
+                          struct BejEncoderOutputHandler* output)
+{
+    // The length of the value bytes in nnint.
+    uint8_t nnintLengthByte = bejNnintLengthFieldOfUInt(value);
+    RETURN_IF_IERROR(output->recvOutput(&nnintLengthByte, sizeof(uint8_t),
+                                        output->handlerContext));
+    // Write the nnint value bytes.
+    return output->recvOutput(&value, nnintLengthByte, output->handlerContext);
+}
+
+/**
+ * @brief Encode a BejTupleF type.
+ */
+static int bejEncodeFormat(const struct BejTupleF* format,
+                           struct BejEncoderOutputHandler* output)
+{
+    return output->recvOutput(format, sizeof(struct BejTupleF),
+                              output->handlerContext);
+}
+
+/**
+ * @brief Encode a BejSet or BejArray type.
+ */
+static int bejEncodeBejSetOrArray(struct RedfishPropertyParent* node,
+                                  struct BejEncoderOutputHandler* output)
+{
+    // Encode Sequence number.
+    RETURN_IF_IERROR(bejEncodeNnint(node->metaData.sequenceNumber, output));
+    // Add the format.
+    RETURN_IF_IERROR(bejEncodeFormat(&node->nodeAttr.format, output));
+    // Encode the value length.
+    RETURN_IF_IERROR(bejEncodeNnint(node->metaData.vSize, output));
+    // Encode the child count
+    return bejEncodeNnint(node->nChildren, output);
+}
+
+/**
+ * @brief Encode the provided node.
+ */
+static int bejEncodeNode(void* node, struct BejEncoderOutputHandler* output)
+{
+    struct RedfishPropertyNode* nodeInfo = node;
+    switch (nodeInfo->format.principalDataType)
+    {
+        case bejSet:
+            RETURN_IF_IERROR(bejEncodeBejSetOrArray(node, output));
+            break;
+        default:
+            fprintf(stderr, "Unsupported node type: %d\n",
+                    nodeInfo->format.principalDataType);
+            return -1;
+    }
+    return 0;
+}
+
+/**
+ * @brief A helper function to add a parent to the stack.
+ */
+static int bejPushParentToStack(struct RedfishPropertyParent* parent,
+                                struct BejPointerStackCallback* stack)
+{
+    // Before pushing the parent node, initialize its nextChild as the first
+    // child.
+    parent->metaData.nextChild = parent->firstChild;
+    return stack->stackPush(parent, stack->stackContext);
+}
+
+/**
+ * @brief Process all the child nodes of a parent.
+ */
+static int bejProcessChildNodes(struct RedfishPropertyParent* parent,
+                                struct BejPointerStackCallback* stack,
+                                struct BejEncoderOutputHandler* output)
+{
+    // Get the next child of the parent.
+    void* childPtr = parent->metaData.nextChild;
+
+    while (childPtr != NULL)
+    {
+        // First encode the current child node.
+        RETURN_IF_IERROR(bejEncodeNode(childPtr, output));
+        // If this child node has its own children, add it to the stack and
+        // return. Because we need to encode the children of the newly added
+        // node before continuing to encode the child nodes of the current
+        // parent.
+        if (bejTreeIsParentType(childPtr))
+        {
+            RETURN_IF_IERROR(bejPushParentToStack(childPtr, stack));
+            // Update the next child of the current parent we need to
+            // process.
+            bejParentGoToNextChild(parent, childPtr);
+            return 0;
+        }
+        childPtr = bejParentGoToNextChild(parent, childPtr);
+    }
+    return 0;
+}
+
+/**
+ * @brief Encode the provided JSON tree.
+ *
+ * The node metadata should be initialized before using this function.
+ */
+static int bejEncodeTree(struct RedfishPropertyParent* root,
+                         struct BejPointerStackCallback* stack,
+                         struct BejEncoderOutputHandler* output)
+{
+    // We need to encode a parent node before its child nodes. So encoding the
+    // root first.
+    RETURN_IF_IERROR(bejEncodeNode(root, output));
+    // Once the root is encoded, push it to the stack used to traverse the child
+    // nodes. We need to keep a parent in this stack until all the child nodes
+    // of this parent has been encoded. Only then we remove the parent node from
+    // the stack.
+    RETURN_IF_IERROR(bejPushParentToStack(root, stack));
+
+    while (!stack->stackEmpty(stack->stackContext))
+    {
+        struct RedfishPropertyParent* parent =
+            stack->stackPeek(stack->stackContext);
+
+        // Encode all the child nodes of the current parent node. If one of
+        // these child nodes has its own child nodes, that child node will be
+        // encoded and added to the stack and this function will return. The
+        // rest of the children of the current parent will be encoded later
+        // (after processing all the nodes under the child node added to the
+        // stack).
+        RETURN_IF_IERROR(bejProcessChildNodes(parent, stack, output));
+
+        // If a new node hasn't been added to the stack by
+        // bejProcessChildNodes(), we know that this parent's child nodes have
+        // been processed. If a new node has been added, then next we need to
+        // process the children of the newly added node.
+        if (parent != stack->stackPeek(stack->stackContext))
+        {
+            continue;
+        }
+        stack->stackPop(stack->stackContext);
+    }
+    return 0;
+}
+
+int bejEncode(const struct BejDictionaries* dictionaries,
+              uint16_t majorSchemaStartingOffset,
+              enum BejSchemaClass schemaClass,
+              struct RedfishPropertyParent* root,
+              struct BejEncoderOutputHandler* output,
+              struct BejPointerStackCallback* stack)
+{
+    NULL_CHECK(dictionaries, "dictionaries");
+    NULL_CHECK(dictionaries->schemaDictionary, "schemaDictionary");
+    NULL_CHECK(dictionaries->annotationDictionary, "annotationDictionary");
+
+    NULL_CHECK(root, "root");
+
+    NULL_CHECK(output, "output");
+    NULL_CHECK(stack, "stack");
+
+    // Assert root node.
+    if (root->nodeAttr.format.principalDataType != bejSet)
+    {
+        fprintf(stderr, "Invalid root node\n");
+        return -1;
+    }
+
+    // First we need to encode a parent node before its child nodes. But before
+    // encoding the parent node, the encoder has to figure out the total size
+    // need to encode the parent's child nodes. Therefore first the encoder need
+    // to visit the child nodes and calculate the size need to encode them
+    // before producing the encoded bytes for the parent node.
+    //
+    // So first the encoder will visit child nodes and calculate the size need
+    // to encode each child node. Then store this information in metadata
+    // properties in each node struct.
+    // Next the encoder will again visit each node starting from the parent
+    // node, and produce the encoded bytes.
+
+    // First calculate metadata for encoding each node.
+    RETURN_IF_IERROR(bejUpdateNodeMetadata(
+        dictionaries, majorSchemaStartingOffset, root, stack));
+
+    // Derive the header of the encoded output.
+    // BEJ version
+    uint32_t version = BEJ_VERSION;
+    RETURN_IF_IERROR(
+        output->recvOutput(&version, sizeof(uint32_t), output->handlerContext));
+    uint16_t reserved = 0;
+    RETURN_IF_IERROR(output->recvOutput(&reserved, sizeof(uint16_t),
+                                        output->handlerContext));
+    RETURN_IF_IERROR(output->recvOutput(&schemaClass, sizeof(uint8_t),
+                                        output->handlerContext));
+
+    // Produce the encoded bytes for the nodes using the previously calculated
+    // metadata.
+    return bejEncodeTree(root, stack, output);
+}
diff --git a/src/bej_encoder_metadata.c b/src/bej_encoder_metadata.c
new file mode 100644
index 0000000..16264c1
--- /dev/null
+++ b/src/bej_encoder_metadata.c
@@ -0,0 +1,192 @@
+#include "bej_encoder_metadata.h"
+
+#include "bej_common.h"
+#include "bej_dictionary.h"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+/**
+ * @brief Update metadata of leaf nodes.
+ *
+ * @param dictionaries - dictionaries needed for encoding.
+ * @param parentDictionary - dictionary used by this node's parent.
+ * @param childPtr - a pointer to the leaf node.
+ * @param childIndex - if this node is an array element, this is the array
+ * index.
+ * @param dictStartingOffset - starting dictionary child offset value of this
+ * node's parent.
+ * @return 0 if successful.
+ */
+static int bejUpdateLeafNodeMetaData(const struct BejDictionaries* dictionaries,
+                                     const uint8_t* parentDictionary,
+                                     void* childPtr, uint16_t childIndex,
+                                     uint16_t dictStartingOffset)
+{
+    // TODO: Implement this
+    (void)dictionaries;
+    (void)parentDictionary;
+    (void)childIndex;
+    (void)dictStartingOffset;
+
+    struct RedfishPropertyLeaf* chNode = childPtr;
+    switch (chNode->nodeAttr.format.principalDataType)
+    {
+        default:
+            fprintf(stderr, "Child type %u not supported\n",
+                    chNode->nodeAttr.format.principalDataType);
+            return -1;
+    }
+    return 0;
+}
+
+/**
+ * @brief Update metadata of a parent node.
+ *
+ * @param dictionaries - dictionaries needed for encoding.
+ * @param parentDictionary - dictionary used by this node's parent.
+ * @param dictStartingOffset - starting dictionary child offset value of this
+ * node's parent.
+ * @param node - a pointer to the parent node.
+ * @param nodeIndex - If this node is an array element, this is the array index.
+ * @return 0 if successful.
+ */
+static int bejUpdateParentMetaData(const struct BejDictionaries* dictionaries,
+                                   const uint8_t* parentDictionary,
+                                   uint16_t dictStartingOffset,
+                                   struct RedfishPropertyParent* node,
+                                   uint16_t nodeIndex)
+{
+    // TODO: Implement this
+    (void)dictionaries;
+    (void)parentDictionary;
+    (void)dictStartingOffset;
+    (void)node;
+    (void)nodeIndex;
+
+    return -1;
+}
+
+/**
+ * @brief Update metadata of child nodes.
+ *
+ * If a child node contains its own child nodes, it will be added to the stack
+ * and function will return.
+ *
+ * @param dictionaries - dictionaries needed for encoding.
+ * @param parent - parent node.
+ * @param stack - stack holding parent nodes.
+ * @return 0 if successful.
+ */
+static int bejProcessChildNodes(const struct BejDictionaries* dictionaries,
+                                struct RedfishPropertyParent* parent,
+                                struct BejPointerStackCallback* stack)
+{
+    // Get the next child of the parent.
+    void* childPtr = parent->metaData.nextChild;
+
+    // Process all the children belongs to the parent.
+    while (childPtr != NULL)
+    {
+        // If we find a child with its own child nodes, add it to the stack and
+        // return.
+        if (bejTreeIsParentType(childPtr))
+        {
+            RETURN_IF_IERROR(bejUpdateParentMetaData(
+                dictionaries, parent->metaData.dictionary,
+                parent->metaData.childrenDictPropOffset, childPtr,
+                parent->metaData.nextChildIndex));
+
+            RETURN_IF_IERROR(stack->stackPush(childPtr, stack->stackContext));
+            bejParentGoToNextChild(parent, childPtr);
+            return 0;
+        }
+
+        RETURN_IF_IERROR(
+            bejUpdateLeafNodeMetaData(dictionaries, parent->metaData.dictionary,
+                                      childPtr, parent->metaData.nextChildIndex,
+                                      parent->metaData.childrenDictPropOffset));
+        // Use the child value size to update the parent value size.
+        struct RedfishPropertyLeaf* leafChild = childPtr;
+        // V: Include the child size in parent's value size.
+        parent->metaData.vSize +=
+            (leafChild->metaData.sflSize + leafChild->metaData.vSize);
+
+        // Get the next child belongs to the parent.
+        childPtr = bejParentGoToNextChild(parent, childPtr);
+    }
+    return 0;
+}
+
+int bejUpdateNodeMetadata(const struct BejDictionaries* dictionaries,
+                          uint16_t majorSchemaStartingOffset,
+                          struct RedfishPropertyParent* root,
+                          struct BejPointerStackCallback* stack)
+{
+    // Decide the starting property offset of the dictionary.
+    uint16_t dictOffset = bejDictGetPropertyHeadOffset();
+    if (majorSchemaStartingOffset != BEJ_DICTIONARY_START_AT_HEAD)
+    {
+        dictOffset = majorSchemaStartingOffset;
+    }
+
+    // Initialize root node metadata.
+    RETURN_IF_IERROR(
+        bejUpdateParentMetaData(dictionaries, dictionaries->schemaDictionary,
+                                dictOffset, root, /*childIndex=*/0));
+
+    // Push the root to the stack. Because we are not done with the parent node
+    // yet. Need to figure out all bytes need to encode children of this parent,
+    // and save it in the parent metadata.
+    RETURN_IF_IERROR(stack->stackPush(root, stack->stackContext));
+
+    while (!stack->stackEmpty(stack->stackContext))
+    {
+        // Get the parent at the top of the stack. Stack is only popped if the
+        // parent stack entry has no pending children; That is
+        // parent->metaData.nextChild == NULL.
+        struct RedfishPropertyParent* parent =
+            stack->stackPeek(stack->stackContext);
+
+        // Calculate metadata of all the child nodes of the current parent node.
+        // If one of these child nodes has its own child nodes, that child node
+        // will be added to the stack and this function will return.
+        RETURN_IF_IERROR(bejProcessChildNodes(dictionaries, parent, stack));
+
+        // If a new node hasn't been added to the stack, we know that this
+        // parent's child nodes have been processed. If not, do not pop the
+        // stack.
+        if (parent != stack->stackPeek(stack->stackContext))
+        {
+            continue;
+        }
+
+        // If we are here;
+        // Then "parent" is the top element of the stack.
+        // All the children of "parent" has been processed.
+
+        // Remove the "parent" from the stack.
+        parent = stack->stackPop(stack->stackContext);
+        // L: Add the length needed to store the number of bytes used for the
+        // parent's value.
+        parent->metaData.sflSize +=
+            bejNnintEncodingSizeOfUInt(parent->metaData.vSize);
+
+        // Since we now know the total size needs to encode the node pointed by
+        // "parent" variable, we should add that to the value size of this
+        // node's parent. Since we already popped this node from the stack, top
+        // of the stack element is this nodes's parent. "parentsParent" can be
+        // NULL if the node pointed by "parent" variable is the root.
+        struct RedfishPropertyParent* parentsParent =
+            stack->stackPeek(stack->stackContext);
+        if (parentsParent != NULL)
+        {
+            // V: Include the total size to encode the current parent in its
+            // parent's value size.
+            parentsParent->metaData.vSize +=
+                (parent->metaData.sflSize + parent->metaData.vSize);
+        }
+    }
+    return 0;
+}
diff --git a/src/bej_tree.c b/src/bej_tree.c
index 6bec216..53511eb 100644
--- a/src/bej_tree.c
+++ b/src/bej_tree.c
@@ -128,3 +128,16 @@
     node->format.readOnlyProperty = readOnlyProperty;
     node->format.nullableProperty = nullableProperty;
 }
+
+void* bejParentGoToNextChild(struct RedfishPropertyParent* parent,
+                             struct RedfishPropertyNode* currentChild)
+{
+    if (parent == NULL || currentChild == NULL)
+    {
+        return NULL;
+    }
+
+    parent->metaData.nextChildIndex += 1;
+    parent->metaData.nextChild = currentChild->sibling;
+    return currentChild->sibling;
+}
diff --git a/src/meson.build b/src/meson.build
index 051b397..4876d80 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -4,6 +4,8 @@
   'bej_common.c',
   'bej_dictionary.c',
   'bej_tree.c',
+  'bej_encoder_core.c',
+  'bej_encoder_metadata.c',
   'bej_decoder_json.cpp',
   include_directories : libbej_incs,
   implicit_include_directories: false,