Add libbej encoder wrapper for C++

Add unit tests and the test data files needed for unit tests.
Move APIs from bej_decoder_test.cpp to a common file, to share those
with bej_encoder_test.cpp

Tested:
Verified that encoding using the wrapper works well at runtime.
Verified that the unit tests pass.

Change-Id: I61b7c17690eb7e7fefd1973a22d4316c6214267e
Signed-off-by: Nikhil Namjoshi <nikhilnamjoshi@google.com>
diff --git a/src/bej_encoder_json.cpp b/src/bej_encoder_json.cpp
new file mode 100644
index 0000000..8117f76
--- /dev/null
+++ b/src/bej_encoder_json.cpp
@@ -0,0 +1,80 @@
+#include "bej_encoder_json.hpp"
+
+namespace libbej
+{
+
+bool stackEmpty(void* dataPtr)
+{
+    return (reinterpret_cast<std::vector<void*>*>(dataPtr))->empty();
+}
+
+void* stackPeek(void* dataPtr)
+{
+    auto stack = reinterpret_cast<std::vector<void*>*>(dataPtr);
+    if (stack->empty())
+    {
+        return nullptr;
+    }
+    return stack->back();
+}
+
+void* stackPop(void* dataPtr)
+{
+    auto stack = reinterpret_cast<std::vector<void*>*>(dataPtr);
+    if (stack->empty())
+    {
+        return nullptr;
+    }
+    void* value = stack->back();
+    stack->pop_back();
+    return value;
+}
+
+int stackPush(void* property, void* dataPtr)
+{
+    auto stack = reinterpret_cast<std::vector<void*>*>(dataPtr);
+    stack->emplace_back(property);
+    return 0;
+}
+
+int getBejEncodedBuffer(const void* data, size_t dataSize, void* handlerContext)
+{
+    auto stack = reinterpret_cast<std::vector<uint8_t>*>(handlerContext);
+    const uint8_t* dataBuf = reinterpret_cast<const uint8_t*>(data);
+    stack->insert(stack->end(), dataBuf, dataBuf + dataSize);
+    return 0;
+}
+
+std::vector<uint8_t> BejEncoderJson::getOutput()
+{
+    std::vector<uint8_t> currentEncodedPayload = std::move(encodedPayload);
+    // Re-Initialize encodedPayload with empty vector to be used again for
+    // next encoding
+    encodedPayload = {};
+
+    return currentEncodedPayload;
+}
+
+int BejEncoderJson::encode(const struct BejDictionaries* dictionaries,
+                           enum BejSchemaClass schemaClass,
+                           struct RedfishPropertyParent* root)
+{
+    struct BejEncoderOutputHandler output = {
+        .handlerContext = &encodedPayload,
+        .recvOutput = &getBejEncodedBuffer,
+    };
+
+    struct BejPointerStackCallback stackCallbacks = {
+        .stackContext = &stack,
+        .stackEmpty = stackEmpty,
+        .stackPeek = stackPeek,
+        .stackPop = stackPop,
+        .stackPush = stackPush,
+        .deleteStack = nullptr,
+    };
+
+    return bejEncode(dictionaries, BEJ_DICTIONARY_START_AT_HEAD, schemaClass,
+                     root, &output, &stackCallbacks);
+}
+
+} // namespace libbej