Added writeOptionalTimeMillisecondsDTagElement, which takes double milliseconds
diff --git a/ndn-cpp/c/encoding/BinaryXMLEncoder.c b/ndn-cpp/c/encoding/BinaryXMLEncoder.c
index c2ca154..b7f1db1 100644
--- a/ndn-cpp/c/encoding/BinaryXMLEncoder.c
+++ b/ndn-cpp/c/encoding/BinaryXMLEncoder.c
@@ -4,6 +4,7 @@
  * See COPYING for copyright and distribution information.
  */
 
+#include <math.h>
 #include "../util/ndn_memory.h"
 #include "BinaryXML.h"
 #include "BinaryXMLEncoder.h"
@@ -148,6 +149,27 @@
   return 0;
 }
 
+/**
+ * Split the absolute value of x into 32 bit unsigned integers hi32 and lo32.
+ * We need this because not all C compilers support 64 bit long long integers, so we carry around
+ * a high precision value as a double, which we assume has more than 32 bits.
+ * But we want to do bit-wise operations on integers.
+ * @param x the double value
+ * @param hi32 output the high 32 bits
+ * @param lo32 output the low 32 bits
+ */
+static inline void splitAbsDouble(double x, unsigned long *hi32, unsigned long *lo32)
+{
+  if (x < 0)
+    x = -x;
+  x = round(x);
+  
+  double twoPower32 = 4294967296.0;
+  double lo32Double = fmod(x, twoPower32);
+  *lo32 = (unsigned long)lo32Double;
+  *hi32 = (unsigned long)((x - lo32Double) / twoPower32);
+}
+
 ndn_Error ndn_BinaryXMLEncoder_encodeTypeAndValue(struct ndn_BinaryXMLEncoder *self, unsigned int type, unsigned int value)
 {
 	if (type > ndn_BinaryXML_UDATA)
@@ -251,17 +273,40 @@
   return 0;
 }
 
-ndn_Error ndn_BinaryXMLEncoder_writeUnsignedIntBigEndianBlob(struct ndn_BinaryXMLEncoder *self, unsigned int value)
+ndn_Error ndn_BinaryXMLEncoder_writeAbsDoubleBigEndianBlob(struct ndn_BinaryXMLEncoder *self, double value)
 {
-  // First encode the big endian backwards, then reverse it.
+  unsigned long hi32, lo32;
+  splitAbsDouble(value, &hi32, &lo32);
+  
+  // First encode the big endian backwards, then reverseBufferAndInsertHeader will reverse it.
   unsigned int startOffset = self->offset;
+  
   ndn_Error error;
-  while (value != 0) {
+  while (lo32 != 0) {
     if (error = ndn_DynamicUCharArray_ensureLength(&self->output, self->offset + 1))
       return error;
     
-    self->output.array[self->offset++] = (unsigned char)(value & 0xff);
-    value >>= 8;
+    self->output.array[self->offset++] = (unsigned char)(lo32 & 0xff);
+    lo32 >>= 8;
+  }
+  
+  if (hi32 != 0) {
+    // Pad the lo values out to 4 bytes.
+    while (self->offset - startOffset < 4) {
+      if (error = ndn_DynamicUCharArray_ensureLength(&self->output, self->offset + 1))
+        return error;
+    
+      self->output.array[self->offset++] = 0;
+    }
+    
+    // Encode hi32
+    while (hi32 != 0) {
+      if (error = ndn_DynamicUCharArray_ensureLength(&self->output, self->offset + 1))
+        return error;
+    
+      self->output.array[self->offset++] = (unsigned char)(hi32 & 0xff);
+      hi32 >>= 8;
+    }
   }
   
   if (error = reverseBufferAndInsertHeader(self, startOffset, ndn_BinaryXML_BLOB))
@@ -269,3 +314,18 @@
   
   return 0;
 }
+
+ndn_Error ndn_BinaryXMLEncoder_writeTimeMillisecondsDTagElement(struct ndn_BinaryXMLEncoder *self, unsigned int tag, double milliseconds)
+{
+  ndn_Error error;
+  if (error = ndn_BinaryXMLEncoder_writeElementStartDTag(self, tag))
+    return error;
+   
+  if (error = ndn_BinaryXMLEncoder_writeAbsDoubleBigEndianBlob(self, (milliseconds / 1000.0) * 4096.0))
+    return error;
+    
+  if (error = ndn_BinaryXMLEncoder_writeElementClose(self))
+    return error;
+  
+  return 0;
+}