📄 saf.cpp
字号:
safRecord.tStdTime = time(NULL); // Hora de STORED (TIME_T Standard ANSI Unix)
safRecord.tFwdTime = 0; // Hora de FORWARDED a NULL
safRecord.wState = SAF_RECSTATE_STORED; // Estado del Registro
safRecord.dwTraceNum = dwTraceNum; // Numero de auditoria
safRecord.dwRefNum = dwRefNum; // Numero de referencia
safRecord.cbBufferLen = cbLen; // Longitud Buffer Datos
// Buffer de Datos copiado
if(cbLen > sizeof safRecord.bBuffer) return FALSE;
memset(safRecord.bBuffer, 0, sizeof safRecord.bBuffer);
memcpy(safRecord.bBuffer, lpbBuffer, cbLen);
// Posicionarse al final del archivo
fseek(hfFile, 0L, SEEK_END);
// Escritura en si misma
cbReadWrite = (SHORT)fwrite((LPBYTE)&safRecord, 1,
sizeof safRecord, hfFile);
// Asegurar que se baje el buffer del Sistema Operativo a disco
fflush(hfFile);
// Retorno incorrecto?
if((cbReadWrite == RET_INVAL) || (cbReadWrite == 0))
return FALSE;
// Ultimo registro STORED
dwLastStdRecord = safRecord.dwRecord;
// Un Stored mas
if(dwStdRecords < ULONG_MAX) dwStdRecords++;
else return FALSE;
// Retorno correcto
return TRUE;
}
// Inicializar estadisticas
BOOL EXPORT StoreAndForward::InitStatistics(LPSTR szXFileName)
{
// Reinicio a cero de Estadisticas
dwStdRecords = 0L; // Registros STORED
dwFwdRecords = 0L; // Registros FORWARDED
dwFirstStdRecord = 0L; // Primer registro STORED
dwLastStdRecord = 0L; // Ultimo registro STORED
/////////////////////////////////////////////////////////////////
tSAFInit = time(NULL); // TimeStamp del inicio de SAF
tLastSAFCheck = 0L; // TimeStamp del ultimo chequeo SAF
/////////////////////////////////////////////////////////////////
// Precondicion
if(NULL == hfFile)
{
hfFile = _fsopen(szXFileName, "bt+");
if(NULL == hfFile)
return FALSE;
else
strcpy(szFileName, szXFileName);
}
if( NULL == szXFileName )
szXFileName = szFileName;
// Posicionarse al inicio del Archivo
fseek(hfFile, 0L, SEEK_SET);
// Lectura adelantada
cbReadWrite = fread((LPBYTE)&safRecord, 1, sizeof safRecord, hfFile);
// Ciclo de lectura
while ((cbReadWrite != 0) && (cbReadWrite != RET_INVAL))
{
// Contadores STORED/FORWARDED
if(safRecord.wState == SAF_RECSTATE_STORED)
{
// Un Stored mas
if(dwStdRecords < ULONG_MAX) dwStdRecords++;
else return FALSE;
// Primer registro STORED?
if (dwFirstStdRecord == 0L)
dwFirstStdRecord = safRecord.dwRecord;
// Ultimo registro STORED?
if (dwLastStdRecord < (DWORD)safRecord.dwRecord)
dwLastStdRecord = safRecord.dwRecord;
}
else if(safRecord.wState == SAF_RECSTATE_FORWARDED)
{
// Un Forwarded mas
if(dwFwdRecords < ULONG_MAX) dwFwdRecords++;
else return FALSE;
}
// Siguiente registro
cbReadWrite = (SHORT)fread((LPBYTE)&safRecord, 1,
sizeof safRecord, hfFile);
}
// Si los registros STORED son los mismos que los FORWARDED,
// o no hay STORED pero si FORWARDED, asegurarse de crear un
// nuevo archivo vacio de SAF, para evitar falta de espacio
// en disco, eliminando lo que ya fue FORWARDeado...
if( ( (dwStdRecords == dwFwdRecords) && (dwStdRecords > 0L) )
||
( (dwStdRecords == 0L) && (dwFwdRecords > 0L) )
)
{
// Cerrarlo, y borrarlo
Remove();
// Recrearlo , y verificar nombre archivo externo
if(szXFileName)
strcpy(szFileName,szXFileName);
return ReCreate();
}
else
// Reabrirlo
return ReOpen();
}
// Cierre
BOOL EXPORT StoreAndForward::Close()
{
// Precondicion : handle valido
if (NULL == hfFile)
return FALSE;
// Precondicion : recuperar tamano de archivo
if(NULL != hfFile)
{
fseek( hfFile, 0L, SEEK_END );
lFileSize = ftell( hfFile );
fseek( hfFile, 0L, SEEK_SET );
}
// Cierre
if (fclose(hfFile) == RET_INVAL)
return FALSE;
// Asegurar handle en NULL
hfFile = NULL;
// Retorno Ok
return TRUE;
}
// Creacion
BOOL EXPORT StoreAndForward::Create(LPSTR szXFileName)
{
// Precondicion
if(hfFile != NULL)
return FALSE;
// Formatear nombre segun el dia actual y un pseudo-random prefijado
SetTodayFileName( szXFileName, szFileName );
// Creacion
return ((hfFile = _fsopen(szXFileName, "w")) == NULL)
? FALSE
: TRUE;
}
// Contador de Stored
DWORD EXPORT StoreAndForward::StoredRecords(void) { return dwStdRecords; }
// Contador de Forwarded
DWORD EXPORT StoreAndForward::ForwardedRecords(void) { return dwFwdRecords; }
// Limite de registros
DWORD EXPORT StoreAndForward::RecordsLimit(DWORD dwNewLimit)
{
// Precondicion: mayor a Cero
return (dwNewLimit <= 0L)
? (dwLimit)
: (dwLimit = dwNewLimit);
}
// Re-Apertura, sin reinicializar Estadisticas
BOOL EXPORT StoreAndForward::ReOpen(void)
{
// Cerrarlo
Close();
// Abrirlo
return((hfFile = _fsopen(szFileName, "br+")) == NULL)
? FALSE
: TRUE ;
}
// Re-Creacion
BOOL EXPORT StoreAndForward::ReCreate(void)
{
char szLocFileName[SZSAFFNAMELEN];// Nombre adoptado local
Close();
strcpy( szLocFileName, szFileName );
return Create( szLocFileName );
}
// Liberacion de SAF
BOOL EXPORT StoreAndForward::FreeStored(void)
{
// Precondicion
if(NULL == hfFile)
return FALSE;
// Posicionarse al inicio del Archivo
fseek(hfFile, 0L, SEEK_SET);
// Leer cada SAF STORED de este producto
cbReadWrite = fread((LPBYTE)&safRecord, 1, sizeof safRecord, hfFile);
// Ciclo de Lectura
while ((cbReadWrite != 0) && (cbReadWrite != RET_INVAL))
{
// Si es STORED
if( SAF_RECSTATE_STORED == safRecord.wState )
{
// Cancelarlo
if(!SetCancelled())
return FALSE;
}
// Siguiente registro
cbReadWrite = (SHORT)fread((LPBYTE)&safRecord, 1,
sizeof safRecord, hfFile);
}
return TRUE;
}
// Ir al inicio del primer registro STORED, para leerlo luego
BOOL EXPORT StoreAndForward::SetFirstStored(void)
{
// Precondicion
if(NULL == hfFile)
return FALSE;
/////////////////////////////////////////////
// Grabar fecha-hora de este chequeo
tLastSAFCheck = time( NULL );
/////////////////////////////////////////////
if((dwFirstStdRecord == 0) || (dwFirstStdRecord == 1))
{
// Posicionarse al inicio del primer registro STORED
return (fseek(hfFile, 0L, SEEK_SET) == RET_INVAL)
? FALSE : TRUE;
}
else
{
// Posicionarse al inicio del primer registro STORED, tentativamente,
// en forma aproximada, porque no se asegura que sea el primero, pero
// si que se empieza a leer a partir de ahi en mas:
return (fseek(hfFile,
(dwFirstStdRecord-1L)*sizeof(safRecord),
SEEK_SET) == RET_INVAL)
? FALSE : TRUE;
}
}
// Nombre de archivo formateado al dia de la fecha
// Esta es la unica funcion no estandard segun Sistema Operativo en que
// se implemente, debido al formato de los nombres en el File System
BOOL EXPORT StoreAndForward::SetTodayFileName(LPCSTR pszInFName, LPSTR pszOutFName)
{
char szTempFName[SZSAFFNAMELEN];// Nombre de archivo temporal
char szTodayDate[SZSAFFNAMELEN];// Fecha ASCII de hoy
char *pszExtension = NULL; // Ptr a CharId de Extension "."
char *pszFile = NULL; // Ptr a CharId de File "\"
///////////////////////////////////////////////////////////////////////////////////////////////////
char szRandom[10] = {0}; // Nro, aleatorio en nombre, prefijado, unico por instancia SAF.
///////////////////////////////////////////////////////////////////////////////////////////////////
// Precondicion: Nombre base
if(pszInFName == NULL)
return FALSE;
// Precondicion: Extension "." presente
if((pszExtension = strrchr(pszInFName,'.')) == NULL)
pszExtension = ".saf"; // default
// Inicio del Nombre de Archivo, denotada por el ultimo "\"
pszFile = strrchr(pszInFName,'\\');
// Si no existe...
if (pszFile == NULL) pszFile = (LPSTR)pszInFName; // Inicio en 1er caracter alfabetico
else pszFile++; // sino en siguiente despues de '\'
// Fecha y Hora actuales y locales del Sistema
time_t tSystemTime = time(NULL); // System Time
tm *ptmLocalTime = localtime(&tSystemTime); // Local System Time
// Formateo ISO-YYMMDD para fecha
strftime(szTodayDate, sizeof szTodayDate, "%y%m%d", ptmLocalTime);
// Copia del Path hasta el Folder/Directorio
// Verifica longitud de nombre, asegurando "xxYYMMDD.ext"
if((pszFile-pszInFName) > (SZSAFFNAMELEN-sizeof("xxYYMMDD.ext")))
return FALSE;
// Copia del Path hasta el Folder/Directorio
strncpy(szTempFName, pszInFName, (size_t)(pszFile-pszInFName));
szTempFName[(size_t)(pszFile-pszInFName)] = 0x00;
// Si existe un Path previo, concatenar el separador de Paths:
if((size_t)(pszFile-pszInFName) != 0)
strcat(szTempFName, "\\");
// Concatenar iniciales, de MessageTracker por default
// si no hay caracteres iniciales alfabeticos en el nombre del archivo:
if( isalpha((int)(*pszFile)) && isalpha((int)(*(pszFile+1))) )
strncat(szTempFName, pszFile, 2);
else
// Concatenar prefijo por default "SA"
strcat(szTempFName, "SA");
// Concatenar formato fecha
strcat(szTempFName, szTodayDate);
///////////////////////////////////////////////////////////////
// Concatenar instancia aleatoria fija, dentro del rango 0..999
// Precondicion : Numero pseudo-random no debe ser negativo
if(bUseRandom)
{
sprintf( szRandom, ".%i", max(0,iRandomNum) );
strcat(szTempFName, szRandom);
};
///////////////////////////////////////////////////////////////
// Concatenar extension
strcat(szTempFName, pszExtension);
// Copia externa?
if(pszOutFName != NULL)
strcpy(pszOutFName, szTempFName);
// Retorno Ok
return TRUE;
}
// Esta es una funcion que retorna TRUE si se verifican ciertos parametros
// internos de la clase que indican que cierta accion es necesaria.
BOOL EXPORT StoreAndForward::IsActionRequired()
{
/* Verificar ultimos N minutos de inactividad */
if(time( NULL ) >= (tLastSAFCheck+(60*SAF_INACTIVITY_MINUTES)))
{
tLastSAFCheck = time( NULL );
/* verificar si hay registros presentes */
if ( StoredRecords() > 0 )
return TRUE;
else
/* no se requiere accion */
return FALSE;
}
/* verificar si hay mas de N registros presentes */
else if ( StoredRecords() >= SAF_RECORDS_ACTION_REQUIRED )
return TRUE;
/* sino, no se requiere accion */
else
return FALSE;
}
// Usar nombre random ? (filename.random.saf)
BOOL EXPORT StoreAndForward::UseRandomName(BOOL bUse)
{
return ( bUseRandom = bUse );
}
// Borra el archivo si corresponde
BOOL EXPORT StoreAndForward::Remove(void)
{
int iRetval = 0;
// Precondicion : recuperar tamano de archivo
if(NULL != hfFile)
{
fseek( hfFile, 0L, SEEK_END );
lFileSize = ftell( hfFile );
fseek( hfFile, 0L, SEEK_SET );
}
// Cierre de archivo
Close();
// Si no tenia ningun registro, borrar el archivo
if( 0L == dwStdRecords && 0 <= dwFwdRecords && 0L <= lFileSize )
iRetval = remove( szFileName );
// Estadisticas a cero
dwLimit = dwStdRecords = dwFwdRecords = 0L;
dwFirstStdRecord = dwLastStdRecord = 0L;
// OK
return (TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -