📄 sblog.cpp
字号:
/****************License************************************************
*
* Copyright 2000-2003. ScanSoft, Inc.
*
* Use of this software is subject to notices and obligations set forth
* in the SpeechWorks Public License - Software Version 1.2 which is
* included with this software.
*
* ScanSoft is a registered trademark of ScanSoft, Inc., and OpenSpeech,
* SpeechWorks and the SpeechWorks logo are registered trademarks or
* trademarks of SpeechWorks International, Inc. in the United States
* and other countries.
*
***********************************************************************/
#include <vxibuildopts.h>
#if P_VXI
static const char *rcsid = 0 ? (char *) &rcsid :
"$Id: SBlog.cpp,v 1.1 2007/06/04 16:10:49 joegenbaclor Exp $";
// -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8
#include "SBlogInternal.h"
#include <cstring> // For memset()
#include <ctime> // For time_t
#include <vector> // For STL vector template class
#define SBLOG_EXPORTS
#include "SBlog.h" // Header for these functions
#include "SBlogOSUtils.h" // for SBlogGetTime(), SBlogVswprintf()
#define __THREADED
#ifdef __THREADED
#include "vxi/VXItrd.h" // for VXItrdMutex
#endif
static const VXIunsigned MAX_LOG_BUFFER = 4096 * 2;
static const VXIunsigned TAG_ARRAY_SIZE = (((SBLOG_MAX_TAG) + 1) / 8 + 1);
#define SBLOG_ERR_OUT_OF_MEMORY 100, L"SBlog: Out of memory", NULL
#define SBLOG_ERR_ALREADY_INITIALIZED 104, L"SBlog: Already initialized", NULL
#define SBLOG_ERR_NOT_INITIALIZED 105, L"SBlog: Not initialized", NULL
#ifndef MODULE_PREFIX
#define MODULE_PREFIX COMPANY_DOMAIN L"."
#endif
#define MODULE_NAME MODULE_PREFIX L"SBlog"
// Global variable to track whether this is initialized
static bool gblInitialized = false;
struct myAPI {
SBlogInterface intf;
void *impl_;
};
struct SBlogErrorCallbackData {
SBlogErrorListener *callback;
void *userdata;
bool operator==(struct SBlogErrorCallbackData &other)
{ return (callback == other.callback && userdata == other.userdata); }
bool operator!=(struct SBlogErrorCallbackData &other)
{ return !operator==(other); }
};
struct SBlogDiagCallbackData {
SBlogDiagnosticListener *callback;
void *userdata;
bool operator==(struct SBlogDiagCallbackData &other)
{ return (callback == other.callback && userdata == other.userdata); }
bool operator!=(struct SBlogDiagCallbackData &other)
{ return !operator==(other); }
};
struct SBlogEventCallbackData{
SBlogEventListener *callback;
void *userdata;
bool operator==(struct SBlogEventCallbackData &other)
{ return (callback == other.callback && userdata == other.userdata); }
bool operator!=(struct SBlogEventCallbackData &other)
{ return !operator==(other); }
};
struct SBlogContentCallbackData{
SBlogContentListener *callback;
void *userdata;
bool operator==(struct SBlogContentCallbackData &other)
{ return (callback == other.callback && userdata == other.userdata); }
bool operator!=(struct SBlogContentCallbackData &other)
{ return !operator==(other); }
};
// Our definition of the opaque VXIlogStream
extern "C" {
struct VXIlogStream {
// Linked list of underlying SBlogListener content streams
typedef std::vector<SBlogStream *> STREAMS;
STREAMS streams;
};
}
class SBlog {
public:
SBlog(SBlogInterface *pThis);
virtual ~SBlog();
bool DiagnosticIsEnabled(VXIunsigned tagID);
VXIlogResult DiagnosticLog(VXIunsigned tagID,
const VXIchar* subtag,
const VXIchar* format,
va_list arguments) const;
VXIlogResult EventLog(VXIunsigned eventID,
const VXIchar* format,
va_list arguments) const;
VXIlogResult EventLog(VXIunsigned eventID,
const VXIVector* keys,
const VXIVector* values) const;
VXIlogResult ErrorLog(const VXIchar* moduleName,
VXIunsigned errorID,
const VXIchar* format,
va_list arguments) const;
VXIlogResult ContentOpen(const VXIchar* moduleName,
const VXIchar* contentType,
VXIString** logKey,
VXIString** logValue,
VXIlogStream** stream) const;
VXIlogResult ContentClose(VXIlogStream** stream) const;
VXIlogResult ContentWrite(const VXIbyte* buffer,
VXIulong buflen,
VXIulong* nwritten,
VXIlogStream* stream) const;
VXIlogResult ControlDiagnosticTag(VXIunsigned tagID,
VXIbool state);
// ----- Register/Unregister callback functions
VXIlogResult RegisterErrorListener(SBlogErrorCallbackData *info);
SBlogErrorCallbackData*
UnregisterErrorListener(SBlogErrorCallbackData *info);
VXIlogResult RegisterDiagnosticListener(SBlogDiagCallbackData *info);
SBlogDiagCallbackData*
UnregisterDiagnosticListener(SBlogDiagCallbackData *info);
VXIlogResult RegisterEventListener(SBlogEventCallbackData *info);
SBlogEventCallbackData*
UnregisterEventListener(SBlogEventCallbackData *info);
VXIlogResult RegisterContentListener(SBlogContentCallbackData *info);
SBlogContentCallbackData*
UnregisterContentListener(SBlogContentCallbackData *info);
// ----- Internal error logging functions
VXIlogResult Error(VXIunsigned errorID, const VXIchar *errorIDText,
const VXIchar *format, ...) const;
static VXIlogResult GlobalError(VXIunsigned errorID,
const VXIchar *errorIDText,
const VXIchar *format, ...);
private:
// Internal methods
static unsigned testbit(unsigned char num, int bitpos);
static void setbit(unsigned char *num, int bitpos);
static void clearbit(unsigned char *num, int bitpos);
bool Convert2Index(VXIunsigned tagID,
VXIunsigned *index,
VXIunsigned *bit_pos) const;
VXIlogResult ParseKeyValue(const VXIchar *format,
va_list args,
VXIVector *keys,
VXIVector *values) const;
#ifdef __THREADED
inline bool Lock( ) const {
bool rc = (VXItrdMutexLock(_callbackLock) == VXItrd_RESULT_SUCCESS);
if (! rc) Error(102, L"SBlog: Mutex lock failed", NULL);
return rc;
}
inline bool Unlock( ) const {
bool rc = (VXItrdMutexUnlock(_callbackLock) == VXItrd_RESULT_SUCCESS);
if (! rc) Error(103, L"SBlog: Mutex unlock failed", NULL);
return rc;
}
inline VXIthreadID GetThreadID( ) const {
return VXItrdThreadGetID();
}
#else
inline bool Lock( ) const { return true; }
inline bool Unlock( ) const { return true; }
inline VXIthreadID GetThreadID( ) const { return (VXIthreadID) 1; }
#endif
private:
typedef std::vector<SBlogDiagCallbackData *> DIAGCALLBACKS;
DIAGCALLBACKS diagCallbacks;
typedef std::vector<SBlogErrorCallbackData *> ERRORCALLBACKS;
ERRORCALLBACKS errorCallbacks;
typedef std::vector<SBlogEventCallbackData *> EVENTCALLBACKS;
EVENTCALLBACKS eventCallbacks;
typedef std::vector<SBlogContentCallbackData *> CONTENTCALLBACKS;
CONTENTCALLBACKS contentCallbacks;
#ifdef __THREADED
VXItrdMutex *_callbackLock;
VXItrdMutex *_internalErrorLoggingLock;
#endif
SBlogInterface *_pThis;
VXIthreadID _internalErrorLoggingThread;
unsigned char _tagIDs[TAG_ARRAY_SIZE];
};
SBlog::SBlog(SBlogInterface *pThis) :
#ifdef __THREADED
_callbackLock(NULL),
_internalErrorLoggingLock(NULL),
#endif
_pThis(pThis),
_internalErrorLoggingThread((VXIthreadID) -1)
{
// reset TAG ID range
memset(_tagIDs, 0, TAG_ARRAY_SIZE);
#ifdef __THREADED
// Create the mutexes
if ((VXItrdMutexCreate(&_callbackLock) != VXItrd_RESULT_SUCCESS) ||
(VXItrdMutexCreate(&_internalErrorLoggingLock) != VXItrd_RESULT_SUCCESS))
Error(101, L"OSBlog: Mutex create failed", NULL);
#endif
}
SBlog::~SBlog()
{
#ifdef __THREADED
// Destroy the mutexes
VXItrdMutexDestroy(&_callbackLock);
VXItrdMutexDestroy(&_internalErrorLoggingLock);
#endif
}
/**
* testbit
* testbit returns the value of the given bit
* 1 is set, 0 is clear
*/
unsigned SBlog::testbit(unsigned char num, int bitpos)
{
return (num >> bitpos) & ~(~0 << 1);
}
/**
* setbit sets a given bit
*/
void SBlog::setbit(unsigned char *num, int bitpos)
{
*num |= (1 << bitpos);
}
/**
* clearbit clears a given bit
*/
void SBlog::clearbit(unsigned char *num, int bitpos)
{
*num &= ~(1 << bitpos);
}
bool SBlog::Convert2Index(VXIunsigned tagID,
VXIunsigned *index,
VXIunsigned *bit_pos) const
{
// check for overflow TAG ID
if (tagID > SBLOG_MAX_TAG) {
Error(300, L"SBlog: Tag ID is too large", L"%s%u", L"tagID", tagID);
return false;
}
// retrieving index for char array
*index = tagID/8; // 8 bits per char
// retrieving bit position (bit range from 0-7)
*bit_pos = tagID%8;
return true; // done
}
VXIlogResult SBlog::ControlDiagnosticTag(VXIunsigned tagID,
VXIbool state)
{
VXIunsigned bindex, bpos;
if(!Convert2Index(tagID, &bindex, &bpos))
return VXIlog_RESULT_INVALID_ARGUMENT;
if(state)
setbit(&_tagIDs[bindex], bpos);
else
clearbit(&_tagIDs[bindex], bpos);
return VXIlog_RESULT_SUCCESS;
}
VXIlogResult SBlog::RegisterErrorListener(SBlogErrorCallbackData *info)
{
if (info == NULL) {
Error(200, L"SBlog: Internal error in RegisterErrorListener(), NULL "
L"callback data", NULL);
return VXIlog_RESULT_INVALID_ARGUMENT;
}
if (! Lock( )) {
return VXIlog_RESULT_SYSTEM_ERROR;
} else {
errorCallbacks.push_back(info);
if (! Unlock( ))
return VXIlog_RESULT_SYSTEM_ERROR;
}
return VXIlog_RESULT_SUCCESS;
}
SBlogErrorCallbackData*
SBlog::UnregisterErrorListener(SBlogErrorCallbackData *info)
{
if (info == NULL) {
Error(201, L"SBlog: Internal error in UnregisterErrorListener(), NULL "
L"callback data", NULL);
return NULL;
}
SBlogErrorCallbackData *status = NULL;
if (! Lock( )) {
return NULL;
} else {
for (ERRORCALLBACKS::iterator i = errorCallbacks.begin();
i != errorCallbacks.end(); ++i)
{
if (*info != *(*i)) continue;
status = *i;
errorCallbacks.erase(i);
break;
}
if (! Unlock( ))
return NULL;
}
return status;
}
VXIlogResult SBlog::RegisterDiagnosticListener(SBlogDiagCallbackData *info)
{
if (info == NULL) {
Error(202, L"SBlog: Internal error in RegisterDiagnosticListener(), NULL "
L"callback data", NULL);
return VXIlog_RESULT_INVALID_ARGUMENT;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -