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