face: NDNLP partial message store
refs #1208
Change-Id: Ie10d590ebd2e3631c884a7b6b2d5ffce2758ab4d
diff --git a/daemon/face/ndnlp-parse.cpp b/daemon/face/ndnlp-parse.cpp
new file mode 100644
index 0000000..1162f0e
--- /dev/null
+++ b/daemon/face/ndnlp-parse.cpp
@@ -0,0 +1,68 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "ndnlp-parse.hpp"
+
+namespace nfd {
+namespace ndnlp {
+
+void
+NdnlpData::wireDecode(const Block& wire)
+{
+ if (wire.type() != tlv::NdnlpData) {
+ throw ParseError("top element is not NdnlpData");
+ }
+ wire.parse();
+ const Block::element_container& elements = wire.elements();
+ if (elements.size() < 2) {
+ throw ParseError("NdnlpData element has incorrect number of children");
+ }
+
+ const Block& sequenceElement = elements.front();
+ if (sequenceElement.type() != tlv::NdnlpSequence) {
+ throw ParseError("NdnlpSequence element is missing");
+ }
+ if (sequenceElement.value_size() != sizeof(uint64_t)) {
+ throw ParseError("NdnlpSequence element has incorrect length");
+ }
+ m_seq = be64toh(*reinterpret_cast<const uint64_t*>(&*sequenceElement.value_begin()));
+
+ const Block& payloadElement = elements.back();
+ if (payloadElement.type() != tlv::NdnlpPayload) {
+ throw ParseError("NdnlpPayload element is missing");
+ }
+ m_payload = payloadElement;
+
+ if (elements.size() == 2) { // single wire packet
+ m_fragIndex = 0;
+ m_fragCount = 1;
+ return;
+ }
+ if (elements.size() != 4) {
+ throw ParseError("NdnlpData element has incorrect number of children");
+ }
+
+ const Block& fragIndexElement = elements.at(1);
+ if (fragIndexElement.type() != tlv::NdnlpFragIndex) {
+ throw ParseError("NdnlpFragIndex element is missing");
+ }
+ if (fragIndexElement.value_size() != sizeof(uint16_t)) {
+ throw ParseError("NdnlpFragIndex element has incorrect length");
+ }
+ m_fragIndex = be16toh(*reinterpret_cast<const uint16_t*>(&*fragIndexElement.value_begin()));
+
+ const Block& fragCountElement = elements.at(2);
+ if (fragCountElement.type() != tlv::NdnlpFragCount) {
+ throw ParseError("NdnlpFragCount element is missing");
+ }
+ if (fragCountElement.value_size() != sizeof(uint16_t)) {
+ throw ParseError("NdnlpFragCount element has incorrect length");
+ }
+ m_fragCount = be16toh(*reinterpret_cast<const uint16_t*>(&*fragCountElement.value_begin()));
+}
+
+} // namespace ndnlp
+} // namespace nfd