2024-02-25 00:07:54 +00:00
|
|
|
/*
|
2025-03-09 00:33:20 +00:00
|
|
|
* Copyright (c) 2015 - 2025 Ember
|
2024-02-25 00:07:54 +00:00
|
|
|
*
|
|
|
|
|
* 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/.
|
|
|
|
|
*/
|
|
|
|
|
|
2025-04-04 21:30:52 +01:00
|
|
|
#define EMBER_BUFFER_DEBUG
|
2024-02-25 00:07:54 +00:00
|
|
|
#include <spark/buffers/DynamicBuffer.h>
|
|
|
|
|
#include <spark/buffers/BufferSequence.h>
|
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
|
#include <memory>
|
|
|
|
|
#include <string>
|
2024-07-17 08:08:50 +01:00
|
|
|
#include <string_view>
|
2024-02-25 00:07:54 +00:00
|
|
|
#include <utility>
|
|
|
|
|
#include <vector>
|
|
|
|
|
#include <cstring>
|
|
|
|
|
|
2024-12-24 01:15:35 +00:00
|
|
|
using namespace ember;
|
2024-07-17 08:08:50 +01:00
|
|
|
using namespace std::literals;
|
2024-02-25 00:07:54 +00:00
|
|
|
|
2024-07-05 00:50:52 +01:00
|
|
|
TEST(DynamicBuffer, Size) {
|
2024-07-16 18:48:43 +01:00
|
|
|
spark::io::DynamicBuffer<32> chain;
|
2024-02-25 00:07:54 +00:00
|
|
|
ASSERT_EQ(0, chain.size()) << "Chain size is incorrect";
|
|
|
|
|
|
|
|
|
|
chain.reserve(50);
|
|
|
|
|
ASSERT_EQ(50, chain.size()) << "Chain size is incorrect";
|
|
|
|
|
|
|
|
|
|
char buffer[20];
|
|
|
|
|
chain.read(buffer, sizeof(buffer));
|
|
|
|
|
ASSERT_EQ(30, chain.size()) << "Chain size is incorrect";
|
|
|
|
|
|
|
|
|
|
chain.skip(10);
|
|
|
|
|
ASSERT_EQ(20, chain.size()) << "Chain size is incorrect";
|
|
|
|
|
|
|
|
|
|
chain.write(buffer, 20);
|
|
|
|
|
ASSERT_EQ(40, chain.size()) << "Chain size is incorrect";
|
|
|
|
|
|
|
|
|
|
chain.clear();
|
|
|
|
|
ASSERT_EQ(0, chain.size()) << "Chain size is incorrect";
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-05 00:50:52 +01:00
|
|
|
TEST(DynamicBuffer, ReadWriteConsistency) {
|
2024-07-16 18:48:43 +01:00
|
|
|
spark::io::DynamicBuffer<32> chain;
|
2024-02-25 00:07:54 +00:00
|
|
|
char text[] = "The quick brown fox jumps over the lazy dog";
|
|
|
|
|
int num = 41521;
|
|
|
|
|
|
|
|
|
|
chain.write(text, sizeof(text));
|
|
|
|
|
chain.write(&num, sizeof(int));
|
|
|
|
|
|
|
|
|
|
char text_out[sizeof(text)];
|
|
|
|
|
int num_out;
|
|
|
|
|
|
|
|
|
|
chain.read(text_out, sizeof(text));
|
|
|
|
|
chain.read(&num_out, sizeof(int));
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(num, num_out) << "Read produced incorrect result";
|
|
|
|
|
ASSERT_STREQ(text, text_out) << "Read produced incorrect result";
|
|
|
|
|
ASSERT_EQ(0, chain.size()) << "Chain should be empty";
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-05 00:50:52 +01:00
|
|
|
TEST(DynamicBuffer, ReserveFetchConsistency) {
|
2024-07-16 18:48:43 +01:00
|
|
|
spark::io::DynamicBuffer<32> chain;
|
2024-02-25 00:07:54 +00:00
|
|
|
char text[] = "The quick brown fox jumps over the lazy dog";
|
|
|
|
|
const std::size_t text_len = sizeof(text);
|
|
|
|
|
|
|
|
|
|
chain.reserve(text_len);
|
|
|
|
|
ASSERT_EQ(text_len, chain.size()) << "Chain size is incorrect";
|
|
|
|
|
|
|
|
|
|
auto buffers = chain.fetch_buffers(text_len);
|
2024-08-25 11:55:10 +01:00
|
|
|
|
2024-02-25 00:07:54 +00:00
|
|
|
// store text in the retrieved buffers
|
|
|
|
|
std::size_t offset = 0;
|
|
|
|
|
|
|
|
|
|
for(auto& buffer : buffers) {
|
2025-03-28 11:57:47 +00:00
|
|
|
std::memcpy(buffer->read_ptr(), text + offset, buffer->size());
|
2024-02-25 00:07:54 +00:00
|
|
|
offset += buffer->size();
|
|
|
|
|
|
|
|
|
|
if(offset > text_len || !offset) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// read text back out
|
2024-08-25 11:55:10 +01:00
|
|
|
std::string output;
|
|
|
|
|
|
|
|
|
|
output.resize_and_overwrite(text_len, [&](char* strbuf, std::size_t size) {
|
|
|
|
|
chain.read(strbuf, size);
|
|
|
|
|
return size;
|
|
|
|
|
});
|
2024-02-25 00:07:54 +00:00
|
|
|
|
|
|
|
|
ASSERT_EQ(0, chain.size()) << "Chain size is incorrect";
|
|
|
|
|
ASSERT_STREQ(text, output.c_str()) << "Read produced incorrect result";
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-05 00:50:52 +01:00
|
|
|
TEST(DynamicBuffer, Skip) {
|
2024-07-16 18:48:43 +01:00
|
|
|
spark::io::DynamicBuffer<32> chain;
|
2024-02-25 00:07:54 +00:00
|
|
|
int foo = 960;
|
|
|
|
|
int bar = 296;
|
|
|
|
|
|
|
|
|
|
chain.write(&foo, sizeof(int));
|
|
|
|
|
chain.write(&bar, sizeof(int));
|
|
|
|
|
chain.skip(sizeof(int));
|
|
|
|
|
chain.read(&foo, sizeof(int));
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(0, chain.size()) << "Chain size is incorrect";
|
|
|
|
|
ASSERT_EQ(bar, foo) << "Skip produced incorrect result";
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-05 00:50:52 +01:00
|
|
|
TEST(DynamicBuffer, Clear) {
|
2024-07-16 18:48:43 +01:00
|
|
|
spark::io::DynamicBuffer<32> chain;
|
2024-02-25 00:07:54 +00:00
|
|
|
const int iterations = 100;
|
|
|
|
|
|
|
|
|
|
for(int i = 0; i < iterations; ++i) {
|
|
|
|
|
chain.write(&i, sizeof(int));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(sizeof(int) * iterations, chain.size()) << "Chain size is incorrect";
|
|
|
|
|
chain.clear();
|
|
|
|
|
ASSERT_EQ(0, chain.size()) << "Chain size is incorrect";
|
2024-07-07 04:42:10 +01:00
|
|
|
ASSERT_TRUE(chain.empty());
|
|
|
|
|
ASSERT_EQ(0, chain.block_count());
|
2024-02-25 00:07:54 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-05 00:50:52 +01:00
|
|
|
TEST(DynamicBuffer, AttachTail) {
|
2024-07-16 18:48:43 +01:00
|
|
|
spark::io::DynamicBuffer<32> chain;
|
2025-03-11 00:58:34 +00:00
|
|
|
auto buffer = chain.get_allocator().allocate();
|
2024-02-25 00:07:54 +00:00
|
|
|
|
|
|
|
|
std::string text("This is a string that is almost certainly longer than 32 bytes");
|
|
|
|
|
std::size_t written = buffer->write(text.c_str(), text.length());
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(0, chain.size()) << "Chain size is incorrect";
|
|
|
|
|
chain.push_back(buffer);
|
|
|
|
|
chain.skip(32); // skip first block
|
2024-07-18 09:44:56 +01:00
|
|
|
chain.advance_write(written);
|
2024-02-25 00:07:54 +00:00
|
|
|
ASSERT_EQ(written, chain.size()) << "Chain size is incorrect";
|
|
|
|
|
|
2024-08-25 11:55:10 +01:00
|
|
|
std::string output;
|
|
|
|
|
|
|
|
|
|
output.resize_and_overwrite(written, [&](char* strbuf, std::size_t size) {
|
|
|
|
|
chain.read(strbuf, size);
|
|
|
|
|
return size;
|
|
|
|
|
});
|
2024-02-25 00:07:54 +00:00
|
|
|
|
|
|
|
|
ASSERT_EQ(0, chain.size()) << "Chain size is incorrect";
|
|
|
|
|
ASSERT_EQ(0, std::memcmp(text.data(), output.data(), written)) << "Output is incorrect";
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-05 00:50:52 +01:00
|
|
|
TEST(DynamicBuffer, PopFrontPushBack) {
|
2024-07-16 18:48:43 +01:00
|
|
|
spark::io::DynamicBuffer<32> chain;
|
2025-03-11 00:58:34 +00:00
|
|
|
auto buffer = chain.get_allocator().allocate();
|
2024-02-25 00:07:54 +00:00
|
|
|
|
|
|
|
|
std::string text("This is a string that is almost certainly longer than 32 bytes");
|
|
|
|
|
std::size_t written = buffer->write(text.c_str(), text.length());
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(0, chain.size()) << "Chain size is incorrect";
|
|
|
|
|
chain.push_back(buffer);
|
|
|
|
|
ASSERT_EQ(written, chain.size()) << "Chain size is incorrect";
|
2025-03-26 10:07:47 +00:00
|
|
|
chain.pop_front();
|
2024-02-25 00:07:54 +00:00
|
|
|
ASSERT_EQ(0, chain.size()) << "Chain size is incorrect";
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-05 00:50:52 +01:00
|
|
|
TEST(DynamicBuffer, RetrieveTail) {
|
2024-07-16 18:48:43 +01:00
|
|
|
spark::io::DynamicBuffer<32> chain;
|
2024-02-25 00:07:54 +00:00
|
|
|
std::string text("This string is < 32 bytes"); // could this fail on exotic platforms?
|
|
|
|
|
chain.write(text.data(), text.length());
|
|
|
|
|
|
|
|
|
|
auto tail = chain.back();
|
2025-03-24 16:43:17 +00:00
|
|
|
ASSERT_TRUE(tail);
|
2024-02-25 00:07:54 +00:00
|
|
|
ASSERT_EQ(0, std::memcmp(text.data(), tail->storage.data(), text.length())) << "Tail data is incorrect";
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-05 00:50:52 +01:00
|
|
|
TEST(DynamicBuffer, Copy) {
|
2024-07-16 18:48:43 +01:00
|
|
|
spark::io::DynamicBuffer<32> chain;
|
2024-02-25 00:07:54 +00:00
|
|
|
int output, foo = 54543;
|
|
|
|
|
chain.write(&foo, sizeof(int));
|
|
|
|
|
ASSERT_EQ(sizeof(int), chain.size());
|
|
|
|
|
chain.copy(&output, sizeof(int));
|
|
|
|
|
ASSERT_EQ(sizeof(int), chain.size()) << "Chain size is incorrect";
|
|
|
|
|
ASSERT_EQ(foo, output) << "Copy output is incorrect";
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-05 00:50:52 +01:00
|
|
|
TEST(DynamicBuffer, CopyChain) {
|
2024-07-16 18:48:43 +01:00
|
|
|
spark::io::DynamicBuffer<sizeof(int)> chain, chain2;
|
2024-02-25 00:07:54 +00:00
|
|
|
int foo = 5491;
|
|
|
|
|
int output;
|
|
|
|
|
|
|
|
|
|
chain.write(&foo, sizeof(int));
|
|
|
|
|
chain.write(&foo, sizeof(int));
|
|
|
|
|
ASSERT_EQ(sizeof(int) * 2, chain.size()) << "Chain size is incorrect";
|
|
|
|
|
ASSERT_EQ(0, chain2.size()) << "Chain size is incorrect";
|
|
|
|
|
|
|
|
|
|
chain2 = chain;
|
|
|
|
|
ASSERT_EQ(sizeof(int) * 2, chain.size()) << "Chain size is incorrect";
|
|
|
|
|
ASSERT_EQ(sizeof(int) * 2, chain2.size()) << "Chain size is incorrect";
|
|
|
|
|
|
|
|
|
|
chain.read(&output, sizeof(int));
|
|
|
|
|
ASSERT_EQ(sizeof(int), chain.size()) << "Chain size is incorrect";
|
|
|
|
|
ASSERT_EQ(sizeof(int) * 2, chain2.size()) << "Chain size is incorrect";
|
|
|
|
|
|
|
|
|
|
chain.clear();
|
|
|
|
|
ASSERT_EQ(0, chain.size()) << "Chain size is incorrect";
|
|
|
|
|
ASSERT_EQ(sizeof(int) * 2, chain2.size()) << "Chain size is incorrect";
|
|
|
|
|
|
|
|
|
|
chain2.read(&output, sizeof(int));
|
|
|
|
|
ASSERT_EQ(foo, output) << "Chain output is incorrect";
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-05 00:50:52 +01:00
|
|
|
TEST(DynamicBuffer, MoveChain) {
|
2024-07-16 18:48:43 +01:00
|
|
|
spark::io::DynamicBuffer<32> chain, chain2;
|
2024-02-25 00:07:54 +00:00
|
|
|
int foo = 23113;
|
|
|
|
|
|
|
|
|
|
chain.write(&foo, sizeof(int));
|
|
|
|
|
ASSERT_EQ(sizeof(int), chain.size()) << "Chain size is incorrect";
|
|
|
|
|
ASSERT_EQ(0, chain2.size()) << "Chain size is incorrect";
|
|
|
|
|
|
|
|
|
|
chain2 = std::move(chain);
|
|
|
|
|
ASSERT_EQ(sizeof(int), chain2.size()) << "Chain size is incorrect";
|
|
|
|
|
|
|
|
|
|
int output;
|
|
|
|
|
chain2.read(&output, sizeof(int));
|
|
|
|
|
ASSERT_EQ(foo, output) << "Chain output is incorrect";
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-05 00:50:52 +01:00
|
|
|
TEST(DynamicBuffer, WriteSeek) {
|
2024-07-16 18:48:43 +01:00
|
|
|
spark::io::DynamicBuffer<1> chain; // ensure the data is split over multiple buffer nodes
|
2024-02-25 00:07:54 +00:00
|
|
|
const std::array<std::uint8_t, 6> data {0x00, 0x01, 0x00, 0x00, 0x04, 0x05};
|
|
|
|
|
const std::array<std::uint8_t, 2> seek_data {0x02, 0x03};
|
|
|
|
|
const std::array<std::uint8_t, 4> expected_data {0x00, 0x01, 0x02, 0x03};
|
|
|
|
|
|
|
|
|
|
chain.write(data.data(), data.size());
|
2026-02-19 01:25:02 +00:00
|
|
|
chain.write_seek(spark::io::BufferSeek::sk_backward, 4);
|
2024-02-25 00:07:54 +00:00
|
|
|
chain.write(seek_data.data(), seek_data.size());
|
|
|
|
|
|
|
|
|
|
// make sure the chain is four bytes (6 written, (-)4 rewound, (+)2 rewritten = 4)
|
|
|
|
|
ASSERT_EQ(chain.size(), 4) << "Chain size is incorrect";
|
|
|
|
|
|
|
|
|
|
std::vector<std::uint8_t> out(chain.size());
|
|
|
|
|
chain.copy(out.data(), out.size());
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(0, std::memcmp(out.data(), expected_data.data(), expected_data.size()))
|
|
|
|
|
<< "Buffer contains incorrect data pattern";
|
|
|
|
|
|
|
|
|
|
// put the write cursor back to its original position and write more data
|
2026-02-19 01:25:02 +00:00
|
|
|
chain.write_seek(spark::io::BufferSeek::sk_forward, 2);
|
2024-02-25 00:07:54 +00:00
|
|
|
|
|
|
|
|
// should be six bytes in there
|
|
|
|
|
ASSERT_EQ(chain.size(), data.size()) << "Chain size is incorrect";
|
|
|
|
|
|
|
|
|
|
const std::array<std::uint8_t, 8> final_data {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
|
|
|
|
|
const std::array<std::uint8_t, 2> new_data {0x06, 0x07};
|
|
|
|
|
chain.write(new_data.data(), new_data.size());
|
|
|
|
|
|
|
|
|
|
// should be eight bytes in there
|
|
|
|
|
ASSERT_EQ(chain.size(), final_data.size()) << "Chain size is incorrect";
|
|
|
|
|
|
|
|
|
|
// check the pattern/sequence/whatever
|
|
|
|
|
out.resize(chain.size());
|
|
|
|
|
chain.read(out.data(), out.size());
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(0, std::memcmp(out.data(), final_data.data(), final_data.size()))
|
|
|
|
|
<< "Buffer contains incorrect data pattern";
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-05 00:50:52 +01:00
|
|
|
TEST(DynamicBuffer, ReadIterator) {
|
2024-07-16 18:48:43 +01:00
|
|
|
spark::io::DynamicBuffer<16> chain; // ensure the string is split over multiple buffers
|
|
|
|
|
spark::io::BufferSequence sequence(chain);
|
2024-02-25 00:07:54 +00:00
|
|
|
std::string skip("Skipping");
|
|
|
|
|
std::string input("The quick brown fox jumps over the lazy dog");
|
|
|
|
|
std::string output;
|
|
|
|
|
|
|
|
|
|
chain.write(skip.data(), skip.size());
|
|
|
|
|
chain.write(input.data(), input.size());
|
|
|
|
|
chain.skip(skip.size()); // ensure skipped data isn't read back out
|
|
|
|
|
|
|
|
|
|
for(auto i = sequence.begin(), j = sequence.end(); i != j; ++i) {
|
|
|
|
|
auto buffer = i.get_buffer();
|
2025-03-28 12:45:34 +00:00
|
|
|
std::copy(buffer.data(), buffer.data() + buffer.size(), std::back_inserter(output));
|
2024-02-25 00:07:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(input, output) << "Read iterator produced incorrect result";
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-02 03:12:03 +00:00
|
|
|
TEST(DynamicBuffer, AsioIteratorRegressionTest) {
|
2024-07-16 18:48:43 +01:00
|
|
|
spark::io::DynamicBuffer<1> chain;
|
|
|
|
|
spark::io::BufferSequence sequence(chain);
|
2024-02-25 00:07:54 +00:00
|
|
|
|
|
|
|
|
// 119 bytes (size of 1.12.1 LoginChallenge packet)
|
|
|
|
|
std::string input("Lorem ipsum dolor sit amet, consectetur adipiscing elit."
|
|
|
|
|
" Etiam sagittis pulvinar massa nec pellentesque. Integer metus.");
|
|
|
|
|
|
|
|
|
|
chain.write(input.data(), input.length());
|
|
|
|
|
ASSERT_EQ(119, chain.size()) << "Chain size was incorrect";
|
|
|
|
|
|
|
|
|
|
auto it = sequence.begin();
|
|
|
|
|
std::size_t bytes_sent = 0;
|
|
|
|
|
|
|
|
|
|
// do first read
|
|
|
|
|
for(std::size_t i = 0; it != sequence.end() && i != 64; ++i, ++it) {
|
2025-03-09 00:33:20 +00:00
|
|
|
bytes_sent += it.get_buffer().size();
|
2024-02-25 00:07:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
chain.skip(bytes_sent);
|
|
|
|
|
ASSERT_EQ(64, bytes_sent) << "First read length was incorrect";
|
|
|
|
|
ASSERT_EQ(55, chain.size()) << "Chain size was incorrect";
|
|
|
|
|
|
|
|
|
|
auto it_s = sequence.begin();
|
|
|
|
|
bytes_sent = 0;
|
|
|
|
|
|
|
|
|
|
// do second read
|
|
|
|
|
for(std::size_t i = 0; it_s != sequence.end() && i != 64; ++i, ++it_s) {
|
2025-03-09 00:33:20 +00:00
|
|
|
bytes_sent += it_s.get_buffer().size();
|
2024-02-25 00:07:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
chain.skip(bytes_sent);
|
|
|
|
|
ASSERT_EQ(55, bytes_sent) << "Second read length was incorrect";
|
|
|
|
|
ASSERT_EQ(0, chain.size()) << "Chain size was incorrect";
|
|
|
|
|
|
|
|
|
|
//chain.clear();
|
|
|
|
|
input = "xy"; // two bytes - size of LoginProof if failed login
|
|
|
|
|
chain.write(input.data(), input.length());
|
|
|
|
|
ASSERT_EQ(2, chain.size()) << "Chain size was incorrect";
|
|
|
|
|
|
|
|
|
|
auto it_t = sequence.begin();
|
|
|
|
|
bytes_sent = 0;
|
|
|
|
|
|
|
|
|
|
// do third read
|
|
|
|
|
for(std::size_t i = 0; it_t != sequence.end() && i != 64; ++i, ++it_t) {
|
2025-03-09 00:33:20 +00:00
|
|
|
bytes_sent += it_t.get_buffer().size();
|
2024-02-25 00:07:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
chain.skip(bytes_sent);
|
|
|
|
|
ASSERT_EQ(2, bytes_sent) << "Regression found - read length was incorrect";
|
|
|
|
|
ASSERT_EQ(0, chain.size()) << "Chain size was incorrect";
|
2024-07-05 00:50:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(DynamicBuffer, Empty) {
|
2024-07-16 18:48:43 +01:00
|
|
|
spark::io::DynamicBuffer<32> chain;
|
2024-07-05 00:50:52 +01:00
|
|
|
ASSERT_TRUE(chain.empty());
|
|
|
|
|
const auto value = 0;
|
|
|
|
|
chain.write(&value, sizeof(value));
|
|
|
|
|
ASSERT_FALSE(chain.empty());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(DynamicBuffer, BlockSize) {
|
2024-07-16 18:48:43 +01:00
|
|
|
spark::io::DynamicBuffer<32> chain;
|
2024-07-05 00:50:52 +01:00
|
|
|
ASSERT_EQ(chain.block_size(), 32);
|
2024-07-16 18:48:43 +01:00
|
|
|
spark::io::DynamicBuffer<64> chain2;
|
2024-07-05 00:50:52 +01:00
|
|
|
ASSERT_EQ(chain2.block_size(), 64);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(DynamicBuffer, BlockCount) {
|
2024-07-16 18:48:43 +01:00
|
|
|
spark::io::DynamicBuffer<1> chain;
|
2024-07-05 00:50:52 +01:00
|
|
|
const std::uint8_t value = 0;
|
|
|
|
|
chain.write(&value, sizeof(value));
|
|
|
|
|
ASSERT_EQ(chain.block_count(), 1);
|
|
|
|
|
chain.write(&value, sizeof(value));
|
|
|
|
|
ASSERT_EQ(chain.block_count(), 2);
|
|
|
|
|
chain.write(&value, sizeof(value));
|
|
|
|
|
chain.write(&value, sizeof(value));
|
|
|
|
|
ASSERT_EQ(chain.block_count(), 4);
|
2025-03-26 10:07:47 +00:00
|
|
|
chain.pop_front();
|
2024-07-05 00:50:52 +01:00
|
|
|
ASSERT_EQ(chain.block_count(), 3);
|
2024-07-17 08:08:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(DynamicBuffer, FindFirstOf) {
|
|
|
|
|
spark::io::DynamicBuffer<64> dynbuf;
|
|
|
|
|
const auto str = "The quick brown fox jumped over the lazy dog"sv;
|
|
|
|
|
dynbuf.write(str.data(), str.size());
|
|
|
|
|
auto pos = dynbuf.find_first_of(std::byte('\0'));
|
|
|
|
|
ASSERT_EQ(pos, dynbuf.npos); // direct string write is not terminated
|
|
|
|
|
pos = dynbuf.find_first_of(std::byte('g'));
|
|
|
|
|
ASSERT_EQ(pos, 43);
|
|
|
|
|
pos = dynbuf.find_first_of(std::byte('T'));
|
|
|
|
|
ASSERT_EQ(pos, 0);
|
|
|
|
|
pos = dynbuf.find_first_of(std::byte('t'));
|
|
|
|
|
ASSERT_EQ(pos, 32);
|
2015-10-26 14:14:42 +00:00
|
|
|
}
|