2
* Copyright (C) 2004-2011 See the AUTHORS file for details.
4
* This program is free software; you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License version 2 as published
6
* by the Free Software Foundation.
12
#include "zncconfig.h"
18
#include <sys/types.h>
27
#define _SQL(s) CString("'" + CString(s).Escape_n(CString::ESQL) + "'")
28
#define _URL(s) CString(s).Escape_n(CString::EURL)
29
#define _HTML(s) CString(s).Escape_n(CString::EHTML)
34
typedef set<CString> SCString;
35
typedef vector<CString> VCString;
36
typedef vector<pair<CString, CString> > VPair;
38
static const unsigned char XX = 0xff;
39
static const unsigned char base64_table[256] = {
40
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
41
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
42
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,62, XX,XX,XX,63,
43
52,53,54,55, 56,57,58,59, 60,61,XX,XX, XX,XX,XX,XX,
44
XX, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
45
15,16,17,18, 19,20,21,22, 23,24,25,XX, XX,XX,XX,XX,
46
XX,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
47
41,42,43,44, 45,46,47,48, 49,50,51,XX, XX,XX,XX,XX,
48
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
49
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
50
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
51
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
52
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
53
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
54
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
55
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
59
* @brief String class that is used inside znc.
61
* All strings that are used in ZNC and its modules should use instances of this
62
* class. It provides helpful functions for parsing input like Token() and
65
class CString : public string {
74
explicit CString(bool b) : string(b ? "true" : "false") {}
75
explicit CString(char c);
76
explicit CString(unsigned char c);
77
explicit CString(short i);
78
explicit CString(unsigned short i);
79
explicit CString(int i);
80
explicit CString(unsigned int i);
81
explicit CString(long i);
82
explicit CString(unsigned long i);
83
explicit CString(long long i);
84
explicit CString(unsigned long long i);
85
explicit CString(double i, int precision = 2);
86
explicit CString(float i, int precision = 2);
88
CString() : string() {}
89
CString(const char* c) : string(c) {}
90
CString(const char* c, size_t l) : string(c, l) {}
91
CString(const string& s) : string(s) {}
95
* Compare this string caselessly to some other string.
96
* @param s The string to compare to.
97
* @param uLen The number of characters to compare.
98
* @return An integer less than, equal to, or greater than zero if this
99
* string smaller, equal.... to the given string.
101
int CaseCmp(const CString& s, unsigned long uLen = CString::npos) const;
103
* Compare this string case sensitively to some other string.
104
* @param s The string to compare to.
105
* @param uLen The number of characters to compare.
106
* @return An integer less than, equal to, or greater than zero if this
107
* string smaller, equal.... to the given string.
109
int StrCmp(const CString& s, unsigned long uLen = CString::npos) const;
111
* Check if this string is equal to some other string.
112
* @param s The string to compare to.
113
* @param bCaseSensitive True if you want the comparision to be case
115
* @param uLen Number of characters to consider.
116
* @return True if the strings are equal.
118
bool Equals(const CString& s, bool bCaseSensitive = false, unsigned long uLen = CString::npos) const;
120
* Do a wildcard comparision between two strings.
121
* For example, the following returns true:
122
* <code>WildCmp("*!?bar@foo", "I_am!~bar@foo");</code>
123
* @param sWild The wildcards used for the comparison.
124
* @param sString The string that is used for comparing.
125
* @return true if the wildcard matches.
127
static bool WildCmp(const CString& sWild, const CString& sString);
129
* Do a wild compare on this string.
130
* @param sWild The wildcards used to for the comparison.
131
* @return The result of <code>this->WildCmp(sWild, *this);</code>.
133
bool WildCmp(const CString& sWild) const;
136
* Turn all characters in this string into their upper-case equivalent.
137
* @returns A reference to *this.
139
CString& MakeUpper();
141
* Turn all characters in this string into their lower-case equivalent.
142
* @returns A reference to *this.
144
CString& MakeLower();
146
* Return a copy of this string with all characters turned into
148
* @return The new string.
150
CString AsUpper() const;
152
* Return a copy of this string with all characters turned into
154
* @return The new string.
156
CString AsLower() const;
158
static EEscape ToEscape(const CString& sEsc);
159
CString Escape_n(EEscape eFrom, EEscape eTo) const;
160
CString Escape_n(EEscape eTo) const;
161
CString& Escape(EEscape eFrom, EEscape eTo);
162
CString& Escape(EEscape eTo);
164
/** Replace all occurrences in a string.
166
* You can specify a "safe zone" via sLeft and sRight. Anything inside
167
* of such a zone will not be replaced. This does not do recursion, so
168
* e.g. with <code>Replace("(a()a)", "a", "b", "(", ")", true)</code>
169
* you would get "a(b)" as result. The second opening brace and the
170
* second closing brace would not be seen as a delimitered and thus
171
* wouldn't be removed. The first a is inside a "safe zone" and thus is
174
* @param sStr The string to do the replacing on. This will also contain
175
* the result when this function returns.
176
* @param sReplace The string that should be replaced.
177
* @param sWith The replacement to use.
178
* @param sLeft The string that marks the begin of the "safe zone".
179
* @param sRight The string that marks the end of the "safe zone".
180
* @param bRemoveDelims If this is true, all matches for sLeft and
181
* sRight are removed.
182
* @returns The number of replacements done.
184
static unsigned int Replace(CString& sStr, const CString& sReplace, const CString& sWith, const CString& sLeft = "", const CString& sRight = "", bool bRemoveDelims = false);
186
/** Replace all occurrences in the current string.
187
* @see CString::Replace
188
* @param sReplace The string to look for.
189
* @param sWith The replacement to use.
190
* @param sLeft The delimiter at the beginning of a safe zone.
191
* @param sRight The delimiter at the end of a safe zone.
192
* @param bRemoveDelims If true, all matching delimiters are removed.
193
* @return The result of the replacing. The current string is left
196
CString Replace_n(const CString& sReplace, const CString& sWith, const CString& sLeft = "", const CString& sRight = "", bool bRemoveDelims = false) const;
197
/** Replace all occurrences in the current string.
198
* @see CString::Replace
199
* @param sReplace The string to look for.
200
* @param sWith The replacement to use.
201
* @param sLeft The delimiter at the beginning of a safe zone.
202
* @param sRight The delimiter at the end of a safe zone.
203
* @param bRemoveDelims If true, all matching delimiters are removed.
204
* @returns The number of replacements done.
206
unsigned int Replace(const CString& sReplace, const CString& sWith, const CString& sLeft = "", const CString& sRight = "", bool bRemoveDelims = false);
207
/** Ellipsize the current string.
208
* For example, ellipsizing "Hello, I'm Bob" to the length 9 would
209
* result in "Hello,...".
210
* @param uLen The length to ellipsize to.
211
* @return The ellipsized string.
213
CString Ellipsize(unsigned int uLen) const;
214
/** Return the left part of the string.
215
* @param uCount The number of characters to keep.
216
* @return The resulting string.
218
CString Left(unsigned int uCount) const;
219
/** Return the right part of the string.
220
* @param uCount The number of characters to keep.
221
* @return The resulting string.
223
CString Right(unsigned int uCount) const;
225
/** Get the first line of this string.
226
* @return The first line of text.
228
CString FirstLine() const { return Token(0, false, "\n"); }
230
/** Get a token out of this string. For example in the string "a bc d e",
231
* each of "a", "bc", "d" and "e" are tokens.
232
* @param uPos The number of the token you are interested. The first
233
* token has a position of 0.
234
* @param bRest If false, only the token you asked for is returned. Else
235
* you get the substring starting from the beginning of
237
* @param sSep Seperator between tokens.
238
* @param bAllowEmpty If this is true, empty tokens are allowed. In the
239
* example from above this means that there is a
240
* token "" before the "e" token.
241
* @return The token you asked for and, if bRest is true, everything
243
* @see Split() if you need a string split into all of its tokens.
245
CString Token(unsigned int uPos, bool bRest = false, const CString& sSep = " ", bool bAllowEmpty = false) const;
247
/** Get a token out of this string. This function behaves much like the
248
* other Token() function in this class. The extra arguments are
249
* handled similarly to Split().
251
CString Token(unsigned int uPos, bool bRest, const CString& sSep, bool bAllowEmpty, const CString& sLeft, const CString& sRight, bool bTrimQuotes = true) const;
253
unsigned int URLSplit(MCString& msRet) const;
254
unsigned int OptionSplit(MCString& msRet, bool bUpperKeys = false) const;
255
unsigned int QuoteSplit(VCString& vsRet) const;
257
/** Split up this string into tokens.
258
* Via sLeft and sRight you can define "markers" like with Replace().
259
* Anything in such a marked section is treated as a single token. All
260
* occurences of sDelim in such a block are ignored.
261
* @param sDelim Delimiter between tokens.
262
* @param vsRet Vector for returning the result.
263
* @param bAllowEmpty Do empty tokens count as a valid token?
264
* @param sLeft Left delimiter like with Replace().
265
* @param sRight Right delimiter like with Replace().
266
* @param bTrimQuotes Should sLeft and sRight be removed from the token
268
* @param bTrimWhiteSpace If this is true, CString::Trim() is called on
270
* @return The number of tokens found.
272
unsigned int Split(const CString& sDelim, VCString& vsRet, bool bAllowEmpty = true,
273
const CString& sLeft = "", const CString& sRight = "", bool bTrimQuotes = true,
274
bool bTrimWhiteSpace = false) const;
276
/** Split up this string into tokens.
277
* This function is identical to the other CString::Split(), except that
278
* the result is returned as a SCString instead of a VCString.
280
unsigned int Split(const CString& sDelim, SCString& ssRet, bool bAllowEmpty = true,
281
const CString& sLeft = "", const CString& sRight = "", bool bTrimQuotes = true,
282
bool bTrimWhiteSpace = false) const;
284
/** Produces a random string.
285
* @param uLength The length of the resulting string.
286
* @return A random string.
288
static CString RandomString(unsigned int uLength);
290
/** @return The MD5 hash of this string. */
292
/** @return The SHA256 hash of this string. */
293
CString SHA256() const;
295
/** Treat this string as base64-encoded data and decode it.
296
* @param sRet String to which the result of the decode is safed.
297
* @return The length of the resulting string.
299
unsigned long Base64Decode(CString& sRet) const;
300
/** Treat this string as base64-encoded data and decode it.
301
* The result is saved in this CString instance.
302
* @return The length of the resulting string.
304
unsigned long Base64Decode();
305
/** Treat this string as base64-encoded data and decode it.
306
* @return The decoded string.
308
CString Base64Decode_n() const;
309
/** Base64-encode the current string.
310
* @param sRet String where the result is saved.
311
* @param uWrap A boolean(!?!) that decides if the result should be
312
* wrapped after everywhere 57 characters.
313
* @return true unless this code is buggy.
315
* @todo This only returns false if some formula we use was wrong?!
317
bool Base64Encode(CString& sRet, unsigned int uWrap = 0) const;
318
/** Base64-encode the current string.
319
* This string is overwritten with the result of the encode.
320
* @todo return value and param are as with Base64Encode() from above.
322
bool Base64Encode(unsigned int uWrap = 0);
323
/** Base64-encode the current string
324
* @todo uWrap is as broken as Base64Encode()'s uWrap.
325
* @return The encoded string.
327
CString Base64Encode_n(unsigned int uWrap = 0) const;
330
CString Encrypt_n(const CString& sPass, const CString& sIvec = "") const;
331
CString Decrypt_n(const CString& sPass, const CString& sIvec = "") const;
332
void Encrypt(const CString& sPass, const CString& sIvec = "");
333
void Decrypt(const CString& sPass, const CString& sIvec = "");
334
void Crypt(const CString& sPass, bool bEncrypt, const CString& sIvec = "");
337
/** Pretty-print a percent value.
338
* @param d The percent value. This should be in range 0-100.
339
* @return The "pretty" string.
341
static CString ToPercent(double d);
342
/** Pretty-print a number of bytes.
343
* @param d The number of bytes.
344
* @return A string describing the number of bytes.
346
static CString ToByteStr(unsigned long long d);
347
/** Pretty-print a time span.
348
* @param s Number of seconds to print.
349
* @return A string like "4w 6d 4h 3m 58s".
351
static CString ToTimeStr(unsigned long s);
353
/** @return True if this string is not "false". */
355
/** @return The numerical value of this string similar to atoi(). */
356
short ToShort() const;
357
/** @return The numerical value of this string similar to atoi(). */
358
unsigned short ToUShort() const;
359
/** @return The numerical value of this string similar to atoi(). */
361
/** @return The numerical value of this string similar to atoi(). */
363
/** @return The numerical value of this string similar to atoi(). */
364
unsigned int ToUInt() const;
365
/** @return The numerical value of this string similar to atoi(). */
366
unsigned long ToULong() const;
367
/** @return The numerical value of this string similar to atoi(). */
368
unsigned long long ToULongLong() const;
369
/** @return The numerical value of this string similar to atoi(). */
370
long long ToLongLong() const;
371
/** @return The numerical value of this string similar to atoi(). */
372
double ToDouble() const;
374
/** Trim this string. All leading/trailing occurences of characters from
376
* @param s A list of characters that should be trimmed.
377
* @return true if this string was modified.
379
bool Trim(const CString& s = " \t\r\n");
380
/** Trim this string. All leading occurences of characters from s are
382
* @param s A list of characters that should be trimmed.
383
* @return true if this string was modified.
385
bool TrimLeft(const CString& s = " \t\r\n");
386
/** Trim this string. All trailing occurences of characters from s are
388
* @param s A list of characters that should be trimmed.
389
* @return true if this string was modified.
391
bool TrimRight(const CString& s = " \t\r\n");
392
/** Trim this string. All leading/trailing occurences of characters from
393
* s are removed. This CString instance is not modified.
394
* @param s A list of characters that should be trimmed.
395
* @return The trimmed string.
397
CString Trim_n(const CString& s = " \t\r\n") const;
398
/** Trim this string. All leading occurences of characters from s are
399
* removed. This CString instance is not modified.
400
* @param s A list of characters that should be trimmed.
401
* @return The trimmed string.
403
CString TrimLeft_n(const CString& s = " \t\r\n") const;
404
/** Trim this string. All trailing occurences of characters from s are
405
* removed. This CString instance is not modified.
406
* @param s A list of characters that should be trimmed.
407
* @return The trimmed string.
409
CString TrimRight_n(const CString& s = " \t\r\n") const;
411
/** Trim a given prefix.
412
* @param sPrefix The prefix that should be removed.
413
* @return True if this string was modified.
415
bool TrimPrefix(const CString& sPrefix);
416
/** Trim a given suffix.
417
* @param sSuffix The suffix that should be removed.
418
* @return True if this string was modified.
420
bool TrimSuffix(const CString& sSuffix);
421
/** Trim a given prefix.
422
* @param sPrefix The prefix that should be removed.
423
* @return A copy of this string without the prefix.
425
CString TrimPrefix_n(const CString& sPrefix) const;
426
/** Trim a given suffix.
427
* @param sSuffix The suffix that should be removed.
428
* @return A copy of this string without the prefix.
430
CString TrimSuffix_n(const CString& sSuffix) const;
432
/** Remove characters from the beginning of this string.
433
* @param uLen The number of characters to remove.
434
* @return true if this string was modified.
436
bool LeftChomp(unsigned int uLen = 1);
437
/** Remove characters from the end of this string.
438
* @param uLen The number of characters to remove.
439
* @return true if this string was modified.
441
bool RightChomp(unsigned int uLen = 1);
442
/** Remove characters from the beginning of this string.
443
* This string object isn't modified.
444
* @param uLen The number of characters to remove.
445
* @return The result of the conversion.
447
CString LeftChomp_n(unsigned int uLen = 1) const;
448
/** Remove characters from the end of this string.
449
* This string object isn't modified.
450
* @param uLen The number of characters to remove.
451
* @return The result of the conversion.
453
CString RightChomp_n(unsigned int uLen = 1) const;
457
unsigned char* strnchr(const unsigned char* src, unsigned char c, unsigned int iMaxBytes, unsigned char* pFill = NULL, unsigned int* piCount = NULL) const;
461
* @brief A dictionary for strings.
463
* This class maps strings to other strings.
465
class MCString : public map<CString, CString> {
467
/** Construct an empty MCString. */
468
MCString() : map<CString, CString>() {}
469
/** Destruct this MCString. */
470
virtual ~MCString() { clear(); }
472
/** Status codes that can be returned by WriteToDisk() and
478
/// Opening the file failed.
480
/// Writing to the file failed.
482
/// WriteFilter() failed.
484
/// ReadFilter() failed.
488
/** Write this map to a file.
489
* @param sPath The file name to write to.
490
* @param iMode The mode for the file.
491
* @return The result of the operation.
494
enum status_t WriteToDisk(const CString& sPath, mode_t iMode = 0644) const;
495
/** Read a map from a file.
496
* @param sPath The file name to read from.
497
* @return The result of the operation.
500
enum status_t ReadFromDisk(const CString& sPath);
502
/** Filter used while writing this map. This function is called by
503
* WriteToDisk() for each pair that is going to be written. This
504
* function has the chance to modify the data that will be written.
505
* @param sKey The key that will be written. Can be modified.
506
* @param sValue The value that will be written. Can be modified.
507
* @return true unless WriteToDisk() should fail with MCS_EWRITEFIL.
509
virtual bool WriteFilter(CString& sKey, CString& sValue) const { return true; }
510
/** Filter used while reading this map. This function is called by
511
* ReadFromDisk() for each pair that is beging read. This function has
512
* the chance to modify the data that is being read.
513
* @param sKey The key that was read. Can be modified.
514
* @param sValue The value that was read. Can be modified.
515
* @return true unless ReadFromDisk() should fail with MCS_EWRITEFIL.
517
virtual bool ReadFilter(CString& sKey, CString& sValue) const { return true; }
519
/** Encode a value so that it can safely be parsed by ReadFromDisk().
520
* This is an internal function.
522
virtual CString& Encode(CString& sValue) const;
523
/** Undo the effects of Encode(). This is an internal function. */
524
virtual CString& Decode(CString& sValue) const;
527
#endif // !ZNCSTRING_H