diff options
Diffstat (limited to 'src/core/basetypes')
-rw-r--r-- | src/core/basetypes/MCArray.cc | 23 | ||||
-rw-r--r-- | src/core/basetypes/MCArray.h | 1 | ||||
-rw-r--r-- | src/core/basetypes/MCData.cc | 3 | ||||
-rw-r--r-- | src/core/basetypes/MCHTMLCleaner.cc | 3 | ||||
-rw-r--r-- | src/core/basetypes/MCIndexSet.cc | 6 | ||||
-rw-r--r-- | src/core/basetypes/MCIterator.h | 55 | ||||
-rw-r--r-- | src/core/basetypes/MCLibetpan.cc | 202 | ||||
-rw-r--r-- | src/core/basetypes/MCLibetpan.h | 12 | ||||
-rw-r--r-- | src/core/basetypes/MCObject.cc | 4 | ||||
-rw-r--r-- | src/core/basetypes/MCOperation.cc | 11 | ||||
-rw-r--r-- | src/core/basetypes/MCOperationQueue.cc | 35 | ||||
-rw-r--r-- | src/core/basetypes/MCOperationQueue.h | 2 | ||||
-rw-r--r-- | src/core/basetypes/MCSet.cc | 2 | ||||
-rw-r--r-- | src/core/basetypes/MCString.cc | 54 | ||||
-rw-r--r-- | src/core/basetypes/MCString.h | 2 | ||||
-rw-r--r-- | src/core/basetypes/MCUtils.h | 2 |
16 files changed, 392 insertions, 25 deletions
diff --git a/src/core/basetypes/MCArray.cc b/src/core/basetypes/MCArray.cc index 804f796c..43ee6bd4 100644 --- a/src/core/basetypes/MCArray.cc +++ b/src/core/basetypes/MCArray.cc @@ -212,21 +212,26 @@ static int sortCompare(Object ** pa, Object ** pb, struct sortData * data) Array * Array::sortedArray(int (* compare)(void * a, void * b, void * context), void * context) { - struct sortData data; Array * result = (Array *) this->copy()->autorelease(); + result->sortArray(compare, context); + return result; +} + +void Array::sortArray(int (* compare)(void * a, void * b, void * context), void * context) +{ + struct sortData data; data.compare = compare; data.context = context; #ifdef __MACH__ - qsort_r(carray_data(result->mArray), carray_count(result->mArray), - sizeof(* carray_data(result->mArray)), &data, - (int (*)(void *, const void *, const void *)) sortCompare); + qsort_r(carray_data(mArray), carray_count(mArray), + sizeof(* carray_data(mArray)), &data, + (int (*)(void *, const void *, const void *)) sortCompare); #else - qsort_r(carray_data(result->mArray), carray_count(result->mArray), - sizeof(* carray_data(result->mArray)), - (int (*)(const void *, const void *, void *)) sortCompare, - &data); + qsort_r(carray_data(mArray), carray_count(mArray), + sizeof(* carray_data(mArray)), + (int (*)(const void *, const void *, void *)) sortCompare, + &data); #endif - return result; } String * Array::componentsJoinedByString(String * delimiter) diff --git a/src/core/basetypes/MCArray.h b/src/core/basetypes/MCArray.h index 6ee64792..82e9760a 100644 --- a/src/core/basetypes/MCArray.h +++ b/src/core/basetypes/MCArray.h @@ -36,6 +36,7 @@ namespace mailcore { virtual bool containsObject(Object * obj); virtual Array * sortedArray(int (* compare)(void * a, void * b, void * context), void * context); + virtual void sortArray(int (* compare)(void * a, void * b, void * context), void * context); virtual String * componentsJoinedByString(String * delimiter); public: // subclass behavior diff --git a/src/core/basetypes/MCData.cc b/src/core/basetypes/MCData.cc index 0a03316c..60b8ff8f 100644 --- a/src/core/basetypes/MCData.cc +++ b/src/core/basetypes/MCData.cc @@ -283,6 +283,9 @@ String * Data::stringWithDetectedCharset(String * hintCharset, bool isHTML) if (result == NULL) { result = data->stringWithCharset("iso-2022-jp"); } + if (result == NULL) { + result = MCSTR(""); + } return result; } diff --git a/src/core/basetypes/MCHTMLCleaner.cc b/src/core/basetypes/MCHTMLCleaner.cc index 78d2461a..81145c9e 100644 --- a/src/core/basetypes/MCHTMLCleaner.cc +++ b/src/core/basetypes/MCHTMLCleaner.cc @@ -43,6 +43,9 @@ String * HTMLCleaner::cleanHTML(String * input) tidyOptSetBool(tdoc, TidyDropEmptyElems, no); #endif tidyOptSetBool(tdoc, TidyXhtmlOut, yes); + tidyOptSetInt(tdoc, TidyDoctypeMode, TidyDoctypeUser); + + tidyOptSetBool(tdoc, TidyMark, no); tidySetCharEncoding(tdoc, "utf8"); tidyOptSetBool(tdoc, TidyForceOutput, yes); //tidyOptSetValue(tdoc, TidyErrFile, "/dev/null"); diff --git a/src/core/basetypes/MCIndexSet.cc b/src/core/basetypes/MCIndexSet.cc index 07d78d5d..768cd601 100644 --- a/src/core/basetypes/MCIndexSet.cc +++ b/src/core/basetypes/MCIndexSet.cc @@ -148,7 +148,7 @@ int IndexSet::leftRangeIndexForIndexWithBounds(uint64_t idx, unsigned int left, Range middleRange = mRanges[middle]; if (left == right) { - if (idx <= middleRange.location) { + if (idx <= RangeRightBound(middleRange)) { return left; } else { @@ -156,7 +156,7 @@ int IndexSet::leftRangeIndexForIndexWithBounds(uint64_t idx, unsigned int left, } } - if (idx <= middleRange.location) { + if (idx <= RangeRightBound(middleRange)) { return leftRangeIndexForIndexWithBounds(idx, left, middle); } else { @@ -372,7 +372,7 @@ void IndexSet::intersectsRange(Range range) } else { removeRange(RangeMake(0, range.location - 1)); - removeRange(RangeMake(right, UINT64_MAX)); + removeRange(RangeMake(right + 1, UINT64_MAX)); } } diff --git a/src/core/basetypes/MCIterator.h b/src/core/basetypes/MCIterator.h index 08a3b256..c8b23fab 100644 --- a/src/core/basetypes/MCIterator.h +++ b/src/core/basetypes/MCIterator.h @@ -12,6 +12,7 @@ #include <MailCore/MCArray.h> #include <MailCore/MCHashMap.h> +#include <MailCore/MCIndexSet.h> #include <MailCore/MCAutoreleasePool.h> #include <string.h> @@ -25,7 +26,7 @@ for (; NULL != (__variable = (type *) mailcore::ArrayIteratorNext(&__variable##_ #define mc_foreacharrayIndex(__index, type, __variable, __array) \ type * __variable; \ mailcore::ArrayIterator __variable##__iterator = mailcore::ArrayIteratorInit(__array); \ -for (unsigned int __index = 0; NULL != (__variable = mailcore::ArrayIteratorNext(&__variable##__iterator)); __index++) +for (unsigned int __index = 0; NULL != (__variable = (type *) mailcore::ArrayIteratorNext(&__variable##__iterator)); __index++) #define mc_foreachhashmapKey(keyType, __key, __hashmap) \ keyType * __key; \ @@ -46,8 +47,60 @@ HashMapIterator __key##__value##__iterator = HashMapIteratorInit(__hashmap, true while (HashMapIteratorRun(&__key##__value##__iterator)) \ while (HashMapIteratorNext(&__key##__value##__iterator, (Object **) &__key, (Object **) &__value)) +#define mc_foreachindexset(__variable, __indexset) \ +int64_t __variable; \ +mailcore::IndexSetIterator __variable##__iterator = mailcore::IndexSetIteratorInit(__indexset); \ +for (; (__variable = IndexSetIteratorValue(&__variable##__iterator)), IndexSetIteratorIsValid(&__variable##__iterator) ; mailcore::IndexSetIteratorNext(&__variable##__iterator)) + namespace mailcore { + struct IndexSetIterator { + unsigned int rangeIndex; + unsigned int index; + Range * currentRange; + IndexSet * indexSet; + }; + + static inline IndexSetIterator IndexSetIteratorInit(IndexSet * indexSet) + { + IndexSetIterator iterator = { 0, 0, NULL, indexSet }; + if (indexSet->rangesCount() >= 1) { + iterator.currentRange = &indexSet->allRanges()[0]; + } + return iterator; + } + + static inline bool IndexSetIteratorIsValid(IndexSetIterator * iterator) + { + return iterator->currentRange != NULL; + } + + static inline int64_t IndexSetIteratorValue(IndexSetIterator * iterator) + { + return iterator->currentRange == NULL ? -1 : iterator->currentRange->location + iterator->index; + } + + static inline bool IndexSetIteratorNext(IndexSetIterator * iterator) + { + iterator->index ++; + if (iterator->index > iterator->currentRange->length) { + // switch to an other range + iterator->index = 0; + iterator->rangeIndex ++; + if (iterator->rangeIndex >= iterator->indexSet->rangesCount()) { + iterator->currentRange = NULL; + return false; + } + else { + iterator->currentRange = &iterator->indexSet->allRanges()[iterator->rangeIndex]; + return true; + } + } + else { + return true; + } + } + struct ArrayIterator { unsigned index; unsigned count; diff --git a/src/core/basetypes/MCLibetpan.cc b/src/core/basetypes/MCLibetpan.cc index fcc1b772..1779d605 100644 --- a/src/core/basetypes/MCLibetpan.cc +++ b/src/core/basetypes/MCLibetpan.cc @@ -10,9 +10,211 @@ #include <libetpan/libetpan.h> +using namespace mailcore; + +static time_t mkgmtime(struct tm * tmp); +static int tmcomp(struct tm * atmp, struct tm * btmp); + __attribute__((constructor)) static void initialize() { // It will enable CFStream on platforms that supports it. mailstream_cfstream_enabled = 1; } + +time_t mailcore::timestampFromDate(struct mailimf_date_time * date_time) +{ + struct tm tmval; + time_t timeval; + int zone_min; + int zone_hour; + + tmval.tm_sec = date_time->dt_sec; + tmval.tm_min = date_time->dt_min; + tmval.tm_hour = date_time->dt_hour; + tmval.tm_mday = date_time->dt_day; + tmval.tm_mon = date_time->dt_month - 1; + if (date_time->dt_year < 1000) { + // workaround when century is not given in year + tmval.tm_year = date_time->dt_year + 2000 - 1900; + } + else { + tmval.tm_year = date_time->dt_year - 1900; + } + + timeval = mkgmtime(&tmval); + + if (date_time->dt_zone >= 0) { + zone_hour = date_time->dt_zone / 100; + zone_min = date_time->dt_zone % 100; + } + else { + zone_hour = -((- date_time->dt_zone) / 100); + zone_min = -((- date_time->dt_zone) % 100); + } + timeval -= zone_hour * 3600 + zone_min * 60; + + return timeval; +} + +struct mailimf_date_time * mailcore::dateFromTimestamp(time_t timeval) +{ + struct tm gmt; + struct tm lt; + int off; + struct mailimf_date_time * date_time; + int sign; + int hour; + int min; + + gmtime_r(&timeval, &gmt); + localtime_r(&timeval, <); + + off = (int) ((mkgmtime(<) - mkgmtime(&gmt)) / 60); + if (off < 0) { + sign = -1; + } + else { + sign = 1; + } + off = off * sign; + min = off % 60; + hour = off / 60; + off = hour * 100 + min; + off = off * sign; + + date_time = mailimf_date_time_new(lt.tm_mday, lt.tm_mon + 1, + lt.tm_year + 1900, + lt.tm_hour, lt.tm_min, lt.tm_sec, + off); + + return date_time; +} + +struct mailimap_date_time * mailcore::imapDateFromTimestamp(time_t timeval) +{ + struct tm gmt; + struct tm lt; + int off; + struct mailimap_date_time * date_time; + int sign; + int hour; + int min; + + gmtime_r(&timeval, &gmt); + localtime_r(&timeval, <); + + off = (int) ((mkgmtime(<) - mkgmtime(&gmt)) / 60); + if (off < 0) { + sign = -1; + } + else { + sign = 1; + } + off = off * sign; + min = off % 60; + hour = off / 60; + off = hour * 100 + min; + off = off * sign; + + date_time = mailimap_date_time_new(lt.tm_mday, lt.tm_mon + 1, + lt.tm_year + 1900, + lt.tm_hour, lt.tm_min, lt.tm_sec, + off); + + return date_time; +} + +time_t mailcore::timestampFromIMAPDate(struct mailimap_date_time * date_time) +{ + struct tm tmval; + time_t timeval; + int zone_min; + int zone_hour; + + tmval.tm_sec = date_time->dt_sec; + tmval.tm_min = date_time->dt_min; + tmval.tm_hour = date_time->dt_hour; + tmval.tm_mday = date_time->dt_day; + tmval.tm_mon = date_time->dt_month - 1; + if (date_time->dt_year < 1000) { + // workaround when century is not given in year + tmval.tm_year = date_time->dt_year + 2000 - 1900; + } + else { + tmval.tm_year = date_time->dt_year - 1900; + } + + timeval = mkgmtime(&tmval); + + if (date_time->dt_zone >= 0) { + zone_hour = date_time->dt_zone / 100; + zone_min = date_time->dt_zone % 100; + } + else { + zone_hour = -((- date_time->dt_zone) / 100); + zone_min = -((- date_time->dt_zone) % 100); + } + timeval -= zone_hour * 3600 + zone_min * 60; + + return timeval; +} + +#define INVALID_TIMESTAMP (-1) + +static int tmcomp(struct tm * atmp, struct tm * btmp) +{ + int result; + + if ((result = (atmp->tm_year - btmp->tm_year)) == 0 && + (result = (atmp->tm_mon - btmp->tm_mon)) == 0 && + (result = (atmp->tm_mday - btmp->tm_mday)) == 0 && + (result = (atmp->tm_hour - btmp->tm_hour)) == 0 && + (result = (atmp->tm_min - btmp->tm_min)) == 0) + result = atmp->tm_sec - btmp->tm_sec; + return result; +} + +static time_t mkgmtime(struct tm * tmp) +{ + int dir; + int bits; + int saved_seconds; + time_t t; + struct tm yourtm, mytm; + + yourtm = *tmp; + saved_seconds = yourtm.tm_sec; + yourtm.tm_sec = 0; + /* + ** Calculate the number of magnitude bits in a time_t + ** (this works regardless of whether time_t is + ** signed or unsigned, though lint complains if unsigned). + */ + for (bits = 0, t = 1; t > 0; ++bits, t <<= 1) + ; + /* + ** If time_t is signed, then 0 is the median value, + ** if time_t is unsigned, then 1 << bits is median. + */ + if(bits > 40) bits = 40; + t = (t < 0) ? 0 : ((time_t) 1 << bits); + for ( ; ; ) { + gmtime_r(&t, &mytm); + dir = tmcomp(&mytm, &yourtm); + if (dir != 0) { + if (bits-- < 0) { + return INVALID_TIMESTAMP; + } + if (bits < 0) + --t; + else if (dir > 0) + t -= (time_t) 1 << bits; + else t += (time_t) 1 << bits; + continue; + } + break; + } + t += saved_seconds; + return t; +} diff --git a/src/core/basetypes/MCLibetpan.h b/src/core/basetypes/MCLibetpan.h index 9670a47b..41024137 100644 --- a/src/core/basetypes/MCLibetpan.h +++ b/src/core/basetypes/MCLibetpan.h @@ -10,6 +10,16 @@ #define MAILCORE_MCLIBETPAN_H -// No API in this file. +#include <time.h> +#include <libetpan/libetpan.h> + +namespace mailcore { + + time_t timestampFromDate(struct mailimf_date_time * date_time); + time_t timestampFromIMAPDate(struct mailimap_date_time * date_time); + struct mailimf_date_time * dateFromTimestamp(time_t timeval); + struct mailimap_date_time * imapDateFromTimestamp(time_t timeval); + +} #endif diff --git a/src/core/basetypes/MCObject.cc b/src/core/basetypes/MCObject.cc index 26b59e67..0e8d9639 100644 --- a/src/core/basetypes/MCObject.cc +++ b/src/core/basetypes/MCObject.cc @@ -5,7 +5,9 @@ #include <cxxabi.h> #include <libetpan/libetpan.h> #include <string.h> +#if __APPLE__ #include <Block.h> +#endif #include "MCAutoreleasePool.h" #include "MCString.h" @@ -367,7 +369,7 @@ void Object::cancelDelayedPerformMethod(Method method, void * context) #else initDelayedPerform(); - struct mainThreadCallData * data = getFromPerformHash(this, method, context, NULL); + struct mainThreadCallData * data = (struct mainThreadCallData *) getFromPerformHash(this, method, context, NULL); if (data == NULL) return; diff --git a/src/core/basetypes/MCOperation.cc b/src/core/basetypes/MCOperation.cc index 71b3c52f..51497cba 100644 --- a/src/core/basetypes/MCOperation.cc +++ b/src/core/basetypes/MCOperation.cc @@ -15,6 +15,11 @@ Operation::Operation() Operation::~Operation() { +#if __APPLE__ + if (mCallbackDispatchQueue != NULL) { + dispatch_release(mCallbackDispatchQueue); + } +#endif pthread_mutex_destroy(&mLock); } @@ -73,7 +78,13 @@ void Operation::start() #if __APPLE__ void Operation::setCallbackDispatchQueue(dispatch_queue_t callbackDispatchQueue) { + if (mCallbackDispatchQueue != NULL) { + dispatch_release(mCallbackDispatchQueue); + } mCallbackDispatchQueue = callbackDispatchQueue; + if (mCallbackDispatchQueue != NULL) { + dispatch_retain(mCallbackDispatchQueue); + } } dispatch_queue_t Operation::callbackDispatchQueue() diff --git a/src/core/basetypes/MCOperationQueue.cc b/src/core/basetypes/MCOperationQueue.cc index 73b62f19..e45f04ee 100644 --- a/src/core/basetypes/MCOperationQueue.cc +++ b/src/core/basetypes/MCOperationQueue.cc @@ -28,10 +28,16 @@ OperationQueue::OperationQueue() #if __APPLE__ mDispatchQueue = dispatch_get_main_queue(); #endif + _pendingCheckRunning = false; } OperationQueue::~OperationQueue() { +#if __APPLE__ + if (mDispatchQueue != NULL) { + dispatch_release(mDispatchQueue); + } +#endif MC_SAFE_RELEASE(mOperations); pthread_mutex_destroy(&mLock); mailsem_free(mOperationSem); @@ -49,6 +55,16 @@ void OperationQueue::addOperation(Operation * op) startThread(); } +void OperationQueue::cancelAllOperations() +{ + pthread_mutex_lock(&mLock); + for (unsigned int i = 0 ; i < mOperations->count() ; i ++) { + Operation * op = (Operation *) mOperations->objectAtIndex(i); + op->cancel(); + } + pthread_mutex_unlock(&mLock); +} + void OperationQueue::runOperationsOnThread(OperationQueue * queue) { queue->runOperations(); @@ -115,7 +131,7 @@ void OperationQueue::runOperations() if (needsCheckRunning) { retain(); // (1) - MCLog("check running %p", this); + //MCLog("check running %p", this); #if __APPLE__ performMethodOnDispatchQueue((Object::Method) &OperationQueue::checkRunningOnMainThread, this, mDispatchQueue); #else @@ -160,12 +176,19 @@ void OperationQueue::callbackOnMainThread(Operation * op) void OperationQueue::checkRunningOnMainThread(void * context) { - cancelDelayedPerformMethod((Object::Method) &OperationQueue::checkRunningAfterDelay, NULL); + retain(); // (4) + if (_pendingCheckRunning) { + cancelDelayedPerformMethod((Object::Method) &OperationQueue::checkRunningAfterDelay, NULL); + release(); // (4) + } + _pendingCheckRunning = true; performMethodAfterDelay((Object::Method) &OperationQueue::checkRunningAfterDelay, NULL, 1); + release(); // (1) } void OperationQueue::checkRunningAfterDelay(void * context) { + _pendingCheckRunning = false; pthread_mutex_lock(&mLock); if (!mQuitting) { if (mOperations->count() == 0) { @@ -179,7 +202,7 @@ void OperationQueue::checkRunningAfterDelay(void * context) // Number of operations can't be changed because it runs on main thread. // And addOperation() should also be called from main thread. - release(); // (1) + release(); // (4) } void OperationQueue::stoppedOnMainThread(void * context) @@ -256,7 +279,13 @@ void OperationQueue::waitUntilAllOperationsAreFinished() #if __APPLE__ void OperationQueue::setDispatchQueue(dispatch_queue_t dispatchQueue) { + if (mDispatchQueue != NULL) { + dispatch_release(mDispatchQueue); + } mDispatchQueue = dispatchQueue; + if (mDispatchQueue != NULL) { + dispatch_retain(mDispatchQueue); + } } dispatch_queue_t OperationQueue::dispatchQueue() diff --git a/src/core/basetypes/MCOperationQueue.h b/src/core/basetypes/MCOperationQueue.h index 202dec40..119befcc 100644 --- a/src/core/basetypes/MCOperationQueue.h +++ b/src/core/basetypes/MCOperationQueue.h @@ -21,6 +21,7 @@ namespace mailcore { virtual ~OperationQueue(); virtual void addOperation(Operation * op); + virtual void cancelAllOperations(); virtual unsigned int count(); @@ -47,6 +48,7 @@ namespace mailcore { #if __APPLE__ dispatch_queue_t mDispatchQueue; #endif + bool _pendingCheckRunning; void startThread(); static void runOperationsOnThread(OperationQueue * queue); diff --git a/src/core/basetypes/MCSet.cc b/src/core/basetypes/MCSet.cc index ad615388..ceccbdcc 100644 --- a/src/core/basetypes/MCSet.cc +++ b/src/core/basetypes/MCSet.cc @@ -45,7 +45,7 @@ Set * Set::setWithArray(Array * objects) String * Set::description() { String * result = String::string(); - result->appendUTF8Format("<%s:%p ", className(), this); + result->appendUTF8Format("<%s:%p ", MCUTF8(className()), this); result->appendString(mHash->allKeys()->description()); result->appendUTF8Characters(">"); return result; diff --git a/src/core/basetypes/MCString.cc b/src/core/basetypes/MCString.cc index 054cbb80..5c2da323 100644 --- a/src/core/basetypes/MCString.cc +++ b/src/core/basetypes/MCString.cc @@ -761,6 +761,9 @@ String * String::string() String * String::stringWithData(Data * data, const char * charset) { + if (data == NULL) { + return String::string(); + } String * result = NULL; result = new String(data->bytes(), data->length(), charset); result->autorelease(); @@ -807,6 +810,9 @@ String * String::stringWithCharacters(const UChar * characters, unsigned int len void String::appendCharactersLength(const UChar * unicodeCharacters, unsigned int length) { + if (unicodeCharacters == NULL) { + return; + } allocate(mLength + length); u_strncpy(&mUnicodeChars[mLength], unicodeCharacters, length); mLength += length; @@ -815,6 +821,9 @@ void String::appendCharactersLength(const UChar * unicodeCharacters, unsigned in void String::appendString(String * otherString) { + if (otherString == NULL) { + return; + } appendCharactersLength(otherString->unicodeCharacters(), otherString->length()); } @@ -831,8 +840,9 @@ void String::appendUTF8Format(const char * format, ...) void String::appendUTF8CharactersLength(const char * UTF8Characters, unsigned int length) { - if (UTF8Characters == NULL) + if (UTF8Characters == NULL) { return; + } UChar * dest; int32_t destLength; @@ -1124,6 +1134,10 @@ String * String::uppercaseString() void String::appendBytes(const char * bytes, unsigned int length, const char * charset) { + if (bytes == NULL) { + return; + } + #if __APPLE__ CFStringEncoding encoding; if (strcasecmp(charset, "mutf-7") == 0) { @@ -1138,7 +1152,16 @@ void String::appendBytes(const char * bytes, unsigned int length, const char * c if (cfStr != NULL) { CFDataRef data = CFStringCreateExternalRepresentation(NULL, cfStr, kCFStringEncodingUTF16LE, '_'); if (data != NULL) { - appendCharactersLength((const UChar *) CFDataGetBytePtr(data), (unsigned int) CFDataGetLength(data) / 2); + UChar * fixedData = (UChar *) malloc(CFDataGetLength(data)); + memcpy(fixedData, CFDataGetBytePtr(data), CFDataGetLength(data)); + unsigned int length = (unsigned int) CFDataGetLength(data) / 2; + for(int32_t i = 0 ; i < length ; i ++) { + if (fixedData[i] == 0) { + fixedData[i] = ' '; + } + } + appendCharactersLength(fixedData, length); + free(fixedData); CFRelease(data); } CFRelease(cfStr); @@ -1269,7 +1292,10 @@ void String::deleteCharactersInRange(Range range) if (range.location > mLength) return; - if (range.location + range.length > mLength) { + if (range.length > mLength) { + range.length = mLength - range.location; + } + else if (range.location + range.length > mLength) { range.length = mLength - range.location; } @@ -1795,6 +1821,24 @@ String * String::flattenHTML() return flattenHTMLAndShowBlockquote(true); } +String * String::stripWhitespace() +{ + String *str = (String *)copy(); + + str->replaceOccurrencesOfString(MCSTR("\t"), MCSTR(" ")); + str->replaceOccurrencesOfString(MCSTR("\n"), MCSTR(" ")); + str->replaceOccurrencesOfString(MCSTR("\v"), MCSTR(" ")); + str->replaceOccurrencesOfString(MCSTR("\f"), MCSTR(" ")); + str->replaceOccurrencesOfString(MCSTR("\r"), MCSTR(" ")); + + while (str->replaceOccurrencesOfString(MCSTR(" "), MCSTR(" ")) > 0) { + /* do nothing */ + } + + return str; +} + + bool String::hasSuffix(String * suffix) { if (mLength >= suffix->mLength) { @@ -2187,9 +2231,9 @@ String * String::htmlMessageContent() } } - if (quoted != nil) { + if (quoted != NULL) { localString->appendString(MCSTR("<blockquote type=\"cite\">")); - localString->appendString(quoted); + localString->appendString(quoted->htmlMessageContent()); localString->appendString(MCSTR("</blockquote>")); MC_SAFE_RELEASE(quoted); } diff --git a/src/core/basetypes/MCString.h b/src/core/basetypes/MCString.h index 7fd07570..25439cf2 100644 --- a/src/core/basetypes/MCString.h +++ b/src/core/basetypes/MCString.h @@ -86,6 +86,8 @@ namespace mailcore { virtual String * flattenHTMLAndShowBlockquote(bool showBlockquote); virtual String * flattenHTMLAndShowBlockquoteAndLink(bool showBlockquote, bool showLink); + virtual String * stripWhitespace(); + virtual String * lastPathComponent(); virtual String * pathExtension(); virtual Data * dataUsingEncoding(const char * charset = NULL); diff --git a/src/core/basetypes/MCUtils.h b/src/core/basetypes/MCUtils.h index e1bef841..ad9c4db5 100644 --- a/src/core/basetypes/MCUtils.h +++ b/src/core/basetypes/MCUtils.h @@ -29,7 +29,7 @@ #define MCSTR(str) mailcore::String::uniquedStringWithUTF8Characters("" str "") -#define MCUTF8(str) ((str) != NULL ? (str)->UTF8Characters() : NULL ) +#define MCUTF8(str) MCUTF8DESC(str) #define MCUTF8DESC(obj) ((obj) != NULL ? (obj)->description()->UTF8Characters() : NULL ) #define MCLOCALIZEDSTRING(key) key |