IMAP: IMAPFolder now stores the last UID.
* So mails are no longer downloaded every time.
This commit is contained in:
@@ -215,8 +215,7 @@ public:
|
|||||||
return status;
|
return status;
|
||||||
|
|
||||||
fState = FETCH_ENTRIES;
|
fState = FETCH_ENTRIES;
|
||||||
// fFirstUID = fLastUID = fFolder->LastUID();
|
fFirstUID = fLastUID = fFolder->LastUID() + 1;
|
||||||
fFirstUID = fLastUID = 0;
|
|
||||||
fMailboxEntries = 0;
|
fMailboxEntries = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
static const char* kMailboxNameAttribute = "IMAP:mailbox";
|
static const char* kMailboxNameAttribute = "IMAP:mailbox";
|
||||||
static const char* kUIDValidityAttribute = "IMAP:uidvalidity";
|
static const char* kUIDValidityAttribute = "IMAP:uidvalidity";
|
||||||
|
static const char* kLastUIDAttribute = "IMAP:lastuid";
|
||||||
static const char* kStateAttribute = "IMAP:state";
|
static const char* kStateAttribute = "IMAP:state";
|
||||||
static const char* kFlagsAttribute = "IMAP:flags";
|
static const char* kFlagsAttribute = "IMAP:flags";
|
||||||
static const char* kUIDAttribute = "MAIL:unique_id";
|
static const char* kUIDAttribute = "MAIL:unique_id";
|
||||||
@@ -88,22 +89,23 @@ IMAPFolder::IMAPFolder(IMAPProtocol& protocol, const BString& mailboxName,
|
|||||||
fProtocol(protocol),
|
fProtocol(protocol),
|
||||||
fRef(ref),
|
fRef(ref),
|
||||||
fMailboxName(mailboxName),
|
fMailboxName(mailboxName),
|
||||||
fUIDValidity(UINT32_MAX)
|
fUIDValidity(UINT32_MAX),
|
||||||
|
fLastUID(0)
|
||||||
{
|
{
|
||||||
// Initialize from folder attributes
|
// Initialize from folder attributes
|
||||||
BNode node(&ref);
|
BNode node(&ref);
|
||||||
if (node.InitCheck() != B_OK)
|
if (node.InitCheck() != B_OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (node.ReadAttrString(kMailboxNameAttribute, &fMailboxName) != B_OK)
|
BString originalMailboxName;
|
||||||
return;
|
if (node.ReadAttrString(kMailboxNameAttribute, &originalMailboxName) == B_OK
|
||||||
|
&& originalMailboxName != mailboxName) {
|
||||||
|
// TODO: mailbox name has changed
|
||||||
|
}
|
||||||
|
|
||||||
uint32 uidValidity;
|
fUIDValidity = _ReadUInt32(node, kUIDValidityAttribute);
|
||||||
if (node.ReadAttr(kUIDValidityAttribute, B_UINT32_TYPE, 0, &uidValidity,
|
fLastUID = _ReadUInt32(node, kLastUIDAttribute);
|
||||||
sizeof(uint32)) != sizeof(uint32))
|
printf("IMAP: %s, last UID %lu\n", fMailboxName.String(), fLastUID);
|
||||||
return;
|
|
||||||
|
|
||||||
fUIDValidity = B_BENDIAN_TO_HOST_INT32(uidValidity);
|
|
||||||
|
|
||||||
attr_info info;
|
attr_info info;
|
||||||
status_t status = node.GetAttrInfo(kStateAttribute, &info);
|
status_t status = node.GetAttrInfo(kStateAttribute, &info);
|
||||||
@@ -135,7 +137,7 @@ IMAPFolder::IMAPFolder(IMAPProtocol& protocol, const BString& mailboxName,
|
|||||||
|
|
||||||
// Initialize current state from actual folder
|
// Initialize current state from actual folder
|
||||||
// TODO: this should be done in another thread
|
// TODO: this should be done in another thread
|
||||||
_InitializeFolderState();
|
//_InitializeFolderState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -154,7 +156,13 @@ IMAPFolder::SetListener(FolderListener* listener)
|
|||||||
void
|
void
|
||||||
IMAPFolder::SetUIDValidity(uint32 uidValidity)
|
IMAPFolder::SetUIDValidity(uint32 uidValidity)
|
||||||
{
|
{
|
||||||
|
if (fUIDValidity == uidValidity)
|
||||||
|
return;
|
||||||
|
|
||||||
fUIDValidity = uidValidity;
|
fUIDValidity = uidValidity;
|
||||||
|
|
||||||
|
BNode node(&fRef);
|
||||||
|
_WriteUInt32(node, kUIDValidityAttribute, uidValidity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -216,8 +224,18 @@ IMAPFolder::MessageStored(entry_ref& ref, BFile& file, uint32 fetchFlags,
|
|||||||
|
|
||||||
// TODO: the call below may move/rename the file
|
// TODO: the call below may move/rename the file
|
||||||
fProtocol.MessageStored(ref, file, fetchFlags);
|
fProtocol.MessageStored(ref, file, fetchFlags);
|
||||||
|
|
||||||
file.Unset();
|
file.Unset();
|
||||||
|
|
||||||
|
if (uid > fLastUID) {
|
||||||
|
// Update last known UID
|
||||||
|
fLastUID = uid;
|
||||||
|
|
||||||
|
BNode directory(&fRef);
|
||||||
|
status_t status = _WriteUInt32(directory, kLastUIDAttribute, uid);
|
||||||
|
if (status != B_OK)
|
||||||
|
fprintf(stderr, "IMAP: Could not write last UID for mailbox "
|
||||||
|
"%s: %s\n", fMailboxName.String(), strerror(status));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -323,16 +341,35 @@ IMAPFolder::_WriteUniqueID(BNode& node, uint32 uid)
|
|||||||
uint32
|
uint32
|
||||||
IMAPFolder::_ReadFlags(BNode& node)
|
IMAPFolder::_ReadFlags(BNode& node)
|
||||||
{
|
{
|
||||||
// TODO!
|
return _ReadUInt32(node, kFlagsAttribute);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
IMAPFolder::_WriteFlags(BNode& node, uint32 flags)
|
IMAPFolder::_WriteFlags(BNode& node, uint32 flags)
|
||||||
{
|
{
|
||||||
ssize_t bytesWritten = node.WriteAttr(kFlagsAttribute, B_UINT32_TYPE, 0,
|
return _WriteUInt32(node, kFlagsAttribute, flags);
|
||||||
&flags, sizeof(uint32));
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32
|
||||||
|
IMAPFolder::_ReadUInt32(BNode& node, const char* attribute)
|
||||||
|
{
|
||||||
|
uint32 value;
|
||||||
|
ssize_t bytesRead = node.ReadAttr(attribute, B_UINT32_TYPE, 0,
|
||||||
|
&value, sizeof(uint32));
|
||||||
|
if (bytesRead == (ssize_t)sizeof(uint32))
|
||||||
|
return value;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
IMAPFolder::_WriteUInt32(BNode& node, const char* attribute, uint32 value)
|
||||||
|
{
|
||||||
|
ssize_t bytesWritten = node.WriteAttr(attribute, B_UINT32_TYPE, 0,
|
||||||
|
&value, sizeof(uint32));
|
||||||
if (bytesWritten == (ssize_t)sizeof(uint32))
|
if (bytesWritten == (ssize_t)sizeof(uint32))
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ public:
|
|||||||
void SetListener(FolderListener* listener);
|
void SetListener(FolderListener* listener);
|
||||||
void SetUIDValidity(uint32 uidValidity);
|
void SetUIDValidity(uint32 uidValidity);
|
||||||
|
|
||||||
|
uint32 LastUID() const { return fLastUID; }
|
||||||
|
|
||||||
status_t StoreMessage(BFile& file, uint32 fetchFlags,
|
status_t StoreMessage(BFile& file, uint32 fetchFlags,
|
||||||
BDataIO& stream, size_t& length,
|
BDataIO& stream, size_t& length,
|
||||||
entry_ref& ref);
|
entry_ref& ref);
|
||||||
@@ -69,6 +71,10 @@ private:
|
|||||||
uint32 _ReadFlags(BNode& node);
|
uint32 _ReadFlags(BNode& node);
|
||||||
status_t _WriteFlags(BNode& node, uint32 flags);
|
status_t _WriteFlags(BNode& node, uint32 flags);
|
||||||
|
|
||||||
|
uint32 _ReadUInt32(BNode& node, const char* attribute);
|
||||||
|
status_t _WriteUInt32(BNode& node,
|
||||||
|
const char* attribute, uint32 value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::hash_map<uint32, uint32> UIDToFlagsMap;
|
typedef std::hash_map<uint32, uint32> UIDToFlagsMap;
|
||||||
typedef std::hash_map<uint32, entry_ref> UIDToRefMap;
|
typedef std::hash_map<uint32, entry_ref> UIDToRefMap;
|
||||||
@@ -77,6 +83,7 @@ private:
|
|||||||
const entry_ref fRef;
|
const entry_ref fRef;
|
||||||
BString fMailboxName;
|
BString fMailboxName;
|
||||||
uint32 fUIDValidity;
|
uint32 fUIDValidity;
|
||||||
|
uint32 fLastUID;
|
||||||
FolderListener* fListener;
|
FolderListener* fListener;
|
||||||
UIDToRefMap fRefMap;
|
UIDToRefMap fRefMap;
|
||||||
UIDToFlagsMap fUIDMap;
|
UIDToFlagsMap fUIDMap;
|
||||||
|
|||||||
Reference in New Issue
Block a user