CFLite/CFTest/CFTest.cpp

From kJams Wiki
Jump to navigation Jump to search
#include "SuperString.h"
#include <CoreFoundation/CFLocale.h>
#include <CoreFoundation/CFNumberFormatter.h>
#include <CoreFoundation/CFDateFormatter.h>
#include <CoreFoundation/CFCalendar.h>
#include <CoreFoundation/CFBundle.h>
#include "CFTest.h"

static void	ShowDiacriticSensitiveCompare(bool insensitiveB)
{
	SuperString		resultStr;

	g_pref_diacritic_insensitive_searchB = insensitiveB;
	
	CCFLog()(resultStr.ssprintf("diacritic %ssensitive\n", insensitiveB ? "in" : "").ref());
	
	SuperString			str1("NeUi");
	SuperString			str2("%C3%B1%C3%A9%C3%BC%C3%AE", kCFStringEncodingPercentEscapes);
	
	bool				diacritic_insensitive_compareB = str1 == str2;
	
	CCFLog()(resultStr.ssprintf("%s %s %s\n", 
		   str1.utf8Z(), 
		   diacritic_insensitive_compareB ? "==" : "!=", 
		   str2.utf8Z()).ref());
	
	if (insensitiveB) {
		CF_ASSERT(diacritic_insensitive_compareB);
	}
}

void	CFTest(const char *pathZ)
{
	SuperString		resultStr;
	
	SetDefaultEncoding(kCFStringEncodingASCII);
	
	//	test console logging and CFSTR macro
	{
		CCFLog()(CFSTR("------------------Strings---------------\n"));
		CCFLog()(CFSTR("Hello, World!\n"));
		ScCFReleaser<CFDataRef>		dataRef(SuperString("yeah baby").CopyDataRef());
		SuperString					str;
		
		str.Set(dataRef);
		CCFLog()(SuperString("The next line should read <yeah baby>\n").ref());
		CCFLog(true)(str.ref());
		
		SuperString		str1("foscoobyar");
		SuperString		str2("scooby");
		
		resultStr.ssprintf(
			"\n%s %s %s\n", 
			str1.utf8Z(), 
			str1.Contains(str2) ? "contains" : "$$$ Error: does not contain(!?)", 
			str2.utf8Z());
		
		CCFLog()(resultStr.ref());
		
		str1.Replace(str2, "o b");
		CCFLog()(SuperString("The next line should read <foo bar>\n").ref());
		CCFLog(true)(str1.ref());
		
		CCFLog()(CFSTR("------------------Case Insensitive Compare---------------\n"));
		ShowDiacriticSensitiveCompare(false);
		CCFLog()(CFSTR("\n"));
		ShowDiacriticSensitiveCompare(true);
		
		{
			CCFLog()(CFSTR("------------------Conversion---------------\n"));
			SuperString			jStr("%E3%82%91%E3%82%92%E3%81%BC%E3%81%BE%E3%81%82%E3%82%BA%E3%82%B8%E3%83%85%E3%83%9D", kCFStringEncodingPercentEscapes);
				
			#if defined(__WIN32__)
				#define		kConvertEncode		kCFStringEncodingDOSJapanese
			#else
				#define		kConvertEncode		kCFStringEncodingMacJapanese
			#endif
			
			ustring				j;
			CopyCFStringToUString(jStr.ref(), j, kConvertEncode);
			
			SuperString			convertedJ;  convertedJ.Set(j, kConvertEncode);
			
			CCFLog()(resultStr.ssprintf(
				"The next line should read <%s>\n%s\n", 
				jStr.utf8Z(), convertedJ.utf8Z()).ref());
			
			CCFLog()(resultStr.ssprintf("conversion: %s\n", convertedJ == jStr ? "Success!" : "$$ FAILED!").ref());
		}
	}
	
	{
		CCFLog()(CFSTR("------------------Encoding---------------\n"));
		CFStringEncoding		encoding = CFStringGetSystemEncoding();
		
		CCFLog()(resultStr.ssprintf("Encoding: %s\n", SuperString(CFStringGetNameOfEncoding(encoding)).utf8Z()).ref());
		CCFLog()(resultStr.ssprintf("IANA charset: %s\n", SuperString(CFStringConvertEncodingToIANACharSetName(encoding)).utf8Z()).ref());
		
		#if defined(__WIN32__)
			UInt32					codePage = CFStringConvertEncodingToWindowsCodepage(encoding);
			
			if (encoding == kCFStringEncodingWindowsLatin1) {
				CF_ASSERT(codePage == kCodePage_WindowsLatin1);
			}
			
			CCFLog()(resultStr.ssprintf("codepage: %ld\n", codePage).ref());
			CF_ASSERT(CFStringConvertWindowsCodepageToEncoding(codePage) == encoding);
		#endif		
	}
	
	CCFLog()(CFSTR("------------------Locale---------------\n"));
	ScCFReleaser<CFLocaleRef>				locale(CFLocaleCopyCurrent());
	
	{
		SuperString				localIdStr(CFLocaleGetIdentifier(locale));
		
		CCFLog()(resultStr.ssprintf("Locale ID: %s\n", localIdStr.utf8Z()).ref());
		
		ScCFReleaser<CFDictionaryRef>	dictRef(CFLocaleCreateComponentsFromLocaleIdentifier(
			kCFAllocatorDefault, localIdStr.ref()));
		
		dict_for_each(dictRef, CCFLog(true));
	}
	
	{
		CCFLog()(CFSTR("------------------Preferred Languages---------------\n"));
		ScCFReleaser<CFArrayRef>	arrayRef(CFLocaleCopyPreferredLanguages());
		
		array_for_each(arrayRef, CCFLog(true));
	}
	
	{
		CCFLog()(CFSTR("------------------Calendar---------------\n"));
		ScCFReleaser<CFCalendarRef>		calendarRef(CFCalendarCopyCurrent());
		
		CCFLog()(resultStr.ssprintf("Calendar ID: %s\n", SuperString(CFCalendarGetIdentifier(calendarRef)).utf8Z()).ref());
		
		ScCFReleaser<CFTimeZoneRef>		timeZoneRef(CFCalendarCopyTimeZone(calendarRef));
		CCFLog(true)(timeZoneRef.Get());
		
		CFAbsoluteTime				absTime = CFAbsoluteTimeGetCurrent();
		
		ScCFReleaser<CFDateRef>		dateRef(CFDateCreate(kCFAllocatorDefault, absTime));
		
		CCFLog(true)(dateRef.Get());
		
		CFGregorianDate				gregDate(CFAbsoluteTimeGetGregorianDate(absTime, timeZoneRef));
		CCFLog()(resultStr.ssprintf("year: %d\nmonth: %d\nday: %d\nhour: %d\nminute: %d\nsecond: %f\n", 
			   (int)gregDate.year, 
			   (int)gregDate.month, 
			   (int)gregDate.day, 
			   (int)gregDate.hour, 
			   (int)gregDate.minute, 
			   (float)gregDate.second).ref());
		
		ScCFReleaser<CFDateFormatterRef>	dateFormatterRef(CFDateFormatterCreate(
			kCFAllocatorDefault, locale, kCFDateFormatterFullStyle, kCFDateFormatterFullStyle));
		
		ScCFReleaser<CFStringRef>			dateStr(CFDateFormatterCreateStringWithDate(
			kCFAllocatorDefault, dateFormatterRef, dateRef));
		
		CCFLog()(CFSTR("Make sure time zone is correct in the next line:\n"));
		CCFLog(true)(dateStr.Get());
	}
	
	{
		CCFLog()(CFSTR("------------------Numbers---------------\n"));
		ScCFReleaser<CFNumberFormatterRef>		numFormatRef;
		ScCFReleaser<CFStringRef>				numStr;
		float									numF = 123456.789;
		ScCFReleaser<CFNumberRef>				numberRef(CFNumberCreate(
			kCFAllocatorDefault, kCFNumberFloat32Type, &numF));
		
		numFormatRef.adopt(CFNumberFormatterCreate(
			kCFAllocatorDefault, locale, kCFNumberFormatterDecimalStyle));
		numStr.adopt(CFNumberFormatterCreateStringWithNumber(
			kCFAllocatorDefault, numFormatRef, numberRef));
		CCFLog(true)(numStr.Get());
		
		numFormatRef.adopt(CFNumberFormatterCreate(
			kCFAllocatorDefault, locale, kCFNumberFormatterCurrencyStyle));
		numStr.adopt(CFNumberFormatterCreateStringWithNumber(
			kCFAllocatorDefault, numFormatRef, numberRef));
		CCFLog(true)(numStr.Get());
	}
	
	{
		CCFLog()(CFSTR("------------------Bundle---------------\n"));	
		
		ScCFReleaser<CFBundleRef>		bundleRef(CFBundleGetMainBundle());
		ScCFReleaser<CFURLRef>			bundleUrlRef;
		
		if (bundleRef.Get() == NULL) {
			if (pathZ != NULL) {
				bundleUrlRef.adopt(CFURLCreateWithFileSystemPath(
					kCFAllocatorDefault, SuperString(pathZ), kCFURLWindowsPathStyle, false));
			}
		} else {
			bundleUrlRef.adopt(CFBundleCopyBundleURL(bundleRef));
			
			//	this is a "get" not a "copy" so extra retain will cancel the extra release
			bundleRef.Retain();
		}
		
		CF_ASSERT(bundleUrlRef.Get());
		
		if (bundleUrlRef.Get() != NULL) {
			
			CCFLog(true)(bundleUrlRef.Get());
			
			if (bundleRef.Get() != NULL) {
				ScCFReleaser<CFDictionaryRef>	dictRef(CFBundleGetInfoDictionary(bundleRef));
				
				dict_for_each(dictRef, CCFLog(true));
			}
			
			{
				CCFLog()(CFSTR("------------------plist - xml---------------\n"));
				
				#if defined(__WIN32__)
					//	you may need to fix this relative URL here
					SuperString				relPathStr("../../");
				#else
					SuperString				relPathStr("../../../");
				#endif
				
				SuperString				testRelPath("test.xml");	testRelPath.prepend(relPathStr);
				ScCFReleaser<CFURLRef>	xmlUrlRef(CFURLCreateWithFileSystemPathRelativeToBase(
					kCFAllocatorDefault, testRelPath.ref(), kCFURLPOSIXPathStyle, false, bundleUrlRef));
				
				if (xmlUrlRef.Get()) {
					ScCFReleaser<CFDictionaryRef>		dictRef;
					ScCFReleaser<CFURLRef>				absUrlRef(CFURLCopyAbsoluteURL(xmlUrlRef));
					
					CCFLog()(resultStr.ssprintf("URL: %s\n", SuperString(CFURLGetString(absUrlRef)).utf8Z()).ref());
					
					if (Read_PList(xmlUrlRef, dictRef.AddressOf())) {
						dict_for_each(dictRef, CCFLog(true));
						
						SuperString				outRelpath("out.xml");	outRelpath.prepend(relPathStr);
						ScCFReleaser<CFURLRef>	outXmlUrlRef(CFURLCreateWithFileSystemPathRelativeToBase(
							kCFAllocatorDefault, outRelpath.ref(), kCFURLPOSIXPathStyle, false, bundleUrlRef));
						
						Write_PList(dictRef.Get(), outXmlUrlRef);
					}
				} else {
					CCFLog()(CFSTR("error illegal file path?\n"));
				}
			}
		}
	}
	
	CCFLog()(CFSTR("\nNote: not exercied here, but I want full CFXML support: input stream, node, parser, tree\n"));

	/*
	*dictP = CFDictionaryCreateMutable(
									   kCFAllocatorDefault, 0,
									   &kCFTypeDictionaryKeyCallBacks,
									   &kCFTypeDictionaryValueCallBacks);

	CFDictionarySetValue(dict, keyRef, rectDictRef);
	CFDictionarySetValue(plist.Get(), OSTypeToString(CM_Key_AlbumDict).ref(), album.Get());
	return (CFStringRef)CFDictionaryGetValue(dict, keyRef.Get());

	*arrayP = CFArrayCreateMutable(
								   kCFAllocatorDefault, 0,
								   &kCFTypeArrayCallBacks);

	CFArrayAppendValue(i_selectionRef, itemRef.Get());
	CFArrayInsertValueAtIndex(arrayRef, atIndex, valRef.Get());
	CFNumberRef			valRef	= (CFNumberRef)CFArrayGetValueAtIndex(dict, indexL);
	CFArraySetValueAtIndex(dict, indexL, valRef.Get());
	return CFArrayGetFirstIndexOfValue(array, rangeRef, valRef.Get());


	*xmlP = CFXMLTreeCreateFromData(
									kCFAllocatorDefault,
									xmlData.Get(), url, 
									kCFXMLParserSkipWhitespace,
									kCFXMLNodeCurrentVersion);
	
	CFXMLNodeTypeCode		type = CFXMLNodeGetTypeCode(nodeRef);
	CFXMLElementInfo	*infoP = (CFXMLElementInfo *)CFXMLNodeGetInfoPtr(nodeRef);
	i_keyStr.Set(CFXMLNodeGetString(nodeRef));
*/
	
	/*
	 bonus points:  CFCharacterSet
	 */
	CCFLog()(CFSTR("--------------------------------------\n"));
}