blob: 5ce4fc5c082cef962bbed531f69fc096b7bd3e29 [file] [log] [blame]
Junxiao Shid6dcd2c2014-02-16 14:49:54 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (C) 2014 Named Data Networking Project
4 * See COPYING for copyright and distribution information.
5 */
6
7#include "ndnlp-parse.hpp"
8
9namespace nfd {
10namespace ndnlp {
11
12void
13NdnlpData::wireDecode(const Block& wire)
14{
15 if (wire.type() != tlv::NdnlpData) {
16 throw ParseError("top element is not NdnlpData");
17 }
18 wire.parse();
19 const Block::element_container& elements = wire.elements();
20 if (elements.size() < 2) {
21 throw ParseError("NdnlpData element has incorrect number of children");
22 }
Junxiao Shidf3b4382014-02-23 11:28:21 -070023
Junxiao Shid6dcd2c2014-02-16 14:49:54 -070024 const Block& sequenceElement = elements.front();
25 if (sequenceElement.type() != tlv::NdnlpSequence) {
26 throw ParseError("NdnlpSequence element is missing");
27 }
28 if (sequenceElement.value_size() != sizeof(uint64_t)) {
29 throw ParseError("NdnlpSequence element has incorrect length");
30 }
31 m_seq = be64toh(*reinterpret_cast<const uint64_t*>(&*sequenceElement.value_begin()));
Junxiao Shidf3b4382014-02-23 11:28:21 -070032
Junxiao Shid6dcd2c2014-02-16 14:49:54 -070033 const Block& payloadElement = elements.back();
34 if (payloadElement.type() != tlv::NdnlpPayload) {
35 throw ParseError("NdnlpPayload element is missing");
36 }
37 m_payload = payloadElement;
38
39 if (elements.size() == 2) { // single wire packet
40 m_fragIndex = 0;
41 m_fragCount = 1;
42 return;
43 }
44 if (elements.size() != 4) {
45 throw ParseError("NdnlpData element has incorrect number of children");
46 }
Junxiao Shidf3b4382014-02-23 11:28:21 -070047
Junxiao Shid6dcd2c2014-02-16 14:49:54 -070048 const Block& fragIndexElement = elements.at(1);
49 if (fragIndexElement.type() != tlv::NdnlpFragIndex) {
50 throw ParseError("NdnlpFragIndex element is missing");
51 }
Junxiao Shidf3b4382014-02-23 11:28:21 -070052 uint64_t fragIndex = ndn::readNonNegativeInteger(fragIndexElement);
53 if (fragIndex > std::numeric_limits<uint16_t>::max()) {
54 throw ParseError("NdnlpFragIndex is too large");
Junxiao Shid6dcd2c2014-02-16 14:49:54 -070055 }
Junxiao Shidf3b4382014-02-23 11:28:21 -070056 m_fragIndex = static_cast<uint16_t>(fragIndex);
57
Junxiao Shid6dcd2c2014-02-16 14:49:54 -070058 const Block& fragCountElement = elements.at(2);
59 if (fragCountElement.type() != tlv::NdnlpFragCount) {
60 throw ParseError("NdnlpFragCount element is missing");
61 }
Junxiao Shidf3b4382014-02-23 11:28:21 -070062 uint64_t fragCount = ndn::readNonNegativeInteger(fragCountElement);
63 if (fragCount > std::numeric_limits<uint16_t>::max()) {
64 throw ParseError("NdnlpFragCount is too large");
Junxiao Shid6dcd2c2014-02-16 14:49:54 -070065 }
Junxiao Shidf3b4382014-02-23 11:28:21 -070066 m_fragCount = static_cast<uint16_t>(fragCount);
67
68 if (m_fragIndex >= m_fragCount) {
69 throw ParseError("NdnlpFragIndex must be less than NdnlpFragCount");
70 }
Junxiao Shid6dcd2c2014-02-16 14:49:54 -070071}
72
73} // namespace ndnlp
74} // namespace nfd