commit a1926680fdc76cd72b61e4212f68c9abe202c36a
parent b2109439bfc2261e333d1655bd280ebe1c2ac580
Author: falkTX <falktx@falktx.com>
Date: Fri, 1 Oct 2021 21:17:41 +0100
VST3: Fix memory leak and utf16 string messages
Signed-off-by: falkTX <falktx@falktx.com>
Diffstat:
2 files changed, 54 insertions(+), 42 deletions(-)
diff --git a/distrho/src/DistrhoPluginVST3.cpp b/distrho/src/DistrhoPluginVST3.cpp
@@ -102,21 +102,6 @@ static dpf_tuid dpf_tuid_processor = { dpf_id_entry, dpf_id_proc, 0, 0 };
static dpf_tuid dpf_tuid_view = { dpf_id_entry, dpf_id_view, 0, 0 };
// --------------------------------------------------------------------------------------------------------------------
-// custom attribute list struct, used for sending utf8 strings
-
-struct v3_attribute_list_utf8 {
- struct v3_funknown;
- v3_result (V3_API *set_string_utf8)(void* self, const char* id, const char* string);
- v3_result (V3_API *get_string_utf8)(void* self, const char* id, char* string, uint32_t size);
-};
-
-static constexpr const v3_tuid v3_attribute_list_utf8_iid =
- V3_ID(d_cconst('D','P','F',' '),
- d_cconst('c','l','a','s'),
- d_cconst('a','t','t','r'),
- d_cconst('u','t','f','8'));
-
-// --------------------------------------------------------------------------------------------------------------------
// Utility functions
const char* tuid2str(const v3_tuid iid)
@@ -145,8 +130,6 @@ const char* tuid2str(const v3_tuid iid)
return "{v3_audio_processor}";
if (v3_tuid_match(iid, v3_attribute_list_iid))
return "{v3_attribute_list_iid}";
- if (v3_tuid_match(iid, v3_attribute_list_utf8_iid))
- return "{v3_attribute_list_utf8_iid|CUSTOM}";
if (v3_tuid_match(iid, v3_bstream_iid))
return "{v3_bstream}";
if (v3_tuid_match(iid, v3_component_iid))
@@ -289,6 +272,37 @@ static constexpr void (*const snprintf_f32_utf16)(int16_t*, float, size_t) = snp
static constexpr void (*const snprintf_u32_utf16)(int16_t*, uint32_t, size_t) = snprintf_utf16_t<uint32_t, format_u32>;
// --------------------------------------------------------------------------------------------------------------------
+// handy way to create a utf16 string during the current function scope, used for DSP->UI communication
+
+struct ScopedUTF16String {
+ int16_t* str;
+ ScopedUTF16String(const char* const s) noexcept;
+ ~ScopedUTF16String() noexcept;
+ operator int16_t*() const noexcept;
+};
+
+// --------------------------------------------------------------------------------------------------------------------
+
+ScopedUTF16String::ScopedUTF16String(const char* const s) noexcept
+ : str(nullptr)
+{
+ const size_t len = strlen(s);
+ str = (int16_t*)malloc(sizeof(int16_t) * len);
+ DISTRHO_SAFE_ASSERT_RETURN(str != nullptr,);
+ strncpy_utf16(str, s, len);
+}
+
+ScopedUTF16String::~ScopedUTF16String() noexcept
+{
+ std::free(str);
+}
+
+ScopedUTF16String::operator int16_t*() const noexcept
+{
+ return str;
+}
+
+// --------------------------------------------------------------------------------------------------------------------
// dpf_plugin_view_create (implemented on UI side)
v3_plugin_view** dpf_plugin_view_create(v3_host_application** host, void* instancePointer, double sampleRate);
@@ -1967,6 +1981,7 @@ private:
v3_cpp_obj(attrlist)->set_float(attrlist, "value", sampleRate);
v3_cpp_obj(fConnection)->notify(fConnection, message);
+ v3_cpp_obj_unref(attrlist);
v3_cpp_obj_unref(message);
}
@@ -1983,6 +1998,7 @@ private:
v3_cpp_obj(attrlist)->set_float(attrlist, "value", value);
v3_cpp_obj(fConnection)->notify(fConnection, message);
+ v3_cpp_obj_unref(attrlist);
v3_cpp_obj_unref(message);
}
@@ -1994,15 +2010,12 @@ private:
v3_attribute_list** const attrlist = v3_cpp_obj(message)->get_attributes(message);
DISTRHO_SAFE_ASSERT_RETURN(attrlist != nullptr,);
- v3_attribute_list_utf8** utf8attrlist = nullptr;
- DISTRHO_SAFE_ASSERT_RETURN(v3_cpp_obj_query_interface(attrlist, v3_attribute_list_utf8_iid, &utf8attrlist) == V3_OK,);
- DISTRHO_SAFE_ASSERT_RETURN(utf8attrlist != nullptr,);
-
v3_cpp_obj(attrlist)->set_int(attrlist, "__dpf_msg_target__", 2);
- v3_cpp_obj(utf8attrlist)->set_string_utf8(utf8attrlist, "key", key);
- v3_cpp_obj(utf8attrlist)->set_string_utf8(utf8attrlist, "value", value);
+ v3_cpp_obj(attrlist)->set_string(attrlist, "key", ScopedUTF16String(key));
+ v3_cpp_obj(attrlist)->set_string(attrlist, "value", ScopedUTF16String(value));
v3_cpp_obj(fConnection)->notify(fConnection, message);
+ v3_cpp_obj_unref(attrlist);
v3_cpp_obj_unref(message);
}
@@ -2017,6 +2030,7 @@ private:
v3_cpp_obj(attrlist)->set_int(attrlist, "__dpf_msg_target__", 2);
v3_cpp_obj(fConnection)->notify(fConnection, message);
+ v3_cpp_obj_unref(attrlist);
v3_cpp_obj_unref(message);
}
#endif
diff --git a/distrho/src/DistrhoUIVST3.cpp b/distrho/src/DistrhoUIVST3.cpp
@@ -52,21 +52,13 @@ static constexpr const setStateFunc setStateCallback = nullptr;
const char* tuid2str(const v3_tuid iid);
void strncpy_utf16(int16_t* dst, const char* src, size_t length);
-// --------------------------------------------------------------------------------------------------------------------
-// custom attribute list struct, used for sending utf8 strings
-
-struct v3_attribute_list_utf8 {
- struct v3_funknown;
- v3_result (V3_API *set_string_utf8)(void* self, const char* id, const char* string);
- v3_result (V3_API *get_string_utf8)(void* self, const char* id, char* string, uint32_t size);
+struct ScopedUTF16String {
+ int16_t* str;
+ ScopedUTF16String(const char* const s) noexcept;
+ ~ScopedUTF16String() noexcept;
+ operator int16_t*() const noexcept;
};
-static constexpr const v3_tuid v3_attribute_list_utf8_iid =
- V3_ID(d_cconst('D','P','F',' '),
- d_cconst('c','l','a','s'),
- d_cconst('a','t','t','r'),
- d_cconst('u','t','f','8'));
-
// --------------------------------------------------------------------------------------------------------------------
/**
@@ -234,6 +226,7 @@ public:
v3_cpp_obj(attrlist)->set_int(attrlist, "__dpf_msg_target__", 1);
v3_cpp_obj(fConnection)->notify(fConnection, message);
+ v3_cpp_obj_unref(attrlist);
v3_cpp_obj_unref(message);
}
@@ -253,6 +246,7 @@ public:
v3_cpp_obj(attrlist)->set_int(attrlist, "__dpf_msg_target__", 1);
v3_cpp_obj(fConnection)->notify(fConnection, message);
+ v3_cpp_obj_unref(attrlist);
v3_cpp_obj_unref(message);
fConnection = nullptr;
@@ -397,6 +391,7 @@ private:
v3_cpp_obj(attrlist)->set_int(attrlist, "__dpf_msg_target__", 1);
v3_cpp_obj(fConnection)->notify(fConnection, message);
+ v3_cpp_obj_unref(attrlist);
v3_cpp_obj_unref(message);
}
@@ -418,6 +413,7 @@ private:
v3_cpp_obj(attrlist)->set_int(attrlist, "started", started ? 1 : 0);
v3_cpp_obj(fConnection)->notify(fConnection, message);
+ v3_cpp_obj_unref(attrlist);
v3_cpp_obj_unref(message);
}
@@ -441,6 +437,7 @@ private:
v3_cpp_obj(attrlist)->set_float(attrlist, "value", realValue);
v3_cpp_obj(fConnection)->notify(fConnection, message);
+ v3_cpp_obj_unref(attrlist);
v3_cpp_obj_unref(message);
}
@@ -493,6 +490,7 @@ private:
v3_cpp_obj(attrlist)->set_binary(attrlist, "data", midiData, sizeof(midiData));
v3_cpp_obj(fConnection)->notify(fConnection, message);
+ v3_cpp_obj_unref(attrlist);
v3_cpp_obj_unref(message);
}
@@ -513,15 +511,12 @@ private:
v3_attribute_list** const attrlist = v3_cpp_obj(message)->get_attributes(message);
DISTRHO_SAFE_ASSERT_RETURN(attrlist != nullptr,);
- v3_attribute_list_utf8** utf8attrlist = nullptr;
- DISTRHO_SAFE_ASSERT_RETURN(v3_cpp_obj_query_interface(attrlist, v3_attribute_list_utf8_iid, &utf8attrlist) == V3_OK,);
- DISTRHO_SAFE_ASSERT_RETURN(utf8attrlist != nullptr,);
-
v3_cpp_obj(attrlist)->set_int(attrlist, "__dpf_msg_target__", 1);
- v3_cpp_obj(utf8attrlist)->set_string_utf8(utf8attrlist, "key", key);
- v3_cpp_obj(utf8attrlist)->set_string_utf8(utf8attrlist, "value", value);
+ v3_cpp_obj(attrlist)->set_string(attrlist, "key", ScopedUTF16String(key));
+ v3_cpp_obj(attrlist)->set_string(attrlist, "value", ScopedUTF16String(value));
v3_cpp_obj(fConnection)->notify(fConnection, message);
+ v3_cpp_obj_unref(attrlist);
v3_cpp_obj_unref(message);
}
@@ -539,6 +534,9 @@ private:
*/
// --------------------------------------------------------------------------------------------------------------------
+// dpf_
+
+// --------------------------------------------------------------------------------------------------------------------
// dpf_plugin_view_content_scale
struct dpf_plugin_view_content_scale : v3_plugin_view_content_scale_cpp {