ZNC  trunk
Message.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004-2024 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 #ifdef SWIG
21 #define ZNC_MSG_DEPRECATED(msg)
22 #else
23 #define ZNC_MSG_DEPRECATED(msg) __attribute__((deprecated(msg)))
24 #endif
25 
26 #include <znc/zncconfig.h>
27 #include <znc/ZNCString.h>
28 #include <znc/Nick.h>
29 #include <sys/time.h>
30 
31 class CChan;
32 class CClient;
33 class CIRCNetwork;
34 
57 class CMessage {
58  public:
59  explicit CMessage(const CString& sMessage = "");
60  CMessage(const CNick& Nick, const CString& sCommand,
61  const VCString& vsParams = VCString(),
62  const MCString& mssTags = MCString::EmptyMap);
63 
64  enum class Type {
65  Unknown,
66  Account,
67  Action,
68  Away,
69  Capability,
70  ChgHost,
71  CTCP,
72  Error,
73  Invite,
74  Join,
75  Kick,
76  Mode,
77  Nick,
78  Notice,
79  Numeric,
80  Part,
81  Ping,
82  Pong,
83  Quit,
84  Text,
85  Topic,
86  Wallops,
87  };
88  Type GetType() const { return m_eType; }
89 
90  bool Equals(const CMessage& Other) const;
91  void Clone(const CMessage& Other);
92 
93  // ZNC <-> IRC
94  CIRCNetwork* GetNetwork() const { return m_pNetwork; }
95  void SetNetwork(CIRCNetwork* pNetwork) { m_pNetwork = pNetwork; }
96 
97  // ZNC <-> CLI
98  CClient* GetClient() const { return m_pClient; }
99  void SetClient(CClient* pClient) { m_pClient = pClient; }
100 
101  CChan* GetChan() const { return m_pChan; }
102  void SetChan(CChan* pChan) { m_pChan = pChan; }
103 
104  CNick& GetNick() { return m_Nick; }
105  const CNick& GetNick() const { return m_Nick; }
106  void SetNick(const CNick& Nick) { m_Nick = Nick; }
107 
108  const CString& GetCommand() const { return m_sCommand; }
109  void SetCommand(const CString& sCommand);
110 
111  const VCString& GetParams() const { return m_vsParams; }
112 
123  VCString GetParamsSplit(unsigned int uIdx, unsigned int uLen = -1) const;
124  void SetParams(const VCString& vsParams);
125  void SetParams(VCString&& vsParams);
126 
128  CString GetParams(unsigned int uIdx, unsigned int uLen = -1) const
129  ZNC_MSG_DEPRECATED("Use GetParamsColon() instead") {
130  return GetParamsColon(uIdx, uLen);
131  }
132  CString GetParamsColon(unsigned int uIdx, unsigned int uLen = -1) const;
133 
134  CString GetParam(unsigned int uIdx) const;
135  void SetParam(unsigned int uIdx, const CString& sParam);
136 
137  const timeval& GetTime() const { return m_time; }
138  void SetTime(const timeval& ts) { m_time = ts; }
139 
140  const MCString& GetTags() const { return m_mssTags; }
141  void SetTags(const MCString& mssTags) { m_mssTags = mssTags; }
142 
143  CString GetTag(const CString& sKey) const;
144  void SetTag(const CString& sKey, const CString& sValue);
145 
146  enum FormatFlags {
147  IncludeAll = 0x0,
149  ExcludeTags = 0x2
150  };
151 
152  CString ToString(unsigned int uFlags = IncludeAll) const;
153  void Parse(const CString& sMessage);
154 
155 // Implicit and explicit conversion to a subclass reference.
156 #ifndef SWIG
157  template <typename M>
158  M& As() & {
159  static_assert(std::is_base_of<CMessage, M>{},
160  "Must be subclass of CMessage");
161  static_assert(sizeof(M) == sizeof(CMessage),
162  "No data members allowed in CMessage subclasses.");
163  return static_cast<M&>(*this);
164  }
165 
166  template <typename M>
167  const M& As() const& {
168  static_assert(std::is_base_of<CMessage, M>{},
169  "Must be subclass of CMessage");
170  static_assert(sizeof(M) == sizeof(CMessage),
171  "No data members allowed in CMessage subclasses.");
172  return static_cast<const M&>(*this);
173  }
174 
175  template <typename M, typename = typename std::enable_if<
176  std::is_base_of<CMessage, M>{}>::type>
177  operator M&() & {
178  return As<M>();
179  }
180  template <typename M, typename = typename std::enable_if<
181  std::is_base_of<CMessage, M>{}>::type>
182  operator const M&() const& {
183  return As<M>();
184  }
185 // REGISTER_ZNC_MESSAGE allows SWIG to instantiate correct .As<> calls.
186 #define REGISTER_ZNC_MESSAGE(M)
187 #else
188  // SWIG (as of 3.0.7) doesn't parse ref-qualifiers, and doesn't
189  // differentiate constness.
190  template <typename M>
191  M& As();
192 #endif
193 
194  private:
195  void InitTime();
196  void InitType();
197 
198  CNick m_Nick;
199  CString m_sCommand;
200  VCString m_vsParams;
201  MCString m_mssTags;
202  timeval m_time;
203  CIRCNetwork* m_pNetwork = nullptr;
204  CClient* m_pClient = nullptr;
205  CChan* m_pChan = nullptr;
206  Type m_eType = Type::Unknown;
207  bool m_bColon = false;
208 };
209 
210 // For gtest
211 #ifdef GTEST_FAIL
212 template <typename M, typename = typename std::enable_if<
213  std::is_base_of<CMessage, M>{}>::type>
214 inline ::std::ostream& operator<<(::std::ostream& os, const M& msg) {
215  return os << msg.ToString().Escape_n(CString::EDEBUG);
216 }
217 #endif
218 
219 // The various CMessage subclasses are "mutable views" to the data held by
220 // CMessage.
221 // They provide convenient access to message type speficic attributes, but are
222 // not
223 // allowed to hold extra data of their own.
224 class CTargetMessage : public CMessage {
225  public:
226  CString GetTarget() const { return GetParam(0); }
227  void SetTarget(const CString& sTarget) { SetParam(0, sTarget); }
228 };
230 
232  public:
233  CString GetText() const {
234  return GetParam(1).TrimPrefix_n("\001ACTION ").TrimSuffix_n("\001");
235  }
236  void SetText(const CString& sText) {
237  SetParam(1, "\001ACTION " + sText + "\001");
238  }
239 };
241 
242 class CCTCPMessage : public CTargetMessage {
243  public:
244  bool IsReply() const { return GetCommand().Equals("NOTICE"); }
245  CString GetText() const {
246  return GetParam(1).TrimPrefix_n("\001").TrimSuffix_n("\001");
247  }
248  void SetText(const CString& sText) { SetParam(1, "\001" + sText + "\001"); }
249 };
251 
252 class CJoinMessage : public CTargetMessage {
253  public:
254  CString GetKey() const { return GetParam(1); }
255  void SetKey(const CString& sKey) { SetParam(1, sKey); }
256 };
258 
259 class CModeMessage : public CTargetMessage {
260  public:
262  CString GetModes() const { return GetParamsColon(1).TrimPrefix_n(":"); }
263 
264  CString GetModeList() const { return GetParam(1); };
265 
266  VCString GetModeParams() const { return GetParamsSplit(2); };
267 
268  bool HasModes() const { return !GetModeList().empty(); };
269 };
271 
272 class CNickMessage : public CMessage {
273  public:
274  CString GetOldNick() const { return GetNick().GetNick(); }
275  CString GetNewNick() const { return GetParam(0); }
276  void SetNewNick(const CString& sNick) { SetParam(0, sNick); }
277 };
279 
281  public:
282  CString GetText() const { return GetParam(1); }
283  void SetText(const CString& sText) { SetParam(1, sText); }
284 };
286 
287 class CNumericMessage : public CMessage {
288  public:
289  unsigned int GetCode() const { return GetCommand().ToUInt(); }
290 };
292 
293 class CKickMessage : public CTargetMessage {
294  public:
295  CString GetKickedNick() const { return GetParam(1); }
296  void SetKickedNick(const CString& sNick) { SetParam(1, sNick); }
297  CString GetReason() const { return GetParam(2); }
298  void SetReason(const CString& sReason) { SetParam(2, sReason); }
299  CString GetText() const { return GetReason(); }
300  void SetText(const CString& sText) { SetReason(sText); }
301 };
303 
304 class CPartMessage : public CTargetMessage {
305  public:
306  CString GetReason() const { return GetParam(1); }
307  void SetReason(const CString& sReason) { SetParam(1, sReason); }
308  CString GetText() const { return GetReason(); }
309  void SetText(const CString& sText) { SetReason(sText); }
310 };
312 
313 class CQuitMessage : public CMessage {
314  public:
315  CString GetReason() const { return GetParam(0); }
316  void SetReason(const CString& sReason) { SetParam(0, sReason); }
317  CString GetText() const { return GetReason(); }
318  void SetText(const CString& sText) { SetReason(sText); }
319 };
321 
322 class CTextMessage : public CTargetMessage {
323  public:
324  CString GetText() const { return GetParam(1); }
325  void SetText(const CString& sText) { SetParam(1, sText); }
326 };
328 
330  public:
331  CString GetTopic() const { return GetParam(1); }
332  void SetTopic(const CString& sTopic) { SetParam(1, sTopic); }
333  CString GetText() const { return GetTopic(); }
334  void SetText(const CString& sText) { SetTopic(sText); }
335 };
337 
338 class CChgHostMessage : public CMessage {
339  public:
340  CString GetNewIdent() const { return GetParam(0); }
341  void SetNewIdent(const CString& sIdent) { SetParam(0, sIdent); }
342  CString GetNewHost() const { return GetParam(1); }
343  void SetNewHost(const CString& sHost) { SetParam(1, sHost); }
344 };
346 
347 #endif // !ZNC_MESSAGE_H
#define REGISTER_ZNC_MESSAGE(M)
Definition: Message.h:186
#define ZNC_MSG_DEPRECATED(msg)
Definition: Message.h:23
std::vector< CString > VCString
Definition: ZNCString.h:38
Definition: Message.h:231
CString GetText() const
Definition: Message.h:233
void SetText(const CString &sText)
Definition: Message.h:236
Definition: Message.h:242
bool IsReply() const
Definition: Message.h:244
CString GetText() const
Definition: Message.h:245
void SetText(const CString &sText)
Definition: Message.h:248
Definition: Chan.h:35
Definition: Message.h:338
void SetNewIdent(const CString &sIdent)
Definition: Message.h:341
CString GetNewIdent() const
Definition: Message.h:340
void SetNewHost(const CString &sHost)
Definition: Message.h:343
CString GetNewHost() const
Definition: Message.h:342
Definition: Client.h:99
Definition: IRCNetwork.h:40
Definition: Message.h:252
void SetKey(const CString &sKey)
Definition: Message.h:255
CString GetKey() const
Definition: Message.h:254
Definition: Message.h:293
CString GetReason() const
Definition: Message.h:297
void SetKickedNick(const CString &sNick)
Definition: Message.h:296
CString GetKickedNick() const
Definition: Message.h:295
void SetText(const CString &sText)
Definition: Message.h:300
void SetReason(const CString &sReason)
Definition: Message.h:298
CString GetText() const
Definition: Message.h:299
Here is a small explanation of how messages on IRC work, and how you can use this class to get useful...
Definition: Message.h:57
void SetTag(const CString &sKey, const CString &sValue)
FormatFlags
Definition: Message.h:146
@ ExcludePrefix
Definition: Message.h:148
@ ExcludeTags
Definition: Message.h:149
@ IncludeAll
Definition: Message.h:147
Type
Definition: Message.h:64
const timeval & GetTime() const
Definition: Message.h:137
void SetNick(const CNick &Nick)
Definition: Message.h:106
void Clone(const CMessage &Other)
void SetClient(CClient *pClient)
Definition: Message.h:99
void SetTime(const timeval &ts)
Definition: Message.h:138
const MCString & GetTags() const
Definition: Message.h:140
Type GetType() const
Definition: Message.h:88
CString ToString(unsigned int uFlags=IncludeAll) const
CClient * GetClient() const
Definition: Message.h:98
CString GetParamsColon(unsigned int uIdx, unsigned int uLen=-1) const
CNick & GetNick()
Definition: Message.h:104
VCString GetParamsSplit(unsigned int uIdx, unsigned int uLen=-1) const
Get a subset of the message parameters.
CChan * GetChan() const
Definition: Message.h:101
bool Equals(const CMessage &Other) const
CString GetParam(unsigned int uIdx) const
CString GetParams(unsigned int uIdx, unsigned int uLen=-1) const ZNC_MSG_DEPRECATED("Use GetParamsColon() instead")
Definition: Message.h:128
CString GetTag(const CString &sKey) const
const VCString & GetParams() const
Definition: Message.h:111
const CNick & GetNick() const
Definition: Message.h:105
void SetChan(CChan *pChan)
Definition: Message.h:102
M & As() &
Definition: Message.h:158
void SetCommand(const CString &sCommand)
CMessage(const CNick &Nick, const CString &sCommand, const VCString &vsParams=VCString(), const MCString &mssTags=MCString::EmptyMap)
CIRCNetwork * GetNetwork() const
Definition: Message.h:94
void SetParams(VCString &&vsParams)
void SetTags(const MCString &mssTags)
Definition: Message.h:141
const M & As() const &
Definition: Message.h:167
const CString & GetCommand() const
Definition: Message.h:108
CMessage(const CString &sMessage="")
void SetNetwork(CIRCNetwork *pNetwork)
Definition: Message.h:95
void SetParams(const VCString &vsParams)
void SetParam(unsigned int uIdx, const CString &sParam)
void Parse(const CString &sMessage)
Definition: Message.h:259
bool HasModes() const
Definition: Message.h:268
VCString GetModeParams() const
Definition: Message.h:266
CString GetModeList() const
Definition: Message.h:264
CString GetModes() const
Definition: Message.h:262
Definition: Message.h:272
void SetNewNick(const CString &sNick)
Definition: Message.h:276
CString GetNewNick() const
Definition: Message.h:275
CString GetOldNick() const
Definition: Message.h:274
Definition: Nick.h:29
const CString & GetNick() const
Definition: Message.h:280
CString GetText() const
Definition: Message.h:282
void SetText(const CString &sText)
Definition: Message.h:283
Definition: Message.h:287
unsigned int GetCode() const
Definition: Message.h:289
Definition: Message.h:304
void SetText(const CString &sText)
Definition: Message.h:309
void SetReason(const CString &sReason)
Definition: Message.h:307
CString GetReason() const
Definition: Message.h:306
CString GetText() const
Definition: Message.h:308
Definition: Message.h:313
CString GetReason() const
Definition: Message.h:315
void SetText(const CString &sText)
Definition: Message.h:318
CString GetText() const
Definition: Message.h:317
void SetReason(const CString &sReason)
Definition: Message.h:316
String class that is used inside ZNC.
Definition: ZNCString.h:68
unsigned int ToUInt() const
@ EDEBUG
Definition: ZNCString.h:76
CString TrimSuffix_n(const CString &sSuffix) const
Trim a given suffix.
CString TrimPrefix_n(const CString &sPrefix=":") const
Trim a given prefix.
bool Equals(const CString &s, CaseSensitivity cs=CaseInsensitive) const
Check if this string is equal to some other string.
Definition: Message.h:224
CString GetTarget() const
Definition: Message.h:226
void SetTarget(const CString &sTarget)
Definition: Message.h:227
Definition: Message.h:322
void SetText(const CString &sText)
Definition: Message.h:325
CString GetText() const
Definition: Message.h:324
Definition: Message.h:329
void SetTopic(const CString &sTopic)
Definition: Message.h:332
CString GetTopic() const
Definition: Message.h:331
void SetText(const CString &sText)
Definition: Message.h:334
CString GetText() const
Definition: Message.h:333
A dictionary for strings.
Definition: ZNCString.h:595
static const MCString EmptyMap
A static instance of an empty map.
Definition: ZNCString.h:606