searchPattern.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #include <algorithm>
  2. #include <sstream>
  3. #include "searchPattern.hh"
  4. #include "jsonObjectEntry.hh"
  5. #include "jsonPrimitive.hh"
  6. SearchPattern::SearchPattern(const std::string &input): flags(0)
  7. {
  8. size_t pos = 0;
  9. bool escaped = false;
  10. std::stringstream ss;
  11. for (pos =0; input[pos] && (input[pos] == ' ' || input[pos] == '\t'); ++pos); //trim leading characters
  12. for (; input[pos]; ++pos)
  13. {
  14. if (escaped)
  15. {
  16. if (input[pos] == '/')
  17. ss.put(input[pos]);
  18. else
  19. ss.put('\\').put(input[pos]);
  20. escaped = false;
  21. }
  22. else if (input[pos] == '\\')
  23. escaped = true;
  24. else if (input[pos] == '/')
  25. {
  26. pattern = ss.str();
  27. evalFlags(&input[pos +1]);
  28. return;
  29. }
  30. else
  31. ss.put(input[pos]);
  32. }
  33. pattern = ss.str();
  34. }
  35. SearchPattern::~SearchPattern()
  36. { }
  37. void SearchPattern::evalFlags(const char *s)
  38. {
  39. while (*s)
  40. {
  41. if (*s == 'i')
  42. {
  43. flags |= SearchPattern::FLAG_CASE;
  44. std::transform(pattern.begin(), pattern.end(), pattern.begin(), ::tolower);
  45. }
  46. else if (*s == 'b')
  47. typeFlag = SearchPattern::TYPE_BOOL;
  48. else if (*s == 'n')
  49. typeFlag = SearchPattern::TYPE_NUMBER;
  50. else if (*s == 's')
  51. typeFlag = SearchPattern::TYPE_STRING;
  52. else if (*s == 'o')
  53. typeFlag = SearchPattern::TYPE_OBJKEY;
  54. else if (*s == 'w')
  55. flags |= SearchPattern::FLAG_WHOLEWORD;
  56. else if (*s == 'f')
  57. flags |= SearchPattern::FLAG_WHOLESTR;
  58. s++;
  59. }
  60. }
  61. bool SearchPattern::isEmpty() const
  62. { return pattern.empty(); }
  63. bool SearchPattern::operator()(char a, char b)
  64. {
  65. if (a == '\t')
  66. a = ' ';
  67. if (flags & SearchPattern::FLAG_CASE)
  68. return std::tolower(a) == b;
  69. return a == b;
  70. }
  71. bool SearchPattern::match(const std::string &str, const JSonElement *type) const
  72. {
  73. if (typeFlag)
  74. {
  75. if (typeFlag == SearchPattern::TYPE_BOOL && !(dynamic_cast<const JSonPrimitive<bool> *>(type)))
  76. return false;
  77. else if (typeFlag == SearchPattern::TYPE_STRING && !(dynamic_cast<const JSonPrimitive<std::string> *>(type)))
  78. return false;
  79. else if (typeFlag == SearchPattern::TYPE_OBJKEY && !(dynamic_cast<const JSonObjectEntry *>(type)))
  80. return false;
  81. else if (typeFlag == SearchPattern::TYPE_NUMBER &&
  82. !(dynamic_cast<const JSonPrimitive<int> *>(type)) &&
  83. !(dynamic_cast<const JSonPrimitive<double> *>(type)) &&
  84. !(dynamic_cast<const JSonPrimitive<long long> *>(type)))
  85. return false;
  86. }
  87. if ((flags & FLAG_WHOLESTR && str.length() != pattern.length())
  88. || pattern.length() > str.length())
  89. return false;
  90. if (flags & FLAG_WHOLEWORD && str.length() > pattern.length())
  91. {
  92. std::string pattern = " " +this->pattern +' ';
  93. return std::search(str.begin(), str.end(), pattern.begin(), pattern.end(), *this) != str.end();
  94. }
  95. return std::search(str.begin(), str.end(), pattern.begin(), pattern.end(), *this) != str.end();
  96. }
  97. const short SearchPattern::FLAG_CASE = 1;
  98. const short SearchPattern::FLAG_WHOLEWORD = 2;
  99. const short SearchPattern::FLAG_WHOLESTR = 4;
  100. const short SearchPattern::TYPE_BOOL = 1;
  101. const short SearchPattern::TYPE_NUMBER = 2;
  102. const short SearchPattern::TYPE_STRING = 3;
  103. const short SearchPattern::TYPE_OBJKEY = 4;