encoding: declare Block operators as hidden friends

Change-Id: Ib6a0792110cb1627e691c66bf83adf27df065c46
This commit is contained in:
Davide Pesavento committed 2023-05-12 19:50:23 -04:00
1 parent 296c3a185d
commit 699cca4ba0
7 files changed
+141 -93

No files matched your search

+29 -21
View File
@@ -25,8 +25,11 @@
#include "ndn-cxx/encoding/buffer-stream.hpp"
#include "ndn-cxx/encoding/encoding-buffer.hpp"
#include "ndn-cxx/encoding/tlv.hpp"
#include "ndn-cxx/security/transform.hpp"
#include "ndn-cxx/security/transform/hex-decode.hpp"
#include "ndn-cxx/security/transform/step-source.hpp"
#include "ndn-cxx/security/transform/stream-sink.hpp"
#include "ndn-cxx/util/ostream-joiner.hpp"
#include "ndn-cxx/util/scope.hpp"
#include "ndn-cxx/util/string-helper.hpp"
#include <boost/asio/buffer.hpp>
@@ -478,41 +481,44 @@ Block::operator boost::asio::const_buffer() const
}
bool
operator==(const Block& lhs, const Block& rhs) noexcept
Block::equals(const Block& other) const noexcept
{
return lhs.type() == rhs.type() &&
lhs.value_size() == rhs.value_size() &&
(lhs.value_size() == 0 ||
std::memcmp(lhs.value(), rhs.value(), lhs.value_size()) == 0);
return type() == other.type() &&
value_size() == other.value_size() &&
(value_size() == 0 ||
std::equal(value_begin(), value_end(), other.value_begin()));
}
std::ostream&
operator<<(std::ostream& os, const Block& block)
void
Block::print(std::ostream& os) const
{
auto oldFmt = os.flags(std::ios_base::dec);
auto oldFlags = os.flags(std::ios_base::dec);
auto restoreFlags = make_scope_exit([&] {
os.flags(oldFlags);
});
if (!block.isValid()) {
if (!isValid()) {
os << "[invalid]";
}
else if (!block.m_elements.empty()) {
else if (!m_elements.empty()) {
EncodingEstimator estimator;
size_t tlvLength = block.encodeValue(estimator);
os << block.type() << '[' << tlvLength << "]={";
std::copy(block.elements_begin(), block.elements_end(), make_ostream_joiner(os, ','));
size_t tlvLength = encodeValue(estimator);
os << type() << '[' << tlvLength << "]={";
std::copy(elements_begin(), elements_end(), make_ostream_joiner(os, ','));
os << '}';
}
else if (block.value_size() > 0) {
os << block.type() << '[' << block.value_size() << "]=";
printHex(os, block.value_bytes(), true);
else if (value_size() > 0) {
os << type() << '[' << value_size() << "]=";
printHex(os, value_bytes(), true);
}
else {
os << block.type() << "[empty]";
os << type() << "[empty]";
}
os.flags(oldFmt);
return os;
}
inline namespace literals {
inline namespace block_literals {
Block
operator ""_block(const char* input, std::size_t len)
{
@@ -537,4 +543,6 @@ operator ""_block(const char* input, std::size_t len)
return Block(os.buf());
}
} // inline namespace block_literals
} // inline namespace literals
} // namespace ndn
+82 -50
View File
@@ -221,20 +221,30 @@ public: // wire format
return m_buffer != nullptr && m_begin != m_end;
}
/** @brief Get begin iterator of encoded wire
* @pre `hasWire() == true`
/**
* @brief Returns an iterator to the beginning of the encoded wire.
* @pre `hasWire() == true`
*/
const_iterator
begin() const;
/** @brief Get end iterator of encoded wire
* @pre `hasWire() == true`
/**
* @brief Returns an iterator past-the-end of the encoded wire.
* @pre `hasWire() == true`
*/
const_iterator
end() const;
/**
* @brief Return a raw pointer to the beginning of the encoded wire
* @brief Returns the size of the encoded wire, i.e., of the whole TLV.
* @pre `isValid() == true`
* @sa value_size()
*/
size_t
size() const;
/**
* @brief Returns a raw pointer to the beginning of the encoded wire, i.e., the whole TLV.
* @pre `hasWire() == true`
* @sa value()
*/
@@ -252,14 +262,7 @@ public: // wire format
}
/**
* @brief Return the size of the encoded wire, i.e., of the whole TLV
* @pre `isValid() == true`
* @sa value_size()
*/
size_t
size() const;
/** @brief Get underlying buffer
* @brief Returns the underlying buffer.
*/
ConstBufferPtr
getBuffer() const
@@ -269,7 +272,7 @@ public: // wire format
public: // type and value
/**
* @brief Return the TLV-TYPE of the Block
* @brief Return the TLV-TYPE of the Block.
* @note This will return tlv::Invalid if isValid() is false.
*/
uint32_t
@@ -279,7 +282,7 @@ public: // type and value
}
/**
* @brief Check if the Block has a non-empty TLV-VALUE
* @brief Check if the Block has a non-empty TLV-VALUE.
*
* This property reflects whether the underlying buffer contains a TLV-VALUE. If this is false,
* TLV-VALUE has zero-length. If this is true, TLV-VALUE may be zero-length.
@@ -293,7 +296,7 @@ public: // type and value
}
/**
* @brief Get begin iterator of TLV-VALUE
* @brief Get begin iterator of TLV-VALUE.
* @pre `hasValue() == true`
*/
const_iterator
@@ -303,7 +306,7 @@ public: // type and value
}
/**
* @brief Get end iterator of TLV-VALUE
* @brief Get end iterator of TLV-VALUE.
* @pre `hasValue() == true`
*/
const_iterator
@@ -313,7 +316,7 @@ public: // type and value
}
/**
* @brief Return the size of TLV-VALUE, i.e., the TLV-LENGTH
* @brief Return the size of TLV-VALUE, i.e., the TLV-LENGTH.
* @sa size()
*/
size_t
@@ -323,7 +326,7 @@ public: // type and value
}
/**
* @brief Return a read-only view of TLV-VALUE as a contiguous range of bytes
* @brief Return a read-only view of TLV-VALUE as a contiguous range of bytes.
*/
span<const uint8_t>
value_bytes() const noexcept
@@ -335,14 +338,14 @@ public: // type and value
}
/**
* @brief Return a raw pointer to the beginning of TLV-VALUE
* @brief Return a raw pointer to the beginning of TLV-VALUE.
* @sa value_bytes(), data()
*/
const uint8_t*
value() const noexcept;
/**
* @brief Return a new Block constructed from the TLV-VALUE of this Block
* @brief Return a new Block constructed from the TLV-VALUE of this Block.
* @pre `value_size() > 0`
*/
Block
@@ -460,24 +463,73 @@ public: // misc
*/
operator boost::asio::const_buffer() const;
protected:
/**
* @brief Returns whether this Block has the same TLV-TYPE/TLV-LENGTH/TLV-VALUE as @p other.
*/
bool
equals(const Block& other) const noexcept;
private:
/** @brief Estimate Block size as if sub-elements are encoded into TLV-VALUE
/**
* @brief Estimate Block size as if sub-elements are encoded into TLV-VALUE.
*/
size_t
encode(EncodingEstimator& estimator) const;
/** @brief Estimate TLV-LENGTH as if sub-elements are encoded into TLV-VALUE
/**
* @brief Estimate TLV-LENGTH as if sub-elements are encoded into TLV-VALUE.
*/
size_t
encodeValue(EncodingEstimator& estimator) const;
/** @brief Encode sub-elements into TLV-VALUE and prepend Block to encoder
* @post TLV-VALUE contains sub-elements from elements()
* @post internal buffer and iterators point to Encoder's buffer
/**
* @brief Encode sub-elements into TLV-VALUE and prepend Block to encoder.
* @post TLV-VALUE contains sub-elements from elements()
* @post internal buffer and iterators point to Encoder's buffer
*/
size_t
encode(EncodingBuffer& encoder);
void
print(std::ostream& os) const;
private: // non-member operators
// NOTE: the following "hidden friend" operators are available via
// argument-dependent lookup only and must be defined inline.
/**
* @brief Compare whether two Blocks have the same TLV-TYPE, TLV-LENGTH, and TLV-VALUE.
*/
friend bool
operator==(const Block& lhs, const Block& rhs) noexcept
{
return lhs.equals(rhs);
}
friend bool
operator!=(const Block& lhs, const Block& rhs) noexcept
{
return !lhs.equals(rhs);
}
/**
* @brief Print @p block to @p os.
*
* Default-constructed Block is printed as: `[invalid]`.
* Zero-length Block is printed as: `TT[empty]`, where TT is TLV-TYPE in decimal.
* Non-zero-length Block on which parse() has not been called is printed as: `TT[LL]=VVVV`,
* where LL is TLV-LENGTH in decimal, and VVVV is TLV-VALUE in hexadecimal.
* Block on which parse() has been called is printed as: `TT[LL]={SUB,SUB}`,
* where each SUB is a sub-element printed using this format.
*/
friend std::ostream&
operator<<(std::ostream& os, const Block& block)
{
block.print(os);
return os;
}
protected:
/** @brief Underlying buffer storing TLV-VALUE and possibly TLV-TYPE and TLV-LENGTH fields
*
@@ -509,19 +561,6 @@ protected:
* This field is valid only if parse() has been called on the Block instance.
*/
mutable element_container m_elements;
/**
* @brief Print @p block to @p os.
*
* Default-constructed Block is printed as: `[invalid]`.
* Zero-length Block is printed as: `TT[empty]`, where TT is TLV-TYPE in decimal.
* Non-zero-length Block on which parse() has not been called is printed as: `TT[LL]=VVVV`,
* where LL is TLV-LENGTH in decimal, and VVVV is TLV-VALUE in hexadecimal.
* Block on which parse() has been called is printed as: `TT[LL]={SUB,SUB}`,
* where each SUB is a sub-element printed using this format.
*/
friend std::ostream&
operator<<(std::ostream& os, const Block& block);
};
inline
@@ -530,17 +569,8 @@ Block::Block(Block&&) noexcept = default;
inline Block&
Block::operator=(Block&&) noexcept = default;
/**
* @brief Compare whether two Blocks have the same TLV-TYPE, TLV-LENGTH, and TLV-VALUE.
*/
bool
operator==(const Block& lhs, const Block& rhs) noexcept;
inline bool
operator!=(const Block& lhs, const Block& rhs) noexcept
{
return !(lhs == rhs);
}
inline namespace literals {
inline namespace block_literals {
/** @brief Construct a Block from hexadecimal @p input.
* @param input a string containing hexadecimal bytes and comments.
@@ -558,6 +588,8 @@ operator!=(const Block& lhs, const Block& rhs) noexcept
Block
operator ""_block(const char* input, std::size_t len);
} // inline namespace block_literals
} // inline namespace literals
} // namespace ndn
#endif // NDN_CXX_ENCODING_BLOCK_HPP
-8
View File
@@ -425,14 +425,6 @@ Component::isParametersSha256Digest() const noexcept
////////////////////////////////////////////////////////////////////////////////
bool
Component::equals(const Component& other) const noexcept
{
return type() == other.type() &&
value_size() == other.value_size() &&
std::equal(value_begin(), value_end(), other.value_begin());
}
int
Component::compare(const Component& other) const
{
+12 -8
View File
@@ -135,19 +135,21 @@ public: // constructors
/**
* @brief Construct a NameComponent of TLV-TYPE @p type, using TLV-VALUE from @p buffer.
* @throw Error the NameComponent is invalid.
*
* This constructor does not copy the underlying buffer, but retains a pointer to it.
* Therefore, the caller must not change the underlying buffer.
*
* @throw Error the NameComponent is invalid.
*/
Component(uint32_t type, ConstBufferPtr buffer);
/**
* @brief Construct a GenericNameComponent, using TLV-VALUE from @p buffer.
* @throw Error the NameComponent is invalid.
*
* This constructor does not copy the underlying buffer, but retains a pointer to it.
* Therefore, the caller must not change the underlying buffer.
*
* @throw Error the NameComponent is invalid.
*/
explicit
Component(ConstBufferPtr buffer)
@@ -480,16 +482,18 @@ public: // comparison
}
/**
* @brief Check if this is the same component as other
*
* @param other The other Component to compare with
* @return true if the components are equal, otherwise false.
* @brief Check whether this is the same component as @p other.
* @param other The name component to compare with
* @return true if the components are equal, false otherwise.
*/
bool
equals(const Component& other) const noexcept;
equals(const Component& other) const noexcept
{
return Block::equals(other);
}
/**
* @brief Compare this to the other Component using NDN canonical ordering
* @brief Compare this to the other Component using NDN canonical ordering.
*
* @param other The other Component to compare with.
* @retval negative this comes before other in canonical ordering
+4 -1
View File
@@ -24,7 +24,10 @@
#include "ndn-cxx/security/certificate.hpp"
#include "ndn-cxx/security/additional-description.hpp"
#include "ndn-cxx/security/transform.hpp"
#include "ndn-cxx/security/transform/base64-encode.hpp"
#include "ndn-cxx/security/transform/buffer-source.hpp"
#include "ndn-cxx/security/transform/public-key.hpp"
#include "ndn-cxx/security/transform/stream-sink.hpp"
#include "ndn-cxx/util/indented-stream.hpp"
namespace ndn::security {
+7 -3
View File
@@ -20,10 +20,14 @@
*/
#include "ndn-cxx/security/tpm/impl/back-end-file.hpp"
#include "ndn-cxx/security/tpm/impl/key-handle-mem.hpp"
#include "ndn-cxx/security/transform.hpp"
#include "ndn-cxx/security/transform/private-key.hpp"
#include "ndn-cxx/encoding/buffer-stream.hpp"
#include "ndn-cxx/security/tpm/impl/key-handle-mem.hpp"
#include "ndn-cxx/security/transform/buffer-source.hpp"
#include "ndn-cxx/security/transform/digest-filter.hpp"
#include "ndn-cxx/security/transform/hex-encode.hpp"
#include "ndn-cxx/security/transform/private-key.hpp"
#include "ndn-cxx/security/transform/stream-sink.hpp"
#include <cstdlib>
#include <fstream>
+7 -2
View File
@@ -20,11 +20,13 @@
*/
#include "ndn-cxx/util/string-helper.hpp"
#include "ndn-cxx/encoding/buffer-stream.hpp"
#include "ndn-cxx/security/transform/buffer-source.hpp"
#include "ndn-cxx/security/transform/hex-decode.hpp"
#include "ndn-cxx/security/transform/hex-encode.hpp"
#include "ndn-cxx/security/transform/stream-sink.hpp"
#include "ndn-cxx/util/scope.hpp"
#include <sstream>
@@ -33,12 +35,15 @@ namespace ndn {
void
printHex(std::ostream& os, uint64_t num, bool wantUpperCase)
{
auto osFlags = os.flags();
auto oldFlags = os.flags();
auto restoreFlags = make_scope_exit([&] {
os.flags(oldFlags);
});
// std::showbase doesn't work with number 0
os << "0x" << std::noshowbase << std::noshowpos
<< (wantUpperCase ? std::uppercase : std::nouppercase)
<< std::hex << num;
os.flags(osFlags);
}
void