22 #include "usLDAPExpr_p.h" 25 #include "usServicePropertiesImpl_p.h" 38 namespace LDAPExprConstants {
54 static std::string s =
"Null query";
60 static std::string s =
"Trailing garbage";
64 static const std::string&
EOS()
66 static std::string s =
"Unexpected end of query";
72 static std::string s =
"Malformed query";
78 static std::string s =
"Undefined operator";
84 bool stricomp(
const std::string::value_type& v1,
const std::string::value_type& v2)
86 return ::tolower(v1) == ::tolower(v2);
93 LDAPExprData(
int op,
const std::vector<LDAPExpr>& args )
94 : m_operator(op), m_args(args), m_attrName(), m_attrValue()
98 LDAPExprData(
int op, std::string attrName,
const std::string& attrValue )
99 : m_operator(op), m_args(), m_attrName(attrName), m_attrValue(attrValue)
103 LDAPExprData(
const LDAPExprData& other )
104 :
SharedData(other), m_operator(other.m_operator),
105 m_args(other.m_args), m_attrName(other.m_attrName),
106 m_attrValue(other.m_attrValue)
111 std::vector<LDAPExpr> m_args;
112 std::string m_attrName;
113 std::string m_attrValue;
116 LDAPExpr::LDAPExpr() : d()
120 LDAPExpr::LDAPExpr(
const std::string &filter ) : d()
122 ParseState ps(filter);
125 LDAPExpr expr = ParseExpr(ps);
127 if (!Trim(ps.rest()).empty())
134 catch (
const std::out_of_range&)
140 LDAPExpr::LDAPExpr(
int op,
const std::vector<LDAPExpr>& args )
141 : d(
new LDAPExprData(op, args))
145 LDAPExpr::LDAPExpr(
int op,
const std::string &attrName,
const std::string &attrValue )
146 : d(
new LDAPExprData(op, attrName, attrValue))
150 LDAPExpr::LDAPExpr(
const LDAPExpr& other )
155 LDAPExpr& LDAPExpr::operator=(
const LDAPExpr& other)
161 LDAPExpr::~LDAPExpr()
165 std::string LDAPExpr::Trim(std::string str)
167 str.erase(0, str.find_first_not_of(
' '));
168 str.erase(str.find_last_not_of(
' ')+1);
172 bool LDAPExpr::GetMatchedObjectClasses(ObjectClassSet& objClasses)
const 174 if (d->m_operator == EQ)
180 objClasses.insert( d->m_attrValue );
185 else if (d->m_operator == AND)
188 for (std::size_t i = 0; i < d->m_args.size( ); i++)
190 LDAPExpr::ObjectClassSet r;
191 if (d->m_args[i].GetMatchedObjectClasses(r))
194 if (objClasses.empty())
202 LDAPExpr::ObjectClassSet::iterator it1 = objClasses.begin();
203 LDAPExpr::ObjectClassSet::iterator it2 = r.begin();
204 while ( (it1 != objClasses.end()) && (it2 != r.end()) )
208 objClasses.erase(it1++);
210 else if (*it2 < *it1)
222 objClasses.erase(it1, objClasses.end());
228 else if (d->m_operator == OR)
230 for (std::size_t i = 0; i < d->m_args.size( ); i++)
232 LDAPExpr::ObjectClassSet r;
233 if (d->m_args[i].GetMatchedObjectClasses(r))
235 std::copy(r.begin(), r.end(), std::inserter(objClasses, objClasses.begin()));
248 std::string LDAPExpr::ToLower(
const std::string& str)
250 std::string lowerStr(str);
251 std::transform(str.begin(), str.end(), lowerStr.begin(), ::tolower);
255 bool LDAPExpr::IsSimple(
const StringList& keywords, LocalCache& cache,
256 bool matchCase )
const 260 cache.resize(keywords.size());
263 if (d->m_operator == EQ)
265 StringList::const_iterator index;
266 if ((index = std::find(keywords.begin(), keywords.end(), matchCase ? d->m_attrName : ToLower(d->m_attrName))) != keywords.end() &&
269 cache[index - keywords.begin()] =
StringList(1, d->m_attrValue);
273 else if (d->m_operator == OR)
275 for (std::size_t i = 0; i < d->m_args.size( ); i++)
277 if (!d->m_args[i].IsSimple(keywords, cache, matchCase))
285 bool LDAPExpr::IsNull()
const 290 bool LDAPExpr::Query(
const std::string& filter,
const ServicePropertiesImpl& pd)
292 return LDAPExpr(filter).Evaluate(pd,
false);
295 bool LDAPExpr::Evaluate(
const ServicePropertiesImpl& p,
bool matchCase )
const 297 if ((d->m_operator & SIMPLE) != 0)
300 int index = p.FindCaseSensitive(d->m_attrName);
301 if (index < 0 && !matchCase) index = p.Find(d->m_attrName);
302 return index < 0 ? false : Compare(p.Value(index), d->m_operator, d->m_attrValue);
306 switch (d->m_operator)
309 for (std::size_t i = 0; i < d->m_args.size(); i++)
311 if (!d->m_args[i].Evaluate(p, matchCase))
316 for (std::size_t i = 0; i < d->m_args.size(); i++)
318 if (d->m_args[i].Evaluate(p, matchCase))
323 return !d->m_args[0].Evaluate(p, matchCase);
330 bool LDAPExpr::Compare(
const Any& obj,
int op,
const std::string& s )
const 339 const std::type_info& objType = obj.
Type();
340 if (objType ==
typeid(std::string))
342 return CompareString(ref_any_cast<std::string>(obj), op, s);
344 else if (objType ==
typeid(std::vector<std::string>))
346 const std::vector<std::string>& list =
ref_any_cast<std::vector<std::string> >(obj);
347 for (std::size_t it = 0; it != list.size(); it++)
349 if (CompareString(list[it], op, s))
353 else if (objType ==
typeid(std::list<std::string>))
355 const std::list<std::string>& list =
ref_any_cast<std::list<std::string> >(obj);
356 for (std::list<std::string>::const_iterator it = list.begin();
357 it != list.end(); ++it)
359 if (CompareString(*it, op, s))
363 else if (objType ==
typeid(
char))
365 return CompareString(std::string(1, ref_any_cast<char>(obj)), op, s);
367 else if (objType ==
typeid(
bool))
369 if (op==LE || op==GE)
372 std::string boolVal =
any_cast<
bool>(obj) ?
"true" :
"false";
373 return std::equal(s.begin(), s.end(), boolVal.begin(),
stricomp);
375 else if (objType ==
typeid(
short))
377 return CompareIntegralType<short>(obj, op, s);
379 else if (objType ==
typeid(
int))
381 return CompareIntegralType<int>(obj, op, s);
383 else if (objType ==
typeid(
long int))
385 return CompareIntegralType<long int>(obj, op, s);
387 else if (objType ==
typeid(
long long int))
389 return CompareIntegralType<long long int>(obj, op, s);
391 else if (objType ==
typeid(
unsigned char))
393 return CompareIntegralType<unsigned char>(obj, op, s);
395 else if (objType ==
typeid(
unsigned short))
397 return CompareIntegralType<unsigned short>(obj, op, s);
399 else if (objType ==
typeid(
unsigned int))
401 return CompareIntegralType<unsigned int>(obj, op, s);
403 else if (objType ==
typeid(
unsigned long int))
405 return CompareIntegralType<unsigned long int>(obj, op, s);
407 else if (objType ==
typeid(
unsigned long long int))
409 return CompareIntegralType<unsigned long long int>(obj, op, s);
411 else if (objType ==
typeid(
float))
414 char* endptr =
nullptr;
415 double sFloat = strtod(s.c_str(), &endptr);
416 if ((errno == ERANGE && (sFloat == 0 || sFloat == HUGE_VAL || sFloat == -HUGE_VAL)) ||
417 (errno != 0 && sFloat == 0) || endptr == s.c_str())
422 double floatVal =
static_cast<double>(
any_cast<
float>(obj));
427 return floatVal <= sFloat;
429 return floatVal >= sFloat;
431 double diff = floatVal - sFloat;
432 return (diff < std::numeric_limits<float>::epsilon()) && (diff > -std::numeric_limits<float>::epsilon());
435 else if (objType ==
typeid(
double))
438 char* endptr =
nullptr;
439 double sDouble = strtod(s.c_str(), &endptr);
440 if ((errno == ERANGE && (sDouble == 0 || sDouble == HUGE_VAL || sDouble == -HUGE_VAL)) ||
441 (errno != 0 && sDouble == 0) || endptr == s.c_str())
446 double doubleVal =
any_cast<
double>(obj);
451 return doubleVal <= sDouble;
453 return doubleVal >= sDouble;
455 double diff = doubleVal - sDouble;
456 return (diff < std::numeric_limits<double>::epsilon()) && (diff > -std::numeric_limits<double>::epsilon());
459 else if (objType ==
typeid(std::vector<Any>))
461 const std::vector<Any>& list =
ref_any_cast<std::vector<Any> >(obj);
462 for (std::size_t it = 0; it != list.size(); it++)
464 if (Compare(list[it], op, s))
478 bool LDAPExpr::CompareIntegralType(
const Any& obj,
const int op,
const std::string& s)
const 481 char* endptr =
nullptr;
482 long longInt = strtol(s.c_str(), &endptr, 10);
484 (errno != 0 && longInt == 0) || endptr == s.c_str())
489 T sInt =
static_cast<T
>(longInt);
495 return intVal <= sInt;
497 return intVal >= sInt;
499 return intVal == sInt;
503 bool LDAPExpr::CompareString(
const std::string& s1,
int op,
const std::string& s2 )
508 return s1.compare(s2) <= 0;
510 return s1.compare(s2) >= 0;
512 return PatSubstr(s1,s2);
514 return FixupString(s2) == FixupString(s1);
520 std::string LDAPExpr::FixupString(
const std::string& s )
523 sb.reserve(s.size());
524 std::size_t len = s.length();
525 for(std::size_t i=0; i<len; i++)
528 if (!std::isspace(c))
538 bool LDAPExpr::PatSubstr(
const std::string& s,
int si,
const std::string& pat,
int pi )
540 if (pat.size()-pi == 0)
541 return s.size()-si == 0;
547 if (PatSubstr(s, si, pat, pi))
549 if (s.size()-si == 0)
556 if (s.size()-si == 0)
564 return PatSubstr(s, ++si, pat, ++pi);
568 bool LDAPExpr::PatSubstr(
const std::string& s,
const std::string& pat )
570 return PatSubstr(s, 0, pat, 0);
573 LDAPExpr LDAPExpr::ParseExpr( ParseState& ps )
596 return ParseSimple(ps);
600 std::vector<LDAPExpr> v;
603 v.push_back(ParseExpr(ps));
605 }
while (ps.peek() ==
'(');
607 std::size_t n = v.size();
608 if (!ps.prefix(
")") || n == 0 || (op == NOT && n > 1))
611 return LDAPExpr(op, v);
614 LDAPExpr LDAPExpr::ParseSimple( ParseState &ps )
616 std::string attrName = ps.getAttributeName();
617 if (attrName.empty())
622 else if (ps.prefix(
"<="))
624 else if(ps.prefix(
">="))
626 else if(ps.prefix(
"~="))
633 std::string attrValue = ps.getAttributeValue();
636 return LDAPExpr(op, attrName, attrValue);
639 const std::string LDAPExpr::ToString()
const 643 if ((d->m_operator & SIMPLE) != 0)
645 res.append(d->m_attrName);
646 switch (d->m_operator)
662 for (std::size_t i = 0; i < d->m_attrValue.length(); i++)
664 Byte c = d->m_attrValue.at(i);
665 if (c ==
'(' || c ==
')' || c ==
'*' || c ==
'\\')
678 switch (d->m_operator)
690 for (std::size_t i = 0; i < d->m_args.size(); i++)
692 res.append(d->m_args[i].ToString());
699 LDAPExpr::ParseState::ParseState(
const std::string& str )
710 bool LDAPExpr::ParseState::prefix(
const std::string& pre )
712 std::string::iterator startIter = m_str.begin() + m_pos;
713 if (!std::equal(pre.begin(), pre.end(), startIter))
719 char LDAPExpr::ParseState::peek()
721 if ( m_pos >= m_str.size() )
723 throw std::out_of_range(
"LDAPExpr" );
725 return m_str.at(m_pos);
728 void LDAPExpr::ParseState::skip(
int n )
733 std::string LDAPExpr::ParseState::rest()
const 735 return m_str.substr(m_pos);
738 void LDAPExpr::ParseState::skipWhite()
740 while (std::isspace(peek()))
746 std::string LDAPExpr::ParseState::getAttributeName()
748 std::size_t start = m_pos;
754 if (c ==
'(' || c ==
')' ||
755 c ==
'<' || c ==
'>' ||
756 c ==
'=' || c ==
'~') {
759 else if (!std::isspace(c))
761 n = m_pos - start + 1;
767 return std::string();
769 return m_str.substr(start, n);
772 std::string LDAPExpr::ParseState::getAttributeValue()
788 sb.append(1, m_str.at(++m_pos));
803 void LDAPExpr::ParseState::error(
const std::string &m )
const 805 std::string errorStr = m +
": " + (m_str.empty() ?
"" : m_str.substr(m_pos));
806 throw std::invalid_argument(errorStr);
static const std::string & OPERATOR()
static LDAPExpr::Byte WILDCARD()
static const std::string & WILDCARD_STRING()
ValueType * any_cast(Any *operand)
static const std::string & MALFORMED()
const std::type_info & Type() const
static const std::string & EOS()
US_Core_EXPORT const std::string & OBJECTCLASS()
std::vector< std::string > StringList
const ValueType & ref_any_cast(const Any &operand)
bool stricomp(const std::string::value_type &v1, const std::string::value_type &v2)
static const std::string & nullptrQ()
static const std::string & GARBAGE()