Fix deserialization format of events

Apparently it uses VLAs, but in a very sneaky way.
This commit is contained in:
Robbert van der Helm
2020-03-09 17:20:15 +01:00
parent 69008e97a4
commit 10b6121cb8
2 changed files with 18 additions and 7 deletions
+7 -5
View File
@@ -16,20 +16,22 @@
#include "serialization.h"
#include <iostream>
DynamicVstEvents::DynamicVstEvents(const VstEvents& c_events)
: events(c_events.numEvents) {
// Copy from the C-style array into a vector for serialization
for (int i = 0; i < c_events.numEvents; i++) {
events[i] = c_events.events[0][i];
events[i] = *c_events.events[i];
}
}
VstEvents& DynamicVstEvents::as_c_events() {
// Populate the vst_events struct with data from the vector
vst_events.numEvents = events.size();
vst_events.events[0] = events.data();
// Populate the vst_events struct with data from the vector. This will
// overflow past the defined length of `vst_events.events` because it's
// actually a VLA. This is why I put some padding at the end of this struct.
std::transform(events.begin(), events.end(), &vst_events.events[0],
[](VstEvent& event) -> VstEvent* { return &event; });
return vst_events;
}
+11 -2
View File
@@ -80,9 +80,9 @@ overload(Ts...)->overload<Ts...>;
*
* Before serialization the events are read from a C-style array into a vector
* using this class's constructor, and after deserializing the original struct
* can be obtained again usign the `as_c_events()` method.
* can be reconstructed usign the `as_c_events()` method.
*/
class DynamicVstEvents {
class alignas(16) DynamicVstEvents {
public:
DynamicVstEvents(){};
@@ -107,6 +107,15 @@ class DynamicVstEvents {
* vector has been filled.
*/
VstEvents vst_events;
/**
* The `VstEvents` struct is defined to look like it contains a one or two
* element array of `VstEvent` pointers. The actual truth is that the
* `VstEvents::event` array is actually a variable length array with length
* `VstEvents::numEvents`. This is probably not part of any header files
* because VLAs are not part of any C++ standard. This struct is here to
* make sure there is enough room to copy the elements into.
*/
size_t dummy[max_midi_events];
};
/**