22 #include "usLDAPExpr_p.h"
25 #include "usServicePropertiesImpl_p.h"
38 namespace LDAPExprConstants {
52 static const std::string&
NULLQ()
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);
90 class LDAPExpr::ParseState
100 ParseState(
const std::string &str);
103 bool prefix(
const std::string &pre);
108 LDAPExpr::Byte peek();
114 std::string rest()
const;
120 std::string getAttributeName();
123 std::string getAttributeValue();
126 void error(
const std::string &m)
const;
131 class LDAPExprData :
public SharedData
135 LDAPExprData(
int op,
const std::vector<LDAPExpr>& args )
136 : m_operator(op), m_args(args), m_attrName(), m_attrValue()
140 LDAPExprData(
int op, std::string attrName,
const std::string& attrValue )
141 : m_operator(op), m_args(), m_attrName(attrName), m_attrValue(attrValue)
145 LDAPExprData(
const LDAPExprData& other )
146 : SharedData(other), m_operator(other.m_operator),
147 m_args(other.m_args), m_attrName(other.m_attrName),
148 m_attrValue(other.m_attrValue)
153 std::vector<LDAPExpr> m_args;
154 std::string m_attrName;
155 std::string m_attrValue;
158 LDAPExpr::LDAPExpr() : d()
162 LDAPExpr::LDAPExpr(
const std::string &filter ) : d()
164 ParseState ps(filter);
167 LDAPExpr expr = ParseExpr(ps);
169 if (!Trim(ps.rest()).empty())
176 catch (
const std::out_of_range&)
182 LDAPExpr::LDAPExpr(
int op,
const std::vector<LDAPExpr>& args )
183 : d(new LDAPExprData(op, args))
187 LDAPExpr::LDAPExpr(
int op,
const std::string &attrName,
const std::string &attrValue )
188 : d(new LDAPExprData(op, attrName, attrValue))
192 LDAPExpr::LDAPExpr(
const LDAPExpr& other )
197 LDAPExpr& LDAPExpr::operator=(
const LDAPExpr& other)
203 LDAPExpr::~LDAPExpr()
207 std::string LDAPExpr::Trim(std::string str)
209 str.erase(0, str.find_first_not_of(
' '));
210 str.erase(str.find_last_not_of(
' ')+1);
214 bool LDAPExpr::GetMatchedObjectClasses(ObjectClassSet& objClasses)
const
216 if (d->m_operator == EQ)
222 objClasses.insert( d->m_attrValue );
227 else if (d->m_operator == AND)
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))
236 if (objClasses.empty())
244 LDAPExpr::ObjectClassSet::iterator it1 = objClasses.begin();
245 LDAPExpr::ObjectClassSet::iterator it2 = r.begin();
246 while ( (it1 != objClasses.end()) && (it2 != r.end()) )
250 objClasses.erase(it1++);
252 else if (*it2 < *it1)
264 objClasses.erase(it1, objClasses.end());
270 else if (d->m_operator == OR)
272 for (std::size_t i = 0; i < d->m_args.size( ); i++)
274 LDAPExpr::ObjectClassSet r;
275 if (d->m_args[i].GetMatchedObjectClasses(r))
277 std::copy(r.begin(), r.end(), std::inserter(objClasses, objClasses.begin()));
290 std::string LDAPExpr::ToLower(
const std::string& str)
292 std::string lowerStr(str);
293 std::transform(str.begin(), str.end(), lowerStr.begin(), ::tolower);
297 bool LDAPExpr::IsSimple(
const StringList& keywords, LocalCache& cache,
298 bool matchCase )
const
302 cache.resize(keywords.size());
305 if (d->m_operator == EQ)
307 StringList::const_iterator index;
308 if ((index = std::find(keywords.begin(), keywords.end(), matchCase ? d->m_attrName : ToLower(d->m_attrName))) != keywords.end() &&
311 cache[index - keywords.begin()] =
StringList(1, d->m_attrValue);
315 else if (d->m_operator == OR)
317 for (std::size_t i = 0; i < d->m_args.size( ); i++)
319 if (!d->m_args[i].IsSimple(keywords, cache, matchCase))
327 bool LDAPExpr::IsNull()
const
332 bool LDAPExpr::Query(
const std::string& filter,
const ServicePropertiesImpl& pd)
334 return LDAPExpr(filter).Evaluate(pd,
false);
337 bool LDAPExpr::Evaluate(
const ServicePropertiesImpl& p,
bool matchCase )
const
339 if ((d->m_operator & SIMPLE) != 0)
342 int index = p.FindCaseSensitive(d->m_attrName);
343 if (index < 0 && !matchCase) index = p.Find(d->m_attrName);
344 return index < 0 ?
false : Compare(p.Value(index), d->m_operator, d->m_attrValue);
348 switch (d->m_operator)
351 for (std::size_t i = 0; i < d->m_args.size(); i++)
353 if (!d->m_args[i].Evaluate(p, matchCase))
358 for (std::size_t i = 0; i < d->m_args.size(); i++)
360 if (d->m_args[i].Evaluate(p, matchCase))
365 return !d->m_args[0].Evaluate(p, matchCase);
372 bool LDAPExpr::Compare(
const Any& obj,
int op,
const std::string& s )
const
381 const std::type_info& objType = obj.Type();
382 if (objType ==
typeid(std::string))
384 return CompareString(ref_any_cast<std::string>(obj), op, s);
386 else if (objType ==
typeid(std::vector<std::string>))
388 const std::vector<std::string>& list =
ref_any_cast<std::vector<std::string> >(obj);
389 for (std::size_t it = 0; it != list.size(); it++)
391 if (CompareString(list[it], op, s))
395 else if (objType ==
typeid(std::list<std::string>))
397 const std::list<std::string>& list =
ref_any_cast<std::list<std::string> >(obj);
398 for (std::list<std::string>::const_iterator it = list.begin();
399 it != list.end(); ++it)
401 if (CompareString(*it, op, s))
405 else if (objType ==
typeid(
char))
407 return CompareString(std::string(1, ref_any_cast<char>(obj)), op, s);
409 else if (objType ==
typeid(
bool))
411 if (op==LE || op==GE)
414 std::string boolVal =
any_cast<
bool>(obj) ?
"true" :
"false";
415 return std::equal(s.begin(), s.end(), boolVal.begin(),
stricomp);
417 else if (objType ==
typeid(
short))
419 return CompareIntegralType<short>(obj, op, s);
421 else if (objType ==
typeid(
int))
423 return CompareIntegralType<int>(obj, op, s);
425 else if (objType ==
typeid(
long int))
427 return CompareIntegralType<long int>(obj, op, s);
429 else if (objType ==
typeid(
long long int))
431 return CompareIntegralType<long long int>(obj, op, s);
433 else if (objType ==
typeid(
unsigned char))
435 return CompareIntegralType<unsigned char>(obj, op, s);
437 else if (objType ==
typeid(
unsigned short))
439 return CompareIntegralType<unsigned short>(obj, op, s);
441 else if (objType ==
typeid(
unsigned int))
443 return CompareIntegralType<unsigned int>(obj, op, s);
445 else if (objType ==
typeid(
unsigned long int))
447 return CompareIntegralType<unsigned long int>(obj, op, s);
449 else if (objType ==
typeid(
unsigned long long int))
451 return CompareIntegralType<unsigned long long int>(obj, op, s);
453 else if (objType ==
typeid(
float))
457 double sFloat = strtod(s.c_str(), &endptr);
458 if ((errno == ERANGE && (sFloat == 0 || sFloat == HUGE_VAL || sFloat == -HUGE_VAL)) ||
459 (errno != 0 && sFloat == 0) || endptr == s.c_str())
464 double floatVal =
static_cast<double>(
any_cast<
float>(obj));
469 return floatVal <= sFloat;
471 return floatVal >= sFloat;
473 double diff = floatVal - sFloat;
474 return (diff < std::numeric_limits<float>::epsilon()) && (diff > -std::numeric_limits<float>::epsilon());
477 else if (objType ==
typeid(
double))
481 double sDouble = strtod(s.c_str(), &endptr);
482 if ((errno == ERANGE && (sDouble == 0 || sDouble == HUGE_VAL || sDouble == -HUGE_VAL)) ||
483 (errno != 0 && sDouble == 0) || endptr == s.c_str())
488 double doubleVal =
any_cast<
double>(obj);
493 return doubleVal <= sDouble;
495 return doubleVal >= sDouble;
497 double diff = doubleVal - sDouble;
498 return (diff < std::numeric_limits<double>::epsilon()) && (diff > -std::numeric_limits<double>::epsilon());
501 else if (objType ==
typeid(std::vector<Any>))
503 const std::vector<Any>& list =
ref_any_cast<std::vector<Any> >(obj);
504 for (std::size_t it = 0; it != list.size(); it++)
506 if (Compare(list[it], op, s))
520 bool LDAPExpr::CompareIntegralType(
const Any& obj,
const int op,
const std::string& s)
const
524 long longInt = strtol(s.c_str(), &endptr, 10);
526 (errno != 0 && longInt == 0) || endptr == s.c_str())
531 T sInt =
static_cast<T
>(longInt);
537 return intVal <= sInt;
539 return intVal >= sInt;
541 return intVal == sInt;
545 bool LDAPExpr::CompareString(
const std::string& s1,
int op,
const std::string& s2 )
550 return s1.compare(s2) <= 0;
552 return s1.compare(s2) >= 0;
554 return PatSubstr(s1,s2);
556 return FixupString(s2) == FixupString(s1);
562 std::string LDAPExpr::FixupString(
const std::string& s )
565 sb.reserve(s.size());
566 std::size_t len = s.length();
567 for(std::size_t i=0; i<len; i++)
570 if (!std::isspace(c))
580 bool LDAPExpr::PatSubstr(
const std::string& s,
int si,
const std::string& pat,
int pi )
582 if (pat.size()-pi == 0)
583 return s.size()-si == 0;
589 if (PatSubstr(s, si, pat, pi))
591 if (s.size()-si == 0)
598 if (s.size()-si == 0)
606 return PatSubstr(s, ++si, pat, ++pi);
610 bool LDAPExpr::PatSubstr(
const std::string& s,
const std::string& pat )
612 return PatSubstr(s, 0, pat, 0);
615 LDAPExpr LDAPExpr::ParseExpr( ParseState& ps )
638 return ParseSimple(ps);
642 std::vector<LDAPExpr> v;
645 v.push_back(ParseExpr(ps));
647 }
while (ps.peek() ==
'(');
649 std::size_t n = v.size();
650 if (!ps.prefix(
")") || n == 0 || (op == NOT && n > 1))
653 return LDAPExpr(op, v);
656 LDAPExpr LDAPExpr::ParseSimple( ParseState &ps )
658 std::string attrName = ps.getAttributeName();
659 if (attrName.empty())
664 else if (ps.prefix(
"<="))
666 else if(ps.prefix(
">="))
668 else if(ps.prefix(
"~="))
675 std::string attrValue = ps.getAttributeValue();
678 return LDAPExpr(op, attrName, attrValue);
681 const std::string LDAPExpr::ToString()
const
685 if ((d->m_operator & SIMPLE) != 0)
687 res.append(d->m_attrName);
688 switch (d->m_operator)
704 for (std::size_t i = 0; i < d->m_attrValue.length(); i++)
706 Byte c = d->m_attrValue.at(i);
707 if (c ==
'(' || c ==
')' || c ==
'*' || c ==
'\\')
720 switch (d->m_operator)
732 for (std::size_t i = 0; i < d->m_args.size(); i++)
734 res.append(d->m_args[i].ToString());
741 LDAPExpr::ParseState::ParseState(
const std::string& str )
752 bool LDAPExpr::ParseState::prefix(
const std::string& pre )
754 std::string::iterator startIter = m_str.begin() + m_pos;
755 if (!std::equal(pre.begin(), pre.end(), startIter))
761 char LDAPExpr::ParseState::peek()
763 if ( m_pos >= m_str.size() )
765 throw std::out_of_range(
"LDAPExpr" );
767 return m_str.at(m_pos);
770 void LDAPExpr::ParseState::skip(
int n )
775 std::string LDAPExpr::ParseState::rest()
const
777 return m_str.substr(m_pos);
780 void LDAPExpr::ParseState::skipWhite()
782 while (std::isspace(peek()))
788 std::string LDAPExpr::ParseState::getAttributeName()
790 std::size_t start = m_pos;
796 if (c ==
'(' || c ==
')' ||
797 c ==
'<' || c ==
'>' ||
798 c ==
'=' || c ==
'~') {
801 else if (!std::isspace(c))
803 n = m_pos - start + 1;
809 return std::string();
811 return m_str.substr(start, n);
814 std::string LDAPExpr::ParseState::getAttributeValue()
830 sb.append(1, m_str.at(++m_pos));
845 void LDAPExpr::ParseState::error(
const std::string &m )
const
847 std::string errorStr = m +
": " + (m_str.empty() ?
"" : m_str.substr(m_pos));
848 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()
static const std::string & EOS()
static const std::string & NULLQ()
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 & GARBAGE()