xref: /haiku/src/add-ons/mail_daemon/inbound_protocols/imap/IMAPFolder.h (revision bab64f65bb775dc23060e276f1f1c4498ab7af6c)
1 /*
2  * Copyright 2012-2016, Axel Dörfler, axeld@pinc-software.de.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef IMAP_FOLDER_H
6 #define IMAP_FOLDER_H
7 
8 
9 #include <hash_map>
10 #include <hash_set>
11 
12 #include <sys/stat.h>
13 
14 #include <Entry.h>
15 #include <Node.h>
16 #include <Handler.h>
17 #include <String.h>
18 
19 #include <locks.h>
20 
21 #include "Commands.h"
22 
23 
24 class BFile;
25 class IMAPProtocol;
26 
27 
28 struct MessageToken {
29 	BString	mailboxName;
30 	uint32	uidValidity;
31 	uint32	uid;
32 };
33 
34 // Additional local only message flags
35 enum FolderMessageFlags {
36 	kPartialMessage = 0x00010000,
37 };
38 
39 
40 class FolderListener {
41 public:
42 	virtual	uint32				MessageAdded(const MessageToken& fromToken,
43 									const entry_ref& ref) = 0;
44 	virtual void				MessageDeleted(const MessageToken& token) = 0;
45 
46 	virtual void				MessageFlagsChanged(const MessageToken& token,
47 									const entry_ref& ref, uint32 oldFlags,
48 									uint32 newFlags) = 0;
49 };
50 
51 
52 class IMAPFolder : public BHandler {
53 public:
54 								IMAPFolder(IMAPProtocol& protocol,
55 									const BString& mailboxName,
56 									const entry_ref& ref);
57 	virtual						~IMAPFolder();
58 
59 			status_t			Init();
60 
MailboxName()61 			const BString&		MailboxName() const { return fMailboxName; }
NodeID()62 			ino_t				NodeID() const { return fNodeID; }
63 
64 			void				SetListener(FolderListener* listener);
65 			void				SetUIDValidity(uint32 uidValidity);
66 
LastUID()67 			uint32				LastUID() const { return fLastUID; }
68 
69 			status_t			GetMessageEntryRef(uint32 uid, entry_ref& ref);
70 			status_t			GetMessageUID(const entry_ref& ref,
71 									uint32& uid) const;
72 			uint32				MessageFlags(uint32 uid);
73 
74 			void				SyncMessageFlags(uint32 uid,
75 									uint32 mailboxFlags);
76 			void				MessageEntriesFetched();
77 
78 			status_t			StoreMessage(uint32 fetchFlags, BDataIO& stream,
79 									size_t& length, entry_ref& ref,
80 									BFile& file);
81 			void				MessageStored(entry_ref& ref, BFile& file,
82 									uint32 fetchFlags, uint32 uid,
83 									uint32 flags);
84 
85 			void				RegisterPendingBodies(
86 									IMAP::MessageUIDList& uids,
87 									const BMessenger* replyTo);
88 			status_t			StoreBody(uint32 uid, BDataIO& stream,
89 									size_t& length, entry_ref& ref,
90 									BFile& file);
91 			void				BodyStored(entry_ref& ref, BFile& file,
92 									uint32 uid);
93 			void				StoringBodyFailed(const entry_ref& ref,
94 									uint32 uid, status_t error);
95 
96 			void				DeleteMessage(uint32 uid);
97 
98 	virtual void				MessageReceived(BMessage* message);
99 
100 private:
101 			void				_WaitForFolderState();
102 			void				_InitializeFolderState();
103 			void				_ReadFolderState();
104 	static	status_t			_ReadFolderState(void* self);
105 
106 			const MessageToken	_Token(uint32 uid) const;
107 			void				_NotifyStoredBody(const entry_ref& ref,
108 									uint32 uid, status_t status);
109 			status_t			_GetMessageEntryRef(uint32 uid,
110 									entry_ref& ref) const;
111 			status_t			_DeleteLocalMessage(uint32 uid);
112 
113 			void				_IMAPToMailFlags(uint32 flags,
114 									BMessage& attributes);
115 			status_t			_MailToIMAPFlags(BNode& node, uint32& flags);
116 			void				_TestMessageFlags(uint32 previousFlags,
117 									uint32 mailboxFlags, uint32 currentFlags,
118 									uint32 testFlag, uint32& nextFlags);
119 
120 			uint32				_ReadUniqueID(BNode& node) const;
121 			status_t			_WriteUniqueID(BNode& node, uint32 uid) const;
122 			uint32				_ReadUniqueIDValidity(BNode& node) const;
123 			status_t			_WriteUniqueIDValidity(BNode& node) const;
124 			uint32				_ReadFlags(BNode& node) const;
125 			status_t			_WriteFlags(BNode& node, uint32 flags) const;
126 
127 			uint32				_ReadUInt32(BNode& node,
128 									const char* attribute) const;
129 			status_t			_WriteUInt32(BNode& node,
130 									const char* attribute, uint32 value) const;
131 
132 			status_t			_WriteStream(BFile& file, BDataIO& stream,
133 									size_t& length) const;
134 
135 private:
136 	typedef std::vector<BMessenger> MessengerList;
137 #if __GNUC__ >= 4
138 	typedef __gnu_cxx::hash_map<uint32, uint32> UIDToFlagsMap;
139 	typedef __gnu_cxx::hash_map<uint32, entry_ref> UIDToRefMap;
140 	typedef __gnu_cxx::hash_map<uint32, MessengerList> MessengerMap;
141 	typedef __gnu_cxx::hash_set<uint32> UIDSet;
142 #else
143 	typedef std::hash_map<uint32, uint32> UIDToFlagsMap;
144 	typedef std::hash_map<uint32, entry_ref> UIDToRefMap;
145 	typedef std::hash_map<uint32, MessengerList> MessengerMap;
146 	typedef std::hash_set<uint32> UIDSet;
147 #endif
148 
149 			IMAPProtocol&		fProtocol;
150 			const entry_ref		fRef;
151 			BString				fMailboxName;
152 			ino_t				fNodeID;
153 			uint32				fUIDValidity;
154 			uint32				fLastUID;
155 			FolderListener*		fListener;
156 			mutex				fLock;
157 			mutex				fFolderStateLock;
158 			thread_id			fReadFolderStateThread;
159 			bool				fFolderStateInitialized;
160 			bool				fQuitFolderState;
161 			UIDToRefMap			fRefMap;
162 			UIDToFlagsMap		fFlagsMap;
163 			UIDSet				fSynchronizedUIDsSet;
164 			UIDToFlagsMap		fPendingFlagsMap;
165 			MessengerMap		fPendingBodies;
166 };
167 
168 
169 #endif	// IMAP_FOLDER_H
170