serialization: Fix incorrect byte alignment when...

...dynamic properties contain object pointers that end with bit-based
properties.
This commit is contained in:
pythonology 2019-06-15 23:12:04 -04:00
parent 40d088efe3
commit 6a89e22a29
3 changed files with 24 additions and 6 deletions

View File

@ -278,6 +278,11 @@ namespace ki
*/ */
void seek(stream_pos position, bool expand = true); void seek(stream_pos position, bool expand = true);
/**
* Realigns the position of the stream so that it lies directly on a byte.
*/
void realign();
/** /**
* @returns The current size of the internal buffer. * @returns The current size of the internal buffer.
*/ */

View File

@ -163,9 +163,9 @@ namespace serialization
void BinarySerializer::save_property(const pclass::IProperty &prop, BitStream &stream) const void BinarySerializer::save_property(const pclass::IProperty &prop, BitStream &stream) const
{ {
// Determine if we need to re-align the stream so that our position lies on a byte // Realign the stream if we're going to write a prefix for this property
if (prop.get_type().is_byte_based() || prop.is_dynamic() || m_is_file) if (prop.is_dynamic() || m_is_file)
stream.seek(BitStream::stream_pos(stream.tell().as_bytes(), 0)); stream.realign();
// Remember where we started writing the property data // Remember where we started writing the property data
const auto start_pos = stream.tell(); const auto start_pos = stream.tell();
@ -196,6 +196,10 @@ namespace serialization
for (auto i = 0; i < prop.get_element_count(); ++i) for (auto i = 0; i < prop.get_element_count(); ++i)
{ {
// Realign the stream if this property works in bytes
if (prop.get_type().is_byte_based())
stream.realign();
if (prop.is_pointer() if (prop.is_pointer()
&& prop.get_type().get_kind() == pclass::Type::Kind::CLASS) && prop.get_type().get_kind() == pclass::Type::Kind::CLASS)
{ {
@ -369,9 +373,9 @@ namespace serialization
void BinarySerializer::load_property(pclass::IProperty &prop, BitStream &stream) const void BinarySerializer::load_property(pclass::IProperty &prop, BitStream &stream) const
{ {
// Determine if we need to re-align the stream so that our position lies on a byte // Re-align the stream if we're going to read a prefix for this property
if (prop.get_type().is_byte_based() || prop.is_dynamic()) if (prop.is_dynamic())
stream.seek(BitStream::stream_pos(stream.tell().as_bytes(), 0)); stream.realign();
// If the property is dynamic, we need to load the element count // If the property is dynamic, we need to load the element count
if (prop.is_dynamic()) if (prop.is_dynamic())
@ -393,6 +397,10 @@ namespace serialization
for (auto i = 0; i < prop.get_element_count(); ++i) for (auto i = 0; i < prop.get_element_count(); ++i)
{ {
// Realign the stream if this property works in bytes
if (prop.get_type().is_byte_based())
stream.realign();
if (prop.is_pointer() && if (prop.is_pointer() &&
prop.get_type().get_kind() == pclass::Type::Kind::CLASS) prop.get_type().get_kind() == pclass::Type::Kind::CLASS)
{ {

View File

@ -386,6 +386,11 @@ namespace ki
m_position = position; m_position = position;
} }
void realign()
{
seek(stream_pos(tell().as_bytes(), 0), false);
}
std::size_t BitStream::capacity() const std::size_t BitStream::capacity() const
{ {
return m_buffer->size(); return m_buffer->size();