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