data: Converting Data packet and related fields to TLV

Change-Id: Ie7a6db7352384f14a830046e65a953a2d9bbb71c
diff --git a/include/ndn-cpp/data.hpp b/include/ndn-cpp/data.hpp
index a227c7f..1fb098f 100644
--- a/include/ndn-cpp/data.hpp
+++ b/include/ndn-cpp/data.hpp
@@ -10,51 +10,94 @@
 
 #include "common.hpp"
 #include "name.hpp"
-#include "util/signed-blob.hpp"
-#include "c/data-types.h"
-#include "encoding/wire-format.hpp"
+#include "encoding/block.hpp"
 
-struct ndn_MetaInfo;
-struct ndn_Signature;
-struct ndn_Data;
 
 namespace ndn {
 
 /**
- * A Signature is an abstract base class providing methods to work with the signature information in a Data packet.
- * You must create an object of a subclass, for example Sha256WithRsaSignature.
+ * A Signature is storage for the signature-related information (info and value) in a Data packet.
  */
 class Signature {
 public:
-  /**
-   * Return a pointer to a new Signature which is a copy of this signature.
-   * This is pure virtual, the subclass must implement it.
-   */
-  virtual ptr_lib::shared_ptr<Signature> 
-  clone() const = 0;
+  enum {
+    DigestSha256 = 0,
+    SignatureSha256WithRsa = 1
+  };
   
-  /**
-   * The virtual destructor.
-   */
-  virtual 
-  ~Signature();
+  Signature()
+    : type_(-1)
+  {
+  }
   
-    /**
-   * Set the signatureStruct to point to the values in this signature object, without copying any memory.
-   * WARNING: The resulting pointers in signatureStruct are invalid after a further use of this object which could reallocate memory.
-   * This is pure virtual, the subclass must implement it.
-   * @param signatureStruct a C ndn_Signature struct where the name components array is already allocated.
-   */
-  virtual void 
-  get(struct ndn_Signature& signatureStruct) const = 0;
+  Signature(const Block &info, const Block &value)
+    : info_(info)
+    , value_(value)
+  {
+    Buffer::const_iterator i = info_.value_begin();
+    type_ = Tlv::readVarNumber(i, info_.value_end());
+  }
 
-  /**
-   * Clear this signature, and set the values by copying from the ndn_Signature struct.
-   * This is pure virtual, the subclass must implement it.
-   * @param signatureStruct a C ndn_Signature struct
-   */
-  virtual void 
-  set(const struct ndn_Signature& signatureStruct) = 0;
+  operator bool() const
+  {
+    return type_ != -1;
+  }
+
+  uint32_t
+  getType() const
+  {
+    return type_;
+  }
+  
+  const Block&
+  getInfo() const
+  {
+    return info_;
+  }
+
+  void
+  setInfo(const Block &info)
+  {
+    info_ = info;
+    if (info_.hasWire() || info_.hasValue())
+      {
+        info_.parse();
+        const Block &signatureType = info_.get(Tlv::SignatureType);
+        
+        Buffer::const_iterator i = signatureType.value_begin();
+        type_ = Tlv::readVarNumber(i, signatureType.value_end());
+      }
+    else
+      {
+        type_ = -1;
+      }
+  }  
+
+  const Block&
+  getValue() const
+  {
+    return value_;
+  }
+
+  void
+  setValue(const Block &value)
+  {
+    value_ = value;
+  }
+
+  void
+  reset()
+  {
+    type_ = -1;
+    info_.reset();
+    value_.reset();
+  }
+
+private:
+  int32_t type_;
+  
+  Block info_;
+  Block value_;
 };
 
 /**
@@ -62,56 +105,39 @@
  */
 class MetaInfo {
 public:
-  MetaInfo() 
+  enum {
+    TYPE_DEFAULT = 0,
+    TYPE_LINK = 1,
+    TYPE_KEY = 2
+  };
+  
+  MetaInfo()
+    : type_(TYPE_DEFAULT)
+    , freshnessPeriod_(-1)
   {   
-    type_ = ndn_ContentType_DATA;
-    freshnessSeconds_ = -1;
   }
+  
+  uint32_t 
+  getType() const
+  { return type_; }
+  
+  void 
+  setType(uint32_t type)
+  { type_ = type; }
+  
+  Milliseconds 
+  getFreshnessPeriod() const
+  { return freshnessPeriod_; }
+  
+  void 
+  setFreshnessPeriod(Milliseconds freshnessPeriod)
+  { freshnessPeriod_ = freshnessPeriod; }
 
-  /**
-   * Set the metaInfoStruct to point to the values in this meta info object, without copying any memory.
-   * WARNING: The resulting pointers in metaInfoStruct are invalid after a further use of this object which could reallocate memory.
-   * @param metaInfoStruct a C ndn_MetaInfo struct where the name components array is already allocated.
-   */
-  void 
-  get(struct ndn_MetaInfo& metaInfoStruct) const;
-
-  /**
-   * Clear this meta info, and set the values by copying from the ndn_MetaInfo struct.
-   * @param metaInfoStruct a C ndn_MetaInfo struct
-   */
-  void 
-  set(const struct ndn_MetaInfo& metaInfoStruct);
-
-  MillisecondsSince1970 
-  getTimestampMilliseconds() const { return timestampMilliseconds_; }
-  
-  ndn_ContentType 
-  getType() const { return type_; }
-  
-  int 
-  getFreshnessSeconds() const { return freshnessSeconds_; }
-  
-  const Name::Component& 
-  getFinalBlockID() const { return finalBlockID_; }
-  
-  void 
-  setTimestampMilliseconds(MillisecondsSince1970 timestampMilliseconds) { timestampMilliseconds_ = timestampMilliseconds; }
-  
-  void 
-  setType(ndn_ContentType type) { type_ = type; }
-  
-  void 
-  setFreshnessSeconds(int freshnessSeconds) { freshnessSeconds_ = freshnessSeconds; }
-
-  void 
-  setFinalBlockID(const Name::Component& finalBlockID) { finalBlockID_ = finalBlockID; }
-    
 private:
-  MillisecondsSince1970 timestampMilliseconds_; /**< milliseconds since 1/1/1970. -1 for none */
-  ndn_ContentType type_;         /**< default is ndn_ContentType_DATA. -1 for none */
-  int freshnessSeconds_;         /**< -1 for none */
-  Name::Component finalBlockID_; /** size 0 for none */
+  uint32_t type_;
+  Milliseconds freshnessPeriod_;
+
+  Block wire_;
 };
   
 class Data {
@@ -119,31 +145,25 @@
   /**
    * Create a new Data object with default values and where the signature is a blank Sha256WithRsaSignature.
    */
-  Data();
+  Data()
+  {
+  }
 
   /**
    * Create a new Data object with the given name and default values and where the signature is a blank Sha256WithRsaSignature.
    * @param name A reference to the name which is copied.
    */
-  Data(const Name& name);
-  
-  /**
-   * The copy constructor: Create a deep copy of the given data object, including a clone of the signature object.
-   * @param data The data object to copy.
-   */
-  Data(const Data& data);
+  Data(const Name& name)
+    : name_(name)
+  {
+  }
   
   /**
    * The virtual destructor.
    */
-  virtual ~Data();
-  
-  /**
-   * The assignment operator: Copy fields and make a clone of the signature.
-   * @param data The other object to copy from.
-   * @return A reference to this object.
-   */
-  Data& operator=(const Data& data);
+  virtual ~Data()
+  {
+  }
   
   /**
    * Encode this Data for a particular wire format. If wireFormat is the default wire format, also set the defaultWireEncoding 
@@ -152,8 +172,11 @@
    * @param wireFormat A WireFormat object used to encode the input. If omitted, use WireFormat getDefaultWireFormat().
    * @return The encoded byte array.
    */
-  SignedBlob 
-  wireEncode(WireFormat& wireFormat = *WireFormat::getDefaultWireFormat()) const;
+  const Block& 
+  wireEncode() const;
+  
+  void
+  wireDecode(const Block &wire);
   
   /**
    * Decode the input using a particular wire format and update this Data. If wireFormat is the default wire format, also 
@@ -162,155 +185,127 @@
    * @param inputLength The length of input.
    * @param wireFormat A WireFormat object used to decode the input. If omitted, use WireFormat getDefaultWireFormat().
    */
-  void 
-  wireDecode(const uint8_t* input, size_t inputLength, WireFormat& wireFormat = *WireFormat::getDefaultWireFormat());
-  
-  /**
-   * Decode the input using a particular wire format and update this Data. If wireFormat is the default wire format, also 
-   * set the defaultWireEncoding field to the input.
-   * @param input The input byte array to be decoded.
-   * @param wireFormat A WireFormat object used to decode the input. If omitted, use WireFormat getDefaultWireFormat().
-   */
-  void 
-  wireDecode(const std::vector<uint8_t>& input, WireFormat& wireFormat = *WireFormat::getDefaultWireFormat()) 
+  void
+  wireDecode(const uint8_t* input, size_t inputLength);
+
+  const Signature&
+  getSignature() const
   {
-    wireDecode(&input[0], input.size(), wireFormat);
+    return signature_;
   }
   
   /**
-   * Set the dataStruct to point to the values in this interest, without copying any memory.
-   * WARNING: The resulting pointers in dataStruct are invalid after a further use of this object which could reallocate memory.
-   * @param dataStruct a C ndn_Data struct where the name components array is already allocated.
-   */
-  void 
-  get(struct ndn_Data& dataStruct) const;
-
-  /**
-   * Clear this data object, and set the values by copying from the ndn_Data struct.
-   * @param dataStruct a C ndn_Data struct
-   */
-  void 
-  set(const struct ndn_Data& dataStruct);
-
-  const Signature* 
-  getSignature() const { return signature_.get(); }
-  
-  Signature* 
-  getSignature() 
-  { 
-    // TODO: Should add an OnChanged listener instead of always calling onChanged.
-    onChanged();
-    return signature_.get(); 
-  }
-  
-  const Name& 
-  getName() const { return name_; }
-  
-  Name& 
-  getName() 
-  { 
-    // TODO: Should add an OnChanged listener instead of always calling onChanged.
-    onChanged();
-    return name_; 
-  }
-  
-  const MetaInfo& 
-  getMetaInfo() const { return metaInfo_; }
-  
-  MetaInfo& 
-  getMetaInfo() 
-  { 
-    // TODO: Should add an OnChanged listener instead of always calling onChanged.
-    onChanged();
-    return metaInfo_; 
-  }
-  
-  const Blob& 
-  getContent() const { return content_; }
-
-  /**
-   * Return a pointer to the defaultWireEncoding.  It may be null.
-   */
-  const SignedBlob&
-  getDefaultWireEncoding() const { return defaultWireEncoding_; }
-  
-  /**
    * Set the signature to a copy of the given signature.
    * @param signature The signature object which is cloned.
    * @return This Data so that you can chain calls to update values.
    */
   Data& 
   setSignature(const Signature& signature) 
-  { 
-    signature_ = signature.clone(); 
+  {
+    signature_ = signature;
     onChanged();
     return *this;
   }
   
+  const Name& 
+  getName() const
+  {
+    return name_;
+  }
+  
   /**
    * Set name to a copy of the given Name.  This is virtual so that a subclass can override to validate the name.
    * @param name The Name which is copied.
    * @return This Data so that you can chain calls to update values.
    */
-  virtual Data& 
-  setName(const Name& name);
+  void
+  setName(const Name& name)
+  { 
+    name_ = name; 
+    onChanged();
+  }
+  
+  const MetaInfo& 
+  getMetaInfo() const { return metaInfo_; }
   
   /**
    * Set metaInfo to a copy of the given MetaInfo.
    * @param metaInfo The MetaInfo which is copied.
    * @return This Data so that you can chain calls to update values.
    */
-  Data& 
+  void
   setMetaInfo(const MetaInfo& metaInfo) 
   { 
     metaInfo_ = metaInfo; 
     onChanged();
-    return *this;
   }
 
+  const Block& 
+  getContent() const { return content_; }
+
   /**
    * Set the content to a copy of the data in the vector.
    * @param content A vector whose contents are copied.
    * @return This Data so that you can chain calls to update values.
    */
-  Data& 
+  void
   setContent(const std::vector<uint8_t>& content) 
-  { 
-    content_ = content; 
+  {
+    setContent(&content[0], content.size());
     onChanged();
-    return *this;
   }
   
-  Data& 
+  void
   setContent(const uint8_t* content, size_t contentLength) 
-  { 
-    content_ = Blob(content, contentLength); 
+  {
+    OBufferStream os;
+    Tlv::writeVarNumber(os, Tlv::Content);
+    Tlv::writeVarNumber(os, contentLength);
+    os.write(reinterpret_cast<const char *>(content), contentLength);
+    
+    content_ = Block(os.buf());
     onChanged();
-    return *this;
   }
-      
-  Data& 
-  setContent(const Blob& content) 
+
+  void
+  setContent(const ConstBufferPtr &contentValue)
+  {
+    content_ = Block(Tlv::Content, contentValue); // not real a wire encoding yet
+    onChanged();
+  }
+  
+  void
+  setContent(const Block& content) 
   { 
     content_ = content;
     onChanged();
-    return *this;
   }
 
 private:
   /**
    * Clear the wire encoding.
    */
-  void 
+  inline void 
   onChanged();
-  
-  ptr_lib::shared_ptr<Signature> signature_;
+
+private:
   Name name_;
   MetaInfo metaInfo_;
-  Blob content_;
-  SignedBlob defaultWireEncoding_;
+  Block content_;
+  Signature signature_;
+
+  Block wire_;
 };
-  
+
+
+inline void 
+Data::onChanged()
+{
+  // The values have changed, so the signature and wire format is invalidated
+  signature_.reset();
+  wire_.reset();
 }
 
+} // namespace ndn
+
 #endif