ZNC  trunk
Message.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004-2020 ZNC, see the NOTICE file for details.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ZNC_MESSAGE_H
18 #define ZNC_MESSAGE_H
19 
20 // Remove this after Feb 2016 when Debian 7 is EOL
21 #if __cpp_ref_qualifiers >= 200710
22 #define ZNC_LVREFQUAL &
23 #elif defined(__clang__)
24 #define ZNC_LVREFQUAL &
25 #elif __GNUC__ > 4 || \
26  __GNUC__ == 4 && (__GNUC_MINOR__ > 8 || \
27  __GNUC_MINOR__ == 8 && __GNUC_PATCHLEVEL__ >= 1)
28 #define ZNC_LVREFQUAL &
29 #else
30 #define ZNC_LVREFQUAL
31 #endif
32 
33 #ifdef SWIG
34 #define ZNC_MSG_DEPRECATED(msg)
35 #else
36 #define ZNC_MSG_DEPRECATED(msg) __attribute__((deprecated(msg)))
37 #endif
38 
39 #include <znc/zncconfig.h>
40 #include <znc/ZNCString.h>
41 #include <znc/Nick.h>
42 #include <sys/time.h>
43 
44 class CChan;
45 class CClient;
46 class CIRCNetwork;
47 
70 class CMessage {
71  public:
72  explicit CMessage(const CString& sMessage = "");
73  CMessage(const CNick& Nick, const CString& sCommand,
74  const VCString& vsParams = VCString(),
75  const MCString& mssTags = MCString::EmptyMap);
76 
77  enum class Type {
78  Unknown,
79  Account,
80  Action,
81  Away,
82  Capability,
83  CTCP,
84  Error,
85  Invite,
86  Join,
87  Kick,
88  Mode,
89  Nick,
90  Notice,
91  Numeric,
92  Part,
93  Ping,
94  Pong,
95  Quit,
96  Text,
97  Topic,
98  Wallops,
99  };
100  Type GetType() const { return m_eType; }
101 
102  bool Equals(const CMessage& Other) const;
103  void Clone(const CMessage& Other);
104 
105  // ZNC <-> IRC
106  CIRCNetwork* GetNetwork() const { return m_pNetwork; }
107  void SetNetwork(CIRCNetwork* pNetwork) { m_pNetwork = pNetwork; }
108 
109  // ZNC <-> CLI
110  CClient* GetClient() const { return m_pClient; }
111  void SetClient(CClient* pClient) { m_pClient = pClient; }
112 
113  CChan* GetChan() const { return m_pChan; }
114  void SetChan(CChan* pChan) { m_pChan = pChan; }
115 
116  CNick& GetNick() { return m_Nick; }
117  const CNick& GetNick() const { return m_Nick; }
118  void SetNick(const CNick& Nick) { m_Nick = Nick; }
119 
120  const CString& GetCommand() const { return m_sCommand; }
121  void SetCommand(const CString& sCommand);
122 
123  const VCString& GetParams() const { return m_vsParams; }
124 
135  VCString GetParamsSplit(unsigned int uIdx, unsigned int uLen = -1) const;
136  void SetParams(const VCString& vsParams);
137 
139  CString GetParams(unsigned int uIdx, unsigned int uLen = -1) const
140  ZNC_MSG_DEPRECATED("Use GetParamsColon() instead") {
141  return GetParamsColon(uIdx, uLen);
142  }
143  CString GetParamsColon(unsigned int uIdx, unsigned int uLen = -1) const;
144 
145  CString GetParam(unsigned int uIdx) const;
146  void SetParam(unsigned int uIdx, const CString& sParam);
147 
148  const timeval& GetTime() const { return m_time; }
149  void SetTime(const timeval& ts) { m_time = ts; }
150 
151  const MCString& GetTags() const { return m_mssTags; }
152  void SetTags(const MCString& mssTags) { m_mssTags = mssTags; }
153 
154  CString GetTag(const CString& sKey) const;
155  void SetTag(const CString& sKey, const CString& sValue);
156 
157  enum FormatFlags {
158  IncludeAll = 0x0,
161  };
162 
163  CString ToString(unsigned int uFlags = IncludeAll) const;
164  void Parse(CString sMessage);
165 
166 // Implicit and explicit conversion to a subclass reference.
167 #ifndef SWIG
168  template <typename M>
170  static_assert(std::is_base_of<CMessage, M>{},
171  "Must be subclass of CMessage");
172  static_assert(sizeof(M) == sizeof(CMessage),
173  "No data members allowed in CMessage subclasses.");
174  return static_cast<M&>(*this);
175  }
176 
177  template <typename M>
178  const M& As() const ZNC_LVREFQUAL {
179  static_assert(std::is_base_of<CMessage, M>{},
180  "Must be subclass of CMessage");
181  static_assert(sizeof(M) == sizeof(CMessage),
182  "No data members allowed in CMessage subclasses.");
183  return static_cast<const M&>(*this);
184  }
185 
186  template <typename M, typename = typename std::enable_if<
187  std::is_base_of<CMessage, M>{}>::type>
188  operator M&() ZNC_LVREFQUAL {
189  return As<M>();
190  }
191  template <typename M, typename = typename std::enable_if<
192  std::is_base_of<CMessage, M>{}>::type>
193  operator const M&() const ZNC_LVREFQUAL {
194  return As<M>();
195  }
196 // REGISTER_ZNC_MESSAGE allows SWIG to instantiate correct .As<> calls.
197 #define REGISTER_ZNC_MESSAGE(M)
198 #else
199  // SWIG (as of 3.0.7) doesn't parse ref-qualifiers, and doesn't
200  // differentiate constness.
201  template <typename M>
202  M& As();
203 #endif
204 
205  private:
206  void InitTime();
207  void InitType();
208 
209  CNick m_Nick;
210  CString m_sCommand;
211  VCString m_vsParams;
212  MCString m_mssTags;
213  timeval m_time;
214  CIRCNetwork* m_pNetwork = nullptr;
215  CClient* m_pClient = nullptr;
216  CChan* m_pChan = nullptr;
217  Type m_eType = Type::Unknown;
218  bool m_bColon = false;
219 };
220 
221 // For gtest
222 #ifdef GTEST_FAIL
223 template <typename M, typename = typename std::enable_if<
224  std::is_base_of<CMessage, M>{}>::type>
225 inline ::std::ostream& operator<<(::std::ostream& os, const M& msg) {
226  return os << msg.ToString().Escape_n(CString::EDEBUG);
227 }
228 #endif
229 
230 // The various CMessage subclasses are "mutable views" to the data held by
231 // CMessage.
232 // They provide convenient access to message type speficic attributes, but are
233 // not
234 // allowed to hold extra data of their own.
235 class CTargetMessage : public CMessage {
236  public:
237  CString GetTarget() const { return GetParam(0); }
238  void SetTarget(const CString& sTarget) { SetParam(0, sTarget); }
239 };
241 
243  public:
244  CString GetText() const {
245  return GetParam(1).TrimPrefix_n("\001ACTION ").TrimSuffix_n("\001");
246  }
247  void SetText(const CString& sText) {
248  SetParam(1, "\001ACTION " + sText + "\001");
249  }
250 };
252 
253 class CCTCPMessage : public CTargetMessage {
254  public:
255  bool IsReply() const { return GetCommand().Equals("NOTICE"); }
256  CString GetText() const {
257  return GetParam(1).TrimPrefix_n("\001").TrimSuffix_n("\001");
258  }
259  void SetText(const CString& sText) { SetParam(1, "\001" + sText + "\001"); }
260 };
262 
263 class CJoinMessage : public CTargetMessage {
264  public:
265  CString GetKey() const { return GetParam(1); }
266  void SetKey(const CString& sKey) { SetParam(1, sKey); }
267 };
269 
270 class CModeMessage : public CTargetMessage {
271  public:
273  CString GetModes() const { return GetParamsColon(1).TrimPrefix_n(":"); }
274 
275  CString GetModeList() const { return GetParam(1); };
276 
277  VCString GetModeParams() const { return GetParamsSplit(2); };
278 
279  bool HasModes() const { return !GetModeList().empty(); };
280 };
282 
283 class CNickMessage : public CMessage {
284  public:
285  CString GetOldNick() const { return GetNick().GetNick(); }
286  CString GetNewNick() const { return GetParam(0); }
287  void SetNewNick(const CString& sNick) { SetParam(0, sNick); }
288 };
290 
292  public:
293  CString GetText() const { return GetParam(1); }
294  void SetText(const CString& sText) { SetParam(1, sText); }
295 };
297 
298 class CNumericMessage : public CMessage {
299  public:
300  unsigned int GetCode() const { return GetCommand().ToUInt(); }
301 };
303 
304 class CKickMessage : public CTargetMessage {
305  public:
306  CString GetKickedNick() const { return GetParam(1); }
307  void SetKickedNick(const CString& sNick) { SetParam(1, sNick); }
308  CString GetReason() const { return GetParam(2); }
309  void SetReason(const CString& sReason) { SetParam(2, sReason); }
310  CString GetText() const { return GetReason(); }
311  void SetText(const CString& sText) { SetReason(sText); }
312 };
314 
315 class CPartMessage : public CTargetMessage {
316  public:
317  CString GetReason() const { return GetParam(1); }
318  void SetReason(const CString& sReason) { SetParam(1, sReason); }
319  CString GetText() const { return GetReason(); }
320  void SetText(const CString& sText) { SetReason(sText); }
321 };
323 
324 class CQuitMessage : public CMessage {
325  public:
326  CString GetReason() const { return GetParam(0); }
327  void SetReason(const CString& sReason) { SetParam(0, sReason); }
328  CString GetText() const { return GetReason(); }
329  void SetText(const CString& sText) { SetReason(sText); }
330 };
332 
333 class CTextMessage : public CTargetMessage {
334  public:
335  CString GetText() const { return GetParam(1); }
336  void SetText(const CString& sText) { SetParam(1, sText); }
337 };
339 
341  public:
342  CString GetTopic() const { return GetParam(1); }
343  void SetTopic(const CString& sTopic) { SetParam(1, sTopic); }
344  CString GetText() const { return GetTopic(); }
345  void SetText(const CString& sText) { SetTopic(sText); }
346 };
348 
349 #endif // !ZNC_MESSAGE_H
Definition: Message.h:298
CString GetTag(const CString &sKey) const
Definition: Message.h:340
#define ZNC_MSG_DEPRECATED(msg)
Definition: Message.h:36
Definition: Message.h:270
CNick & GetNick()
Definition: Message.h:116
void Clone(const CMessage &Other)
void SetText(const CString &sText)
Definition: Message.h:247
CString TrimPrefix_n(const CString &sPrefix=":") const
Trim a given prefix.
Definition: Message.h:160
CString GetText() const
Definition: Message.h:335
#define REGISTER_ZNC_MESSAGE(M)
Definition: Message.h:197
void SetParam(unsigned int uIdx, const CString &sParam)
void SetChan(CChan *pChan)
Definition: Message.h:114
CString GetOldNick() const
Definition: Message.h:285
CChan * GetChan() const
Definition: Message.h:113
const CString & GetNick() const
void SetTarget(const CString &sTarget)
Definition: Message.h:238
Definition: Message.h:235
void SetText(const CString &sText)
Definition: Message.h:320
CString GetText() const
Definition: Message.h:293
void SetText(const CString &sText)
Definition: Message.h:345
bool Equals(const CString &s, CaseSensitivity cs=CaseInsensitive) const
Check if this string is equal to some other string.
bool HasModes() const
Definition: Message.h:279
CString ToString(unsigned int uFlags=IncludeAll) const
Definition: Message.h:159
Definition: Client.h:99
void SetParams(const VCString &vsParams)
CString GetNewNick() const
Definition: Message.h:286
#define ZNC_LVREFQUAL
Definition: Message.h:30
Definition: Message.h:315
Definition: Message.h:291
void SetTag(const CString &sKey, const CString &sValue)
CIRCNetwork * GetNetwork() const
Definition: Message.h:106
bool IsReply() const
Definition: Message.h:255
void SetCommand(const CString &sCommand)
void SetText(const CString &sText)
Definition: Message.h:329
Definition: Nick.h:29
CString GetText() const
Definition: Message.h:319
void SetText(const CString &sText)
Definition: Message.h:336
const M & As() const ZNC_LVREFQUAL
Definition: Message.h:178
CString GetReason() const
Definition: Message.h:326
const CString & GetCommand() const
Definition: Message.h:120
Definition: ZNCString.h:76
CString GetModeList() const
Definition: Message.h:275
Definition: Message.h:253
void SetTags(const MCString &mssTags)
Definition: Message.h:152
Definition: Message.h:324
void Parse(CString sMessage)
Definition: Message.h:242
CString GetText() const
Definition: Message.h:310
void SetReason(const CString &sReason)
Definition: Message.h:327
Type GetType() const
Definition: Message.h:100
const MCString & GetTags() const
Definition: Message.h:151
Definition: IRCNetwork.h:40
std::vector< CString > VCString
Definition: ZNCString.h:38
CString GetParamsColon(unsigned int uIdx, unsigned int uLen=-1) const
void SetText(const CString &sText)
Definition: Message.h:294
unsigned int ToUInt() const
String class that is used inside ZNC.
Definition: ZNCString.h:68
CString GetParam(unsigned int uIdx) const
void SetKickedNick(const CString &sNick)
Definition: Message.h:307
CString GetKickedNick() const
Definition: Message.h:306
void SetNewNick(const CString &sNick)
Definition: Message.h:287
void SetNetwork(CIRCNetwork *pNetwork)
Definition: Message.h:107
CString GetKey() const
Definition: Message.h:265
FormatFlags
Definition: Message.h:157
void SetTopic(const CString &sTopic)
Definition: Message.h:343
const CNick & GetNick() const
Definition: Message.h:117
CString GetTopic() const
Definition: Message.h:342
CString GetText() const
Definition: Message.h:256
CString GetText() const
Definition: Message.h:328
CString GetText() const
Definition: Message.h:344
VCString GetParamsSplit(unsigned int uIdx, unsigned int uLen=-1) const
Get a subset of the message parameters.
static const MCString EmptyMap
A static instance of an empty map.
Definition: ZNCString.h:606
const timeval & GetTime() const
Definition: Message.h:148
CString GetModes() const
Definition: Message.h:273
Definition: Message.h:333
void SetKey(const CString &sKey)
Definition: Message.h:266
Definition: Message.h:158
M & As() ZNC_LVREFQUAL
Definition: Message.h:169
A dictionary for strings.
Definition: ZNCString.h:595
void SetReason(const CString &sReason)
Definition: Message.h:309
Definition: Message.h:283
CString GetTarget() const
Definition: Message.h:237
VCString GetModeParams() const
Definition: Message.h:277
void SetText(const CString &sText)
Definition: Message.h:311
const VCString & GetParams() const
Definition: Message.h:123
Type
Definition: Message.h:77
void SetTime(const timeval &ts)
Definition: Message.h:149
CString TrimSuffix_n(const CString &sSuffix) const
Trim a given suffix.
void SetText(const CString &sText)
Definition: Message.h:259
bool Equals(const CMessage &Other) const
CString GetReason() const
Definition: Message.h:317
CClient * GetClient() const
Definition: Message.h:110
Definition: Message.h:263
void SetReason(const CString &sReason)
Definition: Message.h:318
CString GetParams(unsigned int uIdx, unsigned int uLen=-1) const ZNC_MSG_DEPRECATED("Use GetParamsColon() instead")
Definition: Message.h:139
void SetClient(CClient *pClient)
Definition: Message.h:111
CMessage(const CString &sMessage="")
Definition: Chan.h:35
Definition: Message.h:304
unsigned int GetCode() const
Definition: Message.h:300
CString GetReason() const
Definition: Message.h:308
Here is a small explanation of how messages on IRC work, and how you can use this class to get useful...
Definition: Message.h:70
void SetNick(const CNick &Nick)
Definition: Message.h:118
CString GetText() const
Definition: Message.h:244