Added readBinaryDTagElement
diff --git a/ndn-cpp/encoding/BinaryXMLDecoder.c b/ndn-cpp/encoding/BinaryXMLDecoder.c
index 89f6a9c..f9a1f3a 100644
--- a/ndn-cpp/encoding/BinaryXMLDecoder.c
+++ b/ndn-cpp/encoding/BinaryXMLDecoder.c
@@ -7,6 +7,24 @@
#include "BinaryXML.h"
#include "BinaryXMLDecoder.h"
+/**
+ * Return the octet at self->offset, converting to unsigned int. Increment self->offset.
+ * This does not check for reading past the end of the input, so this is called "unsafe".
+ */
+static inline unsigned int unsafeReadOctet(struct ndn_BinaryXMLDecoder *self)
+{
+ return (unsigned int)(self->input[self->offset++] & 0xff);
+}
+
+/**
+ * Return the octet at self->offset, converting to unsigned int. Do not increment self->offset.
+ * This does not check for reading past the end of the input, so this is called "unsafe".
+ */
+static inline unsigned int unsafeGetOctet(struct ndn_BinaryXMLDecoder *self)
+{
+ return (unsigned int)(self->input[self->offset] & 0xff);
+}
+
char *ndn_BinaryXMLDecoder_decodeTypeAndValue(struct ndn_BinaryXMLDecoder *self, unsigned int *type, unsigned int *valueOut)
{
unsigned int value = 0;
@@ -15,7 +33,7 @@
if (self->offset >= self->inputLength)
return "ndn_BinaryXMLDecoder_decodeTypeAndVal read past the end of the input";
- unsigned int octet = (unsigned int)(self->input[self->offset++] & 0xff);
+ unsigned int octet = unsafeReadOctet(self);
if (octet & ndn_BinaryXML_TT_FINAL) {
// Finished.
@@ -28,7 +46,7 @@
}
*valueOut = value;
- return (char *)0;
+ return 0;
}
char *ndn_BinaryXMLDecoder_readDTag(struct ndn_BinaryXMLDecoder *self, unsigned int expectedTag)
@@ -45,7 +63,7 @@
if (value != expectedTag)
return "ndn_BinaryXMLDecoder_readDTag: did not get the expected DTAG";
- return (char *)0;
+ return 0;
}
char *ndn_BinaryXMLDecoder_readElementClose(struct ndn_BinaryXMLDecoder *self)
@@ -53,12 +71,10 @@
if (self->offset >= self->inputLength)
return "ndn_BinaryXMLDecoder_readElementClose read past the end of the input";
- unsigned int octet = (unsigned int)(self->input[self->offset++] & 0xff);
-
- if (octet != ndn_BinaryXML_CLOSE)
+ if (unsafeReadOctet(self) != ndn_BinaryXML_CLOSE)
return "ndn_BinaryXMLDecoder_readDTag: did not get the expected element close";
- return (char *)0;
+ return 0;
}
char *ndn_BinaryXMLDecoder_peekDTag(struct ndn_BinaryXMLDecoder *self, unsigned int expectedTag, int *gotExpectedTag)
@@ -70,6 +86,7 @@
unsigned int value;
unsigned int saveOffset = self->offset;
char *error = ndn_BinaryXMLDecoder_decodeTypeAndValue(self, &type, &value);
+ // Restore offset.
self->offset = saveOffset;
if (error)
@@ -78,5 +95,38 @@
if (type == ndn_BinaryXML_DTAG && value == expectedTag)
*gotExpectedTag = 1;
- return (char *)0;
-}
\ No newline at end of file
+ return 0;
+}
+
+char *ndn_BinaryXMLDecoder_readBinaryDTagElement
+ (struct ndn_BinaryXMLDecoder *self, unsigned int expectedTag, int allowNull, unsigned char **value, unsigned int *valueLen)
+{
+ char *error;
+ if (error = ndn_BinaryXMLDecoder_readDTag(self, expectedTag))
+ return error;
+
+ if (allowNull) {
+ if (self->offset >= self->inputLength)
+ return "ndn_BinaryXMLDecoder_readBinaryDTagElement read past the end of the input";
+
+ if (unsafeGetOctet(self) == ndn_BinaryXML_CLOSE) {
+ // The binary item is missing, and this is allowed, so read the element close and return a null value.
+ ++self->offset;
+ *value = 0;
+ *valueLen = 0;
+ return 0;
+ }
+ }
+
+ unsigned int itemType;
+ if (error = ndn_BinaryXMLDecoder_decodeTypeAndValue(self, &itemType, valueLen))
+ return error;
+ // Ignore itemType.
+ *value = self->input + self->offset;
+ self->offset += *valueLen;
+
+ if (error = ndn_BinaryXMLDecoder_readElementClose(self))
+ return error;
+
+ return 0;
+}
diff --git a/ndn-cpp/encoding/BinaryXMLDecoder.h b/ndn-cpp/encoding/BinaryXMLDecoder.h
index ed24df7..7696541 100644
--- a/ndn-cpp/encoding/BinaryXMLDecoder.h
+++ b/ndn-cpp/encoding/BinaryXMLDecoder.h
@@ -61,6 +61,24 @@
char *ndn_BinaryXMLDecoder_peekDTag(struct ndn_BinaryXMLDecoder *self, unsigned int expectedTag, int *gotExpectedTag);
/**
+ * Decode the header from self's input starting at offset, expecting the type to be DTAG and the value to be expectedTag.
+ * Then read one item of any type (presumably BLOB, UDATA, TAG or ATTR) and return the item's value and length.
+ * However, if allowNull is 1, then the item may be absent.
+ * Finally, read the element close. Update offset.
+ * @param self pointer to the ndn_BinaryXMLDecoder struct
+ * @param expectedTag the expected value for DTAG
+ * @param allowNull 1 if the binary item may be missing
+ * @param value output a pointer to the binary data inside self's input buffer. However, if allowNull is 1 and the
+ * binary data item is absent, then return 0.
+ * @param valueLen output the length of the binary data. However, if allowNull is 1 and the
+ * binary data item is absent, then return 0.
+ * @return 0 for success, else an error string, including an error if not the expected tag, or if allowNull is 0
+ * and the binary data is absent
+ */
+char *ndn_BinaryXMLDecoder_readBinaryDTagElement
+ (struct ndn_BinaryXMLDecoder *self, unsigned int expectedTag, int allowNull, unsigned char **value, unsigned int *valueLen);
+
+/**
* Set the offset into the input, used for the next read.
* @param self pointer to the ndn_BinaryXMLDecoder struct
* @param offset the new offset