added NotNull pointer to to pointer extensions

This commit is contained in:
fraillt
2017-10-30 08:55:27 +02:00
parent 5b1dc3bcfa
commit be9ccf08d9
4 changed files with 53 additions and 9 deletions

View File

@@ -99,7 +99,8 @@ namespace bitsery {
}
void setError(ReaderError error) {
return _inputAdapter.setError(error);
if (this->error() == ReaderError::NoError)
_inputAdapter.setError(error);
}
void beginSession() {

View File

@@ -163,9 +163,12 @@ namespace bitsery {
break;
}
}
_posItRef = _endItRef;
//restore end position
_endItRef = _sessionsStack.top();
//modify pointers only if no error or buffer overflow
if (_reader.error() == ReaderError::NoError || _reader.error() == ReaderError::DataOverflow) {
_posItRef = _endItRef;
//restore end position
_endItRef = _sessionsStack.top();
}
_sessionsStack.pop();
}
}

View File

@@ -34,6 +34,11 @@ namespace bitsery {
//forward declare
class PointerLinkingContext;
enum PointerType {
Nullable,
NotNull
};
namespace details_pointer {
enum class PointerOwnershipType:uint8_t {
@@ -263,10 +268,13 @@ namespace bitsery {
class PointerOwner {
public:
explicit PointerOwner(PointerType ptrType = PointerType::Nullable):_ptrType{ptrType} {}
template<typename Ser, typename Writer, typename T, typename Fnc>
void serialize(Ser &ser, Writer &w, const T &obj, Fnc &&) const {
auto& ctx = details_pointer::getLinkingContext(ser);
auto id = ctx.createId(obj, details_pointer::PointerOwnershipType::Owner);
assert(id || _ptrType == PointerType::Nullable);
details::writeSize(w, id);
if (id)
ctx.serialize(ser, obj);
@@ -282,18 +290,27 @@ namespace bitsery {
ctx.deserialize(des, obj);
ctx.processOwnerPtr(id, obj, details_pointer::PointerOwnershipType::Owner);
} else {
details_pointer::destroyPointer(obj);
if (_ptrType == PointerType::Nullable)
details_pointer::destroyPointer(obj);
else
r.setError(ReaderError::InvalidPointer);
}
}
private:
PointerType _ptrType;
};
class PointerObserver {
public:
explicit PointerObserver(PointerType ptrType = PointerType::Nullable):_ptrType{ptrType} {}
template<typename Ser, typename Writer, typename T, typename Fnc>
void serialize(Ser &ser, Writer &w, const T &obj, Fnc &&) const {
auto& ctx = details_pointer::getLinkingContext(ser);
details::writeSize(w, ctx.createId(obj, details_pointer::PointerOwnershipType::Observer));
auto id = ctx.createId(obj, details_pointer::PointerOwnershipType::Observer);
assert(id || _ptrType == PointerType::Nullable);
details::writeSize(w, id);
}
template<typename Des, typename Reader, typename T, typename Fnc>
@@ -304,10 +321,14 @@ namespace bitsery {
auto& ctx = details_pointer::getLinkingContext(des);
ctx.processObserverPtr(id, reinterpret_cast<void*&>(obj));
} else {
obj = nullptr;
if (_ptrType == PointerType::Nullable)
obj = nullptr;
else
r.setError(ReaderError::InvalidPointer);
}
}
private:
PointerType _ptrType;
};
class ReferencedByPointer {

View File

@@ -28,6 +28,7 @@ using bitsery::ext::PointerOwner;
using bitsery::ext::PointerObserver;
using bitsery::ext::ReferencedByPointer;
using bitsery::ext::PointerLinkingContext;
using bitsery::ext::PointerType;
using testing::Eq;
@@ -145,6 +146,12 @@ TEST_F(SerializeExtensionPointerSerialization, WhenRererencedByPointerIsSameAsPo
EXPECT_DEATH(ser1.ext2b(d1, ReferencedByPointer{}), "");
}
TEST_F(SerializeExtensionPointerSerialization, WhenNonNullPointerIsNullThenAssert) {
auto& ser1 = createSerializer();
EXPECT_DEATH(ser1.ext2b(p1null, PointerOwner{PointerType::NotNull}), "");
EXPECT_DEATH(ser1.ext2b(p1null, PointerObserver{PointerType::NotNull}), "");
}
#endif
TEST_F(SerializeExtensionPointerSerialization, WhenPointerObserverPointsToOwnerThenIsValid) {
@@ -277,7 +284,7 @@ TEST_F(SerializeExtensionPointerDeserialization, ReferencedByPointer) {
EXPECT_THAT(r3, Eq(d3));
}
TEST_F(SerializeExtensionPointerDeserialization, WhenReferencedByPointerReadsZeroPointerIdThenInvalidPointerError) {
TEST_F(SerializeExtensionPointerDeserialization, WhenReferencedByPointerReadsNullPointerThenInvalidPointerError) {
auto& ser = createSerializer();
bitsery::details::writeSize(*sctx1.bw, 0u);
ser.ext2b(d1, ReferencedByPointer{});
@@ -286,6 +293,18 @@ TEST_F(SerializeExtensionPointerDeserialization, WhenReferencedByPointerReadsZer
EXPECT_THAT(sctx1.br->error(), Eq(bitsery::ReaderError::InvalidPointer));
}
TEST_F(SerializeExtensionPointerDeserialization, WhenNonNullPointerIsNullThenInvalidPointerError) {
createSerializer();
bitsery::details::writeSize(*sctx1.bw, 0u);
auto& des1 = createDeserializer();
des1.ext2b(p1null, PointerOwner{PointerType::NotNull});
EXPECT_THAT(sctx1.br->error(), Eq(bitsery::ReaderError::InvalidPointer));
auto& des2 = createDeserializer();
des2.ext2b(p1null, PointerObserver{PointerType::NotNull});
EXPECT_THAT(sctx1.br->error(), Eq(bitsery::ReaderError::InvalidPointer));
}
TEST_F(SerializeExtensionPointerDeserialization, PointerOwnerCreatesObjects) {
auto& ser = createSerializer();
ser.ext2b(pd1, PointerOwner{});