aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/basetypes
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/basetypes')
-rw-r--r--src/core/basetypes/MCAssert.c2
-rw-r--r--src/core/basetypes/MCBaseTypes.h1
-rw-r--r--src/core/basetypes/MCData.cpp14
-rw-r--r--src/core/basetypes/MCData.h2
-rw-r--r--src/core/basetypes/MCHTMLCleaner.h4
-rw-r--r--src/core/basetypes/MCHashMap.cpp4
-rw-r--r--src/core/basetypes/MCIndexSet.cpp64
-rw-r--r--src/core/basetypes/MCIndexSet.h3
-rw-r--r--src/core/basetypes/MCJSONParser.cpp6
-rw-r--r--src/core/basetypes/MCLog.cpp8
-rw-r--r--src/core/basetypes/MCObject.cpp7
-rw-r--r--src/core/basetypes/MCString.cpp212
-rw-r--r--src/core/basetypes/MCString.h3
-rw-r--r--src/core/basetypes/MCUtils.h18
-rw-r--r--src/core/basetypes/icu-ucsdet/cstring.c2
-rw-r--r--src/core/basetypes/icu-ucsdet/uinvchar.c4
-rw-r--r--src/core/basetypes/icu-ucsdet/ustring.cpp2
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
}