#include "SuperString.h"
#include <CoreFoundation/CFLocale.h>
#include <CoreFoundation/CFNumberFormatter.h>
#include <CoreFoundation/CFDateFormatter.h>
#include <CoreFoundation/CFCalendar.h>
#include <CoreFoundation/CFBundle.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);
}
}
template <class Function>
void xml_for_each(CFXMLTreeRef xmlTree, Function f, short levelS = 0)
{
CFXMLNodeRef xmlNode;
long sizeL = CFTreeGetChildCount(xmlTree);
loop (sizeL) {
CFTreeRef xmlTreeNode = CFTreeGetChildAtIndex(xmlTree, _indexS);
xmlNode = CFXMLTreeGetNode(xmlTreeNode);
f(xmlNode, levelS);
xml_for_each(xmlTreeNode, f, levelS + 1);
}
}
void CFTest(const char *pathZ);
void CFTest(const char *pathZ)
{
SuperString resultStr;
#if defined(__WIN32__)
#define kCodePage_WindowsLatin1 1252
SetConsoleOutputCP(kCodePage_WindowsLatin1);
#endif
// 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 " kLeftQuote "yeah baby" kRightQuote "\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 " kLeftQuote "foo bar" kRightQuote "\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);
if (kConsoleEncoding == kCFStringEncodingUTF8) {
CCFLog()(resultStr.ssprintf(
"The next line should read " kLeftQuote "%s" kRightQuote "\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"));
}