blob: 02a3677ce90247de3f4e0636a36e5fd27b19f417 [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 {
Eric Newberry261dbc22015-07-22 23:18:18 -070046 T type;
47 type.wireDecode(wire);
48 return type;
49 }
50};
51
52template<typename TlvType>
53struct DecodeHelper<TlvType, uint64_t>
54{
55 static uint64_t
56 decode(const Block& wire)
57 {
Eric Newberry261dbc22015-07-22 23:18:18 -070058 return readNonNegativeInteger(wire);
59 }
60};
61
62template<typename TlvType>
63struct DecodeHelper<TlvType, std::pair<Buffer::const_iterator, Buffer::const_iterator>>
64{
65 static std::pair<Buffer::const_iterator, Buffer::const_iterator>
66 decode(const Block& wire)
67 {
Eric Newberry261dbc22015-07-22 23:18:18 -070068 if (wire.value_size() == 0) {
Davide Pesavento96b96af2015-09-19 23:00:40 +020069 BOOST_THROW_EXCEPTION(ndn::tlv::Error(to_string(wire.type()) + " must not be empty"));
Eric Newberry261dbc22015-07-22 23:18:18 -070070 }
71
72 return std::make_pair(wire.value_begin(), wire.value_end());
73 }
74};
75
76template<typename encoding::Tag TAG, typename TlvType, typename T>
77struct EncodeHelper
78{
79 static
80 BOOST_CONCEPT_REQUIRES(((WireEncodable<T>)), (size_t))
81 encode(EncodingImpl<TAG>& encoder, const T& value)
82 {
83 return value.wireEncode(encoder);
84 }
85};
86
87template<typename encoding::Tag TAG, typename TlvType>
88struct EncodeHelper<TAG, TlvType, uint64_t>
89{
90 static size_t
91 encode(EncodingImpl<TAG>& encoder, const uint64_t value)
92 {
93 return prependNonNegativeIntegerBlock(encoder, TlvType::value, value);
94 }
95};
96
97template<typename encoding::Tag TAG, typename TlvType>
98struct EncodeHelper<TAG, TlvType, std::pair<Buffer::const_iterator, Buffer::const_iterator>>
99{
100 static size_t
101 encode(EncodingImpl<TAG>& encoder, const std::pair<Buffer::const_iterator, Buffer::const_iterator>& value)
102 {
103 size_t length = 0;
104 length += encoder.prependRange(value.first, value.second);
105 length += encoder.prependVarNumber(length);
106 length += encoder.prependVarNumber(TlvType::value);
107 return length;
108 }
109};
110
111template<typename LOCATION, typename VALUE, uint64_t TYPE, bool REPEATABLE = false>
112class FieldDecl
113{
114public:
115 typedef LOCATION FieldLocation;
116 typedef VALUE ValueType;
117 typedef std::integral_constant<uint64_t, TYPE> TlvType;
118 typedef std::integral_constant<bool, REPEATABLE> IsRepeatable;
119
Eric Newberry83872fd2015-08-06 17:01:24 -0700120 /** \brief decodes a field
121 * \param wire a Block with top-level type \p TYPE
122 * \return value of the field
123 */
Eric Newberry261dbc22015-07-22 23:18:18 -0700124 static ValueType
125 decode(const Block& wire)
126 {
Eric Newberry83872fd2015-08-06 17:01:24 -0700127 if (wire.type() != TlvType::value) {
Junxiao Shi96973542015-09-27 10:30:29 +0000128 BOOST_THROW_EXCEPTION(ndn::tlv::Error("Unexpected TLV type " + to_string(wire.type())));
Eric Newberry83872fd2015-08-06 17:01:24 -0700129 }
130
Eric Newberry261dbc22015-07-22 23:18:18 -0700131 return DecodeHelper<TlvType, ValueType>::decode(wire);
132 }
133
Eric Newberry83872fd2015-08-06 17:01:24 -0700134 /** \brief encodes a field and prepends to \p encoder its Block with top-level type \p TYPE
Alexander Afanasyev45312f52015-09-27 12:06:50 -0700135 * \param encoder Instance of the buffer encoder or buffer estimator
Eric Newberry83872fd2015-08-06 17:01:24 -0700136 * \param value value of the field
137 */
Eric Newberry261dbc22015-07-22 23:18:18 -0700138 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
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700150#endif // NDN_CXX_LP_DETAIL_FIELD_DECL_HPP