blob: fa584afda2050c41b87aa37e2ed843480671c3bf [file] [log] [blame]
Eric Newberry261dbc22015-07-22 23:18:18 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Teng Liang02960742017-10-24 00:36:45 -07002/*
Teng Liang5b323d12018-01-31 18:50:45 -07003 * Copyright (c) 2013-2018 Regents of the University of California.
Eric Newberry261dbc22015-07-22 23:18:18 -07004 *
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
Alexander Afanasyeve3874232017-03-26 16:58:59 -050022#ifndef NDN_CXX_LP_FIELD_DECL_HPP
23#define NDN_CXX_LP_FIELD_DECL_HPP
Eric Newberry261dbc22015-07-22 23:18:18 -070024
Teng Liang02960742017-10-24 00:36:45 -070025#include "empty-value.hpp"
Alexander Afanasyeve3874232017-03-26 16:58:59 -050026#include "field.hpp"
27#include "tlv.hpp"
Eric Newberry261dbc22015-07-22 23:18:18 -070028
Alexander Afanasyeve3874232017-03-26 16:58:59 -050029#include "../encoding/block-helpers.hpp"
30#include "../util/concepts.hpp"
Eric Newberry261dbc22015-07-22 23:18:18 -070031#include <boost/concept/requires.hpp>
32
33namespace ndn {
34namespace lp {
Eric Newberry261dbc22015-07-22 23:18:18 -070035
36template<typename TlvType, typename T>
37struct DecodeHelper
38{
39 static
40 BOOST_CONCEPT_REQUIRES(((WireDecodable<T>)), (T))
41 decode(const Block& wire)
42 {
Eric Newberry261dbc22015-07-22 23:18:18 -070043 T type;
44 type.wireDecode(wire);
45 return type;
46 }
47};
48
49template<typename TlvType>
Teng Liang02960742017-10-24 00:36:45 -070050struct DecodeHelper<TlvType, EmptyValue>
51{
52 static EmptyValue
53 decode(const Block& wire)
54 {
55 if (wire.value_size() != 0) {
56 BOOST_THROW_EXCEPTION(ndn::tlv::Error("NDNLP field of TLV-TYPE " + to_string(wire.type()) +
57 " must be empty"));
58 }
59
60 return EmptyValue{};
61 }
62};
63
64template<typename TlvType>
Eric Newberry261dbc22015-07-22 23:18:18 -070065struct DecodeHelper<TlvType, uint64_t>
66{
67 static uint64_t
68 decode(const Block& wire)
69 {
Eric Newberry261dbc22015-07-22 23:18:18 -070070 return readNonNegativeInteger(wire);
71 }
72};
73
74template<typename TlvType>
75struct DecodeHelper<TlvType, std::pair<Buffer::const_iterator, Buffer::const_iterator>>
76{
77 static std::pair<Buffer::const_iterator, Buffer::const_iterator>
78 decode(const Block& wire)
79 {
Eric Newberry261dbc22015-07-22 23:18:18 -070080 if (wire.value_size() == 0) {
Teng Liang02960742017-10-24 00:36:45 -070081 BOOST_THROW_EXCEPTION(ndn::tlv::Error("NDNLP field of TLV-TYPE " + to_string(wire.type()) +
82 " cannot be empty"));
Eric Newberry261dbc22015-07-22 23:18:18 -070083 }
84
85 return std::make_pair(wire.value_begin(), wire.value_end());
86 }
87};
88
89template<typename encoding::Tag TAG, typename TlvType, typename T>
90struct EncodeHelper
91{
92 static
Teng Liang5b323d12018-01-31 18:50:45 -070093 BOOST_CONCEPT_REQUIRES(((WireEncodableWithEncodingBuffer<T>)), (size_t))
Eric Newberry261dbc22015-07-22 23:18:18 -070094 encode(EncodingImpl<TAG>& encoder, const T& value)
95 {
96 return value.wireEncode(encoder);
97 }
98};
99
100template<typename encoding::Tag TAG, typename TlvType>
Teng Liang02960742017-10-24 00:36:45 -0700101struct EncodeHelper<TAG, TlvType, EmptyValue>
102{
103 static size_t
104 encode(EncodingImpl<TAG>& encoder, const EmptyValue value)
105 {
106 size_t length = 0;
107 length += encoder.prependVarNumber(0);
108 length += encoder.prependVarNumber(TlvType::value);
109 return length;
110 }
111};
112
113template<typename encoding::Tag TAG, typename TlvType>
Eric Newberry261dbc22015-07-22 23:18:18 -0700114struct EncodeHelper<TAG, TlvType, uint64_t>
115{
116 static size_t
117 encode(EncodingImpl<TAG>& encoder, const uint64_t value)
118 {
119 return prependNonNegativeIntegerBlock(encoder, TlvType::value, value);
120 }
121};
122
123template<typename encoding::Tag TAG, typename TlvType>
124struct EncodeHelper<TAG, TlvType, std::pair<Buffer::const_iterator, Buffer::const_iterator>>
125{
126 static size_t
127 encode(EncodingImpl<TAG>& encoder, const std::pair<Buffer::const_iterator, Buffer::const_iterator>& value)
128 {
129 size_t length = 0;
130 length += encoder.prependRange(value.first, value.second);
131 length += encoder.prependVarNumber(length);
132 length += encoder.prependVarNumber(TlvType::value);
133 return length;
134 }
135};
136
137template<typename LOCATION, typename VALUE, uint64_t TYPE, bool REPEATABLE = false>
138class FieldDecl
139{
140public:
141 typedef LOCATION FieldLocation;
142 typedef VALUE ValueType;
143 typedef std::integral_constant<uint64_t, TYPE> TlvType;
144 typedef std::integral_constant<bool, REPEATABLE> IsRepeatable;
145
Eric Newberry83872fd2015-08-06 17:01:24 -0700146 /** \brief decodes a field
147 * \param wire a Block with top-level type \p TYPE
148 * \return value of the field
149 */
Eric Newberry261dbc22015-07-22 23:18:18 -0700150 static ValueType
151 decode(const Block& wire)
152 {
Eric Newberry83872fd2015-08-06 17:01:24 -0700153 if (wire.type() != TlvType::value) {
Junxiao Shi96973542015-09-27 10:30:29 +0000154 BOOST_THROW_EXCEPTION(ndn::tlv::Error("Unexpected TLV type " + to_string(wire.type())));
Eric Newberry83872fd2015-08-06 17:01:24 -0700155 }
156
Eric Newberry261dbc22015-07-22 23:18:18 -0700157 return DecodeHelper<TlvType, ValueType>::decode(wire);
158 }
159
Eric Newberry83872fd2015-08-06 17:01:24 -0700160 /** \brief encodes a field and prepends to \p encoder its Block with top-level type \p TYPE
Alexander Afanasyev45312f52015-09-27 12:06:50 -0700161 * \param encoder Instance of the buffer encoder or buffer estimator
Eric Newberry83872fd2015-08-06 17:01:24 -0700162 * \param value value of the field
163 */
Eric Newberry261dbc22015-07-22 23:18:18 -0700164 template<typename encoding::Tag TAG, typename T>
165 static size_t
166 encode(EncodingImpl<TAG>& encoder, const T& value)
167 {
168 return EncodeHelper<TAG, TlvType, T>::encode(encoder, value);
169 }
170};
171
Eric Newberry261dbc22015-07-22 23:18:18 -0700172} // namespace lp
Junxiao Shi09bcab52016-07-18 02:43:34 +0000173} // namespace ndn
Eric Newberry261dbc22015-07-22 23:18:18 -0700174
Alexander Afanasyeve3874232017-03-26 16:58:59 -0500175#endif // NDN_CXX_LP_FIELD_DECL_HPP