ndn-cxx: NDN C++ Library 0.9.0-33-g832ea91d
Loading...
Searching...
No Matches
encoder.cpp
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2013-2023 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
23
24#include <boost/endian/conversion.hpp>
25
26namespace ndn::encoding {
27
28namespace endian = boost::endian;
29
30Encoder::Encoder(size_t totalReserve, size_t reserveFromBack)
31 : m_buffer(make_shared<Buffer>(totalReserve))
32{
33 m_begin = m_end = m_buffer->end() - (reserveFromBack < totalReserve ? reserveFromBack : 0);
34}
35
37 : m_buffer(std::const_pointer_cast<Buffer>(block.getBuffer()))
38 , m_begin(m_buffer->begin() + (block.begin() - m_buffer->begin()))
39 , m_end(m_buffer->begin() + (block.end() - m_buffer->begin()))
40{
41}
42
43void
45{
46 if (m_end + size > m_buffer->end())
47 reserve(m_buffer->size() * 2 + size, false);
48}
49
50void
52{
53 if (m_buffer->begin() + size > m_begin)
54 reserve(m_buffer->size() * 2 + size, true);
55}
56
58Encoder::block(bool verifyLength) const
59{
60 return Block(m_buffer, m_begin, m_end, verifyLength);
61}
62
63void
64Encoder::reserve(size_t size, bool addInFront)
65{
66 if (size < m_buffer->size()) {
67 size = m_buffer->size();
68 }
69
70 if (addInFront) {
71 size_t diffEnd = m_buffer->end() - m_end;
72 size_t diffBegin = m_buffer->end() - m_begin;
73
74 Buffer* buf = new Buffer(size);
75 std::copy_backward(m_buffer->begin(), m_buffer->end(), buf->end());
76
77 m_buffer.reset(buf);
78
79 m_end = m_buffer->end() - diffEnd;
80 m_begin = m_buffer->end() - diffBegin;
81 }
82 else {
83 size_t diffEnd = m_end - m_buffer->begin();
84 size_t diffBegin = m_begin - m_buffer->begin();
85
86 Buffer* buf = new Buffer(size);
87 std::copy(m_buffer->begin(), m_buffer->end(), buf->begin());
88
89 m_buffer.reset(buf);
90
91 m_end = m_buffer->begin() + diffEnd;
92 m_begin = m_buffer->begin() + diffBegin;
93 }
94}
95
96size_t
97Encoder::prependBytes(span<const uint8_t> bytes)
98{
99 return prependRange(bytes.begin(), bytes.end());
100}
101
102size_t
103Encoder::appendBytes(span<const uint8_t> bytes)
104{
105 return appendRange(bytes.begin(), bytes.end());
106}
107
108size_t
109Encoder::prependVarNumber(uint64_t varNumber)
110{
111 if (varNumber < 253) {
112 prependBytes({static_cast<uint8_t>(varNumber)});
113 return 1;
114 }
115 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
116 uint16_t value = endian::native_to_big(static_cast<uint16_t>(varNumber));
117 prependBytes({reinterpret_cast<const uint8_t*>(&value), 2});
118 prependBytes({253});
119 return 3;
120 }
121 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
122 uint32_t value = endian::native_to_big(static_cast<uint32_t>(varNumber));
123 prependBytes({reinterpret_cast<const uint8_t*>(&value), 4});
124 prependBytes({254});
125 return 5;
126 }
127 else {
128 uint64_t value = endian::native_to_big(varNumber);
129 prependBytes({reinterpret_cast<const uint8_t*>(&value), 8});
130 prependBytes({255});
131 return 9;
132 }
133}
134
135size_t
136Encoder::appendVarNumber(uint64_t varNumber)
137{
138 if (varNumber < 253) {
139 appendBytes({static_cast<uint8_t>(varNumber)});
140 return 1;
141 }
142 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
143 appendBytes({253});
144 uint16_t value = endian::native_to_big(static_cast<uint16_t>(varNumber));
145 appendBytes({reinterpret_cast<const uint8_t*>(&value), 2});
146 return 3;
147 }
148 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
149 appendBytes({254});
150 uint32_t value = endian::native_to_big(static_cast<uint32_t>(varNumber));
151 appendBytes({reinterpret_cast<const uint8_t*>(&value), 4});
152 return 5;
153 }
154 else {
155 appendBytes({255});
156 uint64_t value = endian::native_to_big(varNumber);
157 appendBytes({reinterpret_cast<const uint8_t*>(&value), 8});
158 return 9;
159 }
160}
161
162size_t
164{
165 if (varNumber <= std::numeric_limits<uint8_t>::max()) {
166 return prependBytes({static_cast<uint8_t>(varNumber)});
167 }
168 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
169 uint16_t value = endian::native_to_big(static_cast<uint16_t>(varNumber));
170 return prependBytes({reinterpret_cast<const uint8_t*>(&value), 2});
171 }
172 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
173 uint32_t value = endian::native_to_big(static_cast<uint32_t>(varNumber));
174 return prependBytes({reinterpret_cast<const uint8_t*>(&value), 4});
175 }
176 else {
177 uint64_t value = endian::native_to_big(varNumber);
178 return prependBytes({reinterpret_cast<const uint8_t*>(&value), 8});
179 }
180}
181
182size_t
184{
185 if (varNumber <= std::numeric_limits<uint8_t>::max()) {
186 return appendBytes({static_cast<uint8_t>(varNumber)});
187 }
188 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
189 uint16_t value = endian::native_to_big(static_cast<uint16_t>(varNumber));
190 return appendBytes({reinterpret_cast<const uint8_t*>(&value), 2});
191 }
192 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
193 uint32_t value = endian::native_to_big(static_cast<uint32_t>(varNumber));
194 return appendBytes({reinterpret_cast<const uint8_t*>(&value), 4});
195 }
196 else {
197 uint64_t value = endian::native_to_big(varNumber);
198 return appendBytes({reinterpret_cast<const uint8_t*>(&value), 8});
199 }
200}
201
202} // namespace ndn::encoding
Represents a TLV element of the NDN packet format.
Definition block.hpp:45
General-purpose automatically managed/resized buffer.
Definition buffer.hpp:43
void reserve(size_t size, bool addInFront)
Reserve size bytes for the underlying buffer.
Definition encoder.cpp:64
size_t size() const noexcept
Returns the size of the encoded buffer.
Definition encoder.hpp:226
Encoder(size_t totalReserve=MAX_NDN_PACKET_SIZE, size_t reserveFromBack=400)
Create instance of the encoder with the specified reserved sizes.
Definition encoder.cpp:30
size_t appendBytes(span< const uint8_t > bytes)
Append a sequence of bytes.
Definition encoder.cpp:103
void reserveFront(size_t size)
Reserve at least isze bytes at the beginning of the underlying buffer.
Definition encoder.cpp:51
Block block(bool verifyLength=true) const
Create Block from the underlying buffer.
Definition encoder.cpp:58
size_t prependBytes(span< const uint8_t > bytes)
Prepend a sequence of bytes.
Definition encoder.cpp:97
size_t prependRange(Iterator first, Iterator last)
Prepend range of bytes from the range [first, last)
Definition encoder.hpp:252
size_t prependVarNumber(uint64_t number)
Prepend number encoded as a VAR-NUMBER in NDN-TLV format.
Definition encoder.cpp:109
size_t prependNonNegativeInteger(uint64_t integer)
Prepend integer encoded as a NonNegativeInteger in NDN-TLV format.
Definition encoder.cpp:163
size_t appendNonNegativeInteger(uint64_t integer)
Append integer encoded as a NonNegativeInteger in NDN-TLV format.
Definition encoder.cpp:183
size_t appendRange(Iterator first, Iterator last)
Append range of bytes from the range [first, last)
Definition encoder.hpp:267
size_t appendVarNumber(uint64_t number)
Append number encoded as a VAR-NUMBER in NDN-TLV format.
Definition encoder.cpp:136
void reserveBack(size_t size)
Reserve at least size bytes at the back of the underlying buffer.
Definition encoder.cpp:44
STL namespace.