Skip to content

Commit 9adadd2

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 394aa89 commit 9adadd2

File tree

3 files changed

+34
-6
lines changed

3 files changed

+34
-6
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 & 1 deletion
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());
@@ -378,11 +384,24 @@ buffer_iterator()
378384
buf.dropBack(1);
379385
fail_unless(buf.empty());
380386
fail_if(buf.debugSelfCheck());
381-
382387
itr = buf.begin();
383388
const auto& citr = itr;
384389
typename tnt::Buffer<N>::iterator itr2(itr);
385390

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

test/EncDecTest.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ test_basic()
230230
mpp::encode(buf, std::integral_constant<bool, false>{});
231231
mpp::encode(buf, std::integral_constant<bool, true>{});
232232
// Strings.
233+
mpp::encode(buf, "");
233234
mpp::encode(buf, "abc");
234235
const char *bbb = "defg";
235236
mpp::encode(buf, bbb);
@@ -322,7 +323,9 @@ test_basic()
322323
fail_if(bt != true);
323324

324325
// Strings.
325-
std::string a;
326+
std::string a = "nothing";
327+
fail_unless(mpp::decode(run, a));
328+
fail_if(a != "");
326329
char b_data[10];
327330
size_t b_size = 0;
328331
auto b = tnt::make_ref_vector(b_data, b_size);

0 commit comments

Comments
 (0)