10 #ifndef OPENDDS_NO_CONTENT_SUBSCRIPTION_PROFILE 27 const char MOD[] =
"MOD";
37 FilterEvaluator::DataForEval::~DataForEval()
40 FilterEvaluator::DeserializedForEval::~DeserializedForEval()
43 FilterEvaluator::FilterEvaluator(
const char* filter,
bool allowOrderBy)
44 : extended_grammar_(false)
46 , number_parameters_(0)
48 const char* out = filter + std::strlen(filter);
49 yard::SimpleTextParser parser(filter, out);
55 bool found_order_by =
false;
56 for (
AstNode* iter = parser.GetAstRoot()->GetFirstChild(); iter;
57 iter = iter->GetSibling()) {
58 if (iter->TypeMatches<
ORDERBY>()) {
59 found_order_by =
true;
60 }
else if (found_order_by && iter->TypeMatches<
FieldName>()) {
61 order_bys_.push_back(
toString(iter));
79 children_.push_back(n);
84 std::for_each(children_.begin(), children_.end(), deleteChild);
118 return meta_.getValue(deserialized_, field);
125 :
DataForEval(type_support.getMetaStructForType(), params)
128 , type_support_(type_support)
129 , exten_(type_support.base_extensibility())
136 if (iter != cache_.end()) {
143 if (!(ser >> encap)) {
145 ACE_TEXT(
"FilterEvaluator::SerializedForEval::lookup: ")
146 ACE_TEXT(
"deserialization of encapsulation header failed.\n")));
147 throw std::runtime_error(
"FilterEvaluator::SerializedForEval::lookup:" 148 "deserialization of encapsulation header failed.\n");
153 ACE_TEXT(
"FilterEvaluator::SerializedForEval::lookup: ")
154 ACE_TEXT(
"failed to convert encapsulation header to encoding.\n")));
155 throw std::runtime_error(
"FilterEvaluator::SerializedForEval::lookup:" 156 "failed to convert encapsulation header to encoding.\n");
158 ser.encoding(encoding);
185 explicit FieldLookup(
AstNode* fnNode)
203 class LiteralInt :
public FilterEvaluator::Operand {
205 explicit LiteralInt(
AstNode* fnNode)
209 if (strVal.length() > 2 && strVal[0] ==
'0' 210 && (strVal[1] ==
'x' || strVal[1] ==
'X')) {
211 std::istringstream is(strVal.c_str() + 2);
213 is >> std::hex >> val;
215 }
else if (!strVal.empty() && strVal[0] ==
'-') {
217 std::istringstream is(strVal.c_str());
222 std::istringstream is(strVal.c_str());
228 Value eval(FilterEvaluator::DataForEval&)
236 class LiteralChar :
public FilterEvaluator::Operand {
238 explicit LiteralChar(
AstNode* fnNode)
242 Value eval(FilterEvaluator::DataForEval&)
250 class LiteralFloat :
public FilterEvaluator::Operand {
252 explicit LiteralFloat(
AstNode* fnNode)
256 Value eval(FilterEvaluator::DataForEval&)
264 class LiteralString :
public FilterEvaluator::Operand {
266 explicit LiteralString(
AstNode* fnNode)
272 Value eval(FilterEvaluator::DataForEval&)
280 class Parameter :
public FilterEvaluator::Operand {
282 explicit Parameter(
AstNode* fnNode)
286 bool isParameter()
const {
return true; }
288 Value eval(FilterEvaluator::DataForEval& data)
290 return Value(data.params_[static_cast<CORBA::ULong>(
param_)],
true);
293 size_t param() {
return param_; }
298 class Comparison :
public FilterEvaluator::EvalNode {
300 enum Operator {OPER_EQ, OPER_LT, OPER_GT, OPER_LTEQ, OPER_GTEQ, OPER_NEQ,
301 OPER_LIKE, OPER_INVALID};
303 explicit Comparison(
AstNode* op, FilterEvaluator::Operand* left, FilterEvaluator::Operand* right)
312 Value eval(FilterEvaluator::DataForEval& data)
318 return left == right;
324 return !(right < left);
326 return !(left < right);
328 return !(left == right);
330 return left.like(right);
338 void setOperator(
AstNode* node)
340 if (node->TypeMatches<
OP_EQ>()) {
342 }
else if (node->TypeMatches<
OP_LT>()) {
344 }
else if (node->TypeMatches<
OP_GT>()) {
346 }
else if (node->TypeMatches<
OP_LTEQ>()) {
348 }
else if (node->TypeMatches<OP_GTEQ>()) {
350 }
else if (node->TypeMatches<
OP_NEQ>()) {
352 }
else if (node->TypeMatches<
OP_LIKE>()) {
364 class Between :
public FilterEvaluator::EvalNode {
366 Between(FilterEvaluator::Operand* field,
AstNode* betweenOrNot, FilterEvaluator::Operand* left, FilterEvaluator::Operand* right)
377 Value eval(FilterEvaluator::DataForEval& data)
382 bool btwn = !(field < left) && !(right < field);
389 FilterEvaluator::Operand*
left_;
390 FilterEvaluator::Operand*
right_;
393 class Call :
public FilterEvaluator::Operand {
395 enum Operator { OP_MOD };
402 throw std::runtime_error(
"Unknown function: " + std::string(name.c_str ()));
406 virtual Value eval(FilterEvaluator::DataForEval& data)
411 if (children_.size() != 2) {
412 std::stringstream ss;
413 ss << MOD <<
" expects 2 arguments, given " << children_.size();
414 throw std::runtime_error(ss.str ());
416 Value left = children_[0]->eval(data);
417 Value right = children_[1]->eval(data);
430 class Logical :
public FilterEvaluator::EvalNode {
432 enum LogicalOp {LG_AND, LG_OR, LG_NOT};
434 explicit Logical(EvalNode*
child)
440 Logical(
AstNode* op, EvalNode* left, EvalNode* right)
444 if (op->TypeMatches<
AND>()) {
446 }
else if (op->TypeMatches<
OR>()) {
453 Value eval(FilterEvaluator::DataForEval& data)
455 Value left = children_[0]->eval(data);
461 if (!left.b_)
return false;
464 if (left.b_)
return true;
467 return children_[1]->eval(data);
478 for (
AstNode* iter = node->GetFirstChild(); iter; iter = iter->GetSibling()) {
487 for (iter = node->GetFirstChild(); idx != 0; iter = iter->GetSibling(), --idx) {}
501 return new Comparison(op, left, right);
507 return new Between(field, op, low, high);
508 }
else if (node->TypeMatches<
CondDef>() || node->TypeMatches<
Cond>()) {
509 size_t a =
arity(node);
519 return new Logical(op, left, right);
531 return new FieldLookup(node);
532 }
else if (node->TypeMatches<
IntVal>()) {
533 return new LiteralInt(node);
534 }
else if (node->TypeMatches<
CharVal>()) {
535 return new LiteralChar(node);
536 }
else if (node->TypeMatches<
FloatVal>()) {
537 return new LiteralFloat(node);
538 }
else if (node->TypeMatches<
StrVal>()) {
539 return new LiteralString(node);
540 }
else if (node->TypeMatches<
ParamVal>()) {
541 Parameter* retval =
new Parameter(node);
547 }
else if (node->TypeMatches<
CallDef>()) {
548 if (
arity(node) == 1) {
553 for (
AstNode* iter =
child(node, 1); iter != 0; iter = iter->GetSibling()) {
570 FilterEvaluator::getOrderBys()
const 582 : type_(VAL_BOOL), b_(b), conversion_preferred_(conversion_preferred)
613 #ifdef NONNATIVE_LONGDOUBLE 632 Value::Value(
const std::wstring& s,
bool conversion_preferred)
652 #ifndef DDS_HAS_WCHAR 683 template<
typename Visitor,
typename Val>
684 typename Visitor::result_type visit(Visitor& vis, Val& val)
706 throw std::runtime_error(
"Unexpected type of Value");
710 template<
typename ResultType =
void>
712 typedef ResultType result_type;
715 struct Assign : VisitorBase<> {
716 explicit Assign(
Value& target,
bool steal =
false)
719 void operator()(
const char* s)
724 template<
typename T>
void operator()(
const T& s)
737 Assign visitor(*
this);
758 Assign visitor1(v,
true);
759 visit(visitor1, *
this);
764 Assign visitor2(*
this,
true);
775 struct Equals : VisitorBase<bool> {
776 explicit Equals(
const Value& lhs) :
lhs_(lhs) {}
778 bool operator()(
const char* s)
const 780 return std::strcmp(
lhs_.s_, s) == 0;
783 template<
typename T>
bool operator()(
const T& rhs)
const 785 return lhs_.get<T>() == rhs;
791 struct Less : VisitorBase<bool> {
792 explicit Less(
const Value& lhs) :
lhs_(lhs) {}
794 bool operator()(
const char* s)
const 796 return std::strcmp(
lhs_.s_, s) < 0;
799 template<
typename T>
bool operator()(
const T& rhs)
const 801 return lhs_.get<T>() < rhs;
807 struct Modulus : VisitorBase<Value> {
808 explicit Modulus(
const Value& lhs) :
lhs_(lhs) {}
810 bool operator()(
const char*&)
const 812 throw std::runtime_error(std::string(MOD) +
" cannot be applied to strings");
815 Value operator()(
const bool&)
const 817 throw std::runtime_error(std::string(MOD) +
" cannot be applied to booleans");
821 Value operator()(
const T& rhs)
const 823 return lhs_.get<T>() % rhs;
826 Value operator()(
const double&)
const 828 throw std::runtime_error(std::string(MOD) +
" cannot be applied to doubles");
833 throw std::runtime_error(std::string(MOD) +
" cannot be applied to ACE_CDR::LongDoubles");
847 return visit(visitor, rhs);
857 return visit(visitor, rhs);
866 Modulus visitor(lhs);
867 return visit(visitor, rhs);
874 throw std::runtime_error(
"'like' operator called on non-string arguments.");
878 for (
size_t i = pattern.find_first_of(
"?*"); i < pattern.length();
879 i = pattern.find_first_of(
"?*", i + 1)) {
880 pattern.insert(i++, 1,
'\\');
883 for (
size_t i = pattern.find_first_of(
"_%"); i < pattern.length();
884 i = pattern.find_first_of(
"_%", i + 1)) {
885 pattern[i] = (pattern[i] ==
'_') ?
'?' :
'*';
891 struct StreamInsert : VisitorBase<> {
892 explicit StreamInsert(std::ostream& os) :
os_(os) {}
894 template<
typename T>
void operator()(
const T& t)
902 struct StreamExtract : VisitorBase<> {
903 explicit StreamExtract(std::istream& is) :
is_(is) {}
905 void operator()(
const char*) {}
910 #ifdef NONNATIVE_LONGDOUBLE 919 template<
typename T>
void operator()(T& t)
935 std::ostringstream oss;
936 StreamInsert visitor(oss);
937 visit(visitor, *
this);
938 asString = oss.str();
949 std::istringstream iss(asString);
950 StreamExtract visitor(iss);
951 visit(visitor, newval);
952 if (iss.eof() && !iss.bad()) {
985 throw std::runtime_error(
"Types don't match and aren't convertible.");
keeps the details of yard out of the FilterEvaluator header file
void swap(MessageBlock &lhs, MessageBlock &rhs)
yard::TreeBuildingParser< char >::Node AstNode
Value & operator=(const Value &v)
LongDouble & assign(const NativeImpl &rhs)
ACE_Message_Block * serialized_
virtual Value getValue(const void *stru, const char *fieldSpec) const =0
size_t number_parameters_
void addChild(EvalNode *n)
virtual Value eval(DataForEval &data)=0
OPENDDS_MAP(OPENDDS_STRING, Value) cache_
FilterEvaluator::Operand * left_
Value(bool b, bool conversion_preferred=false)
#define OPENDDS_ASSERT(C)
const TypeSupportImpl & type_support_
Value lookup(const char *field) const
OPENDDS_STRING fieldName_
bool eval_i(DataForEval &data) const
static FilterEvaluator::AstNodeWrapper child(const FilterEvaluator::AstNodeWrapper &node, size_t idx)
virtual bool has_non_key_fields(const TypeSupportImpl &ts) const
bool conversion_preferred_
OPENDDS_STRING toString(yard::TreeBuildingParser< char >::Node *iter)
EvalNode * walkAst(const AstNodeWrapper &node)
static void conversion(Value &lhs, Value &rhs)
OPENDDS_VECTOR(OPENDDS_STRING) getOrderBys() const
Class to serialize and deserialize data for DDS.
static size_t arity(const FilterEvaluator::AstNodeWrapper &node)
FilterEvaluator::Operand * right_
static void deleteChild(EvalNode *child)
virtual Value lookup(const char *field) const =0
bool operator<(const Value &v) const
String_Manager_T< CORBA::Char > String_Manager
static bool is_encapsulated(Kind kind)
virtual ACE_Message_Block * duplicate(void) const
#define ACE_CDR_LONG_DOUBLE_ASSIGNMENT(LHS, RHS)
virtual bool isParameter() const
unsigned long long ACE_UINT64
Operand * walkOperand(const AstNodeWrapper &node)
void reportErrors(yard::SimpleTextParser &parser, const char *input)
called after parsing has failed, throws std::exception with details
bool eval(const T &sample, const DDS::StringSeq ¶ms) const
SerializedForEval(ACE_Message_Block *data, const TypeSupportImpl &type_support, const DDS::StringSeq ¶ms, Encoding encoding)
FilterEvaluator::Operand * field_
#define OPENDDS_END_VERSIONED_NAMESPACE_DECL
FilterEvaluator(const char *filter, bool allowOrderBy)
String_Manager_T< CORBA::WChar > WString_Manager
char * strdup(const char *s)
bool like(const Value &v) const
bool operator==(const Value &v) const
Value lookup(const char *field) const
const DCPS::Encoding encoding(DCPS::Encoding::KIND_UNALIGNED_CDR, DCPS::ENDIAN_BIG)
The Internal API and Implementation of OpenDDS.
bool wild_match(const char *s, const char *pattern, bool case_sensitive=true, bool character_classes=false)
Value operator%(const Value &v) const
virtual bool is_dcps_key(const char *fieldname) const =0
sequence< string > StringSeq
bool has_non_key_fields(const TypeSupportImpl &ts) const
const Encoding & encoding_
bool to_encoding(Encoding &encoding, Extensibility expected_extensibility)