static OSStatus AUMethodGetProperty()

in Source/AUPlugInDispatch.cpp [116:174]


static OSStatus AUMethodGetProperty(void* self, AudioUnitPropertyID inID, AudioUnitScope inScope,
	AudioUnitElement inElement, void* outData, UInt32* ioDataSize)
{
	OSStatus result = noErr;
	try {
		bool writable = false;

		const AUInstanceGuard guard(self);
		if (ioDataSize == nullptr) {
			AUSDK_LogError("AudioUnitGetProperty: null size pointer");
			return kAudio_ParamError;
		}
		if (outData == nullptr) {
			UInt32 dataSize = 0;

			result = AUInstance(self)->DispatchGetPropertyInfo(
				inID, inScope, inElement, dataSize, writable);
			*ioDataSize = dataSize;
			return result;
		}

		const auto clientBufferSize = *ioDataSize;
		if (clientBufferSize == 0) {
			AUSDK_LogError("AudioUnitGetProperty: *ioDataSize == 0 on entry");
			return kAudio_ParamError;
		}

		UInt32 actualPropertySize = 0;
		result = AUInstance(self)->DispatchGetPropertyInfo(
			inID, inScope, inElement, actualPropertySize, writable);
		if (result != noErr) {
			return result;
		}

		std::vector<std::byte> tempBuffer;
		void* destBuffer = nullptr;
		if (clientBufferSize < actualPropertySize) {
			tempBuffer.resize(actualPropertySize);
			destBuffer = tempBuffer.data();
		} else {
			destBuffer = outData;
		}

		result = AUInstance(self)->DispatchGetProperty(inID, inScope, inElement, destBuffer);

		if (result == noErr) {
			if (clientBufferSize < actualPropertySize && !tempBuffer.empty()) {
				memcpy(outData, tempBuffer.data(), clientBufferSize);
				// ioDataSize remains correct, the number of bytes we wrote
			} else {
				*ioDataSize = actualPropertySize;
			}
		} else {
			*ioDataSize = 0;
		}
	}
	AUSDK_Catch(result)
	return result;
}