00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __PION_COMPARISON_HEADER__
00021 #define __PION_COMPARISON_HEADER__
00022
00023 #include <boost/scoped_array.hpp>
00024 #include <boost/regex.hpp>
00025 #include <boost/regex/icu.hpp>
00026 #include <boost/logic/tribool.hpp>
00027 #include <boost/algorithm/string/compare.hpp>
00028 #include <boost/algorithm/string/predicate.hpp>
00029 #include <boost/tuple/tuple.hpp>
00030 #include <pion/PionConfig.hpp>
00031 #include <pion/PionException.hpp>
00032 #include <pion/platform/Vocabulary.hpp>
00033 #include <pion/platform/Event.hpp>
00034 #include <unicode/uiter.h>
00035 #include <unicode/ustring.h>
00036 #include <unicode/stsearch.h>
00037
00038 namespace pion {
00039 namespace platform {
00040
00044 class PION_PLATFORM_API Comparison
00045 {
00046 public:
00047
00049 enum ComparisonType {
00050 TYPE_FALSE = 0,
00051 TYPE_TRUE,
00052 TYPE_IS_DEFINED,
00053 TYPE_IS_NOT_DEFINED,
00054
00055 TYPE_EQUALS,
00056 TYPE_NOT_EQUALS,
00057 TYPE_GREATER_THAN,
00058 TYPE_LESS_THAN,
00059 TYPE_GREATER_OR_EQUAL,
00060 TYPE_LESS_OR_EQUAL,
00061
00062 TYPE_EXACT_MATCH,
00063 TYPE_NOT_EXACT_MATCH,
00064 TYPE_CONTAINS,
00065 TYPE_NOT_CONTAINS,
00066 TYPE_STARTS_WITH,
00067 TYPE_NOT_STARTS_WITH,
00068 TYPE_ENDS_WITH,
00069 TYPE_NOT_ENDS_WITH,
00070 TYPE_ORDERED_BEFORE,
00071 TYPE_NOT_ORDERED_BEFORE,
00072 TYPE_ORDERED_AFTER,
00073 TYPE_NOT_ORDERED_AFTER,
00074 TYPE_REGEX,
00075 TYPE_NOT_REGEX,
00076
00077 TYPE_EXACT_MATCH_PRIMARY,
00078 TYPE_NOT_EXACT_MATCH_PRIMARY,
00079 TYPE_CONTAINS_PRIMARY,
00080 TYPE_NOT_CONTAINS_PRIMARY,
00081 TYPE_STARTS_WITH_PRIMARY,
00082 TYPE_NOT_STARTS_WITH_PRIMARY,
00083 TYPE_ENDS_WITH_PRIMARY,
00084 TYPE_NOT_ENDS_WITH_PRIMARY,
00085 TYPE_ORDERED_BEFORE_PRIMARY,
00086 TYPE_NOT_ORDERED_BEFORE_PRIMARY,
00087 TYPE_ORDERED_AFTER_PRIMARY,
00088 TYPE_NOT_ORDERED_AFTER_PRIMARY,
00089
00090 TYPE_SAME_DATE_TIME,
00091 TYPE_NOT_SAME_DATE_TIME,
00092 TYPE_EARLIER_DATE_TIME,
00093 TYPE_LATER_DATE_TIME,
00094 TYPE_SAME_OR_EARLIER_DATE_TIME,
00095 TYPE_SAME_OR_LATER_DATE_TIME,
00096
00097 TYPE_SAME_DATE,
00098 TYPE_NOT_SAME_DATE,
00099 TYPE_EARLIER_DATE,
00100 TYPE_LATER_DATE,
00101 TYPE_SAME_OR_EARLIER_DATE,
00102 TYPE_SAME_OR_LATER_DATE,
00103
00104 TYPE_SAME_TIME,
00105 TYPE_NOT_SAME_TIME,
00106 TYPE_EARLIER_TIME,
00107 TYPE_LATER_TIME,
00108 TYPE_SAME_OR_EARLIER_TIME,
00109 TYPE_SAME_OR_LATER_TIME,
00110
00111 LAST_COMPARISON_TYPE = TYPE_SAME_OR_LATER_TIME
00112 };
00113
00115 class UnknownComparisonTypeException : public PionException {
00116 public:
00117 UnknownComparisonTypeException(const std::string& comparison_type)
00118 : PionException("Could not parse unknown comparison type: ", comparison_type) {}
00119 };
00120
00122 class InvalidComparisonException : public std::exception {
00123 public:
00124 virtual const char* what() const throw() {
00125 return "An invalid comparison was attempted";
00126 }
00127 };
00128
00130 class InvalidTypeForTermException : public std::exception {
00131 public:
00132 virtual const char* what() const throw() {
00133 return "Invalid comparison type given for Vocabulary Term";
00134 }
00135 };
00136
00138 class InvalidValueForTypeException : public std::exception {
00139 public:
00140 virtual const char* what() const throw() {
00141 return "Invalid value given for comparison type";
00142 }
00143 };
00144
00145
00147 virtual ~Comparison() {}
00148
00154 explicit Comparison(const Vocabulary::Term& term)
00155 : m_term(term), m_type(TYPE_FALSE), m_match_all_values(false)
00156 {}
00157
00159 Comparison(const Comparison& c)
00160 : m_term(c.m_term), m_type(c.m_type), m_value(c.m_value),
00161 m_str_value(c.m_str_value), m_comparison_func(c.m_comparison_func),
00162 m_regex(c.m_regex), m_match_all_values(c.m_match_all_values)
00163 {}
00164
00172 inline bool evaluate(const Event& e) const;
00173
00181 inline bool evaluateRange(const Event::ValuesRange& values_range) const;
00182
00190 template <typename T>
00191 inline void configure(const ComparisonType type,
00192 const T& value,
00193 const bool match_all_values = false);
00194
00202 inline void configure(const ComparisonType type, const char *value,
00203 const bool match_all_values = false)
00204 {
00205 std::string value_str(value);
00206 configure(type, value_str, match_all_values);
00207 }
00208
00216 void configure(const ComparisonType type, const std::string &value,
00217 const bool match_all_values = false);
00218
00224 void configure(const ComparisonType type);
00225
00232 void updateVocabulary(const Vocabulary& v);
00233
00234
00236 inline const Vocabulary::Term& getTerm(void) const { return m_term; }
00237
00239 inline ComparisonType getType(void) const { return m_type; }
00240
00242 inline const Event::ParameterValue& getValue(void) const { return m_value; }
00243
00245 inline bool getMatchAllValues(void) const { return m_match_all_values; }
00246
00248 inline const boost::u32regex& getRegex(void) const { return m_regex; }
00249
00251 inline const std::string& getRegexStr(void) const { return m_regex_str; }
00252
00259 static ComparisonType parseComparisonType(std::string str);
00260
00267 static std::string getComparisonTypeAsString(const ComparisonType comparison_type);
00268
00270 static bool requiresValue(ComparisonType t);
00271
00272 static void writeComparisonsXML(std::ostream& out);
00273
00274 private:
00275
00277 template <typename T>
00278 class CompareEquals {
00279 public:
00280 CompareEquals(const Event::ParameterValue& value) : m_value(boost::get<const T&>(value)) {}
00281 inline bool operator()(const Event::ParameterValue& event_value) const {
00282 return boost::get<const T&>(event_value) == m_value;
00283 }
00284 private:
00285 const T& m_value;
00286 };
00287
00289 template <typename T>
00290 class CompareGreaterThan {
00291 public:
00292 CompareGreaterThan(const Event::ParameterValue& value) : m_value(boost::get<const T&>(value)) {}
00293 inline bool operator()(const Event::ParameterValue& event_value) const {
00294 return boost::get<const T&>(event_value) > m_value;
00295 }
00296 private:
00297 const T& m_value;
00298 };
00299
00301 template <typename T>
00302 class CompareLessThan {
00303 public:
00304 CompareLessThan(const Event::ParameterValue& value) : m_value(boost::get<const T&>(value)) {}
00305 inline bool operator()(const Event::ParameterValue& event_value) const {
00306 return boost::get<const T&>(event_value) < m_value;
00307 }
00308 private:
00309 const T& m_value;
00310 };
00311
00313 template <typename T>
00314 class CompareGreaterOrEqual {
00315 public:
00316 CompareGreaterOrEqual(const Event::ParameterValue& value) : m_value(boost::get<const T&>(value)) {}
00317 inline bool operator()(const Event::ParameterValue& event_value) const {
00318 return boost::get<const T&>(event_value) >= m_value;
00319 }
00320 private:
00321 const T& m_value;
00322 };
00323
00325 template <typename T>
00326 class CompareLessOrEqual {
00327 public:
00328 CompareLessOrEqual(const Event::ParameterValue& value) : m_value(boost::get<const T&>(value)) {}
00329 inline bool operator()(const Event::ParameterValue& event_value) const {
00330 return boost::get<const T&>(event_value) <= m_value;
00331 }
00332 private:
00333 const T& m_value;
00334 };
00335
00336 class ComparisonFunctor {
00337 public:
00338 ComparisonFunctor(const std::string& value, UColAttributeValue attr);
00339 virtual ~ComparisonFunctor();
00340
00341 virtual bool operator()(const Event::ParameterValue& event_value) const = 0;
00342
00343 protected:
00344 int32_t m_pattern_buf_len;
00345 UChar* m_pattern_buf;
00346 UCollator* m_collator;
00347 };
00348
00350 class CompareStringExactMatch : public ComparisonFunctor {
00351 public:
00352 CompareStringExactMatch(const std::string& value, UColAttributeValue attr = UCOL_DEFAULT);
00353 ~CompareStringExactMatch() {}
00354
00355 virtual bool operator()(const Event::ParameterValue& event_value) const {
00356 UCharIterator text_iter, pattern_iter;
00357 const Event::BlobType& blob = boost::get<const Event::BlobType&>(event_value);
00358 uiter_setUTF8(&text_iter, blob.get(), blob.size());
00359 uiter_setString(&pattern_iter, m_pattern_buf, m_pattern_buf_len);
00360 UErrorCode errorCode = U_ZERO_ERROR;
00361 UCollationResult result = ucol_strcollIter(m_collator, &text_iter, &pattern_iter, &errorCode);
00362
00363 return (result == UCOL_EQUAL);
00364 }
00365 };
00366
00368 class CompareStringContains : public ComparisonFunctor {
00369 public:
00370 CompareStringContains(const std::string& value, UColAttributeValue attr = UCOL_DEFAULT);
00371 ~CompareStringContains() {}
00372
00373 virtual bool operator()(const Event::ParameterValue& event_value) const {
00380
00381
00382 const Event::BlobType& blob = boost::get<const Event::BlobType&>(event_value);
00383 int32_t text_buf_len;
00384 UErrorCode errorCode = U_ZERO_ERROR;
00385 u_strFromUTF8(NULL, 0, &text_buf_len, blob.get(), blob.size(), &errorCode);
00386 errorCode = U_ZERO_ERROR;
00387 boost::scoped_array<UChar> text_buf(new UChar[text_buf_len]);
00388 u_strFromUTF8(text_buf.get(), text_buf_len, NULL, blob.get(), blob.size(), &errorCode);
00389
00390 UStringSearch* ss = usearch_openFromCollator(m_pattern_buf, m_pattern_buf_len, text_buf.get(), text_buf_len, m_collator, NULL, &errorCode);
00391 int pos = usearch_first(ss, &errorCode);
00392 usearch_close(ss);
00393
00394 return (pos != USEARCH_DONE);
00395 }
00396 };
00397
00399 class CompareStringStartsWith : public ComparisonFunctor {
00400 public:
00401 CompareStringStartsWith(const std::string& value, UColAttributeValue attr = UCOL_DEFAULT);
00402 ~CompareStringStartsWith();
00403
00404 virtual bool operator()(const Event::ParameterValue& event_value) const {
00405
00406 const Event::BlobType& blob = boost::get<const Event::BlobType&>(event_value);
00407 UCharIterator text_iter;
00408 uiter_setUTF8(&text_iter, blob.get(), blob.size());
00409
00410
00411 boost::scoped_array<UChar> text_prefix_buf(new UChar[m_pattern_buf_len]);
00412 int i;
00413 for (i = 0; i < m_pattern_buf_len; ++i) {
00414 UChar32 c = text_iter.next(&text_iter);
00415 if (c == U_SENTINEL) {
00416
00417 return false;
00418 }
00419 text_prefix_buf[i] = c;
00420 }
00421
00422 UCollationResult result = ucol_strcoll(m_collator, text_prefix_buf.get(), m_pattern_buf_len, m_pattern_buf, m_pattern_buf_len);
00423 return (result == UCOL_EQUAL);
00424 }
00425 };
00426
00428 class CompareStringEndsWith : public ComparisonFunctor {
00429 public:
00430 CompareStringEndsWith(const std::string& value, UColAttributeValue attr = UCOL_DEFAULT);
00431 ~CompareStringEndsWith() {}
00432
00433 virtual bool operator()(const Event::ParameterValue& event_value) const {
00434
00435 const Event::BlobType& blob = boost::get<const Event::BlobType&>(event_value);
00436 UCharIterator text_iter;
00437 uiter_setUTF8(&text_iter, blob.get(), blob.size());
00438
00439
00440 int32_t p = text_iter.move(&text_iter, -m_pattern_buf_len, UITER_LIMIT);
00441
00442
00443 if (p == U_SENTINEL)
00444 return false;
00445
00446
00447 UCharIterator pattern_iter;
00448 uiter_setString(&pattern_iter, m_pattern_buf, m_pattern_buf_len);
00449 UErrorCode errorCode = U_ZERO_ERROR;
00450 UCollationResult result = ucol_strcollIter(m_collator, &text_iter, &pattern_iter, &errorCode);
00451
00452 return (result == UCOL_EQUAL);
00453 }
00454 };
00455
00457 class CompareStringOrderedBefore : public ComparisonFunctor {
00458 public:
00459 CompareStringOrderedBefore(const std::string& value, UColAttributeValue attr = UCOL_DEFAULT);
00460 ~CompareStringOrderedBefore() {}
00461
00462 virtual bool operator()(const Event::ParameterValue& event_value) const {
00463 UCharIterator text_iter, pattern_iter;
00464 const Event::BlobType& blob = boost::get<const Event::BlobType&>(event_value);
00465 uiter_setUTF8(&text_iter, blob.get(), blob.size());
00466 uiter_setString(&pattern_iter, m_pattern_buf, m_pattern_buf_len);
00467 UErrorCode errorCode = U_ZERO_ERROR;
00468 UCollationResult result = ucol_strcollIter(m_collator, &text_iter, &pattern_iter, &errorCode);
00469
00470 return (result == UCOL_LESS);
00471 }
00472 };
00473
00475 class CompareStringOrderedAfter : public ComparisonFunctor {
00476 public:
00477 CompareStringOrderedAfter(const std::string& value, UColAttributeValue attr = UCOL_DEFAULT);
00478 ~CompareStringOrderedAfter() {}
00479
00480 virtual bool operator()(const Event::ParameterValue& event_value) const {
00481 UCharIterator text_iter, pattern_iter;
00482 const Event::BlobType& blob = boost::get<const Event::BlobType&>(event_value);
00483 uiter_setUTF8(&text_iter, blob.get(), blob.size());
00484 uiter_setString(&pattern_iter, m_pattern_buf, m_pattern_buf_len);
00485 UErrorCode errorCode = U_ZERO_ERROR;
00486 UCollationResult result = ucol_strcollIter(m_collator, &text_iter, &pattern_iter, &errorCode);
00487
00488 return (result == UCOL_GREATER);
00489 }
00490 };
00491
00493 class CompareStringRegex {
00494 public:
00495 CompareStringRegex(const boost::u32regex& value) : m_regex(value) {}
00496 inline bool operator()(const Event::ParameterValue& event_value) const {
00497
00498
00499 return boost::u32regex_search(
00500 boost::get<const Event::BlobType&>(event_value).get(), m_regex);
00501 }
00502 private:
00503 const boost::u32regex& m_regex;
00504 };
00505
00507 class CompareSameDateTime {
00508 public:
00509 CompareSameDateTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00510 inline bool operator()(const Event::ParameterValue& event_value) const {
00511 return boost::get<const PionDateTime&>(event_value) == m_value;
00512 }
00513 private:
00514 const PionDateTime& m_value;
00515 };
00516
00518 class CompareEarlierDateTime {
00519 public:
00520 CompareEarlierDateTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00521 inline bool operator()(const Event::ParameterValue& event_value) const {
00522 return boost::get<const PionDateTime&>(event_value) < m_value;
00523 }
00524 private:
00525 const PionDateTime& m_value;
00526 };
00527
00529 class CompareLaterDateTime {
00530 public:
00531 CompareLaterDateTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00532 inline bool operator()(const Event::ParameterValue& event_value) const {
00533 return boost::get<const PionDateTime&>(event_value) > m_value;
00534 }
00535 private:
00536 const PionDateTime& m_value;
00537 };
00538
00540 class CompareSameOrEarlierDateTime {
00541 public:
00542 CompareSameOrEarlierDateTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00543 inline bool operator()(const Event::ParameterValue& event_value) const {
00544 return boost::get<const PionDateTime&>(event_value) <= m_value;
00545 }
00546 private:
00547 const PionDateTime& m_value;
00548 };
00549
00551 class CompareSameOrLaterDateTime {
00552 public:
00553 CompareSameOrLaterDateTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00554 inline bool operator()(const Event::ParameterValue& event_value) const {
00555 return boost::get<const PionDateTime&>(event_value) >= m_value;
00556 }
00557 private:
00558 const PionDateTime& m_value;
00559 };
00560
00562 class CompareSameDate {
00563 public:
00564 CompareSameDate(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00565 inline bool operator()(const Event::ParameterValue& event_value) const {
00566 return boost::get<const PionDateTime&>(event_value).date() == m_value.date();
00567 }
00568 private:
00569 const PionDateTime& m_value;
00570 };
00571
00573 class CompareEarlierDate {
00574 public:
00575 CompareEarlierDate(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00576 inline bool operator()(const Event::ParameterValue& event_value) const {
00577 return boost::get<const PionDateTime&>(event_value).date() < m_value.date();
00578 }
00579 private:
00580 const PionDateTime& m_value;
00581 };
00582
00584 class CompareLaterDate {
00585 public:
00586 CompareLaterDate(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00587 inline bool operator()(const Event::ParameterValue& event_value) const {
00588 return boost::get<const PionDateTime&>(event_value).date() > m_value.date();
00589 }
00590 private:
00591 const PionDateTime& m_value;
00592 };
00593
00595 class CompareSameOrEarlierDate {
00596 public:
00597 CompareSameOrEarlierDate(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00598 inline bool operator()(const Event::ParameterValue& event_value) const {
00599 return boost::get<const PionDateTime&>(event_value).date() <= m_value.date();
00600 }
00601 private:
00602 const PionDateTime& m_value;
00603 };
00604
00606 class CompareSameOrLaterDate {
00607 public:
00608 CompareSameOrLaterDate(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00609 inline bool operator()(const Event::ParameterValue& event_value) const {
00610 return boost::get<const PionDateTime&>(event_value).date() >= m_value.date();
00611 }
00612 private:
00613 const PionDateTime& m_value;
00614 };
00615
00617 class CompareSameTime {
00618 public:
00619 CompareSameTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00620 inline bool operator()(const Event::ParameterValue& event_value) const {
00621 return boost::get<const PionDateTime&>(event_value).time_of_day() == m_value.time_of_day();
00622 }
00623 private:
00624 const PionDateTime& m_value;
00625 };
00626
00628 class CompareEarlierTime {
00629 public:
00630 CompareEarlierTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00631 inline bool operator()(const Event::ParameterValue& event_value) const {
00632 return boost::get<const PionDateTime&>(event_value).time_of_day() < m_value.time_of_day();
00633 }
00634 private:
00635 const PionDateTime& m_value;
00636 };
00637
00639 class CompareLaterTime {
00640 public:
00641 CompareLaterTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00642 inline bool operator()(const Event::ParameterValue& event_value) const {
00643 return boost::get<const PionDateTime&>(event_value).time_of_day() > m_value.time_of_day();
00644 }
00645 private:
00646 const PionDateTime& m_value;
00647 };
00648
00650 class CompareSameOrEarlierTime {
00651 public:
00652 CompareSameOrEarlierTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00653 inline bool operator()(const Event::ParameterValue& event_value) const {
00654 return boost::get<const PionDateTime&>(event_value).time_of_day() <= m_value.time_of_day();
00655 }
00656 private:
00657 const PionDateTime& m_value;
00658 };
00659
00661 class CompareSameOrLaterTime {
00662 public:
00663 CompareSameOrLaterTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00664 inline bool operator()(const Event::ParameterValue& event_value) const {
00665 return boost::get<const PionDateTime&>(event_value).time_of_day() >= m_value.time_of_day();
00666 }
00667 private:
00668 const PionDateTime& m_value;
00669 };
00670
00671
00679 bool checkForValidType(const ComparisonType type) const;
00680
00691 template <typename ComparisonFunction>
00692 inline bool checkComparison(const ComparisonFunction& comparison_func,
00693 const Event::ValuesRange& values_range) const;
00694
00696 Vocabulary::Term m_term;
00697
00699 ComparisonType m_type;
00700
00702 Event::ParameterValue m_value;
00703
00705 std::string m_str_value;
00706
00707 boost::shared_ptr<ComparisonFunctor>
00708 m_comparison_func;
00709
00711 boost::u32regex m_regex;
00712
00714 std::string m_regex_str;
00715
00717 bool m_match_all_values;
00718 };
00719
00720
00721
00722 template <typename T>
00723 inline void Comparison::configure(const ComparisonType type,
00724 const T& value,
00725 const bool match_all_values)
00726 {
00727 if (! checkForValidType(type))
00728 throw InvalidTypeForTermException();
00729
00730 m_type = type;
00731 m_value = value;
00732 m_match_all_values = match_all_values;
00733
00734
00735 switch (m_term.term_type) {
00736 case Vocabulary::TYPE_NULL:
00737 case Vocabulary::TYPE_OBJECT:
00738 throw InvalidValueForTypeException();
00739 break;
00740 case Vocabulary::TYPE_INT8:
00741 case Vocabulary::TYPE_INT16:
00742 case Vocabulary::TYPE_INT32:
00743 if (boost::get<boost::int32_t>(&m_value) == NULL)
00744 throw InvalidValueForTypeException();
00745 break;
00746 case Vocabulary::TYPE_UINT8:
00747 case Vocabulary::TYPE_UINT16:
00748 case Vocabulary::TYPE_UINT32:
00749 if (boost::get<boost::uint32_t>(&m_value) == NULL)
00750 throw InvalidValueForTypeException();
00751 break;
00752 case Vocabulary::TYPE_INT64:
00753 if (boost::get<boost::int64_t>(&m_value) == NULL)
00754 throw InvalidValueForTypeException();
00755 break;
00756 case Vocabulary::TYPE_UINT64:
00757 if (boost::get<boost::uint64_t>(&m_value) == NULL)
00758 throw InvalidValueForTypeException();
00759 break;
00760 case Vocabulary::TYPE_FLOAT:
00761 if (boost::get<float>(&m_value) == NULL)
00762 throw InvalidValueForTypeException();
00763 break;
00764 case Vocabulary::TYPE_DOUBLE:
00765 if (boost::get<double>(&m_value) == NULL)
00766 throw InvalidValueForTypeException();
00767 break;
00768 case Vocabulary::TYPE_LONG_DOUBLE:
00769 if (boost::get<long double>(&m_value) == NULL)
00770 throw InvalidValueForTypeException();
00771 break;
00772 case Vocabulary::TYPE_SHORT_STRING:
00773 case Vocabulary::TYPE_STRING:
00774 case Vocabulary::TYPE_LONG_STRING:
00775 case Vocabulary::TYPE_CHAR:
00776 case Vocabulary::TYPE_BLOB:
00777 case Vocabulary::TYPE_ZBLOB:
00778 throw InvalidValueForTypeException();
00779 break;
00780 case Vocabulary::TYPE_DATE_TIME:
00781 case Vocabulary::TYPE_DATE:
00782 case Vocabulary::TYPE_TIME:
00783 if (boost::get<PionDateTime>(&m_value) == NULL)
00784 throw InvalidValueForTypeException();
00785 break;
00786 }
00787 }
00788
00789
00790
00791
00792
00793 template <typename ComparisonFunction>
00794 inline bool Comparison::checkComparison(const ComparisonFunction& comparison_func,
00795 const Event::ValuesRange& values_range) const
00796 {
00797 boost::tribool result = boost::indeterminate;
00798
00799
00800 for (Event::ConstIterator i = values_range.first;
00801 i != values_range.second; ++i)
00802 {
00803 if (comparison_func(i->value)) {
00804 if (! m_match_all_values) {
00805 result = true;
00806
00807 break;
00808 }
00809 } else {
00810 if (m_match_all_values) {
00811 result = false;
00812 break;
00813 }
00814 }
00815 }
00816
00817 if (boost::indeterminate(result))
00818 result = m_match_all_values;
00819
00820 return result;
00821 }
00822
00823
00824
00825
00826 inline bool Comparison::evaluateRange(const Event::ValuesRange& values_range) const
00827 {
00828 bool result = false;
00829 bool negate_result = false;
00830
00831 switch (m_type) {
00832 case TYPE_FALSE:
00833 result = false;
00834 break;
00835 case TYPE_TRUE:
00836 result = true;
00837 break;
00838 case TYPE_IS_DEFINED:
00839 result = (values_range.first != values_range.second);
00840 break;
00841 case TYPE_IS_NOT_DEFINED:
00842 result = (values_range.first == values_range.second);
00843 break;
00844
00845 case TYPE_EQUALS:
00846 case TYPE_NOT_EQUALS:
00847 switch (m_term.term_type) {
00848 case Vocabulary::TYPE_INT8:
00849 case Vocabulary::TYPE_INT16:
00850 case Vocabulary::TYPE_INT32:
00851 {
00852 CompareEquals<boost::int32_t> comparison_func(m_value);
00853 result = checkComparison(comparison_func, values_range);
00854 break;
00855 }
00856 case Vocabulary::TYPE_INT64:
00857 {
00858 CompareEquals<boost::int64_t> comparison_func(m_value);
00859 result = checkComparison(comparison_func, values_range);
00860 break;
00861 }
00862 case Vocabulary::TYPE_UINT8:
00863 case Vocabulary::TYPE_UINT16:
00864 case Vocabulary::TYPE_UINT32:
00865 {
00866 CompareEquals<boost::uint32_t> comparison_func(m_value);
00867 result = checkComparison(comparison_func, values_range);
00868 break;
00869 }
00870 case Vocabulary::TYPE_UINT64:
00871 {
00872 CompareEquals<boost::uint64_t> comparison_func(m_value);
00873 result = checkComparison(comparison_func, values_range);
00874 break;
00875 }
00876 case Vocabulary::TYPE_FLOAT:
00877 {
00878 CompareEquals<float> comparison_func(m_value);
00879 result = checkComparison(comparison_func, values_range);
00880 break;
00881 }
00882 case Vocabulary::TYPE_DOUBLE:
00883 {
00884 CompareEquals<double> comparison_func(m_value);
00885 result = checkComparison(comparison_func, values_range);
00886 break;
00887 }
00888 case Vocabulary::TYPE_LONG_DOUBLE:
00889 {
00890 CompareEquals<long double> comparison_func(m_value);
00891 result = checkComparison(comparison_func, values_range);
00892 break;
00893 }
00894 default:
00895 throw InvalidComparisonException();
00896 }
00897 if (m_type == TYPE_NOT_EQUALS)
00898 result = !result;
00899 break;
00900
00901 case TYPE_GREATER_THAN:
00902 switch (m_term.term_type) {
00903 case Vocabulary::TYPE_INT8:
00904 case Vocabulary::TYPE_INT16:
00905 case Vocabulary::TYPE_INT32:
00906 {
00907 CompareGreaterThan<boost::int32_t> comparison_func(m_value);
00908 result = checkComparison(comparison_func, values_range);
00909 break;
00910 }
00911 case Vocabulary::TYPE_INT64:
00912 {
00913 CompareGreaterThan<boost::int64_t> comparison_func(m_value);
00914 result = checkComparison(comparison_func, values_range);
00915 break;
00916 }
00917 case Vocabulary::TYPE_UINT8:
00918 case Vocabulary::TYPE_UINT16:
00919 case Vocabulary::TYPE_UINT32:
00920 {
00921 CompareGreaterThan<boost::uint32_t> comparison_func(m_value);
00922 result = checkComparison(comparison_func, values_range);
00923 break;
00924 }
00925 case Vocabulary::TYPE_UINT64:
00926 {
00927 CompareGreaterThan<boost::uint64_t> comparison_func(m_value);
00928 result = checkComparison(comparison_func, values_range);
00929 break;
00930 }
00931 case Vocabulary::TYPE_FLOAT:
00932 {
00933 CompareGreaterThan<float> comparison_func(m_value);
00934 result = checkComparison(comparison_func, values_range);
00935 break;
00936 }
00937 case Vocabulary::TYPE_DOUBLE:
00938 {
00939 CompareGreaterThan<double> comparison_func(m_value);
00940 result = checkComparison(comparison_func, values_range);
00941 break;
00942 }
00943 case Vocabulary::TYPE_LONG_DOUBLE:
00944 {
00945 CompareGreaterThan<long double> comparison_func(m_value);
00946 result = checkComparison(comparison_func, values_range);
00947 break;
00948 }
00949 default:
00950 throw InvalidComparisonException();
00951 }
00952 break;
00953
00954 case TYPE_LESS_THAN:
00955 switch (m_term.term_type) {
00956 case Vocabulary::TYPE_INT8:
00957 case Vocabulary::TYPE_INT16:
00958 case Vocabulary::TYPE_INT32:
00959 {
00960 CompareLessThan<boost::int32_t> comparison_func(m_value);
00961 result = checkComparison(comparison_func, values_range);
00962 break;
00963 }
00964 case Vocabulary::TYPE_INT64:
00965 {
00966 CompareLessThan<boost::int64_t> comparison_func(m_value);
00967 result = checkComparison(comparison_func, values_range);
00968 break;
00969 }
00970 case Vocabulary::TYPE_UINT8:
00971 case Vocabulary::TYPE_UINT16:
00972 case Vocabulary::TYPE_UINT32:
00973 {
00974 CompareLessThan<boost::uint32_t> comparison_func(m_value);
00975 result = checkComparison(comparison_func, values_range);
00976 break;
00977 }
00978 case Vocabulary::TYPE_UINT64:
00979 {
00980 CompareLessThan<boost::uint64_t> comparison_func(m_value);
00981 result = checkComparison(comparison_func, values_range);
00982 break;
00983 }
00984 case Vocabulary::TYPE_FLOAT:
00985 {
00986 CompareLessThan<float> comparison_func(m_value);
00987 result = checkComparison(comparison_func, values_range);
00988 break;
00989 }
00990 case Vocabulary::TYPE_DOUBLE:
00991 {
00992 CompareLessThan<double> comparison_func(m_value);
00993 result = checkComparison(comparison_func, values_range);
00994 break;
00995 }
00996 case Vocabulary::TYPE_LONG_DOUBLE:
00997 {
00998 CompareLessThan<long double> comparison_func(m_value);
00999 result = checkComparison(comparison_func, values_range);
01000 break;
01001 }
01002 default:
01003 throw InvalidComparisonException();
01004 }
01005 break;
01006
01007 case TYPE_GREATER_OR_EQUAL:
01008 switch (m_term.term_type) {
01009 case Vocabulary::TYPE_INT8:
01010 case Vocabulary::TYPE_INT16:
01011 case Vocabulary::TYPE_INT32:
01012 {
01013 CompareGreaterOrEqual<boost::int32_t> comparison_func(m_value);
01014 result = checkComparison(comparison_func, values_range);
01015 break;
01016 }
01017 case Vocabulary::TYPE_INT64:
01018 {
01019 CompareGreaterOrEqual<boost::int64_t> comparison_func(m_value);
01020 result = checkComparison(comparison_func, values_range);
01021 break;
01022 }
01023 case Vocabulary::TYPE_UINT8:
01024 case Vocabulary::TYPE_UINT16:
01025 case Vocabulary::TYPE_UINT32:
01026 {
01027 CompareGreaterOrEqual<boost::uint32_t> comparison_func(m_value);
01028 result = checkComparison(comparison_func, values_range);
01029 break;
01030 }
01031 case Vocabulary::TYPE_UINT64:
01032 {
01033 CompareGreaterOrEqual<boost::uint64_t> comparison_func(m_value);
01034 result = checkComparison(comparison_func, values_range);
01035 break;
01036 }
01037 case Vocabulary::TYPE_FLOAT:
01038 {
01039 CompareGreaterOrEqual<float> comparison_func(m_value);
01040 result = checkComparison(comparison_func, values_range);
01041 break;
01042 }
01043 case Vocabulary::TYPE_DOUBLE:
01044 {
01045 CompareGreaterOrEqual<double> comparison_func(m_value);
01046 result = checkComparison(comparison_func, values_range);
01047 break;
01048 }
01049 case Vocabulary::TYPE_LONG_DOUBLE:
01050 {
01051 CompareGreaterOrEqual<long double> comparison_func(m_value);
01052 result = checkComparison(comparison_func, values_range);
01053 break;
01054 }
01055 default:
01056 throw InvalidComparisonException();
01057 }
01058 break;
01059
01060 case TYPE_LESS_OR_EQUAL:
01061 switch (m_term.term_type) {
01062 case Vocabulary::TYPE_INT8:
01063 case Vocabulary::TYPE_INT16:
01064 case Vocabulary::TYPE_INT32:
01065 {
01066 CompareLessOrEqual<boost::int32_t> comparison_func(m_value);
01067 result = checkComparison(comparison_func, values_range);
01068 break;
01069 }
01070 case Vocabulary::TYPE_INT64:
01071 {
01072 CompareLessOrEqual<boost::int64_t> comparison_func(m_value);
01073 result = checkComparison(comparison_func, values_range);
01074 break;
01075 }
01076 case Vocabulary::TYPE_UINT8:
01077 case Vocabulary::TYPE_UINT16:
01078 case Vocabulary::TYPE_UINT32:
01079 {
01080 CompareLessOrEqual<boost::uint32_t> comparison_func(m_value);
01081 result = checkComparison(comparison_func, values_range);
01082 break;
01083 }
01084 case Vocabulary::TYPE_UINT64:
01085 {
01086 CompareLessOrEqual<boost::uint64_t> comparison_func(m_value);
01087 result = checkComparison(comparison_func, values_range);
01088 break;
01089 }
01090 case Vocabulary::TYPE_FLOAT:
01091 {
01092 CompareLessOrEqual<float> comparison_func(m_value);
01093 result = checkComparison(comparison_func, values_range);
01094 break;
01095 }
01096 case Vocabulary::TYPE_DOUBLE:
01097 {
01098 CompareLessOrEqual<double> comparison_func(m_value);
01099 result = checkComparison(comparison_func, values_range);
01100 break;
01101 }
01102 case Vocabulary::TYPE_LONG_DOUBLE:
01103 {
01104 CompareLessOrEqual<long double> comparison_func(m_value);
01105 result = checkComparison(comparison_func, values_range);
01106 break;
01107 }
01108 default:
01109 throw InvalidComparisonException();
01110 }
01111 break;
01112
01113 case TYPE_NOT_EXACT_MATCH:
01114 case TYPE_NOT_EXACT_MATCH_PRIMARY:
01115 case TYPE_NOT_CONTAINS:
01116 case TYPE_NOT_CONTAINS_PRIMARY:
01117 case TYPE_NOT_STARTS_WITH:
01118 case TYPE_NOT_STARTS_WITH_PRIMARY:
01119 case TYPE_NOT_ENDS_WITH:
01120 case TYPE_NOT_ENDS_WITH_PRIMARY:
01121 case TYPE_NOT_ORDERED_BEFORE:
01122 case TYPE_NOT_ORDERED_BEFORE_PRIMARY:
01123 case TYPE_NOT_ORDERED_AFTER:
01124 case TYPE_NOT_ORDERED_AFTER_PRIMARY:
01125 negate_result = true;
01126 case TYPE_EXACT_MATCH:
01127 case TYPE_EXACT_MATCH_PRIMARY:
01128 case TYPE_CONTAINS:
01129 case TYPE_CONTAINS_PRIMARY:
01130 case TYPE_STARTS_WITH:
01131 case TYPE_STARTS_WITH_PRIMARY:
01132 case TYPE_ENDS_WITH:
01133 case TYPE_ENDS_WITH_PRIMARY:
01134 case TYPE_ORDERED_BEFORE:
01135 case TYPE_ORDERED_BEFORE_PRIMARY:
01136 case TYPE_ORDERED_AFTER:
01137 case TYPE_ORDERED_AFTER_PRIMARY:
01138 switch (m_term.term_type) {
01139 case Vocabulary::TYPE_SHORT_STRING:
01140 case Vocabulary::TYPE_STRING:
01141 case Vocabulary::TYPE_LONG_STRING:
01142 case Vocabulary::TYPE_CHAR:
01143 case Vocabulary::TYPE_BLOB:
01144 case Vocabulary::TYPE_ZBLOB:
01145 result = checkComparison(*m_comparison_func, values_range);
01146 break;
01147 default:
01148 throw InvalidComparisonException();
01149 }
01150 if (negate_result)
01151 result = !result;
01152 break;
01153
01154 case TYPE_REGEX:
01155 case TYPE_NOT_REGEX:
01156 switch (m_term.term_type) {
01157 case Vocabulary::TYPE_SHORT_STRING:
01158 case Vocabulary::TYPE_STRING:
01159 case Vocabulary::TYPE_LONG_STRING:
01160 case Vocabulary::TYPE_CHAR:
01161 case Vocabulary::TYPE_BLOB:
01162 case Vocabulary::TYPE_ZBLOB:
01163 {
01164 CompareStringRegex comparison_func(m_regex);
01165 result = checkComparison(comparison_func, values_range);
01166 break;
01167 }
01168 default:
01169 throw InvalidComparisonException();
01170 }
01171 if (m_type == TYPE_NOT_REGEX)
01172 result = !result;
01173 break;
01174
01175 case TYPE_SAME_DATE_TIME:
01176 case TYPE_NOT_SAME_DATE_TIME:
01177 {
01178 PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME)
01179 CompareSameDateTime comparison_func(m_value);
01180 result = checkComparison(comparison_func, values_range);
01181 if (m_type == TYPE_NOT_SAME_DATE_TIME)
01182 result = !result;
01183 break;
01184 }
01185
01186 case TYPE_EARLIER_DATE_TIME:
01187 {
01188 PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME)
01189 CompareEarlierDateTime comparison_func(m_value);
01190 result = checkComparison(comparison_func, values_range);
01191 break;
01192 }
01193
01194 case TYPE_LATER_DATE_TIME:
01195 {
01196 PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME)
01197 CompareLaterDateTime comparison_func(m_value);
01198 result = checkComparison(comparison_func, values_range);
01199 break;
01200 }
01201
01202 case TYPE_SAME_OR_EARLIER_DATE_TIME:
01203 {
01204 PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME)
01205 CompareSameOrEarlierDateTime comparison_func(m_value);
01206 result = checkComparison(comparison_func, values_range);
01207 break;
01208 }
01209
01210 case TYPE_SAME_OR_LATER_DATE_TIME:
01211 {
01212 PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME)
01213 CompareSameOrLaterDateTime comparison_func(m_value);
01214 result = checkComparison(comparison_func, values_range);
01215 break;
01216 }
01217
01218 case TYPE_SAME_DATE:
01219 case TYPE_NOT_SAME_DATE:
01220 {
01221 PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_DATE)
01222 CompareSameDate comparison_func(m_value);
01223 result = checkComparison(comparison_func, values_range);
01224 if (m_type == TYPE_NOT_SAME_DATE)
01225 result = !result;
01226 break;
01227 }
01228
01229 case TYPE_EARLIER_DATE:
01230 {
01231 PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_DATE)
01232 CompareEarlierDate comparison_func(m_value);
01233 result = checkComparison(comparison_func, values_range);
01234 break;
01235 }
01236
01237 case TYPE_LATER_DATE:
01238 {
01239 PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_DATE)
01240 CompareLaterDate comparison_func(m_value);
01241 result = checkComparison(comparison_func, values_range);
01242 break;
01243 }
01244
01245 case TYPE_SAME_OR_EARLIER_DATE:
01246 {
01247 PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_DATE)
01248 CompareSameOrEarlierDate comparison_func(m_value);
01249 result = checkComparison(comparison_func, values_range);
01250 break;
01251 }
01252
01253 case TYPE_SAME_OR_LATER_DATE:
01254 {
01255 PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_DATE)
01256 CompareSameOrLaterDate comparison_func(m_value);
01257 result = checkComparison(comparison_func, values_range);
01258 break;
01259 }
01260
01261 case TYPE_SAME_TIME:
01262 case TYPE_NOT_SAME_TIME:
01263 {
01264 PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_TIME)
01265 CompareSameTime comparison_func(m_value);
01266 result = checkComparison(comparison_func, values_range);
01267 if (m_type == TYPE_NOT_SAME_TIME)
01268 result = !result;
01269 break;
01270 }
01271
01272 case TYPE_EARLIER_TIME:
01273 {
01274 PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_TIME)
01275 CompareEarlierTime comparison_func(m_value);
01276 result = checkComparison(comparison_func, values_range);
01277 break;
01278 }
01279
01280 case TYPE_LATER_TIME:
01281 {
01282 PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_TIME)
01283 CompareLaterTime comparison_func(m_value);
01284 result = checkComparison(comparison_func, values_range);
01285 break;
01286 }
01287
01288 case TYPE_SAME_OR_EARLIER_TIME:
01289 {
01290 PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_TIME)
01291 CompareSameOrEarlierTime comparison_func(m_value);
01292 result = checkComparison(comparison_func, values_range);
01293 break;
01294 }
01295
01296 case TYPE_SAME_OR_LATER_TIME:
01297 {
01298 PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_TIME)
01299 CompareSameOrLaterTime comparison_func(m_value);
01300 result = checkComparison(comparison_func, values_range);
01301 break;
01302 }
01303 }
01304
01305 return result;
01306 }
01307
01308
01309
01310
01311 inline bool Comparison::evaluate(const Event& e) const
01312 {
01313 if (m_type == TYPE_IS_DEFINED || m_type == TYPE_IS_NOT_DEFINED) {
01314
01315 if (e.getType() == m_term.term_ref) return m_type == TYPE_IS_DEFINED;
01316 }
01318 Event::ValuesRange values_range = e.equal_range(m_term.term_ref);
01319 return Comparison::evaluateRange(values_range);
01320 }
01321
01322
01323 }
01324 }
01325
01326 #endif