Skip to content

Commit 90a1a90

Browse files
committed
imapmemserver: implement SEARCHRES
1 parent ce1d60f commit 90a1a90

File tree

1 file changed

+31
-7
lines changed

1 file changed

+31
-7
lines changed

imapserver/imapmemserver/mailbox.go

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,8 @@ func (mbox *Mailbox) NewView() *MailboxView {
274274
// selected state.
275275
type MailboxView struct {
276276
*Mailbox
277-
tracker *imapserver.SessionTracker
277+
tracker *imapserver.SessionTracker
278+
searchRes imap.UIDSet
278279
}
279280

280281
// Close releases the resources allocated for the mailbox view.
@@ -327,6 +328,9 @@ func (mbox *MailboxView) Search(numKind imapserver.NumKind, criteria *imap.Searc
327328
continue
328329
}
329330

331+
// Always populate the UID set, since it may be saved later for SEARCHRES
332+
uidSet.AddNum(msg.uid)
333+
330334
var num uint32
331335
switch numKind {
332336
case imapserver.NumKindSeq:
@@ -336,7 +340,6 @@ func (mbox *MailboxView) Search(numKind imapserver.NumKind, criteria *imap.Searc
336340
seqSet.AddNum(seqNum)
337341
num = seqNum
338342
case imapserver.NumKindUID:
339-
uidSet.AddNum(msg.uid)
340343
num = uint32(msg.uid)
341344
}
342345
if data.Min == 0 || num < data.Min {
@@ -355,15 +358,28 @@ func (mbox *MailboxView) Search(numKind imapserver.NumKind, criteria *imap.Searc
355358
data.All = uidSet
356359
}
357360

361+
if options.ReturnSave {
362+
mbox.searchRes = uidSet
363+
}
364+
358365
return &data, nil
359366
}
360367

361368
func (mbox *MailboxView) staticSearchCriteria(criteria *imap.SearchCriteria) {
369+
seqNums := make([]imap.SeqSet, 0, len(criteria.SeqNum))
362370
for _, seqSet := range criteria.SeqNum {
363-
mbox.staticNumSet(seqSet)
371+
numSet := mbox.staticNumSet(seqSet)
372+
switch numSet := numSet.(type) {
373+
case imap.SeqSet:
374+
seqNums = append(seqNums, numSet)
375+
case imap.UIDSet: // can happen with SEARCHRES
376+
criteria.UID = append(criteria.UID, numSet)
377+
}
364378
}
365-
for _, uidSet := range criteria.UID {
366-
mbox.staticNumSet(uidSet)
379+
criteria.SeqNum = seqNums
380+
381+
for i, uidSet := range criteria.UID {
382+
criteria.UID[i] = mbox.staticNumSet(uidSet).(imap.UIDSet)
367383
}
368384

369385
for i := range criteria.Not {
@@ -404,7 +420,7 @@ func (mbox *MailboxView) forEach(numSet imap.NumSet, f func(seqNum uint32, msg *
404420
func (mbox *MailboxView) forEachLocked(numSet imap.NumSet, f func(seqNum uint32, msg *message)) {
405421
// TODO: optimize
406422

407-
mbox.staticNumSet(numSet)
423+
numSet = mbox.staticNumSet(numSet)
408424

409425
for i, msg := range mbox.l {
410426
seqNum := uint32(i) + 1
@@ -429,7 +445,13 @@ func (mbox *MailboxView) forEachLocked(numSet imap.NumSet, f func(seqNum uint32,
429445
//
430446
// This is necessary to properly handle the special symbol "*", which
431447
// represents the maximum sequence number or UID in the mailbox.
432-
func (mbox *MailboxView) staticNumSet(numSet imap.NumSet) {
448+
//
449+
// This function also handles the special SEARCHRES marker "$".
450+
func (mbox *MailboxView) staticNumSet(numSet imap.NumSet) imap.NumSet {
451+
if imap.IsSearchRes(numSet) {
452+
return mbox.searchRes
453+
}
454+
433455
switch numSet := numSet.(type) {
434456
case imap.SeqSet:
435457
max := uint32(len(mbox.l))
@@ -444,6 +466,8 @@ func (mbox *MailboxView) staticNumSet(numSet imap.NumSet) {
444466
staticNumRange((*uint32)(&r.Start), (*uint32)(&r.Stop), max)
445467
}
446468
}
469+
470+
return numSet
447471
}
448472

449473
func staticNumRange(start, stop *uint32, max uint32) {

0 commit comments

Comments
 (0)