add logger response

Change-Id: I2a2888eaf27671374ba8ed7f36ca2d1ffb736ea4
diff --git a/core/logger-response.cpp b/core/logger-response.cpp
new file mode 100644
index 0000000..cef7e64
--- /dev/null
+++ b/core/logger-response.cpp
@@ -0,0 +1,131 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California
+ *
+ * This file is part of NSL (NDN Signature Logger).
+ * See AUTHORS.md for complete list of NSL authors and contributors.
+ *
+ * NSL is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NSL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of nsl authors and contributors.
+ */
+
+#include "logger-response.hpp"
+#include "tlv.hpp"
+
+namespace nsl {
+
+LoggerResponse::LoggerResponse()
+  : m_code(-1)
+{
+}
+
+LoggerResponse::LoggerResponse(int32_t code, const std::string& msg)
+  : m_code(code)
+  , m_msg(msg)
+  , m_dataSeqNo(0)
+{
+}
+
+LoggerResponse::LoggerResponse(const NonNegativeInteger& seqNo)
+  : m_code(0)
+  , m_dataSeqNo(seqNo)
+{
+}
+
+template<ndn::encoding::Tag TAG>
+size_t
+LoggerResponse::wireEncode(ndn::EncodingImpl<TAG>& block) const
+{
+  size_t totalLength = 0;
+
+  if (m_code != 0) {
+    totalLength += block.prependByteArrayBlock(tlv::ResultMsg,
+                                               reinterpret_cast<const uint8_t*>(m_msg.c_str()),
+                                               m_msg.size());
+  }
+  else {
+    totalLength += ndn::prependNonNegativeIntegerBlock(block, tlv::DataSeqNo, m_dataSeqNo);
+  }
+  totalLength += ndn::prependNonNegativeIntegerBlock(block, tlv::ResultCode, m_code);
+
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::LogResponse);
+
+  return totalLength;
+}
+
+template size_t
+LoggerResponse::wireEncode<ndn::encoding::EncoderTag>(ndn::EncodingImpl<ndn::encoding::EncoderTag>&) const;
+
+template size_t
+LoggerResponse::wireEncode<ndn::encoding::EstimatorTag>(ndn::EncodingImpl<ndn::encoding::EstimatorTag>&) const;
+
+
+const Block&
+LoggerResponse::wireEncode() const
+{
+  if (m_wire.hasWire())
+    return m_wire;
+
+  ndn::EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  ndn::EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+  return m_wire;
+}
+
+void
+LoggerResponse::wireDecode(const Block& wire)
+{
+  if (!wire.hasWire()) {
+    throw Error("The supplied block does not contain wire format");
+  }
+
+  m_wire = wire;
+  m_wire.parse();
+
+  if (m_wire.type() != tlv::LogResponse)
+    throw tlv::Error("Unexpected TLV type when decoding log response");
+
+  Block::element_const_iterator it = m_wire.elements_begin();
+
+  // the first block must be result code
+  if (it != m_wire.elements_end() && it->type() == tlv::ResultCode) {
+    m_code = readNonNegativeInteger(*it);
+    it++;
+  }
+  else
+    throw Error("The first sub-TLV is not ResultCode");
+
+  // the second block could be result msg
+  if (it == m_wire.elements_end())
+    return;
+  else if (it->type() == tlv::ResultMsg) {
+    m_msg = std::string(reinterpret_cast<const char*>(it->value()), it->value_size());
+    it++;
+  }
+  else if (it->type() == tlv::DataSeqNo) {
+    m_dataSeqNo = readNonNegativeInteger(*it);
+    it++;
+  }
+  else
+    throw Error("The second sub-TLV is not ResultMsg");
+
+  if (it != m_wire.elements_end())
+    throw Error("No more sub-TLV in log response");
+}
+
+} // namespace nsl