diff options
author | Henning Baldersheim <balder@oath.com> | 2018-06-12 12:30:36 +0200 |
---|---|---|
committer | Henning Baldersheim <balder@oath.com> | 2018-06-12 13:05:27 +0200 |
commit | a8eaaa0c3efac81262d956a71738c7ae30532671 (patch) | |
tree | 03793ec500b24897b6cc150ba7ebea375398c306 /vespalib | |
parent | acb2bb30339e55acd44985c03cd91ce29c4e3112 (diff) |
If moving a non-owned buffer make sure to copy the buffer.
Diffstat (limited to 'vespalib')
-rw-r--r-- | vespalib/src/tests/objects/nbostream/nbostream_test.cpp | 39 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/objects/nbostream.cpp | 28 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/objects/nbostream.h | 6 |
3 files changed, 70 insertions, 3 deletions
diff --git a/vespalib/src/tests/objects/nbostream/nbostream_test.cpp b/vespalib/src/tests/objects/nbostream/nbostream_test.cpp index 8b9ccb8a848..ab7265dfd69 100644 --- a/vespalib/src/tests/objects/nbostream/nbostream_test.cpp +++ b/vespalib/src/tests/objects/nbostream/nbostream_test.cpp @@ -7,6 +7,7 @@ #include <ostream> using vespalib::nbostream; +using vespalib::alloc::Alloc; using ExpBuffer = std::vector<uint8_t>; namespace std @@ -60,6 +61,44 @@ struct Fixture } }; +TEST("test that move of owned buffer does not copy") { + Alloc buf = Alloc::allocHeap(1000); + const void * ptr = buf.get(); + nbostream os(std::move(buf), 0); + os << static_cast<long>(0x567); + EXPECT_EQUAL(ptr, os.peek()); + EXPECT_EQUAL(8ul, os.size()); + nbostream moved(std::move(os)); + EXPECT_TRUE(nullptr == os.peek()); + EXPECT_EQUAL(0ul, os.size()); + EXPECT_EQUAL(ptr, moved.peek()); + EXPECT_EQUAL(8ul, moved.size()); + long tmp(0); + moved >> tmp; + EXPECT_EQUAL(0x567l, tmp); +} + +TEST("test that move of non-owned buffer does copy") { + Alloc buf = Alloc::allocHeap(1000); + const void * ptr = buf.get(); + nbostream os(std::move(buf), 0); + os << static_cast<long>(0x567); + EXPECT_EQUAL(ptr, os.peek()); + EXPECT_EQUAL(8ul, os.size()); + nbostream refering(os.peek(), os.size()); + EXPECT_EQUAL(ptr, os.peek()); + EXPECT_EQUAL(8ul, os.size()); + EXPECT_EQUAL(ptr, refering.peek()); + EXPECT_EQUAL(8ul, refering.size()); + nbostream moved(std::move(refering)); + EXPECT_TRUE(nullptr == refering.peek()); + EXPECT_EQUAL(0ul, refering.size()); + EXPECT_TRUE(ptr != moved.peek()); + EXPECT_EQUAL(8ul, moved.size()); + long tmp(0); + moved >> tmp; + EXPECT_EQUAL(0x567l, tmp); +} TEST_F("test serializing 64-bit signed integers", Fixture) { diff --git a/vespalib/src/vespa/vespalib/objects/nbostream.cpp b/vespalib/src/vespa/vespalib/objects/nbostream.cpp index ea9684efe01..871c88b5465 100644 --- a/vespalib/src/vespa/vespalib/objects/nbostream.cpp +++ b/vespalib/src/vespa/vespalib/objects/nbostream.cpp @@ -63,6 +63,33 @@ nbostream::nbostream(const nbostream & rhs) : memcpy(&_wbuf[0], &rhs._rbuf[rhs._rp], _wp); } +nbostream::nbostream(nbostream && rhs) noexcept + : _wbuf(std::move(rhs._wbuf)), + _rbuf(rhs._rbuf), + _rp(rhs._rp), + _wp(rhs._wp), + _state(rhs._state), + _longLivedBuffer(rhs._longLivedBuffer) +{ + rhs._rp = 0; + rhs._wp = 0; + rhs._rbuf = ConstBufferRef(); + if (!_longLivedBuffer && (_wbuf.capacity() == 0)) { + _wbuf.resize(roundUp2inN(_rbuf.size())); + memcpy(&_wbuf[0], &_rbuf[_rp], size()); + _wp = size(); + _rp = 0; + _rbuf = ConstBufferRef(&_wbuf[0], _wbuf.capacity()); + } +} + +nbostream & +nbostream::operator = (nbostream && rhs) noexcept { + nbostream tmp(std::move(rhs)); + swap(tmp); + return *this; +} + nbostream & nbostream::operator = (const nbostream & rhs) { if (this != &rhs) { @@ -134,6 +161,7 @@ void nbostream::swap(nbostream & os) std::swap(_state, os._state); _wbuf.swap(os._wbuf); std::swap(_rbuf, os._rbuf); + std::swap(_longLivedBuffer, os._longLivedBuffer); } } diff --git a/vespalib/src/vespa/vespalib/objects/nbostream.h b/vespalib/src/vespa/vespalib/objects/nbostream.h index 70a590f79d1..b51fff1b7cc 100644 --- a/vespalib/src/vespa/vespalib/objects/nbostream.h +++ b/vespalib/src/vespa/vespalib/objects/nbostream.h @@ -28,11 +28,11 @@ public: nbostream(const void * buf, size_t sz); nbostream(Alloc && buf, size_t sz); nbostream(const nbostream & rhs); - nbostream(nbostream && rhs) noexcept = default; + nbostream(nbostream && rhs) noexcept; ~nbostream(); nbostream & operator = (const nbostream & rhs); - nbostream & operator = (nbostream && rhs) noexcept = default; + nbostream & operator = (nbostream && rhs) noexcept; nbostream & operator << (double v) { double n(nbo::n2h(v)); write8(&n); return *this; } nbostream & operator >> (double & v) { double n; read8(&n); v = nbo::n2h(n); return *this; } @@ -228,7 +228,7 @@ public: size_t _rp; size_t _wp; State _state; - const bool _longLivedBuffer; + bool _longLivedBuffer; }; class nbostream_longlivedbuf : public nbostream { |