}
- (NSDictionary *)select:(NSString *)_folder {
+ /*
+ Select a folder (required for a lot of methods).
+ eg: 'SELECT "INBOX"'
+
+ The result dict contains the following keys:
+ 'result' - a boolean
+ 'access' - string (eg "READ-WRITE")
+ 'exists' - number? (eg 1)
+ 'recent' - number? (eg 0)
+ 'expunge' - array (of what?)
+ 'flags' - array of strings (eg (answered,flagged,draft,seen);
+ 'RawResponse' - the raw IMAP4 response
+ */
NSString *s;
id tmp;
}
- (NSString *)_searchExprForQual:(EOQualifier *)_qualifier {
+ /*
+ samples:
+ ' ALL'
+ ' SINCE 1-Feb-1994'
+ ' TEXT "why SOPE rocks"'
+ */
id result;
if (_qualifier == nil)
return result;
}
-/* siehe draft-ietf-imapext-thread-12.txt
- returns an array of uids in sort order */
-
- (NSDictionary *)threadBySubject:(BOOL)_bySubject
charset:(NSString *)_charSet
{
- NSString *threadStr;
- NSString *threadAlg;
+ /*
+ http://www.ietf.org/proceedings/03mar/I-D/draft-ietf-imapext-thread-12.txt
- if (_bySubject)
- threadAlg = @"REFERENCES";
- else
- threadAlg = @"ORDEREDSUBJECT";
+ Returns an array of uids in sort order.
+
+ Parameters:
+ _bySubject - if yes, use "REFERENCES" else "ORDEREDSUBJECT" (TODO: ?!)
+ _charSet - default: "UTF-8"
+ Generates:
+ UID THREAD REFERENCES|ORDEREDSUBJECT UTF-8 ALL
+ */
+ NSString *threadStr;
+ NSString *threadAlg;
+
+ threadAlg = (_bySubject)
+ ? @"REFERENCES"
+ : @"ORDEREDSUBJECT";
- if (![_charSet length])
+ if ([_charSet length] == 0)
_charSet = @"UTF-8";
-
+
threadStr = [NSString stringWithFormat:@"UID THREAD %@ %@ ALL",
threadAlg, _charSet];
-
+
return [self->normer normalizeThreadResponse:
[self processCommand:threadStr]];
}
-- (NSDictionary *)sort:(NSArray *)_sortOrderings
- qualifier:(EOQualifier *)_qual
-{
- /* siehe draft-ietf-imapext-sort */
- /* returns an array of uids in sort order */
+- (NSString *)_generateIMAP4SortOrdering:(EOSortOrdering *)_sortOrdering {
+ SEL sel;
+ NSString *key;
+
+ key = [_sortOrdering key];
+ if ([key length] == 0)
+ return nil;
+
+ if (![AllowedSortKeys containsObject:[key uppercaseString]]) {
+ [self logWithFormat:@"ERROR[%s] key %@ is not allowed here!",
+ __PRETTY_FUNCTION__, key];
+ return nil;
+ }
+
+ sel = [_sortOrdering selector];
+ if (sel_eq(sel, EOCompareDescending) ||
+ sel_eq(sel, EOCompareCaseInsensitiveDescending)) {
+ return [@"REVERSE " stringByAppendingString:key];
+ }
+ // TODO: check other selectors whether they make sense instead of silent acc.
+
+ return key;
+}
+
+- (NSString *)_generateIMAP4SortOrderings:(NSArray *)_sortOrderings {
+ /*
+ turn EOSortOrdering into an IMAP4 value for "SORT()"
+
+ eg: "DATE REVERSE SUBJECT"
+
+ It also checks a set of allowed sort-keys (don't know why)
+ */
NSMutableString *sortStr;
- NSEnumerator *enumerator;
+ NSEnumerator *soe;
EOSortOrdering *so;
BOOL isFirst = YES;
-
- sortStr = [NSMutableString stringWithCapacity:128];
if ([_sortOrderings count] == 0)
- return [NSDictionary dictionaryWithObjectsAndKeys:@"result", NoNumber,nil];
-
- enumerator = [_sortOrderings objectEnumerator];
-
- [sortStr appendString:@"UID SORT ("];
+ return nil;
- while ((so = [enumerator nextObject])) {
- SEL sel;
- NSString *key;
-
- key = [[so key] uppercaseString];
-
- if ([key length] == 0)
- continue;
+ sortStr = [NSMutableString stringWithCapacity:128];
+ soe = [_sortOrderings objectEnumerator];
+ while ((so = [soe nextObject])) {
+ NSString *s;
- if (![AllowedSortKeys containsObject:key]) {
- [self logWithFormat:@"ERROR[%s] key %@ is not allowed here!",
- __PRETTY_FUNCTION__, key];
+ s = [self _generateIMAP4SortOrdering:so];
+ if (s == nil)
continue;
- }
+
if (isFirst)
isFirst = NO;
else
[sortStr appendString:@" "];
- sel = [so selector];
-
- if (sel_eq(sel, EOCompareDescending) ||
- sel_eq(sel, EOCompareCaseInsensitiveDescending)) {
- [sortStr appendString:@"REVERSE "];
- }
- [sortStr appendString:[so key]];
- }
- if (isFirst) { /* found no valid key use date sorting */
- [sortStr appendString:@"DATE"];
-#if 0
- return [NSDictionary dictionaryWithObjectsAndKeys:
- NoNumber, @"result", nil];
-#endif
+
+ [sortStr appendString:s];
}
+ return isFirst ? nil : sortStr;
+}
+
+- (NSDictionary *)primarySort:(NSString *)_sort
+ qualifierString:(NSString *)_qualString
+ encoding:(NSString *)_encoding
+{
+ /*
+ http://www.ietf.org/internet-drafts/draft-ietf-imapext-sort-17.txt
+
+ The result dict contains the following keys:
+ 'result' - a boolean
+ 'expunge' - array (of what?)
+ 'sort' - array of uids in sort order
+ 'RawResponse' - the raw IMAP4 response
+
+ Eg: UID SORT ( DATE REVERSE SUBJECT ) UTF-8 TODO
+ */
+ NSMutableString *sortStr;
+
+ if (![_encoding isNotNull]) _encoding = @"UTF-8";
+ if (![_qualString isNotNull]) _qualString = @" ALL";
+
+ sortStr = [NSMutableString stringWithCapacity:128];
+
+ [sortStr appendString:@"UID SORT ("];
+ if (_sort != nil) [sortStr appendString:_sort];
[sortStr appendString:@") "];
- // TODO: make that the other way around! should be an ivar in the client
- [sortStr appendString:[[self context] sortEncoding]];
- [sortStr appendString:[self _searchExprForQual:_qual]];
+
+ [sortStr appendString:_encoding]; /* eg 'UTF-8' */
+
+ /* Note: this is _space sensitive_! to many spaces lead to error! */
+ [sortStr appendString:_qualString]; /* eg ' ALL' or ' TEXT "abc"' */
return [self->normer normalizeSortResponse:[self processCommand:sortStr]];
}
+- (NSDictionary *)sort:(id)_sortSpec
+ qualifier:(EOQualifier *)_qual
+ encoding:(NSString *)_encoding
+{
+ /*
+ http://www.ietf.org/internet-drafts/draft-ietf-imapext-sort-17.txt
+
+ The _sortSpec can be:
+ - a simple 'raw' IMAP4 sort string
+ - an EOSortOrdering
+ - an array of EOSortOrderings
+
+ The result dict contains the following keys:
+ 'result' - a boolean
+ 'expunge' - array (of what?)
+ 'sort' - array of uids in sort order
+ 'RawResponse' - the raw IMAP4 response
+
+ If no sortable key was found, the sort will run against 'DATE'.
+ => TODO: this is inconsistent. If none are passed in, false will be
+ returned
+
+ Eg: UID SORT ( DATE REVERSE SUBJECT ) UTF-8 TODO
+ */
+ NSString *tmp;
+
+ if ([_sortSpec isKindOfClass:[NSArray class]])
+ tmp = [self _generateIMAP4SortOrderings:_sortSpec];
+ else if ([_sortSpec isKindOfClass:[EOSortOrdering class]])
+ tmp = [self _generateIMAP4SortOrdering:_sortSpec];
+ else
+ tmp = [_sortSpec stringValue];
+
+ if ([tmp length] == 0) { /* found no valid key use date sorting */
+ [self logWithFormat:@"Note: no key found for sorting, using 'DATE': %@",
+ _sortSpec];
+ tmp = @"DATE";
+ }
+
+ return [self primarySort:tmp
+ qualifierString:[self _searchExprForQual:_qual]
+ encoding:_encoding];
+}
+- (NSDictionary *)sort:(NSArray *)_sortOrderings
+ qualifier:(EOQualifier *)_qual
+{
+ // DEPRECATED, should not use context!
+ return [self sort:_sortOrderings qualifier:_qual
+ encoding:[[self context] sortEncoding]];
+}
+
- (NSDictionary *)searchWithQualifier:(EOQualifier *)_qualifier {
NSString *s;
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
-// $Id$
+// $Id: NGImap4Folder.m 1 2004-08-20 10:08:27Z znek $
#include "NGImap4Folder.h"
#include "NGImap4Context.h"
qual2 = UnseenQual;
}
-
- if (qual1) {
- dict = [[self->context client] sort:DateSo qualifier:qual1];
-
+
+ if (qual1 != nil) {
+ dict = [[self->context client] sort:DateSo qualifier:qual1
+ encoding:[self->context sortEncoding]];
+
if (![[dict objectForKey:@"result"] boolValue]) {
[self logWithFormat:@"ERROR[%s](1): sort failed (sortOrderings %@, "
@"qual1 %@)", __PRETTY_FUNCTION__, DateSo, qual1];
}
[muids addObjectsFromArray:[dict objectForKey:@"sort"]];
}
- if (qual2) {
- dict = [[self->context client] sort:DateSo qualifier:qual2];
-
+ if (qual2 != nil) {
+ dict = [[self->context client] sort:DateSo qualifier:qual2
+ encoding:[self->context sortEncoding]];
+
if (![[dict objectForKey:@"result"] boolValue]) {
[self logWithFormat:@"ERROR[%s](2): sort failed (sortOrderings %@, "
@"qual2 %@ ", __PRETTY_FUNCTION__, DateSo, qual2];
[self resetLastException];
- dict = [[self->context client] sort:_so qualifier:qual];
-
+ dict = [[self->context client] sort:_so qualifier:qual
+ encoding:[self->context sortEncoding]];
+
if (![self _checkResult:dict cmd:__PRETTY_FUNCTION__])
return nil;