📄 rvloglistener.c
字号:
/* Copy the message to the pending buffer */
memcpy(winInfo->bufferedMessages + winInfo->curUsedBufSize, logMessage, logMessageSize);
winInfo->curUsedBufSize += logMessageSize;
RvLockRelease(&winInfo->lock);
/* Send indication that we have a pending message */
PostMessage(winInfo->hWnd, LOGWND_PENDING, 0, 0);
}
#endif
/********************************************************************************************
* logPrintDebug
*
* purpose : Callback that is executed whenever a message has to be logged to debug
* input : logRecord - Information related with the logged message
* userData - NULL
* output : None
* return : None
********************************************************************************************/
static void RVCALLCONV logPrintDebug(
IN RvLogRecord* logRecord,
IN void* userData)
{
RvChar* logMessage;
RvUint32 logMessageSize;
RV_UNUSED_ARG(userData);
logMessage = logFormatMessage(logRecord, &logMessageSize);
logMessage[logMessageSize] = '\n';
logMessage[logMessageSize+1] = '\0';
RvOutputDebugPrintf(logMessage);
logMessage[logMessageSize] = '\0';
}
#endif /* (RV_LOGLISTENER_TYPE == RV_LOGLISTENER_WIN32) */
/********************************************************************************************
* logListenerConstruct
*
* purpose : Construct a generic log listener
* input : listener - Listener to construct
* logMgr - Log manager to listen to
* printCb - Callback for message logs
* userData - User data to use
* type - Type of listener
* output : None.
* return : RV_OK on success, other values on failure
********************************************************************************************/
static RvStatus logListenerConstruct(
IN RvLogListener* listener,
IN RvLogMgr* logMgr,
IN RvLogPrintCb printCb,
IN void* userData,
IN int type)
{
#ifdef RV_NULLCHECK
if ((listener == NULL) || (logMgr == NULL))
return RvLogListenerErrorCode(RV_ERROR_NULLPTR);
#endif
if (rvListenerUsed[type])
return RvLogListenerErrorCode(RV_ERROR_UNKNOWN);
listener->logMgr = logMgr;
listener->listenerType = type;
return RvLogRegisterListener(logMgr, printCb, userData);
}
#endif /* (RV_LOGLISTENER_TYPE != RV_LOGLISTENER_NONE) */
/********************************************************************************************
*
* Public functions
*
********************************************************************************************/
RvStatus RvLogListenerInit(void)
{
memset(rvListenerUsed, 0, sizeof(rvListenerUsed));
return RV_OK;
}
RvStatus RvLogListenerEnd(void)
{
return RV_OK;
}
#if (RV_LOGLISTENER_TYPE != RV_LOGLISTENER_NONE)
/* Make sure we have the internal listeners set */
/********************************************************************************************
* RvLogListenerConstructTerminal
*
* purpose : Construct a log listener that sends log messages to the terminal, using
* standard output or standard error
* input : listener - Listener to construct
* logMgr - Log manager to listen to
* stdOut - RV_TRUE for stdout, RV_FALSE for stderr
* output : None.
* return : RV_OK on success, other values on failure
********************************************************************************************/
RVCOREAPI
RvStatus RVCALLCONV RvLogListenerConstructTerminal(
IN RvLogListener* listener,
IN RvLogMgr* logMgr,
IN RvBool stdOut)
{
FILE* termStream;
if (stdOut)
termStream = stdout;
else
termStream = stderr;
return logListenerConstruct(listener, logMgr, logPrintTerminal, termStream, RV_LOGLISTENER_TYPE_TERMINAL);
}
/********************************************************************************************
* RvLogListenerDestructTerminal
*
* purpose : Destruct the terminal listener
* input : listener - Listener to destruct
* output : None.
* return : RV_OK on success, other values on failure
********************************************************************************************/
RVCOREAPI
RvStatus RVCALLCONV RvLogListenerDestructTerminal(
IN RvLogListener* listener)
{
return RvLogUnregisterListener(listener->logMgr, logPrintTerminal);
}
/********************************************************************************************
* RvLogListenerConstructLogfile
*
* purpose : Construct a log listener that sends log messages to a file
* input : listener - Listener to construct
* logMgr - Log manager to listen to
* fileName - Name of the logfile
* numFiles - Number of cyclic files to use
* fileSize - Size of each file in cycle in bytes
* This parameter is only applicable if numFiles > 1
* flushEachMessage - RV_TRUE if we want to flush each message written to the
* logfile
* output : None.
* return : RV_OK on success, other values on failure
********************************************************************************************/
RVCOREAPI
RvStatus RVCALLCONV RvLogListenerConstructLogfile(
IN RvLogListener* listener,
IN RvLogMgr* logMgr,
IN const RvChar* fileName,
IN RvUint32 numFiles,
IN RvUint32 fileSize,
IN RvBool flushEachMessage)
{
#if ((RV_LOGLISTENER_TYPE == RV_LOGLISTENER_WIN32) || \
(RV_LOGLISTENER_TYPE == RV_LOGLISTENER_FILE_AND_TERMINAL))
RvStatus ret;
ret = logListenerConstruct(listener, logMgr, logPrintLogfile, &rvLogFileListener, RV_LOGLISTENER_TYPE_LOGFILE);
if (ret == RV_OK)
{
if (numFiles == 0) numFiles = 1;
if (((fileSize != 0) || (numFiles > 1)) && (fileSize < 100000)) fileSize = 100000;
strncpy(rvLogFileListener.baseFilename, fileName, sizeof(rvLogFileListener.baseFilename)-10);
rvLogFileListener.numFiles = numFiles;
rvLogFileListener.maxFileSize = fileSize;
rvLogFileListener.flushLines = flushEachMessage;
rvLogFileListener.curFileNum = numFiles;
rvLogFileListener.curSize = 0;
rvLogFileListener.openError = RV_FALSE;
rvLogFileListener.openedFile = NULL;
}
return ret;
#else
RV_UNUSED_ARG(listener);
RV_UNUSED_ARG(logMgr);
RV_UNUSED_ARG(fileName);
RV_UNUSED_ARG(numFiles);
RV_UNUSED_ARG(fileSize);
RV_UNUSED_ARG(flushEachMessage);
return RvLogListenerErrorCode(RV_ERROR_NOTSUPPORTED);
#endif /* ((RV_LOGLISTENER_TYPE == RV_LOGLISTENER_WIN32) || \
(RV_LOGLISTENER_TYPE == RV_LOGLISTENER_FILE_AND_TERMINAL)) */
}
/********************************************************************************************
* RvLogListenerLogfileGetCurrentFilename
*
* purpose : Get the filename of the current file being written.
* input : listener - Listener to check
* fileNameLength - Maximum length of filename
* output : fileName - Filename of the current file being written
* return : RV_OK on success, other values on failure
********************************************************************************************/
RVCOREAPI
RvStatus RVCALLCONV RvLogListenerLogfileGetCurrentFilename(
IN RvLogListener* listener,
IN RvUint32 fileNameLength,
OUT RvChar* fileName)
{
RV_UNUSED_ARG(listener);
#if (RV_LOGLISTENER_TYPE == RV_LOGLISTENER_WIN32) || (RV_LOGLISTENER_TYPE == RV_LOGLISTENER_FILE_AND_TERMINAL)
#if defined(RV_NULLCHECK)
if (fileName == NULL)
return RvLogListenerErrorCode(RV_ERROR_NULLPTR);
#endif
if (fileNameLength < strlen(rvLogFileListener.baseFilename) + 5)
return RvLogListenerErrorCode(RV_ERROR_OUTOFRANGE);
if (rvLogFileListener.numFiles > 1)
RvSprintf(fileName, "%s%.4d", rvLogFileListener.baseFilename, rvLogFileListener.curFileNum);
else
strcpy(fileName, rvLogFileListener.baseFilename);
return RV_OK;
#else
RV_UNUSED_ARG(fileNameLength);
RV_UNUSED_ARG(fileName);
return RvLogListenerErrorCode(RV_ERROR_NOTSUPPORTED);
#endif
}
/********************************************************************************************
* RvLogListenerDestructLogfile
*
* purpose : Destruct the logfile listener
* input : listener - Listener to destruct
* output : None.
* return : RV_OK on success, other values on failure
********************************************************************************************/
RVCOREAPI
RvStatus RVCALLCONV RvLogListenerDestructLogfile(
IN RvLogListener* listener)
{
#if (RV_LOGLISTENER_TYPE == RV_LOGLISTENER_WIN32)
if (rvLogFileListener.openedFile != INVALID_HANDLE_VALUE)
CloseHandle(rvLogFileListener.openedFile);
#elif (RV_LOGLISTENER_TYPE == RV_LOGLISTENER_FILE_AND_TERMINAL)
if (rvLogFileListener.openedFile != NULL)
fclose(rvLogFileListener.openedFile);
#endif
#if (RV_LOGLISTENER_TYPE == RV_LOGLISTENER_WIN32) || (RV_LOGLISTENER_TYPE == RV_LOGLISTENER_FILE_AND_TERMINAL)
return RvLogUnregisterListener(listener->logMgr, logPrintLogfile);
#else
RV_UNUSED_ARG(listener);
return RvLogListenerErrorCode(RV_ERROR_NOTSUPPORTED);
#endif
}
/********************************************************************************************
* RvLogListenerConstructDebug
*
* purpose : Construct a log listener that sends log messages to the debug window of
* Visual C.
* input : listener - Listener to construct
* logMgr - Log manager to listen to
* output : None.
* return : RV_OK on success, other values on failure
* remarks : This one is only applicable for Win32 applications.
********************************************************************************************/
RVCOREAPI
RvStatus RVCALLCONV RvLogListenerConstructDebug(
IN RvLogListener* listener,
IN RvLogMgr* logMgr)
{
#if (RV_LOGLISTENER_TYPE == RV_LOGLISTENER_WIN32)
return logListenerConstruct(listener, logMgr, logPrintDebug, NULL, RV_LOGLISTENER_TYPE_DEBUG);
#else
RV_UNUSED_ARG(listener);
RV_UNUSED_ARG(logMgr);
return RvLogListenerErrorCode(RV_ERROR_NOTSUPPORTED);
#endif
}
/********************************************************************************************
* RvLogListenerDestructDebug
*
* purpose : Destruct the debug listener
* input : listener - Listener to destruct
* output : None.
* return : RV_OK on success, other values on failure
********************************************************************************************/
RVCOREAPI
RvStatus RVCALLCONV RvLogListenerDestructDebug(
IN RvLogListener* listener)
{
#if (RV_LOGLISTENER_TYPE == RV_LOGLISTENER_WIN32)
return RvLogUnregisterListener(listener->logMgr, logPrintDebug);
#else
RV_UNUSED_ARG(listener);
return RvLogListenerErrorCode(RV_ERROR_NOTSUPPORTED);
#endif
}
#endif /* (RV_LOGLISTENER_TYPE != RV_LOGLISTENER_NONE) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -