/*!
*		
*		
*		(C) 2002 Kaspersky Lab 
*		
*		\file	trafficmonitor_types.h
*		\brief	Здесь задаются типы настроек перехватчика траффик-монитора
*		
*		\author Vitaly DVi Denisov
*		\date	11.03.2004 17:32:41
*		
*		Example:	
*		
*		
*		
*/		

#ifndef _S_MATCHSTRINGS_H_
#define _S_MATCHSTRINGS_H_

//* s - сопоставляемая строка
//* p - шаблон. Символ \ отменяет спецзначение метасимвола.
inline bool MatchStrings(cStringPtr s, cStringPtr p)
{
#define  V(c)   (c.at(0,cCP_SYSTEM_DEFAULT, cSTRING_TO_UPPER))
#define  U(c,p) c=V(p), p++;

	tDWORD scc; // текущий символ строки                 
	tDWORD c, cc, lc;   // lc - предыдущий символ в [...] списке 
	tBOOL  ok, notflag;
	
	for(;;)
	{
        U(scc,s);          // очередной символ строки  
		U(c,p);
        switch (c)
		{ // очередной символ шаблона 
		case '\\':          // a*\*b 
		//case '/':          // a*\*b 
            U(c,p);
            if( c == 0 ) return false; // ошибка: pattern\ 
            else goto def;
		case '[':   // любой символ из списка 
            ok = notflag = 0;
            lc = 077777;      // достаточно большое число 
            if(*p == '!')
			{ notflag=1; ++p; }
			
			U(cc,p);
            while( cc )
			{
				if(cc == ']')
				{   // конец перечисления 
					if (ok)
						break;      // сопоставилось      
					return false;     // не сопоставилось   
				}
				if(cc == '-')
				{   // интервал символов  
					U(c,p);
					--s;
					if( lc <= V(s) && V(s) >= c )
						ok++;
					else if( notflag )
						// из диапазона - неудача 
						return false;
					++s;
				}
				else
				{
					if (cc == '\\')
					{      // [\[\]] 
						U(cc,p);
						if(!cc) return false;// ошибка 
					}
					if (notflag)
					{
						if (scc && scc != (lc = cc))
							ok++;          // не входит в список 
						else return false;
					}
					else
					{
						if (scc == (lc = cc)) // входит в список 
							ok++;
					}
				}
				U(cc,p);
			}
            if (cc == 0)
			{    // конец строки 
				return false;        // ошибка 
			}
            continue;
		case '*':   // любое число любых символов 
			{
            if(!*p)  return true;
            for(--s; *s; s++)
				if(MatchStrings(s, p))
					return true;
			}
			return false;
		case 0:
            return (scc == 0);
		default: def:
            if(c != scc) return false;
            continue;
		case '?':   // один любой символ 
            if (scc == 0) return false;
            continue;
		}
	}
}

//	/***********************************************************************
//	**                                                                    **
//	**   Функция     :  patmat                                            **
//	**                                                                    **
//	**   Задача      :  Соответствие заданному шаблону                    **
//	**                                                                    **
//	**   Использование: Передайте два укзателя на строки. Первый указатель**
//	**                  определяет строку, второй - шаблон.               **
//	**                  Если строка соответствует шаблону, функция        **
//	**                  возвращает 1, иначе возвращается 0                **
//	**                                                                    **
//	**                  например,                                         **
//	**                       patmat("abcdefghi","*ghi") вернет 1.         **
//	**                       patmat("abcdefghi","??c??f*") вернет 1.      **
//	**                       patmat("abcdefghi","*dh*") вернет 0.         **
//	**                       patmat("abcdefghi","*def") вернет 0.         **
//	**                       patmat("abcdef*hi","abcdef\\*hi") вернет 1.  **
//	**                       patmat("abcdef\hi","abcdef\\\\hi") вернет 1. **
//	**                                                                    **
//	**                  Звездочка обозначает любые символы до первого     **
//	**                  появления подстроки, следующей за символом '*'.   **
//	**                  Знак вопроса ? обозначает один любой символ       **
//	**                  в данной позиции строки.                          **
//	**                  Комбинации "*?" или "?*" или "**" считаются       **
//	**                  недопустимыми и результат работы функции может    **
//	**                  быть неопределенным (хотя скорее всего, все       **
//	**                  отработает нормально).                            **
//	**                                                                    **
//	**   Автор       :  Sreenath Chary, Vitaly DVi Denisov (отменяющие слэши)**
//	**                                                                    **
//	**   Логика      :  Единственный простой подход, который можно        **
//	**                  использовать в данном случае - рекурсия.          **
//	**                  Каждый символ шаблона сравнивается с символом     **
//	**                  строки. Если символы совпадают, оставшаяся часть  **
//	**                  строки передается в функцию в качестве параметров **
//	**                  и эта процедура повторяется до тех пор, пока вся  **
//	**                  строка не сравнится с шаблоном. Если на любом     **
//	**                  шаге строка не соответствует шаблону, мы          **
//	**                  возвращаемся на предыдущий уровень и если здесь   **
//	**                  мы находим '*', продолжаем сравнение с оставшейся **
//	**                  строкой, иначе возвращаемся еще на уровень назад. **
//	**                  Этот процесс повторяется, пока не будет достигнут **
//	**                  первый уровень.                                   **
//	**                                                                    **
//	***********************************************************************/
//	inline bool patmat(const char *raw, const char *pat)
//	{  
//		int  i, slraw;
//	   if ((*pat == '\0') && (*raw == '\0'))    /* если конец строки и шаблона,   */
//		 return( 1 ) ;                          /* возвращаем 1                   */
//	   if (*pat == '\0')                        /* если конец шаблона             */
//		 return( 0 ) ;                          /* возвращаем 0                   */
//	   if (                                     /* Рассматриваем маскирующие слэшы*/
//		   (*pat == '\\') && 
//		   (*raw != '\0') &&
//		   (*(pat+1) != '\0')
//		   )    
//		   if ( 
//			   (*(pat+1) == '*'  && *raw == '*') ||
//			   (*(pat+1) == '?'  && *raw == '?') ||
//			   (*(pat+1) == '\\' && *raw == '\\') 
//			   )
//				if (patmat(raw+1,pat+2) == 1)   /* сравниваем оставшиеся части    */
//				   return( 1 ) ;
//	   if (*pat == '*')                         /* если текущий символ - '*'      */
//		{ if (*(pat+1) == '\0')                 /* если после этого конец шаблона */
//			 return( 1 ) ;                      /* то возвращаем 1                */
//		  for(i=0,slraw=strlen(raw);i<=slraw;i++)/* обрабатываем оставшуюся часть */
//			if ((*(raw+i) == *(pat+1)) ||       /*      строки и шаблона          */
//				(*(pat+1) == '?') ||
//				(*(pat+1) == '*'))
//				if (patmat(
//					raw+i+( *(pat+1) != '*' ),
//					pat+2) == 1)                 /* Если строка соответствует шаблону*/
//					return( 1 ) ;                /*     возвращаем 1               */
//		}
//	   else
//		{ if (*raw == '\0')                     /* Если конец строки              */
//			 return( 0 ) ;                      /*    возвращаем 0                */
//		  if ((*pat == '?') || (*pat == *raw))  /* Если символы совпадают         */
//			if (patmat(raw+1,pat+1) == 1)       /* сравниваем оставшиеся части    */
//			   return( 1 ) ;
//		}
//	   return( 0 ) ;                            /*  возвращаем 0                  */
//	}
//

#endif//_S_MATCHSTRINGS_H_
