blob: 44df43171f6e132a0fa9d4a49e0818d7ade5cb3e [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
Eric Newberry261dbc22015-07-22 23:18:18 -070025#include "../field.hpp"
Eric Newberry261dbc22015-07-22 23:18:18 -070026#include "../tlv.hpp"
27
Junxiao Shi4b469982015-12-03 18:20:19 +000028#include "../../encoding/block-helpers.hpp"
29#include "../../util/concepts.hpp"
Eric Newberry261dbc22015-07-22 23:18:18 -070030#include <boost/concept/requires.hpp>
31
32namespace ndn {
33namespace lp {
34namespace detail {
35
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>
50struct DecodeHelper<TlvType, uint64_t>
51{
52 static uint64_t
53 decode(const Block& wire)
54 {
Eric Newberry261dbc22015-07-22 23:18:18 -070055 return readNonNegativeInteger(wire);
56 }
57};
58
59template<typename TlvType>
60struct DecodeHelper<TlvType, std::pair<Buffer::const_iterator, Buffer::const_iterator>>
61{
62 static std::pair<Buffer::const_iterator, Buffer::const_iterator>
63 decode(const Block& wire)
64 {
Eric Newberry261dbc22015-07-22 23:18:18 -070065 if (wire.value_size() == 0) {
Davide Pesavento96b96af2015-09-19 23:00:40 +020066 BOOST_THROW_EXCEPTION(ndn::tlv::Error(to_string(wire.type()) + " must not be empty"));
Eric Newberry261dbc22015-07-22 23:18:18 -070067 }
68
69 return std::make_pair(wire.value_begin(), wire.value_end());
70 }
71};
72
73template<typename encoding::Tag TAG, typename TlvType, typename T>
74struct EncodeHelper
75{
76 static
77 BOOST_CONCEPT_REQUIRES(((WireEncodable<T>)), (size_t))
78 encode(EncodingImpl<TAG>& encoder, const T& value)
79 {
80 return value.wireEncode(encoder);
81 }
82};
83
84template<typename encoding::Tag TAG, typename TlvType>
85struct EncodeHelper<TAG, TlvType, uint64_t>
86{
87 static size_t
88 encode(EncodingImpl<TAG>& encoder, const uint64_t value)
89 {
90 return prependNonNegativeIntegerBlock(encoder, TlvType::value, value);
91 }
92};
93
94template<typename encoding::Tag TAG, typename TlvType>
95struct EncodeHelper<TAG, TlvType, std::pair<Buffer::const_iterator, Buffer::const_iterator>>
96{
97 static size_t
98 encode(EncodingImpl<TAG>& encoder, const std::pair<Buffer::const_iterator, Buffer::const_iterator>& value)
99 {
100 size_t length = 0;
101 length += encoder.prependRange(value.first, value.second);
102 length += encoder.prependVarNumber(length);
103 length += encoder.prependVarNumber(TlvType::value);
104 return length;
105 }
106};
107
108template<typename LOCATION, typename VALUE, uint64_t TYPE, bool REPEATABLE = false>
109class FieldDecl
110{
111public:
112 typedef LOCATION FieldLocation;
113 typedef VALUE ValueType;
114 typedef std::integral_constant<uint64_t, TYPE> TlvType;
115 typedef std::integral_constant<bool, REPEATABLE> IsRepeatable;
116
Eric Newberry83872fd2015-08-06 17:01:24 -0700117 /** \brief decodes a field
118 * \param wire a Block with top-level type \p TYPE
119 * \return value of the field
120 */
Eric Newberry261dbc22015-07-22 23:18:18 -0700121 static ValueType
122 decode(const Block& wire)
123 {
Eric Newberry83872fd2015-08-06 17:01:24 -0700124 if (wire.type() != TlvType::value) {
Junxiao Shi96973542015-09-27 10:30:29 +0000125 BOOST_THROW_EXCEPTION(ndn::tlv::Error("Unexpected TLV type " + to_string(wire.type())));
Eric Newberry83872fd2015-08-06 17:01:24 -0700126 }
127
Eric Newberry261dbc22015-07-22 23:18:18 -0700128 return DecodeHelper<TlvType, ValueType>::decode(wire);
129 }
130
Eric Newberry83872fd2015-08-06 17:01:24 -0700131 /** \brief encodes a field and prepends to \p encoder its Block with top-level type \p TYPE
Alexander Afanasyev45312f52015-09-27 12:06:50 -0700132 * \param encoder Instance of the buffer encoder or buffer estimator
Eric Newberry83872fd2015-08-06 17:01:24 -0700133 * \param value value of the field
134 */
Eric Newberry261dbc22015-07-22 23:18:18 -0700135 template<typename encoding::Tag TAG, typename T>
136 static size_t
137 encode(EncodingImpl<TAG>& encoder, const T& value)
138 {
139 return EncodeHelper<TAG, TlvType, T>::encode(encoder, value);
140 }
141};
142
143} // namespace detail
144} // namespace lp
145} // namesapce ndn
146
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700147#endif // NDN_CXX_LP_DETAIL_FIELD_DECL_HPP