Skip to content

Commit 399aabd

Browse files
alyapunovdrewdzzz
andcommitted
buffer: allow to write zero bytes
Encoder can try to write zero bytes sometimes. For example, when it encodes an empty string. Let's simply handle this case in buffer and iterators instead of assertion. Along the way, replace the assertion in `iterator::get` method as well. It should have be done in 28bae01, but we forgot about this method because it's not used by decoder. Co-authored-by: Andrey Saranchin <[email protected]>
1 parent 77db5f9 commit 399aabd

File tree

3 files changed

+34
-5
lines changed

3 files changed

+34
-5
lines changed

src/Buffer/Buffer.hpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,8 @@ template <size_t N, class allocator>
703703
void
704704
Buffer<N, allocator>::write(WData data)
705705
{
706-
assert(data.size != 0);
706+
if (data.size == 0)
707+
return;
707708

708709
char *new_end = m_end + data.size;
709710
if (TNT_LIKELY(isSameBlock(m_end, new_end))) {
@@ -1105,7 +1106,9 @@ template <bool LIGHT>
11051106
void
11061107
Buffer<N, allocator>::iterator_common<LIGHT>::set(WData data)
11071108
{
1108-
assert(data.size > 0);
1109+
if (data.size == 0)
1110+
return;
1111+
11091112
char *pos = m_position;
11101113
size_t left_in_block = N - (uintptr_t) pos % N;
11111114
while (TNT_UNLIKELY(data.size > left_in_block)) {
@@ -1160,7 +1163,9 @@ template <bool LIGHT>
11601163
void
11611164
Buffer<N, allocator>::iterator_common<LIGHT>::write(WData data)
11621165
{
1163-
assert(data.size > 0);
1166+
if (data.size == 0)
1167+
return;
1168+
11641169
size_t left_in_block = N - (uintptr_t) m_position % N;
11651170
while (TNT_UNLIKELY(data.size >= left_in_block)) {
11661171
std::memcpy(m_position, data.data, left_in_block);
@@ -1216,7 +1221,8 @@ template <bool LIGHT>
12161221
void
12171222
Buffer<N, allocator>::iterator_common<LIGHT>::get(RData data)
12181223
{
1219-
assert(data.size > 0);
1224+
if (data.size == 0)
1225+
return;
12201226
/*
12211227
* The same implementation as in ::set() method buf vice versa:
12221228
* buffer and data sources are swapped.

test/BufferUnitTest.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,12 @@ buffer_basic()
125125
TEST_INIT(1, N);
126126
tnt::Buffer<N> buf;
127127
fail_unless(buf.empty());
128+
129+
/* Empty write should work and don't write anything. */
130+
buf.write(typename tnt::Buffer<N>::WData {nullptr, 0});
131+
fail_unless(buf.empty());
132+
fail_if(buf.debugSelfCheck());
133+
128134
buf.write(int_sample);
129135
fail_unless(! buf.empty());
130136
fail_if(buf.debugSelfCheck());
@@ -383,6 +389,20 @@ buffer_iterator()
383389
const auto& citr = itr;
384390
typename tnt::Buffer<N>::iterator itr2(itr);
385391

392+
/* Empty writes and reads should work and don't write anything. */
393+
itr.write(typename tnt::Buffer<N>::WData {nullptr, 0});
394+
fail_unless(buf.empty());
395+
fail_if(buf.debugSelfCheck());
396+
itr.set(typename tnt::Buffer<N>::WData {nullptr, 0});
397+
fail_unless(buf.empty());
398+
fail_if(buf.debugSelfCheck());
399+
itr.get(typename tnt::Buffer<N>::RData {nullptr, 0});
400+
fail_unless(buf.empty());
401+
fail_if(buf.debugSelfCheck());
402+
itr.read(typename tnt::Buffer<N>::RData {nullptr, 0});
403+
fail_unless(buf.empty());
404+
fail_if(buf.debugSelfCheck());
405+
386406
auto litr1 = itr.enlight();
387407
{
388408
auto itr_test = litr1;

test/EncDecTest.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ test_basic()
221221
mpp::encode(buf, std::integral_constant<bool, false>{});
222222
mpp::encode(buf, std::integral_constant<bool, true>{});
223223
// Strings.
224+
mpp::encode(buf, "");
224225
mpp::encode(buf, "abc");
225226
const char *bbb = "defg";
226227
mpp::encode(buf, bbb);
@@ -313,7 +314,9 @@ test_basic()
313314
fail_if(bt != true);
314315

315316
// Strings.
316-
std::string a;
317+
std::string a = "to be overwritten";
318+
fail_unless(mpp::decode(run, a));
319+
fail_if(a != "");
317320
char b_data[10];
318321
size_t b_size = 0;
319322
auto b = tnt::make_ref_vector(b_data, b_size);

0 commit comments

Comments
 (0)