📄 sblog.cpp
字号:
if (! Lock( )) {
return VXIlog_RESULT_SYSTEM_ERROR;
} else {
diagCallbacks.push_back(info);
if (! Unlock( ))
return VXIlog_RESULT_SYSTEM_ERROR;
}
return VXIlog_RESULT_SUCCESS;
}
SBlogDiagCallbackData*
SBlog::UnregisterDiagnosticListener(SBlogDiagCallbackData *info)
{
if (info == NULL) {
Error(203, L"SBlog: Internal error in UnregisterDiagnosticListener(), "
L"NULL callback data", NULL);
return NULL;
}
SBlogDiagCallbackData *status = NULL;
if (! Lock( )) {
return NULL;
} else {
for (DIAGCALLBACKS::iterator i = diagCallbacks.begin();
i != diagCallbacks.end(); ++i)
{
if (*info != *(*i)) continue;
status = *i;
diagCallbacks.erase(i);
break;
}
if (! Unlock( ))
return NULL;
}
return status;
}
VXIlogResult SBlog::RegisterEventListener(SBlogEventCallbackData *info)
{
if (info == NULL) {
Error(204, L"SBlog: Internal error in RegisterEventListener(), NULL "
L"callback data", NULL);
return VXIlog_RESULT_INVALID_ARGUMENT;
}
if (! Lock( )) {
return VXIlog_RESULT_SYSTEM_ERROR;
} else {
eventCallbacks.push_back(info);
if (! Unlock( ))
return VXIlog_RESULT_SYSTEM_ERROR;
}
return VXIlog_RESULT_SUCCESS;
}
SBlogEventCallbackData*
SBlog::UnregisterEventListener(SBlogEventCallbackData *info)
{
if (info == NULL) {
Error(205, L"SBlog: Internal error in UnregisterEventListener(), NULL "
L"callback data", NULL);
return NULL;
}
SBlogEventCallbackData *status = NULL;
if (! Lock( )) {
return NULL;
} else {
for (EVENTCALLBACKS::iterator i = eventCallbacks.begin();
i != eventCallbacks.end(); ++i)
{
if (*info != *(*i)) continue;
status = *i;
eventCallbacks.erase(i);
break;
}
if (! Unlock( ))
return NULL;
}
return status;
}
VXIlogResult SBlog::RegisterContentListener(SBlogContentCallbackData *info)
{
if (info == NULL) {
Error(206, L"SBlog: Internal error in RegisterContentListener(), NULL "
L"callback data", NULL);
return VXIlog_RESULT_INVALID_ARGUMENT;
}
if (! Lock( )) {
return VXIlog_RESULT_SYSTEM_ERROR;
} else {
contentCallbacks.push_back(info);
if (! Unlock( ))
return VXIlog_RESULT_SYSTEM_ERROR;
}
return VXIlog_RESULT_SUCCESS;
}
SBlogContentCallbackData*
SBlog::UnregisterContentListener(SBlogContentCallbackData *info)
{
if (info == NULL) {
Error(207, L"SBlog: Internal error in RegisterContentListener(), NULL "
L"callback data", NULL);
return NULL;
}
SBlogContentCallbackData *status = NULL;
if (! Lock( )) {
return NULL;
} else {
for (CONTENTCALLBACKS::iterator i = contentCallbacks.begin();
i != contentCallbacks.end(); ++i)
{
if (*info != *(*i)) continue;
status = *i;
contentCallbacks.erase(i);
break;
}
if (! Unlock( ))
return NULL;
}
return status;
}
VXIlogResult SBlog::ParseKeyValue(const VXIchar *format,
va_list args,
VXIVector *keys,
VXIVector *values) const
{
const VXIchar SEP[] = L"{*}";
const int SEP_LEN = 3;
if (( format == NULL ) || ( keys == NULL ) || ( values == NULL )) {
Error(208, L"SBlog: Internal error in ParseKeyValue(), invalid argument",
NULL);
return VXIlog_RESULT_INVALID_ARGUMENT;
}
// Insert delimiters into a revised format string, this does
// validation as well as letting us split it into key/values later
VXIlogResult rc = VXIlog_RESULT_SUCCESS;
bool hadFreeformText = false;
int replacementStart = -1, fieldCount = 0;
size_t resultFormatLen = 0;
VXIchar resultFormat[MAX_LOG_BUFFER];
resultFormat[0] = L'\0';
for (int i = 0; (format[i] != L'\0') && (rc == VXIlog_RESULT_SUCCESS); i++) {
if (format[i] == '%') {
if (replacementStart > -1)
replacementStart = -1; // double %%
else
replacementStart = i;
} else if ((replacementStart > -1) && (SBlogIsAlpha(format[i])) &&
(format[i] != L'l') && (format[i] != L'L') &&
(format[i] != L'h')) {
if ((fieldCount % 2 == 0) && (format[i] != L's') &&
(format[i] != L'S')) {
// Keys must be a %s or %S, truncate from here
Error(301, L"SBlog: Invalid format string for VXIlog API call, "
L"replacements for key names must be %s", L"%s%s", L"format",
format);
rc = VXIlog_RESULT_NON_FATAL_ERROR;
} else {
// Insert the replacement expression and the seperator
size_t index = resultFormatLen;
resultFormatLen += (i - replacementStart) + 1 + SEP_LEN;
if (resultFormatLen < MAX_LOG_BUFFER) {
wcsncpy(&resultFormat[index], &format[replacementStart],
(i - replacementStart) + 1);
index += (i - replacementStart) + 1;
wcscpy(&resultFormat[index], SEP);
} else {
// Overflow, truncate the format string from here
rc = VXIlog_RESULT_NON_FATAL_ERROR;
}
replacementStart = -1;
fieldCount++;
}
} else if (replacementStart == -1) {
// Shouldn't have free-form text, skip it. Proceeding allows us
// to gracefully handle things like "%s0x%p".
hadFreeformText = true;
}
}
// if key/value is not even truncate the field and return an error,
// but proceed with the other fields. If there was free form text,
// we skipped it and return an error, but proceed with logging.
if (fieldCount % 2 != 0) {
Error(302, L"SBlog: Invalid format string for VXIlog API call, "
L"missing value for a key", L"%s%s", L"format", format);
rc = VXIlog_RESULT_NON_FATAL_ERROR;
fieldCount--;
} else if (hadFreeformText) {
Error(303, L"SBlog: Invalid format string for VXIlog API call, "
L"must be a list of format strings for key/value pairs",
L"%s%s", L"format", format);
rc = VXIlog_RESULT_NON_FATAL_ERROR;
}
// get the values
VXIchar result[MAX_LOG_BUFFER];
result[0] = L'\0';
SBlogVswprintf(result, MAX_LOG_BUFFER-1, resultFormat, args);
// parse the key/value based on the inserted separators
long fieldNum = 0;
const VXIchar *start = result, *end;
while ((fieldNum < fieldCount) && ((end = wcsstr(start, SEP)) != NULL)) {
// Insert into key/value vector
fieldNum++;
if (fieldNum % 2) // odd is key
VXIVectorAddElement(keys,(VXIValue*)VXIStringCreateN(start,end-start));
else
VXIVectorAddElement(values,(VXIValue*)VXIStringCreateN(start,end-start));
// Advance
start = &end[SEP_LEN];
}
if (fieldNum != fieldCount) {
// parse error
Error(304, L"SBlog: Internal error, parse failure after key/value "
L"insertions", L"%s%s%s%s", L"format", format, L"result", result);
rc = VXIlog_RESULT_NON_FATAL_ERROR;
}
return rc;
}
VXIlogResult SBlog::Error(VXIunsigned errorID, const VXIchar *errorIDText,
const VXIchar *format, ...) const
{
VXIlogResult rc = VXIlog_RESULT_SUCCESS;
// Avoid recursively reporting logging errors
if (_internalErrorLoggingThread == GetThreadID())
return VXIlog_RESULT_FAILURE;
if (VXItrdMutexLock(_internalErrorLoggingLock) != VXItrd_RESULT_SUCCESS) {
return VXIlog_RESULT_SYSTEM_ERROR;
} else {
VXIthreadID *loggingThread =
const_cast<VXIthreadID *>(&_internalErrorLoggingThread);
*loggingThread = GetThreadID();
va_list args;
va_start(args, format);
rc = ErrorLog(MODULE_NAME, errorID, format, args);
if ( rc != VXIlog_RESULT_SUCCESS )
SBlogVLogErrorToConsole(MODULE_NAME, errorID, errorIDText, format, args);
va_end(args);
*loggingThread = (VXIthreadID) -1;
if (VXItrdMutexUnlock(_internalErrorLoggingLock) != VXItrd_RESULT_SUCCESS)
return VXIlog_RESULT_SYSTEM_ERROR;
}
return rc;
}
VXIlogResult SBlog::GlobalError(VXIunsigned errorID,
const VXIchar *errorIDText,
const VXIchar *format, ...)
{
va_list args;
va_start(args, format);
VXIlogResult rc = SBlogVLogErrorToConsole(MODULE_NAME, errorID, errorIDText,
format, args);
va_end(args);
return rc;
}
bool SBlog::DiagnosticIsEnabled(VXIunsigned tagID)
{
VXIunsigned bindex, bpos;
if (!Convert2Index(tagID, &bindex, &bpos))
return false;
// if this tag is not turned on, just return
if (!testbit(_tagIDs[bindex],bpos))
return false;
return true;
}
VXIlogResult SBlog::DiagnosticLog(VXIunsigned tagID,
const VXIchar* subtag,
const VXIchar* format,
va_list arguments) const
{
VXIunsigned bindex, bpos;
if (!Convert2Index(tagID, &bindex, &bpos))
return VXIlog_RESULT_INVALID_ARGUMENT;
// if this tag is not turned on, just return
if (!testbit(_tagIDs[bindex],bpos))
return VXIlog_RESULT_SUCCESS;
time_t timestamp;
VXIunsigned timestampMsec;
SBlogGetTime (×tamp, ×tampMsec);
wchar_t printmsg[MAX_LOG_BUFFER];
printmsg[0] = L'\0';
if (format != NULL)
SBlogVswprintf(printmsg, MAX_LOG_BUFFER-1, format, arguments);
if (subtag == NULL)
subtag = L"";
// Get a temporary callback vector copy to traverse, allows
// listeners to unregister from within the listener, also increases
// parallelism by allowing multiple threads to be calling the
// callbacks at once
VXIlogResult rc = VXIlog_RESULT_FAILURE;
if (! Lock( )) {
return VXIlog_RESULT_SYSTEM_ERROR;
} else {
DIAGCALLBACKS tempDiag = diagCallbacks;
if (! Unlock( ))
return VXIlog_RESULT_SYSTEM_ERROR;
for (DIAGCALLBACKS::iterator i = tempDiag.begin(); i != tempDiag.end();++i)
{
(*i)->callback(_pThis, tagID, subtag, timestamp, timestampMsec,
printmsg, (*i)->userdata);
rc = VXIlog_RESULT_SUCCESS;
}
}
return rc;
}
VXIlogResult SBlog::EventLog(VXIunsigned eventID,
const VXIchar* format,
va_list args) const
{
time_t timestamp;
VXIunsigned timestampMsec;
SBlogGetTime (×tamp, ×tampMsec);
// Create key/value pairs
VXIVector *keys = VXIVectorCreate();
VXIVector *values = VXIVectorCreate();
if ((! keys) || (! values)) {
Error(SBLOG_ERR_OUT_OF_MEMORY);
return VXIlog_RESULT_OUT_OF_MEMORY;
}
VXIlogResult rc = VXIlog_RESULT_SUCCESS;
if (format) {
rc = ParseKeyValue(format, args, keys, values);
if (rc < VXIlog_RESULT_SUCCESS) {
VXIVectorDestroy(&keys);
VXIVectorDestroy(&values);
return rc;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -