1 //-----------------------------------------------------------------------------
2 // Project : VST SDK
3 //
4 // Category : Helpers
5 // Filename : public.sdk/source/vst/hosting/hostclasses.cpp
6 // Created by : Steinberg, 03/05/2008.
7 // Description : VST 3 hostclasses, example implementations for IHostApplication, IAttributeList and IMessage
8 //
9 //-----------------------------------------------------------------------------
10 // LICENSE
11 // (c) 2019, Steinberg Media Technologies GmbH, All Rights Reserved
12 //-----------------------------------------------------------------------------
13 // Redistribution and use in source and binary forms, with or without modification,
14 // are permitted provided that the following conditions are met:
15 //
16 // * Redistributions of source code must retain the above copyright notice,
17 // this list of conditions and the following disclaimer.
18 // * Redistributions in binary form must reproduce the above copyright notice,
19 // this list of conditions and the following disclaimer in the documentation
20 // and/or other materials provided with the distribution.
21 // * Neither the name of the Steinberg Media Technologies nor the names of its
22 // contributors may be used to endorse or promote products derived from this
23 // software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
26 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 // IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
29 // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
33 // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
34 // OF THE POSSIBILITY OF SUCH DAMAGE.
35 //-----------------------------------------------------------------------------
36
37 #include "hostclasses.h"
38
39 #include <algorithm>
40
41 namespace Steinberg {
42 namespace Vst {
43
44 //-----------------------------------------------------------------------------
HostApplication()45 HostApplication::HostApplication ()
46 {
47 FUNKNOWN_CTOR
48
49 mPlugInterfaceSupport = owned (NEW PlugInterfaceSupport);
50 }
51
52 //-----------------------------------------------------------------------------
getName(String128 name)53 tresult PLUGIN_API HostApplication::getName (String128 name)
54 {
55 String str ("My VST3 HostApplication");
56 str.copyTo16 (name, 0, 127);
57 return kResultTrue;
58 }
59
60 //-----------------------------------------------------------------------------
createInstance(TUID cid,TUID _iid,void ** obj)61 tresult PLUGIN_API HostApplication::createInstance (TUID cid, TUID _iid, void** obj)
62 {
63 FUID classID (FUID::fromTUID (cid));
64 FUID interfaceID (FUID::fromTUID (_iid));
65 if (classID == IMessage::iid && interfaceID == IMessage::iid)
66 {
67 *obj = new HostMessage;
68 return kResultTrue;
69 }
70 else if (classID == IAttributeList::iid && interfaceID == IAttributeList::iid)
71 {
72 *obj = new HostAttributeList;
73 return kResultTrue;
74 }
75 *obj = nullptr;
76 return kResultFalse;
77 }
78
79 //-----------------------------------------------------------------------------
queryInterface(const char * _iid,void ** obj)80 tresult PLUGIN_API HostApplication::queryInterface (const char* _iid, void** obj)
81 {
82 QUERY_INTERFACE (_iid, obj, FUnknown::iid, IHostApplication)
83 QUERY_INTERFACE (_iid, obj, IHostApplication::iid, IHostApplication)
84
85 if (mPlugInterfaceSupport && mPlugInterfaceSupport->queryInterface (iid, obj) == kResultTrue)
86 return kResultOk;
87
88 *obj = nullptr;
89 return kResultFalse;
90 }
91
92 //-----------------------------------------------------------------------------
addRef()93 uint32 PLUGIN_API HostApplication::addRef ()
94 {
95 return 1;
96 }
97
98 //-----------------------------------------------------------------------------
release()99 uint32 PLUGIN_API HostApplication::release ()
100 {
101 return 1;
102 }
103
104 //-----------------------------------------------------------------------------
105 //-----------------------------------------------------------------------------
106 //-----------------------------------------------------------------------------
IMPLEMENT_FUNKNOWN_METHODS(HostMessage,IMessage,IMessage::iid)107 IMPLEMENT_FUNKNOWN_METHODS (HostMessage, IMessage, IMessage::iid)
108 //-----------------------------------------------------------------------------
109 HostMessage::HostMessage () : messageId (nullptr), attributeList (nullptr)
110 {
111 FUNKNOWN_CTOR
112 }
113
114 //-----------------------------------------------------------------------------
~HostMessage()115 HostMessage::~HostMessage ()
116 {
117 setMessageID (nullptr);
118 if (attributeList)
119 attributeList->release ();
120 FUNKNOWN_DTOR
121 }
122
123 //-----------------------------------------------------------------------------
getMessageID()124 const char* PLUGIN_API HostMessage::getMessageID ()
125 {
126 return messageId;
127 }
128
129 //-----------------------------------------------------------------------------
setMessageID(const char * mid)130 void PLUGIN_API HostMessage::setMessageID (const char* mid)
131 {
132 if (messageId)
133 delete[] messageId;
134 messageId = nullptr;
135 if (mid)
136 {
137 size_t len = strlen (mid) + 1;
138 messageId = new char[len];
139 strcpy (messageId, mid);
140 }
141 }
142
143 //-----------------------------------------------------------------------------
getAttributes()144 IAttributeList* PLUGIN_API HostMessage::getAttributes ()
145 {
146 if (!attributeList)
147 attributeList = new HostAttributeList;
148 return attributeList;
149 }
150
151 //-----------------------------------------------------------------------------
152 //-----------------------------------------------------------------------------
153 //-----------------------------------------------------------------------------
154 class HostAttribute
155 {
156 public:
157 enum Type
158 {
159 kInteger,
160 kFloat,
161 kString,
162 kBinary
163 };
164
HostAttribute(int64 value)165 HostAttribute (int64 value) : size (0), type (kInteger) { v.intValue = value; }
HostAttribute(double value)166 HostAttribute (double value) : size (0), type (kFloat) { v.floatValue = value; }
HostAttribute(const TChar * value,uint32 size)167 HostAttribute (const TChar* value, uint32 size) : size (size), type (kString)
168 {
169 v.stringValue = new TChar[size];
170 memcpy (v.stringValue, value, size * sizeof (TChar));
171 }
HostAttribute(const void * value,uint32 size)172 HostAttribute (const void* value, uint32 size) : size (size), type (kBinary)
173 {
174 v.binaryValue = new char[size];
175 memcpy (v.binaryValue, value, size);
176 }
~HostAttribute()177 ~HostAttribute ()
178 {
179 if (size)
180 delete[] v.binaryValue;
181 }
182
intValue() const183 int64 intValue () const { return v.intValue; }
floatValue() const184 double floatValue () const { return v.floatValue; }
stringValue(uint32 & stringSize)185 const TChar* stringValue (uint32& stringSize)
186 {
187 stringSize = size;
188 return v.stringValue;
189 }
binaryValue(uint32 & binarySize)190 const void* binaryValue (uint32& binarySize)
191 {
192 binarySize = size;
193 return v.binaryValue;
194 }
195
getType() const196 Type getType () const { return type; }
197
198 protected:
199 union v
200 {
201 int64 intValue;
202 double floatValue;
203 TChar* stringValue;
204 char* binaryValue;
205 } v;
206 uint32 size;
207 Type type;
208 };
209
210 using mapIterator = std::map<String, HostAttribute*>::iterator;
211
212 //-----------------------------------------------------------------------------
213 //-----------------------------------------------------------------------------
214 //-----------------------------------------------------------------------------
IMPLEMENT_FUNKNOWN_METHODS(HostAttributeList,IAttributeList,IAttributeList::iid)215 IMPLEMENT_FUNKNOWN_METHODS (HostAttributeList, IAttributeList, IAttributeList::iid)
216 //-----------------------------------------------------------------------------
217 HostAttributeList::HostAttributeList ()
218 {
219 FUNKNOWN_CTOR
220 }
221
222 //-----------------------------------------------------------------------------
~HostAttributeList()223 HostAttributeList::~HostAttributeList ()
224 {
225 std::map<String, HostAttribute*>::reverse_iterator it = list.rbegin ();
226 while (it != list.rend ())
227 {
228 delete it->second;
229 it++;
230 }
231 FUNKNOWN_DTOR
232 }
233
234 //-----------------------------------------------------------------------------
removeAttrID(AttrID aid)235 void HostAttributeList::removeAttrID (AttrID aid)
236 {
237 mapIterator it = list.find (aid);
238 if (it != list.end ())
239 {
240 delete it->second;
241 list.erase (it);
242 }
243 }
244
245 //-----------------------------------------------------------------------------
setInt(AttrID aid,int64 value)246 tresult PLUGIN_API HostAttributeList::setInt (AttrID aid, int64 value)
247 {
248 removeAttrID (aid);
249 list[aid] = new HostAttribute (value);
250 return kResultTrue;
251 }
252
253 //-----------------------------------------------------------------------------
getInt(AttrID aid,int64 & value)254 tresult PLUGIN_API HostAttributeList::getInt (AttrID aid, int64& value)
255 {
256 mapIterator it = list.find (aid);
257 if (it != list.end () && it->second)
258 {
259 value = it->second->intValue ();
260 return kResultTrue;
261 }
262 return kResultFalse;
263 }
264
265 //-----------------------------------------------------------------------------
setFloat(AttrID aid,double value)266 tresult PLUGIN_API HostAttributeList::setFloat (AttrID aid, double value)
267 {
268 removeAttrID (aid);
269 list[aid] = new HostAttribute (value);
270 return kResultTrue;
271 }
272
273 //-----------------------------------------------------------------------------
getFloat(AttrID aid,double & value)274 tresult PLUGIN_API HostAttributeList::getFloat (AttrID aid, double& value)
275 {
276 mapIterator it = list.find (aid);
277 if (it != list.end () && it->second)
278 {
279 value = it->second->floatValue ();
280 return kResultTrue;
281 }
282 return kResultFalse;
283 }
284
285 //-----------------------------------------------------------------------------
setString(AttrID aid,const TChar * string)286 tresult PLUGIN_API HostAttributeList::setString (AttrID aid, const TChar* string)
287 {
288 removeAttrID (aid);
289 list[aid] = new HostAttribute (string, String (const_cast<TChar*> (string)).length ());
290 return kResultTrue;
291 }
292
293 //-----------------------------------------------------------------------------
getString(AttrID aid,TChar * string,uint32 size)294 tresult PLUGIN_API HostAttributeList::getString (AttrID aid, TChar* string, uint32 size)
295 {
296 mapIterator it = list.find (aid);
297 if (it != list.end () && it->second)
298 {
299 uint32 stringSize = 0;
300 const TChar* _string = it->second->stringValue (stringSize);
301 memcpy (string, _string, std::min<uint32> (stringSize, size) * sizeof (TChar));
302 return kResultTrue;
303 }
304 return kResultFalse;
305 }
306
307 //-----------------------------------------------------------------------------
setBinary(AttrID aid,const void * data,uint32 size)308 tresult PLUGIN_API HostAttributeList::setBinary (AttrID aid, const void* data, uint32 size)
309 {
310 removeAttrID (aid);
311 list[aid] = new HostAttribute (data, size);
312 return kResultTrue;
313 }
314
315 //-----------------------------------------------------------------------------
getBinary(AttrID aid,const void * & data,uint32 & size)316 tresult PLUGIN_API HostAttributeList::getBinary (AttrID aid, const void*& data, uint32& size)
317 {
318 mapIterator it = list.find (aid);
319 if (it != list.end () && it->second)
320 {
321 data = it->second->binaryValue (size);
322 return kResultTrue;
323 }
324 size = 0;
325 return kResultFalse;
326 }
327 }
328 } // namespace
329