199bd6c90Skasunath #include "bej_encoder_core.h"
299bd6c90Skasunath
399bd6c90Skasunath #include "bej_common.h"
499bd6c90Skasunath #include "bej_encoder_metadata.h"
599bd6c90Skasunath
699bd6c90Skasunath #include <stdio.h>
799bd6c90Skasunath #include <string.h>
899bd6c90Skasunath
999bd6c90Skasunath /**
1099bd6c90Skasunath * @brief Encode a unsigned value with nnint format.
1199bd6c90Skasunath */
bejEncodeNnint(uint64_t value,struct BejEncoderOutputHandler * output)1299bd6c90Skasunath static int bejEncodeNnint(uint64_t value,
1399bd6c90Skasunath struct BejEncoderOutputHandler* output)
1499bd6c90Skasunath {
1599bd6c90Skasunath // The length of the value bytes in nnint.
1699bd6c90Skasunath uint8_t nnintLengthByte = bejNnintLengthFieldOfUInt(value);
1799bd6c90Skasunath RETURN_IF_IERROR(output->recvOutput(&nnintLengthByte, sizeof(uint8_t),
1899bd6c90Skasunath output->handlerContext));
1999bd6c90Skasunath // Write the nnint value bytes.
2099bd6c90Skasunath return output->recvOutput(&value, nnintLengthByte, output->handlerContext);
2199bd6c90Skasunath }
2299bd6c90Skasunath
2399bd6c90Skasunath /**
2499bd6c90Skasunath * @brief Encode a BejTupleF type.
2599bd6c90Skasunath */
bejEncodeFormat(const struct BejTupleF * format,struct BejEncoderOutputHandler * output)2699bd6c90Skasunath static int bejEncodeFormat(const struct BejTupleF* format,
2799bd6c90Skasunath struct BejEncoderOutputHandler* output)
2899bd6c90Skasunath {
2999bd6c90Skasunath return output->recvOutput(format, sizeof(struct BejTupleF),
3099bd6c90Skasunath output->handlerContext);
3199bd6c90Skasunath }
3299bd6c90Skasunath
3399bd6c90Skasunath /**
3499bd6c90Skasunath * @brief Encode a BejSet or BejArray type.
3599bd6c90Skasunath */
bejEncodeBejSetOrArray(struct RedfishPropertyParent * node,struct BejEncoderOutputHandler * output)3699bd6c90Skasunath static int bejEncodeBejSetOrArray(struct RedfishPropertyParent* node,
3799bd6c90Skasunath struct BejEncoderOutputHandler* output)
3899bd6c90Skasunath {
3999bd6c90Skasunath // Encode Sequence number.
4099bd6c90Skasunath RETURN_IF_IERROR(bejEncodeNnint(node->metaData.sequenceNumber, output));
4199bd6c90Skasunath // Add the format.
4299bd6c90Skasunath RETURN_IF_IERROR(bejEncodeFormat(&node->nodeAttr.format, output));
4399bd6c90Skasunath // Encode the value length.
4499bd6c90Skasunath RETURN_IF_IERROR(bejEncodeNnint(node->metaData.vSize, output));
4599bd6c90Skasunath // Encode the child count
4699bd6c90Skasunath return bejEncodeNnint(node->nChildren, output);
4799bd6c90Skasunath }
4899bd6c90Skasunath
4999bd6c90Skasunath /**
500a29193fSkasunath * @brief Encode an integer to bejInteger type.
510a29193fSkasunath */
bejEncodeInteger(int64_t val,struct BejEncoderOutputHandler * output)520a29193fSkasunath static uint8_t bejEncodeInteger(int64_t val,
530a29193fSkasunath struct BejEncoderOutputHandler* output)
540a29193fSkasunath {
550a29193fSkasunath uint8_t copyLength = bejIntLengthOfValue(val);
560a29193fSkasunath return output->recvOutput(&val, copyLength, output->handlerContext);
570a29193fSkasunath }
580a29193fSkasunath
590a29193fSkasunath /**
600a29193fSkasunath * @brief Encode a BejInteger type.
610a29193fSkasunath */
bejEncodeBejInteger(struct RedfishPropertyLeafInt * node,struct BejEncoderOutputHandler * output)620a29193fSkasunath int bejEncodeBejInteger(struct RedfishPropertyLeafInt* node,
630a29193fSkasunath struct BejEncoderOutputHandler* output)
640a29193fSkasunath {
650a29193fSkasunath // Encode Sequence number.
660a29193fSkasunath RETURN_IF_IERROR(
670a29193fSkasunath bejEncodeNnint(node->leaf.metaData.sequenceNumber, output));
680a29193fSkasunath // Add the format.
690a29193fSkasunath RETURN_IF_IERROR(bejEncodeFormat(&node->leaf.nodeAttr.format, output));
700a29193fSkasunath // Encode the value length.
710a29193fSkasunath RETURN_IF_IERROR(bejEncodeNnint(node->leaf.metaData.vSize, output));
720a29193fSkasunath // Encode the value.
730a29193fSkasunath return bejEncodeInteger(node->value, output);
740a29193fSkasunath }
750a29193fSkasunath
760a29193fSkasunath /**
770a29193fSkasunath * @brief Encode a BejEnum type.
780a29193fSkasunath */
bejEncodeBejEnum(struct RedfishPropertyLeafEnum * node,struct BejEncoderOutputHandler * output)790a29193fSkasunath int bejEncodeBejEnum(struct RedfishPropertyLeafEnum* node,
800a29193fSkasunath struct BejEncoderOutputHandler* output)
810a29193fSkasunath {
820a29193fSkasunath // S: Encode Sequence number.
830a29193fSkasunath RETURN_IF_IERROR(
840a29193fSkasunath bejEncodeNnint(node->leaf.metaData.sequenceNumber, output));
850a29193fSkasunath // F: Add the format.
860a29193fSkasunath RETURN_IF_IERROR(bejEncodeFormat(&node->leaf.nodeAttr.format, output));
870a29193fSkasunath // L: Encode the value length.
880a29193fSkasunath RETURN_IF_IERROR(bejEncodeNnint(node->leaf.metaData.vSize, output));
890a29193fSkasunath // V: Encode the value.
900a29193fSkasunath return bejEncodeNnint(node->enumValueSeq, output);
910a29193fSkasunath }
920a29193fSkasunath
bejEncodeBejString(struct RedfishPropertyLeafString * node,struct BejEncoderOutputHandler * output)93*6df0c486Skasunath int bejEncodeBejString(struct RedfishPropertyLeafString* node,
94*6df0c486Skasunath struct BejEncoderOutputHandler* output)
95*6df0c486Skasunath {
96*6df0c486Skasunath // S: Encode Sequence number.
97*6df0c486Skasunath RETURN_IF_IERROR(
98*6df0c486Skasunath bejEncodeNnint(node->leaf.metaData.sequenceNumber, output));
99*6df0c486Skasunath // F: Add the format.
100*6df0c486Skasunath RETURN_IF_IERROR(bejEncodeFormat(&node->leaf.nodeAttr.format, output));
101*6df0c486Skasunath // L: Encode the value length.
102*6df0c486Skasunath RETURN_IF_IERROR(bejEncodeNnint(node->leaf.metaData.vSize, output));
103*6df0c486Skasunath // V: Encode the value.
104*6df0c486Skasunath return output->recvOutput((void*)node->value, node->leaf.metaData.vSize,
105*6df0c486Skasunath output->handlerContext);
106*6df0c486Skasunath }
107*6df0c486Skasunath
bejEncodeBejReal(struct RedfishPropertyLeafReal * node,struct BejEncoderOutputHandler * output)108*6df0c486Skasunath int bejEncodeBejReal(struct RedfishPropertyLeafReal* node,
109*6df0c486Skasunath struct BejEncoderOutputHandler* output)
110*6df0c486Skasunath {
111*6df0c486Skasunath // S: Encode Sequence number.
112*6df0c486Skasunath RETURN_IF_IERROR(
113*6df0c486Skasunath bejEncodeNnint(node->leaf.metaData.sequenceNumber, output));
114*6df0c486Skasunath // F: Add the format.
115*6df0c486Skasunath RETURN_IF_IERROR(bejEncodeFormat(&node->leaf.nodeAttr.format, output));
116*6df0c486Skasunath // L: Encode the value length.
117*6df0c486Skasunath RETURN_IF_IERROR(bejEncodeNnint(node->leaf.metaData.vSize, output));
118*6df0c486Skasunath // V: Encode the value.
119*6df0c486Skasunath // Length of the "whole" value as nnint.
120*6df0c486Skasunath RETURN_IF_IERROR(
121*6df0c486Skasunath bejEncodeNnint(bejIntLengthOfValue(node->bejReal.whole), output));
122*6df0c486Skasunath // Add the "whole" value.
123*6df0c486Skasunath RETURN_IF_IERROR(bejEncodeInteger(node->bejReal.whole, output));
124*6df0c486Skasunath // Leading zero count as a nnint.
125*6df0c486Skasunath RETURN_IF_IERROR(bejEncodeNnint(node->bejReal.zeroCount, output));
126*6df0c486Skasunath // Fraction as a nnint.
127*6df0c486Skasunath RETURN_IF_IERROR(bejEncodeNnint(node->bejReal.fract, output));
128*6df0c486Skasunath // Exp length as a nnint.
129*6df0c486Skasunath RETURN_IF_IERROR(bejEncodeNnint(node->bejReal.expLen, output));
130*6df0c486Skasunath if (node->bejReal.expLen > 0)
131*6df0c486Skasunath {
132*6df0c486Skasunath // Exp length as a nnint.
133*6df0c486Skasunath RETURN_IF_IERROR(bejEncodeNnint(node->bejReal.expLen, output));
134*6df0c486Skasunath RETURN_IF_IERROR(bejEncodeInteger(node->bejReal.exp, output));
135*6df0c486Skasunath }
136*6df0c486Skasunath return 0;
137*6df0c486Skasunath }
138*6df0c486Skasunath
bejEncodeBejBool(struct RedfishPropertyLeafBool * node,struct BejEncoderOutputHandler * output)139*6df0c486Skasunath int bejEncodeBejBool(struct RedfishPropertyLeafBool* node,
140*6df0c486Skasunath struct BejEncoderOutputHandler* output)
141*6df0c486Skasunath {
142*6df0c486Skasunath // S: Encode Sequence number.
143*6df0c486Skasunath RETURN_IF_IERROR(
144*6df0c486Skasunath bejEncodeNnint(node->leaf.metaData.sequenceNumber, output));
145*6df0c486Skasunath // F: Add the format.
146*6df0c486Skasunath RETURN_IF_IERROR(bejEncodeFormat(&node->leaf.nodeAttr.format, output));
147*6df0c486Skasunath // L: Encode the value length.
148*6df0c486Skasunath RETURN_IF_IERROR(bejEncodeNnint(node->leaf.metaData.vSize, output));
149*6df0c486Skasunath // V: Encode the value.
150*6df0c486Skasunath uint8_t value = node->value ? 0xFF : 0x00;
151*6df0c486Skasunath return output->recvOutput(&value, /*data_size=*/sizeof(uint8_t),
152*6df0c486Skasunath output->handlerContext);
153*6df0c486Skasunath }
154*6df0c486Skasunath
bejEncodeBejProAnno(struct RedfishPropertyParent * node,struct BejEncoderOutputHandler * output)155*6df0c486Skasunath int bejEncodeBejProAnno(struct RedfishPropertyParent* node,
156*6df0c486Skasunath struct BejEncoderOutputHandler* output)
157*6df0c486Skasunath {
158*6df0c486Skasunath // Encode Sequence number.
159*6df0c486Skasunath RETURN_IF_IERROR(bejEncodeNnint(node->metaData.sequenceNumber, output));
160*6df0c486Skasunath // Add the format.
161*6df0c486Skasunath RETURN_IF_IERROR(bejEncodeFormat(&node->nodeAttr.format, output));
162*6df0c486Skasunath // Encode the value length.
163*6df0c486Skasunath return bejEncodeNnint(node->metaData.vSize, output);
164*6df0c486Skasunath }
165*6df0c486Skasunath
1660a29193fSkasunath /**
1670a29193fSkasunath * @brief Encode a BejNull type.
1680a29193fSkasunath */
bejEncodeBejNull(struct RedfishPropertyLeafNull * node,struct BejEncoderOutputHandler * output)1690a29193fSkasunath int bejEncodeBejNull(struct RedfishPropertyLeafNull* node,
1700a29193fSkasunath struct BejEncoderOutputHandler* output)
1710a29193fSkasunath {
1720a29193fSkasunath // S: Encode Sequence number.
1730a29193fSkasunath RETURN_IF_IERROR(
1740a29193fSkasunath bejEncodeNnint(node->leaf.metaData.sequenceNumber, output));
1750a29193fSkasunath // F: Add the format.
1760a29193fSkasunath RETURN_IF_IERROR(bejEncodeFormat(&node->leaf.nodeAttr.format, output));
1770a29193fSkasunath // L: Encode the value length.
1780a29193fSkasunath return bejEncodeNnint(node->leaf.metaData.vSize, output);
1790a29193fSkasunath }
1800a29193fSkasunath
1810a29193fSkasunath /**
18299bd6c90Skasunath * @brief Encode the provided node.
18399bd6c90Skasunath */
bejEncodeNode(void * node,struct BejEncoderOutputHandler * output)18499bd6c90Skasunath static int bejEncodeNode(void* node, struct BejEncoderOutputHandler* output)
18599bd6c90Skasunath {
18699bd6c90Skasunath struct RedfishPropertyNode* nodeInfo = node;
18799bd6c90Skasunath switch (nodeInfo->format.principalDataType)
18899bd6c90Skasunath {
18999bd6c90Skasunath case bejSet:
19099bd6c90Skasunath RETURN_IF_IERROR(bejEncodeBejSetOrArray(node, output));
19199bd6c90Skasunath break;
1920a29193fSkasunath case bejArray:
1930a29193fSkasunath RETURN_IF_IERROR(bejEncodeBejSetOrArray(node, output));
1940a29193fSkasunath break;
1950a29193fSkasunath case bejNull:
1960a29193fSkasunath RETURN_IF_IERROR(bejEncodeBejNull(node, output));
1970a29193fSkasunath break;
1980a29193fSkasunath case bejInteger:
1990a29193fSkasunath RETURN_IF_IERROR(bejEncodeBejInteger(node, output));
2000a29193fSkasunath break;
2010a29193fSkasunath case bejEnum:
2020a29193fSkasunath RETURN_IF_IERROR(bejEncodeBejEnum(node, output));
2030a29193fSkasunath break;
204*6df0c486Skasunath case bejString:
205*6df0c486Skasunath RETURN_IF_IERROR(bejEncodeBejString(node, output));
206*6df0c486Skasunath break;
207*6df0c486Skasunath case bejReal:
208*6df0c486Skasunath RETURN_IF_IERROR(bejEncodeBejReal(node, output));
209*6df0c486Skasunath break;
210*6df0c486Skasunath case bejBoolean:
211*6df0c486Skasunath RETURN_IF_IERROR(bejEncodeBejBool(node, output));
212*6df0c486Skasunath break;
213*6df0c486Skasunath case bejPropertyAnnotation:
214*6df0c486Skasunath RETURN_IF_IERROR(bejEncodeBejProAnno(node, output));
215*6df0c486Skasunath break;
21699bd6c90Skasunath default:
21799bd6c90Skasunath fprintf(stderr, "Unsupported node type: %d\n",
21899bd6c90Skasunath nodeInfo->format.principalDataType);
21999bd6c90Skasunath return -1;
22099bd6c90Skasunath }
22199bd6c90Skasunath return 0;
22299bd6c90Skasunath }
22399bd6c90Skasunath
22499bd6c90Skasunath /**
22599bd6c90Skasunath * @brief A helper function to add a parent to the stack.
22699bd6c90Skasunath */
bejPushParentToStack(struct RedfishPropertyParent * parent,struct BejPointerStackCallback * stack)22799bd6c90Skasunath static int bejPushParentToStack(struct RedfishPropertyParent* parent,
22899bd6c90Skasunath struct BejPointerStackCallback* stack)
22999bd6c90Skasunath {
23099bd6c90Skasunath // Before pushing the parent node, initialize its nextChild as the first
23199bd6c90Skasunath // child.
23299bd6c90Skasunath parent->metaData.nextChild = parent->firstChild;
23399bd6c90Skasunath return stack->stackPush(parent, stack->stackContext);
23499bd6c90Skasunath }
23599bd6c90Skasunath
23699bd6c90Skasunath /**
23799bd6c90Skasunath * @brief Process all the child nodes of a parent.
23899bd6c90Skasunath */
bejProcessChildNodes(struct RedfishPropertyParent * parent,struct BejPointerStackCallback * stack,struct BejEncoderOutputHandler * output)23999bd6c90Skasunath static int bejProcessChildNodes(struct RedfishPropertyParent* parent,
24099bd6c90Skasunath struct BejPointerStackCallback* stack,
24199bd6c90Skasunath struct BejEncoderOutputHandler* output)
24299bd6c90Skasunath {
24399bd6c90Skasunath // Get the next child of the parent.
24499bd6c90Skasunath void* childPtr = parent->metaData.nextChild;
24599bd6c90Skasunath
24699bd6c90Skasunath while (childPtr != NULL)
24799bd6c90Skasunath {
24899bd6c90Skasunath // First encode the current child node.
24999bd6c90Skasunath RETURN_IF_IERROR(bejEncodeNode(childPtr, output));
25099bd6c90Skasunath // If this child node has its own children, add it to the stack and
25199bd6c90Skasunath // return. Because we need to encode the children of the newly added
25299bd6c90Skasunath // node before continuing to encode the child nodes of the current
25399bd6c90Skasunath // parent.
25499bd6c90Skasunath if (bejTreeIsParentType(childPtr))
25599bd6c90Skasunath {
25699bd6c90Skasunath RETURN_IF_IERROR(bejPushParentToStack(childPtr, stack));
25799bd6c90Skasunath // Update the next child of the current parent we need to
25899bd6c90Skasunath // process.
25999bd6c90Skasunath bejParentGoToNextChild(parent, childPtr);
26099bd6c90Skasunath return 0;
26199bd6c90Skasunath }
26299bd6c90Skasunath childPtr = bejParentGoToNextChild(parent, childPtr);
26399bd6c90Skasunath }
26499bd6c90Skasunath return 0;
26599bd6c90Skasunath }
26699bd6c90Skasunath
26799bd6c90Skasunath /**
26899bd6c90Skasunath * @brief Encode the provided JSON tree.
26999bd6c90Skasunath *
27099bd6c90Skasunath * The node metadata should be initialized before using this function.
27199bd6c90Skasunath */
bejEncodeTree(struct RedfishPropertyParent * root,struct BejPointerStackCallback * stack,struct BejEncoderOutputHandler * output)27299bd6c90Skasunath static int bejEncodeTree(struct RedfishPropertyParent* root,
27399bd6c90Skasunath struct BejPointerStackCallback* stack,
27499bd6c90Skasunath struct BejEncoderOutputHandler* output)
27599bd6c90Skasunath {
27699bd6c90Skasunath // We need to encode a parent node before its child nodes. So encoding the
27799bd6c90Skasunath // root first.
27899bd6c90Skasunath RETURN_IF_IERROR(bejEncodeNode(root, output));
27999bd6c90Skasunath // Once the root is encoded, push it to the stack used to traverse the child
28099bd6c90Skasunath // nodes. We need to keep a parent in this stack until all the child nodes
28199bd6c90Skasunath // of this parent has been encoded. Only then we remove the parent node from
28299bd6c90Skasunath // the stack.
28399bd6c90Skasunath RETURN_IF_IERROR(bejPushParentToStack(root, stack));
28499bd6c90Skasunath
28599bd6c90Skasunath while (!stack->stackEmpty(stack->stackContext))
28699bd6c90Skasunath {
28799bd6c90Skasunath struct RedfishPropertyParent* parent =
28899bd6c90Skasunath stack->stackPeek(stack->stackContext);
28999bd6c90Skasunath
29099bd6c90Skasunath // Encode all the child nodes of the current parent node. If one of
29199bd6c90Skasunath // these child nodes has its own child nodes, that child node will be
29299bd6c90Skasunath // encoded and added to the stack and this function will return. The
29399bd6c90Skasunath // rest of the children of the current parent will be encoded later
29499bd6c90Skasunath // (after processing all the nodes under the child node added to the
29599bd6c90Skasunath // stack).
29699bd6c90Skasunath RETURN_IF_IERROR(bejProcessChildNodes(parent, stack, output));
29799bd6c90Skasunath
29899bd6c90Skasunath // If a new node hasn't been added to the stack by
29999bd6c90Skasunath // bejProcessChildNodes(), we know that this parent's child nodes have
30099bd6c90Skasunath // been processed. If a new node has been added, then next we need to
30199bd6c90Skasunath // process the children of the newly added node.
30299bd6c90Skasunath if (parent != stack->stackPeek(stack->stackContext))
30399bd6c90Skasunath {
30499bd6c90Skasunath continue;
30599bd6c90Skasunath }
30699bd6c90Skasunath stack->stackPop(stack->stackContext);
30799bd6c90Skasunath }
30899bd6c90Skasunath return 0;
30999bd6c90Skasunath }
31099bd6c90Skasunath
bejEncode(const struct BejDictionaries * dictionaries,uint16_t majorSchemaStartingOffset,enum BejSchemaClass schemaClass,struct RedfishPropertyParent * root,struct BejEncoderOutputHandler * output,struct BejPointerStackCallback * stack)31199bd6c90Skasunath int bejEncode(const struct BejDictionaries* dictionaries,
31299bd6c90Skasunath uint16_t majorSchemaStartingOffset,
31399bd6c90Skasunath enum BejSchemaClass schemaClass,
31499bd6c90Skasunath struct RedfishPropertyParent* root,
31599bd6c90Skasunath struct BejEncoderOutputHandler* output,
31699bd6c90Skasunath struct BejPointerStackCallback* stack)
31799bd6c90Skasunath {
31899bd6c90Skasunath NULL_CHECK(dictionaries, "dictionaries");
31999bd6c90Skasunath NULL_CHECK(dictionaries->schemaDictionary, "schemaDictionary");
32099bd6c90Skasunath NULL_CHECK(dictionaries->annotationDictionary, "annotationDictionary");
32199bd6c90Skasunath
32299bd6c90Skasunath NULL_CHECK(root, "root");
32399bd6c90Skasunath
32499bd6c90Skasunath NULL_CHECK(output, "output");
32599bd6c90Skasunath NULL_CHECK(stack, "stack");
32699bd6c90Skasunath
32799bd6c90Skasunath // Assert root node.
32899bd6c90Skasunath if (root->nodeAttr.format.principalDataType != bejSet)
32999bd6c90Skasunath {
33099bd6c90Skasunath fprintf(stderr, "Invalid root node\n");
33199bd6c90Skasunath return -1;
33299bd6c90Skasunath }
33399bd6c90Skasunath
33499bd6c90Skasunath // First we need to encode a parent node before its child nodes. But before
33599bd6c90Skasunath // encoding the parent node, the encoder has to figure out the total size
33699bd6c90Skasunath // need to encode the parent's child nodes. Therefore first the encoder need
33799bd6c90Skasunath // to visit the child nodes and calculate the size need to encode them
33899bd6c90Skasunath // before producing the encoded bytes for the parent node.
33999bd6c90Skasunath //
34099bd6c90Skasunath // So first the encoder will visit child nodes and calculate the size need
34199bd6c90Skasunath // to encode each child node. Then store this information in metadata
34299bd6c90Skasunath // properties in each node struct.
34399bd6c90Skasunath // Next the encoder will again visit each node starting from the parent
34499bd6c90Skasunath // node, and produce the encoded bytes.
34599bd6c90Skasunath
34699bd6c90Skasunath // First calculate metadata for encoding each node.
34799bd6c90Skasunath RETURN_IF_IERROR(bejUpdateNodeMetadata(
34899bd6c90Skasunath dictionaries, majorSchemaStartingOffset, root, stack));
34999bd6c90Skasunath
35099bd6c90Skasunath // Derive the header of the encoded output.
35199bd6c90Skasunath // BEJ version
35299bd6c90Skasunath uint32_t version = BEJ_VERSION;
35399bd6c90Skasunath RETURN_IF_IERROR(
35499bd6c90Skasunath output->recvOutput(&version, sizeof(uint32_t), output->handlerContext));
35599bd6c90Skasunath uint16_t reserved = 0;
35699bd6c90Skasunath RETURN_IF_IERROR(output->recvOutput(&reserved, sizeof(uint16_t),
35799bd6c90Skasunath output->handlerContext));
35899bd6c90Skasunath RETURN_IF_IERROR(output->recvOutput(&schemaClass, sizeof(uint8_t),
35999bd6c90Skasunath output->handlerContext));
36099bd6c90Skasunath
36199bd6c90Skasunath // Produce the encoded bytes for the nodes using the previously calculated
36299bd6c90Skasunath // metadata.
36399bd6c90Skasunath return bejEncodeTree(root, stack, output);
36499bd6c90Skasunath }
365