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