platform/include/pion/platform/Comparison.hpp

00001 // ------------------------------------------------------------------------
00002 // Pion is a development platform for building Reactors that process Events
00003 // ------------------------------------------------------------------------
00004 // Copyright (C) 2007-2008 Atomic Labs, Inc.  (http://www.atomiclabs.com)
00005 //
00006 // Pion is free software: you can redistribute it and/or modify it under the
00007 // terms of the GNU Affero General Public License as published by the Free
00008 // Software Foundation, either version 3 of the License, or (at your option)
00009 // any later version.
00010 //
00011 // Pion is distributed in the hope that it will be useful, but WITHOUT ANY
00012 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00013 // FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for
00014 // more details.
00015 //
00016 // You should have received a copy of the GNU Affero General Public License
00017 // along with Pion.  If not, see <http://www.gnu.org/licenses/>.
00018 //
00019 
00020 #ifndef __PION_COMPARISON_HEADER__
00021 #define __PION_COMPARISON_HEADER__
00022 
00023 #include <boost/regex.hpp>
00024 #include <boost/logic/tribool.hpp>
00025 #include <boost/algorithm/string/compare.hpp>
00026 #include <boost/algorithm/string/predicate.hpp>
00027 #include <boost/tuple/tuple.hpp>
00028 #include <pion/PionConfig.hpp>
00029 #include <pion/PionException.hpp>
00030 #include <pion/platform/Vocabulary.hpp>
00031 #include <pion/platform/Event.hpp>
00032 
00033 namespace pion {        // begin namespace pion
00034 namespace platform {    // begin namespace platform (Pion Platform Library)
00035 
00039 class PION_PLATFORM_API Comparison
00040 {
00041 public:
00042 
00044     enum ComparisonType {
00045         TYPE_FALSE = 0,                     // always false
00046         TYPE_TRUE,                          // always true
00047         TYPE_IS_DEFINED,                    // true if at least one value is defined
00048         TYPE_IS_NOT_DEFINED,                // true if no values are defined
00049         // numeric operations
00050         TYPE_EQUALS,
00051         TYPE_NOT_EQUALS,
00052         TYPE_GREATER_THAN,
00053         TYPE_LESS_THAN,
00054         TYPE_GREATER_OR_EQUAL,
00055         TYPE_LESS_OR_EQUAL,
00056         // string operations
00057         TYPE_EXACT_MATCH,
00058         TYPE_NOT_EXACT_MATCH,
00059         TYPE_CONTAINS,
00060         TYPE_NOT_CONTAINS,
00061         TYPE_STARTS_WITH,
00062         TYPE_NOT_STARTS_WITH,
00063         TYPE_ENDS_WITH,
00064         TYPE_NOT_ENDS_WITH,
00065         TYPE_ORDERED_BEFORE,
00066         TYPE_NOT_ORDERED_BEFORE,
00067         TYPE_ORDERED_AFTER,
00068         TYPE_NOT_ORDERED_AFTER,
00069         TYPE_REGEX,
00070         TYPE_NOT_REGEX,
00071         // date_time operations
00072         TYPE_SAME_DATE_TIME,
00073         TYPE_NOT_SAME_DATE_TIME,
00074         TYPE_EARLIER_DATE_TIME,
00075         TYPE_LATER_DATE_TIME,
00076         TYPE_SAME_OR_EARLIER_DATE_TIME,
00077         TYPE_SAME_OR_LATER_DATE_TIME,
00078         // date operations
00079         TYPE_SAME_DATE,
00080         TYPE_NOT_SAME_DATE,
00081         TYPE_EARLIER_DATE,
00082         TYPE_LATER_DATE,
00083         TYPE_SAME_OR_EARLIER_DATE,
00084         TYPE_SAME_OR_LATER_DATE,
00085         // time of day operations
00086         TYPE_SAME_TIME,
00087         TYPE_NOT_SAME_TIME,
00088         TYPE_EARLIER_TIME,
00089         TYPE_LATER_TIME,
00090         TYPE_SAME_OR_EARLIER_TIME,
00091         TYPE_SAME_OR_LATER_TIME,
00092     };
00093 
00095     class UnknownComparisonTypeException : public PionException {
00096     public:
00097         UnknownComparisonTypeException(const std::string& comparison_type)
00098             : PionException("Could not parse unknown comparison type: ", comparison_type) {}
00099     };
00100 
00102     class InvalidComparisonException : public std::exception {
00103     public:
00104         virtual const char* what() const throw() {
00105             return "An invalid comparison was attempted";
00106         }
00107     };
00108 
00110     class InvalidTypeForTermException : public std::exception {
00111     public:
00112         virtual const char* what() const throw() {
00113             return "Invalid comparison type given for Vocabulary Term";
00114         }
00115     };
00116 
00118     class InvalidValueForTypeException : public std::exception {
00119     public:
00120         virtual const char* what() const throw() {
00121             return "Invalid value given for comparison type";
00122         }
00123     };
00124 
00125 
00127     virtual ~Comparison() {}
00128 
00134     explicit Comparison(const Vocabulary::Term& term)
00135         : m_term(term), m_type(TYPE_FALSE), m_match_all_values(false)
00136     {}
00137 
00139     Comparison(const Comparison& c)
00140         : m_term(c.m_term), m_type(c.m_type), m_value(c.m_value),
00141         m_str_value(c.m_str_value), m_regex(c.m_regex),
00142         m_match_all_values(c.m_match_all_values)
00143     {}
00144 
00145 
00153     inline bool evaluate(const Event& e) const;
00154 
00162     inline bool evaluateRange(const Event::ValuesRange& values_range) const;
00163 
00171     template <typename T>
00172     inline void configure(const ComparisonType type,
00173                           const T& value,
00174                           const bool match_all_values = false);
00175 
00183     inline void configure(const ComparisonType type, const char *value,
00184                           const bool match_all_values = false)
00185     {
00186         std::string value_str(value);
00187         configure(type, value_str, match_all_values);
00188     }
00189 
00197     void configure(const ComparisonType type, const std::string &value,
00198                    const bool match_all_values = false);
00199 
00205     void configure(const ComparisonType type);
00206 
00213     void updateVocabulary(const Vocabulary& v);
00214 
00215 
00217     inline const Vocabulary::Term& getTerm(void) const { return m_term; }
00218 
00220     inline ComparisonType getType(void) const { return m_type; }
00221 
00223     inline const Event::ParameterValue& getValue(void) const { return m_value; }
00224 
00226     inline bool getMatchAllValues(void) const { return m_match_all_values; }
00227 
00229     inline const boost::regex& getRegex(void) const { return m_regex; }
00230 
00237     static ComparisonType parseComparisonType(std::string str);
00238 
00245     static std::string getComparisonTypeAsString(const ComparisonType comparison_type);
00246 
00248     static inline bool isGenericType(ComparisonType t) {
00249         return (t >= TYPE_FALSE && t <= TYPE_IS_NOT_DEFINED);
00250     }
00251 
00253     static inline bool isNumericType(ComparisonType t) {
00254         return (t >= TYPE_EQUALS && t <= TYPE_LESS_OR_EQUAL);
00255     }
00256 
00258     static inline bool isStringType(ComparisonType t) {
00259         return (t >= TYPE_EXACT_MATCH && t <= TYPE_NOT_REGEX);
00260     }
00261 
00263     static inline bool isDateTimeType(ComparisonType t) {
00264         // includes date (only) and time (only) comparisons
00265         return (t >= TYPE_SAME_DATE_TIME && t <= TYPE_SAME_OR_LATER_TIME);
00266     }
00267 
00269     static inline bool isDateType(ComparisonType t) {
00270         return (t >= TYPE_SAME_DATE && t <= TYPE_SAME_OR_LATER_DATE);
00271     }
00272 
00274     static inline bool isTimeType(ComparisonType t) {
00275         return (t >= TYPE_SAME_TIME && t <= TYPE_SAME_OR_LATER_TIME);
00276     }
00277 
00278 
00279 private:
00280 
00282     template <typename T>
00283     class CompareEquals {
00284     public:
00285         CompareEquals(const Event::ParameterValue& value) : m_value(boost::get<const T&>(value)) {}
00286         inline bool operator()(const Event::ParameterValue& event_value) const {
00287             return boost::get<const T&>(event_value) == m_value;
00288         }
00289     private:
00290         const T&    m_value;
00291     };
00292 
00294     template <typename T>
00295     class CompareGreaterThan {
00296     public:
00297         CompareGreaterThan(const Event::ParameterValue& value) : m_value(boost::get<const T&>(value)) {}
00298         inline bool operator()(const Event::ParameterValue& event_value) const {
00299             return boost::get<const T&>(event_value) > m_value;
00300         }
00301     private:
00302         const T&    m_value;
00303     };
00304 
00306     template <typename T>
00307     class CompareLessThan {
00308     public:
00309         CompareLessThan(const Event::ParameterValue& value) : m_value(boost::get<const T&>(value)) {}
00310         inline bool operator()(const Event::ParameterValue& event_value) const {
00311             return boost::get<const T&>(event_value) < m_value;
00312         }
00313     private:
00314         const T&    m_value;
00315     };
00316 
00318     template <typename T>
00319     class CompareGreaterOrEqual {
00320     public:
00321         CompareGreaterOrEqual(const Event::ParameterValue& value) : m_value(boost::get<const T&>(value)) {}
00322         inline bool operator()(const Event::ParameterValue& event_value) const {
00323             return boost::get<const T&>(event_value) >= m_value;
00324         }
00325     private:
00326         const T&    m_value;
00327     };
00328 
00330     template <typename T>
00331     class CompareLessOrEqual {
00332     public:
00333         CompareLessOrEqual(const Event::ParameterValue& value) : m_value(boost::get<const T&>(value)) {}
00334         inline bool operator()(const Event::ParameterValue& event_value) const {
00335             return boost::get<const T&>(event_value) <= m_value;
00336         }
00337     private:
00338         const T&    m_value;
00339     };
00340 
00342     class CompareStringExactMatch {
00343     public:
00344         CompareStringExactMatch(const std::string& value) : m_value(value) {}
00345         inline bool operator()(const Event::ParameterValue& event_value) const {
00346             return m_value == boost::get<const Event::BlobType&>(event_value).get();
00347         }
00348     private:
00349         const std::string&  m_value;
00350     };
00351 
00353     class CompareStringContains {
00354     public:
00355         CompareStringContains(const std::string& value) : m_value(value) {}
00356         inline bool operator()(const Event::ParameterValue& event_value) const {
00357             return boost::algorithm::contains(
00358                 boost::get<const Event::BlobType&>(event_value).get(),
00359                 m_value.c_str());
00360         }
00361     private:
00362         const std::string&  m_value;
00363     };
00364 
00366     class CompareStringStartsWith {
00367     public:
00368         CompareStringStartsWith(const std::string& value) : m_value(value) {}
00369         inline bool operator()(const Event::ParameterValue& event_value) const {
00370             return boost::algorithm::starts_with(
00371                 boost::get<const Event::BlobType&>(event_value).get(),
00372                 m_value.c_str());
00373         }
00374     private:
00375         const std::string&  m_value;
00376     };
00377 
00379     class CompareStringEndsWith {
00380     public:
00381         CompareStringEndsWith(const std::string& value) : m_value(value) {}
00382         inline bool operator()(const Event::ParameterValue& event_value) const {
00383             return boost::algorithm::ends_with(
00384                 boost::get<const Event::BlobType&>(event_value).get(),
00385                 m_value.c_str());
00386         }
00387     private:
00388         const std::string&  m_value;
00389     };
00390 
00392     class CompareStringOrderedBefore {
00393     public:
00394         CompareStringOrderedBefore(const std::string& value) : m_value(value) {}
00395         inline bool operator()(const Event::ParameterValue& event_value) const {
00396             boost::algorithm::is_less p;
00397             return boost::algorithm::lexicographical_compare(
00398                 boost::get<const Event::BlobType&>(event_value).get(),
00399                 m_value.c_str(), p);
00400         }
00401     private:
00402         const std::string&  m_value;
00403     };
00404 
00406     class CompareStringOrderedAfter {
00407     public:
00408         CompareStringOrderedAfter(const std::string& value) : m_value(value) {}
00409         inline bool operator()(const Event::ParameterValue& event_value) const {
00410             boost::algorithm::is_less p;
00411             return boost::algorithm::lexicographical_compare(m_value.c_str(),
00412                 boost::get<const Event::BlobType&>(event_value).get(), p);
00413         }
00414     private:
00415         const std::string&  m_value;
00416     };
00417 
00419     class CompareStringRegex {
00420     public:
00421         CompareStringRegex(const boost::regex& value) : m_regex(value) {}
00422         inline bool operator()(const Event::ParameterValue& event_value) const {
00423             // note: regex_match must match the ENTIRE string; use regex_search
00424             // instead to match any part of the string
00425             return boost::regex_search(
00426                 boost::get<const Event::BlobType&>(event_value).get(), m_regex);
00427         }
00428     private:
00429         const boost::regex& m_regex;
00430     };
00431 
00433     class CompareSameDateTime {
00434     public:
00435         CompareSameDateTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00436         inline bool operator()(const Event::ParameterValue& event_value) const {
00437             return boost::get<const PionDateTime&>(event_value) == m_value;
00438         }
00439     private:
00440         const PionDateTime& m_value;
00441     };
00442 
00444     class CompareEarlierDateTime {
00445     public:
00446         CompareEarlierDateTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00447         inline bool operator()(const Event::ParameterValue& event_value) const {
00448             return boost::get<const PionDateTime&>(event_value) < m_value;
00449         }
00450     private:
00451         const PionDateTime& m_value;
00452     };
00453 
00455     class CompareLaterDateTime {
00456     public:
00457         CompareLaterDateTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00458         inline bool operator()(const Event::ParameterValue& event_value) const {
00459             return boost::get<const PionDateTime&>(event_value) > m_value;
00460         }
00461     private:
00462         const PionDateTime& m_value;
00463     };
00464 
00466     class CompareSameOrEarlierDateTime {
00467     public:
00468         CompareSameOrEarlierDateTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00469         inline bool operator()(const Event::ParameterValue& event_value) const {
00470             return boost::get<const PionDateTime&>(event_value) <= m_value;
00471         }
00472     private:
00473         const PionDateTime& m_value;
00474     };
00475 
00477     class CompareSameOrLaterDateTime {
00478     public:
00479         CompareSameOrLaterDateTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00480         inline bool operator()(const Event::ParameterValue& event_value) const {
00481             return boost::get<const PionDateTime&>(event_value) >= m_value;
00482         }
00483     private:
00484         const PionDateTime& m_value;
00485     };
00486 
00488     class CompareSameDate {
00489     public:
00490         CompareSameDate(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00491         inline bool operator()(const Event::ParameterValue& event_value) const {
00492             return boost::get<const PionDateTime&>(event_value).date() == m_value.date();
00493         }
00494     private:
00495         const PionDateTime& m_value;
00496     };
00497 
00499     class CompareEarlierDate {
00500     public:
00501         CompareEarlierDate(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00502         inline bool operator()(const Event::ParameterValue& event_value) const {
00503             return boost::get<const PionDateTime&>(event_value).date() < m_value.date();
00504         }
00505     private:
00506         const PionDateTime& m_value;
00507     };
00508 
00510     class CompareLaterDate {
00511     public:
00512         CompareLaterDate(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00513         inline bool operator()(const Event::ParameterValue& event_value) const {
00514             return boost::get<const PionDateTime&>(event_value).date() > m_value.date();
00515         }
00516     private:
00517         const PionDateTime& m_value;
00518     };
00519 
00521     class CompareSameOrEarlierDate {
00522     public:
00523         CompareSameOrEarlierDate(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00524         inline bool operator()(const Event::ParameterValue& event_value) const {
00525             return boost::get<const PionDateTime&>(event_value).date() <= m_value.date();
00526         }
00527     private:
00528         const PionDateTime& m_value;
00529     };
00530 
00532     class CompareSameOrLaterDate {
00533     public:
00534         CompareSameOrLaterDate(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00535         inline bool operator()(const Event::ParameterValue& event_value) const {
00536             return boost::get<const PionDateTime&>(event_value).date() >= m_value.date();
00537         }
00538     private:
00539         const PionDateTime& m_value;
00540     };
00541 
00543     class CompareSameTime {
00544     public:
00545         CompareSameTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00546         inline bool operator()(const Event::ParameterValue& event_value) const {
00547             return boost::get<const PionDateTime&>(event_value).time_of_day() == m_value.time_of_day();
00548         }
00549     private:
00550         const PionDateTime& m_value;
00551     };
00552 
00554     class CompareEarlierTime {
00555     public:
00556         CompareEarlierTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00557         inline bool operator()(const Event::ParameterValue& event_value) const {
00558             return boost::get<const PionDateTime&>(event_value).time_of_day() < m_value.time_of_day();
00559         }
00560     private:
00561         const PionDateTime& m_value;
00562     };
00563 
00565     class CompareLaterTime {
00566     public:
00567         CompareLaterTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00568         inline bool operator()(const Event::ParameterValue& event_value) const {
00569             return boost::get<const PionDateTime&>(event_value).time_of_day() > m_value.time_of_day();
00570         }
00571     private:
00572         const PionDateTime& m_value;
00573     };
00574 
00576     class CompareSameOrEarlierTime {
00577     public:
00578         CompareSameOrEarlierTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00579         inline bool operator()(const Event::ParameterValue& event_value) const {
00580             return boost::get<const PionDateTime&>(event_value).time_of_day() <= m_value.time_of_day();
00581         }
00582     private:
00583         const PionDateTime& m_value;
00584     };
00585 
00587     class CompareSameOrLaterTime {
00588     public:
00589         CompareSameOrLaterTime(const Event::ParameterValue& value) : m_value(boost::get<const PionDateTime&>(value)) {}
00590         inline bool operator()(const Event::ParameterValue& event_value) const {
00591             return boost::get<const PionDateTime&>(event_value).time_of_day() >= m_value.time_of_day();
00592         }
00593     private:
00594         const PionDateTime& m_value;
00595     };
00596 
00597 
00605     bool checkForValidType(const ComparisonType type) const;
00606 
00617     template <typename ComparisonFunction>
00618     inline bool checkComparison(const ComparisonFunction& comparison_func,
00619                                     const Event::ValuesRange& values_range) const;
00620 
00622     Vocabulary::Term            m_term;
00623 
00625     ComparisonType              m_type;
00626 
00628     Event::ParameterValue       m_value;
00629 
00631     std::string                 m_str_value;
00632 
00634     boost::regex                m_regex;
00635 
00637     bool                        m_match_all_values;
00638 };
00639 
00640 
00641 
00642 template <typename T>
00643 inline void Comparison::configure(const ComparisonType type,
00644                                   const T& value,
00645                                   const bool match_all_values)
00646 {
00647     if (! checkForValidType(type))
00648         throw InvalidTypeForTermException();
00649 
00650     m_type = type;
00651     m_value = value;
00652     m_match_all_values = match_all_values;
00653 
00654     // make sure the value matches the comparison type
00655     switch (m_term.term_type) {
00656         case Vocabulary::TYPE_NULL:
00657         case Vocabulary::TYPE_OBJECT:
00658             throw InvalidValueForTypeException();
00659             break;
00660         case Vocabulary::TYPE_INT8:
00661         case Vocabulary::TYPE_INT16:
00662         case Vocabulary::TYPE_INT32:
00663             if (boost::get<boost::int32_t>(&m_value) == NULL)
00664                 throw InvalidValueForTypeException();
00665             break;
00666         case Vocabulary::TYPE_UINT8:
00667         case Vocabulary::TYPE_UINT16:
00668         case Vocabulary::TYPE_UINT32:
00669             if (boost::get<boost::uint32_t>(&m_value) == NULL)
00670                 throw InvalidValueForTypeException();
00671             break;
00672         case Vocabulary::TYPE_INT64:
00673             if (boost::get<boost::int64_t>(&m_value) == NULL)
00674                 throw InvalidValueForTypeException();
00675             break;
00676         case Vocabulary::TYPE_UINT64:
00677             if (boost::get<boost::uint64_t>(&m_value) == NULL)
00678                 throw InvalidValueForTypeException();
00679             break;
00680         case Vocabulary::TYPE_FLOAT:
00681             if (boost::get<float>(&m_value) == NULL)
00682                 throw InvalidValueForTypeException();
00683             break;
00684         case Vocabulary::TYPE_DOUBLE:
00685             if (boost::get<double>(&m_value) == NULL)
00686                 throw InvalidValueForTypeException();
00687             break;
00688         case Vocabulary::TYPE_LONG_DOUBLE:
00689             if (boost::get<long double>(&m_value) == NULL)
00690                 throw InvalidValueForTypeException();
00691             break;
00692         case Vocabulary::TYPE_SHORT_STRING:
00693         case Vocabulary::TYPE_STRING:
00694         case Vocabulary::TYPE_LONG_STRING:
00695         case Vocabulary::TYPE_CHAR:
00696         case Vocabulary::TYPE_BLOB:
00697         case Vocabulary::TYPE_ZBLOB:
00698             throw InvalidValueForTypeException();
00699             break;
00700         case Vocabulary::TYPE_DATE_TIME:
00701         case Vocabulary::TYPE_DATE:
00702         case Vocabulary::TYPE_TIME:
00703             if (boost::get<PionDateTime>(&m_value) == NULL)
00704                 throw InvalidValueForTypeException();
00705             break;
00706     }
00707 }
00708 
00709 //************************************************************************************************************************************************
00710 
00711 // inline member functions for Comparison
00712 
00713 template <typename ComparisonFunction>
00714 inline bool Comparison::checkComparison(const ComparisonFunction& comparison_func,
00715                                         const Event::ValuesRange& values_range) const
00716 {
00717     boost::tribool result = boost::indeterminate;
00718 //  Event::ConstIterator value = values_range.second;
00719 
00720     for (Event::ConstIterator i = values_range.first;
00721          i != values_range.second; ++i)
00722     {
00723         if (comparison_func(i->value)) {
00724             if (! m_match_all_values) {
00725                 result = true;
00726 //              value = i;
00727                 break;
00728             }
00729         } else {
00730             if (m_match_all_values) {
00731                 result = false;
00732                 break;
00733             }
00734         }
00735     }
00736 
00737     if (boost::indeterminate(result))
00738         result = m_match_all_values;
00739 
00740     return result;
00741 }
00742 
00743 
00744 // This method now evaluates only a values_range, in order to support TransformReactor2
00745 // See Comparison::evaluate() on how values_range is defined, and the special case of *_DEFINED
00746 inline bool Comparison::evaluateRange(const Event::ValuesRange& values_range) const
00747 {
00748     bool result = false;
00749 
00750     switch (m_type) {
00751         case TYPE_FALSE:
00752             result = false;
00753             break;
00754         case TYPE_TRUE:
00755             result = true;
00756             break;
00757         case TYPE_IS_DEFINED:
00758             result = (values_range.first != values_range.second);
00759             break;
00760         case TYPE_IS_NOT_DEFINED:
00761             result = (values_range.first == values_range.second);
00762             break;
00763 
00764         case TYPE_EQUALS:
00765         case TYPE_NOT_EQUALS:
00766             switch (m_term.term_type) {
00767                 case Vocabulary::TYPE_INT8:
00768                 case Vocabulary::TYPE_INT16:
00769                 case Vocabulary::TYPE_INT32:
00770                 {
00771                     CompareEquals<boost::int32_t> comparison_func(m_value);
00772                     result = checkComparison(comparison_func, values_range);
00773                     break;
00774                 }
00775                 case Vocabulary::TYPE_INT64:
00776                 {
00777                     CompareEquals<boost::int64_t> comparison_func(m_value);
00778                     result = checkComparison(comparison_func, values_range);
00779                     break;
00780                 }
00781                 case Vocabulary::TYPE_UINT8:
00782                 case Vocabulary::TYPE_UINT16:
00783                 case Vocabulary::TYPE_UINT32:
00784                 {
00785                     CompareEquals<boost::uint32_t> comparison_func(m_value);
00786                     result = checkComparison(comparison_func, values_range);
00787                     break;
00788                 }
00789                 case Vocabulary::TYPE_UINT64:
00790                 {
00791                     CompareEquals<boost::uint64_t> comparison_func(m_value);
00792                     result = checkComparison(comparison_func, values_range);
00793                     break;
00794                 }
00795                 case Vocabulary::TYPE_FLOAT:
00796                 {
00797                     CompareEquals<float> comparison_func(m_value);
00798                     result = checkComparison(comparison_func, values_range);
00799                     break;
00800                 }
00801                 case Vocabulary::TYPE_DOUBLE:
00802                 {
00803                     CompareEquals<double> comparison_func(m_value);
00804                     result = checkComparison(comparison_func, values_range);
00805                     break;
00806                 }
00807                 case Vocabulary::TYPE_LONG_DOUBLE:
00808                 {
00809                     CompareEquals<long double> comparison_func(m_value);
00810                     result = checkComparison(comparison_func, values_range);
00811                     break;
00812                 }
00813                 default:
00814                     throw InvalidComparisonException();
00815             }
00816             if (m_type == TYPE_NOT_EQUALS)
00817                 result = !result;
00818             break;
00819 
00820         case TYPE_GREATER_THAN:
00821             switch (m_term.term_type) {
00822                 case Vocabulary::TYPE_INT8:
00823                 case Vocabulary::TYPE_INT16:
00824                 case Vocabulary::TYPE_INT32:
00825                 {
00826                     CompareGreaterThan<boost::int32_t> comparison_func(m_value);
00827                     result = checkComparison(comparison_func, values_range);
00828                     break;
00829                 }
00830                 case Vocabulary::TYPE_INT64:
00831                 {
00832                     CompareGreaterThan<boost::int64_t> comparison_func(m_value);
00833                     result = checkComparison(comparison_func, values_range);
00834                     break;
00835                 }
00836                 case Vocabulary::TYPE_UINT8:
00837                 case Vocabulary::TYPE_UINT16:
00838                 case Vocabulary::TYPE_UINT32:
00839                 {
00840                     CompareGreaterThan<boost::uint32_t> comparison_func(m_value);
00841                     result = checkComparison(comparison_func, values_range);
00842                     break;
00843                 }
00844                 case Vocabulary::TYPE_UINT64:
00845                 {
00846                     CompareGreaterThan<boost::uint64_t> comparison_func(m_value);
00847                     result = checkComparison(comparison_func, values_range);
00848                     break;
00849                 }
00850                 case Vocabulary::TYPE_FLOAT:
00851                 {
00852                     CompareGreaterThan<float> comparison_func(m_value);
00853                     result = checkComparison(comparison_func, values_range);
00854                     break;
00855                 }
00856                 case Vocabulary::TYPE_DOUBLE:
00857                 {
00858                     CompareGreaterThan<double> comparison_func(m_value);
00859                     result = checkComparison(comparison_func, values_range);
00860                     break;
00861                 }
00862                 case Vocabulary::TYPE_LONG_DOUBLE:
00863                 {
00864                     CompareGreaterThan<long double> comparison_func(m_value);
00865                     result = checkComparison(comparison_func, values_range);
00866                     break;
00867                 }
00868                 default:
00869                     throw InvalidComparisonException();
00870             }
00871             break;
00872 
00873         case TYPE_LESS_THAN:
00874             switch (m_term.term_type) {
00875                 case Vocabulary::TYPE_INT8:
00876                 case Vocabulary::TYPE_INT16:
00877                 case Vocabulary::TYPE_INT32:
00878                 {
00879                     CompareLessThan<boost::int32_t> comparison_func(m_value);
00880                     result = checkComparison(comparison_func, values_range);
00881                     break;
00882                 }
00883                 case Vocabulary::TYPE_INT64:
00884                 {
00885                     CompareLessThan<boost::int64_t> comparison_func(m_value);
00886                     result = checkComparison(comparison_func, values_range);
00887                     break;
00888                 }
00889                 case Vocabulary::TYPE_UINT8:
00890                 case Vocabulary::TYPE_UINT16:
00891                 case Vocabulary::TYPE_UINT32:
00892                 {
00893                     CompareLessThan<boost::uint32_t> comparison_func(m_value);
00894                     result = checkComparison(comparison_func, values_range);
00895                     break;
00896                 }
00897                 case Vocabulary::TYPE_UINT64:
00898                 {
00899                     CompareLessThan<boost::uint64_t> comparison_func(m_value);
00900                     result = checkComparison(comparison_func, values_range);
00901                     break;
00902                 }
00903                 case Vocabulary::TYPE_FLOAT:
00904                 {
00905                     CompareLessThan<float> comparison_func(m_value);
00906                     result = checkComparison(comparison_func, values_range);
00907                     break;
00908                 }
00909                 case Vocabulary::TYPE_DOUBLE:
00910                 {
00911                     CompareLessThan<double> comparison_func(m_value);
00912                     result = checkComparison(comparison_func, values_range);
00913                     break;
00914                 }
00915                 case Vocabulary::TYPE_LONG_DOUBLE:
00916                 {
00917                     CompareLessThan<long double> comparison_func(m_value);
00918                     result = checkComparison(comparison_func, values_range);
00919                     break;
00920                 }
00921                 default:
00922                     throw InvalidComparisonException();
00923             }
00924             break;
00925 
00926         case TYPE_GREATER_OR_EQUAL:
00927             switch (m_term.term_type) {
00928                 case Vocabulary::TYPE_INT8:
00929                 case Vocabulary::TYPE_INT16:
00930                 case Vocabulary::TYPE_INT32:
00931                 {
00932                     CompareGreaterOrEqual<boost::int32_t> comparison_func(m_value);
00933                     result = checkComparison(comparison_func, values_range);
00934                     break;
00935                 }
00936                 case Vocabulary::TYPE_INT64:
00937                 {
00938                     CompareGreaterOrEqual<boost::int64_t> comparison_func(m_value);
00939                     result = checkComparison(comparison_func, values_range);
00940                     break;
00941                 }
00942                 case Vocabulary::TYPE_UINT8:
00943                 case Vocabulary::TYPE_UINT16:
00944                 case Vocabulary::TYPE_UINT32:
00945                 {
00946                     CompareGreaterOrEqual<boost::uint32_t> comparison_func(m_value);
00947                     result = checkComparison(comparison_func, values_range);
00948                     break;
00949                 }
00950                 case Vocabulary::TYPE_UINT64:
00951                 {
00952                     CompareGreaterOrEqual<boost::uint64_t> comparison_func(m_value);
00953                     result = checkComparison(comparison_func, values_range);
00954                     break;
00955                 }
00956                 case Vocabulary::TYPE_FLOAT:
00957                 {
00958                     CompareGreaterOrEqual<float> comparison_func(m_value);
00959                     result = checkComparison(comparison_func, values_range);
00960                     break;
00961                 }
00962                 case Vocabulary::TYPE_DOUBLE:
00963                 {
00964                     CompareGreaterOrEqual<double> comparison_func(m_value);
00965                     result = checkComparison(comparison_func, values_range);
00966                     break;
00967                 }
00968                 case Vocabulary::TYPE_LONG_DOUBLE:
00969                 {
00970                     CompareGreaterOrEqual<long double> comparison_func(m_value);
00971                     result = checkComparison(comparison_func, values_range);
00972                     break;
00973                 }
00974                 default:
00975                     throw InvalidComparisonException();
00976             }
00977             break;
00978 
00979         case TYPE_LESS_OR_EQUAL:
00980             switch (m_term.term_type) {
00981                 case Vocabulary::TYPE_INT8:
00982                 case Vocabulary::TYPE_INT16:
00983                 case Vocabulary::TYPE_INT32:
00984                 {
00985                     CompareLessOrEqual<boost::int32_t> comparison_func(m_value);
00986                     result = checkComparison(comparison_func, values_range);
00987                     break;
00988                 }
00989                 case Vocabulary::TYPE_INT64:
00990                 {
00991                     CompareLessOrEqual<boost::int64_t> comparison_func(m_value);
00992                     result = checkComparison(comparison_func, values_range);
00993                     break;
00994                 }
00995                 case Vocabulary::TYPE_UINT8:
00996                 case Vocabulary::TYPE_UINT16:
00997                 case Vocabulary::TYPE_UINT32:
00998                 {
00999                     CompareLessOrEqual<boost::uint32_t> comparison_func(m_value);
01000                     result = checkComparison(comparison_func, values_range);
01001                     break;
01002                 }
01003                 case Vocabulary::TYPE_UINT64:
01004                 {
01005                     CompareLessOrEqual<boost::uint64_t> comparison_func(m_value);
01006                     result = checkComparison(comparison_func, values_range);
01007                     break;
01008                 }
01009                 case Vocabulary::TYPE_FLOAT:
01010                 {
01011                     CompareLessOrEqual<float> comparison_func(m_value);
01012                     result = checkComparison(comparison_func, values_range);
01013                     break;
01014                 }
01015                 case Vocabulary::TYPE_DOUBLE:
01016                 {
01017                     CompareLessOrEqual<double> comparison_func(m_value);
01018                     result = checkComparison(comparison_func, values_range);
01019                     break;
01020                 }
01021                 case Vocabulary::TYPE_LONG_DOUBLE:
01022                 {
01023                     CompareLessOrEqual<long double> comparison_func(m_value);
01024                     result = checkComparison(comparison_func, values_range);
01025                     break;
01026                 }
01027                 default:
01028                     throw InvalidComparisonException();
01029             }
01030             break;
01031 
01032         case TYPE_EXACT_MATCH:
01033         case TYPE_NOT_EXACT_MATCH:
01034             switch (m_term.term_type) {
01035                 case Vocabulary::TYPE_SHORT_STRING:
01036                 case Vocabulary::TYPE_STRING:
01037                 case Vocabulary::TYPE_LONG_STRING:
01038                 case Vocabulary::TYPE_CHAR:
01039                 case Vocabulary::TYPE_BLOB:
01040                 case Vocabulary::TYPE_ZBLOB:
01041                 {
01042                     CompareStringExactMatch comparison_func(m_str_value);
01043                     result = checkComparison(comparison_func, values_range);
01044                     break;
01045                 }
01046                 default:
01047                     throw InvalidComparisonException();
01048             }
01049             if (m_type == TYPE_NOT_EXACT_MATCH)
01050                 result = !result;
01051             break;
01052 
01053         case TYPE_CONTAINS:
01054         case TYPE_NOT_CONTAINS:
01055             switch (m_term.term_type) {
01056                 case Vocabulary::TYPE_SHORT_STRING:
01057                 case Vocabulary::TYPE_STRING:
01058                 case Vocabulary::TYPE_LONG_STRING:
01059                 case Vocabulary::TYPE_CHAR:
01060                 case Vocabulary::TYPE_BLOB:
01061                 case Vocabulary::TYPE_ZBLOB:
01062                 {
01063                     CompareStringContains comparison_func(m_str_value);
01064                     result = checkComparison(comparison_func, values_range);
01065                     break;
01066                 }
01067                 default:
01068                     throw InvalidComparisonException();
01069             }
01070             if (m_type == TYPE_NOT_CONTAINS)
01071                 result = !result;
01072             break;
01073 
01074         case TYPE_STARTS_WITH:
01075         case TYPE_NOT_STARTS_WITH:
01076             switch (m_term.term_type) {
01077                 case Vocabulary::TYPE_SHORT_STRING:
01078                 case Vocabulary::TYPE_STRING:
01079                 case Vocabulary::TYPE_LONG_STRING:
01080                 case Vocabulary::TYPE_CHAR:
01081                 case Vocabulary::TYPE_BLOB:
01082                 case Vocabulary::TYPE_ZBLOB:
01083                 {
01084                     CompareStringStartsWith comparison_func(m_str_value);
01085                     result = checkComparison(comparison_func, values_range);
01086                     break;
01087                 }
01088                 default:
01089                     throw InvalidComparisonException();
01090             }
01091             if (m_type == TYPE_NOT_STARTS_WITH)
01092                 result = !result;
01093             break;
01094 
01095         case TYPE_ENDS_WITH:
01096         case TYPE_NOT_ENDS_WITH:
01097             switch (m_term.term_type) {
01098                 case Vocabulary::TYPE_SHORT_STRING:
01099                 case Vocabulary::TYPE_STRING:
01100                 case Vocabulary::TYPE_LONG_STRING:
01101                 case Vocabulary::TYPE_CHAR:
01102                 case Vocabulary::TYPE_BLOB:
01103                 case Vocabulary::TYPE_ZBLOB:
01104                 {
01105                     CompareStringEndsWith comparison_func(m_str_value);
01106                     result = checkComparison(comparison_func, values_range);
01107                     break;
01108                 }
01109                 default:
01110                     throw InvalidComparisonException();
01111             }
01112             if (m_type == TYPE_NOT_ENDS_WITH)
01113                 result = !result;
01114             break;
01115 
01116         case TYPE_ORDERED_BEFORE:
01117         case TYPE_NOT_ORDERED_BEFORE:
01118             switch (m_term.term_type) {
01119                 case Vocabulary::TYPE_SHORT_STRING:
01120                 case Vocabulary::TYPE_STRING:
01121                 case Vocabulary::TYPE_LONG_STRING:
01122                 case Vocabulary::TYPE_CHAR:
01123                 case Vocabulary::TYPE_BLOB:
01124                 case Vocabulary::TYPE_ZBLOB:
01125                 {
01126                     CompareStringOrderedBefore comparison_func(m_str_value);
01127                     result = checkComparison(comparison_func, values_range);
01128                     break;
01129                 }
01130                 default:
01131                     throw InvalidComparisonException();
01132             }
01133             if (m_type == TYPE_NOT_ORDERED_BEFORE)
01134                 result = !result;
01135             break;
01136 
01137         case TYPE_ORDERED_AFTER:
01138         case TYPE_NOT_ORDERED_AFTER:
01139             switch (m_term.term_type) {
01140                 case Vocabulary::TYPE_SHORT_STRING:
01141                 case Vocabulary::TYPE_STRING:
01142                 case Vocabulary::TYPE_LONG_STRING:
01143                 case Vocabulary::TYPE_CHAR:
01144                 case Vocabulary::TYPE_BLOB:
01145                 case Vocabulary::TYPE_ZBLOB:
01146                 {
01147                     CompareStringOrderedAfter comparison_func(m_str_value);
01148                     result = checkComparison(comparison_func, values_range);
01149                     break;
01150                 }
01151                 default:
01152                     throw InvalidComparisonException();
01153             }
01154             if (m_type == TYPE_NOT_ORDERED_AFTER)
01155                 result = !result;
01156             break;
01157 
01158         case TYPE_REGEX:
01159         case TYPE_NOT_REGEX:
01160             switch (m_term.term_type) {
01161                 case Vocabulary::TYPE_SHORT_STRING:
01162                 case Vocabulary::TYPE_STRING:
01163                 case Vocabulary::TYPE_LONG_STRING:
01164                 case Vocabulary::TYPE_CHAR:
01165                 case Vocabulary::TYPE_BLOB:
01166                 case Vocabulary::TYPE_ZBLOB:
01167                 {
01168                     CompareStringRegex comparison_func(m_regex);
01169                     result = checkComparison(comparison_func, values_range);
01170                     break;
01171                 }
01172                 default:
01173                     throw InvalidComparisonException();
01174             }
01175             if (m_type == TYPE_NOT_REGEX)
01176                 result = !result;
01177             break;
01178 
01179         case TYPE_SAME_DATE_TIME:
01180         case TYPE_NOT_SAME_DATE_TIME:
01181         {
01182             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME)
01183             CompareSameDateTime comparison_func(m_value);
01184             result = checkComparison(comparison_func, values_range);
01185             if (m_type == TYPE_NOT_SAME_DATE_TIME)
01186                 result = !result;
01187             break;
01188         }
01189 
01190         case TYPE_EARLIER_DATE_TIME:
01191         {
01192             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME)
01193             CompareEarlierDateTime comparison_func(m_value);
01194             result = checkComparison(comparison_func, values_range);
01195             break;
01196         }
01197 
01198         case TYPE_LATER_DATE_TIME:
01199         {
01200             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME)
01201             CompareLaterDateTime comparison_func(m_value);
01202             result = checkComparison(comparison_func, values_range);
01203             break;
01204         }
01205 
01206         case TYPE_SAME_OR_EARLIER_DATE_TIME:
01207         {
01208             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME)
01209             CompareSameOrEarlierDateTime comparison_func(m_value);
01210             result = checkComparison(comparison_func, values_range);
01211             break;
01212         }
01213 
01214         case TYPE_SAME_OR_LATER_DATE_TIME:
01215         {
01216             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME)
01217             CompareSameOrLaterDateTime comparison_func(m_value);
01218             result = checkComparison(comparison_func, values_range);
01219             break;
01220         }
01221 
01222         case TYPE_SAME_DATE:
01223         case TYPE_NOT_SAME_DATE:
01224         {
01225             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_DATE)
01226             CompareSameDate comparison_func(m_value);
01227             result = checkComparison(comparison_func, values_range);
01228             if (m_type == TYPE_NOT_SAME_DATE)
01229                 result = !result;
01230             break;
01231         }
01232 
01233         case TYPE_EARLIER_DATE:
01234         {
01235             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_DATE)
01236             CompareEarlierDate comparison_func(m_value);
01237             result = checkComparison(comparison_func, values_range);
01238             break;
01239         }
01240 
01241         case TYPE_LATER_DATE:
01242         {
01243             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_DATE)
01244             CompareLaterDate comparison_func(m_value);
01245             result = checkComparison(comparison_func, values_range);
01246             break;
01247         }
01248 
01249         case TYPE_SAME_OR_EARLIER_DATE:
01250         {
01251             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_DATE)
01252             CompareSameOrEarlierDate comparison_func(m_value);
01253             result = checkComparison(comparison_func, values_range);
01254             break;
01255         }
01256 
01257         case TYPE_SAME_OR_LATER_DATE:
01258         {
01259             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_DATE)
01260             CompareSameOrLaterDate comparison_func(m_value);
01261             result = checkComparison(comparison_func, values_range);
01262             break;
01263         }
01264 
01265         case TYPE_SAME_TIME:
01266         case TYPE_NOT_SAME_TIME:
01267         {
01268             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_TIME)
01269             CompareSameTime comparison_func(m_value);
01270             result = checkComparison(comparison_func, values_range);
01271             if (m_type == TYPE_NOT_SAME_TIME)
01272                 result = !result;
01273             break;
01274         }
01275 
01276         case TYPE_EARLIER_TIME:
01277         {
01278             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_TIME)
01279             CompareEarlierTime comparison_func(m_value);
01280             result = checkComparison(comparison_func, values_range);
01281             break;
01282         }
01283 
01284         case TYPE_LATER_TIME:
01285         {
01286             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_TIME)
01287             CompareLaterTime comparison_func(m_value);
01288             result = checkComparison(comparison_func, values_range);
01289             break;
01290         }
01291 
01292         case TYPE_SAME_OR_EARLIER_TIME:
01293         {
01294             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_TIME)
01295             CompareSameOrEarlierTime comparison_func(m_value);
01296             result = checkComparison(comparison_func, values_range);
01297             break;
01298         }
01299 
01300         case TYPE_SAME_OR_LATER_TIME:
01301         {
01302             PION_ASSERT(m_term.term_type == Vocabulary::TYPE_DATE_TIME || m_term.term_type == Vocabulary::TYPE_TIME)
01303             CompareSameOrLaterTime comparison_func(m_value);
01304             result = checkComparison(comparison_func, values_range);
01305             break;
01306         }
01307     }
01308 
01309     return result;
01310 }
01311 
01312 // This is the refactored version of evaluate
01313 // Since IS_DEFINED and IS_NOT_DEFINED allow for looking at Event, in addition to range_value,
01314 // it was necessary to put some convoluted special-case logic here...
01315 inline bool Comparison::evaluate(const Event& e) const
01316 {
01318     Event::ValuesRange values_range = e.equal_range(m_term.term_ref);
01319     if (m_type == TYPE_IS_DEFINED || m_type == TYPE_IS_NOT_DEFINED) {
01320         // If object type matches looked for type, return true -- refactored out of evaluateRange
01321         if (m_type == TYPE_IS_DEFINED && e.getType() == m_term.term_ref) return true;
01322         // Evaluate the range
01323         bool result = Comparison::evaluateRange(values_range);
01324         // If object type does not matched looked for type, and object is not found in event, then not found
01325         if (m_type == TYPE_IS_NOT_DEFINED)
01326             return (result && e.getType() != m_term.term_ref);
01327         // Return match by range
01328         return result;
01329     } else
01330         return Comparison::evaluateRange(values_range);
01331 }
01332 
01333 
01334 }   // end namespace platform
01335 }   // end namespace pion
01336 
01337 #endif

Generated on Tue Aug 10 12:20:32 2010 for pion-platform by  doxygen 1.4.7