1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #ifndef _nsMsgSearchAdapter_H_
7 #define _nsMsgSearchAdapter_H_
8
9 #include "nsMsgSearchCore.h"
10 #include "nsCOMPtr.h"
11 #include "nsString.h"
12 #include "nsIMsgSearchAdapter.h"
13 #include "nsIMsgSearchValidityTable.h"
14 #include "nsIMsgSearchValidityManager.h"
15 #include "nsIMsgSearchTerm.h"
16 #include "nsINntpIncomingServer.h"
17
18 class nsIMsgSearchScopeTerm;
19
20 //-----------------------------------------------------------------------------
21 // These Adapter classes contain the smarts to convert search criteria from
22 // the canonical structures in msg_srch.h into whatever format is required
23 // by their protocol.
24 //
25 // There is a separate Adapter class for area (pop, imap, nntp, ldap) to contain
26 // the special smarts for that protocol.
27 //-----------------------------------------------------------------------------
28
29 class nsMsgSearchAdapter : public nsIMsgSearchAdapter {
30 public:
31 nsMsgSearchAdapter(nsIMsgSearchScopeTerm*,
32 nsTArray<RefPtr<nsIMsgSearchTerm>> const&);
33
34 NS_DECL_ISUPPORTS
35 NS_DECL_NSIMSGSEARCHADAPTER
36
37 nsIMsgSearchScopeTerm* m_scope;
38 nsTArray<RefPtr<nsIMsgSearchTerm>>
39 m_searchTerms; /* linked list of criteria terms */
40
41 nsString m_defaultCharset = u"UTF-8"_ns;
42
43 static nsresult EncodeImap(
44 char** ppEncoding, nsTArray<RefPtr<nsIMsgSearchTerm>> const& searchTerms,
45 const char16_t* srcCharset, const char16_t* destCharset,
46 bool reallyDredd = false);
47
48 static nsresult EncodeImapValue(char* encoding, const char* value,
49 bool useQuotes, bool reallyDredd);
50
51 static char* GetImapCharsetParam(const char16_t* destCharset);
52 static char16_t* EscapeSearchUrl(const char16_t* nntpCommand);
53 static char16_t* EscapeImapSearchProtocol(const char16_t* imapCommand);
54 static char16_t* EscapeQuoteImapSearchProtocol(const char16_t* imapCommand);
55 static char* UnEscapeSearchUrl(const char* commandSpecificData);
56 // This stuff lives in the base class because the IMAP search syntax
57 // is used by the Dredd SEARCH command as well as IMAP itself
58 static const char* m_kImapBefore;
59 static const char* m_kImapBody;
60 static const char* m_kImapCC;
61 static const char* m_kImapFrom;
62 static const char* m_kImapNot;
63 static const char* m_kImapOr;
64 static const char* m_kImapSince;
65 static const char* m_kImapSubject;
66 static const char* m_kImapTo;
67 static const char* m_kImapHeader;
68 static const char* m_kImapAnyText;
69 static const char* m_kImapKeyword;
70 static const char* m_kNntpKeywords;
71 static const char* m_kImapSentOn;
72 static const char* m_kImapSeen;
73 static const char* m_kImapAnswered;
74 static const char* m_kImapNotSeen;
75 static const char* m_kImapNotAnswered;
76 static const char* m_kImapCharset;
77 static const char* m_kImapUnDeleted;
78 static const char* m_kImapSizeSmaller;
79 static const char* m_kImapSizeLarger;
80 static const char* m_kImapNew;
81 static const char* m_kImapNotNew;
82 static const char* m_kImapFlagged;
83 static const char* m_kImapNotFlagged;
84
85 protected:
86 virtual ~nsMsgSearchAdapter();
87 typedef enum _msg_TransformType {
88 kOverwrite, /* "John Doe" -> "John*Doe", simple contains */
89 kInsert, /* "John Doe" -> "John* Doe", name completion */
90 kSurround /* "John Doe" -> "John* *Doe", advanced contains */
91 } msg_TransformType;
92
93 char* TransformSpacesToStars(const char*, msg_TransformType transformType);
94 nsresult OpenNewsResultInUnknownGroup(nsMsgResultElement*);
95
96 static nsresult EncodeImapTerm(nsIMsgSearchTerm*, bool reallyDredd,
97 const char16_t* srcCharset,
98 const char16_t* destCharset, char** ppOutTerm);
99 };
100
101 //-----------------------------------------------------------------------------
102 // Validity checking for attrib/op pairs. We need to know what operations are
103 // legal in three places:
104 // 1. when the FE brings up the dialog box and needs to know how to build
105 // the menus and enable their items
106 // 2. when the FE fires off a search, we need to check their lists for
107 // correctness
108 // 3. for on-the-fly capability negotiation e.g. with XSEARCH-capable news
109 // servers
110 //-----------------------------------------------------------------------------
111
112 class nsMsgSearchValidityTable final : public nsIMsgSearchValidityTable {
113 public:
114 nsMsgSearchValidityTable();
115 NS_DECL_NSIMSGSEARCHVALIDITYTABLE
116 NS_DECL_ISUPPORTS
117
118 protected:
119 int m_numAvailAttribs; // number of rows with at least one available operator
120 typedef struct vtBits {
121 uint16_t bitEnabled : 1;
122 uint16_t bitAvailable : 1;
123 uint16_t bitValidButNotShown : 1;
124 } vtBits;
125 vtBits m_table[nsMsgSearchAttrib::kNumMsgSearchAttributes]
126 [nsMsgSearchOp::kNumMsgSearchOperators];
127
128 private:
~nsMsgSearchValidityTable()129 ~nsMsgSearchValidityTable() {}
130 nsMsgSearchAttribValue m_defaultAttrib;
131 };
132
133 // Using getters and setters seems a little nicer then dumping the 2-D array
134 // syntax all over the code
135 #define CHECK_AO \
136 if (a < 0 || a >= nsMsgSearchAttrib::kNumMsgSearchAttributes || o < 0 || \
137 o >= nsMsgSearchOp::kNumMsgSearchOperators) \
138 return NS_ERROR_ILLEGAL_VALUE;
SetAvailable(int a,int o,bool b)139 inline nsresult nsMsgSearchValidityTable::SetAvailable(int a, int o, bool b) {
140 CHECK_AO;
141 m_table[a][o].bitAvailable = b;
142 return NS_OK;
143 }
SetEnabled(int a,int o,bool b)144 inline nsresult nsMsgSearchValidityTable::SetEnabled(int a, int o, bool b) {
145 CHECK_AO;
146 m_table[a][o].bitEnabled = b;
147 return NS_OK;
148 }
SetValidButNotShown(int a,int o,bool b)149 inline nsresult nsMsgSearchValidityTable::SetValidButNotShown(int a, int o,
150 bool b) {
151 CHECK_AO;
152 m_table[a][o].bitValidButNotShown = b;
153 return NS_OK;
154 }
155
GetAvailable(int a,int o,bool * aResult)156 inline nsresult nsMsgSearchValidityTable::GetAvailable(int a, int o,
157 bool* aResult) {
158 CHECK_AO;
159 *aResult = m_table[a][o].bitAvailable;
160 return NS_OK;
161 }
GetEnabled(int a,int o,bool * aResult)162 inline nsresult nsMsgSearchValidityTable::GetEnabled(int a, int o,
163 bool* aResult) {
164 CHECK_AO;
165 *aResult = m_table[a][o].bitEnabled;
166 return NS_OK;
167 }
GetValidButNotShown(int a,int o,bool * aResult)168 inline nsresult nsMsgSearchValidityTable::GetValidButNotShown(int a, int o,
169 bool* aResult) {
170 CHECK_AO;
171 *aResult = m_table[a][o].bitValidButNotShown;
172 return NS_OK;
173 }
174 #undef CHECK_AO
175
176 class nsMsgSearchValidityManager : public nsIMsgSearchValidityManager {
177 public:
178 nsMsgSearchValidityManager();
179
180 protected:
181 virtual ~nsMsgSearchValidityManager();
182
183 public:
184 NS_DECL_NSIMSGSEARCHVALIDITYMANAGER
185 NS_DECL_ISUPPORTS
186
187 nsresult GetTable(int, nsMsgSearchValidityTable**);
188
189 protected:
190 // There's one global validity manager that everyone uses. You *could* do
191 // this with static members of the adapter classes, but having a dedicated
192 // object makes cleanup of these tables (at shutdown-time) automagic.
193
194 nsCOMPtr<nsIMsgSearchValidityTable> m_offlineMailTable;
195 nsCOMPtr<nsIMsgSearchValidityTable> m_offlineMailFilterTable;
196 nsCOMPtr<nsIMsgSearchValidityTable> m_onlineMailTable;
197 nsCOMPtr<nsIMsgSearchValidityTable> m_onlineMailFilterTable;
198 nsCOMPtr<nsIMsgSearchValidityTable> m_onlineManualFilterTable;
199
200 nsCOMPtr<nsIMsgSearchValidityTable> m_newsTable; // online news
201
202 // Local news tables, used for local news searching or offline.
203 nsCOMPtr<nsIMsgSearchValidityTable> m_localNewsTable; // base table
204 nsCOMPtr<nsIMsgSearchValidityTable> m_localNewsJunkTable; // base + junk
205 nsCOMPtr<nsIMsgSearchValidityTable> m_localNewsBodyTable; // base + body
206 nsCOMPtr<nsIMsgSearchValidityTable>
207 m_localNewsJunkBodyTable; // base + junk + body
208 nsCOMPtr<nsIMsgSearchValidityTable> m_ldapTable;
209 nsCOMPtr<nsIMsgSearchValidityTable> m_ldapAndTable;
210 nsCOMPtr<nsIMsgSearchValidityTable> m_localABTable;
211 nsCOMPtr<nsIMsgSearchValidityTable> m_localABAndTable;
212 nsCOMPtr<nsIMsgSearchValidityTable> m_newsFilterTable;
213
214 nsresult NewTable(nsIMsgSearchValidityTable**);
215
216 nsresult InitOfflineMailTable();
217 nsresult InitOfflineMailFilterTable();
218 nsresult InitOnlineMailTable();
219 nsresult InitOnlineMailFilterTable();
220 nsresult InitOnlineManualFilterTable();
221 nsresult InitNewsTable();
222 nsresult InitLocalNewsTable();
223 nsresult InitLocalNewsJunkTable();
224 nsresult InitLocalNewsBodyTable();
225 nsresult InitLocalNewsJunkBodyTable();
226 nsresult InitNewsFilterTable();
227
228 // set the custom headers in the table, changes whenever
229 // "mailnews.customHeaders" pref changes.
230 nsresult SetOtherHeadersInTable(nsIMsgSearchValidityTable* table,
231 const char* customHeaders);
232
233 nsresult InitLdapTable();
234 nsresult InitLdapAndTable();
235 nsresult InitLocalABTable();
236 nsresult InitLocalABAndTable();
237 nsresult SetUpABTable(nsIMsgSearchValidityTable* aTable, bool isOrTable);
238 nsresult EnableDirectoryAttribute(nsIMsgSearchValidityTable* table,
239 nsMsgSearchAttribValue aSearchAttrib);
240 };
241
242 #endif
243