text:
//-----------------------------------------------------------------------------
// Project     : VST SDK
//
// Category    : Helpers
// Filename    : public.sdk/source/vst/hosting/stringconvert.cpp
// Created by  : Steinberg, 11/2014
// Description : c++11 unicode string convert functions
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "stringconvert.h"
#include <codecvt>
#include <locale>
#include <istream>

//------------------------------------------------------------------------
namespace VST3 {
namespace StringConvert {

//------------------------------------------------------------------------
namespace {

#if defined(_MSC_VER) && _MSC_VER >= 1900
#define USE_WCHAR_AS_UTF16TYPE
using UTF16Type = wchar_t;
#else
using UTF16Type = char16_t;
#endif

using Coverter = std::wstring_convert<std::codecvt_utf8_utf16<UTF16Type>, UTF16Type>;

//------------------------------------------------------------------------
Coverter& converter ()
{
	static Coverter conv;
	return conv;
}

//------------------------------------------------------------------------
} // anonymous

//------------------------------------------------------------------------
std::u16string convert (const std::string& utf8Str)
{
#if defined(USE_WCHAR_AS_UTF16TYPE)
	auto wstr = converter ().from_bytes (utf8Str);
	return {wstr.data (), wstr.data () + wstr.size ()};
#else
	return converter ().from_bytes (utf8Str);
#endif
}

//------------------------------------------------------------------------
bool convert (const std::string& utf8Str, Steinberg::Vst::String128 str)
{
	return convert (utf8Str, str, 128);
}

//------------------------------------------------------------------------
bool convert (const std::string& utf8Str, Steinberg::Vst::TChar* str, uint32_t maxCharacters)
{
	auto ucs2 = convert (utf8Str);
	if (ucs2.length () < maxCharacters)
	{
		ucs2.copy (reinterpret_cast<char16_t*> (str), ucs2.length ());
		str[ucs2.length ()] = 0;
		return true;
	}
	return false;
}

//------------------------------------------------------------------------
std::string convert (const Steinberg::Vst::TChar* str)
{
	return converter ().to_bytes (reinterpret_cast<const UTF16Type*> (str));
}

//------------------------------------------------------------------------
std::string convert (const Steinberg::Vst::TChar* str, uint32_t max)
{
	std::string result;
	if (str)
	{
		Steinberg::Vst::TChar tmp[2] {};
		for (uint32_t i = 0; i < max; ++i, ++str)
		{
			tmp[0] = *str;
			if (tmp[0] == 0)
				break;
			result += convert (tmp);
		}
	}
	return result;
}

//------------------------------------------------------------------------
std::string convert (const std::u16string& str)
{
	return converter ().to_bytes (reinterpret_cast<const UTF16Type*> (str.data ()),
	                              reinterpret_cast<const UTF16Type*> (str.data () + str.size ()));
}

//------------------------------------------------------------------------
std::string convert (const char* str, uint32_t max)
{
	std::string result;
	if (str)
	{
		result.reserve (max);
		for (uint32_t i = 0; i < max; ++i, ++str)
		{
			if (*str == 0)
				break;
			result += *str;
		}
	}
	return result;
}

//------------------------------------------------------------------------
} // String
} // VST3


text:
//-----------------------------------------------------------------------------
// Project     : VST SDK
//
// Category    :
// Filename    : public.sdk/source/vst/hosting/stringconvert.h
// Created by  : Steinberg, 11/2014
// Description : c++11 unicode string convert functions
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

#include "pluginterfaces/vst/vsttypes.h"
#include <string>

//------------------------------------------------------------------------
namespace VST3 {
namespace StringConvert {

//------------------------------------------------------------------------
/**
 *  convert an UTF-8 string to an UTF-16 string
 *
 *  @param utf8Str UTF-8 string
 *
 *  @return UTF-16 string
 */
extern std::u16string convert (const std::string& utf8Str);

//------------------------------------------------------------------------
/**
 *  convert an UTF-8 string to an UTF-16 string buffer with max 127 characters
 *
 *  @param utf8Str UTF-8 string
 *  @param str     UTF-16 string buffer
 *
 *  @return true on success
 */
extern bool convert (const std::string& utf8Str, Steinberg::Vst::String128 str);

//------------------------------------------------------------------------
/**
 *  convert an UTF-8 string to an UTF-16 string buffer
 *
 *  @param utf8Str       UTF-8 string
 *  @param str           UTF-16 string buffer
 *  @param maxCharacters max characters that fit into str
 *
 *  @return true on success
 */
extern bool convert (const std::string& utf8Str, Steinberg::Vst::TChar* str,
                     uint32_t maxCharacters);

//------------------------------------------------------------------------
/**
 *  convert an UTF-16 string buffer to an UTF-8 string
 *
 *  @param str UTF-16 string buffer
 *
 *  @return UTF-8 string
 */
extern std::string convert (const Steinberg::Vst::TChar* str);

//------------------------------------------------------------------------
/**
 *  convert an UTF-16 string buffer to an UTF-8 string
 *
 *  @param str UTF-16 string buffer
 *	@param max maximum characters in str
 *
 *  @return UTF-8 string
 */
extern std::string convert (const Steinberg::Vst::TChar* str, uint32_t max);

//------------------------------------------------------------------------
/**
 *  convert an UTF-16 string to an UTF-8 string
 *
 *  @param str UTF-16 string
 *
 *  @return UTF-8 string
 */
extern std::string convert (const std::u16string& str);

//------------------------------------------------------------------------
/**
 *  convert a ASCII string buffer to an UTF-8 string
 *
 *  @param str ASCII string buffer
 *	@param max maximum characters in str
 *
 *  @return UTF-8 string
 */
extern std::string convert (const char* str, uint32_t max);

//------------------------------------------------------------------------
} // String

//------------------------------------------------------------------------
inline const Steinberg::Vst::TChar* toTChar (const std::u16string& str)
{
	return reinterpret_cast<const Steinberg::Vst::TChar*> (str.data ());
}

//------------------------------------------------------------------------
} // VST3

repo_name: fedden/RenderMan

mime_type: text/x-c++


text:
//-----------------------------------------------------------------------------
// Project     : VST SDK
//
// Category    : Helpers
// Filename    : public.sdk/source/vst/hosting/processdata.cpp
// Created by  : Steinberg, 10/2005
// Description : VST Hosting Utilities
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "processdata.h"

//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {

//------------------------------------------------------------------------
// HostProcessData
//------------------------------------------------------------------------
HostProcessData::~HostProcessData ()
{
	unprepare ();
}

//------------------------------------------------------------------------
bool HostProcessData::prepare (IComponent& component, int32 bufferSamples,
                               int32 _symbolicSampleSize)
{
	if (checkIfReallocationNeeded (component, bufferSamples, _symbolicSampleSize))
	{
		unprepare ();

		symbolicSampleSize = _symbolicSampleSize;
		channelBufferOwner = bufferSamples > 0;

		numInputs = createBuffers (component, inputs, kInput, bufferSamples);
		numOutputs = createBuffers (component, outputs, kOutput, bufferSamples);
	}
	else
	{
		// reset silence flags
		for (int32 i = 0; i < numInputs; i++)
		{
			inputs[i].silenceFlags = 0;
		}
		for (int32 i = 0; i < numOutputs; i++)
		{
			outputs[i].silenceFlags = 0;
		}
	}

	return true;
}

//------------------------------------------------------------------------
void HostProcessData::unprepare ()
{
	destroyBuffers (inputs, numInputs);
	destroyBuffers (outputs, numOutputs);

	channelBufferOwner = false;
}

//------------------------------------------------------------------------
bool HostProcessData::checkIfReallocationNeeded (IComponent& component, int32 bufferSamples,
                                                 int32 _symbolicSampleSize)
{
	if (channelBufferOwner != (bufferSamples > 0))
		return true;
	if (symbolicSampleSize != _symbolicSampleSize)
		return true;

	int32 inBusCount = component.getBusCount (kAudio, kInput);
	if (inBusCount != numInputs)
		return true;

	int32 outBusCount = component.getBusCount (kAudio, kOutput);
	if (outBusCount != numOutputs)
		return true;

	for (int32 i = 0; i < inBusCount; i++)
	{
		BusInfo busInfo = {0};

		if (component.getBusInfo (kAudio, kInput, i, busInfo) == kResultTrue)
		{
			if (inputs[i].numChannels != busInfo.channelCount)
				return true;
		}
	}
	for (int32 i = 0; i < outBusCount; i++)
	{
		BusInfo busInfo = {0};

		if (component.getBusInfo (kAudio, kOutput, i, busInfo) == kResultTrue)
		{
			if (outputs[i].numChannels != busInfo.channelCount)
				return true;
		}
	}
	return false;
}

//-----------------------------------------------------------------------------
int32 HostProcessData::createBuffers (IComponent& component, AudioBusBuffers*& buffers,
                                      BusDirection dir, int32 bufferSamples)
{
	int32 busCount = component.getBusCount (kAudio, dir);
	if (busCount > 0)
	{
		buffers = new AudioBusBuffers[busCount];

		for (int32 i = 0; i < busCount; i++)
		{
			BusInfo busInfo = {0};

			if (component.getBusInfo (kAudio, dir, i, busInfo) == kResultTrue)
			{
				buffers[i].numChannels = busInfo.channelCount;

				// allocate for each channel
				if (busInfo.channelCount > 0)
				{
					if (symbolicSampleSize == kSample64)
						buffers[i].channelBuffers64 = new Sample64*[busInfo.channelCount];
					else
						buffers[i].channelBuffers32 = new Sample32*[busInfo.channelCount];

					for (int32 j = 0; j < busInfo.channelCount; j++)
					{
						if (symbolicSampleSize == kSample64)
						{
							if (bufferSamples > 0)
								buffers[i].channelBuffers64[j] = new Sample64[bufferSamples];
							else
								buffers[i].channelBuffers64[j] = 0;
						}
						else
						{
							if (bufferSamples > 0)
								buffers[i].channelBuffers32[j] = new Sample32[bufferSamples];
							else
								buffers[i].channelBuffers32[j] = 0;
						}
					}
				}
			}
		}
	}
	return busCount;
}

//-----------------------------------------------------------------------------
void HostProcessData::destroyBuffers (AudioBusBuffers*& buffers, int32& busCount)
{
	if (buffers)
	{
		for (int32 i = 0; i < busCount; i++)
		{
			if (channelBufferOwner)
			{
				for (int32 j = 0; j < buffers[i].numChannels; j++)
				{
					if (symbolicSampleSize == kSample64)
					{
						if (buffers[i].channelBuffers64[j])
							delete[] buffers[i].channelBuffers64[j];
					}
					else
					{
						if (buffers[i].channelBuffers32[j])
							delete[] buffers[i].channelBuffers32[j];
					}
				}
			}

			if (symbolicSampleSize == kSample64)
			{
				if (buffers[i].channelBuffers64)
					delete[] buffers[i].channelBuffers64;
			}
			else
			{
				if (buffers[i].channelBuffers32)
					delete[] buffers[i].channelBuffers32;
			}
		}

		delete[] buffers;
		buffers = 0;
	}
	busCount = 0;
}

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg


text:
//-----------------------------------------------------------------------------
// Project     : VST SDK
//
// Category    : Helpers
// Filename    : public.sdk/source/vst/hosting/optional.h
// Created by  : Steinberg, 08/2016
// Description : optional helper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#pragma once

#include <memory>
#include <cassert>
#include <utility>

//------------------------------------------------------------------------
namespace VST3 {

//------------------------------------------------------------------------
template <typename T>
struct Optional
{
	Optional () noexcept : valid (false) {}
	explicit Optional (const T& v) noexcept : value (v), valid (true) {}
	Optional (T&& v) noexcept : value (std::move (v)), valid (true) {}

	Optional (Optional&& other) noexcept { *this = std::move (other); }
	Optional& operator= (Optional&& other) noexcept
	{
		valid = other.valid;
		value = std::move (other.value);
		return *this;
	}

	explicit operator bool () const noexcept
	{
		setValidationChecked ();
		return valid;
	}

	const T& operator* () const noexcept
	{
		checkValid ();
		return value;
	}

	const T* operator-> () const noexcept
	{
		checkValid ();
		return &value;
	}

	T& operator* () noexcept
	{
		checkValid ();
		return value;
	}

	T* operator-> () noexcept
	{
		checkValid ();
		return &value;
	}

	void swap (T& other) noexcept
	{
		checkValid ();
		auto tmp = std::move (other);
		other = std::move (value);
		value = std::move (tmp);
	}

private:
	T value {};
	bool valid;

#if !defined(NDEBUG)
	mutable bool validationChecked {false};
#endif

	void setValidationChecked () const
	{
#if !defined(NDEBUG)
		validationChecked = true;
#endif
	}
	void checkValid () const
	{
#if !defined(NDEBUG)
		assert (validationChecked);
#endif
	}
};

//------------------------------------------------------------------------
}


text:
//------------------------------------------------------------------------
// Project     : VST SDK
//
// Category    : Helpers
// Filename    : public.sdk/source/vst/auwrapper/auwrapper_prefix.pch
// Created by  : Steinberg, 12/2007
// Description : VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include <CoreFoundation/CoreFoundation.h>
#include <CoreAudio/CoreAudio.h>


text:
#!/usr/bin/ruby

require 'time'

cocoaClassPrefixDir=ARGV[0]

cocoaClassPrefixDir = ARGV[0]
if cocoaClassPrefixDir == nil
	$stdout << "Cannot resolve output directory\n"
	exit(-1)
end

$stdout << "Generating new class prefix for Objective-C classes in #{cocoaClassPrefixDir}\n"
File.open("#{cocoaClassPrefixDir}/aucocoaclassprefix.h", "w+") do |stream|

  		t = Time.now.to_i
        t.round
        id = t.to_s
        stream << "#define SMTG_AU_NAMESPACE\t"
        stream << "SMTGAUCocoa#{id}_\n"

end


text:
//------------------------------------------------------------------------
// Project     : VST SDK
//
// Category    : Helpers
// Filename    : public.sdk/source/vst/auwrapper/aucarbonview.mm
// Created by  : Steinberg, 12/2007
// Description : VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

/// \cond ignore

#include "aucarbonview.h"

#if !__LP64__

namespace Steinberg {
namespace Vst {

//------------------------------------------------------------------------
AUCarbonView::AUCarbonView (AudioUnitCarbonView auv)
: AUCarbonViewBase (auv)
, editController (0)
, plugView (0)
, hiPlugView (0)
{
}

//------------------------------------------------------------------------
AUCarbonView::~AUCarbonView ()
{
	if (plugView)
	{
		plugView->setFrame (0);
		plugView->removed ();
		plugView->release ();
	}
}

//------------------------------------------------------------------------
OSStatus AUCarbonView::HIViewAdded (EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
{
	UInt32 eventClass = GetEventClass (inEvent);
	UInt32 eventKind = GetEventKind (inEvent);
	if (eventClass == kEventClassControl && eventKind == kEventControlAddedSubControl)
	{
		HIViewRef newControl;
		if (GetEventParameter (inEvent, kEventParamControlSubControl, typeControlRef, NULL, sizeof (HIViewRef) , NULL , &newControl) == noErr)
		{
			AUCarbonView* wrapper = (AUCarbonView*)inUserData;
			wrapper->hiPlugView = newControl;
			RemoveEventHandler (wrapper->eventHandler);
			wrapper->eventHandler = 0;
		}
	}
	return eventNotHandledErr;
}

//------------------------------------------------------------------------
OSStatus AUCarbonView::CreateUI (Float32 xoffset, Float32 yoffset)
{
	AudioUnit unit = GetEditAudioUnit ();
	if (unit)
	{
		if (!editController)
		{
			UInt32 size = sizeof (IEditController*);
			if (AudioUnitGetProperty (unit, 64000, kAudioUnitScope_Global, 0, &editController, &size) != noErr)
				return kAudioUnitErr_NoConnection;
		}
		if (editController)
		{
			plugView = editController->createView (ViewType::kEditor);
			if (!plugView)
				return kAudioUnitErr_NoConnection;

			HIViewRef contentView;
			const EventTypeSpec eventTypes[] = {
				{ kEventClassControl, kEventControlAddedSubControl },
			};
			OSStatus err = HIViewFindByID (HIViewGetRoot (GetCarbonWindow ()), kHIViewWindowContentID, &contentView);
			err = InstallControlEventHandler (contentView, HIViewAdded, 1, eventTypes, this, &eventHandler);

			plugView->setFrame (this);

			if (plugView->attached (GetCarbonWindow (), kPlatformTypeHIView) == kResultTrue)
			{
				HIViewRemoveFromSuperview (hiPlugView);
				EmbedControl (hiPlugView);
				HIViewMoveBy (hiPlugView, xoffset, yoffset);
				return noErr;
			}
			else
				plugView->setFrame (0);
		}
	}
	return kAudioUnitErr_NoConnection;
}

//------------------------------------------------------------------------
tresult PLUGIN_API AUCarbonView::resizeView (IPlugView* view, ViewRect* vr)
{
	if (vr == 0 || view != plugView)
		return kInvalidArgument;

	HIViewRef hiView = GetCarbonPane ();
	if (hiView)
	{
		HIRect r;
		if (HIViewGetFrame (hiView, &r) != noErr)
			return kResultFalse;
		r.size.width = vr->right - vr->left;
		r.size.height = vr->bottom - vr->top;
		if (HIViewSetFrame (hiView, &r) != noErr)
			return kResultFalse;

		if (plugView)
			plugView->onSize (vr);

		return kResultTrue;
	}
	return kResultFalse;
}

//------------------------------------------------------------------------
//COMPONENT_ENTRY(AUCarbonView)
//------------------------------------------------------------------------
extern "C" {
	ComponentResult AUCarbonViewEntry(ComponentParameters *params, AUCarbonView *obj);
	__attribute__ ((visibility ("default"))) ComponentResult AUCarbonViewEntry(ComponentParameters *params, AUCarbonView *obj)
	{
		return ComponentEntryPoint<AUCarbonView>::Dispatch(params, obj);
	}
}

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg
#endif

/// \endcond


text:
if(MAC)
	if (XCODE AND SMTG_COREAUDIO_SDK_PATH)
		set(target auwrapper)
		set(${target}_sources
			aucarbonview.mm
			aucarbonview.h
			aucocoaview.mm
			aucocoaview.h
			ausdk.mm
			auwrapper.mm
			auwrapper.h
			NSDataIBStream.mm
			NSDataIBStream.h
			${SDK_ROOT}/pluginterfaces/base/funknown.cpp
			${SDK_ROOT}/pluginterfaces/base/ustring.cpp
			${SDK_ROOT}/public.sdk/source/vst/hosting/eventlist.cpp
			${SDK_ROOT}/public.sdk/source/vst/hosting/eventlist.h
			${SDK_ROOT}/public.sdk/source/vst/hosting/hostclasses.cpp
			${SDK_ROOT}/public.sdk/source/vst/hosting/hostclasses.h
			${SDK_ROOT}/public.sdk/source/vst/hosting/parameterchanges.cpp
			${SDK_ROOT}/public.sdk/source/vst/hosting/parameterchanges.h
			${SDK_ROOT}/public.sdk/source/vst/hosting/processdata.cpp
			${SDK_ROOT}/public.sdk/source/vst/hosting/processdata.h
		)
		add_library(${target} STATIC ${${target}_sources})
		target_link_libraries(${target} PRIVATE base "-framework AudioUnit" "-framework CoreMIDI" "-framework AudioToolbox" "-framework CoreFoundation" "-framework Carbon" "-framework Cocoa" "-framework CoreAudio")
		target_include_directories(${target} PRIVATE "${SMTG_COREAUDIO_SDK_PATH}/**")
	    add_custom_command(TARGET ${target} PRE_BUILD COMMAND /usr/bin/ruby "./generateCocoaClassNamePrefix.rb" "${CMAKE_CURRENT_LIST_DIR}" WORKING_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}")
	else()
		message("* To enable building the AudioUnit wrapper, you need to use the Xcode generator and set SMTG_COREAUDIO_SDK_PATH to the path of your installation of the CoreAudio SDK!")
	endif()
endif()


text:
//------------------------------------------------------------------------
// Project     : VST SDK
//
// Category    : Helpers
// Filename    : public.sdk/source/vst/auwrapper/auwrapper.h
// Created by  : Steinberg, 12/2007
// Description : VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

/**
***************************
\page auwrapper AudioUnit Wrapper
***************************
\section AUIntroduction Introduction
***************************
The VST 3 SDK comes with an AudioUnit wrapper, which can wrap one VST 3 Audio Processor and Edit Controller as an AudioUnit effect/instrument.

The wrapper is a small dynamic library which loads the VST 3 Plug-in.
As AudioUnits store some important information in their resource fork, this library must be compiled for every VST 3 Plug-in.
\n\n
***************************
\section AUhowdoesitwork How does it work ?
***************************

- build the auwrapper project (public.sdk/source/vst/auwrapper/auwrapper.xcodeproj)
- create a copy of the again AU wrapper example project directory (public.sdk/source/vst/auwrapper/again/)
- rename the copy to your needs
- edit the target settings of the project and change
	- Product Name
	- Library search path so that it points to the directory where libauwrapper.a exists
	- architecture setting so that it only includes architectures the VST 3 Plug-in supports

- search in the project for AUWRAPPER_CHANGE and change the settings to your needs, especially in :
	- edit audiounitconfig.h see comments there
	- edit Info.plist see comments there
- edit the "Make Links Script" for easier debugging/development
- build your project
- done... that is all!

For the release version, you must place a copy or an alias of your VST 3 Plug-in in the resource folder of the bundle named "plugin.vst3"

 */
/// \cond ignore

#pragma once

#if CA_USE_AUDIO_PLUGIN_ONLY
#include "AudioUnits/AUPublic/AUBase/AUBase.h"
#define AUWRAPPER_BASE_CLASS AUBase
#else
#include "AudioUnits/AUPublic/OtherBases/MusicDeviceBase.h"
#define AUWRAPPER_BASE_CLASS MusicDeviceBase
#endif
#include "pluginterfaces/vst/ivstaudioprocessor.h"
#include "pluginterfaces/vst/ivsteditcontroller.h"
#include "pluginterfaces/vst/ivstprocesscontext.h"
#include "pluginterfaces/vst/ivstunits.h"
#include "public.sdk/source/vst/hosting/parameterchanges.h"
#include "public.sdk/source/vst/hosting/processdata.h"
#include "public.sdk/source/vst/hosting/eventlist.h"
#include "base/source/timer.h"
#include "base/source/fstring.h"
#include "base/source/flock.h"
#include <Cocoa/Cocoa.h>
#include <AudioToolbox/AudioToolbox.h>
#include <vector>
#include <map>

namespace Steinberg {
namespace Vst {

//------------------------------------------------------------------------
typedef struct MIDIMessageInfoStruct {
	UInt8	status;
	UInt8	channel;
	UInt8	data1;
	UInt8	data2;
	UInt32	startFrame;
} MIDIMessageInfoStruct;

//------------------------------------------------------------------------
class MIDIOutputCallbackHelper
{
public:
	MIDIOutputCallbackHelper ()
	{
		mMIDIMessageList.reserve (16);
		mMIDICallbackStruct.midiOutputCallback = NULL;
	}
	virtual	~MIDIOutputCallbackHelper () {};

	void SetCallbackInfo (AUMIDIOutputCallback callback, void* userData)
	{
		mMIDICallbackStruct.midiOutputCallback = callback;
		mMIDICallbackStruct.userData = userData;
	}

	void AddEvent (UInt8 status, UInt8 channel, UInt8 data1, UInt8 data2, UInt32 inStartFrame)
	{
		MIDIMessageInfoStruct info = {status, channel, data1, data2, inStartFrame};
		mMIDIMessageList.push_back (info);
	}

	void FireAtTimeStamp (const AudioTimeStamp& inTimeStamp)
	{
		if (!mMIDIMessageList.empty () && mMIDICallbackStruct.midiOutputCallback != 0)
		{
			// synthesize the packet list and call the MIDIOutputCallback
			// iterate through the vector and get each item
			std::vector<MIDIMessageInfoStruct>::iterator myIterator;
			MIDIPacketList* pktlist = PacketList ();

			for (myIterator = mMIDIMessageList.begin (); myIterator != mMIDIMessageList.end (); myIterator++)
			{
				MIDIMessageInfoStruct item = *myIterator;

				MIDIPacket* pkt = MIDIPacketListInit (pktlist);
				bool tooBig = false;
				Byte data[3] = { item.status, item.data1, item.data2 };
				if ((pkt = MIDIPacketListAdd (pktlist, sizeof (mBuffersAllocated), pkt, item.startFrame, 4, const_cast<Byte*>(data))) == NULL)
					tooBig = true;

				if (tooBig)
				{	// send what we have and then clear the buffer and send again
					// issue the callback with what we got
					OSStatus result = mMIDICallbackStruct.midiOutputCallback (mMIDICallbackStruct.userData, &inTimeStamp, 0, pktlist);
					if (result != noErr)
						printf ("error calling output callback: %d", (int) result);

					// clear stuff we've already processed, and fire again
					mMIDIMessageList.erase (mMIDIMessageList.begin (), myIterator);
					this->FireAtTimeStamp (inTimeStamp);
					return;
				}
			}
			// fire callback
			OSStatus result = mMIDICallbackStruct.midiOutputCallback (mMIDICallbackStruct.userData, &inTimeStamp, 0, pktlist);
			if (result != noErr)
				printf ("error calling output callback: %d", (int) result);

			mMIDIMessageList.clear ();
		}
	}

protected:
	typedef std::vector<MIDIMessageInfoStruct> MIDIMessageList;

private:
	MIDIPacketList* PacketList () {return (MIDIPacketList*)mBuffersAllocated;}

	Byte mBuffersAllocated[1024];
	AUMIDIOutputCallbackStruct mMIDICallbackStruct;
	MIDIMessageList	mMIDIMessageList;
};

//------------------------------------------------------------------------
//------------------------------------------------------------------------
class AUWrapper
: public AUWRAPPER_BASE_CLASS
, public IComponentHandler
, public ITimerCallback
{
public:
	AUWrapper (ComponentInstanceRecord* ci);
	~AUWrapper ();

	//---ComponentBase---------------------
	ComponentResult	Version () SMTG_OVERRIDE;
	void PostConstructor () SMTG_OVERRIDE;

	//---AUBase-----------------------------
	void Cleanup () SMTG_OVERRIDE;
	ComponentResult Initialize () SMTG_OVERRIDE;
	AUElement* CreateElement (AudioUnitScope scope, AudioUnitElement element) SMTG_OVERRIDE;
	UInt32 SupportedNumChannels (const AUChannelInfo** outInfo) SMTG_OVERRIDE;
	bool StreamFormatWritable (AudioUnitScope scope, AudioUnitElement element) SMTG_OVERRIDE;
	ComponentResult ChangeStreamFormat (AudioUnitScope inScope, AudioUnitElement inElement, const CAStreamBasicDescription& inPrevFormat, const CAStreamBasicDescription& inNewFormat) SMTG_OVERRIDE;
	ComponentResult SetConnection (const AudioUnitConnection& inConnection) SMTG_OVERRIDE;
	ComponentResult GetParameterInfo (AudioUnitScope inScope, AudioUnitParameterID inParameterID, AudioUnitParameterInfo& outParameterInfo) SMTG_OVERRIDE;
	ComponentResult SetParameter (AudioUnitParameterID inID, AudioUnitScope inScope, AudioUnitElement inElement, AudioUnitParameterValue inValue, UInt32 inBufferOffsetInFrames) SMTG_OVERRIDE;

	ComponentResult SaveState (CFPropertyListRef* outData) SMTG_OVERRIDE;
	ComponentResult RestoreState (CFPropertyListRef inData) SMTG_OVERRIDE;

	ComponentResult Render (AudioUnitRenderActionFlags &ioActionFlags, const AudioTimeStamp &inTimeStamp, UInt32 inNumberFrames) SMTG_OVERRIDE;
	void processOutputEvents (const AudioTimeStamp &inTimeStamp);

	int GetNumCustomUIComponents () SMTG_OVERRIDE;
	void GetUIComponentDescs (ComponentDescription* inDescArray) SMTG_OVERRIDE;

	ComponentResult GetPropertyInfo (AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, UInt32 &outDataSize, Boolean &outWritable) SMTG_OVERRIDE;
	ComponentResult GetProperty (AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, void* outData) SMTG_OVERRIDE;
	ComponentResult SetProperty (AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, const void* inData, UInt32 inDataSize) SMTG_OVERRIDE;
	bool CanScheduleParameters() const; // Not in the base class anymore in newer CoreAudio SDKs

	Float64 GetLatency () SMTG_OVERRIDE;
	Float64 GetTailTime () SMTG_OVERRIDE;

	//---Factory presets
	OSStatus GetPresets (CFArrayRef* outData) const SMTG_OVERRIDE;
	OSStatus NewFactoryPresetSet (const AUPreset& inNewFactoryPreset) SMTG_OVERRIDE;

	//---MusicDeviceBase-------------------------
	ComponentResult StartNote (MusicDeviceInstrumentID inInstrument, MusicDeviceGroupID inGroupID, NoteInstanceID* outNoteInstanceID, UInt32 inOffsetSampleFrame, const MusicDeviceNoteParams &inParams) SMTG_OVERRIDE;
	ComponentResult StopNote (MusicDeviceGroupID inGroupID, NoteInstanceID inNoteInstanceID, UInt32 inOffsetSampleFrame) SMTG_OVERRIDE;
	OSStatus GetInstrumentCount (UInt32 &outInstCount) const SMTG_OVERRIDE;

	//---AUMIDIBase------------------------------
	OSStatus HandleNonNoteEvent (UInt8 status, UInt8 channel, UInt8	data1, UInt8 data2, UInt32 inStartFrame) SMTG_OVERRIDE;

	//---custom----------------------------------
	void setControllerParameter (ParamID pid, ParamValue value);

	// return for a given midiChannel the unitID and the ProgramListID
	bool getProgramListAndUnit (int32 midiChannel, UnitID& unitId, ProgramListID& programListId);

	// restore preset state, add StateType "Project" to stream if loading from project
	ComponentResult restoreState (CFPropertyListRef inData, bool fromProject);

	//------------------------------------------------------------------------
#if !CA_USE_AUDIO_PLUGIN_ONLY
	static ComponentResult ComponentEntryDispatch (ComponentParameters* params, AUWrapper* This);
#endif
	//------------------------------------------------------------------------
	static CFBundleRef gBundleRef;
	//------------------------------------------------------------------------
	DECLARE_FUNKNOWN_METHODS

protected:
	//---from IComponentHandler-------------------
	tresult PLUGIN_API beginEdit (ParamID tag) SMTG_OVERRIDE;
	tresult PLUGIN_API performEdit (ParamID tag, ParamValue valueNormalized) SMTG_OVERRIDE;
	tresult PLUGIN_API endEdit (ParamID tag) SMTG_OVERRIDE;
	tresult PLUGIN_API restartComponent (int32 flags) SMTG_OVERRIDE;

	//---from ITimerCallback----------------------
	void onTimer (Timer* timer) SMTG_OVERRIDE;

	// internal helpers
	double getSampleRate () const { return sampleRate; }
	void updateProcessContext ();
	void syncParameterValues ();
	void cacheParameterValues ();
	void clearParameterValueCache ();

	virtual IPluginFactory* getFactory ();
	void loadVST3Module ();
	void unloadVST3Module ();
	bool validateChannelPair (int inChannelsIn, int inChannelsOut, const AUChannelInfo* info, UInt32 numChanInfo) const;

	IAudioProcessor* audioProcessor;
	IEditController* editController;
	IMidiMapping* midiMapping;

	Timer* timer;

	HostProcessData processData;
	ParameterChanges processParamChanges;
	ParameterChanges outputParamChanges;
	ParameterChangeTransfer transferParamChanges;
	ParameterChangeTransfer outputParamTransfer;
	ProcessContext processContext;
	EventList eventList;

	typedef std::map<uint32, AudioUnitParameterInfo> CachedParameterInfoMap;
	typedef std::map<UnitID, UnitInfo> UnitInfoMap;
	typedef std::vector<String> ClumpGroupVector;

	UnitInfoMap unitInfos;
	ClumpGroupVector clumpGroups;
	CachedParameterInfoMap cachedParameterInfos;
	FLock parameterCacheChanging;

	NoteInstanceID noteCounter;
	double sampleRate;
	ParamID bypassParamID;

	AUPreset* presets;
	int32 numPresets;
	ParamID factoryProgramChangedID;

	bool isInstrument;
	bool isBypassed;

	AUParameterListenerRef paramListenerRef;
	static const int32 kMaxProgramChangeParameters = 16;
	ParamID programChangeParameters[kMaxProgramChangeParameters]; // for each midi channel

	int32 midiOutCount; // currently only 0 or 1 supported
	MIDIOutputCallbackHelper mCallbackHelper;
	EventList outputEvents;
private:
	void buildUnitInfos (IUnitInfo* unitInfoController, UnitInfoMap& units) const;
};

//------------------------------------------------------------------------
class AutoreleasePool
{
public:
	AutoreleasePool () { ap = [[NSAutoreleasePool alloc] init]; }
	~AutoreleasePool () { [ap drain]; }
//------------------------------------------------------------------------
protected:
	NSAutoreleasePool* ap;
};

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

/// \endcond


text:
//------------------------------------------------------------------------
// Project     : VST SDK
//
// Category    : Helpers
// Filename    : public.sdk/source/vst/auwrapper/ausdk.mm
// Created by  : Steinberg, 12/2007
// Description : VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

/// \cond ignore

#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

#ifndef MAC_OS_X_VERSION_10_7
	#define MAC_OS_X_VERSION_10_7 1070
#endif

#import "PublicUtility/CAAudioChannelLayout.cpp"
#import "PublicUtility/CABundleLocker.cpp"
#import "PublicUtility/CAHostTimeBase.cpp"
#import "PublicUtility/CAStreamBasicDescription.cpp"
#import "PublicUtility/CAVectorUnit.cpp"
#import "PublicUtility/CAAUParameter.cpp"

#import "AUPublic/AUBase/ComponentBase.cpp"
#import "AUPublic/AUBase/AUScopeElement.cpp"
#import "AUPublic/AUBase/AUOutputElement.cpp"
#import "AUPublic/AUBase/AUInputElement.cpp"
#import "AUPublic/AUBase/AUBase.cpp"

#if !__LP64__
	#import "AUPublic/AUCarbonViewBase/AUCarbonViewBase.cpp"
	#import "AUPublic/AUCarbonViewBase/AUCarbonViewControl.cpp"
	#import "AUPublic/AUCarbonViewBase/AUCarbonViewDispatch.cpp"
	#import "AUPublic/AUCarbonViewBase/AUControlGroup.cpp"
	#import "AUPublic/AUCarbonViewBase/CarbonEventHandler.cpp"
#endif

#import "AUPublic/Utility/AUTimestampGenerator.cpp"
#import "AUPublic/Utility/AUBuffer.cpp"
#import "AUPublic/Utility/AUBaseHelper.cpp"

#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
	#import "AUPublic/OtherBases/AUMIDIEffectBase.cpp"
	#import "AUPublic/Utility/AUDebugDispatcher.cpp"
#else
	#import "AUPublic/AUBase/AUPlugInDispatch.cpp"
#endif

#if !CA_USE_AUDIO_PLUGIN_ONLY
	#import "AUPublic/AUBase/AUDispatch.cpp"
	#import "AUPublic/OtherBases/MusicDeviceBase.cpp"
	#import "AUPublic/OtherBases/AUMIDIBase.cpp"
	#import "AUPublic/OtherBases/AUEffectBase.cpp"
#endif

/// \endcond


text:
//------------------------------------------------------------------------
// Project     : VST SDK
//
// Category    : Helpers
// Filename    : public.sdk/source/vst/auwrapper/NSDataIBStream.h
// Created by  : Steinberg, 12/2007
// Description : VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

/// \cond ignore

#pragma once

#import <Foundation/Foundation.h>
#import "pluginterfaces/base/ibstream.h"
#import "public.sdk/source/vst/hosting/hostclasses.h"

//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {

//------------------------------------------------------------------------
class NSDataIBStream : public IBStream, Vst::IStreamAttributes
{
public:
	NSDataIBStream (NSData* data, bool hideAttributes = false);
	virtual ~NSDataIBStream ();

	//---from IBStream-------------------
	tresult PLUGIN_API read  (void* buffer, int32 numBytes, int32* numBytesRead = 0) SMTG_OVERRIDE;
	tresult PLUGIN_API write (void* buffer, int32 numBytes, int32* numBytesWritten = 0) SMTG_OVERRIDE;
	tresult PLUGIN_API seek  (int64 pos, int32 mode, int64* result = 0) SMTG_OVERRIDE;
	tresult PLUGIN_API tell  (int64* pos) SMTG_OVERRIDE;

	//---from Vst::IStreamAttributes-----
	virtual tresult PLUGIN_API getFileName (String128 name) SMTG_OVERRIDE;
	virtual IAttributeList* PLUGIN_API getAttributes () SMTG_OVERRIDE;

	//------------------------------------------------------------------------
	DECLARE_FUNKNOWN_METHODS
protected:
	NSData* data;
	int64 currentPos;
	HostAttributeList attrList;
	bool hideAttributes;
};

//------------------------------------------------------------------------
class NSMutableDataIBStream : public NSDataIBStream
{
public:
	NSMutableDataIBStream (NSMutableData* data);
	virtual ~NSMutableDataIBStream ();

	tresult PLUGIN_API write (void* buffer, int32 numBytes, int32* numBytesWritten = 0);
//------------------------------------------------------------------------
protected:
	NSMutableData* mdata;
};

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

/// \endcond


text:
//------------------------------------------------------------------------
// Project     : VST SDK
//
// Category    : Helpers
// Filename    : public.sdk/source/vst/auwrapper/aucarbonview.h
// Created by  : Steinberg, 12/2007
// Description : VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

/// \cond ignore

#pragma once

#if !__LP64__

#include "AUPublic/AUCarbonViewBase/AUCarbonViewBase.h"
#include "pluginterfaces/vst/ivsteditcontroller.h"
#include "base/source/fobject.h"
#include "pluginterfaces/gui/iplugview.h"

namespace Steinberg {
namespace Vst {
class AUCarbonPlugFrame;

//------------------------------------------------------------------------
class AUCarbonView : public AUCarbonViewBase, public IPlugFrame, public FObject
{
public:
	AUCarbonView (AudioUnitCarbonView auv);
	~AUCarbonView ();

	OSStatus CreateUI (Float32 xoffset, Float32 yoffset);

	OBJ_METHODS(AUCarbonView, FObject)
	DEF_INTERFACES_1(IPlugFrame, FObject)
	REFCOUNT_METHODS(FObject)

protected:
	tresult PLUGIN_API resizeView (IPlugView* view, ViewRect* vr);

	static OSStatus HIViewAdded (EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void* inUserData);

	IEditController* editController;
	AUCarbonPlugFrame* plugFrame;
	IPlugView* plugView;
	HIViewRef hiPlugView;
	EventHandlerRef eventHandler;
};

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

#endif // !__LP64__

/// \endcond


text:
//------------------------------------------------------------------------
// Project     : VST SDK
//
// Category    : Helpers
// Filename    : public.sdk/source/vst/auwrapper/aucocoaview.mm
// Created by  : Steinberg, 12/2007
// Description : VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

/// \cond ignore

#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

#import "aucocoaview.h"
#import "auwrapper.h"
#import "pluginterfaces/vst/ivsteditcontroller.h"
#import "pluginterfaces/gui/iplugview.h"
#import "base/source/fobject.h"

namespace Steinberg {
DEF_CLASS_IID(IPlugFrame)

//------------------------------------------------------------------------
class AUPlugFrame : public FObject, public IPlugFrame
//------------------------------------------------------------------------
{
public:
	AUPlugFrame (NSView* parent) : parent (parent) {}
	tresult PLUGIN_API resizeView (IPlugView* view, ViewRect* vr) SMTG_OVERRIDE
	{
		NSRect newSize = NSMakeRect ([parent frame].origin.x, [parent frame].origin.y, vr->right - vr->left, vr->bottom - vr->top);
		[parent setFrame:newSize];
		return kResultTrue;
	}

	OBJ_METHODS(AUPlugFrame, FObject)
	DEF_INTERFACES_1(IPlugFrame, FObject)
	REFCOUNT_METHODS(FObject)
protected:
	NSView* parent;
};

} // namespace Steinberg

using namespace Steinberg;

//------------------------------------------------------------------------
@interface SMTGCocoa_NSViewWrapperForAU : NSView {
//------------------------------------------------------------------------
	IPlugView* plugView;
	Vst::IEditController* editController;
	AudioUnit audioUnit;
	FObject* dynlib;
	AUPlugFrame* plugFrame;

	BOOL isAttached;
}

- (id) initWithEditController: (Vst::IEditController*) editController audioUnit: (AudioUnit) au preferredSize: (NSSize) size;

@end

//------------------------------------------------------------------------
// SMTG_AU_PLUGIN_NAMESPACE (SMTGAUPluginCocoaView)
//------------------------------------------------------------------------

//------------------------------------------------------------------------
@implementation SMTG_AU_PLUGIN_NAMESPACE (SMTGAUPluginCocoaView)

//------------------------------------------------------------------------
- (unsigned) interfaceVersion
{
    return 0;
}

//------------------------------------------------------------------------
- (NSString *) description
{
    return @"Cocoa View";
}

//------------------------------------------------------------------------
- (NSView *)uiViewForAudioUnit:(AudioUnit)inAU withSize:(NSSize)inPreferredSize
{
    Vst::IEditController* editController = 0;
    UInt32 size = sizeof (Vst::IEditController*);
    if (AudioUnitGetProperty (inAU, 64000, kAudioUnitScope_Global, 0, &editController, &size) != noErr)
        return nil;
    return [[[SMTGCocoa_NSViewWrapperForAU alloc] initWithEditController:editController audioUnit:inAU preferredSize:inPreferredSize] autorelease];
}

@end

//------------------------------------------------------------------------
@implementation SMTGCocoa_NSViewWrapperForAU
//------------------------------------------------------------------------
- (id) initWithEditController: (Vst::IEditController*) _editController audioUnit: (AudioUnit) au preferredSize: (NSSize) size
{
	self = [super initWithFrame: NSMakeRect (0, 0, size.width, size.height)];
	if (self)
	{
		editController = _editController;
		editController->addRef ();
		audioUnit = au;
		plugView = editController->createView (Vst::ViewType::kEditor);
		if (!plugView || plugView->isPlatformTypeSupported (kPlatformTypeNSView) != kResultTrue)
		{
			[self dealloc];
			return nil;
		}

		plugFrame = NEW AUPlugFrame (self);
		plugView->setFrame (plugFrame);

		if (plugView->attached (self, kPlatformTypeNSView) != kResultTrue)
		{
			[self dealloc];
			return nil;
		}
		ViewRect vr;
		if (plugView->getSize (&vr) == kResultTrue)
		{
			NSRect newSize = NSMakeRect (0, 0, vr.right - vr.left, vr.bottom - vr.top);
			[self setFrame:newSize];
		}

		isAttached = YES;
		UInt32 size = sizeof (FObject*);
		if (AudioUnitGetProperty (audioUnit, 64001, kAudioUnitScope_Global, 0, &dynlib, &size) == noErr)
			dynlib->addRef ();
	}
	return self;
}

//------------------------------------------------------------------------
- (void) setFrame: (NSRect) newSize
{
	[super setFrame: newSize];
	ViewRect viewRect (0, 0, newSize.size.width, newSize.size.height);

	if (plugView)
		plugView->onSize (&viewRect);
}

//------------------------------------------------------------------------
- (BOOL)isFlipped { return YES; }

//------------------------------------------------------------------------
- (void)viewDidMoveToSuperview
{
	if (plugView)
	{
		if ([self superview])
		{
			if (!isAttached)
			{
				isAttached = plugView->attached (self, kPlatformTypeNSView) == kResultTrue;
			}
		}
		else
		{
			if (isAttached)
			{
				plugView->removed ();
				isAttached = NO;
			}
		}
	}
}

//------------------------------------------------------------------------
- (void) dealloc
{
	if (plugView)
	{
		if (isAttached)
		{
			plugView->setFrame (0);
			plugView->removed ();
		}
		plugView->release ();
		if (plugFrame)
			plugFrame->release ();

		if (editController)
		{
			Steinberg::uint32 refCount= editController->addRef ();
			if (refCount == 2)
				editController->terminate ();

			editController->release ();
			editController->release ();
			editController = 0;
		}
	}
	if (dynlib)
		dynlib->release ();
	[super dealloc];
}

@end

/// \endcond


text:
//------------------------------------------------------------------------
// Project     : VST SDK
//
// Category    : Helpers
// Filename    : public.sdk/source/vst/auwrapper/auresource.r
// Created by  : Steinberg, 12/2007
// Description : VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include <AudioUnit/AudioUnit.r>
#include <AudioUnit/AudioUnitCarbonView.r>

#include "audiounitconfig.h"
/*	----------------------------------------------------------------------------------------------------------------------------------------
//	audiounitconfig.h needs the following definitions:
	#define kAudioUnitVersion			0xFFFFFFFF							// Version Number, needs to be in hex
	#define kAudioUnitName				"Steinberg: MyVST3 as AudioUnit"	// Company Name + Effect Name
	#define kAudioUnitDescription		"My VST3 as AudioUnit"				// Effect Description
	#define kAudioUnitType				kAudioUnitType_Effect				// can be kAudioUnitType_Effect or kAudioUnitType_MusicDevice
	#define kAudioUnitComponentSubType	'test'								// unique id
	#define kAudioUnitComponentManuf	'SMTG'								// registered company id
	#define kAudioUnitCarbonView		1									// if 0 no Carbon view support will be added
*/

#define kAudioUnitResID_Processor				1000
#define kAudioUnitResID_CarbonView				9000

//----------------------Processor----------------------------------------------

#define RES_ID			kAudioUnitResID_Processor
#define COMP_TYPE		kAudioUnitType
#define COMP_SUBTYPE	kAudioUnitComponentSubType
#define COMP_MANUF		kAudioUnitComponentManuf

#define VERSION			kAudioUnitVersion
#define NAME			kAudioUnitName
#define DESCRIPTION		kAudioUnitDescription
#define ENTRY_POINT		"AUWrapperEntry"

#include "AUResources.r"

#if kAudioUnitCarbonView
//----------------------View----------------------------------------------

#define RES_ID			kAudioUnitResID_CarbonView
#define COMP_TYPE		kAudioUnitCarbonViewComponentType
#define COMP_SUBTYPE	kAudioUnitComponentSubType
#define COMP_MANUF		kAudioUnitComponentManuf

#define VERSION			kAudioUnitVersion
#define NAME			"CarbonView"
#define DESCRIPTION		"CarbonView"
#define ENTRY_POINT		"AUCarbonViewEntry"

#include "AUResources.r"

#endif


text:
//------------------------------------------------------------------------
// Project     : VST SDK
//
// Category    : Helpers
// Filename    : public.sdk/source/vst/auwrapper/aucocoaview.h
// Created by  : Steinberg, 12/2007
// Description : VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

/// \cond ignore

#pragma once

#import "aucocoaclassprefix.h"

#import <Cocoa/Cocoa.h>
#import <AudioUnit/AUCocoaUIView.h>

#ifndef SMTG_AU_NAMESPACE
# error define SMTG_AU_NAMESPACE
#endif

//-----------------------------------------------------------------------------
#define SMTG_AU_PLUGIN_NAMESPACE0(x) x
#define SMTG_AU_PLUGIN_NAMESPACE1(a, b) a##_##b
#define SMTG_AU_PLUGIN_NAMESPACE2(a, b) SMTG_AU_PLUGIN_NAMESPACE1(a,b)
#define SMTG_AU_PLUGIN_NAMESPACE(name) SMTG_AU_PLUGIN_NAMESPACE2(SMTG_AU_PLUGIN_NAMESPACE0(name), SMTG_AU_PLUGIN_NAMESPACE0(SMTG_AU_NAMESPACE))

//-----------------------------------------------------------------------------
// SMTG_AU_PLUGIN_NAMESPACE (SMTGAUPluginCocoaView)
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
@interface SMTG_AU_PLUGIN_NAMESPACE (SMTGAUPluginCocoaView) : NSObject <AUCocoaUIBase>
{
}

//-----------------------------------------------------------------------------
@end

/// \endcond


text:
//------------------------------------------------------------------------
// Project     : VST SDK
//
// Category    : Helpers
// Filename    : public.sdk/source/vst/auwrapper/NSDataIBStream.mm
// Created by  : Steinberg, 12/2007
// Description : VST 3 -> AU Wrapper
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

/// \cond ignore

#include "NSDataIBStream.h"

#include "pluginterfaces/vst/ivstattributes.h"

#include <algorithm>

#if __clang__
#if __has_feature(objc_arc) && __clang_major__ >= 3
#define ARC_ENABLED 1
#endif // __has_feature(objc_arc)
#endif // __clang__

namespace Steinberg {
namespace Vst {

DEF_CLASS_IID(IStreamAttributes);

//------------------------------------------------------------------------
NSDataIBStream::NSDataIBStream (NSData* data, bool hideAttributes)
: data (data)
, currentPos (0)
, hideAttributes (hideAttributes)
{
	FUNKNOWN_CTOR
#if !ARC_ENABLED
	[data retain];
#endif
}

//------------------------------------------------------------------------
NSDataIBStream::~NSDataIBStream ()
{
#if !ARC_ENABLED
	[data release];
#endif
	FUNKNOWN_DTOR
}

//------------------------------------------------------------------------
IMPLEMENT_REFCOUNT (NSDataIBStream)

//------------------------------------------------------------------------
tresult PLUGIN_API NSDataIBStream::queryInterface (const TUID iid, void** obj)
{
	QUERY_INTERFACE (iid, obj, FUnknown::iid, IBStream)
	QUERY_INTERFACE (iid, obj, IBStream::iid, IBStream)
	if (!hideAttributes)
		QUERY_INTERFACE (iid, obj, IStreamAttributes::iid, IStreamAttributes)
	*obj = 0;
	return kNoInterface;
}

//------------------------------------------------------------------------
tresult PLUGIN_API NSDataIBStream::read (void* buffer, int32 numBytes, int32* numBytesRead)
{
	int32 useBytes = std::min (numBytes, (int32)([data length] - currentPos));
	if (useBytes > 0)
	{
		[data getBytes: buffer range: NSMakeRange (currentPos, useBytes)];
		if (numBytesRead)
			*numBytesRead = useBytes;
		currentPos += useBytes;
		return kResultTrue;
	}
	return kResultFalse;
}

//------------------------------------------------------------------------
tresult PLUGIN_API NSDataIBStream::write (void* buffer, int32 numBytes, int32* numBytesWritten)
{
	return kResultFalse;
}

//------------------------------------------------------------------------
tresult PLUGIN_API NSDataIBStream::seek (int64 pos, int32 mode, int64* result)
{
	switch (mode)
	{
		case kIBSeekSet:
		{
			if (pos <= [data length])
			{
				currentPos = pos;
				if (result)
					tell (result);
				return kResultTrue;
			}
			break;
		}
		case kIBSeekCur:
		{
			if (currentPos + pos <= [data length])
			{
				currentPos += pos;
				if (result)
					tell (result);
				return kResultTrue;
			}
			break;
		}
		case kIBSeekEnd:
		{
			if ([data length] + pos <= [data length])
			{
				currentPos = [data length] + pos;
				if (result)
					tell (result);
				return kResultTrue;
			}
			break;
		}
	}
	return kResultFalse;
}

//------------------------------------------------------------------------
tresult PLUGIN_API NSDataIBStream::tell (int64* pos)
{
	if (pos)
	{
		*pos = currentPos;
		return kResultTrue;
	}
	return kResultFalse;
}

//------------------------------------------------------------------------
tresult PLUGIN_API NSDataIBStream::getFileName (String128 name)
{
	return kNotImplemented;
}

//------------------------------------------------------------------------
IAttributeList* PLUGIN_API NSDataIBStream::getAttributes ()
{
	return hideAttributes ? 0 : &attrList;
}

//------------------------------------------------------------------------
//------------------------------------------------------------------------
//------------------------------------------------------------------------
NSMutableDataIBStream::NSMutableDataIBStream (NSMutableData* data)
: NSDataIBStream (data, true)
, mdata (data)
{
}

//------------------------------------------------------------------------
NSMutableDataIBStream::~NSMutableDataIBStream ()
{
	[mdata setLength:currentPos];
}

//------------------------------------------------------------------------
tresult PLUGIN_API NSMutableDataIBStream::write (void* buffer, int32 numBytes, int32* numBytesWritten)
{
	[mdata replaceBytesInRange:NSMakeRange (currentPos, numBytes) withBytes:buffer];
	if (numBytesWritten)
		*numBytesWritten = numBytes;
	currentPos += numBytes;
	return kResultTrue;
}

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

/// \endcond