Thanks to Leeor's help fixing my issue with multiple inheritance, I was continuing work on adding a Serializer interface to OP2Utility.
Unfortunately I've hit a roadblock and am not sure how to proceed.
Below I have the prototype of the Serializer interface. Notice that Serialize takes a const char* buffer as an argument.
class Serializer {
public:
virtual ~Serializer() = 0 {};
virtual void Serialize(const char* buffer, size_t size) = 0;
};
This works well for Writing streams, as it allows passing both const and non-const sources of data for writing.
void MemoryStreamWriter::Serialize(const char* buffer, size_t size)
{
if (offset + size > streamSize) {
throw std::runtime_error("Size of bytes to write exceeds remaining size of buffer.");
}
memcpy(streamBuffer + offset, buffer, size);
offset += size;
}
However, this does not work for the opposite case of reading from memory into a buffer (StreamReader). Since the buffer is const to comply with the definition of Serializer::Serialize, nothing can be read into the buffer.
void MemoryStreamReader::Serialize(const char* buffer, size_t size)
{
if (offset + size > streamSize) {
throw std::runtime_error("Size of bytes to read exceeds remaining size of buffer.");
}
memcpy(buffer, streamBuffer + offset, size);
offset += size;
}
One solution would be to remove the const qualifier from Serialize(const char* buffer, size_t size). This would allow for both reading and writing. The problem here is we can no longer write from a const source.
We could include a function overload of Serialize that only exists within StreamReader that has a const buffer. Then reading from const sources would be allowed in StreamReader. Both StreamReader and StreamWriter would comply with the Serialize interface
However, if you were reading from a source by referencing the Serialize interface, the class would not recognize the existence of the Serialize function overload containing the const buffer. This could be overcome by casting a Serializer as a StreamReader (assuming C++ supports this sort of casting like C# does?).
However, this makes me question the usefulness of having a base Serializer interface if we are casting it to read const data. This wrinkle would be in addition to checking if the Serializer is a StreamReader or StreamWriter when the size of a container needs to be initialized for writing. Between these two special case situations I'm questioning the usefulness of a Serializer interface.
Perhaps someone has a better solution for the Serialize function?
If not but people still see incorporating the Serialize interface as a net win, I will continue working on it.
Thoughts?
Thanks,
Brett