InspIRCd  2.0
 All Classes Namespaces Functions Variables Typedefs Enumerations
hashcomp.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  * Copyright (C) 2011 Adam <Adam@anope.org>
5  * Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
6  * Copyright (C) 2007, 2009 Dennis Friis <peavey@inspircd.org>
7  * Copyright (C) 2005-2009 Craig Edwards <craigedwards@brainbox.cc>
8  * Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
9  * Copyright (C) 2008 Pippijn van Steenhoven <pip88nl@gmail.com>
10  *
11  * This file is part of InspIRCd. InspIRCd is free software: you can
12  * redistribute it and/or modify it under the terms of the GNU General Public
13  * License as published by the Free Software Foundation, version 2.
14  *
15  * This program is distributed in the hope that it will be useful, but WITHOUT
16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program. If not, see <http://www.gnu.org/licenses/>.
22  */
23 
24 
25 #ifndef HASHCOMP_H
26 #define HASHCOMP_H
27 
28 #include <cstring>
29 #include <string>
30 #include <vector>
31 #include <deque>
32 #include <map>
33 #include <set>
34 #include "hash_map.h"
35 
36 /*******************************************************
37  * This file contains classes and templates that deal
38  * with the comparison and hashing of 'irc strings'.
39  * An 'irc string' is a string which compares in a
40  * case insensitive manner, and as per RFC 1459 will
41  * treat [ identical to {, ] identical to }, and \
42  * as identical to |.
43  *
44  * Our hashing functions are designed to accept
45  * std::string and compare/hash them as type irc::string
46  * by converting them internally. This makes them
47  * backwards compatible with other code which is not
48  * aware of irc::string.
49  *******************************************************/
50 
57 CoreExport extern unsigned const char *national_case_insensitive_map;
58 
62 CoreExport extern unsigned const char rfc_case_insensitive_map[256];
63 
68 CoreExport extern unsigned const char ascii_case_insensitive_map[256];
69 
72 CoreExport extern unsigned const char rfc_case_sensitive_map[256];
73 
74 template<typename T> const T& SearchAndReplace(T& text, const T& pattern, const T& replace)
75 {
76  T replacement;
77  if ((!pattern.empty()) && (!text.empty()))
78  {
79  for (std::string::size_type n = 0; n != text.length(); ++n)
80  {
81  if (text.length() >= pattern.length() && text.substr(n, pattern.length()) == pattern)
82  {
83  /* Found the pattern in the text, replace it, and advance */
84  replacement.append(replace);
85  n = n + pattern.length() - 1;
86  }
87  else
88  {
89  replacement += text[n];
90  }
91  }
92  }
93  text = replacement;
94  return text;
95 }
96 
99 namespace irc
100 {
101 
106  struct CoreExport StrHashComp
107  {
110  bool operator()(const std::string& s1, const std::string& s2) const;
111  };
112 
117  struct irc_char_traits : std::char_traits<char> {
118 
124  static bool eq(char c1st, char c2nd);
125 
131  static bool ne(char c1st, char c2nd);
132 
138  static bool lt(char c1st, char c2nd);
139 
147  static CoreExport int compare(const char* str1, const char* str2, size_t n);
148 
155  static CoreExport const char* find(const char* s1, int n, char c);
156  };
157 
163  CoreExport std::string hex(const unsigned char *raw, size_t rawsz);
164 
167  typedef std::basic_string<char, irc_char_traits, std::allocator<char> > string;
168 
175  class CoreExport stringjoiner
176  {
177  private:
178 
181  std::string joined;
182 
183  public:
184 
191  stringjoiner(const std::string &seperator, const std::vector<std::string> &sequence, int begin, int end);
192 
199  stringjoiner(const std::string &seperator, const std::deque<std::string> &sequence, int begin, int end);
200 
207  stringjoiner(const std::string &seperator, const char* const* sequence, int begin, int end);
208 
212  std::string& GetJoined();
213  };
214 
219  class CoreExport modestacker
220  {
221  private:
224  std::deque<std::string> sequence;
225 
230  bool adding;
231  public:
232 
237  modestacker(bool add);
238 
247  void Push(char modeletter, const std::string &parameter);
248 
256  void Push(char modeletter);
257 
260  void PushPlus();
261 
264  void PushMinus();
265 
282  int GetStackedLine(std::vector<std::string> &result, int max_line_size = 360);
283 
285  int GetStackedLine(std::deque<std::string> &result, int max_line_size = 360) {
286  std::vector<std::string> r;
287  int n = GetStackedLine(r, max_line_size);
288  result.clear();
289  result.insert(result.end(), r.begin(), r.end());
290  return n;
291  }
292  };
293 
306  class CoreExport tokenstream
307  {
308  private:
309 
312  std::string tokens;
313 
316  std::string::iterator last_starting_position;
317 
320  std::string::iterator n;
321 
324  bool last_pushed;
325  public:
326 
329  tokenstream(const std::string &source);
330 
333  ~tokenstream();
334 
339  bool GetToken(std::string &token);
340 
345  bool GetToken(irc::string &token);
346 
351  bool GetToken(int &token);
352 
357  bool GetToken(long &token);
358  };
359 
365  class CoreExport sepstream
366  {
367  private:
370  std::string tokens;
373  std::string::iterator last_starting_position;
376  std::string::iterator n;
379  char sep;
380  public:
383  sepstream(const std::string &source, char seperator);
384 
387  virtual ~sepstream();
388 
393  virtual bool GetToken(std::string &token);
394 
398  virtual const std::string GetRemaining();
399 
403  virtual bool StreamEnd();
404  };
405 
408  class CoreExport commasepstream : public sepstream
409  {
410  public:
413  commasepstream(const std::string &source) : sepstream(source, ',')
414  {
415  }
416  };
417 
420  class CoreExport spacesepstream : public sepstream
421  {
422  public:
425  spacesepstream(const std::string &source) : sepstream(source, ' ')
426  {
427  }
428  };
429 
438  class CoreExport portparser
439  {
440  private:
441 
444  commasepstream sep;
445 
448  long in_range;
449 
452  long range_begin;
453 
456  long range_end;
457 
460  bool overlapped;
461 
465  std::set<long> overlap_set;
466 
469  bool Overlaps(long val);
470  public:
471 
476  portparser(const std::string &source, bool allow_overlapped = true);
477 
481  long GetToken();
482  };
483 
488  CoreExport const char* Spacify(const char* n);
489 
490  struct hash
491  {
496  size_t CoreExport operator()(const irc::string &s) const;
497  };
498 }
499 
500 /* Define operators for using >> and << with irc::string to an ostream on an istream. */
501 /* This was endless fun. No. Really. */
502 /* It was also the first core change Ommeh made, if anyone cares */
503 
506 inline std::ostream& operator<<(std::ostream &os, const irc::string &str) { return os << str.c_str(); }
507 
510 inline std::istream& operator>>(std::istream &is, irc::string &str)
511 {
512  std::string tmp;
513  is >> tmp;
514  str = tmp.c_str();
515  return is;
516 }
517 
518 /* Define operators for + and == with irc::string to std::string for easy assignment
519  * and comparison
520  *
521  * Operator +
522  */
523 inline std::string operator+ (std::string& leftval, irc::string& rightval)
524 {
525  return leftval + std::string(rightval.c_str());
526 }
527 
528 /* Define operators for + and == with irc::string to std::string for easy assignment
529  * and comparison
530  *
531  * Operator +
532  */
533 inline irc::string operator+ (irc::string& leftval, std::string& rightval)
534 {
535  return leftval + irc::string(rightval.c_str());
536 }
537 
538 /* Define operators for + and == with irc::string to std::string for easy assignment
539  * and comparison
540  *
541  * Operator ==
542  */
543 inline bool operator== (const std::string& leftval, const irc::string& rightval)
544 {
545  return (leftval.c_str() == rightval);
546 }
547 
548 /* Define operators for + and == with irc::string to std::string for easy assignment
549  * and comparison
550  *
551  * Operator ==
552  */
553 inline bool operator== (const irc::string& leftval, const std::string& rightval)
554 {
555  return (leftval == rightval.c_str());
556 }
557 
558 /* Define operators != for irc::string to std::string for easy comparison
559  */
560 inline bool operator!= (const irc::string& leftval, const std::string& rightval)
561 {
562  return !(leftval == rightval.c_str());
563 }
564 
565 /* Define operators != for std::string to irc::string for easy comparison
566  */
567 inline bool operator!= (const std::string& leftval, const irc::string& rightval)
568 {
569  return !(leftval.c_str() == rightval);
570 }
571 
574 inline std::string assign(const irc::string &other) { return other.c_str(); }
575 
578 inline irc::string assign(const std::string &other) { return other.c_str(); }
579 
582 inline std::string& trim(std::string &str)
583 {
584  std::string::size_type start = str.find_first_not_of(" ");
585  std::string::size_type end = str.find_last_not_of(" ");
586  if (start == std::string::npos || end == std::string::npos)
587  str = "";
588  else
589  str = str.substr(start, end-start+1);
590 
591  return str;
592 }
593 
597 BEGIN_HASHMAP_NAMESPACE
598 
601 #if defined(_WIN32) && !defined(HAS_TR1_UNORDERED)
602  template<> class CoreExport hash_compare<irc::string, std::less<irc::string> >
603  {
604  public:
605  enum { bucket_size = 4, min_buckets = 8 }; /* Got these numbers from the CRT source, if anyone wants to change them feel free. */
606 
609  bool operator()(const irc::string & s1, const irc::string & s2) const
610  {
611  if(s1.length() != s2.length()) return true;
612  return (irc::irc_char_traits::compare(s1.c_str(), s2.c_str(), (size_t)s1.length()) < 0);
613  }
614 
617  size_t operator()(const irc::string & s) const;
618  };
619 
620  template<> class CoreExport hash_compare<std::string, std::less<std::string> >
621  {
622  public:
623  enum { bucket_size = 4, min_buckets = 8 }; /* Again, from the CRT source */
624 
627  bool operator()(const std::string & s1, const std::string & s2) const
628  {
629  if(s1.length() != s2.length()) return true;
630  return (irc::irc_char_traits::compare(s1.c_str(), s2.c_str(), (size_t)s1.length()) < 0);
631  }
632 
637  size_t operator()(const std::string & s) const;
638  };
639 #else
640 
641  /* XXX FIXME: Implement a hash function overriding std::string's that works with TR1! */
642 
643 #ifdef HASHMAP_DEPRECATED
644  struct insensitive
645 #else
646  CoreExport template<> struct hash<std::string>
647 #endif
648  {
649  size_t CoreExport operator()(const std::string &s) const;
650  };
651 
652 #endif
653 
657  void strlower(char *n);
658 
659 END_HASHMAP_NAMESPACE
660 
661 #endif
CoreExport std::string hex(const unsigned char *raw, size_t rawsz)
Definition: hashcomp.cpp:347
Definition: hashcomp.h:219
static CoreExport const char * find(const char *s1, int n, char c)
Definition: hashcomp.cpp:213
int GetStackedLine(std::deque< std::string > &result, int max_line_size=360)
Definition: hashcomp.h:285
Definition: hashcomp.h:306
std::basic_string< char, irc_char_traits, std::allocator< char > > string
Definition: hashcomp.h:167
Definition: hashcomp.h:365
CoreExport const char * Spacify(const char *n)
Definition: hashcomp.cpp:368
static bool ne(char c1st, char c2nd)
Definition: hashcomp.cpp:184
static bool lt(char c1st, char c2nd)
Definition: hashcomp.cpp:189
commasepstream(const std::string &source)
Definition: hashcomp.h:413
Definition: hashcomp.h:420
spacesepstream(const std::string &source)
Definition: hashcomp.h:425
Definition: hashcomp.h:106
static bool eq(char c1st, char c2nd)
Definition: hashcomp.cpp:179
Definition: hashcomp.h:438
size_t CoreExport operator()(const irc::string &s) const
Definition: hashcomp.cpp:150
Definition: hashcomp.h:490
Definition: hashcomp.h:117
void strlower(char *n)
Definition: hashcomp.h:408
static CoreExport int compare(const char *str1, const char *str2, size_t n)
Definition: hashcomp.cpp:194
Definition: hashcomp.h:175