Skip to content

Updating dependent libraries, docs, utility usage #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/gen_docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- name: checkout
uses: actions/checkout@v4
- name: run-doxygen
uses: mattnotmitt/doxygen-action@v1.9.8
uses: mattnotmitt/doxygen-action@v1.12.0
with:
working-directory: doc
- name: deploy-pages
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2024 by Cliff Green
# Copyright (c) 2024-2025 by Cliff Green
#
# https://github.com/connectivecpp/shared-buffer
#
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

The `shared_buffer` classes are reference counted `std::byte` buffer classes useful for asynchronous networking. In particular, the Asio asynchronous networking library requires a buffer to be kept alive and valid until the outstanding IO operation (e.g. a network write) is completed. A straightforward and idiomatic way to achieve this is by using reference counted buffers.

There are two classes - `const_shared_buffer` for outgoing buffers (which should not be modified), and `mutable_shared_buffer` for incoming buffers (mutable and expandable as data arrives). There are efficient (move) operations for creating a `const_shared_buffer` from a `mutable_shared_buffer`, which allows the use case of creating a message and serializing its contents, then sending it out over the network.
There are two classes - `const_shared_buffer` for outgoing buffers (which should not be modified), and `mutable_shared_buffer` for incoming buffers (mutable and expandable as data arrives). In addition there are efficient (move) operations for creating a `const_shared_buffer` from a `mutable_shared_buffer`. This allows the following use common networking use case: create a `mutable_shared_buffer`, serialize objects into it, then (efficiently) construct a `const_shared_buffer` and send it out over the network.

While internally all data is kept in `std::byte` buffers, convenience methods are provided for converting between traditional buffer types (such as `char *` or `unsigned char*` or similar).

Expand Down
2 changes: 1 addition & 1 deletion cmake/download_cpm.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

file(
DOWNLOAD
https://github.com/cpm-cmake/CPM.cmake/releases/download/v0.39.0/CPM.cmake
https://github.com/cpm-cmake/CPM.cmake/releases/download/v0.40.0/CPM.cmake
${CMAKE_CURRENT_BINARY_DIR}/cmake/CPM.cmake
)
include(${CMAKE_CURRENT_BINARY_DIR}/cmake/CPM.cmake)
6 changes: 3 additions & 3 deletions example/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2024 by Cliff Green
# Copyright (c) 2024-2025 by Cliff Green
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
Expand All @@ -11,8 +11,8 @@ project ( shared_buffer_example LANGUAGES CXX )
# add dependencies
include ( ../cmake/download_cpm.cmake )

CPMAddPackage ( "gh:connectivecpp/utility-rack@1.0.0" )
CPMAddPackage ( "gh:connectivecpp/binary-serialize@1.0.0" )
CPMAddPackage ( "gh:connectivecpp/utility-rack@1.0.5" )
CPMAddPackage ( "gh:connectivecpp/binary-serialize@1.0.4" )

# add executable
add_executable ( shared_buffer_example shared_buffer_example.cpp )
Expand Down
49 changes: 30 additions & 19 deletions example/shared_buffer_example.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
/** @file
*
* @brief Example code demonstrating use of @c chops::shared_buffer and
* @c chops::repeat. See @c threaded_wait_shared_demo.cpp for multithreaded
* example.
* @brief Example code demonstrating use of @c chops::shared_buffer.
* See @c threaded_wait_shared_demo.cpp for multithreaded example.
*
* @author Thurman Gillespy
*
* @copyright (c) 2019 by Thurman Gillespy
* 3/22/19
*
* Minor changes 4/3/2025 by Cliff Green (change repeat to iota, append now has endian flag).
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
Expand All @@ -25,10 +26,11 @@
#include <cstddef> // std::byte
#include <cstdint> // std::uint16_t
#include <string>
#include <cstring> // std::strlen
#include <ranges> // std::views::iota

#include "serialize/extract_append.hpp"
#include "buffer/shared_buffer.hpp"
#include "utility/repeat.hpp"

// tasty utility lambda function
constexpr auto printLn = [] () { std::cout << std::endl; };
Expand All @@ -55,17 +57,18 @@ int main() {
constexpr char str1[] = "A cat in the hat.";
const char* strptr = str1;

// add one char at a time, inside chops::repeat
chops::repeat(sizeof(str1),
[&] () { buf1.append(static_cast<std::byte> (*strptr++)); });
// add one char at a time
for (int i : std::views::iota(0u, std::strlen(strptr) + 1)) {
buf1.append(static_cast<std::byte> (*strptr++));
}

// what str1 and chops::repeat replaces
// what str1 and the loop replaces
// buf1.append(static_cast<std::byte>('A');
// buf1.append((static_cast<std::byte>(' ');
// buf1.append((static_cast<std::byte>('c');
// etc.

std::cout << "buffer1 contains " << buf1.size() << " bytes" << std::endl;
std::cout << "buffer1 contains (including trailing nul char) " << buf1.size() << " bytes" << std::endl;
// print the output, one char at a time
const char* byte = cast_to_char_ptr (buf1); // data starts here
for (unsigned int i = 0; i < buf1.size(); ++i) {
Expand All @@ -90,29 +93,37 @@ int main() {
std::cout << "buffer2 contains " << buf2.size() << " bytes and ";
std::cout << (buf2.size()/sizeof(std::uint16_t)) << " short integers\n";

// input some numbers using chops::repeat
// input some numbers
const std::uint16_t* data = cast_to_uint16_ptr (buf2);// data starts here
std::uint16_t* valptr = const_cast<std::uint16_t*>(data); // remove const*

// create number, convert to 'network' (big endian) byte order, place into buf2
std::uint16_t count = 1;
chops::repeat(NUM_INTS, [count, x = buf2.data()] () mutable {auto sz =
chops::append_val <std::uint16_t> (x, count++ * 5); x += sz; });
auto x = buf2.data();
for (int i : std::views::iota(0, NUM_INTS)) {
auto sz = chops::append_val <std::endian::big, std::uint16_t> (x, count++ * 5);
x += sz;
}

// print them out
valptr = const_cast<std::uint16_t*> (data);
// read 2 bytes, convert back to proper endian order, print
auto f = [x = buf2.data()] () mutable { std::cout << chops::extract_val<std::uint16_t>(x) << " "; x+=2;};
chops::repeat(NUM_INTS, f);
// read 2 bytes, convert back to native endian order, print
x = buf2.data();
for (int i : std::views::iota(0, NUM_INTS)) {
std::cout << chops::extract_val<std::endian::native, std::uint16_t>(x) << " ";
x+=2;
}

printLn();

// swap the buffers, print result
buf2.swap(buf1);
std::cout << "buffer2 contents after swap" << std::endl;
std::cout << cast_to_char_ptr (buf2) << std::endl;
std::cout << "buffer1 contents after swap" << std::endl;
valptr = const_cast<std::uint16_t*> (data);
chops::repeat(NUM_INTS, f);
x = buf1.data();
for (int i : std::views::iota(0, NUM_INTS)) {
std::cout << chops::extract_val<std::endian::native, std::uint16_t>(x) << " ";
x+=2;
}
printLn();

return EXIT_SUCCESS;
Expand Down
12 changes: 6 additions & 6 deletions include/buffer/shared_buffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@
* convenience methods for appending data. @c const_shared_buffer is a reference counted
* non-modifiable buffer class. Once the object is constructed, it cannot be modified.
*
* A @c const_shared_buffer can be efficiently constructed (no buffer copies) from a
* @c mutable shared_buffer. This allows the use case of serializing data into a
* @c mutable_shared_buffer then constructing a @c const_shared_buffer for writing to
* the network.
* A @c const_shared_buffer can be efficiently constructed (no buffer copies, only
* pointer assignments through move construction) from a @c mutable shared_buffer. This
* allows the use case of serializing data into a @c mutable_shared_buffer then
* constructing a @c const_shared_buffer for writing to the network.
*
* Besides the data buffer lifetime management, these utility classes eliminate data
* copies and (obviously) do not have to be used only in networking use cases.
* copies and (obviously) can be utilized in use cases other than networking.
*
* ### Additional Details
*
Expand Down Expand Up @@ -64,7 +64,7 @@
*
* @authors Cliff Green, Chris Kohlhoff
*
* @copyright (c) 2017-2024 by Cliff Green
* @copyright (c) 2017-2025 by Cliff Green
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Expand Down
4 changes: 2 additions & 2 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2024 by Cliff Green
# Copyright (c) 2024-2025 by Cliff Green
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
Expand All @@ -16,7 +16,7 @@ target_compile_features ( shared_buffer_test PRIVATE cxx_std_20 )
include ( ../cmake/download_cpm.cmake )

CPMAddPackage ( "gh:catchorg/Catch2@3.8.0" )
CPMAddPackage ( "gh:connectivecpp/utility-rack@1.0.4" )
CPMAddPackage ( "gh:connectivecpp/utility-rack@1.0.5" )

# link dependencies
target_link_libraries ( shared_buffer_test PRIVATE shared_buffer utility_rack Catch2::Catch2WithMain )
Expand Down
13 changes: 7 additions & 6 deletions test/shared_buffer_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*
* @author Cliff Green
*
* @copyright (c) 2017-2024 by Cliff Green
* @copyright (c) 2017-2025 by Cliff Green
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Expand All @@ -23,10 +23,10 @@
#include <array>
#include <algorithm> // std::copy
#include <bit> // std::bit_cast
#include <ranges> // std::views::iota

#include "buffer/shared_buffer.hpp"

#include "utility/repeat.hpp"
#include "utility/byte_array.hpp"

constexpr std::size_t test_data_size { 12u };
Expand Down Expand Up @@ -203,15 +203,16 @@ TEST_CASE ( "Mutable shared buffer resize and clear",

sb.resize(N);
REQUIRE (sb.size() == N);
chops::repeat(N, [&sb] (int i) { REQUIRE (std::to_integer<int>(*(sb.data() + i)) == 0 ); } );

for (int i : std::views::iota(0, N)) {
REQUIRE (std::to_integer<int>(*(sb.data() + i)) == 0 );
}
SECTION ( "Compare two resized mutable shared buffer with same size" ) {
chops::mutable_shared_buffer sb2(N);
REQUIRE (sb == sb2);
chops::repeat(N, [&sb, &sb2] (int i) {
for (int i : std::views::iota(0, N)) {
REQUIRE (std::to_integer<int>(*(sb.data() + i)) == 0 );
REQUIRE (std::to_integer<int>(*(sb2.data() + i)) == 0 );
} );
}
}
SECTION ( "Clear, check size" ) {
sb.clear();
Expand Down