blob: 301e0fe944160e3e0adc41a819f2bd3b55e93546 [file] [log] [blame]
Zhiyi Zhangcea58d52015-08-26 10:19:56 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014-2015, Regents of the University of California
4 *
5 * This file is part of ndn-group-encrypt (Group-based Encryption Protocol for NDN).
6 * See AUTHORS.md for complete list of ndn-group-encrypt authors and contributors.
7 *
8 * ndn-group-encrypt is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * ndn-group-encrypt is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * ndn-group-encrypt, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * @author Zhiyi Zhang <dreamerbarrychang@gmail.com>
20 */
21
22#include "schedule.hpp"
23#include "tlv.hpp"
24
25#include <ndn-cxx/encoding/block-helpers.hpp>
26#include <ndn-cxx/util/concepts.hpp>
27
28namespace ndn {
29namespace gep {
30
31BOOST_CONCEPT_ASSERT((WireEncodable<Schedule>));
32BOOST_CONCEPT_ASSERT((WireDecodable<Schedule>));
33
34Schedule::Schedule() = default;
35
36Schedule::Schedule(const Block& block)
37{
38 wireDecode(block);
39}
40
41template<encoding::Tag TAG>
42size_t
43Schedule::wireEncode(EncodingImpl<TAG>& encoder) const
44{
45 size_t totalLength = 0;
46 size_t blackLength = 0;
47 size_t whiteLength = 0;
48
49 // encode the blackIntervalList as an embed TLV structure
50 for (const RepetitiveInterval& element : m_blackIntervalList) {
51 blackLength += encoder.prependBlock(element.wireEncode());
52 }
53 blackLength += encoder.prependVarNumber(blackLength);
54 blackLength += encoder.prependVarNumber(tlv::BlackIntervalList);
55
56 // encode the whiteIntervalList as an embed TLV structure
57 for (const RepetitiveInterval& element : m_whiteIntervalList) {
58 whiteLength += encoder.prependBlock(element.wireEncode());
59 }
60 whiteLength += encoder.prependVarNumber(whiteLength);
61 whiteLength += encoder.prependVarNumber(tlv::WhiteIntervalList);
62
63 totalLength = whiteLength + blackLength;
64 totalLength += encoder.prependVarNumber(totalLength);
65 totalLength += encoder.prependVarNumber(tlv::Schedule);
66
67 return totalLength;
68}
69
70const Block&
71Schedule::wireEncode() const
72{
73 if (m_wire.hasWire())
74 return m_wire;
75
76 EncodingEstimator estimator;
77 size_t estimatedSize = wireEncode(estimator);
78
79 EncodingBuffer buffer(estimatedSize, 0);
80 wireEncode(buffer);
81
82 this->m_wire = buffer.block();
83 return m_wire;
84}
85
86void
87Schedule::wireDecode(const Block& wire)
88{
89 if (wire.type() != tlv::Schedule)
90 BOOST_THROW_EXCEPTION(tlv::Error("Unexpected TLV type when decoding RepetitiveInterval"));
91
92 m_wire = wire;
93 m_wire.parse();
94
95 if (m_wire.elements_size() != 2)
96 BOOST_THROW_EXCEPTION(tlv::Error("RepetitiveInterval tlv does not have two sub-TLVs"));
97
98 Block::element_const_iterator it = m_wire.elements_begin();
99
100 if (it != m_wire.elements_end() && it->type() == tlv::WhiteIntervalList) {
101 it->parse();
102 Block::element_const_iterator tempIt = it->elements_begin();
103 while (tempIt != it->elements_end() && tempIt->type() == tlv::RepetitiveInterval) {
104 m_whiteIntervalList.insert(RepetitiveInterval(*tempIt));
105 tempIt++;
106 }
107 it++;
108 }
109 else
110 BOOST_THROW_EXCEPTION(tlv::Error("The first element must be WhiteIntervalList"));
111
112 if (it != m_wire.elements_end() && it->type() == tlv::BlackIntervalList) {
113 it->parse();
114 Block::element_const_iterator tempIt = it->elements_begin();
115 while (tempIt != it->elements_end() && tempIt->type() == tlv::RepetitiveInterval) {
116 m_blackIntervalList.insert(RepetitiveInterval(*tempIt));
117 tempIt++;
118 }
119 it++;
120 }
121 else
122 BOOST_THROW_EXCEPTION(tlv::Error("The second element must be BlackIntervalList"));
123}
124
125Schedule&
126Schedule::addWhiteInterval(const RepetitiveInterval& repetitiveInterval)
127{
128 m_whiteIntervalList.insert(repetitiveInterval);
129 return *this;
130}
131
132Schedule&
133Schedule::addBlackInterval(const RepetitiveInterval& repetitiveInterval)
134{
135 m_blackIntervalList.insert(repetitiveInterval);
136 return *this;
137}
138
139Interval
140Schedule::getCoveringInterval(const TimeStamp& tp) const
141{
142 Interval blackResult;
143 Interval whiteResult(true);
144 Interval tempInterval;
145 bool isPositive;
146
147 // get the blackResult
148 for (const RepetitiveInterval& element : m_blackIntervalList) {
149 std::tie(isPositive, tempInterval) = element.getInterval(tp);
150 if (isPositive == true) {
151 // tempInterval is a black repetitive interval covering the time stamp, return empty interval
152 return Interval(true);
153 }
154 else {
155 // tempInterval is not covering the time stamp, && the tempInterval to the blackResult
156 if (!blackResult.isValid())
157 blackResult = tempInterval;
158 else
159 blackResult && tempInterval;
160 }
161 }
162
163 // get the whiteResult
164 for (const RepetitiveInterval& element : m_whiteIntervalList) {
165 std::tie(isPositive, tempInterval) = element.getInterval(tp);
166 if (isPositive == true) {
167 // tempInterval is a white repetitive interval covering the time stamp, || to the white result
168 whiteResult || tempInterval;
169 }
170 }
171
172 return whiteResult && blackResult;
173}
174
175} // namespace gep
176} // namespace ndn