// V7LogProvider.cpp: implementation of the CV7LogProvider class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "V7LogProvider.h"
#include "..\\SetOfHierarchy.h"
#include "..\\SQL\\MetaDataWork.h"


#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#define _INT64_(a) (static_cast<LONGLONG>(a))
#define _ROW_FIELD_INDEX_(a) (a-LOG_DP_FILTER_DATE)


//////////////////////////////////////////////////////////////////////////
// class CLogRow
//////////////////////////////////////////////////////////////////////////

const CLogRow::FieldsNames CLogRow::m_sFields[]=
{
	{_T("Дата"),                    _T("Date")          },	// 0
	{_T("Время"),                   _T("Time")          },	// 1
	{_T("Пользователь"),            _T("User")          },	// 2
	{_T("Режим"),                   _T("Mode")          },	// 3
	{_T("ТипСобытия"),              _T("EventType")     },	// 4
	{_T("Событие"),                 _T("Event")         },	// 5
	{_T("Категория"),               _T("Category")      },	// 6
	{_T("Комментарий"),             _T("Comment")       },	// 7
	{_T("Объект"),                  _T("Object")        },	// 8
	{_T("ПредставлениеОбъекта"),    _T("ObjectPresent") }	// 9
};
const CValue CLogRow::m_vEmpty=CValue();


CLogRow::CLogRow(LARGE_INTEGER liPosition, CString* pRow) : m_liPosition(liPosition)
{
	if (pRow)
	{
		for(int nIndex=0; nIndex<LOG_DP_FIELD_COUNT; nIndex++)
		{
			if (pRow[nIndex].IsEmpty())
				m_ppValues[nIndex]=NULL;
			else
			{
				switch (nIndex)
				{
				case 0:
					m_ppValues[0]=new CValue(CDate(atoi(pRow[0].Left(4)),atoi(pRow[0].Mid(4,2)),atoi(pRow[0].Mid(6,2))));
					break;
				case 6:
					m_ppValues[6]=new CValue(CNumeric(atoi(pRow[6])));
					break;
				case 8:
					{
						CValue val;
						if (LogValueFromString(val,pRow[8],1))
							m_ppValues[8]=new CValue(val);
						else
							m_ppValues[8]=NULL;
					};
					break;
				default:
					m_ppValues[nIndex]=new CValue(pRow[nIndex]);
				};
			};
		};
	}
	else
	{
		for(int nIndex=0; nIndex<LOG_DP_FIELD_COUNT; nIndex++)
			m_ppValues[nIndex]=NULL;
	};

}


CLogRow::~CLogRow()
{
	for(int nIndex=0; nIndex<LOG_DP_FIELD_COUNT; nIndex++)
	{
		if (m_ppValues[nIndex])
			delete m_ppValues[nIndex];
	};
}


int CLogRow::GetFieldIndexOf(LPCSTR szFieldName)
{
	for (int nIndex=0; nIndex<LOG_DP_FIELD_COUNT; nIndex++)
		if (stricmp(szFieldName, m_sFields[nIndex].strRus) == 0)
			return nIndex;
		else
		{
			if (stricmp(szFieldName, m_sFields[nIndex].strEng) == 0)
				return nIndex;
		};
	return -1;
}


LPCSTR CLogRow::GetFieldName(int nIndex)
{
	if ((nIndex >= 0) && (nIndex < LOG_DP_FIELD_COUNT))
		return m_sFields[nIndex].strRus;
	else
		return "";
}


void CLogRow::FormatField(int nIndex, CString& strValue)
{
	if ((nIndex >= 0) && (nIndex < LOG_DP_FIELD_COUNT))
	{
		if (m_ppValues[nIndex])
			FormatValue(*m_ppValues[nIndex], strValue);
		else
			FormatValue(m_vEmpty, strValue);
	}
	else
		FormatValue(m_vEmpty, strValue);
}


const CValue& CLogRow::GetValue(int nIndex) const
{
	if ((nIndex >= 0) && (nIndex < LOG_DP_FIELD_COUNT))
	{
		if (m_ppValues[nIndex])
			return *m_ppValues[nIndex];
		else
			return m_vEmpty;
	}
    else
		return m_vEmpty;
}


//////////////////////////////////////////////////////////////////////////
// class CV7LogProvider
//////////////////////////////////////////////////////////////////////////
BEGIN_BL_METH_MAP(CV7LogProvider)
	BL_METH("SetPeriod",    "УстановитьПериод",      2, NULL,        SetPeriod,     DefaultPeriod)
	BL_METH("ChangeFilter", "ИзменитьФильтр",        2, NULL,        ChangeFilter,  DefaultFilter)
	BL_METH("SetFilter",    "УстановитьФильтр",      1, NULL,        SetFilter,     DefaultFilter)
	BL_METH("SetScanDeep",  "УстановитьГлубину",     2, NULL,        SetScanDeep,   DefaultScanDeep)
	BL_METH("OpenFile",     "ОткрытьФайл",           0, NULL,        OpenFile,      NULL)
	BL_METH("CloseFile",    "ЗакрытьФайл",           0, CloseFile,   NULL,          NULL)
	BL_METH("SelectLines",  "ВыбратьСтроки",         1, NULL,        SelectLines,   DefaultSelectLines)
	BL_METH("GetLine",      "ПолучитьСтроку",        0, NULL,        GetLine,       NULL)
	BL_METH("SetPeriodEx",  "УстановитьПериодРасш",  4, NULL,        SetPeriodEx,   DefaultPeriodEx)
END_BL_METH_MAP()

BEGIN_BL_PROP_MAP(CV7LogProvider)
	BL_PROP("BeginOfPeriod",      "НачалоПериода",              GetBegOfPeriodDate,    NULL)
	BL_PROP("EndOfPeriod",        "КонецПериода",               GetEndOfPeriodDate,    NULL)
	BL_PROP("PeriodBeginingTime", "ВремяНачалаПериода",         GetBegOfPeriodTime,    NULL)
	BL_PROP("PeriodEndingTime",   "ВремяОкончанияПериода",      GetEndOfPeriodTime,    NULL)
	BL_PROP("ScanDeep",           "ГлубинаПросмотра",           GetScanDeep,           NULL)
	BL_PROP("LastScanDate",       "ПоследняяПросмотреннаяДата", GetLastScanDate,       NULL)
	BL_PROP("UsingBuffer",        "ИспользованиеБуфера",        GetUsingBuffer,        NULL)

	BL_PROP("Position",      "Позиция",                    RowGetPosition,        NULL)
	BL_PROP("Date",          "Дата",                       RowGetDate,            NULL)
	BL_PROP("Time",          "Время",                      RowGetTime,            NULL)
	BL_PROP("User",          "Пользователь",               RowGetUser,            NULL)
	BL_PROP("Mode",          "Режим",                      RowGetMode,            NULL)
	BL_PROP("EventType",     "ТипСобытия",                 RowGetEventType,       NULL)
	BL_PROP("Event",         "Событие",                    RowGetEvent,           NULL)
	BL_PROP("Category",      "Категория",                  RowCategory,           NULL)
	BL_PROP("Comment",       "Комментарий",                RowGetComment,         NULL)
	BL_PROP("Object",        "Объект",                     RowGetObject,          NULL)
	BL_PROP("ObjectPresent", "ПредставлениеОбъекта",       RowGetObjectPresent,   NULL)

	BL_PROP("FileName",      "ИмяФайла",                   GetLogFileName,        SetLogFileName)
END_BL_PROP_MAP()

IMPLEMENT_MY_CONTEXT(CV7LogProvider, "LogProvider", "ПоставщикДанныхЖурналРегистрации", 1, NULL, NULL, -1);


const CV7LogProvider::FilterInfo CV7LogProvider::m_stFiltersInfo[]=
{
	{ _T(""),                     NULL,      NULL,      LOG_DP_FILTER_PARAM_STR_VL,  LOG_DP_FILTER_USER-1,         0  }, // 0
	{ _T(""),                     NULL,      NULL,      LOG_DP_FILTER_PARAM_STR,     LOG_DP_FILTER_MODE-1,         0  }, // 1
	{ _T(""),                     NULL,      NULL,      LOG_DP_FILTER_PARAM_STR,     LOG_DP_FILTER_CATEGORY-1,     0  }, // 2
	{ _T("Sys"),                  NULL,      _T("0"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENTTYPE-1,    0  }, // 3
	{ _T("OpenSession"),          NULL,      _T("0"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,        3  }, // 4
	{ _T("CloseSession"),         NULL,      _T("0"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,        3  }, // 5
	{ _T("Consts"),               _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENTTYPE-1,    0  }, // 6
	{ _T("ConstWrite"),           _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,        6  }, // 7
	{ _T("ConstDel"),             _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,        6  }, // 8
	{ _T("Refs"),                 _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENTTYPE-1,    0  }, // 9
	{ _T("RefNew"),               _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,        9  }, // 10
	{ _T("RefWrite"),             _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,        9  }, // 11
	{ _T("RefUnmarkDel"),         _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,        9  }, // 12
	{ _T("RefDel"),               _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,        9  }, // 13
	{ _T("RefMarkDel"),           _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,        9  }, // 14
	{ _T("RefGrpMove"),           _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,        9  }, // 15
	{ _T("RefAttrWrite"),         _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,        9  }, // 16
	{ _T("RefAttrDel"),           _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,        9  }, // 17
	{ _T("Docs"),                 _T("E"),   _T("23"),  LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENTTYPE-1,    0  }, // 18
	{ _T("DocNew"),               _T("E"),   _T("3"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       18  }, // 19
	{ _T("DocOpen"),              _T("E"),   _T("3"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       18  }, // 20
	{ _T("DocWrite"),             _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       18  }, // 21
	{ _T("DocWriteNew"),          _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       18  }, // 22
	{ _T("DocNotWrite"),          _T("E"),   _T("3"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       18  }, // 23
	{ _T("DocPassed"),            _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       18  }, // 24
	{ _T("DocBackPassed"),        _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       18  }, // 25
	{ _T("DocNotPassed"),         _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       18  }, // 26
	{ _T("DocMakeNotPassed"),     _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       18  }, // 27
	{ _T("DocWriteAndRepassed"),  _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       18  }, // 28
	{ _T("DocWriteAndPostBfAP"),  _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       18  }, // 29
	{ _T("DocTimeChanged"),       _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       18  }, // 30
	{ _T("DocOperWrite"),         _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       18  }, // 31
	{ _T("DocOperOn"),            _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       18  }, // 32
	{ _T("DocOperOff"),           _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       18  }, // 33
	{ _T("DocMarkDel"),           _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       18  }, // 34
	{ _T("DocUnmarkDel"),         _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       18  }, // 35
	{ _T("DocDel"),               _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       18  }, // 36
	{ _T("CJ"),                   _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENTTYPE-1,    0  }, // 37
	{ _T("CJPerChng"),            _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       37  }, // 38
	{ _T("CJPerBackChng"),        _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       37  }, // 39
	{ _T("CJPerNotChng"),         _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       37  }, // 40
	{ _T("CJUneditRec"),          _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       37  }, // 41
	{ _T("CJEditRec"),            _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       37  }, // 42
	{ _T("Accs"),                 _T("E"),   _T("23"),  LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENTTYPE-1,    0  }, // 43
	{ _T("AccNew"),               _T("E"),   _T("3"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       43  }, // 44
	{ _T("AccWrite"),             _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       43  }, // 45
	{ _T("AccDel"),               _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       43  }, // 46
	{ _T("AccMarkDel"),           _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       43  }, // 47
	{ _T("AccUnmarkDel"),         _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       43  }, // 48
	{ _T("AccAttrWrite"),         _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       43  }, // 49
	{ _T("AccAttrDel"),           _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       43  }, // 50
	{ _T("CorrProvs"),            _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENTTYPE-1,    0  }, // 51
	{ _T("CorrProvNew"),          _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       51  }, // 52
	{ _T("CorrProvEdit"),         _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       51  }, // 53
	{ _T("CorrProvDel"),          _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       51  }, // 54
	{ _T("TmplOpers"),            _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENTTYPE-1,    0  }, // 55
	{ _T("TmplOperNew"),          _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       55  }, // 56
	{ _T("TmplOperWrite"),        _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       55  }, // 57
	{ _T("TmplOperDel"),          _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       55  }, // 58
	{ _T("TmplOperGrpMove"),      _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       55  }, // 59
	{ _T("Grbgs"),                _T("EM"),  _T("125"), LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENTTYPE-1,    0  }, // 60
	{ _T("GrbgTAChng"),           _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       60  }, // 61
	{ _T("GrbgSnapChng"),         _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       60  }, // 62
	{ _T("GrbgRclcDocs"),         _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       60  }, // 63
	{ _T("GrbgNewPerBuhTot"),     _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       60  }, // 64
	{ _T("GrbgRclcAllBuhTot"),    _T("E"),   _T("2"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       60  }, // 65
	{ _T("GrbgLogArch"),          _T("M"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       60  }, // 66
	{ _T("GrbgSyntaxErr"),        _T("E"),   _T("5"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       60  }, // 67
	{ _T("GrbgRuntimeErr"),       _T("E"),   _T("5"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       60  }, // 68
	{ _T("Restruct"),             _T("C"),   _T("1345"),LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENTTYPE-1,    0  }, // 69
	{ _T("RestructSaveMD"),       _T("C"),   _T("3"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       69  }, // 70
	{ _T("RestructStart"),        _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       69  }, // 71
	{ _T("RestructCopy"),         _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       69  }, // 72
	{ _T("RestructAcptEnd"),      _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       69  }, // 73
	{ _T("RestructStatus"),       _T("C"),   _T("3"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       69  }, // 74
	{ _T("RestructAnalys"),       _T("C"),   _T("3"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       69  }, // 75
	{ _T("RestructWarn"),         _T("C"),   _T("4"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       69  }, // 76
	{ _T("RestructErr"),          _T("C"),   _T("5"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       69  }, // 77
	{ _T("RestructCritErr"),      _T("C"),   _T("5"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       69  }, // 78
	{ _T("Distr"),                _T("C"),   _T("15"),  LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENTTYPE-1,    0  }, // 79
	{ _T("DistBatchErr"),         _T("C"),   _T("5"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       79  }, // 80
	{ _T("DistDnldBeg"),          _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       79  }, // 81
	{ _T("DistDnldSuc"),          _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       79  }, // 82
	{ _T("DistDnldFail"),         _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       79  }, // 83
	{ _T("DistDnlErr"),           _T("C"),   _T("5"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       79  }, // 84
	{ _T("DistDnlStatus"),        _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       79  }, // 85
	{ _T("DistUplBeg"),           _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       79  }, // 86
	{ _T("DistUplSuc"),           _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       79  }, // 87
	{ _T("DistUplFail"),          _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       79  }, // 88
	{ _T("DistUplErr"),           _T("C"),   _T("5"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       79  }, // 89
	{ _T("DistUplStatus"),        _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       79  }, // 90
	{ _T("DistDnldPrimBeg"),      _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       79  }, // 91
	{ _T("DistDnldPrimSuc"),      _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       79  }, // 92
	{ _T("DistDnldPrimFail"),     _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       79  }, // 93
	{ _T("DistDnldPrimErr"),      _T("C"),   _T("5"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       79  }, // 94
	{ _T("DistInit"),             _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       79  }, // 95
	{ _T("DistPIBCreat"),         _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       79  }, // 96
	{ _T("DistPIBDel"),           _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       79  }, // 97
	{ _T("DistIBModi"),           _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       79  }, // 98
	{ _T("DistAEParam"),          _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,       79  }, // 99
	{ _T("UpDown"),               _T("C"),   _T("15"),  LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENTTYPE-1,    0  }, // 100
	{ _T("?"),                    _T("C"),   _T("5"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      100  }, // 101
	{ _T("UpDownDnldToFile"),     _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      100  }, // 102
	{ _T("UpDownDnldSuc"),        _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      100  }, // 103
	{ _T("UpDownDnldFail"),       _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      100  }, // 104
	{ _T("UpDownDnldErr"),        _T("C"),   _T("5"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      100  }, // 105
	{ _T("UpDownUplFromFile"),    _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      100  }, // 106
	{ _T("UpDownUplSuc"),         _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      100  }, // 107
	{ _T("UpDownUplFail"),        _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      100  }, // 108
	{ _T("UpDownUplErr"),         _T("C"),   _T("5"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      100  }, // 109
	{ _T("Archive"),              _T("C"),   _T("15"),  LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENTTYPE-1,    0  }, // 110
	{ _T("ArchiveStart"),         _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      110  }, // 111
	{ _T("ArchiveEnd"),           _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      110  }, // 112
	{ _T("DearchiveStart"),       _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      110  }, // 113
	{ _T("DearchiveEnd"),         _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      110  }, // 114
	{ _T("ArchiveError"),         _T("C"),   _T("5"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      110  }, // 115
	{ _T("?"),                    _T("C"),   _T("5"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      110  }, // 116
	{ _T("Batch"),                NULL,      _T("15"),  LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENTTYPE-1,    0  }, // 117
	{ _T("?"),                    NULL,      _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      117  }, // 118
	{ _T("?"),                    NULL,      _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      117  }, // 119
	{ _T("BatchErr"),             NULL,      _T("5"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      117  }, // 120
	{ _T("UsrDef"),               _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENTTYPE-1,  121  }, // 121
	{ _T("Doctor"),               _T("C"),   _T("15"),  LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENTTYPE-1,    0  }, // 122
	{ _T("dctTRBeg"),             _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      123  }, // 123
	{ _T("dctTBeg"),              _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      123  }, // 124
	{ _T("dctPhInt"),             _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      123  }, // 125
	{ _T("dctReind"),             _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      123  }, // 126
	{ _T("dctLgInt"),             _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      123  }, // 127
	{ _T("dctRcST"),              _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      123  }, // 128
	{ _T("dctRcT"),               _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      123  }, // 129
	{ _T("dctTREnd"),             _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      123  }, // 130
	{ _T("dctTEnd"),              _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      123  }, // 131
	{ _T("dctErr"),               _T("C"),   _T("5"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      123  }, // 132
	{ _T("dctPck"),               _T("C"),   _T("1"),   LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      123  }, // 133
	{ _T("User"),                 _T("E"),   NULL,      LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENTTYPE-1,    0  }, // 134
	{ _T("UserMsg"),              _T("E"),   NULL,      LOG_DP_FILTER_PARAM_NO,      LOG_DP_FILTER_EVENT-1,      134  }, // 135
	{ _T(""),                     _T("E"),   NULL,      LOG_DP_FILTER_PARAM_STR_VL,  LOG_DP_FILTER_EVENT-1,      134  }, // 136
	{ _T(""),                     _T("E"),   NULL,      LOG_DP_FILTER_PARAM_STR_VL,  LOG_DP_FILTER_EVENTTYPE-1,    0  }, // 137
	{ _T(""),                     NULL,      NULL,      LOG_DP_FILTER_PARAM_STR,     LOG_DP_FILTER_COMMENT-1,      0  }, // 138
	{ _T(""),                     _T("E"),   NULL,      LOG_DP_FILTER_PARAM_STR_VL,  LOG_DP_FILTER_OBJECTKIND-1,   0  }, // 139
	{ _T(""),                     _T("E"),   NULL,      LOG_DP_FILTER_PARAM_OBJ_VL,  LOG_DP_FILTER_OBJECT-1,       0  }, // 140
	{ _T(""),                     _T("E"),   NULL,      LOG_DP_FILTER_PARAM_STR,     LOG_DP_FILTER_PRESENT-1,      0  }  // 141
};
#define LOG_DP_FILTER_MAX_PARAM     142
#define LOG_DP_MAX_DATE             99999999999999

// конструктор / деструктор
CV7LogProvider::CV7LogProvider()
{
	m_strLogFileName.Empty();

	Init();
}


void CV7LogProvider::Init()
{
	m_hLogFile=NULL;
	m_qwStartLogDate=0;
	m_eProviderMode=pmNormalBrowse;
	m_strBuffer.Empty();

	m_qwBegDate=0;
	m_qwEndDate=0;
	m_liBegPosition.QuadPart=0;
	m_liEndPosition.QuadPart=0;

	m_dwFilter=0;
	m_bInvalidFilter=FALSE;
	m_nScanDeep=0;
	m_dwLastScanDate=0;

	m_RowPosition=NULL;

	m_bLinesSelectionEnabled=FALSE;
}


CV7LogProvider::~CV7LogProvider()
{
	CloseLog();
}


// работа с файлом
BOOL CV7LogProvider::OpenLog()
{
	if (m_hLogFile)
		return TRUE;

	CValue filename;
	GetLogFileName(filename);

	m_hLogFile = CreateFile(filename.GetString() ,GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (m_hLogFile == INVALID_HANDLE_VALUE)
	{
		m_hLogFile = NULL;
		return FALSE;
	}
	else
	{
		m_liCurrentPosition.QuadPart=0;
		DWORD dwRead;
		ReadLog(LOG_DP_DATE_TIME_LENGTH,dwRead);

		IsDateTimeValid(FALSE,m_strBuffer,&m_qwStartLogDate);
		if (m_qwStartLogDate < 19800101000000)
			CloseLog();
	};

	return m_hLogFile ? TRUE : FALSE;
}


void CV7LogProvider::CloseLog()
{
	if (m_hLogFile)
		CloseHandle(m_hLogFile);

	Init();

	CValue param=CValue(CNumeric(0));
	CValue* pValue=&param;
	ChangeFilter(param,&pValue);
}


BOOL CV7LogProvider::ReadLog(const DWORD dwBytesToRead, DWORD& dwBytesRead, const DWORD dwHowToTrim)
{
	BOOL bResult=FALSE;
	dwBytesRead = 0;
	if (m_hLogFile)
	{
		LPTSTR p = m_strBuffer.GetBuffer(dwBytesToRead);
		bResult=ReadFile(m_hLogFile, p, dwBytesToRead, &dwBytesRead, NULL);
		m_strBuffer.ReleaseBuffer(dwBytesRead);
		while (int nLen=m_strBuffer.GetLength())
		{
			BOOL bBreak=TRUE;
			if (dwHowToTrim&LOG_DP_TRIM_10_13_RIGHT)
			{
				nLen--;
				if ((m_strBuffer[nLen]==_T(LOG_DP_NEW_ROW_10))||(m_strBuffer[nLen]==_T(LOG_DP_NEW_ROW_13)))
				{
					m_strBuffer = m_strBuffer.Left(nLen);
					dwBytesRead--;
					bBreak=FALSE;
				};
			};
			if (dwHowToTrim&LOG_DP_TRIM_10_13_LEFT)
			{
				if ((m_strBuffer[0]==_T(LOG_DP_NEW_ROW_10))||(m_strBuffer[0]==_T(LOG_DP_NEW_ROW_13)))
				{
					m_strBuffer = m_strBuffer.Mid(1);
					dwBytesRead--;
					bBreak=FALSE;
				};
			};
			if (bBreak)
				break;
		};
		
	};
	return bResult;
}


BOOL CV7LogProvider::SetPosition(LARGE_INTEGER &liPosition, const DWORD dwMoveMethod)
{
	BOOL bResult=FALSE;
	if (m_hLogFile)
	{
		liPosition.LowPart=SetFilePointer(m_hLogFile, liPosition.LowPart, &liPosition.HighPart, dwMoveMethod);
		if (bResult=(liPosition.LowPart!=0xFFFFFFFF || GetLastError()==NO_ERROR))
			m_liCurrentPosition=liPosition;
	};
	return bResult;
}


// свойства и методы
BOOL CV7LogProvider::OpenFile(CValue& Result, CValue** ppValue)
{
	Result=CNumeric(OpenLog()?1:0);
	return TRUE;
}


BOOL CV7LogProvider::CloseFile(CValue** ppValue)
{
	CloseLog();
	return TRUE;
}


BOOL CV7LogProvider::GetBegOfPeriodDate(CValue& Value) const
{
	if (m_qwBegDate)
	{
		DWORD dwDate=m_qwBegDate/1000000;
		int nY=dwDate/10000;
		int nM=(dwDate-nY*10000)/100;
		Value=CDate(nY,nM,dwDate%100);
	}
	else
	{
		Value=CDate(0,0,0);
		Value.m_Date.m_DateNum=0;
	};
	return TRUE;
}


BOOL CV7LogProvider::GetEndOfPeriodDate(CValue& Value) const
{
	if (m_qwEndDate)
	{
		DWORD dwDate=m_qwEndDate/1000000;
		int nY=dwDate/10000;
		int nM=(dwDate-nY*10000)/100;
		Value=CDate(nY,nM,dwDate%100);
	}
	else
	{
		Value=CDate(0,0,0);
		Value.m_Date.m_DateNum=0;
	};
	return TRUE;
}


BOOL CV7LogProvider::GetBegOfPeriodTime(CValue& Value) const
{
	if (m_qwBegDate)
	{
		TCHAR buf[10];
		CString strTime=CString(CString(_T("000000"))+CString(itoa(m_qwBegDate%1000000,buf,10))).Right(6);
		strTime.Insert(2,_T(':'));
		strTime.Insert(5,_T(':'));
		Value=strTime;
	}
	else
		Value=CValue();

	return TRUE;
}


BOOL CV7LogProvider::GetEndOfPeriodTime(CValue& Value) const
{
	if (m_qwEndDate)
	{
		TCHAR buf[10];
		CString strTime=CString(CString(_T("000000"))+CString(itoa(m_qwEndDate%1000000,buf,10))).Right(6);
		strTime.Insert(2,_T(':'));
		strTime.Insert(5,_T(':'));
		Value=strTime;
	}
	else
		Value=CValue();

	return TRUE;
}


BOOL CV7LogProvider::SetPeriodInternal(ULONGLONG& qwBegDate, ULONGLONG& qwEndDate)
{
	if (qwBegDate<=235959)
		qwBegDate=0;

	if (qwEndDate<=235959)
		qwEndDate=0;

	switch ((qwBegDate!=0)+(qwEndDate!=0))
	{
	case 0:
		qwBegDate=0;
		qwEndDate=LOG_DP_MAX_DATE;
		m_eProviderMode=pmNormalBrowse;
		break;
	case 1:
		{
			if (qwBegDate)
				qwEndDate=LOG_DP_MAX_DATE;
			if ((m_qwBegDate!=qwBegDate)||(m_qwEndDate!=qwEndDate))
				m_eProviderMode=pmBoundsSearch;
		};
		break;
	case 2:
		if ((m_qwBegDate!=qwBegDate)||(m_qwEndDate!=qwEndDate))
			m_eProviderMode=pmBoundsSearch;
		break;
	};

	
	BOOL bResult;
	if (bResult=qwBegDate<=qwEndDate)
	{
		m_bSkipRow = FALSE;
		
		if (m_eProviderMode==pmBoundsSearch)
		{
			if (qwBegDate<=m_qwStartLogDate)
				qwBegDate=0;
			
			if (bResult=qwEndDate>=m_qwStartLogDate)
			{
				if (qwEndDate==m_qwStartLogDate)
					qwBegDate=0;
			};
			
			if (bResult)
			{
				LARGE_INTEGER liPosition;
				liPosition.QuadPart=0;
				if (bResult=SetPosition(liPosition,FILE_END))
				{
					m_bStandardBuffer = TRUE;
					m_nBufferGrowCount = 0;
					m_strBuffer.Empty();
					
					ULONGLONG qwDate;
					CString strRow;
					if (bResult=GetRow(TRUE,TRUE,liPosition,strRow,&qwDate))
					{
						if (bResult=qwBegDate<=qwDate)
						{
							if (qwEndDate>=qwDate)
								qwEndDate=LOG_DP_MAX_DATE;
						};
					};
				};
			};
		};
		
		if (bResult)
		{
			if (qwBegDate)
			{
				if (m_qwBegDate!=qwBegDate)
					bResult=SearchBound(FALSE,qwBegDate);
			}
			else
				m_liBegPosition.QuadPart=0;
		};
		
		if (bResult)
		{
			if (qwEndDate!=LOG_DP_MAX_DATE)
			{
				if (m_qwEndDate!=qwEndDate)
					bResult=SearchBound(TRUE,qwEndDate);
			}
			else
			{
				qwEndDate=0;
				m_liEndPosition.QuadPart=0;
			};
		};
	};
	

	GetRowResult res=grrMatch;
	if (bResult)
	{
		if (m_liBegPosition.QuadPart||m_liEndPosition.QuadPart)
		{
			m_qwBegDate=qwBegDate;
			m_qwEndDate=qwEndDate;
			m_eProviderMode=pmPeriodBrowse;
		}
		else
		{
			m_qwBegDate=0;
			m_qwEndDate=0;
			m_eProviderMode=pmNormalBrowse;
		};
		
		if (BufferMode())
		{
			
			LONGLONG llBytesToRead=0;
			LONGLONG llBytesRead=0;
			
			if (m_RowsList.IsEmpty())
			{
				llBytesToRead=GetBytesToRead();
				res=AddRowsToList(amNormal,m_liBegPosition,llBytesToRead,llBytesRead);
			}
			else
			{
				LONGLONG llHeadPos=m_RowsList.GetHead();
				LONGLONG llTailPos=m_RowsList.GetTail();
				
				bool bSearchContinue=true;
				
				if (llTailPos<=m_liBegPosition.QuadPart) // меньше начала периода
				{
					m_RowsList.RemoveAll();
					llBytesToRead=GetBytesToRead();
					res=AddRowsToList(amNormal,m_liBegPosition,llBytesToRead,llBytesRead);
					bSearchContinue=false;
				}
				else
				{
					if (llHeadPos>m_liBegPosition.QuadPart)
					{
						if (m_liEndPosition.QuadPart&&(llHeadPos>=m_liEndPosition.QuadPart)) // меньше начала периода
						{
							m_RowsList.RemoveAll();
							llBytesToRead=GetBytesToRead();
							res=AddRowsToList(amNormal,m_liBegPosition,llBytesToRead,llBytesRead);
							bSearchContinue=false;
						}
						else // добавить кусок в начало
						{
							llBytesToRead=llHeadPos-m_liBegPosition.QuadPart;
							
							if (m_liEndPosition.QuadPart)
							{
								if (llTailPos<m_liEndPosition.QuadPart)
									llBytesToRead+=(m_liEndPosition.QuadPart-llTailPos);
							}
							else
								llBytesToRead+=GetBytesToRead(llTailPos);
							
							res=AddRowsToList(amToHead,m_liBegPosition,llBytesToRead,llBytesRead);
						};
					}
					else
					{
						while (llHeadPos<m_liBegPosition.QuadPart)
						{
							m_RowsList.RemoveHead();
							if (m_RowsList.IsEmpty())
								break;
							else
								llHeadPos=m_RowsList.GetHead();
						};
					};
				};
				
				if (bSearchContinue&&(res==grrMatch))
				{
					LARGE_INTEGER liTail;
					liTail.QuadPart=llTailPos;
					
					if (m_liEndPosition.QuadPart)
					{
						if (llTailPos<m_liEndPosition.QuadPart) // добавить кусок в конец
							res=AddRowsToList(amToTail,liTail,llBytesToRead,llBytesRead);
						else
						{
							while (llTailPos>m_liEndPosition.QuadPart)
							{
								m_RowsList.RemoveTail();
								if (m_RowsList.IsEmpty())
									break;
								else
									llTailPos=m_RowsList.GetTail();
							};
						};
					}
					else
						res=AddRowsToList(amToTail,liTail,llBytesToRead,llBytesRead);
				};
			};
			
		};

	}
	else
	{
		m_qwBegDate=0;
		m_qwEndDate=0;
		m_eProviderMode=pmInvalidPeriod;
	};

	if (GetControl())
		ResetData();
	
	if (res==grrEscPressed)
		RuntimeError(_T("Log data provider: установка периода прервана по ESC."));

	return bResult;
}


BOOL CV7LogProvider::SetPeriodEx(CValue& Result, CValue** ppValue)
{

	Result=CNumeric(0);

	if (!m_hLogFile)
		return TRUE;

	if ((ppValue[0]->GetTypeCode() == DATE_TYPE_1C)&&
		(ppValue[1]->GetTypeCode() == STRING_TYPE_1C)&&
		(ppValue[2]->GetTypeCode() == DATE_TYPE_1C)&&
		(ppValue[3]->GetTypeCode() == STRING_TYPE_1C))
	{

		ULONGLONG qwBegDate;
		CString strBegTime=ppValue[1]->GetString();
		if (strBegTime.IsEmpty())
			strBegTime=_T("00:00:00");

		if (IsDateTimeValid(TRUE,ppValue[0]->GetString()+_T(";")+strBegTime+_T(";"),&qwBegDate))
		{
			ULONGLONG qwEndDate;
			CString strEndTime=ppValue[3]->GetString();
			if (strEndTime.IsEmpty())
				strEndTime=_T("23:59:59");

			if (IsDateTimeValid(TRUE,ppValue[2]->GetString()+_T(";")+strEndTime+_T(";"),&qwEndDate))
			{
				if (SetPeriodInternal(qwBegDate,qwEndDate))
					Result=CNumeric(1);
			};
		}
	};

	return TRUE;
}


BOOL CV7LogProvider::SetPeriod(CValue& Result, CValue** ppValue)
{

	Result=CNumeric(0);

	if (!m_hLogFile)
		return TRUE;

	if ((ppValue[0]->GetTypeCode() == DATE_TYPE_1C)&&(ppValue[1]->GetTypeCode() == DATE_TYPE_1C))
	{
		ULONGLONG qwBegDate, qwEndDate;

		IsDateTimeValid(FALSE,ppValue[0]->GetString()+_T(";00:00:00;"),&qwBegDate);
		IsDateTimeValid(FALSE,ppValue[1]->GetString()+_T(";23:59:59;"),&qwEndDate);

		if (SetPeriodInternal(qwBegDate,qwEndDate))
			Result=CNumeric(1);
	};

	return TRUE;
}


BOOL CV7LogProvider::DefaultPeriod(int nParam, CValue* param) const
{
	switch(nParam)
	{
	case 0:
		*param = CDate(0,0,0);
		break;
	case 1:
		*param = CDate(0,0,0);
		break;
	}
	return TRUE;
}


BOOL CV7LogProvider::DefaultPeriodEx(int nParam, CValue* param) const
{
	switch(nParam)
	{
	case 0:
		*param = CDate(0,0,0);
		break;
	case 1:
		*param = CValue(_T("00:00:00"));
		break;
	case 2:
		*param = CDate(0,0,0);
		break;
	case 3:
		*param = CValue(_T("23:59:59"));
		break;
	}
	return TRUE;
}


void CV7LogProvider::GetModeAndCategory(const CIStringMapToIndex* const pMap, const BOOL bMode, CString& strCheck) const
{
	POSITION pos=pMap->GetStartPosition();
	while (pos!=NULL)
	{
		CString strKey;
		int nVal;
		pMap->GetNextAssoc(pos,strKey,nVal);
		CString strTmp(bMode?m_stFiltersInfo[nVal].strMode:m_stFiltersInfo[nVal].strCategory);
		if (int nLen=strTmp.GetLength())
		{
			for (int nIndex=0; nIndex<nLen; nIndex++)
			{
				TCHAR chSymb=strTmp[nIndex];
				if (strCheck.Find(chSymb)==-1)
					strCheck+=chSymb;
			};
		};
	};
}


LONGLONG CV7LogProvider::GetBytesToRead(LONGLONG llEndPos) const
{
	LONGLONG res;
	if (m_liEndPosition.QuadPart)
		res=m_liEndPosition.QuadPart-m_liBegPosition.QuadPart;
	else
	{
		ULARGE_INTEGER uiFileSize;
		uiFileSize.LowPart=GetFileSize(m_hLogFile, &uiFileSize.HighPart);
		if (!llEndPos)
			llEndPos=m_liBegPosition.QuadPart;
		res=uiFileSize.QuadPart-llEndPos;
	};
	return res;
}


CV7LogProvider::GetRowResult CV7LogProvider::AddRowsToList(const AddingMode HowToAdd, LARGE_INTEGER liFromPosition, LONGLONG &llBytesToRead, LONGLONG &llBytesRead)
{
	if (SetPosition(liFromPosition,FILE_BEGIN))
	{
		LONGLONG llPosition=0;
		switch (HowToAdd)
		{
		case amToHead:
			if (!m_RowsList.IsEmpty())
				llPosition=m_RowsList.GetHead();
			break;
		case amToTail:
			if (!m_RowsList.IsEmpty())
				llPosition=m_RowsList.GetTail();
			break;
		};
		CList<LONGLONG,LONGLONG&> tmpList;

		m_bSkipRow = FALSE;
		m_bStandardBuffer = TRUE;
		m_nBufferGrowCount = 0;
		m_strBuffer.Empty();
		
		int nScanDeep=m_nScanDeep;

		LONGLONG llOnePercent=llBytesToRead/100;
		int nPercentPrev=-1;
		
		bool bWhile=true;
		while (bWhile)
		{
			CString mRow[LOG_DP_FIELD_COUNT];
			DWORD dwRowLength;

			switch (GetFilteredRow(TRUE,TRUE,FALSE,liFromPosition,mRow,&dwRowLength))
			{
			case grrMismatch:
				if (m_nScanDeep)
				{
					nScanDeep--;
					bWhile=nScanDeep==0;
				};
				break;
			case grrMatch:
				{
					switch (HowToAdd)
					{
					case amNormal:
						m_RowsList.AddTail(liFromPosition.QuadPart);
						break;
					case amToHead:
						if (liFromPosition.QuadPart==llPosition)
							bWhile=false;
						else
							tmpList.AddTail(liFromPosition.QuadPart);
						break;
					case amToTail:
						if (liFromPosition.QuadPart!=llPosition)
							tmpList.AddTail(liFromPosition.QuadPart);
						break;
					};
					nScanDeep=m_nScanDeep;
				}
				break;
			case grrNoMoreRows:
				bWhile=false;
				break;
			case grrEscPressed:
				return grrEscPressed;
				break;
			};

			llBytesRead+=dwRowLength;

			int nPercentCurr=100;
			if (llOnePercent)
				nPercentCurr=llBytesRead/llOnePercent;

			if (nPercentPrev!=nPercentCurr)
			{
				CString strStatus(_T("Процесс фильтрации: "));

				if (nPercentCurr>100)
					strStatus+=_T("завершение...");
				else
				{
					char buf[10];
					strStatus+=CString(ltoa(nPercentCurr,buf,10))+_T("%");
				};
				pBkEndUI->DoStatusLine(strStatus);
				nPercentPrev=nPercentCurr;
			};

		};

		switch (HowToAdd)
		{
		case amToHead:
			m_RowsList.AddHead(&tmpList);
			break;
		case amToTail:
			m_RowsList.AddTail(&tmpList);
			break;
		};

		return grrMatch;
	}
	else
	{
		// ???
		return grrNoMoreRows;
	};
}


BOOL CV7LogProvider::SetFilter(CValue& Result, CValue** ppValue)
{
	if (!m_hLogFile)
	{
		Result=CNumeric(0);
		return TRUE;
	};

	bool bResult=false;
	int nUseBuffer;
	if (ppValue[0]->GetTypeCode() == NUMBER_TYPE_1C)
	{
		nUseBuffer=ppValue[0]->GetNumeric();
		bResult=(nUseBuffer==0)||(nUseBuffer==1);
	};
	if (!bResult)
	{
		Result=CNumeric(0);
		RuntimeError(_T("Log data provider: неверное значение параметра %s"), _T("ИспользоватьБуфер"));
		return TRUE;
	};

	if (bResult&&(m_strMode.GetLength()))
	{
		CString strCheck("");
		GetModeAndCategory(&m_mapEventType,TRUE,strCheck);
		GetModeAndCategory(&m_mapEvent,TRUE,strCheck);
		GetModeAndCategory(&m_mapObject,TRUE,strCheck);
		GetModeAndCategory(&m_mapObjectKind,TRUE,strCheck);
		if (int nLen=strCheck.GetLength())
		{
			for (int nIndex=0; nIndex<nLen; nIndex++)
				if (bResult=m_strMode.Find(strCheck[nIndex])!=-1)
					break;
		};
		if (bResult&&(m_strPresent.GetLength()))
			bResult=m_strMode.Find(_T('E'))!=-1;
	};
	if (bResult&&(m_strCategory.GetLength()))
	{
		CString strCheck("");
		GetModeAndCategory(&m_mapEventType,FALSE,strCheck);
		GetModeAndCategory(&m_mapEvent,FALSE,strCheck);
		GetModeAndCategory(&m_mapObject,FALSE,strCheck);
		GetModeAndCategory(&m_mapObjectKind,FALSE,strCheck);
		if (int nLen=strCheck.GetLength())
		{
			for (int nIndex=0; nIndex<nLen; nIndex++)
				if (bResult=m_strCategory.Find(strCheck[nIndex])!=-1)
					break;
		};
	};

	if (bResult)
	{
		for (UCHAR chFilterType=LOG_DP_FILTER_USER; chFilterType<=LOG_DP_FILTER_OBJECTKIND; chFilterType++)
		{
			int nSize=0;
			switch (chFilterType)
			{
			case LOG_DP_FILTER_USER:
				nSize=m_mapUser.GetCount();
				break;
			case LOG_DP_FILTER_MODE:
				nSize=m_strMode.GetLength();
				break;
			case LOG_DP_FILTER_CATEGORY:
				nSize=m_strCategory.GetLength();
				break;
			case LOG_DP_FILTER_EVENTTYPE:
				nSize=m_mapEventType.GetCount();
				break;
			case LOG_DP_FILTER_EVENT:
				nSize=m_mapEvent.GetCount();
				break;
			case LOG_DP_FILTER_COMMENT:
				nSize=m_strComment.GetLength();
				break;
			case LOG_DP_FILTER_OBJECT:
				nSize=m_mapObject.GetCount();
				break;
			case LOG_DP_FILTER_OBJECTKIND:
				nSize=m_mapObjectKind.GetCount();
				break;
			case LOG_DP_FILTER_PRESENT:
				nSize=m_strPresent.GetLength();
				break;
			};

			if (nSize)
				m_dwFilter=m_dwFilter|(1<<(chFilterType-1));
			else
				m_dwFilter=m_dwFilter&(-1^(1<<(chFilterType-1)));
		};

		m_bInvalidFilter=FALSE;
		Result=CNumeric(1);

		if (GetControl())
		{
			GetRowResult res=grrMatch;

			m_RowsList.RemoveAll();
			
			if (m_dwFilter&&nUseBuffer)
			{
				m_dwFilter=m_dwFilter|(1<<(LOG_DP_FILTER_USING_BUFFER-1));

				LONGLONG llBytesToRead=GetBytesToRead();
				LONGLONG llBytesRead=0;
				
				res=AddRowsToList(amNormal,m_liBegPosition,llBytesToRead,llBytesRead);
			}
			else
				m_dwFilter=m_dwFilter&(-1^(1<<(LOG_DP_FILTER_USING_BUFFER-1)));

			ResetData();

			if (res==grrEscPressed)
				RuntimeError(_T("Log data provider: установка фильтра прервана по ESC."));

		};

	}
	else
	{
		m_bInvalidFilter=TRUE;
		Result=CNumeric(0);
	};

	return TRUE;
}


BOOL CV7LogProvider::ChangeFilter(CValue& Result, CValue** ppValue)
{
	if (ppValue[0]->GetTypeCode() == NUMBER_TYPE_1C)
	{
		if (int nFilter=ppValue[0]->GetNumeric())
		{
			if (abs(nFilter)>LOG_DP_FILTER_MAX_PARAM)
			{
				Result=CNumeric(0);
				return TRUE;
			};
			bool bAddParam=nFilter>0;

			if (bAddParam)
				nFilter--;
			else
				nFilter++;
			
			UCHAR chSecondParam=m_stFiltersInfo[abs(nFilter)].chSecondParam;
			UCHAR chFilterType=m_stFiltersInfo[abs(nFilter)].chFilterType+1;
			
			if (chSecondParam == LOG_DP_FILTER_PARAM_NO)
			{
				CString strTmp(m_stFiltersInfo[abs(nFilter)].strEventOrType);
				switch (chFilterType)
				{
				case LOG_DP_FILTER_EVENT:
					if (bAddParam)
					{
						int nIndex=m_stFiltersInfo[nFilter].chParent;
						m_mapEventType.RemoveKey(m_stFiltersInfo[nIndex].strEventOrType);
						m_mapEvent.SetAt(strTmp,nFilter);
					}
					else
						m_mapEvent.RemoveKey(strTmp);
					break;
				case LOG_DP_FILTER_EVENTTYPE:
					if (bAddParam)
					{
						int nIndex=nFilter+1;
						while (m_stFiltersInfo[nIndex].chParent)
						{
							m_mapEvent.RemoveKey(m_stFiltersInfo[nIndex].strEventOrType);
							nIndex++;
						};
						m_mapEventType.SetAt(strTmp,nFilter);
					}
					else
						m_mapEventType.RemoveKey(strTmp);
					break;
				};
			}
			else
			{
				switch (int nParamType=ppValue[1]->GetTypeCode())
				{
				case UNDEFINE_TYPE_1C:
					if (!bAddParam)
					{
						switch (chFilterType)
						{
						case LOG_DP_FILTER_USER:
							m_mapUser.RemoveAll();
							break;
						case LOG_DP_FILTER_MODE:
							m_strMode.Empty();
							break;
						case LOG_DP_FILTER_CATEGORY:
							m_strCategory.Empty();
							break;
						case LOG_DP_FILTER_EVENTTYPE:
							m_mapEventType.RemoveAll();
							break;
						case LOG_DP_FILTER_EVENT:
							m_mapEvent.RemoveAll();
							break;
						case LOG_DP_FILTER_COMMENT:
							m_strComment.Empty();
						case LOG_DP_FILTER_OBJECT:
							{
								POSITION pos=m_mapObject.GetStartPosition();
								while (pos!=NULL)
								{
									CString strKey;
									int nVal;
									m_mapObject.GetNextAssoc(pos,strKey,nVal);
									if (m_stFiltersInfo[nVal].chFilterType==LOG_DP_FILTER_OBJECT)
									{
										m_mapObject.RemoveKey(strKey);
										pos=m_mapObject.GetStartPosition();
									};
								};
							};
						case LOG_DP_FILTER_OBJECTKIND:
							{
								POSITION pos=m_mapObjectKind.GetStartPosition();
								while (pos!=NULL)
								{
									CString strKey;
									int nVal;
									m_mapObjectKind.GetNextAssoc(pos,strKey,nVal);
									if (m_stFiltersInfo[nVal].chFilterType==LOG_DP_FILTER_OBJECTKIND)
									{
										m_mapObjectKind.RemoveKey(strKey);
										pos=m_mapObjectKind.GetStartPosition();
									};
								};
							};
							break;
						case LOG_DP_FILTER_PRESENT:
							m_strPresent.Empty();
							break;
						};
					}
					else
					{
						Result=CNumeric(0);
						return TRUE;
					};
					break;
				case STRING_TYPE_1C:
					if (chSecondParam&LOG_DP_FILTER_PARAM_STR)
					{
						CString strTmp=ppValue[1]->GetString();
						if (!strTmp.IsEmpty())
						{
							switch (chFilterType)
							{
							case LOG_DP_FILTER_USER:
								if (bAddParam)
									m_mapUser.SetAt(strTmp,NULL);
								else
									m_mapUser.RemoveKey(strTmp);
								break;
							case LOG_DP_FILTER_MODE:
								m_strMode=GetStringFromTmpl(m_strMode, strTmp, CString("ECMD"), bAddParam);
								break;
							case LOG_DP_FILTER_CATEGORY:
								m_strCategory=GetStringFromTmpl(m_strCategory, strTmp, CString("012345"), bAddParam);
								break;
							case LOG_DP_FILTER_EVENTTYPE:
								if (bAddParam)
									m_mapEventType.SetAt(strTmp,nFilter);
								else
									m_mapEventType.RemoveKey(strTmp);
								break;
							case LOG_DP_FILTER_EVENT:
								if (bAddParam)
									m_mapEvent.SetAt(strTmp,nFilter);
								else
									m_mapEvent.RemoveKey(strTmp);
								break;
							case LOG_DP_FILTER_COMMENT:
								strTmp.MakeLower();
								m_strComment=strTmp;
								break;
							case LOG_DP_FILTER_OBJECTKIND:
								{
									CType t(0);
									CMetaDataWork::SetTypeAndKind(t,strTmp);
									CValue val(t);
									if (GetStringPresent(&val,FALSE,strTmp))
									{
										if (bAddParam)
											m_mapObjectKind.SetAt(strTmp,nFilter);
										else
											m_mapObjectKind.RemoveKey(strTmp);
									};
								};
								break;
							case LOG_DP_FILTER_PRESENT:
								strTmp.MakeLower();
								m_strPresent=strTmp;
								break;
							};
						};
					};
					break;
				case AGREGATE_TYPE_1C:
					if (chSecondParam&LOG_DP_FILTER_PARAM_VL)
					{
						CBLContext* pBLContext = ppValue[1]->GetContext();
						if (pBLContext->GetInternalData()->GetRuntimeClass() == RUNTIME_CLASS(CValueListContextData))
						{
							CValueListContextData* pVLCD = static_cast<CValueListContextData*>(pBLContext->GetInternalData());
							PValueItemArrayT *pValItAr = (PValueItemArrayT*)pVLCD->GetValueList();
							for(int i=0; i<pValItAr->GetSize(); i++)
							{
								CValue* val=(CValue*)pValItAr->GetAt(i);
								
								if (int nParamType=val->GetTypeCode()==STRING_TYPE_1C)
								{
									if (chSecondParam&LOG_DP_FILTER_PARAM_STR)
									{
										CString strTmp=val->GetString();
										if (!strTmp.IsEmpty())
										{
											switch (chFilterType)
											{
											case LOG_DP_FILTER_USER:
												if (bAddParam)
													m_mapUser.SetAt(strTmp,NULL);
												else
													m_mapUser.RemoveKey(strTmp);
												break;
											case LOG_DP_FILTER_EVENTTYPE:
												if (bAddParam)
													m_mapEventType.SetAt(strTmp,nFilter);
												else
													m_mapEventType.RemoveKey(strTmp);
												break;
											case LOG_DP_FILTER_EVENT:
												if (bAddParam)
													m_mapEvent.SetAt(strTmp,nFilter);
												else
													m_mapEvent.RemoveKey(strTmp);
												break;
											case LOG_DP_FILTER_OBJECTKIND:
												{
													CType t(0);
													CMetaDataWork::SetTypeAndKind(t,strTmp);
													CValue val(t);
													if (GetStringPresent(&val,FALSE,strTmp))
													{
														if (bAddParam)
															m_mapObjectKind.SetAt(strTmp,nFilter);
														else
															m_mapObjectKind.RemoveKey(strTmp);
													};
												};
												break;
											};
										};
									};
								}
								else
								{
									if (chSecondParam&LOG_DP_FILTER_PARAM_OBJ)
									{
										CString strTmp;
										if (GetStringPresent(val,TRUE,strTmp))
										{
											if (bAddParam)
												m_mapObject.SetAt(strTmp,nFilter);
											else
												m_mapObject.RemoveKey(strTmp);
										};
									};
								};
							};
						};
					};
					break;
				default:
					if (chSecondParam&LOG_DP_FILTER_PARAM_OBJ)
					{
						CString strTmp;
						if (GetStringPresent(ppValue[1],TRUE,strTmp))
						{
							if (bAddParam)
								m_mapObject.SetAt(strTmp,nFilter);
							else
								m_mapObject.RemoveKey(strTmp);
						};
					};
				};
			};
		}
		else
		{
			m_dwFilter=0;
			m_bInvalidFilter=FALSE;

			m_strMode.Empty();
			m_strCategory.Empty();
			m_strComment.Empty();
			m_strPresent.Empty();

			m_mapUser.RemoveAll();
			m_mapEventType.RemoveAll();
			m_mapEvent.RemoveAll();
			m_mapObject.RemoveAll();
			m_mapObjectKind.RemoveAll();

			m_RowsList.RemoveAll();

		};
		Result=CNumeric(1);
	}
	else
	{
		Result=CNumeric(0);
	};
	return TRUE;
}


BOOL CV7LogProvider::DefaultFilter(int nParam, CValue* param) const
{
	switch(nParam)
	{
	case 0:
		*param = CValue(CNumeric(LOG_DP_FILTER_CLEAR));
		break;
	case 1:
		*param = CValue();
		break;
	};
	return TRUE;
}


BOOL CV7LogProvider::GetUsingBuffer(CValue& Value) const
{
	Value=CNumeric(BufferMode()?1:0);
	return TRUE;
}


BOOL CV7LogProvider::BufferMode() const
{
	return m_dwFilter&(1<<(LOG_DP_FILTER_USING_BUFFER-1)) ? TRUE : FALSE;
}


BOOL CV7LogProvider::SetScanDeep(CValue& Result, CValue** ppValue)
{
	Result=CNumeric(0);
	if ((ppValue[0]->GetTypeCode()==NUMBER_TYPE_1C)&&(ppValue[1]->GetTypeCode()==NUMBER_TYPE_1C))
	{
		long nVal=ppValue[0]->GetNumeric();
		if (nVal>=0)
		{
			if (m_nScanDeep!=nVal)
			{
				m_nScanDeep=nVal;
				if ((ppValue[1]->GetNumeric()==1)&&GetControl())
					ResetData();
			};
			Result=CNumeric(1);
		};
	};
	return TRUE;
}


BOOL CV7LogProvider::GetScanDeep(CValue& Value) const
{
	Value=CNumeric(m_nScanDeep);
	return TRUE;
}


BOOL CV7LogProvider::DefaultScanDeep(int nParam, CValue* param) const
{
	switch(nParam)
	{
	case 0:
		*param = CValue(CNumeric(0));
		break;
	case 1:
		*param = CValue(CNumeric(1));
		break;
	};
	return TRUE;
}


BOOL CV7LogProvider::GetLastScanDate(CValue& Value) const
{
	if (DWORD dwDate=!m_bInvalidFilter&&m_dwFilter?m_dwLastScanDate:0)
	{
		int nY=dwDate/10000;
		int nM=(dwDate-nY*10000)/100;
		Value=CDate(nY,nM,dwDate%100);
	}
	else
	{
		Value=CDate(0,0,0);
		Value.m_Date.m_DateNum=0;
	};
	return TRUE;
}


BOOL CV7LogProvider::IsDateTimeValid(const BOOL bCheckDateTime, CString& strDateTime, ULONGLONG* pqwDateTime) const
{
	if (bCheckDateTime)
	{
		if (strDateTime.GetLength()!=LOG_DP_DATE_TIME_LENGTH)
			return FALSE;
		
		BOOL bIsValidRow;
		
		if (bIsValidRow=(strDateTime[8]==_T(';')) && (strDateTime[17]==_T(';')) && (strDateTime[11]==_T(':')) && (strDateTime[14]==_T(':')))
		{
			int nNumber=strDateTime.GetLength();
			CString strTemplate=_T("0123456789;:");

			for (int i=0;i<nNumber;i++)
			{
				if (strTemplate.Find(strDateTime[i])==-1)
				{
					bIsValidRow=FALSE;
					break;
				};
			};

			if (bIsValidRow)
			{
				nNumber=atoi(strDateTime.Left(4));
				if (bIsValidRow=((nNumber>1979)&&(nNumber<=2099)))
				{
					nNumber=atoi(strDateTime.Mid(4,2));
					if (bIsValidRow=((nNumber>0)&&(nNumber<=12)))
					{
						nNumber=atoi(strDateTime.Mid(6,2));
						if (bIsValidRow=((nNumber>0)&&(nNumber<=31)))
						{
							nNumber=atoi(strDateTime.Mid(9,2));
							if (bIsValidRow=((nNumber>=0)&&(nNumber<=23)))
							{
								nNumber=atoi(strDateTime.Mid(12,2));
								if (bIsValidRow=((nNumber>=0)&&(nNumber<=59)))
								{
									nNumber=atoi(strDateTime.Mid(15,2));
									bIsValidRow=(nNumber>=0)&&(nNumber<=59);
								};
							};
						};
					};
				};
			};
		};

		if (!bIsValidRow)
			return FALSE;
	};

	if (pqwDateTime)
	{
		strDateTime.Remove(_T(';'));
		strDateTime.Remove(_T(':'));
		*pqwDateTime=_atoi64(strDateTime);
	};

	return TRUE;
}


// все остальное
BOOL CV7LogProvider::GetRow(const BOOL bFetch, BOOL bBackward, LARGE_INTEGER &liRowPosition, CString &strRow, ULONGLONG* pqwDate)
{
	strRow.Empty();

	if (bBackward&&(m_liCurrentPosition.QuadPart==0))
	{
		liRowPosition.QuadPart=0;
		return FALSE;
	};

	// если не Fetch, то сначала всегда ищем с конца буфера
	if (!bFetch)
		bBackward = TRUE;

	BOOL bFullCheck=TRUE;
	BOOL bRememberPosition=TRUE;

	LARGE_INTEGER liOldPosition=m_liCurrentPosition;

	DWORD dwBytesToRead;
	DWORD dwJumpSize;
	if (!m_dwFilter||(m_eProviderMode==pmBoundsSearch))
	{
		dwBytesToRead=LOG_DP_MIN_READ_BLOCK_SIZE;
		switch (m_nBufferGrowCount)
		{
		case 0:
			dwJumpSize=0;
			break;
		case 1:
			dwJumpSize=LOG_DP_MIN_READ_BLOCK_SIZE;
			break;
		default:
			dwJumpSize=LOG_DP_MIN_READ_BLOCK_SIZE<<(m_nBufferGrowCount-1);
		};
	}
	else
	{
		dwBytesToRead=LOG_DP_MAX_READ_BLOCK_SIZE;
		dwJumpSize=m_nBufferGrowCount?LOG_DP_MAX_READ_BLOCK_SIZE:0;
	};

	int nBufferGrowCount=0;

	while (1)
	{
		
		int nPos = bBackward ? m_strBuffer.ReverseFind(LOG_DP_NEW_ROW_13) : m_strBuffer.Find(LOG_DP_NEW_ROW_13, 0);

		if ((nPos == -1) && m_bStandardBuffer)
		{
			CString strTmp=m_strBuffer;

			LARGE_INTEGER liPosition;
			liPosition.QuadPart=0;

			DWORD dwMoveMethod=FILE_CURRENT;

			if (bBackward)
			{
				liRowPosition = m_liCurrentPosition;

				dwJumpSize+=dwBytesToRead;

				if (m_liCurrentPosition.QuadPart < _INT64_(dwBytesToRead))
				{
					dwMoveMethod=FILE_BEGIN;
					m_bStandardBuffer=FALSE;
				}
				else
				{
					liPosition.QuadPart=-_INT64_(dwJumpSize);
					nBufferGrowCount++;
					dwJumpSize=dwBytesToRead;
				};
			};

			if (!SetPosition(liPosition,dwMoveMethod))
			{
				liRowPosition.QuadPart=0;
				strRow.Empty();
				return FALSE;
			}
			else
			{
				ULARGE_INTEGER uiFileSize;
				uiFileSize.LowPart=GetFileSize(m_hLogFile, &uiFileSize.HighPart);
				if (liPosition.QuadPart >= uiFileSize.QuadPart)
				{
					liRowPosition.QuadPart=0;
					strRow.Empty();
					return FALSE;
				};
			};

			DWORD dwRead;
			ReadLog(dwBytesToRead,dwRead,LOG_DP_TRIM_10_13_NO);

			if (bBackward)
			{
				if (liRowPosition.QuadPart < _INT64_(dwBytesToRead))//_INT64_(LOG_DP_READ_BLOCK_SIZE))
					m_strBuffer = m_strBuffer.Left(liRowPosition.LowPart);
				else
					m_strBuffer+=strTmp;
				m_liCurrentPosition.QuadPart+=_INT64_(m_strBuffer.GetLength());
			}
			else
			{
				m_liCurrentPosition.QuadPart-=_INT64_(strTmp.GetLength());
				m_strBuffer=strTmp+m_strBuffer;
			};

			if (dwBytesToRead<LOG_DP_MAX_READ_BLOCK_SIZE)
				dwBytesToRead=dwBytesToRead<<1;

		}
		else
		{
			if (bBackward)
			{
				if (nPos == -1)
				{
					if (m_strBuffer.IsEmpty())
					{
						liRowPosition.QuadPart=0;
						strRow.Empty();
						return FALSE;
					};

					strRow = m_strBuffer + strRow;
					m_liCurrentPosition.QuadPart = _INT64_(m_strBuffer.GetLength()+LOG_DP_NEW_LINE_LENGTH);
					m_strBuffer.Empty();
					if (bRememberPosition)
					{
						liRowPosition.QuadPart = 0;
						bRememberPosition=FALSE;
					};
				}
				else
				{
					CString strTmp = m_strBuffer.Mid(nPos+LOG_DP_NEW_LINE_LENGTH);
					strRow = strTmp + strRow;
					m_strBuffer = m_strBuffer.Left(nPos);
					m_liCurrentPosition.QuadPart-=_INT64_(strTmp.GetLength()+LOG_DP_NEW_LINE_LENGTH);
					if (bRememberPosition)
					{
						liRowPosition.QuadPart = m_liCurrentPosition.QuadPart+LOG_DP_NEW_LINE_LENGTH;
						bRememberPosition=FALSE;
					};
				};
			}
			else
			{
				if (bRememberPosition)
				{
					liRowPosition = m_liCurrentPosition;
					bRememberPosition=FALSE;
				};
				strRow += m_strBuffer.Left(nPos);
				m_strBuffer = m_strBuffer.Mid(nPos+LOG_DP_NEW_LINE_LENGTH);
				m_liCurrentPosition.QuadPart+=_INT64_(nPos+LOG_DP_NEW_LINE_LENGTH);
			};

			int nLen=strRow.GetLength();
			if (nLen<LOG_DP_DATE_TIME_LENGTH)
			{
				bRememberPosition=TRUE;
				if (!bFetch)
				{
					strRow.Empty();
					liOldPosition.QuadPart-=_INT64_(nLen);
				};
			}
			else
			{
				BOOL bIsValidRow=FALSE;

				int nCount=bFullCheck?1:2;

				while (nCount)
				{
					BOOL bIsBackward=nCount==1?bBackward:!bBackward;

					CString strDateTime;
					if (bIsBackward)
						strDateTime=strRow.Left(LOG_DP_DATE_TIME_LENGTH);
					else
					{
						if (nCount==1)
						{
							if (m_strBuffer.GetLength()<LOG_DP_DATE_TIME_LENGTH)
							{
								CString strTmp=m_strBuffer;
								DWORD dwRead;
								ReadLog(LOG_DP_MIN_READ_BLOCK_SIZE,dwRead,LOG_DP_TRIM_10_13_LEFT);
								m_strBuffer=strTmp+m_strBuffer;
							}
							strDateTime=m_strBuffer.Left(LOG_DP_DATE_TIME_LENGTH);
						}
						else
						{
							LARGE_INTEGER liPosition=liOldPosition;
							if (!SetPosition(liPosition,FILE_BEGIN))
							{
								liRowPosition.QuadPart=0;
								strRow.Empty();
								return FALSE;
							};
							DWORD dwRead;
							ReadLog(LOG_DP_MIN_READ_BLOCK_SIZE,dwRead,LOG_DP_TRIM_10_13_LEFT);
							strDateTime=m_strBuffer.Left(LOG_DP_DATE_TIME_LENGTH);
						};
					};
					if (bIsBackward||(strDateTime.GetLength()==LOG_DP_DATE_TIME_LENGTH))
						bIsValidRow=IsDateTimeValid(TRUE,strDateTime);
					else
						bIsValidRow=TRUE;

					if (bFetch)
						break;
					else
					{
						if (!bIsValidRow||(nCount==2))
							break;
					};
					nCount++;
				};

				if (bIsValidRow)
				{
					if (m_bSkipRow)
					{
						m_bSkipRow=FALSE;
						bRememberPosition=TRUE;
						strRow.Empty();
					}
					else
					{
						if (pqwDate)
						{
							CString strDateTime=strRow.Left(LOG_DP_DATE_TIME_LENGTH);
							strDateTime.Remove(_T(':'));
							strDateTime.Remove(_T(';'));
							*pqwDate=_atoi64(strDateTime);
						};
						break;
					}
				}
				else
				{
					if (bFetch)
					{
						if (bBackward)
						{
							strRow=CString(13)+CString(10)+strRow;
							bRememberPosition=TRUE;
						}
						else strRow+=CString(13)+CString(10);
					}
					else
					{
						if (nCount==2)
						{
							bBackward=!bBackward;
							bFullCheck=FALSE;
						};
					};
				};
			};
		};
	};

	if (nBufferGrowCount)
		m_nBufferGrowCount=__min(nBufferGrowCount,7);

	return !strRow.IsEmpty();
}


BOOL CV7LogProvider::SearchBound(const BOOL bLowerBound, const ULONGLONG& qwSearchDate)
{
	ULONGLONG qwFoundDate=0;

	ULARGE_INTEGER uiFileSize;
	uiFileSize.LowPart=GetFileSize(m_hLogFile, &uiFileSize.HighPart);

	ULONGLONG qwJumpSize=uiFileSize.QuadPart;
	int nLen=(sizeof(qwJumpSize)<<3)-1;
	while (!(qwJumpSize&(static_cast<ULONGLONG>(1)<<nLen)))
		nLen--;
	if ((static_cast<ULONGLONG>(1)<<nLen)<qwJumpSize)
		nLen++;
	int nCount=nLen-10; // размер буфера 2^10=1024 байт


	CString strRow;
	strRow.Empty();

	BOOL bResult=FALSE;
	BOOL bBackward=FALSE;

	LARGE_INTEGER liFoundPosition;
	liFoundPosition.QuadPart=0;

	while (nCount&&qwJumpSize)
	{
		if (qwSearchDate==qwFoundDate)
			bBackward=!bLowerBound;
		else
			bBackward=qwSearchDate<qwFoundDate;

		nLen=strRow.GetLength();
		if ((qwJumpSize>>1)>=(nLen+LOG_DP_MIN_ROW_LENGTH))
			qwJumpSize=qwJumpSize>>1;
		else
		{
			if ((qwJumpSize+LOG_DP_MIN_ROW_LENGTH)<=nLen)
				qwJumpSize=nLen+LOG_DP_MIN_ROW_LENGTH;
		};

		BOOL bLikeFetch=FALSE;
		if (bBackward)
		{
			liFoundPosition.QuadPart-=qwJumpSize;
			if (liFoundPosition.QuadPart<0)
			{
				liFoundPosition.QuadPart=0;
				bLikeFetch=TRUE;
			};
		}
		else
		{
			liFoundPosition.QuadPart+=qwJumpSize;
			if (liFoundPosition.QuadPart>uiFileSize.QuadPart)
			{
				liFoundPosition.QuadPart=uiFileSize.QuadPart;
				bLikeFetch=TRUE;
			};
		};
		if (!SetPosition(liFoundPosition,FILE_BEGIN))
			return FALSE;

		m_bStandardBuffer=TRUE;
		m_nBufferGrowCount=0;
		m_strBuffer.Empty();

		GetRow(bLikeFetch, liFoundPosition.QuadPart!=0, liFoundPosition, strRow, &qwFoundDate);

		nCount--;
	};

	if (qwSearchDate==qwFoundDate)
		bBackward=!bLowerBound;
	else
		bBackward=qwSearchDate<qwFoundDate;

	if (!SetPosition(liFoundPosition,FILE_BEGIN))
		return FALSE;

	m_bStandardBuffer=TRUE;
	m_nBufferGrowCount=0;
	m_strBuffer.Empty();

	LARGE_INTEGER liPrevPosition;

	nCount = INT_MAX;
	while (nCount)
	{
		liPrevPosition=liFoundPosition;
		if (GetRow(TRUE,bBackward,liFoundPosition,strRow,&qwFoundDate))
		{
			if (bLowerBound)
			{
				if (bBackward)
				{
					if (qwSearchDate>=qwFoundDate)
					{
						bResult=TRUE;
						m_liEndPosition=liPrevPosition;
						break;
					};
				}
				else
				{
					if (qwSearchDate<qwFoundDate)
					{
						bResult=TRUE;
						m_liEndPosition=liFoundPosition;
						break;
					};
				};
			}
			else
			{
				if (bBackward)
				{
					if (qwSearchDate>qwFoundDate)
					{
						bResult=TRUE;
						m_liBegPosition=liPrevPosition;
						break;
					};
				}
				else
				{
					if (qwSearchDate==qwFoundDate)
					{
						bResult=TRUE;
						m_liBegPosition=liFoundPosition;
						break;
					}
					else
					{
						if (qwSearchDate<qwFoundDate)
						{
							if (m_qwEndDate)
								bResult=qwFoundDate<=m_qwEndDate;
							else
								bResult=TRUE;
							if (bResult)
								m_liBegPosition=liFoundPosition;
							break;
						};
					};
				};
			};
		}
		else
			break;
		nCount--;
	};
	
	return bResult;
}


//CDataProvider
void CV7LogProvider::QueryRows(CDataRow* pRowFrom, int nRowsCount, int nPageSizeHint)
{
	if ((nRowsCount == 0) || !GetControl() || !m_hLogFile)
        return;
	if (m_bInvalidFilter)
	{
		m_nQueryRowsCount=0;
		return;
	};

    m_nQueryRowsCount = nRowsCount;
	m_bSkipRow = FALSE;
	m_bStandardBuffer = TRUE;
	m_nBufferGrowCount = 0;

	LARGE_INTEGER liPosition;
	
    if (pRowFrom)
	{
		liPosition = static_cast<CLogRow*>(pRowFrom)->m_liPosition;
		switch (m_eProviderMode)
		{
		case pmNormalBrowse:
			if (!liPosition.QuadPart&&(nRowsCount < 0))
				m_nQueryRowsCount = 0;
			break;
		case pmPeriodBrowse:
			{
				if (m_liBegPosition.QuadPart)
				{
					if (liPosition.QuadPart <= m_liBegPosition.QuadPart)
					{
						if (nRowsCount>0)
							liPosition.QuadPart=m_liBegPosition.QuadPart;
						else
							m_nQueryRowsCount=0;
					}
				};
				if (m_liEndPosition.QuadPart)
				{
					if (liPosition.QuadPart >= m_liEndPosition.QuadPart)
					{
						if (nRowsCount>0)
							m_nQueryRowsCount=0;
						else
							liPosition.QuadPart=m_liEndPosition.QuadPart;
					};
				};
			};
			break;
		default:
			m_nQueryRowsCount = 0;
		};
		if (m_nQueryRowsCount)
		{
			if (BufferMode())
			{
				if (m_RowsList.IsEmpty())
					m_RowPosition=NULL;
				else
				{
					m_RowPosition=m_RowsList.Find(liPosition.QuadPart);
					if (m_RowPosition)
					{
						if (m_nQueryRowsCount<0)
							m_RowsList.GetPrev(m_RowPosition);
						else
							m_RowsList.GetNext(m_RowPosition);
					}
					else
					{
						LONGLONG llPosition=m_RowsList.GetHead();
						if (llPosition>liPosition.QuadPart)
							m_RowPosition=m_RowsList.GetHeadPosition();
						else
						{
							llPosition=m_RowsList.GetTail();
							if (llPosition<liPosition.QuadPart)
								//m_RowPosition=m_RowsList.GetTailPosition();
								m_RowPosition=NULL;
							else
							{
								m_RowPosition=NULL;
								POSITION pos=m_RowsList.GetHeadPosition();
								while (pos)
								{
									if (m_RowsList.GetAt(pos)>liPosition.QuadPart)
									{
										m_RowPosition=pos;
										break;
									}
									else
										m_RowsList.GetNext(pos);
								};
							};
						};
					};
				};
				if (!m_RowPosition)
					m_nQueryRowsCount = 0;
			}
			else
			{
				if (SetPosition(liPosition,FILE_BEGIN))
					m_bSkipRow = m_nQueryRowsCount > 0;
				else
					m_nQueryRowsCount = 0;
			};
		};
	}
	else
	{
		DWORD dwMoveMethod;
		switch (m_eProviderMode)
		{
		case pmNormalBrowse:
			liPosition.QuadPart=0;
			dwMoveMethod=nRowsCount < 0 ? FILE_END : FILE_BEGIN;
			break;
		case pmPeriodBrowse:
			if (nRowsCount<0)
			{
				liPosition = m_liEndPosition;
				dwMoveMethod = m_liEndPosition.QuadPart == 0 ? FILE_END : FILE_BEGIN;
			}
			else
			{
				liPosition = m_liBegPosition;
				dwMoveMethod = FILE_BEGIN;
			};
			break;
		case pmInvalidPeriod:
			m_nQueryRowsCount=0;
			break;
		};

		if (m_nQueryRowsCount)
		{
			if (SetPosition(liPosition,dwMoveMethod))
			{
				if (BufferMode())
				{
					if (nRowsCount<0)
						m_RowPosition=m_RowsList.GetTailPosition();
					else
						m_RowPosition=m_RowsList.GetHeadPosition();
				};
			}
			else
			{
				m_nQueryRowsCount=0;
				m_eProviderMode=pmInvalidPeriod;
			};
		};

		m_bStandardBuffer = TRUE;
		m_nBufferGrowCount = 0;

	};
	
	m_strBuffer.Empty(); // подумать над этим
}


CV7LogProvider::GetRowResult CV7LogProvider::GetFilteredRow(const BOOL bSeeESC, const BOOL bCheckFilter, BOOL bBackward, LARGE_INTEGER &liPosition, CString* pRow, LPDWORD pdwRowLength, ULONGLONG* pqwDate)
{
	CString strRow;
	
	if (GetRow(TRUE,bBackward,liPosition,strRow,pqwDate))
	{
		if (m_eProviderMode==pmPeriodBrowse)
		{
			if (liPosition.QuadPart<m_liBegPosition.QuadPart)
				return grrNoMoreRows;
			else
			{
				if (m_liEndPosition.QuadPart&&(liPosition.QuadPart>=m_liEndPosition.QuadPart))
					return grrNoMoreRows;
			}
		}
		
		if (pdwRowLength)
			*pdwRowLength=strRow.GetLength()+LOG_DP_NEW_LINE_LENGTH;
		
		strRow.Replace(_T("\"\""),CString(_T('\x1')));
		
		for(int nCount=0; nCount<LOG_DP_FIELD_COUNT; nCount++)
		{
			pRow[nCount].Empty();

			CString csSeparator(strRow[0]==_T('"') ? _T("\";") : _T(";"));
			int nFind=strRow.Find(csSeparator,0);
			
			CString csTmp;
			if (nFind==-1)
				csTmp=strRow;
			else
				csTmp=strRow.Left(nFind);
			
			if ((nCount==8)&&(!m_strLogFileName.IsEmpty()))
				csTmp.Empty();
			else
			{
				csTmp.Remove(_T('"'));
				if (nCount==4)
				{
					if (csTmp[0] == _T('$'))
						csTmp=csTmp.Mid(1);
				}
			}
			csTmp.Replace(_T('\x1'),_T('"'));
			pRow[nCount]=csTmp;
			strRow=strRow.Mid(nFind+csSeparator.GetLength());
		}
		
		if (bCheckFilter)
		{
			if (bSeeESC)
			{
				MSG msg;
				if (PeekMessage(&msg,NULL,WM_KEYFIRST,WM_KEYLAST,PM_REMOVE))
				{
					//DefWindowProc(msg.hwnd,msg.message,msg.wParam,msg.lParam);
					if (msg.wParam == VK_ESCAPE)
					{
						if (m_nScanDeep)
							m_dwLastScanDate=atoi(pRow[0]);
						return grrEscPressed;
					}
				}
			}
			
			if (m_dwFilter) // проверка фильтров
			{
				DWORD dwTest=1<<(LOG_DP_FILTER_USER-1);
				int nIndex=LOG_DP_FILTER_USER;
				while (nIndex<=LOG_DP_FILTER_OBJECTKIND)
				{
					if (m_dwFilter&dwTest)
					{
						BOOL IsRowValid;
						switch (nIndex)
						{
						case LOG_DP_FILTER_USER:
							{
								CString strTmp=pRow[2].IsEmpty()?_T("<>"):pRow[2];
								CObject *p;
								IsRowValid=m_mapUser.Lookup(strTmp,p);
							}
							break;
						case LOG_DP_FILTER_MODE:
							IsRowValid=m_strMode.Find(pRow[3])!=-1;
							break;
						case LOG_DP_FILTER_CATEGORY:
							IsRowValid=m_strCategory.Find(pRow[6])!=-1;
							break;
						case LOG_DP_FILTER_EVENTTYPE:
							if (pRow[4].IsEmpty())
								IsRowValid=FALSE;
							else
							{
								int nIndex;
								IsRowValid=m_mapEventType.Lookup(pRow[4],nIndex);
							}
							break;
						case LOG_DP_FILTER_EVENT:
							if (pRow[5].IsEmpty())
								IsRowValid=FALSE;
							else
							{
								int nIndex;
								IsRowValid=m_mapEvent.Lookup(pRow[5],nIndex);
							}
							break;
						case LOG_DP_FILTER_COMMENT:
							{
								CString strTmp=pRow[7];
								strTmp.MakeLower();
								IsRowValid=strTmp.Find(m_strComment)!=-1;
							}
							break;
						case LOG_DP_FILTER_OBJECT:
						case LOG_DP_FILTER_OBJECTKIND:
							if (pRow[8].IsEmpty())
								IsRowValid=FALSE;
							else
							{
								int nIndex;
								if (m_mapObject.IsEmpty())
									IsRowValid=FALSE;
								else
									IsRowValid=m_mapObject.Lookup(pRow[8],nIndex);
								if (!IsRowValid)
								{
									if (!m_mapObjectKind.IsEmpty())
									{
										if (m_mapObjectKind.Lookup(CString(pRow[8][0]),nIndex))
											IsRowValid=TRUE;
										else
										{
											nIndex=pRow[8].ReverseFind(_T('/'));
											if (nIndex==-1)
												IsRowValid=FALSE;
											else
												IsRowValid=m_mapObjectKind.Lookup(pRow[8].Left(nIndex),nIndex);
										}
									}
								}
							}
							break;
						case LOG_DP_FILTER_PRESENT:
							{
								CString strTmp=pRow[9];
								strTmp.MakeLower();
								IsRowValid=strTmp.Find(m_strPresent)!=-1;
							}
							break;
						}
						
						if (!IsRowValid)
						{
							if (m_nScanDeep)
								m_dwLastScanDate=atoi(pRow[0]);
							return grrMismatch;
						}
					}
					dwTest=dwTest<<1;
					nIndex++;
				}
			}
		}
		
		return grrMatch;
	}
	else
		return grrNoMoreRows;
}


CDataRow* CV7LogProvider::Fetch()
{
	if ((m_nQueryRowsCount == 0) || !GetControl() || !m_hLogFile)
        return NULL;

	LARGE_INTEGER liPosition;
	CString mRow[LOG_DP_FIELD_COUNT];

	BOOL bBackward=m_nQueryRowsCount<0;

	GetRowResult result=grrNoMoreRows;

	if (BufferMode())
	{
		if (m_RowPosition)
		{
			if (bBackward)
				liPosition.QuadPart=m_RowsList.GetPrev(m_RowPosition);
			else
				liPosition.QuadPart=m_RowsList.GetNext(m_RowPosition);

			if (SetPosition(liPosition,FILE_BEGIN))
			{
				//m_bSkipRow = FALSE;
				m_bStandardBuffer = TRUE;
				m_nBufferGrowCount = 0;
				m_strBuffer.Empty();

				result=GetFilteredRow(TRUE,FALSE,FALSE,liPosition,mRow);
			};
		};
	}
	else
	{
		int nScanDeep=m_nScanDeep;

		while (!(result=GetFilteredRow(TRUE,TRUE,bBackward,liPosition,mRow)))
		{
			if (m_nScanDeep)
			{
				nScanDeep--;
				if (!nScanDeep)
				{
					result=grrNoMoreRows;
					break;
				};
			};
		};
	};

	if (result==grrMatch)
	{
		if (bBackward)
		{
			if (liPosition.QuadPart==m_liBegPosition.QuadPart)
				m_nQueryRowsCount=0;
			else
				m_nQueryRowsCount++;
		}
		else
			m_nQueryRowsCount--;

		return new CLogRow(liPosition,mRow);
	}
	else
	{
		m_nQueryRowsCount=0;
		return NULL;
	};
}


BOOL CV7LogProvider::RefreshRow(CDataRow* pRowFrom)
{
    //if (m_hLogFile)
	if (GetControl())
	{
		ULARGE_INTEGER uiFileSize;
		uiFileSize.LowPart=GetFileSize(m_hLogFile, &uiFileSize.HighPart);
		return static_cast<CLogRow*>(pRowFrom)->m_liPosition.QuadPart < uiFileSize.QuadPart;
	}
	else
        return FALSE;
}


BOOL CV7LogProvider::CompareRows(CDataRow* pRow1, CDataRow* pRow2) const
{
	return static_cast<CLogRow*>(pRow1)->m_liPosition.QuadPart == static_cast<CLogRow*>(pRow2)->m_liPosition.QuadPart;
}


void CV7LogProvider::OnAttach()
{
	if (OpenLog())
		ResetData();
}


BOOL CV7LogProvider::SelectLines(CValue& Result, CValue** ppValue)
{
	m_bLinesSelectionEnabled=FALSE;
	Result=CNumeric(0);

	if (GetControl())
		return TRUE;

	if (!m_hLogFile)
		return TRUE;

	if (ppValue[0]->GetTypeCode()!=NUMBER_TYPE_1C)
		return TRUE;

	LARGE_INTEGER liPosition;
	liPosition.QuadPart=ppValue[0]->GetNumeric();

	if (liPosition.QuadPart<0)
		return TRUE;

	if (GetRowByPosition(TRUE,liPosition))
	{
		if (SetPosition(liPosition,FILE_BEGIN))
		{
			m_strBuffer.Empty();
			m_nBufferGrowCount=0;
			m_bStandardBuffer=TRUE;
			m_bSkipRow=FALSE;

			for(int nIndex=0; nIndex<LOG_DP_FIELD_COUNT; nIndex++)
				m_sCurrentRow.fields[nIndex].Empty();
			m_sCurrentRow.pos=-1;
			m_bLinesSelectionEnabled=TRUE;

			Result=CNumeric(1);
		}
	};

	return TRUE;
}


BOOL CV7LogProvider::DefaultSelectLines(int nParam, CValue* param) const
{
	switch(nParam)
	{
	case 0:
		*param = CNumeric(0);
		break;
	};
	return TRUE;
}


BOOL CV7LogProvider::GetLine(CValue& Result, CValue** ppValue)
{
	Result=CNumeric(0);

	if (!m_bLinesSelectionEnabled)
		return TRUE;

	if (GetControl())
		return TRUE;

	if (!m_hLogFile)
		return TRUE;

	LARGE_INTEGER liPosition;
	
	int nScanDeep=m_nScanDeep;
	GetRowResult result;
		
	while (!(result=GetFilteredRow(TRUE,TRUE,FALSE,liPosition,m_sCurrentRow.fields)))
	{
		if (m_nScanDeep)
		{
			nScanDeep--;
			if (!nScanDeep)
			{
				result=grrNoMoreRows;
				break;
			};
		};
	};

	if (result==grrMatch)
	{
		m_sCurrentRow.pos=liPosition.QuadPart;
		Result=CNumeric(1);
	}
	else
	{
		m_bLinesSelectionEnabled=FALSE;

		if (result==grrEscPressed)
			RuntimeError(_T("Log data provider: выборка строк прервана по ESC."));
	};

	return TRUE;
}


BOOL CV7LogProvider::RowGetPosition(CValue& Value) const
{
	GetRowFieldValue(LOG_DP_FIELD_POSITION,Value);
	return TRUE;
}


BOOL CV7LogProvider::RowGetDate(CValue& Value) const
{
	GetRowFieldValue(LOG_DP_FILTER_DATE,Value);
	return TRUE;
}


BOOL CV7LogProvider::RowGetTime(CValue& Value) const
{
	GetRowFieldValue(LOG_DP_FILTER_TIME,Value);
	return TRUE;
}


BOOL CV7LogProvider::RowGetUser(CValue& Value) const
{
	GetRowFieldValue(LOG_DP_FILTER_USER,Value);
	return TRUE;
}


BOOL CV7LogProvider::RowGetMode(CValue& Value) const
{
	GetRowFieldValue(LOG_DP_FILTER_MODE,Value);
	return TRUE;
}


BOOL CV7LogProvider::RowGetEventType(CValue& Value) const
{
	GetRowFieldValue(LOG_DP_FILTER_EVENTTYPE,Value);
	return TRUE;
}


BOOL CV7LogProvider::RowGetEvent(CValue& Value) const
{
	GetRowFieldValue(LOG_DP_FILTER_EVENT,Value);
	return TRUE;
}


BOOL CV7LogProvider::RowCategory(CValue& Value) const
{
	GetRowFieldValue(LOG_DP_FILTER_CATEGORY,Value);
	return TRUE;
}


BOOL CV7LogProvider::RowGetComment(CValue& Value) const
{
	GetRowFieldValue(LOG_DP_FILTER_COMMENT,Value);
	return TRUE;
}


BOOL CV7LogProvider::RowGetObject(CValue& Value) const
{
	GetRowFieldValue(LOG_DP_FILTER_OBJECT,Value);
	return TRUE;
}


BOOL CV7LogProvider::RowGetObjectPresent(CValue& Value) const
{
	GetRowFieldValue(LOG_DP_FILTER_PRESENT,Value);
	return TRUE;
}


BOOL CV7LogProvider::GetLogFileName(CValue& Value) const
{
	CString strFile=m_strLogFileName;

	if (strFile.IsEmpty())
	{
		strFile = CSetOfHierarchy::GetHierarchy()->pathBase1C;
		strFile += strFile.Right(1) == _T("\\") ? _T("") : _T("\\");
		strFile += _T("Syslog\\1cv7.mlg");
	};

	Value=strFile;

	return TRUE;
}


BOOL CV7LogProvider::SetLogFileName(CValue const& Value)
{
	if (Value.GetTypeCode()==STRING_TYPE_1C)
	{
		if (m_strLogFileName.CompareNoCase(Value.GetString())!=0)
		{
			m_strLogFileName.Empty();
			CValue v;
			GetLogFileName(v);
			if (v.GetString().CompareNoCase(Value.GetString())!=0)
				m_strLogFileName=Value.GetString();

			if (GetControl())
			{
				CloseLog();
				OpenLog();
				ResetData();
			};
		};
	}
	else
		RuntimeError(_T("Имя файла должно иметь тип 'строка'!"));

	return TRUE;
}


void CV7LogProvider::GetRowFieldValue(const int nFieldIndex, CValue& Value) const
{
	Value=CValue();

	if (m_bLinesSelectionEnabled)
	{
		if (nFieldIndex==LOG_DP_FIELD_POSITION)
			Value=CValue(m_sCurrentRow.pos);
		else
		{
			if (!m_sCurrentRow.fields[_ROW_FIELD_INDEX_(nFieldIndex)].IsEmpty())
			{
				switch (nFieldIndex)
				{
				case LOG_DP_FILTER_DATE:
					Value=CValue(CDate(atoi(m_sCurrentRow.fields[_ROW_FIELD_INDEX_(nFieldIndex)].Left(4)),atoi(m_sCurrentRow.fields[_ROW_FIELD_INDEX_(nFieldIndex)].Mid(4,2)),atoi(m_sCurrentRow.fields[_ROW_FIELD_INDEX_(nFieldIndex)].Mid(6,2))));
					break;
				case LOG_DP_FILTER_CATEGORY:
					Value=CValue(CNumeric(atoi(m_sCurrentRow.fields[_ROW_FIELD_INDEX_(nFieldIndex)])));
					break;
				case LOG_DP_FILTER_OBJECT:
					LogValueFromString(Value,CString(m_sCurrentRow.fields[_ROW_FIELD_INDEX_(nFieldIndex)]),1);
					break;
				case LOG_DP_FILTER_TIME:
				case LOG_DP_FILTER_USER:
				case LOG_DP_FILTER_MODE:
				case LOG_DP_FILTER_EVENTTYPE:
				case LOG_DP_FILTER_EVENT:
				case LOG_DP_FILTER_COMMENT:
				case LOG_DP_FILTER_PRESENT:
					Value=CValue(m_sCurrentRow.fields[_ROW_FIELD_INDEX_(nFieldIndex)]);
					break;
				};
			};
		};
	}
	else
	{
		if (GetControl())
			RuntimeError(_T("Log data provider: доступ к полям запрещен."));
	};
}


BOOL CV7LogProvider::GetRowByPosition(const BOOL bCheckEnd, LARGE_INTEGER &liPosition)
{
	BOOL bLikeFetch=FALSE;
	BOOL bBackward=TRUE;

	if (m_liBegPosition.QuadPart)
	{
		if (m_liBegPosition.QuadPart>=liPosition.QuadPart)
		{
			liPosition=m_liBegPosition;
			bLikeFetch=TRUE;
			bBackward=FALSE;
		};
	};

	if (m_liEndPosition.QuadPart)
	{
		if (m_liEndPosition.QuadPart<=liPosition.QuadPart)
		{
			if (bCheckEnd)
				return FALSE;
			else
			{
				liPosition=m_liEndPosition;
				bLikeFetch=TRUE;
			};
		};
	};

	DWORD dwMoveMethod=FILE_BEGIN;

	if (!bLikeFetch)
	{
		liPosition.QuadPart+=LOG_DP_DATE_TIME_LENGTH;
		ULARGE_INTEGER uiFileSize;
		uiFileSize.LowPart=GetFileSize(m_hLogFile, &uiFileSize.HighPart);
		if (liPosition.QuadPart >= uiFileSize.QuadPart)
		{
			liPosition.QuadPart=0;
			bLikeFetch=TRUE;
			dwMoveMethod=FILE_END;
		};
	};

	if (SetPosition(liPosition,dwMoveMethod))
	{
		m_strBuffer.Empty();
		m_nBufferGrowCount=0;
		m_bStandardBuffer=TRUE;
		m_bSkipRow=FALSE;

		CString strRow;
		if (GetRow(bLikeFetch,bBackward,liPosition,strRow))
			return TRUE;
	};

	return FALSE;
}


//CV7DataProvider
void CV7LogProvider::GetRowValue(CDataRow* pDataRow, CValue& value) const
{
	LONGLONG nFilePos=static_cast<CLogRow*>(pDataRow)->m_liPosition.QuadPart;
	value=CValue(nFilePos);
}


CDataRow* CV7LogProvider::BuildRowByValue(const CValue& value)
{
	if (!GetControl())
		return NULL;

	if (!m_hLogFile)
		return NULL;

	if (value.GetTypeCode()!=NUMBER_TYPE_1C)
		return NULL;

	LARGE_INTEGER liPosition;
	liPosition.QuadPart=value.GetNumeric();

	if (liPosition.QuadPart<0)
		return NULL;

	if (GetRowByPosition(FALSE,liPosition))
		return new CLogRow(liPosition,NULL);
	else
		return NULL;
}


CV7DataRow* CV7LogProvider::GetV7DataRow(CDataRow* pDataRow) const
{
    return static_cast<CLogRow*>(pDataRow);
}


// вспомогательные функции
CString GetStringFromTmpl(CString strFindIn, CString& strTmp, const CString& strTmpl, const BOOL& bAddParam)
{
	strTmp.MakeUpper();
	strTmp = strTmp.SpanIncluding(strTmpl);
	if (!bAddParam&&strFindIn.IsEmpty())
		strFindIn=strTmpl;
	int nLen=strTmp.GetLength();
	for(int i=0;i<nLen;i++)
	{
		TCHAR chMode=strTmp[i];
		int nPos=strFindIn.Find(chMode);
		if (bAddParam)
		{
			if (nPos==-1)
			{
				strFindIn+=chMode;
				if (strFindIn.GetLength()==strTmpl.GetLength())
					strFindIn.Empty();
			};
		}
		else
		{
			if (nPos!=-1)
				strFindIn=strFindIn.SpanExcluding(CString(chMode));
		};
	};
	return strFindIn;
}


BOOL GetStringPresent(const CValue* const val, const BOOL bFull, CString& csResult)
{
	UCHAR chType;
	switch (val->GetTypeCode())
	{
	case ENUM_TYPE_1C:
		chType='E';
		break;
	case REFERENCE_TYPE_1C:
		chType='B';
		break;
	case DOCUMENT_TYPE_1C:
		chType='O';
		break;
	case CALENDAR_TYPE_1C:
		chType='C';
		break;
	case CALCULATIONKIND_TYPE_1C:
		chType='A';
		break;
	case ACCOUNT_TYPE_1C:
		chType='T';
		break;
	case SUBCONTOKIND_TYPE_1C:
		chType='K';
		break;
	case CHART_OF_ACC_TYPE_1C:
		chType='P';
		break;
	default:
		chType=0;
	};

	csResult.Empty();

	if (chType)
	{
		csResult=chType;
		char buf[20];
		if (long nKind=val->GetTypeID())
			csResult+="/"+CString(ltoa(nKind,buf,10));
		else
		{
			if (bFull)
				csResult+="/0";
		};
		if (bFull)
		{
			CString strSign=val->m_ObjID.GetDBSign();
			if (strSign.Compare("   "))
				csResult+="/("+strSign+")";
			else
				csResult+="/";
			long nID=val->m_ObjID.GetlObjID();
			csResult+=CString(ltoa(nID,buf,10));
		};
	};
	return !csResult.IsEmpty();
}
