blob: e6fd4aa2b3639aa29987a21e8f20380902d8a1da [file] [log] [blame]
Eric Newberry261dbc22015-07-22 23:18:18 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2013-2015 Regents of the University of California.
4 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * 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.
10 *
11 * 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.
14 *
15 * 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.
20 */
21
22#ifndef NDN_CXX_LP_DETAIL_FIELD_DECL_HPP
23#define NDN_CXX_LP_DETAIL_FIELD_DECL_HPP
24
25#include "../../common.hpp"
26
27#include "../field.hpp"
28#include "../sequence.hpp"
29#include "../cache-policy.hpp"
30#include "../nack.hpp"
31#include "../tlv.hpp"
32
33#include <boost/concept/requires.hpp>
34
35namespace ndn {
36namespace lp {
37namespace detail {
38
39template<typename TlvType, typename T>
40struct DecodeHelper
41{
42 static
43 BOOST_CONCEPT_REQUIRES(((WireDecodable<T>)), (T))
44 decode(const Block& wire)
45 {
46 if (wire.type() != TlvType::value) {
47 throw ndn::tlv::Error("Unexpected TLV type " + std::to_string(wire.type()));
48 }
49
50 T type;
51 type.wireDecode(wire);
52 return type;
53 }
54};
55
56template<typename TlvType>
57struct DecodeHelper<TlvType, uint64_t>
58{
59 static uint64_t
60 decode(const Block& wire)
61 {
62 if (wire.type() != TlvType::value) {
63 throw ndn::tlv::Error("Unexpected TLV type " + std::to_string(wire.type()));
64 }
65
66 return readNonNegativeInteger(wire);
67 }
68};
69
70template<typename TlvType>
71struct DecodeHelper<TlvType, std::pair<Buffer::const_iterator, Buffer::const_iterator>>
72{
73 static std::pair<Buffer::const_iterator, Buffer::const_iterator>
74 decode(const Block& wire)
75 {
76 if (wire.type() != TlvType::value) {
77 throw ndn::tlv::Error("Unexpected TLV type " + std::to_string(wire.type()));
78 }
79
80 if (wire.value_size() == 0) {
81 throw ndn::tlv::Error(std::to_string(wire.type()) + " must not be empty");
82 }
83
84 return std::make_pair(wire.value_begin(), wire.value_end());
85 }
86};
87
88template<typename encoding::Tag TAG, typename TlvType, typename T>
89struct EncodeHelper
90{
91 static
92 BOOST_CONCEPT_REQUIRES(((WireEncodable<T>)), (size_t))
93 encode(EncodingImpl<TAG>& encoder, const T& value)
94 {
95 return value.wireEncode(encoder);
96 }
97};
98
99template<typename encoding::Tag TAG, typename TlvType>
100struct EncodeHelper<TAG, TlvType, uint64_t>
101{
102 static size_t
103 encode(EncodingImpl<TAG>& encoder, const uint64_t value)
104 {
105 return prependNonNegativeIntegerBlock(encoder, TlvType::value, value);
106 }
107};
108
109template<typename encoding::Tag TAG, typename TlvType>
110struct EncodeHelper<TAG, TlvType, std::pair<Buffer::const_iterator, Buffer::const_iterator>>
111{
112 static size_t
113 encode(EncodingImpl<TAG>& encoder, const std::pair<Buffer::const_iterator, Buffer::const_iterator>& value)
114 {
115 size_t length = 0;
116 length += encoder.prependRange(value.first, value.second);
117 length += encoder.prependVarNumber(length);
118 length += encoder.prependVarNumber(TlvType::value);
119 return length;
120 }
121};
122
123template<typename LOCATION, typename VALUE, uint64_t TYPE, bool REPEATABLE = false>
124class FieldDecl
125{
126public:
127 typedef LOCATION FieldLocation;
128 typedef VALUE ValueType;
129 typedef std::integral_constant<uint64_t, TYPE> TlvType;
130 typedef std::integral_constant<bool, REPEATABLE> IsRepeatable;
131
132 static ValueType
133 decode(const Block& wire)
134 {
135 return DecodeHelper<TlvType, ValueType>::decode(wire);
136 }
137
138 template<typename encoding::Tag TAG, typename T>
139 static size_t
140 encode(EncodingImpl<TAG>& encoder, const T& value)
141 {
142 return EncodeHelper<TAG, TlvType, T>::encode(encoder, value);
143 }
144};
145
146} // namespace detail
147} // namespace lp
148} // namesapce ndn
149
150#endif // NDN_CXX_LP_DETAIL_FIELD_DECL_HPP