CARLA
 
载入中...
搜索中...
未找到
test_buffer.cpp
浏览该文件的文档.
1// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
2// de Barcelona (UAB).
3//
4// This work is licensed under the terms of the MIT license.
5// For a copy, see <https://opensource.org/licenses/MIT>.
6
7#include "test.h"
8
9#include <carla/Buffer.h>
10#include <carla/BufferPool.h>
11
12#include <array>
13#include <list>
14#include <set>
15#include <string>
16#include <vector>
17
18using namespace util::buffer;
19// 测试 Buffer 的编译兼容性
20// 目的是验证 Buffer 类的 copy_from 方法在接受多种不同类型的缓冲区容器和单个缓冲区类型作为参数时,能否顺利通过编译。
21// 通过在不同的代码块中使用各种不同类型的缓冲区相关数据结构来调用 copy_from 方法,检查编译过程中是否出现问题。
22// 这有助于确保 Buffer 类在面对多种常见和不同使用场景下的编译兼容性。
23TEST(buffer, compile) {
24 carla::Buffer buffer;
25 { std::array<boost::asio::const_buffer, 3u> s; buffer.copy_from(s); }// 使用 std::array<boost::asio::const_buffer, 3u> 进行 copy_from 操作
26 { std::array<boost::asio::mutable_buffer, 3u> s; buffer.copy_from(s); }// 使用 std::array<boost::asio::mutable_buffer, 3u> 进行 copy_from 操作
27 { std::vector<boost::asio::const_buffer> s; buffer.copy_from(s); }// 使用 std::vector<boost::asio::const_buffer> 进行 copy_from 操作
28 { std::vector<boost::asio::mutable_buffer> s; buffer.copy_from(s); } // 使用 std::vector<boost::asio::mutable_buffer> 进行 copy_from 操作
29 { std::list<boost::asio::const_buffer> s; buffer.copy_from(s); }// 使用 std::list<boost::asio::const_buffer> 进行 copy_from 操作
30 { std::list<boost::asio::mutable_buffer> s; buffer.copy_from(s); }// 使用 std::list<boost::asio::mutable_buffer> 进行 copy_from 操作
31 { std::set<boost::asio::const_buffer> s; buffer.copy_from(s); }// 使用 std::set<boost::asio::const_buffer> 进行 copy_from 操作
32 { std::set<boost::asio::mutable_buffer> s; buffer.copy_from(s); }// 使用 std::set<boost::asio::mutable_buffer> 进行 copy_from 操作
33
34 { boost::asio::const_buffer v; buffer.copy_from(v); }// 使用单个 boost::asio::const_buffer 进行 copy_from 操作
35 { boost::asio::mutable_buffer v; buffer.copy_from(v); }// 使用单个 boost::asio::mutable_buffer 进行 copy_from 操作
36 { int v[3u]; buffer.copy_from(v); }// 使用 int 数组进行 copy_from 操作
37 { std::vector<int> v; buffer.copy_from(v); }// 使用 std::vector<int> 进行 copy_from 操作
38 { std::string v; buffer.copy_from(v); }// 使用 std::string 进行 copy_from 操作
39 { std::wstring v; buffer.copy_from(v); }// 使用 std::wstring 进行 copy_from 操作
40 { struct C { int x = 0; } v[3u]; buffer.copy_from(v); }// 使用自定义结构体数组进行 copy_from 操作
41 { struct C { int x = 0; }; std::array<C, 3u> v; buffer.copy_from(v); }// 使用自定义结构体 std::array 进行 copy_from 操作
42 { struct C { int x = 0; }; std::vector<C> v; buffer.copy_from(v); }// 使用自定义结构体 std::vector 进行 copy_from 操作
43}
44// 测试从多个缓冲区序列复制到单个缓冲区
45// 此测试用例先创建多个缓冲区,将相同的字符串内容复制到每个缓冲区中,形成一个缓冲区序列
46// 然后从这个缓冲区序列创建一个新的缓冲区,并验证新缓冲区的大小和内容是否符合预期
47TEST(buffer, copy_buffer_sequence) {
48 constexpr auto number_of_buffers = 15u;
49 const std::string str = "WXdI<x->+<If$ua>$pu1AUBmS]?_PT{3z$B7L(E|?$]";
50 std::string message;
51 std::array<Buffer, number_of_buffers> buffers;
52 std::array<boost::asio::const_buffer, number_of_buffers> sequence;
53 for (auto i = 0u; i < number_of_buffers; ++i) {
54 message += str;
55 buffers[i].copy_from(str);
56 sequence[i] = buffers[i].buffer();
57 }
58 // 从多个缓冲区序列创建一个新的缓冲区
59 // 使用之前构建好的包含多个 const_buffer 元素的 sequence 数组来创建一个新的 Buffer 对象,
60 // 这个操作会将 sequence 中各个缓冲区的数据合并到新创建的缓冲区中,后续将验证合并后的结果是否正确。
61 auto result = Buffer(sequence);
62 ASSERT_EQ(result.size(), message.size());
63 // 将新生成的缓冲区转换为字符串形式,并与之前拼接好的 message 字符串进行对比,验证内容是否一致。
64 auto result_str = as_string(result);
65 ASSERT_EQ(result_str, message);
66}
67// 测试将字符串转换为缓冲区和从缓冲区转换回字符串
68// 这个测试用例先从一个给定的字符串创建缓冲区,验证缓冲区大小是否和字符串长度相等
69// 然后再将缓冲区转换回字符串,验证转换后的字符串是否和原始字符串一致
70TEST(buffer, to_from_string) {
71 const std::string str = "The quick brown fox jumps over the lazy dog";
72 // 从字符串创建缓冲区
73 // 使用给定的字符串 str 通过 Buffer 类的构造函数创建一个缓冲区对象,
74 // 此时缓冲区应该包含了与字符串对应的字符数据,并且其大小理论上应等于字符串的长度。
75 Buffer buffer(str);
76 ASSERT_EQ(buffer.size(), str.size());
77 // 将缓冲区转换回字符串
78 // 通过调用 as_string 函数(假设该函数的功能是将缓冲区转换为对应的字符串表示),将之前创建的缓冲区转换回字符串,
79 // 然后与原始字符串 str 进行比较,验证转换后的字符串内容是否与原始字符串一致,以此来检验转换功能的正确性。
80 const std::string result = as_string(buffer);
81 ASSERT_EQ(result, str);
82}
83// 测试将向量转换为缓冲区和从缓冲区转换回向量
84// 该测试用例先创建一个指定大小且填充了特定数据的向量,然后从这个向量创建缓冲区
85// 接着从缓冲区中提取数据重新构建一个向量,最后验证新构建的向量和原始向量是否相等
86TEST(buffer, to_from_vector) {
87 constexpr auto size = 1000u;
88 using T = size_t;
89 std::vector<T> v;
90 v.reserve(size);
91 // 循环向向量中添加数据,从 0 开始依次递增,填充一个包含指定数量元素的向量,用于后续转换为缓冲区以及相关验证操作。
92 for (auto i = 0u; i < size; ++i) {
93 v.emplace_back(i);
94 }
95 // 从向量创建缓冲区
96 // 通过调用 Buffer 类的构造函数(假设其支持从向量创建缓冲区的功能),将填充好数据的向量 v 转换为缓冲区对象,
97 // 同时验证生成的缓冲区大小是否等于向量中元素所占的字节数总和(通过 sizeof(T) * size 计算),以此来检验转换时缓冲区大小设置的正确性。
98 Buffer buffer(v);
99 ASSERT_EQ(buffer.size(), sizeof(T) * size);
100 auto begin = reinterpret_cast<const T *>(buffer.data());
101 // 从缓冲区中提取数据,根据缓冲区的数据指针和元素类型 T,重新构建一个向量对象,
102 // 这里通过指定起始和结束迭代器的方式,将缓冲区中的数据转换回向量表示形式,以便后续与原始向量进行对比验证。
103 std::vector<T> result(begin, begin + size);
104 ASSERT_EQ(result, v);
105}
106// 测试缓冲区的复制
107// 此测试用例先创建一个随机内容的缓冲区,然后创建一个空缓冲区并将前者的内容复制过来
108// 最后验证两个缓冲区的大小和内容是否一致
109TEST(buffer, copy) {
110 auto msg = make_random(1024u);
111 // 创建一个空的缓冲区指针(假设 make_empty 函数返回一个指向可用于后续操作的缓冲区的指针,初始为空),用于接收复制的数据。
112 auto cpy = make_empty();
113 cpy->copy_from(*msg);
114 ASSERT_EQ(msg->size(), cpy->size());
115 ASSERT_EQ(*cpy, *msg);
116}
117// 测试带偏移量的缓冲区复制
118// 这个测试用例先创建一个缓冲区,然后使用指定的偏移量将一部分数据复制到缓冲区中
119// 接着手动在缓冲区合适位置添加一些字符,最后验证缓冲区的大小和内容是否符合预期
120TEST(buffer, copy_with_offset) {
121 const char str0[] = "Hello";
122 const char str1[] = "buffer!";
123 Buffer buffer;
124 auto offset = static_cast<Buffer::size_type>(sizeof(str0));
125 // 使用 copy_from 方法,在指定的偏移量位置,将 str1 字符串对应的字符数据复制到 buffer 缓冲区中,
126 // 这里涉及到根据偏移量计算正确的复制位置以及处理不同长度的数据复制操作,后续将验证整体缓冲区内容是否正确。
127 buffer.copy_from(
128 offset,
129 reinterpret_cast<const unsigned char *>(&str1),
130 std::strlen(str1));
131 std::memcpy(buffer.data(), str0, std::strlen(str0));
132 buffer[std::strlen(str0)] = ' ';
133 auto str = std::string(str0) + " " + str1;
134 ASSERT_EQ(buffer.size(), str.size());
135 ASSERT_EQ(as_string(buffer), str.c_str());
136}
137// 测试使用 memcpy 进行缓冲区复制
138// 该测试用例先创建一个随机内容的缓冲区,然后创建一个相同大小的空缓冲区
139// 接着使用memcpy函数将原缓冲区内容复制到新缓冲区,最后验证两个缓冲区内容是否一致
140TEST(buffer, memcpy) {
141 auto msg = make_random(1024u);
142 // 创建一个与 msg 缓冲区大小相同的空缓冲区指针(通过调用 make_empty 函数并指定大小),用于后续使用 memcpy 进行数据复制。
143 auto cpy = make_empty(msg->size());
144 ASSERT_EQ(msg->size(), cpy->size());
145 auto buffer = cpy->buffer();
146 std::memcpy(buffer.data(), msg->data(), buffer.size());
147 ASSERT_EQ(*cpy, *msg);
148}
149
150#ifndef LIBCARLA_NO_EXCEPTIONS
151// 测试缓冲区大小过大时抛出异常
152// 这个测试用例验证当尝试创建一个过大尺寸的缓冲区(超出允许范围)时,是否会正确抛出std::invalid_argument异常
153// 分别测试创建缓冲区对象和重置缓冲区大小时的情况
154TEST(buffer, message_too_big) {
155 ASSERT_THROW(Buffer(4294967296ul), std::invalid_argument);
156 Buffer buf;
157 ASSERT_THROW(buf.reset(4294967296ul), std::invalid_argument);
158}
159#endif // LIBCARLA_NO_EXCEPTIONS
160// 测试缓冲区池
161// 此测试用例先创建一个缓冲区池,从池中获取一个缓冲区并复制特定字符串进去
162// 然后再次从池中获取缓冲区,验证其内容是否符合预期,以及获取不同的缓冲区时内容是否不同
163// 最后通过重置缓冲区池来测试池中弱引用相关的情况
164TEST(buffer, buffer_pool) {
165 const std::string str = "Hello buffer!";
166 // 创建一个共享指针指向 carla::BufferPool 对象,用于管理缓冲区的分配和复用等操作,后续将从这个池中获取缓冲区进行相关测试。
167 auto pool = std::make_shared<carla::BufferPool>();
168 {
169 auto buff = pool->Pop();
170 buff.copy_from(str);
171 }
172 auto buff1 = pool->Pop();
173 ASSERT_EQ(as_string(buff1), str);
174 auto buff2 = pool->Pop();
175 ASSERT_NE(as_string(buff2), str);
176 // 现在清空缓存池来测试缓存里面的弱引用
177 pool.reset();
178}
auto begin() const noexcept
名称范围迭代支持
Traits::size_t size_t
一块原始数据。 请注意,如果需要更多容量,则会分配一个新的内存块,并 删除旧的内存块。这意味着默认情况下,缓冲区只能增长。要释放内存,使用 clear 或 pop。
const value_type * data() const noexcept
直接访问分配的内存,如果没有分配内存则返回 nullptr。
void reset(size_type size)
重置缓冲区的大小。如果容量不足,当前内存将被丢弃,并分配一个新的大小为 size的内存块。 allocated.
size_type size() const noexcept
void copy_from(const T &source)
将 source复制到此缓冲区。如果需要,则分配内存。
uint32_t size_type
static std::string as_string(const Buffer &buf)
Definition test/Buffer.h:38
static shared_buffer make_empty(size_t size=0u)
Definition test/Buffer.h:25
shared_buffer make_random(size_t size)
TEST(buffer, compile)