| | /* ----------------------------------------------------------------------------------
Процесс авторегистрации абонентов
---------------------------------------------------------------------------------- */
#include "stdafx.h"
#include "../siglib/sys_inline.h"
#include "../siglib/sys_signals.h" // auto include
// Максимальное число номеров для регистрации
#define MAX_NUMBERLIST_LEN 30
// Разрешение таймера регистраций в миллисекундах
#define REG_CHECK_TIMEOUT 1000
// Актуальность регистраций в секундах
#define DEFAULT_REGISTRATION_TIMEOUT 180
// Повтор регистраций в секундах
#define NEXT_TRY_TIMEOUT 10
struct UserInfo
{
char Name[SHORT_LEN]; // Расширенное имя абонента
char Number[TEL_NUMBER_LEN]; // Номер абонента
char Password[BIG_LEN]; // Пароль абонента
WORD RegTimeout; // Таймер перерегистрации
BOOL RegProgress; // TRUE - Линия регистрируется
BOOL Registred; // Линия зарегистрирована
};
struct AUTO_REGISTRATOR__ContextType
{
struct UserInfo Users[MAX_NUMBERLIST_LEN]; // Номера для регистрации
WORD UserCount; // Count of numbers
WORD RegTimeout; // Registration timeout
WORD RegQueue[MAX_NUMBERLIST_LEN]; // Registration queue
WORD RegQueueLen; // Len of registration queue
WORD RegCurrent; // Регистрируемый номер
};
// -- States for AUTO_REGISTRATOR --
enum AUTO_REGISTRATOR__StatesEnum
{
AUTO_REGISTRATOR_State_Init = 0, // Init
AUTO_REGISTRATOR_State_Idle = 1, // Idle
AUTO_REGISTRATOR_State_Register = 2, // Registraton in progress
};
static struct _AU_StateInfo StatesNames__AUTO_REGISTRATOR[] =
{
{"Init", "Init"},
{"Idle", "Idle"},
{"Register", "Registraton in progress"},
{NULL, NULL}
};
void AUTO_REGISTRATOR__InitContext(WORD nContext, struct AU_BaseContext* pContext)
{
printf("------- BEGIN_INIT_CONTEXT\n");
((struct AUTO_REGISTRATOR__ContextType*)(pContext->pContext))->UserCount = 0;
memset(((struct AUTO_REGISTRATOR__ContextType*)(pContext->pContext))->Users, 0, MAX_NUMBERLIST_LEN*sizeof(struct UserInfo));
((struct AUTO_REGISTRATOR__ContextType*)(pContext->pContext))->RegQueueLen = 0;
((struct AUTO_REGISTRATOR__ContextType*)(pContext->pContext))->RegTimeout = DEFAULT_REGISTRATION_TIMEOUT;
pContext->State=AUTO_REGISTRATOR_State_Init;
}
BOOL AppendUser(struct Call_SetRegInfo_struct* pUser)
{
WORD i;
printf("+++++ AppendUser(%s %s %s)\n", pUser->Number, pUser->Name, pUser->Password);
printf("+++++ Count=%d\n", ((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->UserCount);
for(i=0;i<((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->UserCount;i++)
{
if(!stricmp(((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[i].Number, pUser->Number))
{
// Переопределяем
strcpy(((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[i].Name, pUser->Name);
strcpy(((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[i].Password, pUser->Password);
printf("+++++ 1\n");
return TRUE;
}
}
if(((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->UserCount==MAX_NUMBERLIST_LEN)
{
printf("+++++ 1\n");
return FALSE;
}
strcpy(((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->UserCount].Number, pUser->Number);
strcpy(((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->UserCount].Name, pUser->Name);
strcpy(((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->UserCount].Password, pUser->Password);
((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->UserCount++;
printf("+++++ Count=%d\n", ((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->UserCount);
return TRUE;
}
int AUTO_REGISTRATOR__CallContext(struct AU_BaseContext* pContext, WORD nContext, DWORD Code, void* pOut, size_t BufLen)
{
switch(Code)
{
case REG_EXPIRE_TIMEOUT:
((struct AUTO_REGISTRATOR__ContextType*)(pContext->pContext))->RegTimeout = *((WORD*)pOut);
return ERROR_noError;
case ADD_NUMBER_FOR_REGISTRATION:
{
struct Call_SetRegInfo_struct* pUser = (struct Call_SetRegInfo_struct*)pOut;
WORD i;
printf("+++++ AppendUser(%s %s %s)\n", pUser->Number, pUser->Name, pUser->Password);
printf("+++++ Count=%d\n", ((struct AUTO_REGISTRATOR__ContextType*)(pContext->pContext))->UserCount);
for(i=0;i<((struct AUTO_REGISTRATOR__ContextType*)(pContext->pContext))->UserCount;i++)
{
if(!stricmp(((struct AUTO_REGISTRATOR__ContextType*)(pContext->pContext))->Users[i].Number, pUser->Number))
{
// Переопределяем
strcpy(((struct AUTO_REGISTRATOR__ContextType*)(pContext->pContext))->Users[i].Name, pUser->Name);
strcpy(((struct AUTO_REGISTRATOR__ContextType*)(pContext->pContext))->Users[i].Password, pUser->Password);
printf("+++++ 1\n");
return ERROR_noError;
}
}
if(((struct AUTO_REGISTRATOR__ContextType*)(pContext->pContext))->UserCount==MAX_NUMBERLIST_LEN)
{
printf("+++++ 1\n");
return ERROR_tooBig;
}
strcpy(((struct AUTO_REGISTRATOR__ContextType*)(pContext->pContext))->Users[((struct AUTO_REGISTRATOR__ContextType*)(pContext->pContext))->UserCount].Number, pUser->Number);
strcpy(((struct AUTO_REGISTRATOR__ContextType*)(pContext->pContext))->Users[((struct AUTO_REGISTRATOR__ContextType*)(pContext->pContext))->UserCount].Name, pUser->Name);
strcpy(((struct AUTO_REGISTRATOR__ContextType*)(pContext->pContext))->Users[((struct AUTO_REGISTRATOR__ContextType*)(pContext->pContext))->UserCount].Password, pUser->Password);
((struct AUTO_REGISTRATOR__ContextType*)(pContext->pContext))->UserCount++;
printf("+++++ Count=%d\n", ((struct AUTO_REGISTRATOR__ContextType*)(pContext->pContext))->UserCount);
}
return ERROR_noError;
default:
return -1;
}
return ERROR_noError;
}
WORD PrintContext__AUTO_REGISTRATOR(struct AU_BaseContext* pContext, char* pOut, size_t BufLen)
{ size_t offset=0;
char tmp[100];
WORD i;
sprintf(pOut+offset, "<reg_queue_len data=\"%d\"%s", ((struct AUTO_REGISTRATOR__ContextType*)(pContext->pContext))->RegQueueLen, "/>\r\n");
offset+=strlen(pOut+offset);
tmp[0] = 0;
sprintf(tmp, "%d:", ((struct AUTO_REGISTRATOR__ContextType*)(pContext->pContext))->UserCount);
for(i=0;i<((struct AUTO_REGISTRATOR__ContextType*)(pContext->pContext))->UserCount;i++)
{
sprintf(tmp+strlen(tmp), " %s", ((struct AUTO_REGISTRATOR__ContextType*)(pContext->pContext))->Users[i].Number);
}
sprintf(pOut+offset, "<users data=\"%s\"%s", tmp, "/>\r\n");
offset+=strlen(pOut+offset);
return (WORD)strlen(pOut);
}
// Обработка сигнала KL_START
void AUTO_REGISTRATOR__OnSignal__KL_START__Default()
{
SetEventTimer(shedule_pCurBaseContext, shedule_pCurrentProcess->ID, shedule_nContext, T0-T0, REG_CHECK_TIMEOUT, TRUE, TRUE);
{shedule_pCurBaseContext->State=AUTO_REGISTRATOR_State_Idle;if(shedule_pCurBaseContext->TraceCnt){_XML_TraceState(shedule_pCurrentProcess, shedule_pCurBaseContext, shedule_nContext, StatesNames__AUTO_REGISTRATOR[shedule_pCurBaseContext->State].pName, StatesNames__AUTO_REGISTRATOR[shedule_pCurBaseContext->State].pDescription, TraceBuffer);TraceMessage(shedule_pCurrentProcess, shedule_nContext, TraceBuffer, (WORD)strlen(TraceBuffer));}}
shedule_pCurBaseContext->ActivityFlag = TRUE;
}
// Обработка сигнала KL_STOP
void AUTO_REGISTRATOR__OnSignal__KL_STOP__Default()
{
shedule_pCurBaseContext->ActivityFlag = TRUE;
}
static void TryRegister(WORD LineNo)
{
// Посылаем запрос регистрации
struct RF_Register a1066_buffer_query; struct RF_Register* query = &a1066_buffer_query;
((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[LineNo].RegProgress = TRUE;
strcpy(query->Name, ((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[LineNo].Name);
strcpy(query->Number, ((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[LineNo].Number);
strcpy(query->Password, ((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[LineNo].Password);
query->Timeout = ((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->RegTimeout*2;
((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->RegCurrent = LineNo;
_sfSendSignal(RF_REGISTER, FALSE, sizeof(struct RF_Register), (char*)(query));
}
static BOOL TryNextRegister()
{
// Если есть ожидающие регистрации, то регистрируем
if(((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->RegQueueLen)
{
TryRegister(((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->RegQueue[0]);
((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->RegQueueLen--;
memcpy(((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->RegQueue, ((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->RegQueue+1, ((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->RegQueueLen*sizeof(WORD));
return TRUE;
}
return FALSE;
}
void AUTO_REGISTRATOR__OnSignal__RF_COMPLETE__InState__Register()
{
// Помечаем как зарегистрированного
((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->RegCurrent].Registred = TRUE;
((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->RegCurrent].RegTimeout = ((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->RegTimeout;
((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->RegCurrent].RegProgress = FALSE;
if(!TryNextRegister()) {shedule_pCurBaseContext->State=AUTO_REGISTRATOR_State_Idle;if(shedule_pCurBaseContext->TraceCnt){_XML_TraceState(shedule_pCurrentProcess, shedule_pCurBaseContext, shedule_nContext, StatesNames__AUTO_REGISTRATOR[shedule_pCurBaseContext->State].pName, StatesNames__AUTO_REGISTRATOR[shedule_pCurBaseContext->State].pDescription, TraceBuffer);TraceMessage(shedule_pCurrentProcess, shedule_nContext, TraceBuffer, (WORD)strlen(TraceBuffer));}}
shedule_pCurBaseContext->ActivityFlag = TRUE;
}
void AUTO_REGISTRATOR__OnSignal__RF_FILED__InState__Register()
{
// Откладываем повторную регистрацию
((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->RegCurrent].RegTimeout = NEXT_TRY_TIMEOUT;
((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->RegCurrent].RegProgress = FALSE;
if(!TryNextRegister()) {shedule_pCurBaseContext->State=AUTO_REGISTRATOR_State_Idle;if(shedule_pCurBaseContext->TraceCnt){_XML_TraceState(shedule_pCurrentProcess, shedule_pCurBaseContext, shedule_nContext, StatesNames__AUTO_REGISTRATOR[shedule_pCurBaseContext->State].pName, StatesNames__AUTO_REGISTRATOR[shedule_pCurBaseContext->State].pDescription, TraceBuffer);TraceMessage(shedule_pCurrentProcess, shedule_nContext, TraceBuffer, (WORD)strlen(TraceBuffer));}}
shedule_pCurBaseContext->ActivityFlag = TRUE;
}
void AUTO_REGISTRATOR__OnSignal__T0__InState__Register()
{
WORD i;
for(i=0;i<((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->UserCount;i++)
{
if( ((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[i].RegProgress ||
!((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[i].Number[0])
continue;
if(((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[i].RegTimeout)
((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[i].RegTimeout--;
else
{
// Добавляем в очередь для регистрации
((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[i].Registred = FALSE;
((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[i].RegProgress = TRUE;
((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->RegQueue[((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->RegQueueLen] = i;
((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->RegQueueLen++;
}
}
shedule_pCurBaseContext->ActivityFlag = TRUE;
}
void AUTO_REGISTRATOR__OnSignal__HR_PASSWORD_RQ__InState__Idle(const struct HR_Password_Rq* pSignal, WORD SignalLen)
{
WORD i;
struct HR_Password_Ans a1066_buffer_ans; struct HR_Password_Ans* ans = &a1066_buffer_ans;
ans->Hook = pSignal->Hook;
for(i=0;i<((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->UserCount;i++)
{
if(!strcmp(((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[i].Number, pSignal->Name))
{
ans->Result = TRUE;
strcpy(ans->Password, ((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[i].Password);
snContext = SheduleSendContext; SheduleSendContext = shedule_pEvent->lMark;
_sfSendSignal(HR_PASSWORD_ANS, FALSE, sizeof(struct HR_Password_Ans), (char*)(ans)); SheduleSendContext = snContext;
return;
}
}
ans->Result = FALSE;
snContext = SheduleSendContext; SheduleSendContext = shedule_pEvent->lMark;
_sfSendSignal(HR_PASSWORD_ANS, FALSE, sizeof(struct HR_Password_Ans), (char*)(ans)); SheduleSendContext = snContext;
shedule_pCurBaseContext->ActivityFlag = TRUE;
}
void AUTO_REGISTRATOR__OnSignal__T0__InState__Idle()
{
WORD i;
BOOL flag = FALSE;
for(i=0;i<((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->UserCount;i++)
{
if(!((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[i].Number[0]) continue;
if(((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[i].RegTimeout)
((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[i].RegTimeout--;
else
{
((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[i].Registred = FALSE;
if(!flag)
{
TryRegister(i); // Регистрируем
flag = TRUE;
}
else
{
// Добавляем в очередь для регистрации
((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->Users[i].RegProgress = TRUE;
((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->RegQueue[((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->RegQueueLen] = i;
((struct AUTO_REGISTRATOR__ContextType*)shedule_pCurContext)->RegQueueLen++;
}
}
}
if(flag){ {shedule_pCurBaseContext->State=AUTO_REGISTRATOR_State_Register;if(shedule_pCurBaseContext->TraceCnt){_XML_TraceState(shedule_pCurrentProcess, shedule_pCurBaseContext, shedule_nContext, StatesNames__AUTO_REGISTRATOR[shedule_pCurBaseContext->State].pName, StatesNames__AUTO_REGISTRATOR[shedule_pCurBaseContext->State].pDescription, TraceBuffer);TraceMessage(shedule_pCurrentProcess, shedule_nContext, TraceBuffer, (WORD)strlen(TraceBuffer));}} }
shedule_pCurBaseContext->ActivityFlag = TRUE;
}
// ***** SUPER_FINISH(cc) ***** Root file="auto_registrator"
// ***** DECLARE_PROCESS
static char sAUTO_REGISTRATOR__XMLSignalMap[] =
"<signalmap>\r\n\
<signal id=KL_STOP>\r\n\
<state id=""/>\r\n\
</signal>\r\n\
<signal id=HR_PASSWORD_RQ>\r\n\
<state id=Idle/>\r\n\
</signal>\r\n\
<signal id=T0>\r\n\
<state id=Idle/>\r\n\
<state id=Register/>\r\n\
</signal>\r\n\
<signal id=RF_FILED>\r\n\
<state id=Register/>\r\n\
</signal>\r\n\
<signal id=KL_START>\r\n\
<state id=""/>\r\n\
</signal>\r\n\
<signal id=RF_COMPLETE>\r\n\
<state id=Register/>\r\n\
</signal>\r\n\
</signalmap>";
const char* get_AUTO_REGISTRATOR__XMLSignalMap() {return sAUTO_REGISTRATOR__XMLSignalMap;}
void AUTO_REGISTRATOR__ProcessEvents(const struct AU_Event* pEvent)
{
shedule_pEvent = (struct AU_Event*)pEvent;
snContext = SheduleSendContext;
sSyncSignalFlag = FALSE;
switch(pEvent->Code)
{
case KL_STOP:
switch(shedule_pCurBaseContext->State)
{
default:
AUTO_REGISTRATOR__OnSignal__KL_STOP__Default();
}
break;
case HR_PASSWORD_RQ:
switch(shedule_pCurBaseContext->State)
{
case AUTO_REGISTRATOR_State_Idle:
AUTO_REGISTRATOR__OnSignal__HR_PASSWORD_RQ__InState__Idle((const struct HR_Password_Rq*)(pEvent->pData), pEvent->DataLen);
break;
}
break;
case T0:
switch(shedule_pCurBaseContext->State)
{
case AUTO_REGISTRATOR_State_Idle:
AUTO_REGISTRATOR__OnSignal__T0__InState__Idle();
break;
case AUTO_REGISTRATOR_State_Register:
AUTO_REGISTRATOR__OnSignal__T0__InState__Register();
break;
}
break;
case RF_FILED:
switch(shedule_pCurBaseContext->State)
{
case AUTO_REGISTRATOR_State_Register:
AUTO_REGISTRATOR__OnSignal__RF_FILED__InState__Register();
break;
}
break;
case KL_START:
switch(shedule_pCurBaseContext->State)
{
default:
AUTO_REGISTRATOR__OnSignal__KL_START__Default();
}
break;
case RF_COMPLETE:
switch(shedule_pCurBaseContext->State)
{
case AUTO_REGISTRATOR_State_Register:
AUTO_REGISTRATOR__OnSignal__RF_COMPLETE__InState__Register();
break;
}
break;
default:
{
sprintf(pErrorString, "Signal not processed! Process:%s Context:%d Signal:%d Len:%d From:%d Route:%d", shedule_pCurrentProcess->Name, shedule_nContext, pEvent->Code, pEvent->DataLen, pEvent->From, pEvent->Route);
ErrorStack_Push(pErrorString);
}
}
}
BOOL AUTO_REGISTRATOR__TuneContext(struct AU_BaseContext* pContext, WORD nContext, const char* pParam, const char* pParamValue);
BOOL AUTO_REGISTRATOR__TraceContext(struct AU_BaseContext* pContext, WORD nContext, char* pOut, size_t OutLen);
const char* get_AUTO_REGISTRATOR__XMLClassInfo();
const char* get_AUTO_REGISTRATOR__XMLSignalMap();
void RegisterProcess__AUTO_REGISTRATORClass(struct AU_ProcessTemplate* pClass)
{
sprintf(pClass->Description, "Auto registrator");
pClass->pInitFunc = AUTO_REGISTRATOR__InitContext;
pClass->pTuneFunc = AUTO_REGISTRATOR__TuneContext;
pClass->pTraceFunc = AUTO_REGISTRATOR__TraceContext;
pClass->pEventFunc = AUTO_REGISTRATOR__ProcessEvents;
pClass->pBaseInfoFunc = get_AUTO_REGISTRATOR__XMLClassInfo;
pClass->pSignalMapFunc = get_AUTO_REGISTRATOR__XMLSignalMap;
pClass->pCallFunc = AUTO_REGISTRATOR__CallContext;
pClass->ExtContextSize = sizeof(struct AUTO_REGISTRATOR__ContextType);
}
BOOL AUTO_REGISTRATOR__TraceContext(struct AU_BaseContext* pBaseContext, WORD nContext, char* pOut, size_t OutLen)
{
size_t offset;
offset = _XML_TraceContext(shedule_pCurrentProcess, pBaseContext, nContext, StatesNames__AUTO_REGISTRATOR[pBaseContext->State].pName, StatesNames__AUTO_REGISTRATOR[pBaseContext->State].pDescription, pOut);
PrintContext__AUTO_REGISTRATOR(pBaseContext, pOut+offset, OutLen);
offset+=strlen(pOut+offset);
sprintf(pOut+offset, "</params>\r\n</context>");
return TRUE;
}
BOOL AUTO_REGISTRATOR__TuneContext(struct AU_BaseContext* pContext, WORD nContext, const char* pParam, const char* pParamValue)
{
return FALSE;
}
static char AUTO_REGISTRATOR_XMLClassInfo[] =
"<class name=AUTO_REGISTRATOR info=\"Auto registrator\">\r\n\
<states>\r\n\
<state id=Register>Registraton in progress</state>\r\n\
<state id=Idle>Idle</state>\r\n\
<state id=Init>Init</state>\r\n\
</states>\r\n\
<tunes>\r\n\
</tunes>\r\n\
<signal_map>\r\n\
</signal_map>\r\n\
</class>\r\n";
const char* get_AUTO_REGISTRATOR__XMLClassInfo() {return AUTO_REGISTRATOR_XMLClassInfo;}
|
|