fb5558da81
This patch updates the seqNums after an Expunge operation. When an expunge operation occurs, the seqNum of the deleted message is reported. The Imap spec [0] states that an immediate decrement of all seqnums greater than the deleted occurs, even before the next reporting of an expunge update. [0]: https://datatracker.ietf.org/doc/html/rfc3501#section-7.4.1 Fixes: https://todo.sr.ht/~rjarry/aerc/61 Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Signed-off-by: Robin Jarry <robin@jarry.cc>
60 lines
1 KiB
Go
60 lines
1 KiB
Go
package imap
|
|
|
|
import (
|
|
"sync"
|
|
)
|
|
|
|
type SeqMap struct {
|
|
lock sync.Mutex
|
|
// map of IMAP sequence numbers to message UIDs
|
|
m map[uint32]uint32
|
|
}
|
|
|
|
func (s *SeqMap) Size() int {
|
|
s.lock.Lock()
|
|
size := len(s.m)
|
|
s.lock.Unlock()
|
|
return size
|
|
}
|
|
|
|
func (s *SeqMap) Get(seqnum uint32) (uint32, bool) {
|
|
s.lock.Lock()
|
|
uid, found := s.m[seqnum]
|
|
s.lock.Unlock()
|
|
return uid, found
|
|
}
|
|
|
|
func (s *SeqMap) Put(seqnum, uid uint32) {
|
|
s.lock.Lock()
|
|
if s.m == nil {
|
|
s.m = make(map[uint32]uint32)
|
|
}
|
|
s.m[seqnum] = uid
|
|
s.lock.Unlock()
|
|
}
|
|
|
|
func (s *SeqMap) Pop(seqnum uint32) (uint32, bool) {
|
|
s.lock.Lock()
|
|
uid, found := s.m[seqnum]
|
|
if found {
|
|
m := make(map[uint32]uint32)
|
|
for s, u := range s.m {
|
|
if s > seqnum {
|
|
// All sequence numbers greater than the removed one must be decremented by one
|
|
// https://datatracker.ietf.org/doc/html/rfc3501#section-7.4.1
|
|
m[s-1] = u
|
|
} else if s < seqnum {
|
|
m[s] = u
|
|
}
|
|
}
|
|
s.m = m
|
|
}
|
|
s.lock.Unlock()
|
|
return uid, found
|
|
}
|
|
|
|
func (s *SeqMap) Clear() {
|
|
s.lock.Lock()
|
|
s.m = make(map[uint32]uint32)
|
|
s.lock.Unlock()
|
|
}
|