Skip to content

Commit 1588ee7

Browse files
More changes, adding example CMake, doc enhancements
1 parent 0846c7b commit 1588ee7

File tree

7 files changed

+165
-15
lines changed

7 files changed

+165
-15
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
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.
1414

15-
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).
15+
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.
1616

1717
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).
1818

@@ -36,7 +36,9 @@ Continuous integration workflows build and unit test on g++ (through Ubuntu), MS
3636

3737
The unit test code uses [Catch2](https://github.com/catchorg/Catch2). If the `SHARED_BUFFER_BUILD_TESTS` flag is provided to Cmake (see commands below) the Cmake configure / generate will download the Catch2 library as appropriate using the [CPM.cmake](https://github.com/cpm-cmake/CPM.cmake) dependency manager. If Catch2 (v3 or greater) is already installed using a different package manager (such as Conan or vcpkg), the `CPM_USE_LOCAL_PACKAGES` variable can be set which results in `find_package` being attempted. Note that v3 (or later) of Catch2 is required.
3838

39-
Specific version (or branch) specs for the Catch2 dependency is in `test/CMakeLists.txt`.
39+
The unit test uses utilities from Connective C++'s [utility-rack](https://github.com/connectivecpp/utility-rack).
40+
41+
Specific version (or branch) specs for the dependenies are in `test/CMakeLists.txt`.
4042

4143
## Build and Run Unit Tests
4244

cmake/download_cpm.cmake

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
# copied from CPM.cmake GitHub site
3+
# download CPM.cmake
4+
5+
file(
6+
DOWNLOAD
7+
https://github.com/cpm-cmake/CPM.cmake/releases/download/v0.39.0/CPM.cmake
8+
${CMAKE_CURRENT_BINARY_DIR}/cmake/CPM.cmake
9+
)
10+
include(${CMAKE_CURRENT_BINARY_DIR}/cmake/CPM.cmake)

example/CMakeLists.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Copyright (c) 2024 by Cliff Green
2+
#
3+
# Distributed under the Boost Software License, Version 1.0.
4+
# (See accompanying file LICENSE.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
5+
6+
cmake_minimum_required ( VERSION 3.14 FATAL_ERROR )
7+
8+
# create project
9+
project ( shared_buffer_example LANGUAGES CXX )
10+
11+
# add executable
12+
add_executable ( shared_buffer_example shared_buffer_example.cpp )
13+
target_compile_features ( shared_buffer_example PRIVATE cxx_std_20 )
14+
15+
# link dependencies
16+
target_link_libraries ( shared_buffer_example PRIVATE shared_buffer )
17+

example/shared_buffer_example.cpp

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/** @file
2+
*
3+
* @brief Example code demonstrating use of @c chops::shared_buffer and
4+
* @c chops::repeat. See @c threaded_wait_shared_demo.cpp for multithreaded
5+
* example.
6+
*
7+
* @ingroup example_module
8+
*
9+
* @author Thurman Gillespy
10+
*
11+
* Copyright (c)2019 by Thurman Gillespy
12+
* 3/22/19
13+
*
14+
* Distributed under the Boost Software License, Version 1.0.
15+
* (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
16+
*
17+
* Sample make file:
18+
* g++ -std=c++17 -I ~/Projects/utility-rack/include/ \
19+
* -I ~/Projects/boost_1_69_0/ \
20+
* shared_buffer_demo.cpp
21+
*
22+
*
23+
*/
24+
25+
#include <iostream>
26+
#include <cstdlib> // EXIT_SUCCESS
27+
#include <cstddef> // std::byte
28+
#include <cstdint> // std::uint16_t
29+
#include <string>
30+
31+
#include "marshall/extract_append.hpp"
32+
#include "marshall/shared_buffer.hpp"
33+
#include "utility/repeat.hpp"
34+
35+
// tasty utility lambda function
36+
constexpr auto printLn = [] () { std::cout << std::endl; };
37+
38+
// utility functions for casting @c wait_queue.data()
39+
template <class C>
40+
const char* cast_to_char_ptr (const C& buf) {
41+
return static_cast<const char*> (static_cast<const void*> (buf.data()));
42+
}
43+
44+
template <class C>
45+
const std::uint16_t* cast_to_uint16_ptr (const C& buf) {
46+
return static_cast<const std::uint16_t*> (static_cast<const void*> (buf.data()));
47+
}
48+
49+
50+
int main() {
51+
52+
// create empty shared buffer1
53+
chops::mutable_shared_buffer buf1;
54+
55+
std::cout << "buffer1 contains " << buf1.size() << " bytes" << std::endl;
56+
// c-string to add to buffer1
57+
constexpr char str1[] = "A cat in the hat.";
58+
const char* strptr = str1;
59+
60+
// add one char at a time, inside chops::repeat
61+
chops::repeat(sizeof(str1),
62+
[&] () { buf1.append(static_cast<std::byte> (*strptr++)); });
63+
64+
// what str1 and chops::repeat replaces
65+
// buf1.append(static_cast<std::byte>('A');
66+
// buf1.append((static_cast<std::byte>(' ');
67+
// buf1.append((static_cast<std::byte>('c');
68+
// etc.
69+
70+
std::cout << "buffer1 contains " << buf1.size() << " bytes" << std::endl;
71+
// print the output, one char at a time
72+
const char* byte = cast_to_char_ptr (buf1); // data starts here
73+
for (unsigned int i = 0; i < buf1.size(); ++i) {
74+
std::cout << *byte++;
75+
}
76+
printLn();
77+
78+
// append a string with one call to append
79+
buf1.clear(); // empty the buffer
80+
std::cout << "buffer1 contains " << buf1.size() << " bytes" << std::endl;
81+
const std::string str = "Green eggs and ham.";
82+
// convert str to C-string, add to buffer1
83+
buf1.append(str.c_str(), str.size() + 1);
84+
std::cout << "buffer1 contains " << buf1.size() << " bytes" << std::endl;
85+
// print c-string
86+
std::cout << cast_to_char_ptr (buf1) << std::endl;
87+
88+
89+
// write some short ints to a buffer
90+
constexpr int NUM_INTS = 15;
91+
chops::mutable_shared_buffer buf2(NUM_INTS * sizeof(std::uint16_t));
92+
std::cout << "buffer2 contains " << buf2.size() << " bytes and ";
93+
std::cout << (buf2.size()/sizeof(std::uint16_t)) << " short integers\n";
94+
95+
// input some numbers using chops::repeat
96+
const std::uint16_t* data = cast_to_uint16_ptr (buf2);// data starts here
97+
std::uint16_t* valptr = const_cast<std::uint16_t*>(data); // remove const*
98+
99+
// create number, convert to 'network' (big endian) byte order, place into buf2
100+
std::uint16_t count = 1;
101+
chops::repeat(NUM_INTS, [count, x = buf2.data()] () mutable {auto sz =
102+
chops::append_val <std::uint16_t> (x, count++ * 5); x += sz; });
103+
104+
// print them out
105+
valptr = const_cast<std::uint16_t*> (data);
106+
// read 2 bytes, convert back to proper endian order, print
107+
auto f = [x = buf2.data()] () mutable { std::cout << chops::extract_val<std::uint16_t>(x) << " "; x+=2;};
108+
chops::repeat(NUM_INTS, f);
109+
printLn();
110+
111+
// swap the buffers, print result
112+
buf2.swap(buf1);
113+
std::cout << "buffer2 contents after swap" << std::endl;
114+
std::cout << cast_to_char_ptr (buf2) << std::endl;
115+
std::cout << "buffer1 contents after swap" << std::endl;
116+
valptr = const_cast<std::uint16_t*> (data);
117+
chops::repeat(NUM_INTS, f);
118+
printLn();
119+
120+
return EXIT_SUCCESS;
121+
}

include/buffer/shared_buffer.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,12 @@
4444
#include <cstddef> // std::byte
4545
#include <vector>
4646
#include <memory> // std::shared_ptr
47+
#include <compare> // spaceship operator
48+
#include <span>
4749

4850
#include <utility> // std::move, std::swap
4951
#include <cstring> // std::memcpy
5052

51-
#include "utility/cast_ptr_to.hpp"
52-
5353
namespace chops {
5454

5555
class const_shared_buffer;

test/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ target_compile_features ( shared_buffer_test PRIVATE cxx_std_20 )
1616
include ( ../cmake/download_cpm.cmake )
1717

1818
CPMAddPackage ( "gh:catchorg/Catch2@3.5.4" )
19+
CPMAddPackage ( "gh:connectivecpp/utility-rack@1.0.0" )
1920

2021
# link dependencies
21-
target_link_libraries ( shared_buffer_test PRIVATE Catch2::Catch2WithMain )
22+
target_link_libraries ( shared_buffer_test PRIVATE utility_rack Catch2::Catch2WithMain )
2223

2324
enable_testing()
2425

test/shared_buffer_test.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,26 @@
11
/** @file
22
*
3-
* @ingroup test_module
3+
* @brief Test scenarios for @c mutable_shared_buffer and
4+
* @c const_shared_buffer classes.
45
*
5-
* @brief Test scenarios for @c mutable_shared_buffer and
6-
* @c const_shared_buffer classes.
6+
* @author Cliff Green
77
*
8-
* @author Cliff Green
8+
* Copyright (c) 2017-2024 by Cliff Green
99
*
10-
* Copyright (c) 2017-2018 by Cliff Green
11-
*
12-
* Distributed under the Boost Software License, Version 1.0.
13-
* (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10+
* Distributed under the Boost Software License, Version 1.0.
11+
* (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
1412
*
1513
*/
1614

17-
#include "catch2/catch.hpp"
15+
#include "catch2/catch_test_macros.hpp"
1816

1917

2018
#include <cstddef> // std::byte
2119
#include <list>
2220
#include <string_view>
21+
#include <span>
2322

24-
#include "marshall/shared_buffer.hpp"
23+
#include "buffer/shared_buffer.hpp"
2524

2625
#include "utility/repeat.hpp"
2726
#include "utility/make_byte_array.hpp"

0 commit comments

Comments
 (0)