📄 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. * ***********************************************************************/ static const char *rcsid = 0 ? (char *) &rcsid : "$Id: SBlog.cpp,v 1.23.2.4 2003/10/22 17:37:59 mpanacci 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() #ifdef __THREADED #include "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; } 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) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -