face: perform wire format encoding in frontend class

Face::put encodes Data and Nack into wire format before passing to Impl class,
so that Face::put(const Data&) doesn't require the Data to be managed by a
shared_ptr.
For the common case of sending Data without other NDNLPv2 headers, this commit
adds an optimization that the Data is not copied into an LpPacket, but directly
encodes into wire format.

refs #3678

Change-Id: I7ac7bb574a5cb3b07f6c62060809c94ff1cf3dee
diff --git a/tests/unit-tests/face.t.cpp b/tests/unit-tests/face.t.cpp
index 42def58..6e81644 100644
--- a/tests/unit-tests/face.t.cpp
+++ b/tests/unit-tests/face.t.cpp
@@ -304,13 +304,32 @@
 
 BOOST_AUTO_TEST_SUITE(Producer)
 
+BOOST_AUTO_TEST_CASE(PutData)
+{
+  BOOST_CHECK_EQUAL(face.sentData.size(), 0);
+
+  Data data("/4g7xxcuEow/KFvK5Kf2m");
+  signData(data);
+  face.put(data);
+
+  lp::CachePolicy cachePolicy;
+  cachePolicy.setPolicy(lp::CachePolicyType::NO_CACHE);
+  data.setTag(make_shared<lp::CachePolicyTag>(cachePolicy));
+  face.put(data);
+
+  advanceClocks(time::milliseconds(10));
+  BOOST_REQUIRE_EQUAL(face.sentData.size(), 2);
+  BOOST_CHECK(face.sentData[0].getTag<lp::CachePolicyTag>() == nullptr);
+  BOOST_CHECK(face.sentData[1].getTag<lp::CachePolicyTag>() != nullptr);
+}
+
 BOOST_AUTO_TEST_CASE(PutNack)
 {
   BOOST_CHECK_EQUAL(face.sentNacks.size(), 0);
 
   face.put(makeNack(Interest("/Hello/World", time::milliseconds(50)), lp::NackReason::NO_ROUTE));
-  advanceClocks(time::milliseconds(10));
 
+  advanceClocks(time::milliseconds(10));
   BOOST_CHECK_EQUAL(face.sentNacks.size(), 1);
 }