diff options
Diffstat (limited to 'src/core/basetypes')
-rw-r--r-- | src/core/basetypes/MCAssert.c | 2 | ||||
-rw-r--r-- | src/core/basetypes/MCBaseTypes.h | 1 | ||||
-rw-r--r-- | src/core/basetypes/MCData.cpp | 14 | ||||
-rw-r--r-- | src/core/basetypes/MCData.h | 2 | ||||
-rw-r--r-- | src/core/basetypes/MCHTMLCleaner.h | 4 | ||||
-rw-r--r-- | src/core/basetypes/MCHashMap.cpp | 4 | ||||
-rw-r--r-- | src/core/basetypes/MCIndexSet.cpp | 64 | ||||
-rw-r--r-- | src/core/basetypes/MCIndexSet.h | 3 | ||||
-rw-r--r-- | src/core/basetypes/MCJSONParser.cpp | 6 | ||||
-rw-r--r-- | src/core/basetypes/MCLog.cpp | 8 | ||||
-rw-r--r-- | src/core/basetypes/MCObject.cpp | 7 | ||||
-rw-r--r-- | src/core/basetypes/MCString.cpp | 212 | ||||
-rw-r--r-- | src/core/basetypes/MCString.h | 3 | ||||
-rw-r--r-- | src/core/basetypes/MCUtils.h | 18 | ||||
-rw-r--r-- | src/core/basetypes/icu-ucsdet/cstring.c | 2 | ||||
-rw-r--r-- | src/core/basetypes/icu-ucsdet/uinvchar.c | 4 | ||||
-rw-r--r-- | src/core/basetypes/icu-ucsdet/ustring.cpp | 2 |
17 files changed, 322 insertions, 34 deletions
diff --git a/src/core/basetypes/MCAssert.c b/src/core/basetypes/MCAssert.c index ce9b5703..564f1648 100644 --- a/src/core/basetypes/MCAssert.c +++ b/src/core/basetypes/MCAssert.c @@ -9,6 +9,6 @@ void MCAssertInternal(const char * filename, unsigned int line, int cond, const return; } - fprintf(stderr, "%s:%i: assert %s\n", filename, line, condString); + fprintf(stderr, "%s:%u: assert %s\n", filename, line, condString); abort(); } diff --git a/src/core/basetypes/MCBaseTypes.h b/src/core/basetypes/MCBaseTypes.h index ce3e1153..3088d4c2 100644 --- a/src/core/basetypes/MCBaseTypes.h +++ b/src/core/basetypes/MCBaseTypes.h @@ -26,5 +26,6 @@ #include <MailCore/MCICUTypes.h> #include <MailCore/MCIterator.h> #include <MailCore/MCConnectionLogger.h> +#include <MailCore/MCHTMLCleaner.h> #endif diff --git a/src/core/basetypes/MCData.cpp b/src/core/basetypes/MCData.cpp index 8b689036..079344da 100644 --- a/src/core/basetypes/MCData.cpp +++ b/src/core/basetypes/MCData.cpp @@ -718,6 +718,20 @@ void Data::importSerializable(HashMap * serializable) setData(((String *) (serializable->objectForKey(MCSTR("data"))))->decodedBase64Data()); } +ErrorCode Data::writeToFile(String * filename) +{ + FILE * f = fopen(filename->fileSystemRepresentation(), "wb"); + if (f == NULL) { + return ErrorFile; + } + size_t result = fwrite(bytes(), length(), 1, f); + fclose(f); + if (result == 0) { + return ErrorFile; + } + return ErrorNone; +} + #if __APPLE__ static CFStringEncoding encodingFromCString(const char * charset) { diff --git a/src/core/basetypes/MCData.h b/src/core/basetypes/MCData.h index bec75008..0bb1bc07 100644 --- a/src/core/basetypes/MCData.h +++ b/src/core/basetypes/MCData.h @@ -44,6 +44,8 @@ namespace mailcore { virtual Data * decodedDataUsingEncoding(Encoding encoding); virtual String * base64String(); + + virtual ErrorCode writeToFile(String * filename); public: // private virtual String * charsetWithFilteredHTML(bool filterHTML, String * hintCharset = NULL); diff --git a/src/core/basetypes/MCHTMLCleaner.h b/src/core/basetypes/MCHTMLCleaner.h index 33e65767..eccf88c9 100644 --- a/src/core/basetypes/MCHTMLCleaner.h +++ b/src/core/basetypes/MCHTMLCleaner.h @@ -13,6 +13,8 @@ #include <MailCore/MCString.h> #include <MailCore/MCUtils.h> +#ifdef __cplusplus + namespace mailcore { class MAILCORE_EXPORT HTMLCleaner { @@ -23,3 +25,5 @@ namespace mailcore { } #endif + +#endif diff --git a/src/core/basetypes/MCHashMap.cpp b/src/core/basetypes/MCHashMap.cpp index c56277fc..9958c502 100644 --- a/src/core/basetypes/MCHashMap.cpp +++ b/src/core/basetypes/MCHashMap.cpp @@ -169,6 +169,10 @@ void HashMap::removeObjectForKey(Object * key) { unsigned int func, indx; HashMapIter * iter, * old; + + if (key == NULL) { + return; + } func = key->hash();; indx = func % mAllocated; diff --git a/src/core/basetypes/MCIndexSet.cpp b/src/core/basetypes/MCIndexSet.cpp index 7f7e1db3..191a1588 100644 --- a/src/core/basetypes/MCIndexSet.cpp +++ b/src/core/basetypes/MCIndexSet.cpp @@ -398,6 +398,21 @@ void IndexSet::importSerializable(HashMap * serializable) } } +bool IndexSet::isEqual(Object * otherObject) +{ + IndexSet * otherIndexSet = (IndexSet *) otherObject; + if (mCount != otherIndexSet->mCount) { + return false; + } + for(unsigned int i = 0 ; i < mCount ; i ++) { + if ((mRanges[i].location != otherIndexSet->mRanges[i].location) || + (mRanges[i].length != otherIndexSet->mRanges[i].length)) { + return false; + } + } + return true; +} + void IndexSet::addIndexSet(IndexSet * indexSet) { for(unsigned int i = 0 ; i < indexSet->rangesCount() ; i ++) { @@ -435,3 +450,52 @@ INITIALIZE(IndexSet) { Object::registerObjectConstructor("mailcore::IndexSet", &createObject); } + +/* + +Unit test: + +String * uidsStr = MCSTR("129597-129662,129664,129667-129671,129673-129674,129678-129694,129696-129804"); +String * cachedUidsStr = MCSTR("129755-129804"); +IndexSet * uids = NULL; +IndexSet * cachedUids = NULL; + +{ + IndexSet * result = new IndexSet(); + Array * array = uidsStr->componentsSeparatedByString(MCSTR(",")); + mc_foreacharray(String, rangeStr, array) { + Array * rangeArray = rangeStr->componentsSeparatedByString(MCSTR("-")); + if (rangeArray->count() == 2) { + int left = ((String *) rangeArray->objectAtIndex(0))->intValue(); + int right = ((String *) rangeArray->objectAtIndex(1))->intValue(); + int length = right - left; + result->addRange(RangeMake(left, length)); + } + else { + result->addIndex(rangeStr->intValue()); + } + } + //fprintf(stderr, "%s\n", MCUTF8DESC(result)); + uids = result; +} +{ + IndexSet * result = new IndexSet(); + Array * array = cachedUidsStr->componentsSeparatedByString(MCSTR(",")); + mc_foreacharray(String, rangeStr, array) { + Array * rangeArray = rangeStr->componentsSeparatedByString(MCSTR("-")); + if (rangeArray->count() == 2) { + int left = ((String *) rangeArray->objectAtIndex(0))->intValue(); + int right = ((String *) rangeArray->objectAtIndex(1))->intValue(); + int length = right - left; + result->addRange(RangeMake(left, length)); + } + else { + result->addIndex(rangeStr->intValue()); + } + } + cachedUids = result; +} +fprintf(stderr, "|%s|\n", MCUTF8DESC(uids)); +uids->removeIndexSet(cachedUids); +fprintf(stderr, "|%s|\n", MCUTF8DESC(uids)); +*/ diff --git a/src/core/basetypes/MCIndexSet.h b/src/core/basetypes/MCIndexSet.h index 2e2f4892..2cf67b07 100644 --- a/src/core/basetypes/MCIndexSet.h +++ b/src/core/basetypes/MCIndexSet.h @@ -50,7 +50,8 @@ namespace mailcore { virtual Object * copy(); virtual HashMap * serializable(); virtual void importSerializable(HashMap * serializable); - + virtual bool isEqual(Object * otherObject); + private: Range * mRanges; unsigned int mCount; diff --git a/src/core/basetypes/MCJSONParser.cpp b/src/core/basetypes/MCJSONParser.cpp index d9f68204..cfddbf9e 100644 --- a/src/core/basetypes/MCJSONParser.cpp +++ b/src/core/basetypes/MCJSONParser.cpp @@ -587,7 +587,7 @@ bool JSONParser::parseFloat() } else { mPosition += endptr - str; - mResult = Value::valueWithDoubleValue(value); + mResult = Value::valueWithDoubleValue(value)->retain(); } pool->release(); @@ -617,7 +617,9 @@ Object * JSONParser::objectFromString(String * str) parser->setContent(str); parser->parse(); result = parser->result(); - result->retain()->autorelease(); + if (result != NULL) { + result->retain()->autorelease(); + } parser->release(); return result; diff --git a/src/core/basetypes/MCLog.cpp b/src/core/basetypes/MCLog.cpp index 952229ec..386ac422 100644 --- a/src/core/basetypes/MCLog.cpp +++ b/src/core/basetypes/MCLog.cpp @@ -53,9 +53,7 @@ static void logInternalv(FILE * file, return; while (1) { - const char * p = filename; - - p = strchr(filename, '/'); + const char * p = strchr(filename, '/'); if (p == NULL) { break; } @@ -80,7 +78,7 @@ static void logInternalv(FILE * file, #else if (0) { #endif - fprintf(file, "[%i:main] %s:%i: ", sPid, filename, line); + fprintf(file, "[%i:main] %s:%u: ", sPid, filename, line); } else { unsigned long threadValue; @@ -91,7 +89,7 @@ static void logInternalv(FILE * file, #else threadValue = (unsigned long) thread_id; #endif - fprintf(file, "[%i:%lx] %s:%i: ", sPid, threadValue, filename, line); + fprintf(file, "[%i:%lx] %s:%u: ", sPid, threadValue, filename, line); } vfprintf(file, format, argp); fprintf(file, "\n"); diff --git a/src/core/basetypes/MCObject.cpp b/src/core/basetypes/MCObject.cpp index bbcddb2f..6f776ef6 100644 --- a/src/core/basetypes/MCObject.cpp +++ b/src/core/basetypes/MCObject.cpp @@ -181,7 +181,7 @@ static void removeFromPerformHash(Object * obj, Object::Method method, void * co keyData.method = method; key.data = &keyData; key.len = sizeof(keyData); - + pthread_mutex_lock(&delayedPerformLock); chash_delete(delayedPerformHash, (chashdatum *) &key, NULL); pthread_mutex_unlock(&delayedPerformLock); @@ -360,7 +360,9 @@ void Object::performMethodOnDispatchQueueAfterDelay(Method method, void * contex } dupCancelableBlock(false); Block_release(dupCancelableBlock); - release(); + if (!cancelled) { + release(); + } }); } @@ -373,6 +375,7 @@ void Object::cancelDelayedPerformMethodOnDispatchQueue(Method method, void * con } removeFromPerformHash(this, method, context, targetDispatchQueue); dupCancelableBlock(true); + release(); } #endif diff --git a/src/core/basetypes/MCString.cpp b/src/core/basetypes/MCString.cpp index 213d5e5f..9c024067 100644 --- a/src/core/basetypes/MCString.cpp +++ b/src/core/basetypes/MCString.cpp @@ -823,7 +823,9 @@ String::String(const char * UTF8Characters) { mUnicodeChars = NULL; reset(); - allocate((unsigned int) strlen(UTF8Characters), true); + if (UTF8Characters != NULL) { + allocate((unsigned int) strlen(UTF8Characters), true); + } appendUTF8Characters(UTF8Characters); } @@ -890,7 +892,7 @@ void String::allocate(unsigned int length, bool force) String * String::string() { - return stringWithCharacters(NULL); + return stringWithCharacters(NULL, 0); } String * String::stringWithData(Data * data, const char * charset) @@ -926,12 +928,18 @@ String * String::stringWithVUTF8Format(const char * format, va_list ap) String * String::stringWithUTF8Characters(const char * UTF8Characters) { + if (UTF8Characters == NULL) { + return NULL; + } String * result = new String(UTF8Characters); return (String *) result->autorelease(); } String * String::stringWithCharacters(const UChar * characters) { + if (characters == NULL) { + return NULL; + } String * result = new String(characters); return (String *) result->autorelease(); } @@ -1194,6 +1202,9 @@ Data * String::encodedMIMEHeaderValueForSubject() int String::compareWithCaseSensitive(String * otherString, bool caseSensitive) { + if (otherString == NULL) { + return 1; + } if ((length() == 0) && (otherString->length() == 0)) { return 0; } @@ -1206,7 +1217,7 @@ int String::compareWithCaseSensitive(String * otherString, bool caseSensitive) } if (otherString->unicodeCharacters() == NULL) { - return -1; + return 1; } #if DISABLE_ICU @@ -2034,25 +2045,69 @@ String * String::flattenHTML() 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(" ")); - str->replaceOccurrencesOfString(s_unicode160, MCSTR(" ")); - str->replaceOccurrencesOfString(s_unicode133, MCSTR(" ")); - str->replaceOccurrencesOfString(s_unicode2028, MCSTR(" ")); + String * str = (String *)copy(); - while (str->replaceOccurrencesOfString(MCSTR(" "), MCSTR(" ")) > 0) { - /* do nothing */ + // replace space-like characters with space. + const UChar * source = str->unicodeCharacters(); + UChar * dest = str->mUnicodeChars; + while (* source != 0) { + if (* source == '\t') { + * dest = ' '; + } + else if (* source == '\n') { + * dest = ' '; + } + else if (* source == '\t') { + * dest = ' '; + } + else if (* source == '\f') { + * dest = ' '; + } + else if (* source == '\r') { + * dest = ' '; + } + else if (* source == 160) { + * dest = ' '; + } + else if (* source == 133) { + * dest = ' '; + } + else if (* source == 0x2028) { + * dest = ' '; + } + else { + * dest = * source; + } + dest ++; + source ++; } - while (str->hasPrefix(MCSTR(" "))) { - str->deleteCharactersInRange(RangeMake(0, 1)); + + // skip spaces at the beginning. + source = str->unicodeCharacters(); + dest = str->mUnicodeChars; + while (* source == ' ') { + source ++; } - while (str->hasSuffix(MCSTR(" "))) { - str->deleteCharactersInRange(RangeMake(str->length() - 1, 1)); + + // copy content + while (* source != 0) { + if ((* source == ' ') && (* (source + 1) == ' ')) { + source ++; + } + * dest = * source; + source ++; + dest ++; + } + * dest = 0; + str->mLength = (unsigned int) (dest - str->mUnicodeChars); + + // skip spaces at the end. + if (str->mLength > 0) { + while (* (dest - 1) == ' ') { + dest --; + } + * dest = 0; + str->mLength = (unsigned int) (dest - str->mUnicodeChars); } str->autorelease(); @@ -2241,10 +2296,29 @@ Array * String::componentsSeparatedByString(String * separator) p = mUnicodeChars; while (1) { UChar * location; +#if 0 location = u_strstr(p, separator->unicodeCharacters()); if (location == NULL) { break; } +#else + int remaining = length() - (int) (p - mUnicodeChars); + location = NULL; + while (location == NULL) { + location = (UChar *) memmem(p, remaining * sizeof(UChar), separator->unicodeCharacters(), separator->length() * sizeof(UChar)); + if (location == NULL) { + break; + } + // If it's odd, it's an invalid location. Keep looking for the pattern. + if (((char *) location - (char *) p) % sizeof(UChar) != 0) { + p = (UChar *) (((char *) location) + 1); + location = NULL; + } + } + if (location == NULL) { + break; + } +#endif unsigned int length = (unsigned int) (location - p); String * value = new String(p, length); @@ -2357,6 +2431,10 @@ String * String::uniquedStringWithUTF8Characters(const char * UTF8Characters) static pthread_once_t once = PTHREAD_ONCE_INIT; int r; + if (UTF8Characters == NULL) { + return NULL; + } + pthread_once(&once, initUniquedStringHash); key.data = (void *) UTF8Characters; key.len = (unsigned int) strlen(UTF8Characters); @@ -2512,6 +2590,102 @@ Data * String::decodedBase64Data() return result; } +static int hexValue(const char * code) { + int value = 0; + const char * pch = code; + for (;;) { + int digit = *pch++; + if (digit >= '0' && digit <= '9') { + value += digit - '0'; + } + else if (digit >= 'A' && digit <= 'F') { + value += digit - 'A' + 10; + } + else if (digit >= 'a' && digit <= 'f') { + value += digit - 'a' + 10; + } + else { + return -1; + } + if (pch == code + 2) { + return value; + } + value <<= 4; + } +} + +String * String::urlDecodedString() +{ + Data * sourceData = dataUsingEncoding(); + const char * source = sourceData->bytes(); + char * start = (char *) malloc(sourceData->length() + 1); + char * dest = start; + unsigned int i = 0; + while (i < sourceData->length()) { + switch (source[i]) { + case '%': + { + if (i + 2 < sourceData->length()) { + int value = hexValue(&source[i + 1]); + if (value >= 0) { + *(dest++) = value; + i += 3; + } + else { + *dest++ = '?'; + i ++; + } + } + else { + *dest++ = '?'; + i ++; + } + break; + } + default: + { + *dest++ = source[i]; + i ++; + break; + } + } + } + * dest = 0; + String * result = String::stringWithUTF8Characters(start); + free(start); + return result; +} + +static inline bool isValidUrlChar(char ch) { + return strchr("$&+,/:;=?@[]#!'()* ", ch) == NULL; +} + +String * String::urlEncodedString() +{ + const char * digits = "0123456789ABCDEF"; + Data * sourceData = dataUsingEncoding(); + const char * source = sourceData->bytes(); + char * start = (char *) malloc(sourceData->length() * 3 + 1); + char * dest = start; + unsigned int i = 0; + while (i < sourceData->length()) { + unsigned char ch = (unsigned char) source[i]; + if (isValidUrlChar(ch)) { + *dest++ = ch; + } else { + *dest++ = '%'; + *dest++ = digits[(ch >> 4) & 0x0F]; + *dest++ = digits[ ch & 0x0F]; + } + i ++; + } + *dest = 0; + String * result = String::stringWithUTF8Characters(dest); + free(start); + + return result; +} + HashMap * String::serializable() { HashMap * result = Object::serializable(); diff --git a/src/core/basetypes/MCString.h b/src/core/basetypes/MCString.h index cbe5538b..5ee2ad65 100644 --- a/src/core/basetypes/MCString.h +++ b/src/core/basetypes/MCString.h @@ -117,6 +117,9 @@ namespace mailcore { virtual Data * decodedBase64Data(); + virtual String * urlDecodedString(); + virtual String * urlEncodedString(); + public: // private static String * uniquedStringWithUTF8Characters(const char * UTF8Characters); diff --git a/src/core/basetypes/MCUtils.h b/src/core/basetypes/MCUtils.h index eb4ef290..ef8f3cd3 100644 --- a/src/core/basetypes/MCUtils.h +++ b/src/core/basetypes/MCUtils.h @@ -48,6 +48,20 @@ # define MAILCORE_EXPORT #endif +#ifdef __ANDROID_API__ +#if __ANDROID_API__ < 21 +#include <wchar.h> +extern int iswblank(wint_t); +extern int vfwscanf(FILE*, const wchar_t*, va_list); +extern int vswscanf(const wchar_t*, const wchar_t*, va_list); +extern int vwscanf(const wchar_t*, va_list); +extern float wcstof(const wchar_t*, wchar_t**); +extern long double wcstold(const wchar_t*, wchar_t**); +extern long long wcstoll(const wchar_t*, wchar_t**, int); +extern unsigned long long wcstoull(const wchar_t*, wchar_t**, int); +#endif +#endif + #ifdef __clang__ #if __has_feature(attribute_analyzer_noreturn) @@ -65,4 +79,8 @@ #endif +#ifndef DEPRECATED_ATTRIBUTE +#define DEPRECATED_ATTRIBUTE __attribute__((deprecated)) +#endif + #endif diff --git a/src/core/basetypes/icu-ucsdet/cstring.c b/src/core/basetypes/icu-ucsdet/cstring.c index 3af959eb..868ee5c0 100644 --- a/src/core/basetypes/icu-ucsdet/cstring.c +++ b/src/core/basetypes/icu-ucsdet/cstring.c @@ -225,7 +225,7 @@ U_CAPI int32_t U_EXPORT2 T_CString_stringToInteger(const char *integerString, int32_t radix) { char *end; - return uprv_strtoul(integerString, &end, radix); + return (int32_t)uprv_strtoul(integerString, &end, radix); } diff --git a/src/core/basetypes/icu-ucsdet/uinvchar.c b/src/core/basetypes/icu-ucsdet/uinvchar.c index f874edd9..81f73d80 100644 --- a/src/core/basetypes/icu-ucsdet/uinvchar.c +++ b/src/core/basetypes/icu-ucsdet/uinvchar.c @@ -569,7 +569,7 @@ uprv_aestrncpy(uint8_t *dst, const uint8_t *src, int32_t n) uint8_t *orig_dst = dst; if(n==-1) { - n = uprv_strlen((const char*)src)+1; /* copy NUL */ + n = (int32_t)uprv_strlen((const char*)src)+1; /* copy NUL */ } /* copy non-null */ while(*src && n>0) { @@ -590,7 +590,7 @@ uprv_eastrncpy(uint8_t *dst, const uint8_t *src, int32_t n) uint8_t *orig_dst = dst; if(n==-1) { - n = uprv_strlen((const char*)src)+1; /* copy NUL */ + n = (int32_t)uprv_strlen((const char*)src)+1; /* copy NUL */ } /* copy non-null */ while(*src && n>0) { diff --git a/src/core/basetypes/icu-ucsdet/ustring.cpp b/src/core/basetypes/icu-ucsdet/ustring.cpp index 40d23c06..d5d748fc 100644 --- a/src/core/basetypes/icu-ucsdet/ustring.cpp +++ b/src/core/basetypes/icu-ucsdet/ustring.cpp @@ -997,7 +997,7 @@ u_strlen(const UChar *s) while(*t != 0) { ++t; } - return t - s; + return (int32_t)(t - s); #endif } |