Added String methods used to append using printf.
Added static String methods to be used with plain C strings: starts/end check, skip string or characters in given set. Added support to build an AutoGenObject not owning the pointer. MatchingItem: added dump support, added matching parameters, added random matching.
This commit is contained in:
parent
4b9310defc
commit
4c2de15148
|
@ -1376,6 +1376,33 @@ String& String::printf(const char* format, ...)
|
|||
return *this;
|
||||
}
|
||||
|
||||
String& String::printfAppend(unsigned int length, const char* format, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va,format);
|
||||
char* buf = string_printf(length,format,va);
|
||||
va_end(va);
|
||||
if (buf) {
|
||||
*this << buf;
|
||||
::free(buf);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
String& String::printfAppend(const char* format, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va,format);
|
||||
unsigned int len = TelEngine::null(format) ? 0 : (128 + ::strlen(format));
|
||||
char* buf = string_printf(len,format,va);
|
||||
va_end(va);
|
||||
if (buf) {
|
||||
*this << buf;
|
||||
::free(buf);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
String& String::appendFixed(unsigned int fixedLength, const char* str, unsigned int len, char fill, int align)
|
||||
{
|
||||
if (len == (unsigned int)-1)
|
||||
|
@ -2093,6 +2120,90 @@ const String* String::atom(const String*& str, const char* val)
|
|||
return str;
|
||||
}
|
||||
|
||||
static unsigned int c_find_str(bool start, const char* str, const char* what,
|
||||
int lenStr, int lenWhat, bool caseInsensitive)
|
||||
{
|
||||
if (!lenStr || !lenWhat || TelEngine::null(str) || TelEngine::null(what))
|
||||
return 0;
|
||||
if (lenStr < 0)
|
||||
lenStr = ::strlen(str);
|
||||
if (lenWhat < 0)
|
||||
lenWhat = ::strlen(what);
|
||||
if (lenStr < lenWhat)
|
||||
return 0;
|
||||
if (!start)
|
||||
str += lenStr - lenWhat - 1;
|
||||
if (caseInsensitive) {
|
||||
if (::strncasecmp(str,what,lenWhat))
|
||||
return 0;
|
||||
}
|
||||
else if (::strncmp(str,what,lenWhat))
|
||||
return 0;
|
||||
return lenWhat;
|
||||
}
|
||||
|
||||
unsigned int String::c_starts_with(const char* str, const char* what, int lenStr, int lenWhat,
|
||||
bool caseInsensitive)
|
||||
{
|
||||
return c_find_str(true,str,what,lenStr,lenWhat,caseInsensitive);
|
||||
}
|
||||
|
||||
unsigned int String::c_ends_with(const char* str, const char* what, int lenStr, int lenWhat,
|
||||
bool caseInsensitive)
|
||||
{
|
||||
return c_find_str(false,str,what,lenStr,lenWhat,caseInsensitive);
|
||||
}
|
||||
|
||||
unsigned int String::c_skip_chars(const char*& str, const char* what, int len, bool skipFound)
|
||||
{
|
||||
if (!len || TelEngine::null(str) || TelEngine::null(what))
|
||||
return 0;
|
||||
const char* orig = str;
|
||||
if (skipFound) {
|
||||
if (len < 0) {
|
||||
if (what[1])
|
||||
while (*str) {
|
||||
if (!::strchr(what,*str))
|
||||
break;
|
||||
str++;
|
||||
}
|
||||
else
|
||||
while (*str == *what)
|
||||
str++;
|
||||
}
|
||||
else if (what[1])
|
||||
while (len-- && *str) {
|
||||
if (!::strchr(what,*str))
|
||||
break;
|
||||
str++;
|
||||
}
|
||||
else
|
||||
while (len-- && *str == *what)
|
||||
str++;
|
||||
}
|
||||
else if (len < 0) {
|
||||
if (what[1])
|
||||
while (*str) {
|
||||
if (::strchr(what,*str))
|
||||
break;
|
||||
str++;
|
||||
}
|
||||
else
|
||||
while (*str && *str != *what)
|
||||
str++;
|
||||
}
|
||||
else if (what[1])
|
||||
while (len-- && *str) {
|
||||
if (::strchr(what,*str))
|
||||
break;
|
||||
str++;
|
||||
}
|
||||
else
|
||||
while (len-- && *str && *str != *what)
|
||||
str++;
|
||||
return (unsigned int)(str - orig);
|
||||
}
|
||||
|
||||
|
||||
Regexp::Regexp()
|
||||
: m_regexp(0), m_compile(true), m_flags(0)
|
||||
|
@ -2344,23 +2455,236 @@ String& String::changeStringData(char* data, unsigned int len)
|
|||
|
||||
|
||||
//
|
||||
// MatchingItemList
|
||||
// MatchingItemDump
|
||||
//
|
||||
bool MatchingItemList::append(MatchingItemBase* item, unsigned int overAlloc)
|
||||
static inline void addFlags(String& buf, const String& flags)
|
||||
{
|
||||
if (flags)
|
||||
buf << '[' << flags << "] ";
|
||||
}
|
||||
|
||||
static inline const char* miType(const MatchingItemBase* item)
|
||||
{
|
||||
if (!item)
|
||||
return false;
|
||||
unsigned int pos = 0;
|
||||
while (m_value.at(pos))
|
||||
pos++;
|
||||
if (pos == m_value.length())
|
||||
m_value.resize(m_value.length() + 1 + overAlloc,true);
|
||||
if (pos < length()) {
|
||||
m_value.set(item,pos);
|
||||
return "";
|
||||
if (item->itemList())
|
||||
return "list";
|
||||
if (item->itemString())
|
||||
return "string";
|
||||
if (item->itemRegexp())
|
||||
return "regexp";
|
||||
if (item->itemRandom())
|
||||
return "random";
|
||||
if (item->itemCustom())
|
||||
return item->itemCustom()->type().safe("custom");
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
static const TokenDict s_miDumpFlags[] = {
|
||||
{"no_initial_list_desc", MatchingItemDump::NoInitialListDesc},
|
||||
{0,0}
|
||||
};
|
||||
|
||||
void MatchingItemDump::init(const NamedList& params)
|
||||
{
|
||||
for (ObjList* o = params.paramList()->skipNull(); o; o = o->skipNext()) {
|
||||
NamedString* ns = static_cast<NamedString*>(o->get());
|
||||
if (ns->name() == YSTRING("flags"))
|
||||
m_flags = ns->encodeFlags(s_miDumpFlags);
|
||||
else if (ns->name() == YSTRING("rex_enclose"))
|
||||
m_rexEnclose = (*ns)[0];
|
||||
else if (ns->name() == YSTRING("str_enclose"))
|
||||
m_strEnclose = (*ns)[0];
|
||||
else if (ns->name() == YSTRING("name_value_sep"))
|
||||
m_nameValueSep = *ns;
|
||||
else if (ns->name() == YSTRING("prop_negated"))
|
||||
m_negated = (*ns)[0];
|
||||
else if (ns->name() == YSTRING("prop_caseinsensitive"))
|
||||
m_caseInsentive = (*ns)[0];
|
||||
else if (ns->name() == YSTRING("prop_rex_basic"))
|
||||
m_regexpBasic = (*ns)[0];
|
||||
else if (ns->name() == YSTRING("prop_rex_extended"))
|
||||
m_regexpExtended = (*ns)[0];
|
||||
}
|
||||
}
|
||||
|
||||
String& MatchingItemDump::dumpValue(const MatchingItemBase* item, String& buf,
|
||||
const String& indent, const String& origIndent, unsigned int depth) const
|
||||
{
|
||||
if (!item)
|
||||
return buf;
|
||||
String tmp;
|
||||
// Done if already dumped (item implements dumpValue())
|
||||
if (item->dumpValue(tmp,this,indent,origIndent,depth))
|
||||
return buf << tmp;
|
||||
XDebug("MatchingItemDump",DebugAll,"dumpValue (%p) %s '%s' indent='%s' origIndent='%s'",
|
||||
item,miType(item),item->name().safe(),indent.safe(),origIndent.safe());
|
||||
if (item->itemList()) {
|
||||
for (unsigned int i = 0; i < item->itemList()->length(); ++i) {
|
||||
String tmp;
|
||||
buf << dump(item->itemList()->at(i),tmp,indent,origIndent,depth);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const MatchingItemString* str = item->itemString();
|
||||
const MatchingItemRegexp* rex = str ? 0 : item->itemRegexp();
|
||||
String flags;
|
||||
if (item->negated())
|
||||
flags << m_negated;
|
||||
if (str) {
|
||||
if (str->caseInsensitive())
|
||||
flags << m_caseInsentive;
|
||||
addFlags(buf,flags);
|
||||
buf << m_strEnclose << item->itemString()->value() << m_strEnclose;
|
||||
}
|
||||
else if (rex) {
|
||||
if (rex->value().isCaseInsensitive())
|
||||
flags << m_caseInsentive;
|
||||
if (rex->value().isExtended())
|
||||
flags << m_regexpExtended;
|
||||
else
|
||||
flags << m_regexpBasic;
|
||||
addFlags(buf,flags);
|
||||
buf << m_rexEnclose << item->itemRegexp()->value() << m_rexEnclose;
|
||||
}
|
||||
else {
|
||||
addFlags(buf,flags);
|
||||
if (item->itemRandom()) {
|
||||
buf << "RANDOM " << item->itemRandom()->value();
|
||||
if (item->itemRandom()->maxValue() == 100)
|
||||
buf << '%';
|
||||
else
|
||||
buf << '/' << item->itemRandom()->maxValue();
|
||||
}
|
||||
else if (item->itemCustom())
|
||||
buf << "<CUSTOM " << item->itemCustom()->type() << '>';
|
||||
else
|
||||
buf << "<UNKNOWN>";
|
||||
}
|
||||
}
|
||||
XDebug("MatchingItemDump",DebugAll,"Dumped value (%p) '%s'\r\n-----\r\n%s\r\n-----",
|
||||
item,item->name().safe(),buf.safe());
|
||||
return buf;
|
||||
}
|
||||
|
||||
String& MatchingItemDump::dump(const MatchingItemBase* item, String& buf,
|
||||
const String& indent, const String& origIndent, unsigned int depth) const
|
||||
{
|
||||
if (!item)
|
||||
return buf;
|
||||
|
||||
XDebug("MatchingItemDump",DebugAll,"dump (%p) %s '%s' indent='%s' origIndent='%s'",
|
||||
item,miType(item),item->name().safe(),indent.safe(),origIndent.safe());
|
||||
unsigned int oLen = buf.length();
|
||||
item->dump(buf,this,indent,origIndent,depth);
|
||||
// Done if already dumped (item implements dump())
|
||||
if (oLen != buf.length())
|
||||
return buf;
|
||||
|
||||
const MatchingItemList* list = item->itemList();
|
||||
if (list) {
|
||||
String newIndent = indent;
|
||||
if (depth || 0 == (m_flags & NoInitialListDesc)) {
|
||||
String flags;
|
||||
if (list->negated())
|
||||
flags.append("negated",",");
|
||||
if (!list->matchAll())
|
||||
flags.append("any",",");
|
||||
if (flags)
|
||||
flags.printf(" [%s]",flags.safe());
|
||||
if (flags || depth || item->name()) {
|
||||
buf << indent << item->name().safe("List") << ':' << flags;
|
||||
if (depth)
|
||||
newIndent += origIndent;
|
||||
}
|
||||
}
|
||||
for (unsigned int i = 0; i < list->length(); ++i) {
|
||||
String tmp;
|
||||
buf << dump(list->at(i),tmp,newIndent,origIndent,depth + 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
String val;
|
||||
dumpValue(item,val);
|
||||
if (item->name() || val) {
|
||||
buf << indent << origIndent;
|
||||
if (item->name())
|
||||
buf << item->name() << m_nameValueSep.safe("=");
|
||||
buf << val;
|
||||
}
|
||||
}
|
||||
XDebug("MatchingItemDump",DebugAll,"Dumped (%p) '%s'\r\n-----\r\n%s\r\n-----",
|
||||
item,item->name().safe(),buf.safe());
|
||||
return buf;
|
||||
}
|
||||
|
||||
//
|
||||
// MatchingItemRegexp
|
||||
//
|
||||
MatchingItemRegexp* MatchingItemRegexp::build(const char* name, const String& str,
|
||||
int negated, bool insensitive, bool extended, int fail)
|
||||
{
|
||||
Regexp rex(0,extended,insensitive);
|
||||
if (str) {
|
||||
if (negated >= 0)
|
||||
rex.assign(str);
|
||||
else {
|
||||
unsigned int pos = str.length() - 1;
|
||||
negated = (str[pos] == '^') ? 1 : 0;
|
||||
if (negated)
|
||||
rex.assign(str.substr(0,pos));
|
||||
else
|
||||
rex.assign(str);
|
||||
}
|
||||
}
|
||||
else if (negated < 0)
|
||||
negated = 0;
|
||||
if (fail > 1) {
|
||||
if (!rex.compile())
|
||||
return 0;
|
||||
}
|
||||
else if (fail < 0 && !rex.c_str())
|
||||
return 0;
|
||||
return new MatchingItemRegexp(name,rex,negated);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// MatchingItemList
|
||||
//
|
||||
bool MatchingItemList::change(MatchingItemBase* item, int pos, bool ins, unsigned int overAlloc)
|
||||
{
|
||||
if (!item) {
|
||||
unsigned int n = count();
|
||||
if (ins || pos < 0 || pos >= (int)n)
|
||||
return false;
|
||||
// Remove
|
||||
GenObject* gen = m_value.take(pos);
|
||||
if (gen) {
|
||||
for (; pos < (int)n; ++pos)
|
||||
m_value.set(m_value.take(pos + 1),pos);
|
||||
TelEngine::destruct(gen);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
TelEngine::destruct(item);
|
||||
return false;
|
||||
// Detect first free position
|
||||
unsigned int firstFree = 0;
|
||||
while (m_value.at(firstFree))
|
||||
firstFree++;
|
||||
if (firstFree >= m_value.length()) {
|
||||
if (firstFree >= m_value.resize(m_value.length() + 1 + overAlloc,true)) {
|
||||
TelEngine::destruct(item);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (pos < 0 || pos >= (int)firstFree)
|
||||
pos = firstFree;
|
||||
else if (ins) {
|
||||
for (; (int)firstFree > pos; --firstFree)
|
||||
m_value.set(m_value.take(firstFree - 1),firstFree);
|
||||
}
|
||||
m_value.set(item,pos);
|
||||
return true;
|
||||
}
|
||||
|
||||
MatchingItemBase* MatchingItemList::copy() const
|
||||
|
@ -2380,30 +2704,39 @@ MatchingItemBase* MatchingItemList::copy() const
|
|||
return lst;
|
||||
}
|
||||
|
||||
#define MatchingItemList_RUN_LIST(func,param) { \
|
||||
int pos = -1; \
|
||||
while (true) { \
|
||||
MatchingItemBase* item = static_cast<MatchingItemBase*>(m_value.at(++pos)); \
|
||||
if (!item) \
|
||||
break; \
|
||||
if (item->func(param)) { \
|
||||
if (!m_matchAll) \
|
||||
return true; \
|
||||
} \
|
||||
else if (m_matchAll) \
|
||||
return false; \
|
||||
} \
|
||||
return pos ? m_matchAll : false; \
|
||||
static inline bool matchingListRun(const MatchingItemList& mil, MatchingParams* params,
|
||||
const NamedList* list, const String& str = String::empty())
|
||||
{
|
||||
int pos = -1;
|
||||
bool allMatch = mil.matchAll();
|
||||
while (true) {
|
||||
const MatchingItemBase* item = const_cast<MatchingItemBase*>(mil.at(++pos));
|
||||
if (!item)
|
||||
break;
|
||||
bool ok = list ? item->matchListParam(*list,params) : item->matchString(str,params);
|
||||
// Matched: done if not all match (any match)
|
||||
// Not matched: done if all match is required
|
||||
if (ok) {
|
||||
if (!allMatch)
|
||||
return true;
|
||||
}
|
||||
else if (allMatch)
|
||||
return false;
|
||||
}
|
||||
// End of list reached
|
||||
// Empty list or match any: not matched
|
||||
// Otherwise: matched
|
||||
return pos && allMatch;
|
||||
}
|
||||
|
||||
bool MatchingItemList::runMatchString(const String& str) const
|
||||
bool MatchingItemList::runMatchString(const String& str, MatchingParams* params) const
|
||||
{
|
||||
MatchingItemList_RUN_LIST(matchString,str)
|
||||
return matchingListRun(*this,params,0,str);
|
||||
}
|
||||
|
||||
bool MatchingItemList::runMatchListParam(const NamedList& list) const
|
||||
bool MatchingItemList::runMatchListParam(const NamedList& list, MatchingParams* params) const
|
||||
{
|
||||
MatchingItemList_RUN_LIST(matchListParam,list)
|
||||
return matchingListRun(*this,params,&list);
|
||||
}
|
||||
|
||||
#undef MatchingItemList_RUN_LIST
|
||||
|
@ -2413,9 +2746,11 @@ MatchingItemBase* MatchingItemList::optimize(MatchingItemList* list)
|
|||
if (!list || list->at(1))
|
||||
return list;
|
||||
MatchingItemBase* ret = static_cast<MatchingItemBase*>(list->m_value.take(0));
|
||||
// Reverse item (not)negated flag if list is negated to keep the same matching behaviour
|
||||
if (list->negated())
|
||||
ret->m_notNegated = !ret->m_notNegated;
|
||||
if (ret) {
|
||||
// Reverse item (not)negated flag if list is negated to keep the same matching behaviour
|
||||
if (list->negated())
|
||||
ret->m_notNegated = !ret->m_notNegated;
|
||||
}
|
||||
TelEngine::destruct(list);
|
||||
return ret;
|
||||
}
|
||||
|
|
662
yateclass.h
662
yateclass.h
|
@ -930,6 +930,36 @@ void YCLASS2(class type,class base1,class base2);
|
|||
*/
|
||||
void YCLASS3(class type,class base1,class base2,class base3);
|
||||
|
||||
/**
|
||||
* Macro to create a GenObject class from a base class and implement @ref GenObject::getObject
|
||||
* Try to obtain something from a data member first
|
||||
* @param dataPtr Pointer to member data variable
|
||||
* @param type Class that is declared
|
||||
* @param base Base class that is inherited
|
||||
*/
|
||||
void YCLASS_DATA(var dataPtr,class type,class base);
|
||||
|
||||
/**
|
||||
* Macro to create a GenObject class from two base classes and implement @ref GenObject::getObject
|
||||
* Try to obtain something from a data member first
|
||||
* @param dataPtr Pointer to member data variable
|
||||
* @param type Class that is declared
|
||||
* @param base1 First base class that is inherited
|
||||
* @param base2 Second base class that is inherited
|
||||
*/
|
||||
void YCLASS2_DATA(var dataPtr,class type,class base1,class base2);
|
||||
|
||||
/**
|
||||
* Macro to create a GenObject class from three base classes and implement @ref GenObject::getObject
|
||||
* Try to obtain something from a data member first
|
||||
* @param dataPtr Pointer to member data variable
|
||||
* @param type Class that is declared
|
||||
* @param base1 First base class that is inherited
|
||||
* @param base2 Second base class that is inherited
|
||||
* @param base3 Third base class that is inherited
|
||||
*/
|
||||
void YCLASS3_DATA(var dataPtr,class type,class base1,class base2,class base3);
|
||||
|
||||
/**
|
||||
* Macro to implement @ref GenObject::getObject in a derived class
|
||||
* @param type Class that is declared
|
||||
|
@ -987,6 +1017,32 @@ public: virtual void* getObject(const String& name) const \
|
|||
tmp = base2::getObject(name); \
|
||||
return tmp ? tmp : base3::getObject(name); }
|
||||
|
||||
#define YCLASS_CALL(res) { void* tmp = res; if (tmp) return tmp; }
|
||||
#define YCLASS_CALL_LAST(base1,base2) { void* tmp = base1::getObject(name); return tmp ? tmp : base2::getObject(name); }
|
||||
#define YCLASS_DATA_CHECK_PTR(dataPtr,type) { \
|
||||
if (dataPtr) YCLASS_CALL((dataPtr)->getObject(name)) \
|
||||
if (name == YATOM(#type)) return const_cast<type*>(this); \
|
||||
}
|
||||
|
||||
#define YCLASS_DATA(dataPtr,type,base) \
|
||||
public: virtual void* getObject(const String& name) const { \
|
||||
YCLASS_DATA_CHECK_PTR(dataPtr,type) \
|
||||
return base::getObject(name); \
|
||||
}
|
||||
|
||||
#define YCLASS2_DATA(dataPtr,type,base1,base2) \
|
||||
public: virtual void* getObject(const String& name) const { \
|
||||
YCLASS_DATA_CHECK_PTR(dataPtr,type) \
|
||||
YCLASS_CALL_LAST(base,base2) \
|
||||
}
|
||||
|
||||
#define YCLASS3_DATA(dataPtr,type,base1,base2,base3) \
|
||||
public: virtual void* getObject(const String& name) const { \
|
||||
YCLASS_DATA_CHECK_PTR(dataPtr,type) \
|
||||
YCLASS_CALL(base1::getObject(name)) \
|
||||
YCLASS_CALL_LAST(base2,base3) \
|
||||
}
|
||||
|
||||
#define YCLASSIMP(type,base) \
|
||||
void* type::getObject(const String& name) const \
|
||||
{ return (name == YATOM(#type)) ? const_cast<type*>(this) : base::getObject(name); }
|
||||
|
@ -1171,75 +1227,6 @@ inline void destruct(GenObject* obj)
|
|||
template <class Obj> void destruct(Obj*& obj)
|
||||
{ if (obj) { obj->destruct(); obj = 0; } }
|
||||
|
||||
/**
|
||||
* This class holds an automatic (owned) GenObject pointer
|
||||
* @short GenObject pointer holder (owned)
|
||||
*/
|
||||
class YATE_API AutoGenObject
|
||||
{
|
||||
YNOCOPY(AutoGenObject); // no automatic copies please
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* @param gen Optional pointer to object
|
||||
*/
|
||||
inline AutoGenObject(GenObject* gen = 0)
|
||||
: m_pointer(gen)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
inline ~AutoGenObject()
|
||||
{ set(); }
|
||||
|
||||
/**
|
||||
* Take the pointer. Caller retains ownership
|
||||
* @return GenObject pointer, NULL if not set
|
||||
*/
|
||||
inline GenObject* take() {
|
||||
GenObject* gen = m_pointer;
|
||||
m_pointer = 0;
|
||||
return gen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assignment from pointer
|
||||
* @param gen New pointer value
|
||||
*/
|
||||
inline AutoGenObject& operator=(GenObject* gen)
|
||||
{ set(gen); return *this; }
|
||||
|
||||
/**
|
||||
* Conversion to regular pointer operator
|
||||
* @return The stored pointer
|
||||
*/
|
||||
inline operator GenObject*() const
|
||||
{ return m_pointer; }
|
||||
|
||||
/**
|
||||
* Member access operator
|
||||
*/
|
||||
inline GenObject* operator->() const
|
||||
{ return m_pointer; }
|
||||
|
||||
/**
|
||||
* Dereferencing operator
|
||||
*/
|
||||
inline GenObject& operator*() const
|
||||
{ return *m_pointer; }
|
||||
|
||||
private:
|
||||
inline void set(GenObject* gen = 0) {
|
||||
if (m_pointer == gen)
|
||||
return;
|
||||
GenObject* tmp = m_pointer;
|
||||
m_pointer = gen;
|
||||
TelEngine::destruct(tmp);
|
||||
}
|
||||
GenObject* m_pointer;
|
||||
};
|
||||
|
||||
/**
|
||||
* A reference counted object.
|
||||
* Whenever using multiple inheritance you should inherit this class virtually.
|
||||
|
@ -2950,6 +2937,20 @@ public:
|
|||
*/
|
||||
String& printf(unsigned int length, const char* format, ...) FORMAT_CHECK(3);
|
||||
|
||||
/**
|
||||
* Append a String in a printf style.
|
||||
* @param format The output format.
|
||||
* NOTE: The length of added string will be at most 128 + length of format
|
||||
*/
|
||||
String& printfAppend(const char* format, ...) FORMAT_CHECK(2);
|
||||
|
||||
/**
|
||||
* Append a String in a printf style.
|
||||
* @param length maximum length of the resulting string
|
||||
* @param format The output format.
|
||||
*/
|
||||
String& printfAppend(unsigned int length, const char* format, ...) FORMAT_CHECK(3);
|
||||
|
||||
/**
|
||||
* Build a fixed aligned string from str and append it.
|
||||
* @param fixedLength The fixed length in which the 'str' will be aligned.
|
||||
|
@ -3315,6 +3316,57 @@ public:
|
|||
*/
|
||||
static const String* atom(const String*& str, const char* val);
|
||||
|
||||
/**
|
||||
* Checks if a string starts with a substring
|
||||
* @param str String to search in
|
||||
* @param what Substring to check
|
||||
* @param lenStr String length, negative to detect
|
||||
* @param lenWhat Substring length, negative to detect
|
||||
* @param caseInsensitive Compare case-insensitive if set
|
||||
* @return The length of substring if string starts with it
|
||||
*/
|
||||
static unsigned int c_starts_with(const char* str, const char* what, int lenStr = -1,
|
||||
int lenWhat = -1, bool caseInsensitive = false);
|
||||
|
||||
/**
|
||||
* Checks if a string ends with a substring
|
||||
* @param str String to search in
|
||||
* @param what Substring to check
|
||||
* @param lenStr String length, negative to detect
|
||||
* @param lenWhat Substring length, negative to detect
|
||||
* @param caseInsensitive Compare case-insensitive if set
|
||||
* @return The length of substring if string ends with it
|
||||
*/
|
||||
static unsigned int c_ends_with(const char* str, const char* what, int lenStr = -1,
|
||||
int lenWhat = -1, bool caseInsensitive = false);
|
||||
|
||||
/**
|
||||
* Skip substring in string if matches
|
||||
* @param str String to search in. Will be advanced by skipped chars
|
||||
* @param what Substring to match
|
||||
* @param lenStr String length, negative to detect
|
||||
* @param lenWhat Substring length, negative to detect
|
||||
* @param caseInsensitive Compare case-insensitive if set
|
||||
* @return The number of skipped chars (length of substring), 0 if not matched
|
||||
*/
|
||||
static inline unsigned int c_skip(const char*& str, const char* what, int lenStr = -1,
|
||||
int lenWhat = -1, bool caseInsensitive = false) {
|
||||
unsigned int n = c_starts_with(str,what,lenStr,lenWhat,caseInsensitive);
|
||||
str += n;
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip chars in string
|
||||
* @param str String to skip in. Will be advanced by skipped chars
|
||||
* @param what Characters to match
|
||||
* @param len Optional maximum length to search in string, negative to use the whole string
|
||||
* @param skipFound Set it to false to skip while NOT match (until first match character)
|
||||
* @return Number of skipped chars
|
||||
*/
|
||||
static unsigned int c_skip_chars(const char*& str, const char* what,
|
||||
int len = -1, bool skipFound = true);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Called whenever the value changed (except in constructors).
|
||||
|
@ -3331,6 +3383,95 @@ private:
|
|||
StringMatchPrivate* m_matches;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class holds an automatic (owned) GenObject pointer
|
||||
* Ownership may be reset to avoid releasing the held pointer when destroyed
|
||||
* @short GenObject pointer holder
|
||||
*/
|
||||
class YATE_API AutoGenObject : public String
|
||||
{
|
||||
YCLASS_DATA(m_pointer,AutoGenObject,String)
|
||||
YNOCOPY(AutoGenObject); // no automatic copies please
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* @param gen Optional pointer to object
|
||||
* @param name Optional name
|
||||
* @param owned True if held object is owned
|
||||
*/
|
||||
inline AutoGenObject(GenObject* gen = 0, const char* name = 0, bool owned = true)
|
||||
: String(name), m_pointer(gen), m_owned(owned)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
inline ~AutoGenObject()
|
||||
{ set(); }
|
||||
|
||||
/**
|
||||
* Retrieve the held data
|
||||
* @return The stored pointer
|
||||
*/
|
||||
inline GenObject* data() const
|
||||
{ return m_pointer; }
|
||||
|
||||
/**
|
||||
* Take the pointer. Caller retains ownership
|
||||
* @return GenObject pointer, NULL if not set
|
||||
*/
|
||||
inline GenObject* take() {
|
||||
GenObject* gen = m_pointer;
|
||||
m_pointer = 0;
|
||||
return gen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace data
|
||||
* @param gen Optional pointer to object
|
||||
* @param owned True if held object is owned
|
||||
*/
|
||||
inline void set(GenObject* gen = 0, bool owned = true) {
|
||||
if (m_pointer == gen)
|
||||
return;
|
||||
GenObject* tmp = m_pointer;
|
||||
m_pointer = gen;
|
||||
if (m_owned)
|
||||
TelEngine::destruct(tmp);
|
||||
m_owned = owned;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assignment from pointer
|
||||
* @param gen New pointer value
|
||||
*/
|
||||
inline AutoGenObject& operator=(GenObject* gen)
|
||||
{ set(gen); return *this; }
|
||||
|
||||
/**
|
||||
* Conversion to regular pointer operator
|
||||
* @return The stored pointer
|
||||
*/
|
||||
inline operator GenObject*() const
|
||||
{ return m_pointer; }
|
||||
|
||||
/**
|
||||
* Member access operator
|
||||
*/
|
||||
inline GenObject* operator->() const
|
||||
{ return m_pointer; }
|
||||
|
||||
/**
|
||||
* Dereferencing operator
|
||||
*/
|
||||
inline GenObject& operator*() const
|
||||
{ return *m_pointer; }
|
||||
|
||||
private:
|
||||
GenObject* m_pointer;
|
||||
bool m_owned;
|
||||
};
|
||||
|
||||
/**
|
||||
* Template for generic object vector
|
||||
* The vector can be resized (up/down)
|
||||
|
@ -6565,9 +6706,119 @@ protected:
|
|||
mutable int m_port;
|
||||
};
|
||||
|
||||
class MatchingItemBase;
|
||||
class MatchingItemString;
|
||||
class MatchingItemRegexp;
|
||||
class MatchingItemRandom;
|
||||
class MatchingItemList;
|
||||
class MatchingItemCustom;
|
||||
|
||||
/**
|
||||
* This class holds matching parameters to be passed when matching in item
|
||||
* @short Matching item match parameters
|
||||
*/
|
||||
class YATE_API MatchingParams : public String
|
||||
{
|
||||
YCLASS(MatchingParams,String)
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* @param name Item name
|
||||
*/
|
||||
inline MatchingParams(const char* name = 0)
|
||||
: String(name), m_now(0)
|
||||
{}
|
||||
|
||||
uint64_t m_now; // Current time to be set when needed
|
||||
ObjList m_params; // Arbitray parameters. May be set during matching
|
||||
};
|
||||
|
||||
/**
|
||||
* This class holds dump matching item parameters
|
||||
* @short Matching item dump parameters
|
||||
*/
|
||||
class YATE_API MatchingItemDump : public String
|
||||
{
|
||||
YCLASS(MatchingItemDump,String)
|
||||
public:
|
||||
/**
|
||||
* Dump behaviour flags
|
||||
*/
|
||||
enum DumpFlags {
|
||||
NoInitialListDesc = 0x00000001, // Do not dump list description at depth 0
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param params Optional parameters
|
||||
* @param name Optional name
|
||||
*/
|
||||
inline MatchingItemDump(const NamedList* params = 0, const char* name = 0)
|
||||
: String(name), m_flags(0), m_rexEnclose('/'), m_strEnclose('\''),
|
||||
m_nameValueSep(": "), m_negated('!'), m_caseInsentive('i'),
|
||||
m_regexpBasic(0), m_regexpExtended(0)
|
||||
{
|
||||
if (params)
|
||||
init(*params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize dumper data
|
||||
* @param params Parameters list
|
||||
*/
|
||||
virtual void init(const NamedList& params);
|
||||
|
||||
/**
|
||||
* Dump an item
|
||||
* @param mi Item to dump
|
||||
* @param buf Destination buffer
|
||||
* @param indent Spaces for output
|
||||
* @param origIndent Original indent
|
||||
* @param depth Re-enter depth
|
||||
* @return Destination buffer reference
|
||||
*/
|
||||
virtual String& dump(const MatchingItemBase* mi, String& buf,
|
||||
const String& indent = String::empty(), const String& origIndent = String::empty(),
|
||||
unsigned int depth = 0) const;
|
||||
|
||||
/**
|
||||
* Dump an item's value
|
||||
* @param mi Item to dump
|
||||
* @param buf Destination buffer
|
||||
* @param indent Indent for each item (line). Increased by 'origIndent' when depth advances
|
||||
* @param origIndent Original indent
|
||||
* @param depth Re-enter depth
|
||||
* @return Destination buffer reference
|
||||
*/
|
||||
virtual String& dumpValue(const MatchingItemBase* mi, String& buf,
|
||||
const String& indent = String::empty(), const String& origIndent = String::empty(),
|
||||
unsigned int depth = 0) const;
|
||||
|
||||
/**
|
||||
* Dump an item
|
||||
* @param mi Item to dump
|
||||
* @param buf Destination buffer
|
||||
* @param indent Indent for each item (line). Increased by 'origIndent' when depth advances
|
||||
* @param origIndent Original indent
|
||||
* @param params Optional dumper parameters parameters
|
||||
* @return Destination buffer reference
|
||||
*/
|
||||
static inline String& dumpItem(const MatchingItemBase* mi, String& buf,
|
||||
const String& indent = String::empty(), const String& origIndent = String::empty(),
|
||||
const NamedList* params = 0) {
|
||||
MatchingItemDump tmp(params);
|
||||
return tmp.dump(mi,buf,indent,origIndent);
|
||||
}
|
||||
|
||||
unsigned int m_flags; // Dump flags
|
||||
char m_rexEnclose; // Regexp enclose char
|
||||
char m_strEnclose; // String enclose char
|
||||
String m_nameValueSep; // Separator to be set between name and value
|
||||
char m_negated; // Negated match value
|
||||
char m_caseInsentive; // Case insensitive match value
|
||||
char m_regexpBasic; // Basic POSIX regexp value
|
||||
char m_regexpExtended; // Extended POSIX regexp value
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class for all matching items
|
||||
|
@ -6605,33 +6856,37 @@ public:
|
|||
/**
|
||||
* String match. Handles matching result negation
|
||||
* @param str String to match
|
||||
* @param params Optional parameters used during match
|
||||
* @return True if matches, false otherwise
|
||||
*/
|
||||
inline bool matchString(const String& str) const
|
||||
{ return m_notNegated == runMatchString(str); }
|
||||
inline bool matchString(const String& str, MatchingParams* params = 0) const
|
||||
{ return m_notNegated == runMatchString(str,params); }
|
||||
|
||||
/**
|
||||
* NamedList parameter match. Handles matching result negation
|
||||
* @param list List to search for parameter match
|
||||
* @param params Optional parameters used during match
|
||||
* @return True if matches, false otherwise
|
||||
*/
|
||||
inline bool matchListParam(const NamedList& list) const
|
||||
{ return m_notNegated == runMatchListParam(list); }
|
||||
inline bool matchListParam(const NamedList& list, MatchingParams* params = 0) const
|
||||
{ return m_notNegated == runMatchListParam(list,params); }
|
||||
|
||||
/**
|
||||
* String match to be implemented by descendants
|
||||
* @param str String to match
|
||||
* @param params Optional parameters used during match
|
||||
* @return False
|
||||
*/
|
||||
virtual bool runMatchString(const String& str) const
|
||||
virtual bool runMatchString(const String& str, MatchingParams* params = 0) const
|
||||
{ return false; }
|
||||
|
||||
/**
|
||||
* NamedList parameter match
|
||||
* @param list List to search for parameter match
|
||||
* @param params Optional parameters used during match
|
||||
* @return True if matches, false otherwise
|
||||
*/
|
||||
virtual bool runMatchListParam(const NamedList& list) const
|
||||
virtual bool runMatchListParam(const NamedList& list, MatchingParams* params = 0) const
|
||||
{ return runMatchString(list[name()]); }
|
||||
|
||||
/**
|
||||
|
@ -6655,6 +6910,13 @@ public:
|
|||
virtual const MatchingItemRegexp* itemRegexp() const
|
||||
{ return 0; }
|
||||
|
||||
/**
|
||||
* Check if this item is a MatchingItemRandom one
|
||||
* @return MatchingItemRandom pointer
|
||||
*/
|
||||
virtual const MatchingItemRandom* itemRandom() const
|
||||
{ return 0; }
|
||||
|
||||
/**
|
||||
* Check if this item is a MatchingItemList one
|
||||
* @return MatchingItemList pointer, NULL if this item is not a MatchingItemList
|
||||
|
@ -6662,6 +6924,48 @@ public:
|
|||
virtual const MatchingItemList* itemList() const
|
||||
{ return 0; }
|
||||
|
||||
/**
|
||||
* Check if this item is a MatchingItemCustom one
|
||||
* @return MatchingItemCustom pointer
|
||||
*/
|
||||
virtual const MatchingItemCustom* itemCustom() const
|
||||
{ return 0; }
|
||||
|
||||
/**
|
||||
* Dump this item
|
||||
* @param buf Destination buffer
|
||||
* @param indent Indent for each item (line). Increased by 'origIndent' when depth advances
|
||||
* @param origIndent Original indent
|
||||
* @param dump Optional dumper
|
||||
* @param depth Re-enter depth
|
||||
* @return Destination buffer reference
|
||||
*/
|
||||
virtual String& dump(String& buf, const MatchingItemDump* dump = 0,
|
||||
const String& indent = String::empty(), const String& origIndent = String::empty(),
|
||||
unsigned int depth = 0) const
|
||||
{ return buf; }
|
||||
|
||||
/**
|
||||
* Dump this item's value
|
||||
* @param buf Destination buffer
|
||||
* @param dump Optional dumper
|
||||
* @param indent Indent for each item (line). Increased by 'origIndent' when depth advances
|
||||
* @param origIndent Original indent
|
||||
* @param depth Re-enter depth
|
||||
* @return Destination buffer reference
|
||||
*/
|
||||
virtual String& dumpValue(String& buf, const MatchingItemDump* dump = 0,
|
||||
const String& indent = String::empty(), const String& origIndent = String::empty(),
|
||||
unsigned int depth = 0) const
|
||||
{ return buf; }
|
||||
|
||||
/**
|
||||
* Retrieve item name (suitable for list retrieval)
|
||||
* @return Item name
|
||||
*/
|
||||
virtual const String& toString() const
|
||||
{ return name(); }
|
||||
|
||||
private:
|
||||
String m_name; // Item name
|
||||
bool m_notNegated; // Item is not negated
|
||||
|
@ -6705,9 +7009,10 @@ public:
|
|||
/**
|
||||
* String match
|
||||
* @param str String to match
|
||||
* @param params Optional parameters used during match
|
||||
* @return True if matched, false otherwise
|
||||
*/
|
||||
virtual bool runMatchString(const String& str) const
|
||||
virtual bool runMatchString(const String& str, MatchingParams* params = 0) const
|
||||
{ return m_caseMatch ? (str == m_value) : (str &= m_value); }
|
||||
|
||||
/**
|
||||
|
@ -6769,9 +7074,10 @@ public:
|
|||
/**
|
||||
* String match
|
||||
* @param str String to match
|
||||
* @param params Optional parameters used during match
|
||||
* @return True if matched, false otherwise
|
||||
*/
|
||||
virtual bool runMatchString(const String& str) const
|
||||
virtual bool runMatchString(const String& str, MatchingParams* params = 0) const
|
||||
{ return m_value.matches(str); }
|
||||
|
||||
/**
|
||||
|
@ -6788,10 +7094,113 @@ public:
|
|||
virtual const MatchingItemRegexp* itemRegexp() const
|
||||
{ return this; }
|
||||
|
||||
/**
|
||||
* Build a MatchingItemRegexp from string
|
||||
* @param name Item name
|
||||
* @param str Regexp string
|
||||
* @param negated Greater than 0: build a negated match, 0: buid a non negated match,
|
||||
* negative: build a negated match if str ends with ^
|
||||
* @param insensitive Build a case insensitive regexp
|
||||
* @param extended Build a regexp using extended POSIX
|
||||
* @param fail positive: fail if regexp compile fails, negative fail if empty (do not check the regexp)
|
||||
* Remember: failed regexp never matches
|
||||
* @return MatchingItemRegexp pointer, NULL on failure
|
||||
*/
|
||||
static MatchingItemRegexp* build(const char* name, const String& str, int negated = 0,
|
||||
bool insensitive = false, bool extended = false, int fail = 1);
|
||||
|
||||
private:
|
||||
Regexp m_value; // Regexp used for matching
|
||||
};
|
||||
|
||||
/**
|
||||
* Match using a random number
|
||||
* Implements a matching of a reference value greater than RANDOM[0..MAX - 1]
|
||||
* List match and item name set:
|
||||
* Parameter present: use random match
|
||||
* Parameter not present: no match (return false)
|
||||
* @short Random number matching
|
||||
*/
|
||||
class YATE_API MatchingItemRandom : public MatchingItemBase
|
||||
{
|
||||
YCLASS(MatchingItemRandom,MatchingItemBase)
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* Random percent match: val=[PERCENT] maxVal=100
|
||||
* @param val Reference value. 0: never match, 'maxVal' is ignored
|
||||
* @param maxVal Upper interval value. 0, 1, less than / equal to 'val': always match
|
||||
* @param negated True if matching is negated (return the opposite of match in
|
||||
* public methods), false otherwise
|
||||
* @param name Item name
|
||||
*/
|
||||
inline MatchingItemRandom(uint32_t val, uint32_t maxVal, bool negated = false,
|
||||
const char* name = 0)
|
||||
: MatchingItemBase(name,negated), m_value(val), m_maxVal(maxVal) {
|
||||
if (!m_value) // Never match
|
||||
m_maxVal = 100;
|
||||
else if (m_maxVal < 2) // Always match. Avoid division by 0
|
||||
m_value = m_maxVal = 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the reference value used to make a decision
|
||||
* @return The reference value used to make a decision
|
||||
*/
|
||||
inline uint32_t value() const
|
||||
{ return m_value; }
|
||||
|
||||
/**
|
||||
* Retrieve the maximum value for random number
|
||||
* @return The maximum value for random number
|
||||
*/
|
||||
inline uint32_t maxValue() const
|
||||
{ return m_maxVal; }
|
||||
|
||||
/**
|
||||
* Run the match. Ignore the 'negated' property
|
||||
* @return True if matched, false otherwise
|
||||
*/
|
||||
inline bool randomMatch() const
|
||||
{ return value() > (Random::random() % maxValue()); }
|
||||
|
||||
/**
|
||||
* String match
|
||||
* @param str String to match
|
||||
* @param params Optional parameters used during match
|
||||
* @return True if matched, false otherwise
|
||||
*/
|
||||
virtual bool runMatchString(const String& str, MatchingParams* params = 0) const
|
||||
{ return randomMatch(); }
|
||||
|
||||
/**
|
||||
* NamedList parameter match
|
||||
* @param list List to search for parameter match
|
||||
* @param params Optional parameters used during match
|
||||
* @return True if matches, false otherwise
|
||||
*/
|
||||
virtual bool runMatchListParam(const NamedList& list, MatchingParams* params = 0) const
|
||||
{ return (!name() || list.getParam(name())) ? randomMatch() : false; }
|
||||
|
||||
/**
|
||||
* Copy this item
|
||||
* @return MatchingItemBase pointer
|
||||
*/
|
||||
virtual MatchingItemBase* copy() const
|
||||
{ return new MatchingItemRandom(value(),maxValue(),negated(),name()); }
|
||||
|
||||
/**
|
||||
* Check if this item is a MatchingItemRandom one
|
||||
* @return MatchingItemRandom pointer
|
||||
*/
|
||||
virtual const MatchingItemRandom* itemRandom() const
|
||||
{ return this; }
|
||||
|
||||
private:
|
||||
uint32_t m_value; // Reference value
|
||||
uint32_t m_maxVal; // Max value
|
||||
};
|
||||
|
||||
/**
|
||||
* List of matching items
|
||||
* @short A list of matching items
|
||||
|
@ -6840,6 +7249,36 @@ public:
|
|||
inline const MatchingItemBase* at(unsigned int index) const
|
||||
{ return static_cast<MatchingItemBase*>(m_value.at(index)); }
|
||||
|
||||
/**
|
||||
* Retrieve the index of an item found by name
|
||||
* @param name Item name
|
||||
* @return Index of found item, negative if not found
|
||||
*/
|
||||
inline int indexOf(const String& name) const
|
||||
{ return m_value.index(name); }
|
||||
|
||||
/**
|
||||
* Find an item by name
|
||||
* @param name Item name
|
||||
* @return MatchingItemBase pointer, NULL if not found
|
||||
*/
|
||||
inline const MatchingItemBase* find(const String& name) const {
|
||||
int idx = indexOf(name);
|
||||
return idx >= 0 ? at(idx) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change list (append,insert,replace,remove)
|
||||
* Item is removed if given pointer is NULL, position is valid and 'ins' is false
|
||||
* @param item Item to set, pointer will be consumed
|
||||
* @param pos Item position. Append if negative or past list length
|
||||
* @param ins Set it to true to insert, false to replace or append
|
||||
* @param overAlloc Optional number of items to over allocate
|
||||
* This parameter is ignored if there is enough space in the list set append the item
|
||||
* @return True on success, false on failure (memory allocation error or NULL pointer given)
|
||||
*/
|
||||
bool change(MatchingItemBase* item, int pos = -1, bool ins = false, unsigned int overAlloc = 1);
|
||||
|
||||
/**
|
||||
* Append an item to the list
|
||||
* @param item Item to append, pointer will be consumed
|
||||
|
@ -6847,21 +7286,47 @@ public:
|
|||
* This parameter is ignored if there is enough space in the list set append the item
|
||||
* @return True on success, false on failure (memory allocation error or NULL pointer given)
|
||||
*/
|
||||
bool append(MatchingItemBase* item, unsigned int overAlloc = 1);
|
||||
inline bool append(MatchingItemBase* item, unsigned int overAlloc = 1)
|
||||
{ return change(item,-1,false,overAlloc); }
|
||||
|
||||
/**
|
||||
* Set an item at given position
|
||||
* Item is removed if given pointer is NULL
|
||||
* @param item Item to set, pointer will be consumed
|
||||
* @param pos Item position. Append if past list length
|
||||
* @param overAlloc Optional number of items to over allocate
|
||||
* This parameter is ignored if there is enough space in the list set append the item
|
||||
* @return True on success, false on failure (memory allocation error or NULL pointer given)
|
||||
*/
|
||||
inline bool set(MatchingItemBase* item, unsigned int pos, unsigned int overAlloc = 1)
|
||||
{ return change(item,pos,false,overAlloc); }
|
||||
|
||||
/**
|
||||
* Insert an item at list start
|
||||
* @param item Item to insert, pointer will be consumed
|
||||
* @param pos Item position. Append if past list length
|
||||
* @param overAlloc Optional number of items to over allocate
|
||||
* This parameter is ignored if there is enough space in the list set append the item
|
||||
* @return True on success, false on failure (memory allocation error or NULL pointer given)
|
||||
*/
|
||||
inline bool insert(MatchingItemBase* item, unsigned int pos = 0, unsigned int overAlloc = 1)
|
||||
{ return change(item,pos,true,overAlloc); }
|
||||
|
||||
/**
|
||||
* String match
|
||||
* @param str String to match
|
||||
* @param params Optional parameters used during match
|
||||
* @return True if matched, false otherwise
|
||||
*/
|
||||
virtual bool runMatchString(const String& str) const;
|
||||
virtual bool runMatchString(const String& str, MatchingParams* params = 0) const;
|
||||
|
||||
/**
|
||||
* NamedList parameter match
|
||||
* @param list List to search for parameter match
|
||||
* @param params Optional parameters used during match
|
||||
* @return True if matches, false otherwise
|
||||
*/
|
||||
virtual bool runMatchListParam(const NamedList& list) const;
|
||||
virtual bool runMatchListParam(const NamedList& list, MatchingParams* params = 0) const;
|
||||
|
||||
/**
|
||||
* Copy this item
|
||||
|
@ -6890,6 +7355,43 @@ private:
|
|||
bool m_matchAll; // Match all/any item(s)
|
||||
};
|
||||
|
||||
/**
|
||||
* Custom match
|
||||
* @short Base class for custom matching
|
||||
*/
|
||||
class YATE_API MatchingItemCustom : public MatchingItemBase
|
||||
{
|
||||
YCLASS(MatchingItemCustom,MatchingItemBase)
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* @param name Item name
|
||||
* @param type Type name
|
||||
* @param negated True if matching is negated (return the opposite of match in
|
||||
* public methods), false otherwise
|
||||
*/
|
||||
inline MatchingItemCustom(const char* name, const char* type, bool negated = false)
|
||||
: MatchingItemBase(name,negated), m_type(type)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Retrieve the type
|
||||
* @return Type name
|
||||
*/
|
||||
inline const String& type() const
|
||||
{ return m_type; }
|
||||
|
||||
/**
|
||||
* Check if this item is a MatchingItemCustom one
|
||||
* @return MatchingItemCustom pointer
|
||||
*/
|
||||
virtual const MatchingItemCustom* itemCustom() const
|
||||
{ return this; }
|
||||
|
||||
private:
|
||||
String m_type;
|
||||
};
|
||||
|
||||
class MutexPrivate;
|
||||
class SemaphorePrivate;
|
||||
class ThreadPrivate;
|
||||
|
|
Loading…
Reference in New Issue