blob: 49fec54b0bfdadead2c67178fa25749c56140491 [file] [log] [blame]
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi9da07c52017-08-06 16:59:30 +00002/*
Tianxing Ma241df422018-10-09 22:21:47 -05003 * Copyright (c) 2013-2018 Regents of the University of California.
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -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
22#include "block-helpers.hpp"
23
24namespace ndn {
25namespace encoding {
26
Junxiao Shi9da07c52017-08-06 16:59:30 +000027// ---- non-negative integer ----
28
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070029template<Tag TAG>
30size_t
31prependNonNegativeIntegerBlock(EncodingImpl<TAG>& encoder, uint32_t type, uint64_t value)
32{
33 size_t valueLength = encoder.prependNonNegativeInteger(value);
34 size_t totalLength = valueLength;
35 totalLength += encoder.prependVarNumber(valueLength);
36 totalLength += encoder.prependVarNumber(type);
37
38 return totalLength;
39}
40
41template size_t
Junxiao Shi9da07c52017-08-06 16:59:30 +000042prependNonNegativeIntegerBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t, uint64_t);
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070043
44template size_t
Junxiao Shi9da07c52017-08-06 16:59:30 +000045prependNonNegativeIntegerBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, uint64_t);
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070046
47Block
48makeNonNegativeIntegerBlock(uint32_t type, uint64_t value)
49{
50 EncodingEstimator estimator;
51 size_t totalLength = prependNonNegativeIntegerBlock(estimator, type, value);
52
53 EncodingBuffer encoder(totalLength, 0);
54 prependNonNegativeIntegerBlock(encoder, type, value);
55
56 return encoder.block();
57}
58
59uint64_t
60readNonNegativeInteger(const Block& block)
61{
Tianxing Ma241df422018-10-09 22:21:47 -050062 auto begin = block.value_begin();
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070063 return tlv::readNonNegativeInteger(block.value_size(), begin, block.value_end());
64}
65
Junxiao Shi9da07c52017-08-06 16:59:30 +000066// ---- empty ----
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070067
68template<Tag TAG>
69size_t
70prependEmptyBlock(EncodingImpl<TAG>& encoder, uint32_t type)
71{
72 size_t totalLength = encoder.prependVarNumber(0);
73 totalLength += encoder.prependVarNumber(type);
74
75 return totalLength;
76}
77
78template size_t
Junxiao Shi9da07c52017-08-06 16:59:30 +000079prependEmptyBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t);
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070080
81template size_t
Junxiao Shi9da07c52017-08-06 16:59:30 +000082prependEmptyBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t);
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070083
84Block
85makeEmptyBlock(uint32_t type)
86{
87 EncodingEstimator estimator;
88 size_t totalLength = prependEmptyBlock(estimator, type);
89
90 EncodingBuffer encoder(totalLength, 0);
91 prependEmptyBlock(encoder, type);
92
93 return encoder.block();
94}
95
Junxiao Shi9da07c52017-08-06 16:59:30 +000096// ---- string ----
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070097
98template<Tag TAG>
99size_t
100prependStringBlock(EncodingImpl<TAG>& encoder, uint32_t type, const std::string& value)
101{
Junxiao Shi9da07c52017-08-06 16:59:30 +0000102 return encoder.prependByteArrayBlock(type, reinterpret_cast<const uint8_t*>(value.data()), value.size());
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700103}
104
105template size_t
Junxiao Shi9da07c52017-08-06 16:59:30 +0000106prependStringBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t, const std::string&);
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700107
108template size_t
Junxiao Shi9da07c52017-08-06 16:59:30 +0000109prependStringBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, const std::string&);
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700110
111Block
112makeStringBlock(uint32_t type, const std::string& value)
113{
Junxiao Shi9da07c52017-08-06 16:59:30 +0000114 return makeBinaryBlock(type, value.data(), value.size());
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700115}
116
117std::string
118readString(const Block& block)
119{
120 return std::string(reinterpret_cast<const char*>(block.value()), block.value_size());
121}
122
Tianxing Ma241df422018-10-09 22:21:47 -0500123// ---- double ----
124
125static_assert(std::numeric_limits<double>::is_iec559, "This code requires IEEE-754 doubles");
126
127template<Tag TAG>
128size_t
129prependDoubleBlock(EncodingImpl<TAG>& encoder, uint32_t type, double value)
130{
131 uint64_t temp = 0;
132 std::memcpy(&temp, &value, 8);
133 boost::endian::native_to_big_inplace(temp);
134 return encoder.prependByteArrayBlock(type, reinterpret_cast<const uint8_t*>(&temp), 8);
135}
136
137template size_t
138prependDoubleBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t, double);
139
140template size_t
141prependDoubleBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, double);
142
143Block
144makeDoubleBlock(uint32_t type, double value)
145{
146 EncodingEstimator estimator;
147 size_t totalLength = prependDoubleBlock(estimator, type, value);
148
149 EncodingBuffer encoder(totalLength, 0);
150 prependDoubleBlock(encoder, type, value);
151
152 return encoder.block();
153}
154
155double
156readDouble(const Block& block)
157{
158 if (block.value_size() != 8) {
159 BOOST_THROW_EXCEPTION(tlv::Error("Invalid length for double (must be 8)"));
160 }
161
162 uint64_t temp = 0;
163 std::memcpy(&temp, block.value(), 8);
164 boost::endian::big_to_native_inplace(temp);
165 double d = 0;
166 std::memcpy(&d, &temp, 8);
167 return d;
168}
169
Junxiao Shi9da07c52017-08-06 16:59:30 +0000170// ---- binary ----
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700171
172Block
173makeBinaryBlock(uint32_t type, const uint8_t* value, size_t length)
174{
175 EncodingEstimator estimator;
176 size_t totalLength = estimator.prependByteArrayBlock(type, value, length);
177
178 EncodingBuffer encoder(totalLength, 0);
179 encoder.prependByteArrayBlock(type, value, length);
180
181 return encoder.block();
182}
183
184Block
185makeBinaryBlock(uint32_t type, const char* value, size_t length)
186{
187 return makeBinaryBlock(type, reinterpret_cast<const uint8_t*>(value), length);
188}
189
190} // namespace encoding
191} // namespace ndn