blob: c3bc3329ef84bc6b86041d175a2351a40229033e [file] [log] [blame]
Yanbiao Li8ee37ed2015-05-19 12:44:04 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev80b68e12015-09-17 17:01:04 -07003 * Copyright (c) 2013-2015 Regents of the University of California.
Yanbiao Li8ee37ed2015-05-19 12:44:04 -07004 *
Alexander Afanasyev80b68e12015-09-17 17:01:04 -07005 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Yanbiao Li8ee37ed2015-05-19 12:44:04 -07006 *
Alexander Afanasyev80b68e12015-09-17 17:01:04 -07007 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070010 *
Alexander Afanasyev80b68e12015-09-17 17:01:04 -070011 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070014 *
Alexander Afanasyev80b68e12015-09-17 17:01:04 -070015 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070020 */
21
22#include "status-dataset-context.hpp"
23
24namespace ndn {
25namespace mgmt {
26
27const time::milliseconds DEFAULT_STATUS_DATASET_FRESHNESS_PERIOD = time::milliseconds(1000);
28
29const Name&
30StatusDatasetContext::getPrefix() const
31{
32 return m_prefix;
33}
34
35StatusDatasetContext&
36StatusDatasetContext::setPrefix(const Name& prefix)
37{
38 if (!m_interest.getName().isPrefixOf(prefix)) {
39 BOOST_THROW_EXCEPTION(std::invalid_argument("prefix does not start with Interest Name"));
40 }
41
42 if (m_state != State::INITIAL) {
43 BOOST_THROW_EXCEPTION(std::domain_error("state is not in INITIAL"));
44 }
45
46 m_prefix = prefix;
47
48 if (!m_prefix[-1].isVersion()) {
49 m_prefix.appendVersion();
50 }
51
52 return *this;
53}
54
55const time::milliseconds&
56StatusDatasetContext::getExpiry() const
57{
58 return m_expiry;
59}
60
61StatusDatasetContext&
62StatusDatasetContext::setExpiry(const time::milliseconds& expiry)
63{
64 m_expiry = expiry;
65 return *this;
66}
67
68void
69StatusDatasetContext::append(const Block& block)
70{
71 if (m_state == State::FINALIZED) {
72 BOOST_THROW_EXCEPTION(std::domain_error("state is in FINALIZED"));
73 }
74
75 m_state = State::RESPONDED;
76
77 size_t nBytesLeft = block.size();
78
79 while (nBytesLeft > 0) {
80 size_t nBytesAppend = std::min(nBytesLeft,
81 (ndn::MAX_NDN_PACKET_SIZE >> 1) - m_buffer->size());
82 m_buffer->appendByteArray(block.wire() + (block.size() - nBytesLeft), nBytesAppend);
83 nBytesLeft -= nBytesAppend;
84
85 if (nBytesLeft > 0) {
86 const Block& content = makeBinaryBlock(tlv::Content, m_buffer->buf(), m_buffer->size());
87 m_dataSender(Name(m_prefix).appendSegment(m_segmentNo++), content,
88 MetaInfo().setFreshnessPeriod(m_expiry));
89
90 m_buffer = std::make_shared<EncodingBuffer>();
91 }
92 }
93}
94
95void
96StatusDatasetContext::end()
97{
98 if (m_state == State::FINALIZED) {
99 BOOST_THROW_EXCEPTION(std::domain_error("state is in FINALIZED"));
100 }
101
102 m_state = State::FINALIZED;
103
104 auto dataName = Name(m_prefix).appendSegment(m_segmentNo++);
105 m_dataSender(dataName, makeBinaryBlock(tlv::Content, m_buffer->buf(), m_buffer->size()),
106 MetaInfo().setFreshnessPeriod(m_expiry).setFinalBlockId(dataName[-1]));
107}
108
109void
110StatusDatasetContext::reject(const ControlResponse& resp /*= a ControlResponse with 400*/)
111{
112 if (m_state != State::INITIAL) {
113 BOOST_THROW_EXCEPTION(std::domain_error("state is in REPONSED or FINALIZED"));
114 }
115
116 m_state = State::FINALIZED;
117
118 m_dataSender(m_interest.getName(), resp.wireEncode(),
119 MetaInfo().setType(tlv::ContentType_Nack));
120}
121
122StatusDatasetContext::StatusDatasetContext(const Interest& interest,
123 const DataSender& dataSender)
124 : m_interest(interest)
125 , m_dataSender(dataSender)
126 , m_expiry(DEFAULT_STATUS_DATASET_FRESHNESS_PERIOD)
127 , m_buffer(make_shared<EncodingBuffer>())
128 , m_segmentNo(0)
129 , m_state(State::INITIAL)
130{
131 setPrefix(interest.getName());
132}
133
134} // namespace mgmt
135} // namespace ndn