VSTGUI Drag and Drop filepath issue

I am using the following code to determine if there is a file that was dragged on my plugin:

char const* findFilePath(IDataPackage *iDrag)
{
  for(uint32_t i = 0; i < iDrag->getCount(); i++)
  {
    void const *buffer;
    IDataPackage::Type type;
    iDrag->getData(i, buffer, type);
    if(type == IDataPackage::kFilePath)
      return static_cast<char const *>(buffer);
  }
  return nullptr;
}

The issue I am having is that sometimes the path contains extra garbage character(s):

this is from my log:

  • First 2 lines show an extra garbage character.
  • Second 2 lines show an extra garbage character + a space.
  • Last line shows the correct file path.

That was 3 attempts at dragging the SAME file!

Am I doing something wrong? Or is there a bug?

Thanks

I think I know what my problem is and my code is wrong. The string returned by getData is not \0 terminated.

Instead I need to do this:

std::string findFilePath(IDataPackage *iDrag)
{
  for(uint32_t i = 0; i < iDrag->getCount(); i++)
  {
    void const *buffer;
    IDataPackage::Type type;
    iDrag->getData(i, buffer, type);
    if(type == IDataPackage::kFilePath)
      return std::string{static_cast<char const *>(buffer), iDrag->getDataSize(i)};
  }
  return "";
}

I believe my misunderstanding of the API stemmed from the comment in IDataPackage

	enum Type {
		/** File type (UTF-8 C-String) */
		kFilePath = 0,
              // ....
	};

because C-String are always 0 terminated… maybe the comment should be amended to explicitly states that although it is a C string it is not 0 terminated, and getDataSize() must be used to know the length.

Hi
I think it should return 0-terminated string. I did a quick look. Disclaimer: I am under Win. In my case DataPackage::data is nullptr and stringsAreFiles == true and I did tests when VST is DropTarget (probably same as Yours)

uint32_t Win32DataPackage::getData (uint32_t index, const void*& buffer, Type& type) const
{
	if (index < nbItems)
	{
		if (data)
		{
			buffer = data;
			type = kBinary;
			return dataSize;
		}
		buffer = strings[index].c_str ();
		type = stringsAreFiles ? kFilePath : kText;
		return static_cast<uint32_t> (strings[index].length ());
	}
	return 0;
}