]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#3210] refactor io utilities
authorAndrei Pavel <andrei@isc.org>
Mon, 4 Mar 2024 09:48:47 +0000 (11:48 +0200)
committerAndrei Pavel <andrei@isc.org>
Thu, 21 Mar 2024 16:30:04 +0000 (18:30 +0200)
- Rename util/io_utilities.h to util/io.h to escape redundancy.
- Create readUint and writeUint templates.
- Use reverse_copy for potential performance boost.
- Add missing unit tests.

32 files changed:
src/bin/dhcp6/dhcp6_srv.cc
src/lib/asiodns/tests/io_fetch_unittest.cc
src/lib/asiolink/tcp_socket.h
src/lib/asiolink/tests/tcp_socket_unittest.cc
src/lib/asiolink/tests/tls_socket_unittest.cc
src/lib/asiolink/tests/udp_socket_unittest.cc
src/lib/dhcp/duid.cc
src/lib/dhcp/duid_factory.cc
src/lib/dhcp/opaque_data_tuple.h
src/lib/dhcp/option.cc
src/lib/dhcp/option4_addrlst.cc
src/lib/dhcp/option4_client_fqdn.cc
src/lib/dhcp/option6_addrlst.cc
src/lib/dhcp/option6_auth.cc
src/lib/dhcp/option6_client_fqdn.cc
src/lib/dhcp/option6_ia.cc
src/lib/dhcp/option6_iaaddr.cc
src/lib/dhcp/option6_iaprefix.cc
src/lib/dhcp/option6_pdexclude.cc
src/lib/dhcp/option6_status_code.cc
src/lib/dhcp/option_custom.h
src/lib/dhcp/option_data_types.h
src/lib/dhcp/option_int.h
src/lib/dhcp/option_int_array.h
src/lib/dhcp/option_vendor.h
src/lib/dhcp/pkt6.cc
src/lib/eval/token.cc
src/lib/util/Makefile.am
src/lib/util/io.h [new file with mode: 0644]
src/lib/util/io_utilities.h [deleted file]
src/lib/util/tests/io_unittests.cc [new file with mode: 0644]
src/lib/util/tests/io_utilities_unittest.cc [deleted file]

index 1dfc4aa98273a7e7565cba0d19bd1285092055c6..548eaa8b9a5133b856137cc79839091548432a5b 100644 (file)
@@ -48,7 +48,7 @@
 #include <hooks/hooks_manager.h>
 #include <stats/stats_mgr.h>
 #include <util/encode/encode.h>
-#include <util/io_utilities.h>
+#include <util/io.h>
 #include <util/pointer_util.h>
 #include <util/range_utilities.h>
 #include <log/logger.h>
index 47bac7ce93abdd518af12d357acaed258eced360..0fcb6528127f4454e812d69229c223d04807e2d1 100644 (file)
@@ -17,7 +17,7 @@
 #include <dns/name.h>
 #include <dns/rcode.h>
 #include <util/buffer.h>
-#include <util/io_utilities.h>
+#include <util/io.h>
 
 #include <gtest/gtest.h>
 #include <boost/date_time/posix_time/posix_time_types.hpp>
index 44e83057a2bbb77482f0d98c5b5f594523006580..2aa7d27d4c4d0938ebae6d57f51a1a039a384408 100644 (file)
@@ -21,7 +21,7 @@
 #include <boost/numeric/conversion/cast.hpp>
 
 #include <util/buffer.h>
-#include <util/io_utilities.h>
+#include <util/io.h>
 
 #include <asiolink/io_asio_socket.h>
 #include <asiolink/io_endpoint.h>
index 9486b582d822e99f4dadd3a354f7b13750070101..82c74ca66e29f3049e4e58a76085b3abe6245e91 100644 (file)
@@ -16,7 +16,7 @@
 #include <asiolink/tcp_endpoint.h>
 #include <asiolink/tcp_socket.h>
 #include <util/buffer.h>
-#include <util/io_utilities.h>
+#include <util/io.h>
 
 #include <boost/shared_ptr.hpp>
 #include <gtest/gtest.h>
index e5c21d8c14939366cef4c04da6b7b8a373fd062f..c409e0bd8c855ed01358776f54616bfd0ce1d259 100644 (file)
@@ -17,7 +17,7 @@
 #include <asiolink/tls_socket.h>
 #include <asiolink/testutils/test_tls.h>
 #include <util/buffer.h>
-#include <util/io_utilities.h>
+#include <util/io.h>
 
 #include <boost/shared_ptr.hpp>
 #include <gtest/gtest.h>
index 0668414ceda807877a3aef6f2cf943b8a2f4e668..a3ea985ba3d3b59dc0b5e9fbd8750edd672f765c 100644 (file)
@@ -16,7 +16,7 @@
 #include <asiolink/udp_endpoint.h>
 #include <asiolink/udp_socket.h>
 #include <util/buffer.h>
-#include <util/io_utilities.h>
+#include <util/io.h>
 
 #include <boost/shared_ptr.hpp>
 #include <gtest/gtest.h>
index 2338118feb733ed473ee889485be8148c2fdf069..ef7a62a0eaf37a3ccec475ea4bc0383ed9d5d66b 100644 (file)
@@ -8,7 +8,7 @@
 
 #include <dhcp/duid.h>
 #include <exceptions/exceptions.h>
-#include <util/io_utilities.h>
+#include <util/io.h>
 #include <iomanip>
 #include <cctype>
 #include <sstream>
index 8d1ed0e046a167db7bb6ce6c20f45f5a1b58c15a..43c33638dc46b3b2c1b6ddbdbfd5bb0fb800dfab 100644 (file)
@@ -9,7 +9,7 @@
 #include <dhcp/duid_factory.h>
 #include <dhcp/iface_mgr.h>
 #include <exceptions/exceptions.h>
-#include <util/io_utilities.h>
+#include <util/io.h>
 #include <util/range_utilities.h>
 #include <util/strutil.h>
 #include <ctime>
index a8f5528eea6d4e4b2ae292ca9881ee76a16103b4..f6dabedb5364ac7f472c6730ec9b9365fbfee75b 100644 (file)
@@ -9,7 +9,7 @@
 
 #include <dhcp/option.h>
 #include <util/buffer.h>
-#include <util/io_utilities.h>
+#include <util/io.h>
 
 #include <iostream>
 #include <iterator>
index eda9d5838174408d7ce6ffd9318079f121482851..95a5138e498ec21d60c1533bfe5388579631d5a1 100644 (file)
@@ -11,7 +11,7 @@
 #include <dhcp/option_space.h>
 #include <exceptions/exceptions.h>
 #include <util/encode/encode.h>
-#include <util/io_utilities.h>
+#include <util/io.h>
 
 #include <boost/make_shared.hpp>
 
index 1dd9c3267ced1ea90afd6ff9a9832421f4b32730..1afada585610003a7c8b5b4ee6a9436439d63242 100644 (file)
@@ -9,7 +9,7 @@
 #include <asiolink/io_address.h>
 #include <dhcp/option4_addrlst.h>
 #include <exceptions/exceptions.h>
-#include <util/io_utilities.h>
+#include <util/io.h>
 
 #include <iomanip>
 #include <sstream>
index 7869c0eac724819cd7b6dfdb75baba2989090fff..17b804b57be23760753dbf7714cfc57121dec01d 100644 (file)
@@ -10,7 +10,7 @@
 #include <dhcp/option4_client_fqdn.h>
 #include <dns/labelsequence.h>
 #include <util/buffer.h>
-#include <util/io_utilities.h>
+#include <util/io.h>
 #include <util/strutil.h>
 #include <sstream>
 
index a617e5bd6fcd9e7de66edc13429462cc9ced938e..41c4e8dbec300f2b7c43a275e0a23b75b7c996be 100644 (file)
@@ -11,7 +11,7 @@
 #include <dhcp/libdhcp++.h>
 #include <dhcp/option6_addrlst.h>
 #include <exceptions/exceptions.h>
-#include <util/io_utilities.h>
+#include <util/io.h>
 
 #include <sstream>
 
index 8ce63a1c8d7a289c98eb0863a8367166a7528f8f..a4cca527e904c2ae4e3d2cf6a0ce2b47846198af 100644 (file)
@@ -10,7 +10,7 @@
 #include <dhcp/option6_auth.h>
 #include <dhcp/option_space.h>
 #include <exceptions/exceptions.h>
-#include <util/io_utilities.h>
+#include <util/io.h>
 #include <util/encode/encode.h>
 
 #include <sstream>
index 573a6ba8b9a4cc597636b0980507fe6ba27ed0f6..dd28599fa4578b9281b8519e2e8dd33f7377f826 100644 (file)
@@ -10,7 +10,7 @@
 #include <dhcp/option6_client_fqdn.h>
 #include <dns/labelsequence.h>
 #include <util/buffer.h>
-#include <util/io_utilities.h>
+#include <util/io.h>
 #include <util/strutil.h>
 #include <sstream>
 
index 0519bb2e38bfd12c74468a2700fd284a6bf82e6b..72aaf743ad125d839be023ce13a2f813c5e87315 100644 (file)
@@ -10,7 +10,7 @@
 #include <dhcp/option6_ia.h>
 #include <dhcp/option_space.h>
 #include <exceptions/exceptions.h>
-#include <util/io_utilities.h>
+#include <util/io.h>
 
 #include <arpa/inet.h>
 #include <sstream>
index 0cfed7e1ab47dc39dd9001b6528a7de563135c68..9836ad909c812d1de8fe0d7e416394d9ca9643fd 100644 (file)
@@ -12,7 +12,7 @@
 #include <dhcp/option6_iaaddr.h>
 #include <dhcp/option_space.h>
 #include <exceptions/exceptions.h>
-#include <util/io_utilities.h>
+#include <util/io.h>
 
 #include <sstream>
 
index 675e0676cd24596c9dc0c2d26ec8c3e90fc561ba..ceb40f9b5adb47bac42acc03f7ad8372b542f76b 100644 (file)
@@ -12,7 +12,7 @@
 #include <dhcp/option6_iaprefix.h>
 #include <dhcp/option_space.h>
 #include <exceptions/exceptions.h>
-#include <util/io_utilities.h>
+#include <util/io.h>
 
 #include <sstream>
 
index bdee4471b7c5078aca8d821328f4b6cc30b7e4e6..c4d99f74083f8f286adeeb99875608769699061c 100644 (file)
@@ -11,7 +11,7 @@
 #include <dhcp/option6_pdexclude.h>
 #include <exceptions/exceptions.h>
 #include <util/encode/encode.h>
-#include <util/io_utilities.h>
+#include <util/io.h>
 
 #include <boost/dynamic_bitset.hpp>
 #include <iostream>
index 8e709190c91d47b91fa5eb501f9368fef80629e0..969192cf0719fb255ba69e0e4fdf55d11f0352e4 100644 (file)
@@ -10,7 +10,7 @@
 #include <dhcp/dhcp6.h>
 #include <dhcp/option6_status_code.h>
 #include <dhcp/option_data_types.h>
-#include <util/io_utilities.h>
+#include <util/io.h>
 #include <iterator>
 #include <sstream>
 
index 9208651e2d439ec3cec1d8c1ac707eade639c248..48533d1cada8f777c6047b26a9e5f54ba1671332 100644 (file)
@@ -11,7 +11,7 @@
 #include <dhcp/option.h>
 #include <dhcp/option_definition.h>
 #include <exceptions/isc_assert.h>
-#include <util/io_utilities.h>
+#include <util/io.h>
 
 namespace isc {
 namespace dhcp {
index a34ab0839d333ded1c92f727fb0f7ed4d96258e1..58bee3d1e6fb78054148b054c672e7a8fb082eec 100644 (file)
@@ -11,7 +11,7 @@
 #include <dhcp/opaque_data_tuple.h>
 #include <dhcp/option.h>
 #include <exceptions/exceptions.h>
-#include <util/io_utilities.h>
+#include <util/io.h>
 
 #include <stdint.h>
 #include <utility>
index be5b95dcb5d4123bf6a8d030feea62db6f7dee34..bc20fd25d80f0f07a01d245a44ae8618d6f23850 100644 (file)
@@ -11,7 +11,7 @@
 #include <dhcp/option.h>
 #include <dhcp/option_data_types.h>
 #include <dhcp/option_space.h>
-#include <util/io_utilities.h>
+#include <util/io.h>
 
 #include <stdint.h>
 #include <sstream>
index 1f73c0bfa5290843125da4c3e2db8f18625bd3b3..168492c799f9ed4f28a3c912e9da5470ce81dfa5 100644 (file)
@@ -10,7 +10,7 @@
 #include <dhcp/libdhcp++.h>
 #include <dhcp/option.h>
 #include <dhcp/option_data_types.h>
-#include <util/io_utilities.h>
+#include <util/io.h>
 #include <boost/shared_ptr.hpp>
 #include <sstream>
 #include <stdint.h>
index 43a0aaeb628370d633e702b2ec862f497ed53bbc..2de6f37e2516e46d91015f08bb7a115ae4c19ba2 100644 (file)
@@ -10,7 +10,7 @@
 #include <dhcp/libdhcp++.h>
 #include <dhcp/option.h>
 #include <dhcp/option_data_types.h>
-#include <util/io_utilities.h>
+#include <util/io.h>
 
 #include <stdint.h>
 
index dfbc01c997b73b6db7cf7350927711408bda6743..87f05869896d64825893e34a93f769b9aef3cf58 100644 (file)
@@ -14,7 +14,7 @@
 #include <dhcp/option_vendor.h>
 #include <dhcp/pkt6.h>
 #include <dhcp/docsis3_option_defs.h>
-#include <util/io_utilities.h>
+#include <util/io.h>
 #include <exceptions/exceptions.h>
 #include <dhcp/duid.h>
 #include <dhcp/iface_mgr.h>
index 4c99eca95eeb58f16056b5fd3c28de5a6d16f82a..ed0984415c9afe10b39db3f0e98f0d59fc5434c6 100644 (file)
@@ -10,7 +10,7 @@
 #include <eval/eval_log.h>
 #include <eval/eval_context.h>
 #include <util/encode/encode.h>
-#include <util/io_utilities.h>
+#include <util/io.h>
 #include <asiolink/io_address.h>
 #include <dhcp/pkt4.h>
 #include <dhcp/pkt6.h>
index bab1def0aa3978ad8f1b0e466c1b8f76ac5bba40..828e0fe7eda7ae375bdc022a853fe7262fc3b1a0 100644 (file)
@@ -10,13 +10,14 @@ lib_LTLIBRARIES = libkea-util.la
 libkea_util_la_SOURCES  =
 libkea_util_la_SOURCES += bigints.h
 libkea_util_la_SOURCES += boost_time_utils.h boost_time_utils.cc
-libkea_util_la_SOURCES += buffer.h io_utilities.h
+libkea_util_la_SOURCES += buffer.h
 libkea_util_la_SOURCES += chrono_time_utils.h chrono_time_utils.cc
 libkea_util_la_SOURCES += csv_file.h csv_file.cc
 libkea_util_la_SOURCES += dhcp_space.h dhcp_space.cc
 libkea_util_la_SOURCES += doubles.h
 libkea_util_la_SOURCES += filesystem.h filesystem.cc
 libkea_util_la_SOURCES += hash.h
+libkea_util_la_SOURCES += io.h
 libkea_util_la_SOURCES += labeled_value.h labeled_value.cc
 libkea_util_la_SOURCES += memory_segment.h
 libkea_util_la_SOURCES += memory_segment_local.h memory_segment_local.cc
@@ -61,7 +62,7 @@ libkea_util_include_HEADERS = \
        doubles.h \
        filesystem.h \
        hash.h \
-       io_utilities.h \
+       io.h \
        labeled_value.h \
        memory_segment.h \
        memory_segment_local.h \
diff --git a/src/lib/util/io.h b/src/lib/util/io.h
new file mode 100644 (file)
index 0000000..975299c
--- /dev/null
@@ -0,0 +1,111 @@
+// Copyright (C) 2011-2024 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef KEA_UTIL_IO_H
+#define KEA_UTIL_IO_H
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+
+namespace isc {
+namespace util {
+
+/// \brief Read an unsigned integer from given buffer.
+///
+/// \tparam uint_t Data type of the unsigned integer.
+/// \param buffer Data buffer at least two bytes long of which the first bytes are assumed to
+///        represent an unsigned integer in network-byte order.
+/// \param length Length of the data buffer.
+///
+/// \return Value of the integer.
+template <typename uint_t>
+uint_t
+readUint(void const* const buffer, size_t const length) {
+    constexpr size_t size(sizeof(uint_t));
+    if (length < size) {
+        isc_throw(OutOfRange, "Expected buffer to be long enough to read a "
+                                  << size << "-byte integer, but got " << length << " byte"
+                                  << (length == 1 ? "" : "s") << " instead");
+    }
+
+    uint8_t const* const byte_buffer(static_cast<uint8_t const* const>(buffer));
+    uint_t result;
+    uint8_t* pointer_to_result(static_cast<uint8_t*>(static_cast<void*>(&result)));
+
+    std::reverse_copy(byte_buffer, byte_buffer + size, pointer_to_result);
+
+    return (result);
+}
+
+/// \brief Write the given unsigned integer to the given buffer.
+///
+/// \tparam uint_t Data type of the unsigned integer.
+/// \param value Value to convert.
+/// \param buffer Data buffer at least two bytes long into which the unsigned integer value is
+///        written in network-byte order.
+/// \param length Length of the data buffer.
+///
+/// \return pointer to the next byte after stored value
+template <typename uint_t>
+uint8_t*
+writeUint(uint_t const value, void* const buffer, size_t const length) {
+    constexpr size_t size(sizeof(uint_t));
+    if (length < size) {
+        isc_throw(OutOfRange, "Expected buffer to be long enough to write a "
+                                  << size << "-byte integer, but got " << length << " byte"
+                                  << (length == 1 ? "" : "s") << " instead");
+    }
+
+    uint8_t const* const pointer_to_value(
+        static_cast<uint8_t const* const>(static_cast<void const* const>(&value)));
+    uint8_t* const byte_buffer(static_cast<uint8_t* const>(buffer));
+
+    std::reverse_copy(pointer_to_value, pointer_to_value + size, byte_buffer);
+
+    return (byte_buffer + size);
+}
+
+/// \brief uint16_t wrapper over readUint.
+inline uint16_t
+readUint16(void const* const buffer, size_t const length) {
+    return readUint<uint16_t>(buffer, length);
+}
+
+/// \brief uint32_t wrapper over readUint.
+inline uint32_t
+readUint32(void const* const buffer, size_t const length) {
+    return readUint<uint32_t>(buffer, length);
+}
+
+/// \brief uint16_t wrapper over readUint.
+inline uint64_t
+readUint64(void const* const buffer, size_t const length) {
+    return readUint<uint64_t>(buffer, length);
+}
+
+/// \brief uint16_t wrapper over writeUint.
+inline uint8_t*
+writeUint16(uint16_t const value, void* const buffer, size_t const length) {
+    return writeUint(value, buffer, length);
+}
+
+/// \brief uint32_t wrapper over writeUint.
+inline uint8_t*
+writeUint32(uint32_t const value, void* const buffer, size_t const length) {
+    return writeUint(value, buffer, length);
+}
+
+/// \brief uint64_t wrapper over writeUint.
+inline uint8_t*
+writeUint64(uint64_t const value, void* const buffer, size_t const length) {
+    return writeUint(value, buffer, length);
+}
+
+}  // namespace util
+}  // namespace isc
+
+#endif  // KEA_UTIL_IO_H
diff --git a/src/lib/util/io_utilities.h b/src/lib/util/io_utilities.h
deleted file mode 100644 (file)
index bb32819..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright (C) 2011-2023 Internet Systems Consortium, Inc. ("ISC")
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef IO_UTILITIES_H
-#define IO_UTILITIES_H
-
-#include <exceptions/exceptions.h>
-#include <cstddef>
-
-namespace isc {
-namespace util {
-
-/// \brief Read Unsigned 16-Bit Integer from Buffer
-///
-/// This is essentially a copy of the isc::util::InputBuffer::readUint16.  It
-/// should really be moved into a separate library.
-///
-/// \param buffer Data buffer at least two bytes long of which the first two
-///        bytes are assumed to represent a 16-bit integer in network-byte
-///        order.
-/// \param length Length of the data buffer.
-///
-/// \return Value of 16-bit integer
-inline uint16_t
-readUint16(const void* buffer, size_t length) {
-    if (length < sizeof(uint16_t)) {
-        isc_throw(isc::OutOfRange,
-                  "Length (" << length << ") of buffer is insufficient " <<
-                  "to read a uint16_t");
-    }
-
-    const uint8_t* byte_buffer = static_cast<const uint8_t*>(buffer);
-
-    uint16_t result = (static_cast<uint16_t>(byte_buffer[0])) << 8;
-    result |= static_cast<uint16_t>(byte_buffer[1]);
-
-    return (result);
-}
-
-/// \brief Write Unsigned 16-Bit Integer to Buffer
-///
-/// This is essentially a copy of isc::util::OutputBuffer::writeUint16.  It
-/// should really be moved into a separate library.
-///
-/// \param value 16-bit value to convert
-/// \param buffer Data buffer at least two bytes long into which the 16-bit
-///        value is written in network-byte order.
-/// \param length Length of the data buffer.
-///
-/// \return pointer to the next byte after stored value
-inline uint8_t*
-writeUint16(uint16_t value, void* buffer, size_t length) {
-    if (length < sizeof(uint16_t)) {
-        isc_throw(isc::OutOfRange,
-                  "Length (" << length << ") of buffer is insufficient " <<
-                  "to write a uint16_t");
-    }
-
-    uint8_t* byte_buffer = static_cast<uint8_t*>(buffer);
-
-    byte_buffer[0] = static_cast<uint8_t>((value & 0xff00U) >> 8);
-    byte_buffer[1] = static_cast<uint8_t>(value & 0x00ffU);
-
-    return (byte_buffer + sizeof(uint16_t));
-}
-
-/// \brief Read Unsigned 32-Bit Integer from Buffer
-///
-/// \param buffer Data buffer at least four bytes long of which the first four
-///        bytes are assumed to represent a 32-bit integer in network-byte
-///        order.
-/// \param length Length of the data buffer.
-///
-/// \return Value of 32-bit unsigned integer
-inline uint32_t
-readUint32(const void* buffer, size_t length) {
-    if (length < sizeof(uint32_t)) {
-        isc_throw(isc::OutOfRange,
-                  "Length (" << length << ") of buffer is insufficient " <<
-                  "to read a uint32_t");
-    }
-
-    const uint8_t* byte_buffer = static_cast<const uint8_t*>(buffer);
-
-    uint32_t result = (static_cast<uint32_t>(byte_buffer[0])) << 24;
-    result |= (static_cast<uint32_t>(byte_buffer[1])) << 16;
-    result |= (static_cast<uint32_t>(byte_buffer[2])) << 8;
-    result |= (static_cast<uint32_t>(byte_buffer[3]));
-
-    return (result);
-}
-
-/// \brief Write Unsigned 32-Bit Integer to Buffer
-///
-/// \param value 32-bit value to convert
-/// \param buffer Data buffer at least four bytes long into which the 32-bit
-///        value is written in network-byte order.
-/// \param length Length of the data buffer.
-///
-/// \return pointer to the next byte after stored value
-inline uint8_t*
-writeUint32(uint32_t value, void* buffer, size_t length) {
-    if (length < sizeof(uint32_t)) {
-        isc_throw(isc::OutOfRange,
-                  "Length (" << length << ") of buffer is insufficient " <<
-                  "to write a uint32_t");
-    }
-
-    uint8_t* byte_buffer = static_cast<uint8_t*>(buffer);
-
-    byte_buffer[0] = static_cast<uint8_t>((value & 0xff000000U) >> 24);
-    byte_buffer[1] = static_cast<uint8_t>((value & 0x00ff0000U) >> 16);
-    byte_buffer[2] = static_cast<uint8_t>((value & 0x0000ff00U) >> 8);
-    byte_buffer[3] = static_cast<uint8_t>((value & 0x000000ffU));
-
-    return (byte_buffer + sizeof(uint32_t));
-}
-
-/// \brief Read Unsigned 64-Bit Integer from Buffer
-///
-/// \param buffer Data buffer at least four bytes long of which the first four
-///        bytes are assumed to represent a 64-bit integer in network-byte
-///        order.
-/// \param length Length of the data buffer.
-///
-/// \return Value of 64-bit unsigned integer
-inline uint64_t
-readUint64(const void* buffer, size_t length) {
-    if (length < sizeof(uint64_t)) {
-        isc_throw(isc::OutOfRange,
-                  "Length (" << length << ") of buffer is insufficient " <<
-                  "to read a uint64_t");
-    }
-
-    const uint8_t* byte_buffer = static_cast<const uint8_t*>(buffer);
-
-    uint64_t result = (static_cast<uint64_t>(byte_buffer[0])) << 56;
-    result |= (static_cast<uint64_t>(byte_buffer[1])) << 48;
-    result |= (static_cast<uint64_t>(byte_buffer[2])) << 40;
-    result |= (static_cast<uint64_t>(byte_buffer[3])) << 32;
-    result |= (static_cast<uint64_t>(byte_buffer[4])) << 24;
-    result |= (static_cast<uint64_t>(byte_buffer[5])) << 16;
-    result |= (static_cast<uint64_t>(byte_buffer[6])) << 8;
-    result |= (static_cast<uint64_t>(byte_buffer[7]));
-
-    return (result);
-}
-
-/// \brief Write Unsigned 64-Bit Integer to Buffer
-///
-/// \param value 64-bit value to convert
-/// \param buffer Data buffer at least four bytes long into which the 64-bit
-///        value is written in network-byte order.
-/// \param length Length of the data buffer.
-///
-/// \return pointer to the next byte after stored value
-inline uint8_t*
-writeUint64(uint64_t value, void* buffer, size_t length) {
-    if (length < sizeof(uint64_t)) {
-        isc_throw(isc::OutOfRange,
-                  "Length (" << length << ") of buffer is insufficient " <<
-                  "to write a uint64_t");
-    }
-
-    uint8_t* byte_buffer = static_cast<uint8_t*>(buffer);
-
-    byte_buffer[0] = static_cast<uint8_t>((value & 0xff00000000000000UL) >> 56);
-    byte_buffer[1] = static_cast<uint8_t>((value & 0x00ff000000000000UL) >> 48);
-    byte_buffer[2] = static_cast<uint8_t>((value & 0x0000ff0000000000UL) >> 40);
-    byte_buffer[3] = static_cast<uint8_t>((value & 0x000000ff00000000UL) >> 32);
-    byte_buffer[4] = static_cast<uint8_t>((value & 0x00000000ff000000UL) >> 24);
-    byte_buffer[5] = static_cast<uint8_t>((value & 0x0000000000ff0000UL) >> 16);
-    byte_buffer[6] = static_cast<uint8_t>((value & 0x000000000000ff00UL) >> 8);
-    byte_buffer[7] = static_cast<uint8_t>((value & 0x00000000000000ffUL));
-
-    return (byte_buffer + sizeof(uint64_t));
-}
-
-} // namespace util
-} // namespace isc
-
-#endif // IO_UTILITIES_H
diff --git a/src/lib/util/tests/io_unittests.cc b/src/lib/util/tests/io_unittests.cc
new file mode 100644 (file)
index 0000000..c4b6a36
--- /dev/null
@@ -0,0 +1,210 @@
+// Copyright (C) 2011-2024 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+/// \brief Test of asiolink utilities
+///
+/// Tests the functionality of the asiolink utilities code by comparing them
+/// with the equivalent methods in isc::dns::[Input/Output]Buffer.
+
+#include <config.h>
+
+#include <testutils/gtest_utils.h>
+#include <util/buffer.h>
+#include <util/io.h>
+
+#include <cstddef>
+#include <cstdint>
+
+#include <arpa/inet.h>
+#include <gtest/gtest.h>
+
+using namespace isc;
+using namespace isc::util;
+
+namespace {
+
+/// @brief Check whether uint16_t can be read from a buffer properly.
+TEST(asioutil, readUint16) {
+    // Reference buffer
+    uint8_t data[2] = {0, 0};
+    InputBuffer buffer(data, sizeof(data));
+
+    // Avoid possible compiler warnings by only setting uint8_t variables to
+    // uint8_t values.
+    uint8_t i8 = 0;
+    uint8_t j8 = 0;
+    for (int i = 0; i < (2 << 8); ++i, ++i8) {
+        for (int j = 0; j < (2 << 8); ++j, ++j8) {
+            data[0] = i8;
+            data[1] = j8;
+            buffer.setPosition(0);
+            EXPECT_EQ(buffer.readUint16(), readUint16(data, sizeof(data)));
+        }
+    }
+}
+
+/// @brief Check whether reading an uint16_t results in an exception.
+TEST(asioutil, readUint16OutOfRange) {
+    uint8_t data = 0;
+    EXPECT_THROW_MSG(readUint16(&data, sizeof(data)), OutOfRange,
+                     "Expected buffer to be long enough to read a 2-byte integer, but got 1 byte "
+                     "instead");
+}
+
+/// @brief Check whether uint16_t can be written to a buffer properly.
+TEST(asioutil, writeUint16) {
+    // Reference buffer
+    OutputBuffer buffer(2);
+    uint8_t test[2];
+
+    // Avoid possible compiler warnings by only setting uint16_t variables to
+    // uint16_t values.
+    uint16_t i16 = 0;
+    for (uint32_t i = 0; i < (2 << 16); ++i, ++i16) {
+        // Write the reference data
+        buffer.clear();
+        buffer.writeUint16(i16);
+
+        // ... and the test data
+        writeUint16(i16, test, sizeof(test));
+
+        // ... and compare
+        const uint8_t* ref = static_cast<const uint8_t*>(buffer.getData());
+        EXPECT_EQ(ref[0], test[0]);
+        EXPECT_EQ(ref[1], test[1]);
+    }
+}
+
+/// @brief Check whether writing an uint16_t results in an exception.
+TEST(asioutil, writeUint16OutOfRange) {
+    uint16_t i16 = 42;
+    uint8_t data;
+    EXPECT_THROW_MSG(writeUint16(i16, &data, sizeof(data)), OutOfRange,
+                     "Expected buffer to be long enough to write a 2-byte integer, but got 1 byte "
+                     "instead");
+}
+
+/// @brief Test data shared amount readUint32 and writeUint32 tests.
+const static uint32_t test32[] = {0, 1, 2000, 0x80000000, 0xffffffff};
+
+/// @brief Check whether uint32_t can be read from a buffer properly.
+TEST(asioutil, readUint32) {
+    uint8_t data[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+
+    // Make sure that we can read data, regardless of
+    // the memory alignment. That is why we need to repeat
+    // it 4 times.
+    for (int offset = 0; offset < 4; offset++) {
+        for (size_t i = 0; i < sizeof(test32) / sizeof(uint32_t); i++) {
+            uint32_t tmp = htonl(test32[i]);
+            memcpy(&data[offset], &tmp, sizeof(uint32_t));
+
+            EXPECT_EQ(test32[i], readUint32(&data[offset], sizeof(uint32_t)));
+        }
+    }
+}
+
+/// @brief Check whether reading an uint32_t results in an exception.
+TEST(asioutil, readUint32OutOfRange) {
+    uint8_t data[3] = {0, 0, 0};
+    EXPECT_THROW_MSG(readUint32(data, sizeof(data)), OutOfRange,
+                     "Expected buffer to be long enough to read a 4-byte integer, but got 3 bytes "
+                     "instead");
+}
+
+/// @brief Check whether uint32_t can be written to a buffer properly.
+TEST(asioutil, writeUint32) {
+    uint8_t data[8];
+
+    // make sure that we can write data, regardless of
+    // the memory alignment. That's why we need to repeat
+    // it 4 times.
+    for (int offset = 0; offset < 4; offset++) {
+        for (size_t i = 0; i < sizeof(test32) / sizeof(uint32_t); i++) {
+            uint8_t* ptr = writeUint32(test32[i], &data[offset], sizeof(uint32_t));
+
+            EXPECT_EQ(&data[offset] + sizeof(uint32_t), ptr);
+
+            uint32_t tmp = htonl(test32[i]);
+
+            EXPECT_EQ(0, memcmp(&tmp, &data[offset], sizeof(uint32_t)));
+        }
+    }
+}
+
+/// @brief Check whether writing an uint32_t results in an exception.
+TEST(asioutil, writeUint32OutOfRange) {
+    uint32_t i32 = 28;
+    uint8_t data[3];
+    EXPECT_THROW_MSG(writeUint32(i32, data, sizeof(data)), OutOfRange,
+                     "Expected buffer to be long enough to write a 4-byte integer, but got 3 bytes "
+                     "instead");
+}
+
+/// @brief Check whether uint64_t can be read from a buffer properly.
+TEST(asioutil, readUint64) {
+    uint8_t buf[8];
+    for (size_t offset = 0; offset < sizeof(buf); offset++) {
+        buf[offset] = offset + 1;
+    }
+
+    // Now check if a real value could be read.
+    const uint64_t exp_val = 0x0102030405060708ul;
+    uint64_t val;
+
+    EXPECT_NO_THROW_LOG(val = readUint64(buf, 8));
+    EXPECT_EQ(val, exp_val);
+
+    // Now check if there are no buffer overflows.
+    memset(buf, 0xff, 8);
+
+    EXPECT_NO_THROW_LOG(val = readUint64(buf, 8));
+    EXPECT_EQ(0xfffffffffffffffful, val);
+}
+
+/// @brief Check whether reading an uint64_t results in an exception.
+TEST(asioutil, readUint64OutOfRange) {
+    uint8_t buf[8];
+
+    // Let's do some simple sanity checks first.
+    EXPECT_THROW_MSG(readUint64(NULL, 0), OutOfRange,
+                     "Expected buffer to be long enough to read a 8-byte integer, but got 0 bytes "
+                     "instead");
+    EXPECT_THROW_MSG(readUint64(buf, 7), OutOfRange,
+                     "Expected buffer to be long enough to read a 8-byte integer, but got 7 bytes "
+                     "instead");
+}
+
+/// @brief Check whether uint64 can be written to a buffer properly.
+TEST(asioutil, writeUint64) {
+    uint8_t data[8];
+
+    // make sure that we can write data, regardless of
+    // the memory alignment. That's why we need to repeat
+    // it 4 times.
+    for (int offset = 0; offset < 4; offset++) {
+        for (size_t i = 0; i < sizeof(test32) / sizeof(uint32_t); i++) {
+            uint8_t* ptr = writeUint32(test32[i], &data[offset], sizeof(uint32_t));
+
+            EXPECT_EQ(&data[offset] + sizeof(uint32_t), ptr);
+
+            uint32_t tmp = htonl(test32[i]);
+
+            EXPECT_EQ(0, memcmp(&tmp, &data[offset], sizeof(uint32_t)));
+        }
+    }
+}
+
+/// @brief Check whether writing an uint64_t results in an exception.
+TEST(asioutil, writeUint64OutOfRange) {
+    uint32_t i32 = 28;
+    uint8_t data[3];
+    EXPECT_THROW_MSG(writeUint32(i32, data, sizeof(data)), OutOfRange,
+                     "Expected buffer to be long enough to write a 4-byte integer, but got 3 bytes "
+                     "instead");
+}
+
+}  // namespace
diff --git a/src/lib/util/tests/io_utilities_unittest.cc b/src/lib/util/tests/io_utilities_unittest.cc
deleted file mode 100644 (file)
index 003f14f..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright (C) 2011-2024 Internet Systems Consortium, Inc. ("ISC")
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-/// \brief Test of asiolink utilities
-///
-/// Tests the functionality of the asiolink utilities code by comparing them
-/// with the equivalent methods in isc::dns::[Input/Output]Buffer.
-
-#include <config.h>
-
-#include <cstddef>
-
-#include <arpa/inet.h>
-#include <gtest/gtest.h>
-
-#include <util/buffer.h>
-#include <util/io_utilities.h>
-
-using namespace isc::util;
-
-TEST(asioutil, readUint16) {
-
-    // Reference buffer
-    uint8_t data[2] = {0, 0};
-    InputBuffer buffer(data, sizeof(data));
-
-    // Avoid possible compiler warnings by only setting uint8_t variables to
-    // uint8_t values.
-    uint8_t i8 = 0;
-    uint8_t j8 = 0;
-    for (int i = 0; i < (2 << 8); ++i, ++i8) {
-        for (int j = 0; j < (2 << 8); ++j, ++j8) {
-            data[0] = i8;
-            data[1] = j8;
-            buffer.setPosition(0);
-            EXPECT_EQ(buffer.readUint16(), readUint16(data, sizeof(data)));
-        }
-    }
-}
-
-TEST(asioutil, readUint16OutOfRange) {
-    uint8_t data = 0;
-    EXPECT_THROW(readUint16(&data, sizeof(data)), isc::OutOfRange);
-}
-
-TEST(asioutil, writeUint16) {
-
-    // Reference buffer
-    OutputBuffer buffer(2);
-    uint8_t test[2];
-
-    // Avoid possible compiler warnings by only setting uint16_t variables to
-    // uint16_t values.
-    uint16_t i16 = 0;
-    for (uint32_t i = 0; i < (2 << 16); ++i, ++i16) {
-
-        // Write the reference data
-        buffer.clear();
-        buffer.writeUint16(i16);
-
-        // ... and the test data
-        writeUint16(i16, test, sizeof(test));
-
-        // ... and compare
-        const uint8_t* ref = buffer.getData();
-        EXPECT_EQ(ref[0], test[0]);
-        EXPECT_EQ(ref[1], test[1]);
-    }
-}
-
-TEST(asioutil, writeUint16OutOfRange) {
-    uint16_t i16 = 42;
-    uint8_t data;
-    EXPECT_THROW(writeUint16(i16, &data, sizeof(data)), isc::OutOfRange);
-}
-
-// test data shared amount readUint32 and writeUint32 tests
-const static uint32_t test32[] = {
-    0,
-    1,
-    2000,
-    0x80000000,
-    0xffffffff
-};
-
-TEST(asioutil, readUint32) {
-    uint8_t data[8] = {0, 0, 0, 0, 0, 0, 0, 0};
-
-    // make sure that we can read data, regardless of
-    // the memory alignment. That' why we need to repeat
-    // it 4 times.
-    for (int offset=0; offset < 4; offset++) {
-        for (int i=0; i < sizeof(test32)/sizeof(uint32_t); i++) {
-            uint32_t tmp = htonl(test32[i]);
-            memcpy(&data[offset], &tmp, sizeof(uint32_t));
-
-            EXPECT_EQ(test32[i], readUint32(&data[offset], sizeof(uint32_t)));
-        }
-    }
-}
-
-TEST(asioutil, readUint32OutOfRange) {
-    uint8_t data[3] = {0, 0, 0};
-    EXPECT_THROW(readUint32(data, sizeof(data)), isc::OutOfRange);
-}
-
-TEST(asioutil, writeUint32) {
-    uint8_t data[8];
-
-    // make sure that we can write data, regardless of
-    // the memory alignment. That's why we need to repeat
-    // it 4 times.
-    for (int offset=0; offset < 4; offset++) {
-        for (int i=0; i < sizeof(test32)/sizeof(uint32_t); i++) {
-            uint8_t* ptr = writeUint32(test32[i], &data[offset],
-                                       sizeof(uint32_t));
-
-            EXPECT_EQ(&data[offset]+sizeof(uint32_t), ptr);
-
-            uint32_t tmp = htonl(test32[i]);
-
-            EXPECT_EQ(0, memcmp(&tmp, &data[offset], sizeof(uint32_t)));
-        }
-    }
-}
-
-TEST(asioutil, writeUint32OutOfRange) {
-    uint32_t i32 = 28;
-    uint8_t data[3];
-    EXPECT_THROW(writeUint32(i32, data, sizeof(data)), isc::OutOfRange);
-}
-
-// Tests whether uint64 can be read from a buffer properly.
-TEST(asioutil, readUint64) {
-
-    uint8_t buf[8];
-    for (int offset = 0; offset < sizeof(buf); offset++) {
-        buf[offset] = offset+1;
-    }
-
-    // Let's do some simple sanity checks first.
-    EXPECT_THROW(readUint64(NULL, 0), isc::OutOfRange);
-    EXPECT_THROW(readUint64(buf, 7), isc::OutOfRange);
-
-    // Now check if a real value could be read.
-    const uint64_t exp_val = 0x0102030405060708ul;
-    uint64_t val;
-
-    EXPECT_NO_THROW(val = readUint64(buf, 8));
-    EXPECT_EQ(val, exp_val);
-
-    // Now check if there are no buffer overflows.
-    memset(buf, 0xff, 8);
-
-    EXPECT_NO_THROW(val = readUint64(buf, 8));
-    EXPECT_EQ(0xfffffffffffffffful, val);
-}