Move C code into ndn-cpp/c
diff --git a/ndn-cpp/c/Name.h b/ndn-cpp/c/Name.h
new file mode 100644
index 0000000..a80e3d5
--- /dev/null
+++ b/ndn-cpp/c/Name.h
@@ -0,0 +1,49 @@
+/* 
+ * Author: Jeff Thompson
+ *
+ * BSD license, See the LICENSE file for more information.
+ */
+
+#ifndef NDN_NAME_H
+#define	NDN_NAME_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+  
+struct ndn_NameComponent {
+  unsigned char *value;     /**< pointer to the component value */
+  unsigned int valueLength; /**< the number of bytes in value */
+};
+
+static inline void ndn_NameComponent_init(struct ndn_NameComponent *self, unsigned char *value, unsigned int valueLength) 
+{
+  self->value = value;
+  self->valueLength = valueLength;
+}
+  
+struct ndn_Name {
+  struct ndn_NameComponent *components; /**< pointer to the array of components. */
+  unsigned int maxComponents;           /**< the number of elements in the allocated components array */
+  unsigned int nComponents;             /**< the number of components in the name */
+};
+
+/**
+ * Initialize an ndn_Name struct with the components array.
+ * @param self pointer to the ndn_Name struct
+ * @param components the array of ndn_NameComponent already allocated
+ * @param maxComponents the number of elements in the allocated components array
+ */
+static inline void ndn_Name_init(struct ndn_Name *self, struct ndn_NameComponent *components, unsigned int maxComponents) 
+{
+  self->components = components;
+  self->maxComponents = maxComponents;
+  self->nComponents = 0;
+}
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif
+
diff --git a/ndn-cpp/c/encoding/BinaryXML.h b/ndn-cpp/c/encoding/BinaryXML.h
new file mode 100644
index 0000000..e39c785
--- /dev/null
+++ b/ndn-cpp/c/encoding/BinaryXML.h
@@ -0,0 +1,145 @@
+/* 
+ * Author: Jeff Thompson
+ *
+ * BSD license, See the LICENSE file for more information.
+ */
+
+#ifndef NDN_BINARYXML_H
+#define	NDN_BINARYXML_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+enum {
+  ndn_BinaryXML_EXT = 0x00, 	
+  ndn_BinaryXML_TAG = 0x01, 
+  ndn_BinaryXML_DTAG = 0x02, 
+  ndn_BinaryXML_ATTR = 0x03, 
+  ndn_BinaryXML_DATTR = 0x04, 
+  ndn_BinaryXML_BLOB = 0x05, 
+  ndn_BinaryXML_UDATA = 0x06, 
+  ndn_BinaryXML_CLOSE = 0x0,
+
+  ndn_BinaryXML_TT_BITS = 3,
+  ndn_BinaryXML_TT_MASK = ((1 << ndn_BinaryXML_TT_BITS) - 1),
+  ndn_BinaryXML_TT_VALUE_BITS = 4,
+  ndn_BinaryXML_TT_VALUE_MASK = ((1 << (ndn_BinaryXML_TT_VALUE_BITS)) - 1),
+  ndn_BinaryXML_REGULAR_VALUE_BITS = 7,
+  ndn_BinaryXML_REGULAR_VALUE_MASK = ((1 << ndn_BinaryXML_REGULAR_VALUE_BITS) - 1),
+  ndn_BinaryXML_TT_FINAL = 0x80,
+
+  ndn_BinaryXML_DTag_Any = 13,
+  ndn_BinaryXML_DTag_Name = 14,
+  ndn_BinaryXML_DTag_Component = 15,
+  ndn_BinaryXML_DTag_Certificate = 16,
+  ndn_BinaryXML_DTag_Collection = 17,
+  ndn_BinaryXML_DTag_CompleteName = 18,
+  ndn_BinaryXML_DTag_Content = 19,
+  ndn_BinaryXML_DTag_SignedInfo = 20,
+  ndn_BinaryXML_DTag_ContentDigest = 21,
+  ndn_BinaryXML_DTag_ContentHash = 22,
+  ndn_BinaryXML_DTag_Count = 24,
+  ndn_BinaryXML_DTag_Header = 25,
+  ndn_BinaryXML_DTag_Interest = 26,	/* 20090915 */
+  ndn_BinaryXML_DTag_Key = 27,
+  ndn_BinaryXML_DTag_KeyLocator = 28,
+  ndn_BinaryXML_DTag_KeyName = 29,
+  ndn_BinaryXML_DTag_Length = 30,
+  ndn_BinaryXML_DTag_Link = 31,
+  ndn_BinaryXML_DTag_LinkAuthenticator = 32,
+  ndn_BinaryXML_DTag_NameComponentCount = 33,	/* DeprecatedInInterest */
+  ndn_BinaryXML_DTag_RootDigest = 36,
+  ndn_BinaryXML_DTag_Signature = 37,
+  ndn_BinaryXML_DTag_Start = 38,
+  ndn_BinaryXML_DTag_Timestamp = 39,
+  ndn_BinaryXML_DTag_Type = 40,
+  ndn_BinaryXML_DTag_Nonce = 41,
+  ndn_BinaryXML_DTag_Scope = 42,
+  ndn_BinaryXML_DTag_Exclude = 43,
+  ndn_BinaryXML_DTag_Bloom = 44,
+  ndn_BinaryXML_DTag_BloomSeed = 45,
+  ndn_BinaryXML_DTag_AnswerOriginKind = 47,
+  ndn_BinaryXML_DTag_InterestLifetime = 48,
+  ndn_BinaryXML_DTag_Witness = 53,
+  ndn_BinaryXML_DTag_SignatureBits = 54,
+  ndn_BinaryXML_DTag_DigestAlgorithm = 55,
+  ndn_BinaryXML_DTag_BlockSize = 56,
+  ndn_BinaryXML_DTag_FreshnessSeconds = 58,
+  ndn_BinaryXML_DTag_FinalBlockID = 59,
+  ndn_BinaryXML_DTag_PublisherPublicKeyDigest = 60,
+  ndn_BinaryXML_DTag_PublisherCertificateDigest = 61,
+  ndn_BinaryXML_DTag_PublisherIssuerKeyDigest = 62,
+  ndn_BinaryXML_DTag_PublisherIssuerCertificateDigest = 63,
+  ndn_BinaryXML_DTag_ContentObject = 64,	/* 20090915 */
+  ndn_BinaryXML_DTag_WrappedKey = 65,
+  ndn_BinaryXML_DTag_WrappingKeyIdentifier = 66,
+  ndn_BinaryXML_DTag_WrapAlgorithm = 67,
+  ndn_BinaryXML_DTag_KeyAlgorithm = 68,
+  ndn_BinaryXML_DTag_Label = 69,
+  ndn_BinaryXML_DTag_EncryptedKey = 70,
+  ndn_BinaryXML_DTag_EncryptedNonceKey = 71,
+  ndn_BinaryXML_DTag_WrappingKeyName = 72,
+  ndn_BinaryXML_DTag_Action = 73,
+  ndn_BinaryXML_DTag_FaceID = 74,
+  ndn_BinaryXML_DTag_IPProto = 75,
+  ndn_BinaryXML_DTag_Host = 76,
+  ndn_BinaryXML_DTag_Port = 77,
+  ndn_BinaryXML_DTag_MulticastInterface = 78,
+  ndn_BinaryXML_DTag_ForwardingFlags = 79,
+  ndn_BinaryXML_DTag_FaceInstance = 80,
+  ndn_BinaryXML_DTag_ForwardingEntry = 81,
+  ndn_BinaryXML_DTag_MulticastTTL = 82,
+  ndn_BinaryXML_DTag_MinSuffixComponents = 83,
+  ndn_BinaryXML_DTag_MaxSuffixComponents = 84,
+  ndn_BinaryXML_DTag_ChildSelector = 85,
+  ndn_BinaryXML_DTag_RepositoryInfo = 86,
+  ndn_BinaryXML_DTag_Version = 87,
+  ndn_BinaryXML_DTag_RepositoryVersion = 88,
+  ndn_BinaryXML_DTag_GlobalPrefix = 89,
+  ndn_BinaryXML_DTag_LocalName = 90,
+  ndn_BinaryXML_DTag_Policy = 91,
+  ndn_BinaryXML_DTag_Namespace = 92,
+  ndn_BinaryXML_DTag_GlobalPrefixName = 93,
+  ndn_BinaryXML_DTag_PolicyVersion = 94,
+  ndn_BinaryXML_DTag_KeyValueSet = 95,
+  ndn_BinaryXML_DTag_KeyValuePair = 96,
+  ndn_BinaryXML_DTag_IntegerValue = 97,
+  ndn_BinaryXML_DTag_DecimalValue = 98,
+  ndn_BinaryXML_DTag_StringValue = 99,
+  ndn_BinaryXML_DTag_BinaryValue = 100,
+  ndn_BinaryXML_DTag_NameValue = 101,
+  ndn_BinaryXML_DTag_Entry = 102,
+  ndn_BinaryXML_DTag_ACL = 103,
+  ndn_BinaryXML_DTag_ParameterizedName = 104,
+  ndn_BinaryXML_DTag_Prefix = 105,
+  ndn_BinaryXML_DTag_Suffix = 106,
+  ndn_BinaryXML_DTag_Root = 107,
+  ndn_BinaryXML_DTag_ProfileName = 108,
+  ndn_BinaryXML_DTag_Parameters = 109,
+  ndn_BinaryXML_DTag_InfoString = 110,
+  ndn_BinaryXML_DTag_StatusResponse = 112,
+  ndn_BinaryXML_DTag_StatusCode = 113,
+  ndn_BinaryXML_DTag_StatusText = 114,
+  ndn_BinaryXML_DTag_SyncNode = 115,
+  ndn_BinaryXML_DTag_SyncNodeKind = 116,
+  ndn_BinaryXML_DTag_SyncNodeElement = 117,
+  ndn_BinaryXML_DTag_SyncVersion = 118,
+  ndn_BinaryXML_DTag_SyncNodeElements = 119,
+  ndn_BinaryXML_DTag_SyncContentHash = 120,
+  ndn_BinaryXML_DTag_SyncLeafCount = 121,
+  ndn_BinaryXML_DTag_SyncTreeDepth = 122,
+  ndn_BinaryXML_DTag_SyncByteCount = 123,
+  ndn_BinaryXML_DTag_SyncConfigSlice = 124,
+  ndn_BinaryXML_DTag_SyncConfigSliceList = 125,
+  ndn_BinaryXML_DTag_SyncConfigSliceOp = 126,
+  ndn_BinaryXML_DTag_SyncNodeDeltas = 127,
+  ndn_BinaryXML_DTag_SequenceNumber = 256,
+  ndn_BinaryXML_DTag_CCNProtocolDataUnit = 17702112
+};
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif
diff --git a/ndn-cpp/c/encoding/BinaryXMLDecoder.c b/ndn-cpp/c/encoding/BinaryXMLDecoder.c
new file mode 100644
index 0000000..6a8900a
--- /dev/null
+++ b/ndn-cpp/c/encoding/BinaryXMLDecoder.c
@@ -0,0 +1,146 @@
+/* 
+ * Author: Jeff Thompson
+ *
+ * BSD license, See the LICENSE file for more information.
+ */
+
+#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;
+  int gotFirstOctet = 0;
+  
+	while (1) {
+    if (self->offset >= self->inputLength)
+      return "ndn_BinaryXMLDecoder_decodeTypeAndVal: read past the end of the input";
+    
+		unsigned int octet = unsafeReadOctet(self);
+		
+    if (!gotFirstOctet) {
+      if (octet == 0)
+        return "ndn_BinaryXMLDecoder_decodeTypeAndVal: the first header octet may not be zero";
+      
+      gotFirstOctet = 1;
+    }
+    
+		if (octet & ndn_BinaryXML_TT_FINAL) {
+      // Finished.
+			*type = octet & ndn_BinaryXML_TT_MASK;
+			value = (value << ndn_BinaryXML_TT_VALUE_BITS) | ((octet >> ndn_BinaryXML_TT_BITS) & ndn_BinaryXML_TT_VALUE_MASK);
+      break;
+		}
+		
+    value = (value << ndn_BinaryXML_REGULAR_VALUE_BITS) | (octet & ndn_BinaryXML_REGULAR_VALUE_MASK);		
+	}
+
+	*valueOut = value;
+  return 0;
+}
+
+char *ndn_BinaryXMLDecoder_readDTag(struct ndn_BinaryXMLDecoder *self, unsigned int expectedTag)
+{
+  char *error;
+  unsigned int type;
+  unsigned int value;
+  if (error = ndn_BinaryXMLDecoder_decodeTypeAndValue(self, &type, &value))
+    return error;
+  
+  if (type != ndn_BinaryXML_DTAG)
+    return "ndn_BinaryXMLDecoder_readDTag: header type is not a DTAG";
+  
+  if (value != expectedTag)
+    return "ndn_BinaryXMLDecoder_readDTag: did not get the expected DTAG";
+  
+  return 0;
+}
+
+char *ndn_BinaryXMLDecoder_readElementClose(struct ndn_BinaryXMLDecoder *self)
+{
+  if (self->offset >= self->inputLength)
+    return "ndn_BinaryXMLDecoder_readElementClose: read past the end of the input";
+  
+  if (unsafeReadOctet(self) != ndn_BinaryXML_CLOSE)
+    return "ndn_BinaryXMLDecoder_readDTag: did not get the expected element close";
+  
+  return 0;
+}
+
+char *ndn_BinaryXMLDecoder_peekDTag(struct ndn_BinaryXMLDecoder *self, unsigned int expectedTag, int *gotExpectedTag)
+{
+  // Default to 0.
+  *gotExpectedTag = 0;
+
+  // First check if it is an element close (which cannot be the expected tag).  
+  if (self->offset >= self->inputLength)
+    return "ndn_BinaryXMLDecoder_readElementClose: read past the end of the input";
+  if (unsafeGetOctet(self) == 0)
+    return 0;
+
+  unsigned int type;
+  unsigned int value;
+  unsigned int saveOffset = self->offset;
+  char *error = ndn_BinaryXMLDecoder_decodeTypeAndValue(self, &type, &value);
+  // Restore offset.
+  self->offset = saveOffset;
+  
+  if (error)
+    return error;
+  
+  if (type == ndn_BinaryXML_DTAG && value == expectedTag)
+    *gotExpectedTag = 1;
+  
+  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/c/encoding/BinaryXMLDecoder.h b/ndn-cpp/c/encoding/BinaryXMLDecoder.h
new file mode 100644
index 0000000..0f3285b
--- /dev/null
+++ b/ndn-cpp/c/encoding/BinaryXMLDecoder.h
@@ -0,0 +1,94 @@
+/* 
+ * Author: Jeff Thompson
+ *
+ * BSD license, See the LICENSE file for more information.
+ */
+
+#ifndef NDN_BINARYXMLDECODER_H
+#define	NDN_BINARYXMLDECODER_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+struct ndn_BinaryXMLDecoder {
+  unsigned char *input;
+  unsigned int inputLength;
+  unsigned int offset;
+};
+
+static inline void ndn_BinaryXMLDecoder_init(struct ndn_BinaryXMLDecoder *self, unsigned char *input, unsigned int inputLength) 
+{
+  self->input = input;
+  self->inputLength = inputLength;
+  self->offset = 0;
+}
+
+/**
+ * Decode the header's type and value from self's input starting at offset. Update offset.
+ * @param self pointer to the ndn_BinaryXMLDecoder struct
+ * @param type output for the header type
+ * @param value output for the header value
+ * @return 0 for success, else an error string for read past the end of the input or if the initial byte is zero
+ */
+char *ndn_BinaryXMLDecoder_decodeTypeAndValue(struct ndn_BinaryXMLDecoder *self, unsigned int *type, unsigned int *value);
+
+/**
+ * Decode the header from self's input starting at offset, expecting the type to be DTAG and the value to be expectedTag.
+ * Update offset.
+ * @param self pointer to the ndn_BinaryXMLDecoder struct
+ * @param expectedTag the expected value for DTAG
+ * @return 0 for success, else an error string, including an error if not the expected tag
+ */
+char *ndn_BinaryXMLDecoder_readDTag(struct ndn_BinaryXMLDecoder *self, unsigned int expectedTag);
+
+/**
+ * Read one byte from self's input starting at offset, expecting it to be the element close.
+ * @param self pointer to the ndn_BinaryXMLDecoder struct
+ * @return 0 for success, else an error string, including an error if not the element close
+ */
+char *ndn_BinaryXMLDecoder_readElementClose(struct ndn_BinaryXMLDecoder *self);
+
+/**
+ * Decode the header from self's input starting at offset, and if it is a DTAG where the value is the expectedTag,
+ * then set gotExpectedTag to 1, else 0.  Do not update offset, including if returning an error.
+ * @param self pointer to the ndn_BinaryXMLDecoder struct
+ * @param expectedTag the expected value for DTAG
+ * @param gotExpectedTag output a 1 if got the expected tag, else 0
+ * @return 0 for success, else an error string for read past the end of the input
+ */
+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
+ */
+static inline void ndn_BinaryXMLDecoder_seek(struct ndn_BinaryXMLDecoder *self, unsigned int offset) 
+{
+  self->offset = offset;
+}
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif
diff --git a/ndn-cpp/c/encoding/BinaryXMLEncoder.c b/ndn-cpp/c/encoding/BinaryXMLEncoder.c
new file mode 100644
index 0000000..c70a44a
--- /dev/null
+++ b/ndn-cpp/c/encoding/BinaryXMLEncoder.c
@@ -0,0 +1,74 @@
+/* 
+ * Author: Jeff Thompson
+ *
+ * BSD license, See the LICENSE file for more information.
+ */
+
+#include "BinaryXML.h"
+#include "BinaryXMLEncoder.h"
+
+enum {
+  ENCODING_LIMIT_1_BYTE = ((1 << ndn_BinaryXML_TT_VALUE_BITS) - 1),
+  ENCODING_LIMIT_2_BYTES = ((1 << (ndn_BinaryXML_TT_VALUE_BITS + ndn_BinaryXML_REGULAR_VALUE_BITS)) - 1),
+  ENCODING_LIMIT_3_BYTES = ((1 << (ndn_BinaryXML_TT_VALUE_BITS + 2 * ndn_BinaryXML_REGULAR_VALUE_BITS)) - 1)
+};
+
+/**
+ * Return the number of bytes to encode a header of value x.
+ */
+static unsigned int getNEncodingBytes(unsigned int x) 
+{
+  // Do a quick check for pre-compiled results.
+	if (x <= ENCODING_LIMIT_1_BYTE) 
+    return 1;
+	if (x <= ENCODING_LIMIT_2_BYTES) 
+    return 2;
+	if (x <= ENCODING_LIMIT_3_BYTES) 
+    return 3;
+	
+	unsigned int nBytes = 1;
+	
+	// Last byte gives you TT_VALUE_BITS.
+	// Remainder each gives you REGULAR_VALUE_BITS.
+	x >>= ndn_BinaryXML_TT_VALUE_BITS;
+	while (x != 0) {
+    ++nBytes;
+	  x >>= ndn_BinaryXML_REGULAR_VALUE_BITS;
+	}
+  
+	return nBytes;
+}
+
+char *ndn_BinaryXMLEncoder_encodeTypeAndValue(struct ndn_BinaryXMLEncoder *self, unsigned int type, unsigned int value)
+{
+	if (type > ndn_BinaryXML_UDATA)
+		return "ndn_BinaryXMLEncoder_encodeTypeAndValue: type is out of range";
+  
+	// Encode backwards. Calculate how many bytes we need.
+	unsigned int nEncodingBytes = getNEncodingBytes(value);
+  char *error;
+  if (error = ndn_DynamicUCharArray_ensureLength(&self->output, self->offset + nEncodingBytes))
+    return error;
+
+	// Bottom 4 bits of value go in last byte with tag.
+	self->output.array[self->offset + nEncodingBytes - 1] = 
+		(ndn_BinaryXML_TT_MASK & type | 
+		((ndn_BinaryXML_TT_VALUE_MASK & value) << ndn_BinaryXML_TT_BITS)) |
+		ndn_BinaryXML_TT_FINAL; // set top bit for last byte
+	value >>= ndn_BinaryXML_TT_VALUE_BITS;
+	
+	// Rest of value goes into preceding bytes, 7 bits per byte. (Zero top bit is "more" flag.)
+	unsigned int i = self->offset + nEncodingBytes - 2;
+	while (value != 0 && i >= self->offset) {
+		self->output.array[i] = (value & ndn_BinaryXML_REGULAR_VALUE_MASK);
+		value >>= ndn_BinaryXML_REGULAR_VALUE_BITS;
+		--i;
+	}
+	if (value != 0)
+    // This should not happen if getNEncodingBytes is correct.
+		return "ndn_BinaryXMLEncoder_encodeTypeAndValue: : miscalculated N encoding bytes";
+	
+	self->offset+= nEncodingBytes;
+  
+  return 0;
+}
diff --git a/ndn-cpp/c/encoding/BinaryXMLEncoder.h b/ndn-cpp/c/encoding/BinaryXMLEncoder.h
new file mode 100644
index 0000000..e606dee
--- /dev/null
+++ b/ndn-cpp/c/encoding/BinaryXMLEncoder.h
@@ -0,0 +1,44 @@
+/* 
+ * Author: Jeff Thompson
+ *
+ * BSD license, See the LICENSE file for more information.
+ */
+
+#ifndef NDN_BINARYXMLENCODER_H
+#define	NDN_BINARYXMLENCODER_H
+
+#include "../util/DynamicUCharArray.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+struct ndn_BinaryXMLEncoder {
+  struct ndn_DynamicUCharArray output; /**< receives the encoded output */
+  unsigned int offset;             /**< the offset into output.array for the next encoding */
+};
+
+/**
+ * Initialize an ndn_BinaryXMLEncoder_init struct with the arguments for initializing the ndn_DynamicUCharArray.
+ * @param self pointer to the ndn_BinaryXMLEncoder struct
+ * @param outputArray the allocated array buffer to receive the encoding
+ * @param outputArrayLength the length of outputArray
+ * @param reallocFunction the realloc function used by ndn_DynamicUCharArray_ensureLength.  If outputArrayLength
+ * is large enough to receive the entire encoding, this can be 0.
+ */
+static inline void ndn_BinaryXMLEncoder_init
+  (struct ndn_BinaryXMLEncoder *self, unsigned char *outputArray, unsigned int outputArrayLength, 
+   unsigned char (*reallocFunction)(unsigned char *, unsigned int)) 
+{
+  ndn_DynamicUCharArray_init(&self->output, outputArray, outputArrayLength, reallocFunction);
+  self->offset = 0;
+}
+
+char *ndn_BinaryXMLEncoder_encodeTypeAndValue(struct ndn_BinaryXMLEncoder *self, unsigned int type, unsigned int value);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif
+
diff --git a/ndn-cpp/c/encoding/BinaryXMLName.c b/ndn-cpp/c/encoding/BinaryXMLName.c
new file mode 100644
index 0000000..6a4aebb
--- /dev/null
+++ b/ndn-cpp/c/encoding/BinaryXMLName.c
@@ -0,0 +1,45 @@
+/* 
+ * Author: Jeff Thompson
+ *
+ * BSD license, See the LICENSE file for more information.
+ */
+
+#include "BinaryXMLDecoder.h"
+#include "BinaryXML.h"
+#include "BinaryXMLName.h"
+
+char *ndn_decodeBinaryXMLName(struct ndn_Name *name, unsigned char *input, unsigned int inputLength)
+{
+  struct ndn_BinaryXMLDecoder decoder;
+  ndn_BinaryXMLDecoder_init(&decoder, input, inputLength);
+  
+  char *error;
+  if (error = ndn_BinaryXMLDecoder_readDTag(&decoder, ndn_BinaryXML_DTag_Name))
+    return error;
+    
+  while (1) {
+    int gotExpectedTag;
+    if (error = ndn_BinaryXMLDecoder_peekDTag(&decoder, ndn_BinaryXML_DTag_Component, &gotExpectedTag))
+      return error;
+    
+    if (!gotExpectedTag)
+      // No more components.
+      break;
+    
+    unsigned char *component;
+    unsigned int componentLen;
+    if (error = ndn_BinaryXMLDecoder_readBinaryDTagElement(&decoder, ndn_BinaryXML_DTag_Component, 0, &component, &componentLen))
+      return error;
+    
+    // Add the component to the name.
+    if (name->nComponents >= name->maxComponents)
+      return "ndn_decodeBinaryXMLName: read a component past the maximum number of components allowed in the name";
+    ndn_NameComponent_init(name->components + name->nComponents, component, componentLen);
+    ++name->nComponents;
+  }
+  
+  if (error = ndn_BinaryXMLDecoder_readElementClose(&decoder))
+    return error;
+  
+  return 0;
+}
diff --git a/ndn-cpp/c/encoding/BinaryXMLName.h b/ndn-cpp/c/encoding/BinaryXMLName.h
new file mode 100644
index 0000000..3a83b8c
--- /dev/null
+++ b/ndn-cpp/c/encoding/BinaryXMLName.h
@@ -0,0 +1,23 @@
+/* 
+ * Author: Jeff Thompson
+ *
+ * BSD license, See the LICENSE file for more information.
+ */
+
+#ifndef NDN_BINARYXMLNAME_H
+#define	NDN_BINARYXMLNAME_H
+
+#include "../Name.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+char *ndn_decodeBinaryXMLName(struct ndn_Name *name, unsigned char *input, unsigned int inputLength);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif
+
diff --git a/ndn-cpp/c/encoding/BinaryXMLStructureDecoder.c b/ndn-cpp/c/encoding/BinaryXMLStructureDecoder.c
new file mode 100644
index 0000000..a2fd405
--- /dev/null
+++ b/ndn-cpp/c/encoding/BinaryXMLStructureDecoder.c
@@ -0,0 +1,150 @@
+/* 
+ * Author: Jeff Thompson
+ *
+ * BSD license, See the LICENSE file for more information.
+ */
+
+#include "../util/ndn_memory.h"
+#include "BinaryXML.h"
+#include "BinaryXMLDecoder.h"
+#include "BinaryXMLStructureDecoder.h"
+
+void ndn_BinaryXMLStructureDecoder_init(struct ndn_BinaryXMLStructureDecoder *self) 
+{
+  self->gotElementEnd = 0;
+  self->offset = 0;
+  self->level = 0;
+  self->state = ndn_BinaryXMLStructureDecoder_READ_HEADER_OR_CLOSE;
+  self->headerLength = 0;
+  self->useHeaderBuffer = 0;
+  self->nBytesToRead = 0;
+}
+
+/**
+ * Set the state to READ_HEADER_OR_CLOSE and set up to start reading the header.
+ */
+static inline void startHeader(struct ndn_BinaryXMLStructureDecoder *self)
+{
+  self->headerLength = 0;
+  self->useHeaderBuffer = 0;
+  self->state = ndn_BinaryXMLStructureDecoder_READ_HEADER_OR_CLOSE;    
+}
+
+char *ndn_BinaryXMLStructureDecoder_findElementEnd
+  (struct ndn_BinaryXMLStructureDecoder *self, unsigned char *input, unsigned int inputLength) 
+{
+  if (self->gotElementEnd)
+    // Someone is calling when we already got the end.
+    return 0;
+  
+  struct ndn_BinaryXMLDecoder decoder;
+  ndn_BinaryXMLDecoder_init(&decoder, input, inputLength);
+  
+  while (1) {
+    if (self->offset >= inputLength)
+      // All the cases assume we have some input. Return and wait for more.
+      return 0;
+    
+    if (self->state == ndn_BinaryXMLStructureDecoder_READ_HEADER_OR_CLOSE) {
+      // First check for CLOSE.
+      if (self->headerLength == 0 && input[self->offset] == ndn_BinaryXML_CLOSE) {
+        ++self->offset;
+        // Close the level.
+        --self->level;
+        if (self->level == 0) {
+          // Finished.
+          self->gotElementEnd = 1;
+          return 0;
+        }
+        if (self->level < 0)
+          return "ndn_BinaryXMLStructureDecoder_findElementEnd: Unexpected close tag";
+          
+        // Get ready for the next header.
+        startHeader(self);
+        continue;
+      }
+        
+      unsigned int startingHeaderLength = self->headerLength;
+      while (1) {
+        if (self->offset >= inputLength) {
+          // We can't get all of the header bytes from this input. Save in headerBuffer.
+          if (self->headerLength > sizeof(self->headerBuffer))
+            return "ndn_BinaryXMLStructureDecoder_findElementEnd: Can't store more header bytes than the size of headerBuffer";
+          self->useHeaderBuffer = 1;
+          unsigned int nNewBytes = self->headerLength - startingHeaderLength;
+          ndn_memcpy(self->headerBuffer + startingHeaderLength, input + (self->offset - nNewBytes), nNewBytes);
+            
+          return 0;
+        }
+        unsigned int headerByte = (unsigned int)input[self->offset++];
+        ++self->headerLength;
+        if (headerByte & ndn_BinaryXML_TT_FINAL)
+          // Break and read the header.
+          break;
+      }
+        
+      unsigned int type;
+      unsigned int value;
+      if (self->useHeaderBuffer) {
+        // Copy the remaining bytes into headerBuffer.
+        if (self->headerLength > sizeof(self->headerBuffer))
+          return "ndn_BinaryXMLStructureDecoder_findElementEnd: Can't store more header bytes than the size of headerBuffer";
+        unsigned int nNewBytes = self->headerLength - startingHeaderLength;
+        ndn_memcpy(self->headerBuffer + startingHeaderLength, input + (self->offset - nNewBytes), nNewBytes);
+
+        // Use a local decoder just for the headerBuffer.
+        struct ndn_BinaryXMLDecoder bufferDecoder;
+        ndn_BinaryXMLDecoder_init(&bufferDecoder, self->headerBuffer, sizeof(self->headerBuffer));
+        if (ndn_BinaryXMLDecoder_decodeTypeAndValue(&bufferDecoder, &type, &value))
+          return "ndn_BinaryXMLStructureDecoder_findElementEnd: Can't read header type and value";
+      }
+      else {
+        // We didn't have to use the headerBuffer.
+        ndn_BinaryXMLDecoder_seek(&decoder, self->offset - self->headerLength);
+        if (ndn_BinaryXMLDecoder_decodeTypeAndValue(&decoder, &type, &value))
+          return "ndn_BinaryXMLStructureDecoder_findElementEnd: Can't read header type and value";
+      }
+        
+      // Set the next state based on the type.
+      if (type == ndn_BinaryXML_DATTR)
+        // We already consumed the item. READ_HEADER_OR_CLOSE again.
+        // Binary XML has rules about what must follow an attribute, but we are just scanning.
+        startHeader(self);
+      else if (type == ndn_BinaryXML_DTAG || type == ndn_BinaryXML_EXT) {
+        // Start a new level and READ_HEADER_OR_CLOSE again.
+        ++self->level;
+        startHeader(self);
+      }
+      else if (type == ndn_BinaryXML_TAG || type == ndn_BinaryXML_ATTR) {
+        if (type == ndn_BinaryXML_TAG)
+          // Start a new level and read the tag.
+          ++self->level;
+        // Minimum tag or attribute length is 1.
+        self->nBytesToRead = value + 1;
+        self->state = ndn_BinaryXMLStructureDecoder_READ_BYTES;
+        // Binary XML has rules about what must follow an attribute, but we are just scanning.
+      }
+      else if (type == ndn_BinaryXML_BLOB || type == ndn_BinaryXML_UDATA) {
+        self->nBytesToRead = value;
+        self->state = ndn_BinaryXMLStructureDecoder_READ_BYTES;
+      }
+      else
+        return "ndn_BinaryXMLStructureDecoder_findElementEnd: Unrecognized header type";
+    }  
+    else if (self->state == ndn_BinaryXMLStructureDecoder_READ_BYTES) {
+      unsigned int nRemainingBytes = inputLength - self->offset;
+      if (nRemainingBytes < self->nBytesToRead) {
+        // Need more.
+        self->offset += nRemainingBytes;
+        self->nBytesToRead -= nRemainingBytes;
+        return 0;
+      }
+      // Got the bytes. Read a new header or close.
+      self->offset += self->nBytesToRead;
+      startHeader(self);
+    }
+    else
+      // We don't expect this to happen.
+      return "ndn_BinaryXMLStructureDecoder_findElementEnd: Unrecognized state";
+  }
+}
diff --git a/ndn-cpp/c/encoding/BinaryXMLStructureDecoder.h b/ndn-cpp/c/encoding/BinaryXMLStructureDecoder.h
new file mode 100644
index 0000000..504a1bd
--- /dev/null
+++ b/ndn-cpp/c/encoding/BinaryXMLStructureDecoder.h
@@ -0,0 +1,50 @@
+/* 
+ * Author: Jeff Thompson
+ *
+ * BSD license, See the LICENSE file for more information.
+ */
+
+#ifndef NDN_BINARYXMLSTRUCTUREDECODER_H
+#define	NDN_BINARYXMLSTRUCTUREDECODER_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+struct ndn_BinaryXMLStructureDecoder {
+  int gotElementEnd; /**< boolean */
+  unsigned int offset;
+  int level;
+  int state;
+  unsigned int headerLength;
+  int useHeaderBuffer; /**< boolean */
+  // 10 bytes is enough to hold an encoded header with a type and a 64 bit value.
+  unsigned char headerBuffer[10];
+  int nBytesToRead;
+};
+
+enum {
+  ndn_BinaryXMLStructureDecoder_READ_HEADER_OR_CLOSE,
+  ndn_BinaryXMLStructureDecoder_READ_BYTES
+};
+
+void ndn_BinaryXMLStructureDecoder_init(struct ndn_BinaryXMLStructureDecoder *self);
+        
+/**
+ * Continue scanning input starting from self->offset to find the element end.  On return, you must check
+ *   self->gotElementEnd: If the end of the element which started at offset 0 is found, 
+ *   then self->gotElementEnd is 1 and self->offset is the length of the element.  Otherwise, self-forElementEnd is 0 
+ *   which means you should read more into input and call again.
+ * @param self pointer to the ndn_BinaryXMLStructureDecoder struct
+ * @param input the input buffer. You have to pass in input each time because the buffer could be reallocated.
+ * @param inputLength the number of bytes in input.
+ * @return 0 for success, else an error string
+ */
+char *ndn_BinaryXMLStructureDecoder_findElementEnd
+  (struct ndn_BinaryXMLStructureDecoder *self, unsigned char *input, unsigned int inputLength);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif
diff --git a/ndn-cpp/c/util/DynamicUCharArray.c b/ndn-cpp/c/util/DynamicUCharArray.c
new file mode 100644
index 0000000..ac1e451
--- /dev/null
+++ b/ndn-cpp/c/util/DynamicUCharArray.c
@@ -0,0 +1,13 @@
+/* 
+ * Author: Jeff Thompson
+ *
+ * BSD license, See the LICENSE file for more information.
+ */
+
+#include "DynamicUCharArray.h"
+
+char *ndn_DynamicUCharArray_reallocArray(struct ndn_DynamicUCharArray *self, unsigned int length)
+{
+  // TODO: implement.
+  return "ndn_DynamicUCharArray_reallocArray: realloc function pointer not supplied";
+}
\ No newline at end of file
diff --git a/ndn-cpp/c/util/DynamicUCharArray.h b/ndn-cpp/c/util/DynamicUCharArray.h
new file mode 100644
index 0000000..67060fa
--- /dev/null
+++ b/ndn-cpp/c/util/DynamicUCharArray.h
@@ -0,0 +1,79 @@
+/* 
+ * Author: Jeff Thompson
+ *
+ * BSD license, See the LICENSE file for more information.
+ */
+
+#ifndef NDN_DYNAMICUCHARARRAY_H
+#define	NDN_DYNAMICUCHARARRAY_H
+
+#include "ndn_memory.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+struct ndn_DynamicUCharArray {
+  unsigned char *array; /**< the allocated array buffer */
+  unsigned int length;  /**< the length of the allocated array buffer */
+  unsigned char (*realloc)(unsigned char *array, unsigned int length); /**< a pointer to a function that reallocates array and returns a new buffer of
+                                                                        * length bytes or 0 for error.  The original array pointer is no longer used.
+                                                                        * This may be 0 (which causes an error if a reallocate is necessary). */
+};
+
+/**
+ * Initialize an ndn_DynamicUCharArray struct with the given array buffer.
+ * @param self pointer to the ndn_DynamicUCharArray struct
+ * @param array the allocated array buffer
+ * @param length the length of the allocated array buffer
+ * @param reallocFunction see ndn_DynamicUCharArray_ensureLength.  This may be 0.
+ */
+static inline void ndn_DynamicUCharArray_init
+  (struct ndn_DynamicUCharArray *self, unsigned char *array, unsigned int length, unsigned char (*reallocFunction)(unsigned char *, unsigned int)) 
+{
+  self->array = array;
+  self->length = length;
+  self->realloc = reallocFunction;
+}
+
+char *ndn_DynamicUCharArray_reallocArray(struct ndn_DynamicUCharArray *self, unsigned int length);
+
+/**
+ * Ensure that self->length is greater than or equal to length.  If it is, just return 0 for success.
+ * Otherwise, if the self->realloc function pointer is null, then return an error.
+ * If not null, call self->realloc to reallocate self->array, and update self->length (which may be greater than length).
+ * @param self pointer to the ndn_DynamicUCharArray struct
+ * @param length the needed minimum size for self->length
+ * @return 0 for success, else an error string if need to reallocate the array but can't
+ */
+static inline char *ndn_DynamicUCharArray_ensureLength(struct ndn_DynamicUCharArray *self, unsigned int length) 
+{
+  if (self->length >= length)
+    return 0;
+
+  return ndn_DynamicUCharArray_reallocArray(self, length);
+}
+
+/**
+ * Copy value into self->array at offset, using ndn_DynamicUCharArray_ensureLength to make sure self->array has enough length.
+ * @param self pointer to the ndn_DynamicUCharArray struct
+ * @param value the buffer to copy from
+ * @param valueLength the length of the value buffer
+ * @param offset the offset in self->array to copy to
+ * @return 0 for success, else an error string if need to reallocate the array but can't
+ */
+static inline char *ndn_DynamicUCharArray_set
+  (struct ndn_DynamicUCharArray *self, unsigned char *value, unsigned int valueLength, unsigned int offset) 
+{
+  char *error;
+  if (error = ndn_DynamicUCharArray_ensureLength(self, valueLength + offset))
+    return error;
+  ndn_memcpy(self->array + offset, value, valueLength);
+};
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif
+
diff --git a/ndn-cpp/c/util/ndn_memory.c b/ndn-cpp/c/util/ndn_memory.c
new file mode 100644
index 0000000..8699309
--- /dev/null
+++ b/ndn-cpp/c/util/ndn_memory.c
@@ -0,0 +1,31 @@
+/* 
+ * Author: Jeff Thompson
+ *
+ * BSD license, See the LICENSE file for more information.
+ */
+
+#include "ndn_memory.h"
+
+#if !HAVE_MEMCPY
+void ndn_memcpy(unsigned char *dest, unsigned char *src, unsigned int len)
+{
+  unsigned int i;
+  
+  for (i = 0; i < len; i++)
+    dest[i] = src[i];
+}
+#else
+int ndn_memcpy_stub_to_avoid_empty_file_warning = 0;
+#endif
+
+#if !HAVE_MEMSET
+void ndn_memset(unsigned char *dest, int val, unsigned int len)
+{
+  unsigned int i;
+  
+  for (i = 0; i < len; i++)
+    dest[i] = (unsigned char)val;
+}
+#else
+int ndn_memset_stub_to_avoid_empty_file_warning = 0;
+#endif
\ No newline at end of file
diff --git a/ndn-cpp/c/util/ndn_memory.h b/ndn-cpp/c/util/ndn_memory.h
new file mode 100644
index 0000000..9051a02
--- /dev/null
+++ b/ndn-cpp/c/util/ndn_memory.h
@@ -0,0 +1,51 @@
+/* 
+ * Author: Jeff Thompson
+ *
+ * BSD license, See the LICENSE file for more information.
+ */
+
+/*
+ * Based on HAVE_MEMCPY and HAVE_MEMSET in config.h, use the library version or a local implementation of memcpy and memset.
+ */
+
+#ifndef NDN_MEMORY_H
+#define	NDN_MEMORY_H
+
+#include "../../../config.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#if HAVE_MEMCPY
+#include <memory.h>
+/**
+ * Use the library version of memcpy.
+ */
+static inline void ndn_memcpy(unsigned char *dest, unsigned char *src, unsigned int len) { memcpy(dest, src, len); }
+#else
+/**
+ * Use a local implementation of memcpy instead of the library version.
+ */
+void ndn_memcpy(unsigned char *dest, unsigned char *src, unsigned int len);
+#endif
+
+#if HAVE_MEMSET
+#include <memory.h>
+/**
+ * Use the library version of memset.
+ */
+static inline void ndn_memset(unsigned char *dest, int val, unsigned int len) { memset(dest, val, len); }
+#else
+/**
+ * Use a local implementation of memset instead of the library version.
+ */
+void ndn_memset(unsigned char *dest, int val, unsigned int len);
+#endif
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif
+