/*=============================================================================
	CACFDictionary.cpp
	CAAudioEngine

	$Log: CACFDictionary.cpp,v $
	Revision 1.14  2004/09/14 19:53:58  jcm10
	add GetBool()
	
	Revision 1.13  2003/10/29 01:53:48  bills
	a couple of new methods
	
	Revision 1.12  2003/10/02 00:45:54  bills
	GetData
	
	Revision 1.11  2003/07/16 00:59:49  bills
	HasKey is const
	
	Revision 1.10  2003/05/22 19:07:18  jcm10
	rework this class to prevent polymorphic problems with CFTypes
	
	Revision 1.9  2003/05/04 00:00:54  jcm10
	add getters for CFArrays and CFDictionaries
	
	Revision 1.8  2003/04/27 02:32:58  bills
	add Float32 support
	
	Revision 1.7  2003/04/02 18:20:02  bills
	changes to make persistence work
	
	Revision 1.6  2003/03/25 18:59:09  bills
	get should really get:)
	
	Revision 1.5  2003/03/23 02:53:12  bills
	some rewrite and add methods
	
	Revision 1.4  2003/03/21 06:53:36  bills
	prelim impl of CA-AU persistence
	
	Revision 1.3  2003/03/17 02:55:52  bills
	couple of other API
	
	Revision 1.2  2003/03/12 05:05:05  bills
	refactor persistence
	

	Created by William Stewart on Mon Mar 10 2003.
	Copyright (c) 2003 Apple Computer. All rights reserved.

=============================================================================*/

//=============================================================================
//	Includes
//=============================================================================

//	Self Include
#include "CACFDictionary.h"

//	PublicUtility Includes
#include "CACFString.h"
#include "CACFNumber.h"

//=============================================================================
//	CACFDictionary
//=============================================================================

bool	CACFDictionary::HasKey(const CFStringRef inKey) const
{
	return CFDictionaryContainsKey(mCFDictionary, inKey) != 0;
}

UInt32	CACFDictionary::Size () const
{
	return CFDictionaryGetCount(mCFDictionary);
}

void	CACFDictionary::GetKeys (const void **keys) const
{
	CFDictionaryGetKeysAndValues(mCFDictionary, keys, NULL);
}

bool	CACFDictionary::GetBool(const CFStringRef inKey, bool& outValue) const
{
	bool theAnswer = false;
	
	CFTypeRef theValue = NULL;
	if(GetCFType(inKey, theValue))
	{
		if((theValue != NULL) && (CFGetTypeID(theValue) == CFBooleanGetTypeID()))
		{
			outValue = CFBooleanGetValue(static_cast<CFBooleanRef>(theValue));
			theAnswer = true;
		}
		else if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
		{
			SInt32 theNumericValue = 0;
			CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &theNumericValue);
			outValue = theNumericValue != 0;
			theAnswer = true;
		}
	}
	
	return theAnswer;
}

bool	CACFDictionary::GetSInt32(const CFStringRef inKey, SInt32& outValue) const
{
	bool theAnswer = false;
	
	CFTypeRef theValue = NULL;
	if(GetCFType(inKey, theValue))
	{
		if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
		{
			CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &outValue);
			theAnswer = true;
		}
	}
	
	return theAnswer;
}

bool	CACFDictionary::GetUInt32(const CFStringRef inKey, UInt32& outValue) const
{
	bool theAnswer = false;
	
	CFTypeRef theValue = NULL;
	if(GetCFType(inKey, theValue))
	{
		if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
		{
			CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &outValue);
			theAnswer = true;
		}
	}
	
	return theAnswer;
}

bool	CACFDictionary::GetSInt64(const CFStringRef inKey, SInt64& outValue) const
{
	bool theAnswer = false;
	
	CFTypeRef theValue = NULL;
	if(GetCFType(inKey, theValue))
	{
		if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
		{
			CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt64Type, &outValue);
			theAnswer = true;
		}
	}
	
	return theAnswer;
}

bool	CACFDictionary::GetUInt64(const CFStringRef inKey, UInt64& outValue) const
{
	bool theAnswer = false;
	
	CFTypeRef theValue = NULL;
	if(GetCFType(inKey, theValue))
	{
		if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
		{
			CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt64Type, &outValue);
			theAnswer = true;
		}
	}
	
	return theAnswer;
}

bool	CACFDictionary::GetFloat32(const CFStringRef inKey, Float32& outValue) const
{
	bool theAnswer = false;
	
	CFTypeRef theValue = NULL;
	if(GetCFType(inKey, theValue))
	{
		if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
		{
			CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberFloat32Type, &outValue);
			theAnswer = true;
		}
	}
	
	return theAnswer;
}

bool	CACFDictionary::GetFloat64(const CFStringRef inKey, Float64& outValue) const
{
	bool theAnswer = false;
	
	CFTypeRef theValue = NULL;
	if(GetCFType(inKey, theValue))
	{
		if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
		{
			CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberFloat64Type, &outValue);
			theAnswer = true;
		}
	}
	
	return theAnswer;
}

bool	CACFDictionary::GetString(const CFStringRef inKey, CFStringRef& outValue) const
{
	bool theAnswer = false;
	
	CFTypeRef theValue = NULL;
	if(GetCFType(inKey, theValue))
	{
		if((theValue != NULL) && (CFGetTypeID(theValue) == CFStringGetTypeID()))
		{
			outValue = static_cast<CFStringRef>(theValue);
			theAnswer = true;
		}
	}
	
	return theAnswer;
}
	
bool	CACFDictionary::GetArray(const CFStringRef inKey, CFArrayRef& outValue) const
{
	bool theAnswer = false;
	
	CFTypeRef theValue = NULL;
	if(GetCFType(inKey, theValue))
	{
		if((theValue != NULL) && (CFGetTypeID(theValue) == CFArrayGetTypeID()))
		{
			outValue = static_cast<CFArrayRef>(theValue);
			theAnswer = true;
		}
	}
	
	return theAnswer;
}
	
bool	CACFDictionary::GetDictionary(const CFStringRef inKey, CFDictionaryRef& outValue) const
{
	bool theAnswer = false;
	
	CFTypeRef theValue = NULL;
	if(GetCFType(inKey, theValue))
	{
		if((theValue != NULL) && (CFGetTypeID(theValue) == CFDictionaryGetTypeID()))
		{
			outValue = static_cast<CFDictionaryRef>(theValue);
			theAnswer = true;
		}
	}
	
	return theAnswer;
}

bool	CACFDictionary::GetData(const CFStringRef inKey, CFDataRef& outValue) const
{
	bool theAnswer = false;
	
	CFTypeRef theValue = NULL;
	if(GetCFType(inKey, theValue))
	{
		if((theValue != NULL) && (CFGetTypeID(theValue) == CFDataGetTypeID()))
		{
			outValue = static_cast<CFDataRef>(theValue);
			theAnswer = true;
		}
	}
	
	return theAnswer;
}

bool	CACFDictionary::GetCFType(const CFStringRef inKey, CFTypeRef& outValue) const
{
	bool theAnswer = false;
	
	if(mCFDictionary != NULL)
	{
		outValue = CFDictionaryGetValue(mCFDictionary, inKey);
		theAnswer = (outValue != NULL);
	}
	
	return theAnswer;
}

bool	CACFDictionary::GetCFTypeWithCStringKey(const char* inKey, CFTypeRef& outValue) const
{
	bool theAnswer = false;
	
	if(mCFDictionary != NULL)
	{
		CACFString theKey(inKey);
		if(theKey.IsValid())
		{
			theAnswer = GetCFType(theKey.GetCFString(), outValue);
		}
	}
	
	return theAnswer;
}

bool	CACFDictionary::AddSInt32(const CFStringRef inKey, SInt32 inValue)
{
	bool theAnswer = false;
	
	if(mMutable && (mCFDictionary != NULL))
	{
		CACFNumber theValue(inValue);
		theAnswer = AddCFType(inKey, theValue.GetCFNumber());
	}
	
	return theAnswer;
}

bool	CACFDictionary::AddUInt32(const CFStringRef inKey, UInt32 inValue)
{
	bool theAnswer = false;
	
	if(mMutable && (mCFDictionary != NULL))
	{
		CACFNumber theValue(inValue);
		theAnswer = AddCFType(inKey, theValue.GetCFNumber());
	}
	
	return theAnswer;
}

bool	CACFDictionary::AddSInt64(const CFStringRef inKey, SInt64 inValue)
{
	bool theAnswer = false;
	
	if(mMutable && (mCFDictionary != NULL))
	{
		CACFNumber theValue(inValue);
		theAnswer = AddCFType(inKey, theValue.GetCFNumber());
	}
	
	return theAnswer;
}

bool	CACFDictionary::AddUInt64(const CFStringRef inKey, UInt64 inValue)
{
	bool theAnswer = false;
	
	if(mMutable && (mCFDictionary != NULL))
	{
		CACFNumber theValue(inValue);
		theAnswer = AddCFType(inKey, theValue.GetCFNumber());
	}
	
	return theAnswer;
}

bool	CACFDictionary::AddFloat32(const CFStringRef inKey, Float32 inValue)
{
	bool theAnswer = false;
	
	if(mMutable && (mCFDictionary != NULL))
	{
		CACFNumber theValue(inValue);
		theAnswer = AddCFType(inKey, theValue.GetCFNumber());
	}
	
	return theAnswer;
}

bool	CACFDictionary::AddFloat64(const CFStringRef inKey, Float64 inValue)
{
	bool theAnswer = false;
	
	if(mMutable && (mCFDictionary != NULL))
	{
		CACFNumber theValue(inValue);
		theAnswer = AddCFType(inKey, theValue.GetCFNumber());
	}
	
	return theAnswer;
}

bool	CACFDictionary::AddNumber(const CFStringRef inKey, const CFNumberRef inValue)
{
	bool theAnswer = false;
	
	if(mMutable && (mCFDictionary != NULL))
	{
		theAnswer = AddCFType(inKey, inValue);
	}
	
	return theAnswer;
}

bool	CACFDictionary::AddString(const CFStringRef inKey, const CFStringRef inValue)
{
	bool theAnswer = false;
	
	if(mMutable && (mCFDictionary != NULL))
	{
		theAnswer = AddCFType(inKey, inValue);
	}
	
	return theAnswer;
}

bool	CACFDictionary::AddArray(const CFStringRef inKey, const CFArrayRef inValue)
{
	bool theAnswer = false;
	
	if(mMutable && (mCFDictionary != NULL))
	{
		theAnswer = AddCFType(inKey, inValue);
	}
	
	return theAnswer;
}

bool	CACFDictionary::AddDictionary(const CFStringRef inKey, const CFDictionaryRef inValue)
{
	bool theAnswer = false;
	
	if(mMutable && (mCFDictionary != NULL))
	{
		theAnswer = AddCFType(inKey, inValue);
	}
	
	return theAnswer;
}

bool	CACFDictionary::AddCFType(const CFStringRef inKey, const CFTypeRef inValue)
{
	bool theAnswer = false;
	
	if(mMutable && (mCFDictionary != NULL))
	{
		CFDictionarySetValue(mCFDictionary, inKey, inValue);
		theAnswer = true;
	}
	
	return theAnswer;
}

bool	CACFDictionary::AddCFTypeWithCStringKey(const char* inKey, const CFTypeRef inValue)
{
	bool theAnswer = false;
	
	if(mMutable && (mCFDictionary != NULL))
	{
		CACFString theKey(inKey);
		if(theKey.IsValid())
		{
			theAnswer = AddCFType(theKey.GetCFString(), inValue);
		}
	}
	
	return theAnswer;
}

bool	CACFDictionary::AddCString(const CFStringRef inKey, const char* inValue)
{
	bool theAnswer = false;
	
	if(mMutable && (mCFDictionary != NULL))
	{
		CACFString theValue(inValue);
		if(theValue.IsValid())
		{
			theAnswer = AddCFType(inKey, theValue.GetCFString());
		}
	}
	
	return theAnswer;
}
