CFLite/CFTest/SuperString.cpp: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
No edit summary |
||
| (One intermediate revision by the same user not shown) | |||
| Line 5: | Line 5: | ||
* | * | ||
* Created by David M. Cotter on 6/25/08. | * Created by David M. Cotter on 6/25/08. | ||
* Copyright 2008 | * Copyright 2008 David M. Cotter. All rights reserved. | ||
* | * | ||
*/ | */ | ||
#include "stdafx.h" | |||
#include "SuperString.h" | #ifndef KJAMS | ||
#include "SuperString.h" | |||
#else | |||
#include "CApp.h" | |||
#include "CPreferences.h" | |||
#include "StringUtils.h" | |||
#include "MessageAlert.h" | |||
#endif | |||
void CCFLog::operator()(CFTypeRef valRef) { | |||
#if 1 | |||
SuperString valStr; valStr.Set_CFType(valRef); | |||
FILE *log_fileP = stdout; | |||
if (i_crB) { | |||
valStr.append("\n"); | |||
} | |||
#if defined(__WIN32__) | |||
#ifdef __MWERKS__ | |||
// console app | |||
static HANDLE consoleH = NULL; | |||
if (!consoleH) { | |||
consoleH = GetStdHandle(STD_OUTPUT_HANDLE); | |||
} | |||
unsigned long outL; | |||
WriteConsoleW(consoleH, valStr.w_str(), valStr.uni().i_lengthL, &outL, NULL); | |||
log_fileP = NULL; | |||
#else | |||
// GUI APP | |||
static FILE *s_logP = NULL; | |||
if (s_logP == NULL) { | |||
(void)fopen_s(&s_logP, "log.txt", "a"); | |||
} | |||
log_fileP = s_logP; | |||
#endif | |||
#endif | |||
if (log_fileP) { | |||
#ifdef KJAMS | |||
Log(valStr.utf8Z(), false); | |||
#else | |||
fprintf(log_fileP, "%s", valStr.utf8Z()); | |||
fflush(log_fileP); | |||
#endif | |||
} | |||
#else | |||
fflush(stdout); | |||
CFShow(valRef); | |||
if (i_crB) { | |||
printf("\n"); | |||
} | |||
fflush(stdout); | |||
#endif | |||
} | |||
void CCFLog::operator()(CFStringRef keyRef, CFTypeRef valRef) { | |||
SuperString keyStr(keyRef); | |||
keyStr.append(": "); | |||
{ | |||
bool wasB = i_crB; | |||
i_crB = false; | |||
operator()(keyStr.ref()); | |||
i_crB = wasB; | |||
} | |||
operator()(valRef); | |||
} | |||
#ifndef KJAMS | |||
void LogErr(const char *utf8Z, OSStatus err, bool crB, bool unixB) | |||
{ | |||
if (err) { // && gApp->Logging()) { | |||
SuperString keyStr(uc(utf8Z)); | |||
SuperString valStr((long)err); | |||
CCFLog logger(crB); | |||
logger(keyStr.ref(), valStr.ref()); | |||
} | |||
} | |||
#endif | |||
char* strrstr(const char* stringZ, const char* findZ) | char* strrstr(const char* stringZ, const char* findZ) | ||
{ | { | ||
bool firstB = true, doneB = false; | bool firstB = true, doneB = false; | ||
char *nextZ; | const char *nextZ; | ||
do { | do { | ||
| Line 37: | Line 130: | ||
} | } | ||
const char * CopyLongToC(long valL) | |||
{ | { | ||
static char s_bufAC[256]; | static char s_bufAC[256]; | ||
| Line 54: | Line 147: | ||
class Asciify { | class Asciify { | ||
public: void operator()(char &ch) { | public: void operator()(char &ch) { | ||
if (ch < 32 || ch > 126) ch = '?'; | |||
} | } | ||
}; | }; | ||
| Line 63: | Line 156: | ||
{ | { | ||
return nameRef == NULL || CFStringEqual(nameRef, CFSTR("")); | return nameRef == NULL || CFStringEqual(nameRef, CFSTR("")); | ||
} | |||
CFStringEncoding s_file_encoding = kCFStringEncodingInvalidId; | |||
void SetDefaultEncoding(CFStringEncoding encoding) | |||
{ | |||
s_file_encoding = encoding; | |||
} | } | ||
| Line 68: | Line 167: | ||
{ | { | ||
if (encoding == kCFStringEncodingInvalidId) { | if (encoding == kCFStringEncodingInvalidId) { | ||
encoding = | encoding = s_file_encoding; | ||
CF_ASSERT(encoding != kCFStringEncodingInvalidId); | |||
} | } | ||
| Line 75: | Line 176: | ||
CFStringRef CFStringCreateWithC( | CFStringRef CFStringCreateWithC( | ||
const char * bufZ, | |||
CFStringEncoding encoding) | |||
{ | { | ||
if (bufZ) { | if (bufZ) { | ||
| Line 98: | Line 199: | ||
CFStringRef CFStringCreateWithCu( | CFStringRef CFStringCreateWithCu( | ||
const UTF8Char * bufZ, | |||
CFStringEncoding encoding) | |||
{ | { | ||
return CFStringCreateWithC((const char *)bufZ, encoding); | return CFStringCreateWithC((const char *)bufZ, encoding); | ||
| Line 141: | Line 242: | ||
std::string &CopyCFStringToStd( | std::string &CopyCFStringToStd( | ||
CFStringRef str, | |||
std::string &stdstr, | |||
CFStringEncoding encoding) | |||
{ | { | ||
stdstr.clear(); | stdstr.clear(); | ||
| Line 163: | Line 264: | ||
return stdstr; | return stdstr; | ||
} | |||
char *OSTypeToChar(OSType osType, char *bufZ) | |||
{ | |||
osType = CFSwapInt32HostToBig(osType); | |||
*((OSType *)bufZ) = osType; | |||
bufZ[4] = 0; | |||
return bufZ; | |||
} | |||
SuperString OSTypeToString(OSType osType) | |||
{ | |||
SuperString str; | |||
if (osType == -1) { | |||
str.Set("-"); | |||
} else { | |||
char bufAC[5]; | |||
str.Set(OSTypeToChar(osType, bufAC)); | |||
} | |||
return str; | |||
} | |||
OSType CharToOSType(const char *bufZ) | |||
{ | |||
OSType osType; | |||
short lenL = strlen(bufZ); | |||
osType = *((OSType *)(&bufZ[lenL - 4])); | |||
osType = CFSwapInt32BigToHost(osType); | |||
return osType; | |||
} | } | ||
| Line 205: | Line 339: | ||
} | } | ||
bool g_pref_diacritic_insensitive_searchB = true; | #ifndef __WIN32__ | ||
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 | |||
enum { | |||
kCFCompareDiacriticInsensitive = 128, /* If specified, ignores diacritics (o-umlaut == o) */ | |||
kCFCompareWidthInsensitive = 256, /* If specified, ignores width differences ('a' == UFF41) */ | |||
kCFCompareForcedOrdering = 512 /* If specified, comparisons are forced to return either kCFCompareLessThan or kCFCompareGreaterThan if the strings are equivalent but not strictly equal, for stability when sorting (e.g. "aaa" > "AAA" with kCFCompareCaseInsensitive specified) */ | |||
}; | |||
#endif | |||
#endif | |||
#ifdef KJAMS | |||
ushort GetSystemVers(void); | |||
#define diacritic_insensitiveB (gApp && gApp->i_prefs && gApp->i_prefs->i_pref.diacritic_insensitive_searchB) | |||
#else | |||
bool g_pref_diacritic_insensitive_searchB = true; | |||
#define diacritic_insensitiveB g_pref_diacritic_insensitive_searchB | |||
#ifdef _ROSE_ | |||
unsigned short GetSystemVers(void); | |||
#else | |||
static unsigned short GetSystemVers(void) { | |||
return 0x1050; // fake it to be OS 10.5 | |||
} | |||
#endif | |||
#endif | |||
static CFOptionFlags GetFlags_NormalizeStrings( | static CFOptionFlags GetFlags_NormalizeStrings( | ||
| Line 214: | Line 374: | ||
| kCFCompareLocalized) | | kCFCompareLocalized) | ||
{ | { | ||
if ( | if (diacritic_insensitiveB) { | ||
static bool s_diacritic_compare_inittedB = false; | static bool s_diacritic_compare_inittedB = false; | ||
static bool s_has_diacritic_insensitive_compareB; | static bool s_has_diacritic_insensitive_compareB; | ||
| Line 229: | Line 389: | ||
== kCFCompareEqualTo; | == kCFCompareEqualTo; | ||
#else | #else | ||
s_has_diacritic_insensitive_compareB = | s_has_diacritic_insensitive_compareB = GetSystemVers() >= 0x1050; | ||
#endif | #endif | ||
| Line 266: | Line 426: | ||
CFComparisonResult compareResult = kCFCompareEqualTo; | CFComparisonResult compareResult = kCFCompareEqualTo; | ||
if (ref1 == NULL || ref2 == NULL) { | if ((ref1 == NULL) || (ref2 == NULL)) { | ||
if (ref1 == NULL ^ ref2 == NULL) { | if ((ref1 == NULL) ^ (ref2 == NULL)) { | ||
if (ref1) { | if (ref1) { | ||
compareResult = kCFCompareLessThan; | compareResult = kCFCompareLessThan; | ||
| Line 306: | Line 466: | ||
} | } | ||
#ifndef KJAMS | |||
static void mt_vsnprintf(char *destZ, size_t sizeL, const char *formatZ, va_list &args) | static void mt_vsnprintf(char *destZ, size_t sizeL, const char *formatZ, va_list &args) | ||
{ | { | ||
vsnprintf(destZ, sizeL - 1, formatZ, args); | vsnprintf(destZ, sizeL - 1, formatZ, args); | ||
destZ[sizeL - 1] = 0; | destZ[sizeL - 1] = 0; | ||
} | |||
#endif | |||
bool SuperString::Split(const char *splitZ, SuperString *rhsP0, bool from_endB) | |||
{ | |||
bool splitB; | |||
if (from_endB) { | |||
splitB = strrstr(utf8Z(), splitZ) != NULL; | |||
} else { | |||
splitB = strstr(utf8Z(), splitZ) != NULL; | |||
} | |||
if (splitB) { | |||
UCharVec bufAC; | |||
bufAC.assign(utf8().begin(), utf8().end()); | |||
bufAC.push_back(0); | |||
UTF8Char *chZ; | |||
if (from_endB) { | |||
chZ = (UTF8Char *)strrstr((char *)&bufAC[0], (char *)splitZ); | |||
} else { | |||
chZ = (UTF8Char *)strstr((char *)&bufAC[0], (char *)splitZ); | |||
} | |||
SuperString temp(chZ + strlen(splitZ)); | |||
*chZ = 0; | |||
Set(&bufAC[0]); | |||
if (rhsP0) { | |||
rhsP0->Set(temp); | |||
} | |||
} | |||
return splitB; | |||
} | } | ||
| Line 324: | Line 522: | ||
Set(uc(&buf[0])); | Set(uc(&buf[0])); | ||
return *this; | return *this; | ||
} | |||
SuperString & SuperString::pop_back(UInt32 numCharsL) | |||
{ | |||
ustring ustr(utf8()); | |||
if (!ustr.empty()) { | |||
ustr.resize(ustr.size() - numCharsL); | |||
Set(ustr.c_str()); | |||
} | |||
return *this; | |||
} | |||
#ifdef __WIN32__ | |||
#if defined(__MWERKS__) | |||
class CIsZero { | |||
public: bool operator()(const wchar_t& ch) { | |||
return ch == 0; | |||
} | |||
}; | |||
static size_t wcslen(const wchar_t *wcharZ) | |||
{ | |||
const wchar_t* it(std::find_if(&wcharZ[0], &wcharZ[512], CIsZero())); | |||
return std::distance(&wcharZ[0], it); | |||
} | |||
#endif | |||
SuperString::SuperString(const wchar_t *wcharZ) | |||
{ | |||
UTF16Vec vec((UTF16Char *)&wcharZ[0], (UTF16Char *)&wcharZ[wcslen(wcharZ)]); | |||
SetNULL(); | |||
Set(vec); | |||
} | |||
#endif | |||
void SuperString::Set_p(ConstStr255Param strZ, CFStringEncoding encoding) | |||
{ | |||
UCharVec charVec; | |||
charVec.assign(&strZ[1], &strZ[strZ[0] + 1]); | |||
charVec.push_back(0); | |||
Set(&charVec[0], encoding); | |||
} | } | ||
| Line 336: | Line 581: | ||
ScCFReleaser<CFStringRef> descRef(CFCopyDescription(cfType)); | ScCFReleaser<CFStringRef> descRef(CFCopyDescription(cfType)); | ||
SuperString descIDStr(descIDRef.Get()), descStr(descRef.Get()); | SuperString descIDStr(descIDRef.Get()), descStr(descRef.Get()); | ||
SuperString logStr("Type: | SuperString logStr("Type: <%s>, Value: <%s>"); | ||
logStr.ssprintf(NULL, descIDStr.utf8Z(), descStr.utf8Z()); | logStr.ssprintf(NULL, descIDStr.utf8Z(), descStr.utf8Z()); | ||
| Line 343: | Line 588: | ||
} | } | ||
#ifndef KJAMS | |||
int AssertAlert(const char *msgZ, const char *fileZ, long lineL, bool noThrowB) | int AssertAlert(const char *msgZ, const char *fileZ, long lineL, bool noThrowB) | ||
{ | { | ||
SuperString formatStr("$$$ Assert Fail: %s, in file: '%s' at line %ld"); | SuperString formatStr("$$$ Assert Fail: %s, in file: '%s' at line %ld\n"); | ||
formatStr.ssprintf(NULL, msgZ, fileZ, lineL); | formatStr.ssprintf(NULL, msgZ, fileZ, lineL); | ||
CCFLog()(formatStr.ref()); | |||
return 1; | return 1; | ||
} | } | ||
#endif | |||
bool Read_PList(const CFURLRef &url, CFDictionaryRef *plistP) | bool Read_PList(const CFURLRef &url, CFDictionaryRef *plistP) | ||
| Line 375: | Line 622: | ||
// Log("created plist from xml"); | // Log("created plist from xml"); | ||
} else { | } else { | ||
CCFLog()("FAILED converting xml to plist\n"); | |||
} | } | ||
} else { | } else { | ||
CCFLog()("FAILED creating xml from file\n"); | |||
} | } | ||
return successB; | return successB; | ||
} | } | ||
OSStatus Write_PList( | OSStatus Write_PList( | ||
| Line 408: | Line 653: | ||
return err; | return err; | ||
} | } | ||
</pre> | </pre> | ||
Latest revision as of 22:30, 22 July 2008
/*
* SuperString.cpp
* CFTest
*
* Created by David M. Cotter on 6/25/08.
* Copyright 2008 David M. Cotter. All rights reserved.
*
*/
#include "stdafx.h"
#ifndef KJAMS
#include "SuperString.h"
#else
#include "CApp.h"
#include "CPreferences.h"
#include "StringUtils.h"
#include "MessageAlert.h"
#endif
void CCFLog::operator()(CFTypeRef valRef) {
#if 1
SuperString valStr; valStr.Set_CFType(valRef);
FILE *log_fileP = stdout;
if (i_crB) {
valStr.append("\n");
}
#if defined(__WIN32__)
#ifdef __MWERKS__
// console app
static HANDLE consoleH = NULL;
if (!consoleH) {
consoleH = GetStdHandle(STD_OUTPUT_HANDLE);
}
unsigned long outL;
WriteConsoleW(consoleH, valStr.w_str(), valStr.uni().i_lengthL, &outL, NULL);
log_fileP = NULL;
#else
// GUI APP
static FILE *s_logP = NULL;
if (s_logP == NULL) {
(void)fopen_s(&s_logP, "log.txt", "a");
}
log_fileP = s_logP;
#endif
#endif
if (log_fileP) {
#ifdef KJAMS
Log(valStr.utf8Z(), false);
#else
fprintf(log_fileP, "%s", valStr.utf8Z());
fflush(log_fileP);
#endif
}
#else
fflush(stdout);
CFShow(valRef);
if (i_crB) {
printf("\n");
}
fflush(stdout);
#endif
}
void CCFLog::operator()(CFStringRef keyRef, CFTypeRef valRef) {
SuperString keyStr(keyRef);
keyStr.append(": ");
{
bool wasB = i_crB;
i_crB = false;
operator()(keyStr.ref());
i_crB = wasB;
}
operator()(valRef);
}
#ifndef KJAMS
void LogErr(const char *utf8Z, OSStatus err, bool crB, bool unixB)
{
if (err) { // && gApp->Logging()) {
SuperString keyStr(uc(utf8Z));
SuperString valStr((long)err);
CCFLog logger(crB);
logger(keyStr.ref(), valStr.ref());
}
}
#endif
char* strrstr(const char* stringZ, const char* findZ)
{
bool firstB = true, doneB = false;
const char *nextZ;
do {
if (firstB) {
nextZ = strstr(stringZ, findZ);
} else {
nextZ = strstr(&stringZ[1], findZ);
}
doneB = nextZ == NULL;
if (!doneB) {
stringZ = nextZ;
} else if (firstB) {
stringZ = NULL;
}
firstB = false;
} while (!doneB);
return const_cast<char *>(stringZ);
}
const char * CopyLongToC(long valL)
{
static char s_bufAC[256];
sprintf(s_bufAC, "%d", valL);
return s_bufAC;
}
float CStringToFloat(const char *numF)
{
float valF = 0;
sscanf(numF, "%f", &valF);
return valF;
}
class Asciify {
public: void operator()(char &ch) {
if (ch < 32 || ch > 126) ch = '?';
}
};
/********************************************************/
bool CFStringIsEmpty(CFStringRef nameRef)
{
return nameRef == NULL || CFStringEqual(nameRef, CFSTR(""));
}
CFStringEncoding s_file_encoding = kCFStringEncodingInvalidId;
void SetDefaultEncoding(CFStringEncoding encoding)
{
s_file_encoding = encoding;
}
static CFStringEncoding ValidateEncoding(CFStringEncoding encoding = kCFStringEncodingInvalidId)
{
if (encoding == kCFStringEncodingInvalidId) {
encoding = s_file_encoding;
CF_ASSERT(encoding != kCFStringEncodingInvalidId);
}
return encoding;
}
CFStringRef CFStringCreateWithC(
const char * bufZ,
CFStringEncoding encoding)
{
if (bufZ) {
encoding = ValidateEncoding(encoding);
CFStringRef cf = NULL;
cf = CFStringCreateWithCString(kCFAllocatorDefault, bufZ, encoding);
if (!cf) cf = CFStringCreateWithCString(kCFAllocatorDefault, bufZ, kCFStringEncodingWindowsLatin1);
if (!cf) cf = CFStringCreateWithCString(kCFAllocatorDefault, bufZ, kCFStringEncodingISOLatin1);
if (!cf) cf = CFStringCreateWithCString(kCFAllocatorDefault, bufZ, kCFStringEncodingMacRoman);
CF_ASSERT(cf);
if (!cf) return NULL;
return (CFStringRef)CFRetainDebug(cf, false);
} else {
return (CFStringRef)CFRetainDebug(CFSTR(""));
}
}
CFStringRef CFStringCreateWithCu(
const UTF8Char * bufZ,
CFStringEncoding encoding)
{
return CFStringCreateWithC((const char *)bufZ, encoding);
}
static inline CFRange CFStrGetRange(CFStringRef ref)
{
return CFRangeMake(0, CFStringGetLength(ref));
}
ustring &CopyCFStringToUString(CFStringRef str, ustring &result, CFStringEncoding encoding, bool externalB)
{
result.clear();
if (str) {
#define kBufSize 256
UTF8Char utf8Buf[kBufSize];
CFRange cfRange = CFStrGetRange(str);
CFIndex resultSize;
CFIndex numChars;
encoding = ValidateEncoding(encoding);
while (cfRange.length > 0) {
numChars = CFStringGetBytes(
str, cfRange, encoding, '?', externalB,
&utf8Buf[0], kBufSize, &resultSize);
if (numChars == 0) break; // Failed to convert anything...
result.append(&utf8Buf[0], &utf8Buf[resultSize]);
cfRange.location += numChars;
cfRange.length -= numChars;
}
}
return result;
}
std::string &CopyCFStringToStd(
CFStringRef str,
std::string &stdstr,
CFStringEncoding encoding)
{
stdstr.clear();
encoding = ValidateEncoding(encoding);
if (str) {
const char *charZ = CFStringGetCStringPtr(str, encoding);
if (charZ) {
stdstr = charZ;
} else {
ustring ustr;
CopyCFStringToUString(str, ustr, encoding);
stdstr.append(ustr.begin(), ustr.end());
}
}
return stdstr;
}
char *OSTypeToChar(OSType osType, char *bufZ)
{
osType = CFSwapInt32HostToBig(osType);
*((OSType *)bufZ) = osType;
bufZ[4] = 0;
return bufZ;
}
SuperString OSTypeToString(OSType osType)
{
SuperString str;
if (osType == -1) {
str.Set("-");
} else {
char bufAC[5];
str.Set(OSTypeToChar(osType, bufAC));
}
return str;
}
OSType CharToOSType(const char *bufZ)
{
OSType osType;
short lenL = strlen(bufZ);
osType = *((OSType *)(&bufZ[lenL - 4]));
osType = CFSwapInt32BigToHost(osType);
return osType;
}
// you should provide this function. stubbed out here because my CF doesn't have it
#define CFStringTransform(a, b, c, d) true
SuperString& SuperString::Normalize()
{
ScCFReleaser<CFMutableStringRef> str1;
str1.Set(CFStringCreateMutableCopy(kCFAllocatorDefault, 0, ref()));
CFStringNormalize(str1, kCFStringNormalizationFormD);
CFRange range = CFStrGetRange(str1);
if (CFStringTransform(str1, &range, kCFStringTransformStripCombiningMarks, false)) {
Set(str1);
}
// void CFStringFold(CFMutableStringRef theString, CFOptionFlags theFlags, CFLocaleRef theLocale) AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER;
return *this;
}
void CFStrReplaceWith(CFMutableStringRef stringRef, CFStringRef replaceStr, CFStringRef withStr)
{
ScCFReleaser<CFArrayRef> arrayRef;
arrayRef.Set(CFStringCreateArrayWithFindResults(
NULL, stringRef, replaceStr, CFStrGetRange(stringRef), kCFCompareCaseInsensitive));
if (arrayRef.Get()) {
CFRange *rangeRef;
loop_reverse (CFArrayGetCount(arrayRef)) {
rangeRef = (CFRange *)CFArrayGetValueAtIndex(arrayRef, _indexS);
CFStringReplace(stringRef, *rangeRef, withStr);
}
}
}
#ifndef __WIN32__
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
enum {
kCFCompareDiacriticInsensitive = 128, /* If specified, ignores diacritics (o-umlaut == o) */
kCFCompareWidthInsensitive = 256, /* If specified, ignores width differences ('a' == UFF41) */
kCFCompareForcedOrdering = 512 /* If specified, comparisons are forced to return either kCFCompareLessThan or kCFCompareGreaterThan if the strings are equivalent but not strictly equal, for stability when sorting (e.g. "aaa" > "AAA" with kCFCompareCaseInsensitive specified) */
};
#endif
#endif
#ifdef KJAMS
ushort GetSystemVers(void);
#define diacritic_insensitiveB (gApp && gApp->i_prefs && gApp->i_prefs->i_pref.diacritic_insensitive_searchB)
#else
bool g_pref_diacritic_insensitive_searchB = true;
#define diacritic_insensitiveB g_pref_diacritic_insensitive_searchB
#ifdef _ROSE_
unsigned short GetSystemVers(void);
#else
static unsigned short GetSystemVers(void) {
return 0x1050; // fake it to be OS 10.5
}
#endif
#endif
static CFOptionFlags GetFlags_NormalizeStrings(
SuperString& str1,
SuperString& str2,
CFOptionFlags optionFlags = 0
| kCFCompareNonliteral
| kCFCompareLocalized)
{
if (diacritic_insensitiveB) {
static bool s_diacritic_compare_inittedB = false;
static bool s_has_diacritic_insensitive_compareB;
if (!s_diacritic_compare_inittedB) {
#if defined(__WIN32__)
SuperString str_e("e");
UInt32 e_grave(CFSwapInt32HostToBig(0xC3A90000));
SuperString str_e_grave((UInt8*)&e_grave);
s_has_diacritic_insensitive_compareB = ::CFStringCompare(
str_e.ref(), str_e_grave.ref(), (CFOptionFlags)kCFCompareDiacriticInsensitive)
== kCFCompareEqualTo;
#else
s_has_diacritic_insensitive_compareB = GetSystemVers() >= 0x1050;
#endif
s_diacritic_compare_inittedB = true;
}
if (s_has_diacritic_insensitive_compareB) {
optionFlags |= (CFOptionFlags)(0
| kCFCompareDiacriticInsensitive
| kCFCompareWidthInsensitive);
} else {
str1.Normalize();
str2.Normalize();
}
}
return optionFlags;
}
bool CFStringContains(CFStringRef inRef, CFStringRef findRef, bool case_sensitiveB)
{
if (inRef == NULL || findRef == NULL) {
return false;
}
SuperString str1(inRef), str2(findRef);
CFOptionFlags optionFlags = case_sensitiveB ? kCFCompareCaseInsensitive : 0;
optionFlags = GetFlags_NormalizeStrings(str1, str2, optionFlags);
return !!CFStringFindWithOptions(str1.ref(), str2.ref(), CFStrGetRange(str1.ref()), optionFlags, NULL);
}
CFComparisonResult CFStringCompare(CFStringRef ref1, CFStringRef ref2, bool case_sensitiveB)
{
CFComparisonResult compareResult = kCFCompareEqualTo;
if ((ref1 == NULL) || (ref2 == NULL)) {
if ((ref1 == NULL) ^ (ref2 == NULL)) {
if (ref1) {
compareResult = kCFCompareLessThan;
} else {
compareResult = kCFCompareGreaterThan;
}
}
} else {
SuperString str1(ref1), str2(ref2);
CFOptionFlags optionFlags = case_sensitiveB ? 0 : kCFCompareCaseInsensitive;
optionFlags = GetFlags_NormalizeStrings(str1, str2, optionFlags);
compareResult = ::CFStringCompare(str1.ref(), str2.ref(), optionFlags);
}
return compareResult;
}
bool CFStringEqual(CFStringRef str1, CFStringRef str2, bool case_sensitiveB)
{
return CFStringCompare(str1, str2, case_sensitiveB) == kCFCompareEqualTo;
}
bool CFStringLess(CFStringRef lhs, CFStringRef rhs, bool case_sensitiveB)
{
bool lessB = CFStringCompare(lhs, rhs, case_sensitiveB) == kCFCompareLessThan;
return lessB;
}
SuperString operator+(const SuperString &lhs, SuperString rhs)
{
SuperString str(lhs);
str.append(rhs);
return str;
}
#ifndef KJAMS
static void mt_vsnprintf(char *destZ, size_t sizeL, const char *formatZ, va_list &args)
{
vsnprintf(destZ, sizeL - 1, formatZ, args);
destZ[sizeL - 1] = 0;
}
#endif
bool SuperString::Split(const char *splitZ, SuperString *rhsP0, bool from_endB)
{
bool splitB;
if (from_endB) {
splitB = strrstr(utf8Z(), splitZ) != NULL;
} else {
splitB = strstr(utf8Z(), splitZ) != NULL;
}
if (splitB) {
UCharVec bufAC;
bufAC.assign(utf8().begin(), utf8().end());
bufAC.push_back(0);
UTF8Char *chZ;
if (from_endB) {
chZ = (UTF8Char *)strrstr((char *)&bufAC[0], (char *)splitZ);
} else {
chZ = (UTF8Char *)strstr((char *)&bufAC[0], (char *)splitZ);
}
SuperString temp(chZ + strlen(splitZ));
*chZ = 0;
Set(&bufAC[0]);
if (rhsP0) {
rhsP0->Set(temp);
}
}
return splitB;
}
SuperString& SuperString::ssprintf(const char *formatZ0, ...)
{
CharVec buf(2048);
va_list args;
CF_ASSERT(utf8().size() < 1024);
va_start(args, formatZ0);
mt_vsnprintf(&buf[0], buf.size(), formatZ0 ? formatZ0 : utf8Z(), args);
va_end(args);
Set(uc(&buf[0]));
return *this;
}
SuperString & SuperString::pop_back(UInt32 numCharsL)
{
ustring ustr(utf8());
if (!ustr.empty()) {
ustr.resize(ustr.size() - numCharsL);
Set(ustr.c_str());
}
return *this;
}
#ifdef __WIN32__
#if defined(__MWERKS__)
class CIsZero {
public: bool operator()(const wchar_t& ch) {
return ch == 0;
}
};
static size_t wcslen(const wchar_t *wcharZ)
{
const wchar_t* it(std::find_if(&wcharZ[0], &wcharZ[512], CIsZero()));
return std::distance(&wcharZ[0], it);
}
#endif
SuperString::SuperString(const wchar_t *wcharZ)
{
UTF16Vec vec((UTF16Char *)&wcharZ[0], (UTF16Char *)&wcharZ[wcslen(wcharZ)]);
SetNULL();
Set(vec);
}
#endif
void SuperString::Set_p(ConstStr255Param strZ, CFStringEncoding encoding)
{
UCharVec charVec;
charVec.assign(&strZ[1], &strZ[strZ[0] + 1]);
charVec.push_back(0);
Set(&charVec[0], encoding);
}
void SuperString::Set_CFType(CFTypeRef cfType)
{
CFTypeID cfTypeID(CFGetTypeID(cfType));
if (cfTypeID == CFStringGetTypeID()) {
Set((CFStringRef)cfType);
} else {
ScCFReleaser<CFStringRef> descIDRef(CFCopyTypeIDDescription(cfTypeID));
ScCFReleaser<CFStringRef> descRef(CFCopyDescription(cfType));
SuperString descIDStr(descIDRef.Get()), descStr(descRef.Get());
SuperString logStr("Type: <%s>, Value: <%s>");
logStr.ssprintf(NULL, descIDStr.utf8Z(), descStr.utf8Z());
Set(logStr);
}
}
#ifndef KJAMS
int AssertAlert(const char *msgZ, const char *fileZ, long lineL, bool noThrowB)
{
SuperString formatStr("$$$ Assert Fail: %s, in file: '%s' at line %ld\n");
formatStr.ssprintf(NULL, msgZ, fileZ, lineL);
CCFLog()(formatStr.ref());
return 1;
}
#endif
bool Read_PList(const CFURLRef &url, CFDictionaryRef *plistP)
{
bool successB = false;
ScCFReleaser<CFDataRef> xmlData;
*plistP = NULL;
if (CFURLCreateDataAndPropertiesFromResource(
kCFAllocatorDefault, url, xmlData.AddressOf(), NULL, NULL, NULL)
) {
//Log("created xml from file");
*plistP = (CFDictionaryRef)CFPropertyListCreateFromXMLData(
kCFAllocatorDefault,
xmlData,
kCFPropertyListImmutable,
NULL);
successB = *plistP != NULL;
if (successB) {
// Log("created plist from xml");
} else {
CCFLog()("FAILED converting xml to plist\n");
}
} else {
CCFLog()("FAILED creating xml from file\n");
}
return successB;
}
OSStatus Write_PList(
CFPropertyListRef plist,
CFURLRef urlRef)
{
OSStatus err = noErr;
ScCFReleaser<CFDataRef> xmlData;
// Convert the property list into XML data.
xmlData.Set(CFPropertyListCreateXMLData(kCFAllocatorDefault, plist));
ETRL(xmlData.Get() == NULL, "creating xml data");
if (!err) {
(void)CFURLWriteDataAndPropertiesToResource (
urlRef, // URL to use
xmlData, // data to write
NULL,
&err);
}
ETRL(err, "writing xml");
return err;
}