mirror of
https://github.com/fraillt/bitsery.git
synced 2026-06-08 00:03:54 +00:00
added NotNull pointer to to pointer extensions
This commit is contained in:
@@ -99,7 +99,8 @@ namespace bitsery {
|
||||
}
|
||||
|
||||
void setError(ReaderError error) {
|
||||
return _inputAdapter.setError(error);
|
||||
if (this->error() == ReaderError::NoError)
|
||||
_inputAdapter.setError(error);
|
||||
}
|
||||
|
||||
void beginSession() {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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{});
|
||||
|
||||
Reference in New Issue
Block a user