From 73aa65fabd76d3f76b33e51b8a7e4c3a4bc92b46 Mon Sep 17 00:00:00 2001 From: ahodgkinson Date: Thu, 1 Jun 2006 19:42:56 +0000 Subject: [PATCH] Added a few more routines required to port FLAIM to FTK. git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@497 0109f412-320b-0410-ab79-c3e0c5ffbbe6 --- ftk/src/ftk.h | 100 ++++- ftk/src/ftkcoll.cpp | 87 +++-- ftk/src/ftkfsys.cpp | 79 ++++ ftk/src/ftkftx.cpp | 494 ++++++++++++++++++++--- ftk/src/ftklock.cpp | 4 +- ftk/src/ftklog.cpp | 924 ++++++++++++++++++++++++++++++++++++++++++++ ftk/src/ftkmisc.cpp | 28 +- ftk/src/ftkrset.cpp | 2 +- ftk/src/ftktext.cpp | 29 ++ ftk/src/ftkthrd.cpp | 17 + 10 files changed, 1660 insertions(+), 104 deletions(-) diff --git a/ftk/src/ftk.h b/ftk/src/ftk.h index 0adc75a..dfe6838 100644 --- a/ftk/src/ftk.h +++ b/ftk/src/ftk.h @@ -3276,6 +3276,10 @@ FLMUINT FLMAPI f_strlen( const char * pszStr); + + RCODE FLMAPI f_strdup( + const char * pszSrc, + char ** ppszDup); RCODE FLMAPI f_getCharFromUTF8Buf( const FLMBYTE ** ppucBuf, @@ -3530,14 +3534,14 @@ FLM_SLAB_USAGE * pUsageStats) = 0; virtual void * FLMAPI allocCell( - IF_Relocator * pRelocator, + IF_Relocator * pRelocator = NULL, void * pvInitialData = NULL, FLMUINT uiDataSize = 0, FLMBOOL bMutexLocked = FALSE) = 0; virtual void FLMAPI freeCell( void * ptr, - FLMBOOL bMutexLocked) = 0; + FLMBOOL bMutexLocked = FALSE) = 0; virtual void FLMAPI freeUnused( void) = 0; @@ -4345,7 +4349,7 @@ virtual FLMBOOL FLMAPI setLockCount( // Return TRUE to continue, FALSE to stop FLMUINT uiTotalLocks) = 0; - virtual FLMBOOL FLMAPI addLockInfo( // Return TRUE to continue, FALSE to stop + virtual FLMBOOL FLMAPI addLockInfo( // Return TRUE to continue, FALSE to stop FLMUINT uiLockNum, // Position in queue (0 = lock holder, // 1 ... n = lock waiter) FLMUINT uiThreadID, // Thread ID of the lock holder/waiter @@ -4401,10 +4405,10 @@ FLMINT iPriority, eLockType * peCurrLockType, FLMUINT * puiThreadId, - FLMUINT * puiNumExclQueued, - FLMUINT * puiNumSharedQueued, - FLMUINT * puiPriorityCount) = 0; - + FLMUINT * puiNumExclQueued = NULL, + FLMUINT * puiNumSharedQueued = NULL, + FLMUINT * puiPriorityCount = NULL) = 0; + virtual RCODE FLMAPI getLockInfo( IF_LockInfoClient * pLockInfo) = 0; @@ -4505,6 +4509,22 @@ return( TRUE); } + FINLINE FLMUINT64 f_roundUp( + FLMUINT64 ui64ValueToRound, + FLMUINT64 ui64Boundary) + { + FLMUINT64 ui64RetVal; + + ui64RetVal = ((ui64ValueToRound / ui64Boundary) * ui64Boundary); + + if( ui64RetVal < ui64ValueToRound) + { + ui64RetVal += ui64Boundary; + } + + return( ui64RetVal); + } + RCODE FLMAPI f_filecpy( const char * pszSourceFile, const char * pszData); @@ -4512,7 +4532,11 @@ RCODE FLMAPI f_filecat( const char * pszSourceFile, const char * pszData); - + + RCODE FLMAPI f_filetobuf( + const char * pszSourceFile, + char ** ppszBuffer); + /**************************************************************************** Desc: FTX ****************************************************************************/ @@ -4992,6 +5016,66 @@ void FLMAPI FTXBeep( void); + RCODE FLMAPI f_conInit( + FLMUINT uiRows, + FLMUINT uiCols, + const char * pszTitle); + + void FLMAPI f_conExit( void); + + void FLMAPI f_conGetScreenSize( + FLMUINT * puiNumColsRV, + FLMUINT * puiNumRowsRV); + + void FLMAPI f_conDrawBorder( void); + + void FLMAPI f_conStrOut( + const char * pszString); + + void FLMAPI f_conStrOutXY( + const char * pszString, + FLMUINT uiCol, + FLMUINT uiRow); + + void FLMAPI f_conPrintf( + const char * pszFormat, ...); + + void FLMAPI f_conCPrintf( + eColorType back, + eColorType fore, + const char * pszFormat, ...); + + void FLMAPI f_conClearScreen( + FLMUINT uiCol, + FLMUINT uiRow); + + void FLMAPI f_conClearLine( + FLMUINT uiCol, + FLMUINT uiRow); + + void FLMAPI f_conSetBackFore( + eColorType backColor, + eColorType foreColor); + + FLMUINT FLMAPI f_conGetCursorColumn( void); + + FLMUINT FLMAPI f_conGetCursorRow( void); + + void FLMAPI f_conSetCursorType( + FLMUINT uiType); + + void FLMAPI f_conSetCursorPos( + FLMUINT uiCol, + FLMUINT uiRow); + + FLMUINT FLMAPI f_conGetKey( void); + + FLMBOOL FLMAPI f_conHaveKey( void); + + FLMUINT FLMAPI f_conLineEdit( + char * pszString, + FLMUINT uiMaxLen); + /**************************************************************************** Desc: ****************************************************************************/ diff --git a/ftk/src/ftkcoll.cpp b/ftk/src/ftkcoll.cpp index ed3f61a..27db7c9 100644 --- a/ftk/src/ftkcoll.cpp +++ b/ftk/src/ftkcoll.cpp @@ -345,7 +345,7 @@ static FLMUINT gv_uiMaxWPChar = 0; /**************************************************************************** Desc: Table of # of characters in each character set ****************************************************************************/ -FLMBYTE fwp_c60_max[] = +static FLMBYTE fwp_c60_max[] = { ASC_N, // ascii ML1_N, // multinational 1 @@ -375,7 +375,7 @@ Notes: In the following table, the bits are numbered from left EX. 00000000b ;0-7 bit# 01234567 ****************************************************************************/ -FLMBYTE fwp_ml1_cb60[] = +static FLMBYTE fwp_ml1_cb60[] = { 0x00, // 0-7 0x00, // 8-15 @@ -419,7 +419,7 @@ Desc: Format of index: Notes: Diacritical char is always in same set as composed char base is in same set if other table indicates, else in ASCII ****************************************************************************/ -BASE_DIACRIT_TABLE fwp_ml1c_table[] = +static BASE_DIACRIT_TABLE fwp_ml1c_table[] = { {'A',acute}, {'a',acute}, @@ -642,7 +642,7 @@ BASE_DIACRIT_TABLE fwp_ml1c_table[] = /**************************************************************************** Desc: ****************************************************************************/ -BASE_DIACRIT fwp_ml1c = +static BASE_DIACRIT fwp_ml1c = { 216, // # of characters in table 26, // start char @@ -844,7 +844,7 @@ Desc: Format of index: Notes: Diacritical char is always in same set as composed char base is in same set ****************************************************************************/ -static BASE_DIACRIT_TABLE fwp_rus_c_table[] = +static BASE_DIACRIT_TABLE fwp_rus_c_table[] = { { 14, 204 }, // ZHE with right descender { 15, 204 }, // zhe with right descender @@ -981,7 +981,7 @@ static BASE_DIACRIT fwp_rus_c = /**************************************************************************** Desc: Table of pointers to character component tables. ****************************************************************************/ -BASE_DIACRIT * fwp_car60_c[ NCHSETS] = +static BASE_DIACRIT * fwp_car60_c[ NCHSETS] = { (BASE_DIACRIT*)0, // no composed characters for ascii. &fwp_ml1c, @@ -1003,7 +1003,7 @@ BASE_DIACRIT * fwp_car60_c[ NCHSETS] = /**************************************************************************** Desc: Map special chars in CharSet (x24) to collation values ****************************************************************************/ -BYTE_WORD_TBL fwp_Ch24ColTbl[] = // Position in the table+1 is subColValue +static BYTE_WORD_TBL fwp_Ch24ColTbl[] = { {1, COLLS+2}, // comma {2, COLLS+1}, // maru @@ -1038,7 +1038,7 @@ Notes: the subcollation area. The original table is listed below. ****************************************************************************/ -FLMBYTE KanaSubColTbl[] = +static FLMBYTE KanaSubColTbl[] = { 0,1,0,1,0,1,0,1,0,1, // a A i I u U e E o O 1,3,0,3,0,3,1,3,0,3, // KA GA KI GI KU GU KE GE KO GO @@ -1059,7 +1059,7 @@ Desc: Map katakana (CharSet x26) to collation values kana collating values are two byte values where the high byte is 0x01. ****************************************************************************/ -FLMBYTE KanaColTbl[] = +static FLMBYTE KanaColTbl[] = { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, // a A i I u U e E o O 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, // KA GA KI GI KU GU KE GE KO GO @@ -1079,7 +1079,7 @@ FLMBYTE KanaColTbl[] = Desc: Map KataKana collated value to vowel value for use for the previous char. ****************************************************************************/ -FLMBYTE KanaColToVowel[] = +static FLMBYTE KanaColToVowel[] = { 0,1,2,3,4, // a i u e o 0,1,2,3,4, // ka ki ku ke ko @@ -1099,7 +1099,7 @@ Desc: Convert Zenkaku (double wide) to Hankaku (single wide) This enables collation values to be found on some symbols. This is also used to convert symbols from hankaku to Zen24. ****************************************************************************/ -BYTE_WORD_TBL Zen24ToHankaku[] = +static BYTE_WORD_TBL Zen24ToHankaku[] = { { 0 ,0x0020 }, // space { 1 ,0x0b03 }, // japanese comma @@ -1221,7 +1221,7 @@ Desc: Maps CS26 to CharSet 11 0xC0 - add handakuten 0xFF - no mapping exists ****************************************************************************/ -FLMBYTE MapCS26ToCharSet11[ 86] = +static FLMBYTE MapCS26ToCharSet11[ 86] = { 0x06, // 0 a 0x10, // 1 A @@ -1327,7 +1327,7 @@ Desc: Conversion from single (Hankaku) to double (Zenkaku) wide characters Used in flmWPHanToZenkaku() Maps from charset 11 to CS24 (punctuation) (starting from 11,0) ****************************************************************************/ -FLMBYTE From0AToZen[] = // ' changed because of windows +static FLMBYTE From0AToZen[] = { 0, 9, 40, 0x53, // sp ! " # 0x4f, 0x52, 0x54, 38, // $ % & ' @@ -1339,7 +1339,7 @@ FLMBYTE From0AToZen[] = // ' changed because of windows /**************************************************************************** Desc: ****************************************************************************/ -FLMBYTE From0BToZen[] = +static FLMBYTE From0BToZen[] = { 6, 7, 0x42, 0x40, // : ; < = 0x43, 8, 0x56 // > ? @ @@ -1348,7 +1348,7 @@ FLMBYTE From0BToZen[] = /**************************************************************************** Desc: ****************************************************************************/ -FLMBYTE From0CToZen[] = +static FLMBYTE From0CToZen[] = { 0x2d, 0x1f, 0x2e, 0x0f, 0x11, 0x0d // [ BACKSLASH ] ^ _ ` }; @@ -1356,7 +1356,7 @@ FLMBYTE From0CToZen[] = /**************************************************************************** Desc: ****************************************************************************/ -FLMBYTE From0DToZen[] = +static FLMBYTE From0DToZen[] = { 0x2f, 0x22, 0x30, 0x20 // { | } ~ }; @@ -1364,7 +1364,7 @@ FLMBYTE From0DToZen[] = /**************************************************************************** Desc: ****************************************************************************/ -FLMBYTE From8ToZen[] = +static FLMBYTE From8ToZen[] = { 0x5e, 0x7e, 0x5f, 0x7f, 0x5f, 0xFF, 0x60, 0x80, 0x61, 0x81, 0x62, 0x82, 0x63, 0x83, 0x64, 0x84, @@ -1378,7 +1378,7 @@ FLMBYTE From8ToZen[] = /**************************************************************************** Desc: ****************************************************************************/ -FLMBYTE From11AToZen[] = // 11 to 24 punctuation except dash +static FLMBYTE From11AToZen[] = { 2, // japanese period 0x35, // left bracket @@ -1390,7 +1390,7 @@ FLMBYTE From11AToZen[] = // 11 to 24 punctuation except dash /**************************************************************************** Desc: ****************************************************************************/ -FLMBYTE From11BToZen[] = // 11 to 26 (katakana) from 11,5 +static FLMBYTE From11BToZen[] = { 0x51, // wo 0,2,4,6,8,0x42,0x44,0x46,0x22, // small a i u e o ya yu yo tsu @@ -1409,7 +1409,7 @@ FLMBYTE From11BToZen[] = // 11 to 26 (katakana) from 11,5 /**************************************************************************** Desc: ****************************************************************************/ -FLMUINT16 fwp_indexi[] = +static FLMUINT16 fwp_indexi[] = { 0,11,14,15,17,18,19,21,22,23,24,25,26,35,59 }; @@ -1417,7 +1417,7 @@ FLMUINT16 fwp_indexi[] = /**************************************************************************** Desc: ****************************************************************************/ -FLMUINT16 fwp_indexj[] = // DOUBLE CHAR AREA - LANGUAGES +static FLMUINT16 fwp_indexj[] = { FLM_CA_LANG, // Catalan (0) FLM_CF_LANG, // Canadian French @@ -1486,7 +1486,7 @@ FLMUINT16 fwp_indexj[] = // DOUBLE CHAR AREA - LANGUAGES /**************************************************************************** Desc: ****************************************************************************/ -FLMUINT16 fwp_valuea[] = +static FLMUINT16 fwp_valuea[] = { // DOUBLE CHAR STATE VALUES STATE1, // 00 @@ -1589,7 +1589,7 @@ FLMUINT16 fwp_valuea[] = /**************************************************************************** Desc: ****************************************************************************/ -FLMBYTE fwp_asc60Tbl[ ASCTBLLEN + 2] = +static FLMBYTE fwp_asc60Tbl[ ASCTBLLEN + 2] = { 0x20, // initial character offset!! ASCTBLLEN, // len of this table @@ -1693,7 +1693,7 @@ FLMBYTE fwp_asc60Tbl[ ASCTBLLEN + 2] = /**************************************************************************** Desc: ****************************************************************************/ -FLMBYTE fwp_mn60Tbl[ MNTBLLEN + 2] = // multinational table +static FLMBYTE fwp_mn60Tbl[ MNTBLLEN + 2] = { 23, // initial character offset!! MNTBLLEN, // len of this table @@ -1933,7 +1933,7 @@ FLMBYTE fwp_mn60Tbl[ MNTBLLEN + 2] = // multinational table /**************************************************************************** Desc: ****************************************************************************/ -FLMBYTE fwp_sym60Tbl[ SYMTBLLEN + 2] = +static FLMBYTE fwp_sym60Tbl[ SYMTBLLEN + 2] = { 11, // initial character offset!! SYMTBLLEN, // len of this table @@ -1951,7 +1951,7 @@ FLMBYTE fwp_sym60Tbl[ SYMTBLLEN + 2] = /**************************************************************************** Desc: ****************************************************************************/ -FLMBYTE fwp_grk60Tbl[ GRKTBLLEN + 2] = +static FLMBYTE fwp_grk60Tbl[ GRKTBLLEN + 2] = { 0, // starting offset GRKTBLLEN, // length @@ -2200,7 +2200,7 @@ FLMBYTE fwp_grk60Tbl[ GRKTBLLEN + 2] = /**************************************************************************** Desc: ****************************************************************************/ -FLMBYTE fwp_cyrl60Tbl[ CYRLTBLLEN + 2] = +static FLMBYTE fwp_cyrl60Tbl[ CYRLTBLLEN + 2] = { 0, // starting offset CYRLTBLLEN, // len of table @@ -2438,7 +2438,7 @@ FLMBYTE fwp_cyrl60Tbl[ CYRLTBLLEN + 2] = Desc: The Hebrew characters are collated over the Russian characters Therefore sorting both Hebrew and Russian is impossible to do. ****************************************************************************/ -FLMBYTE fwp_heb60TblA[ HEBTBL1LEN + 2] = +static FLMBYTE fwp_heb60TblA[ HEBTBL1LEN + 2] = { 0, // starting offset HEBTBL1LEN, // len of table @@ -2476,7 +2476,7 @@ Desc: This is the ANCIENT HEBREW SCRIPT piece. The actual value will be stored in the subcollation. This way we don't play diacritic/subcollation games. ****************************************************************************/ -FLMBYTE fwp_heb60TblB[ HEBTBL2LEN + 2] = +static FLMBYTE fwp_heb60TblB[ HEBTBL2LEN + 2] = { 84, HEBTBL2LEN, @@ -2544,7 +2544,7 @@ Desc: The Arabic characters are collated OVER the Russian characters to add more collation values. Some chars in CS14 are combined when urdu, pashto and sindhi characters overlap. ****************************************************************************/ -FLMBYTE fwp_ar160Tbl[ AR1TBLLEN + 2] = +static FLMBYTE fwp_ar160Tbl[ AR1TBLLEN + 2] = { 38, // starting offset AR1TBLLEN, // len of table @@ -2757,7 +2757,7 @@ Desc: Alef needs a subcollation table. [13,152]..[13,153] - taa marbuuTah - nosubcoll [13,64] ..[13,67] - taa - subcoll of 1 ****************************************************************************/ -FLMBYTE fwp_alefSubColTbl[] = +static FLMBYTE fwp_alefSubColTbl[] = { // [13,165] 1, // ?? alif hamzah @@ -2783,7 +2783,7 @@ FLMBYTE fwp_alefSubColTbl[] = /**************************************************************************** Desc: ****************************************************************************/ -FLMBYTE fwp_ar260Tbl[ AR2TBLLEN + 2] = +static FLMBYTE fwp_ar260Tbl[ AR2TBLLEN + 2] = { 41, // starting offset AR2TBLLEN, // len of table @@ -2991,7 +2991,7 @@ Desc: If the bit position is set then save the character in the sub-col FLAIM COLTBL1 to see which characters are combined with other Arabic characters. ****************************************************************************/ -FLMBYTE fwp_ar2BitTbl[] = +static FLMBYTE fwp_ar2BitTbl[] = { // Start at character 64 // The only 'clean' areas uncollate to the correct place, they are... @@ -3030,7 +3030,7 @@ FLMBYTE fwp_ar2BitTbl[] = Desc: This table describes and gives addresses for collating 5.0 character sets. Each line corresponds with a character set. ***************************************************************************/ -TBL_B_TO_BP fwp_col60Tbl[] = +static TBL_B_TO_BP fwp_col60Tbl[] = { {CHSASCI, fwp_asc60Tbl}, // ascii - " " - "~" {CHSMUL1, fwp_mn60Tbl}, // multinational @@ -3044,7 +3044,7 @@ TBL_B_TO_BP fwp_col60Tbl[] = Desc: This table is for sorting the hebrew/arabic languages. These values overlap the end of ASC/european and cyrillic tables. ****************************************************************************/ -TBL_B_TO_BP fwp_HebArabicCol60Tbl[] = +static TBL_B_TO_BP fwp_HebArabicCol60Tbl[] = { {CHSASCI, fwp_asc60Tbl}, // ascii - " " - "~" {CHSMUL1, fwp_mn60Tbl}, // multinational @@ -3072,7 +3072,7 @@ Desc: The diacritical to collated table translates the first 26 This table is index by the diacritical value. ****************************************************************************/ -FLMBYTE fwp_dia60Tbl[] = +static FLMBYTE fwp_dia60Tbl[] = { 2, // grave offset = 0 16, // centerd offset = 1 @@ -3129,7 +3129,7 @@ static FLMBYTE fwp_caseConvertableRange[] = /**************************************************************************** Desc: ****************************************************************************/ -FLMUINT16 colToWPChr[ COLS11 - COLLS] = +static FLMUINT16 colToWPChr[ COLS11 - COLLS] = { 0x20, // colls - 0x2e, // colls+1 - . @@ -3354,7 +3354,7 @@ FLMUINT16 colToWPChr[ COLS11 - COLLS] = /**************************************************************************** Desc: ****************************************************************************/ -FLMUINT16 HebArabColToWPChr[] = +static FLMUINT16 HebArabColToWPChr[] = { // Start at COLS10a+0 // [0] @@ -3465,7 +3465,7 @@ FLMUINT16 HebArabColToWPChr[] = /**************************************************************************** Desc: ****************************************************************************/ -FLMUINT16 ArabSubColToWPChr[] = +static FLMUINT16 ArabSubColToWPChr[] = { 0x0D00 +177, // Alef maddah - default value - here for documentation 0x0D00 +165, // Alef Hamzah @@ -3481,7 +3481,7 @@ FLMUINT16 ArabSubColToWPChr[] = /**************************************************************************** Desc: Turns a collated diacritic value into the original diacritic value ****************************************************************************/ -FLMBYTE ml1_COLtoD[27] = +static FLMBYTE ml1_COLtoD[27] = { 23, // dbls sort value = 0 sorts as 'ss' 6, // acute sort value = 1 @@ -3516,7 +3516,7 @@ FLMBYTE ml1_COLtoD[27] = Desc: Notes: Only 48 values + 0x40, 0x41, 0x42 (169..171) ****************************************************************************/ -FLMBYTE ColToKanaTbl[ 48] = +static FLMBYTE ColToKanaTbl[ 48] = { 0, // a=0, A=1 2, // i=2, I=3 @@ -3626,7 +3626,7 @@ Notes: This table is used to convert a subset of Unicode characters to contractions. ****************************************************************************/ #define UTOWP60_ENTRIES 1502 -FLMUINT16 WP_UTOWP60[ UTOWP60_ENTRIES][2] = +static FLMUINT16 WP_UTOWP60[ UTOWP60_ENTRIES][2] = { { 0x00A1, 0x0407 }, // 7 , 4 { 0x00A2, 0x0413 }, // 19 , 4 @@ -9953,6 +9953,9 @@ Exit: return( rc); } +/************************************************************************** +Desc: +***************************************************************************/ void FLMAPI F_CollIStream::getCurrPosition( F_CollStreamPos * pPos) { diff --git a/ftk/src/ftkfsys.cpp b/ftk/src/ftkfsys.cpp index e766f4e..93eeb2e 100644 --- a/ftk/src/ftkfsys.cpp +++ b/ftk/src/ftkfsys.cpp @@ -74,6 +74,23 @@ public: RCODE setup( void); + FLMINT FLMAPI AddRef( void) + { + return( f_atomicInc( &m_refCnt)); + } + + FLMINT FLMAPI Release( void) + { + FLMINT iRefCnt = f_atomicDec( &m_refCnt); + + if( !iRefCnt) + { + delete this; + } + + return( iRefCnt); + } + RCODE FLMAPI createFile( const char * pszFileName, FLMUINT uiIoFlags, @@ -2403,3 +2420,65 @@ Exit: return( rc); } + +/**************************************************************************** +Desc: +****************************************************************************/ +RCODE FLMAPI f_filetobuf( + const char * pszSourceFile, + char ** ppszBuffer) +{ + RCODE rc = NE_FLM_OK; + char * pszBuffer = NULL; + IF_FileHdl * pFileHdl = NULL; + FLMUINT64 ui64FileSize; + FLMUINT uiBytesRead; + IF_FileSystem * pFileSystem = f_getFileSysPtr(); + + if( RC_BAD(rc = pFileSystem->openFile( pszSourceFile, + FLM_IO_RDONLY, &pFileHdl))) + { + goto Exit; + } + + if( RC_BAD( rc = pFileHdl->size( &ui64FileSize))) + { + goto Exit; + } + + if( !ui64FileSize) + { + *pszBuffer = NULL; + goto Exit; + } + + if( RC_BAD( rc = f_alloc( ui64FileSize + 1, &pszBuffer))) + { + goto Exit; + } + + if( RC_BAD( rc = pFileHdl->read( 0, (FLMUINT)ui64FileSize, + pszBuffer, &uiBytesRead))) + { + goto Exit; + } + + f_assert( (FLMUINT)ui64FileSize == uiBytesRead); + pszBuffer[ ui64FileSize] = 0; + *ppszBuffer = pszBuffer; + pszBuffer = NULL; + +Exit: + + if( pFileHdl) + { + pFileHdl->Release(); + } + + if( pszBuffer) + { + f_free( &pszBuffer); + } + + return( rc); +} diff --git a/ftk/src/ftkftx.cpp b/ftk/src/ftkftx.cpp index 37a302a..da939fe 100644 --- a/ftk/src/ftkftx.cpp +++ b/ftk/src/ftkftx.cpp @@ -354,10 +354,13 @@ typedef struct FTX_INFO #endif -static FLMBOOL gv_bInitialized = FALSE; +static FLMATOMIC gv_ftxInitCount = 0; static FLMBOOL gv_bDisplayInitialized = FALSE; -static FLMUINT gv_uiInitCount = 0; static FTX_INFO * gv_pFtxInfo = NULL; +static FLMATOMIC gv_conInitCount = 0; +static FTX_SCREEN * gv_pConScreen = NULL; +static FTX_WINDOW * gv_pConWindow = NULL; +static F_MUTEX gv_hConMutex = F_MUTEX_NULL; #if defined( FLM_WIN) @@ -530,9 +533,8 @@ RCODE FLMAPI FTXInit( FTX_INFO * pFtxInfo; IF_ThreadMgr * pThreadMgr = f_getThreadMgrPtr(); - if( gv_bInitialized) + if( f_atomicInc( &gv_ftxInitCount) > 1) { - gv_uiInitCount++; goto Exit; } @@ -621,9 +623,6 @@ RCODE FLMAPI FTXInit( goto Exit; } - gv_bInitialized = TRUE; - gv_uiInitCount++; - Exit: return( rc); @@ -637,50 +636,62 @@ void FLMAPI FTXExit( void) { FTX_SCREEN * pScreen; - if( !gv_bInitialized || --gv_uiInitCount > 0 || !gv_pFtxInfo) + if( !gv_ftxInitCount || + f_atomicDec( &gv_ftxInitCount) > 0 || + !gv_pFtxInfo) { return; } - // Shut down the display, keyboard, and backgroudn threads - - gv_pFtxInfo->pKeyboardThrd->stopThread(); - gv_pFtxInfo->pKeyboardThrd->Release(); - gv_pFtxInfo->pKeyboardThrd = NULL; - - gv_pFtxInfo->pDisplayThrd->stopThread(); - gv_pFtxInfo->pDisplayThrd->Release(); - gv_pFtxInfo->pDisplayThrd = NULL; - - gv_pFtxInfo->pBackgroundThrd->stopThread(); - gv_pFtxInfo->pBackgroundThrd->Release(); - gv_pFtxInfo->pBackgroundThrd = NULL; - - f_mutexLock( gv_pFtxInfo->hFtxMutex); - - gv_bInitialized = FALSE; - gv_pFtxInfo->bExiting = TRUE; - - while( (pScreen = gv_pFtxInfo->pScreenCur) != NULL) + if( gv_pFtxInfo->pKeyboardThrd) { - ftxScreenFree( pScreen); + gv_pFtxInfo->pKeyboardThrd->stopThread(); + gv_pFtxInfo->pKeyboardThrd->Release(); + gv_pFtxInfo->pKeyboardThrd = NULL; } - - ftxDisplayReset(); - ftxDisplayExit(); - -#if defined( FLM_WIN) - - f_free( &gv_pFtxInfo->pCells); - -#elif defined( FLM_NLM) - - CloseScreen( gv_pFtxInfo->hScreen); - -#endif - - f_mutexUnlock( gv_pFtxInfo->hFtxMutex); - f_mutexDestroy( &(gv_pFtxInfo->hFtxMutex)); + + if( gv_pFtxInfo->pDisplayThrd) + { + gv_pFtxInfo->pDisplayThrd->stopThread(); + gv_pFtxInfo->pDisplayThrd->Release(); + gv_pFtxInfo->pDisplayThrd = NULL; + } + + if( gv_pFtxInfo->pBackgroundThrd) + { + gv_pFtxInfo->pBackgroundThrd->stopThread(); + gv_pFtxInfo->pBackgroundThrd->Release(); + gv_pFtxInfo->pBackgroundThrd = NULL; + } + + if( gv_pFtxInfo->hFtxMutex != F_MUTEX_NULL) + { + f_mutexLock( gv_pFtxInfo->hFtxMutex); + + gv_pFtxInfo->bExiting = TRUE; + + while( (pScreen = gv_pFtxInfo->pScreenCur) != NULL) + { + ftxScreenFree( pScreen); + } + + ftxDisplayReset(); + ftxDisplayExit(); + + #if defined( FLM_WIN) + + f_free( &gv_pFtxInfo->pCells); + + #elif defined( FLM_NLM) + + CloseScreen( gv_pFtxInfo->hScreen); + + #endif + + f_mutexUnlock( gv_pFtxInfo->hFtxMutex); + f_mutexDestroy( &(gv_pFtxInfo->hFtxMutex)); + } + f_free( &gv_pFtxInfo); } @@ -5840,3 +5851,396 @@ FSTATIC FLMBOOL ftxUnixKBTest( void) return( (c == ERR) ? FALSE : TRUE); } #endif + +/**************************************************************************** +Desc: +****************************************************************************/ +RCODE FLMAPI f_conInit( + FLMUINT uiRows, + FLMUINT uiCols, + const char * pszTitle) +{ + RCODE rc = NE_FLM_OK; + + if( f_atomicInc( &gv_conInitCount) > 1) + { + goto Exit; + } + + if( RC_BAD( rc = FTXInit( pszTitle, uiCols, uiRows, + FLM_BLACK, FLM_LIGHTGRAY, NULL, NULL))) + { + goto Exit; + } + + if( RC_BAD( rc = f_mutexCreate( &gv_hConMutex))) + { + goto Exit; + } + + if( RC_BAD( rc = FTXScreenInit( pszTitle, &gv_pConScreen))) + { + goto Exit; + } + + if( RC_BAD( rc = FTXWinInit( gv_pConScreen, gv_pConScreen->uiCols, + gv_pConScreen->uiRows, &gv_pConWindow))) + { + goto Exit; + } + + if( RC_BAD( rc = FTXWinOpen( gv_pConWindow))) + { + goto Exit; + } + +Exit: + + if( RC_BAD( rc)) + { + f_conExit(); + } + + return( rc); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +void FLMAPI f_conExit( void) +{ + if( !gv_conInitCount || f_atomicDec( &gv_conInitCount) > 0) + { + return; + } + + if( gv_pConWindow) + { + FTXWinFree( &gv_pConWindow); + } + + if( gv_pConScreen) + { + FTXScreenFree( &gv_pConScreen); + } + + if( gv_hConMutex != F_MUTEX_NULL) + { + f_mutexDestroy( &gv_hConMutex); + } + + FTXExit(); +} + +/**************************************************************************** +Desc: Returns the size of the screen in columns and rows. +****************************************************************************/ +void FLMAPI f_conGetScreenSize( + FLMUINT * puiNumColsRV, + FLMUINT * puiNumRowsRV) +{ + f_mutexLock( gv_hConMutex); + FTXWinGetCanvasSize( gv_pConWindow, puiNumColsRV, puiNumRowsRV); + f_mutexUnlock( gv_hConMutex); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +void FLMAPI f_conStrOut( + const char * pszString) +{ + f_mutexLock( gv_hConMutex); + FTXWinPrintStr( gv_pConWindow, pszString); + f_mutexUnlock( gv_hConMutex); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +void FLMAPI f_conStrOutXY( + const char * pszString, + FLMUINT uiCol, + FLMUINT uiRow) +{ + f_mutexLock( gv_hConMutex); + FTXWinPrintStrXY( gv_pConWindow, pszString, uiCol, uiRow); + f_mutexUnlock( gv_hConMutex); +} + +/**************************************************************************** +Desc: Output a formatted string at present cursor location. +****************************************************************************/ +void FLMAPI f_conPrintf( + const char * pszFormat, ...) +{ + char szBuffer[ 512]; + f_va_list args; + + f_va_start( args, pszFormat); + f_vsprintf( szBuffer, pszFormat, &args); + f_va_end( args); + + f_mutexLock( gv_hConMutex); + FTXWinPrintStr( gv_pConWindow, szBuffer); + f_mutexUnlock( gv_hConMutex); +} + +/**************************************************************************** +Desc: Output a formatted string at present cursor location with color +****************************************************************************/ +void FLMAPI f_conCPrintf( + eColorType back, + eColorType fore, + const char * pszFormat, ...) +{ + char szBuffer[ 512]; + f_va_list args; + eColorType oldBack; + eColorType oldFore; + + f_va_start( args, pszFormat); + f_vsprintf( szBuffer, pszFormat, &args); + f_va_end( args); + + f_mutexLock( gv_hConMutex); + FTXWinGetBackFore( gv_pConWindow, &oldBack, &oldFore); + FTXWinSetBackFore( gv_pConWindow, back, fore); + FTXWinPrintStr( gv_pConWindow, szBuffer); + FTXWinSetBackFore( gv_pConWindow, oldBack, oldFore); + f_mutexUnlock( gv_hConMutex); +} + +/**************************************************************************** +Desc: Clear the screen from the col/row down +****************************************************************************/ +void FLMAPI f_conClearScreen( + FLMUINT uiCol, + FLMUINT uiRow) +{ + FLMUINT uiCurrCol; + FLMUINT uiCurrRow; + + f_mutexLock( gv_hConMutex); + + FTXWinGetCursorPos( gv_pConWindow, &uiCurrCol, &uiCurrRow); + + if( uiCol == 255) + { + uiCol = uiCurrCol; + } + + if( uiRow == 255) + { + uiRow = uiCurrRow; + } + + FTXWinClearXY( gv_pConWindow, uiCol, uiRow); + FTXWinSetCursorPos( gv_pConWindow, uiCol, uiRow); + + f_mutexUnlock( gv_hConMutex); +} + +/**************************************************************************** +Desc: Position to the column and row specified. +Notes: The NLM could call GetPositionOfOutputCursor(&r,&c); +****************************************************************************/ +void FLMAPI f_conSetCursorPos( + FLMUINT uiCol, + FLMUINT uiRow) +{ + FLMUINT uiCurrCol; + FLMUINT uiCurrRow; + + f_mutexLock( gv_hConMutex); + + FTXWinGetCursorPos( gv_pConWindow, &uiCurrCol, &uiCurrRow); + + if( uiCol == 255) + { + uiCol = uiCurrCol; + } + + if( uiRow == 255) + { + uiRow = uiCurrRow; + } + + FTXWinSetCursorPos( gv_pConWindow, uiCol, uiRow); + + f_mutexUnlock( gv_hConMutex); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +void FLMAPI f_conClearLine( + FLMUINT uiCol, + FLMUINT uiRow) +{ + FLMUINT uiCurrCol; + FLMUINT uiCurrRow; + + f_mutexLock( gv_hConMutex); + + FTXWinGetCursorPos( gv_pConWindow, &uiCurrCol, &uiCurrRow); + + if( uiCol == 255) + { + uiCol = uiCurrCol; + } + + if( uiRow == 255) + { + uiRow = uiCurrRow; + } + + FTXWinClearLine( gv_pConWindow, uiCol, uiRow); + + f_mutexUnlock( gv_hConMutex); +} + +/**************************************************************************** +Desc: Edit a line of data like gets(s). Newline replaced by NULL character. +****************************************************************************/ +FLMUINT FLMAPI f_conLineEdit( + char * pszString, + FLMUINT uiMaxLen) +{ + FLMUINT uiCharCount; + FLMUINT uiCursorType; + + f_mutexLock( gv_hConMutex); + + uiCursorType = FTXWinGetCursorType( gv_pConWindow); + FTXWinSetCursorType( gv_pConWindow, FLM_CURSOR_UNDERLINE); + uiCharCount = FTXLineEd( gv_pConWindow, pszString, uiMaxLen); + FTXWinSetCursorType( gv_pConWindow, uiCursorType); + + f_mutexUnlock( gv_hConMutex); + + return( uiCharCount); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +void FLMAPI f_conSetShutdown( + FLMBOOL * pbShutdown) +{ + FTXSetShutdownFlag( pbShutdown); +} + +/**************************************************************************** +Desc: Edit a line of data with advanced features. +Ret: Number of characters input. +****************************************************************************/ +FLMUINT FLMAPI f_conLineEditExt( + char * pszBuffer, + FLMUINT uiBufSize, + FLMUINT uiMaxWidth, + FLMUINT * puiTermChar) +{ + FLMUINT uiCharCount = 0; + FLMUINT uiCursorType; + + f_mutexLock( gv_hConMutex); + + uiCursorType = FTXWinGetCursorType( gv_pConWindow); + FTXWinSetCursorType( gv_pConWindow, FLM_CURSOR_UNDERLINE); + FTXLineEdit( gv_pConWindow, pszBuffer, uiBufSize, uiMaxWidth, + &uiCharCount, puiTermChar); + FTXWinSetCursorType( gv_pConWindow, uiCursorType); + f_mutexUnlock( gv_hConMutex); + + return( (FLMINT)uiCharCount); +} + +/**************************************************************************** +Desc: Get the current X coordinate of the cursor +****************************************************************************/ +FLMUINT FLMAPI f_conGetCursorColumn( void) +{ + FLMUINT uiCol; + + f_mutexLock( gv_hConMutex); + FTXWinGetCursorPos( gv_pConWindow, &uiCol, NULL); + f_mutexUnlock( gv_hConMutex); + + return( uiCol); +} + +/**************************************************************************** +Desc: Get the current Y coordinate of the cursor +****************************************************************************/ +FLMUINT FLMAPI f_conGetCursorRow( void) +{ + FLMUINT uiRow; + + f_mutexLock( gv_hConMutex); + FTXWinGetCursorPos( gv_pConWindow, NULL, &uiRow); + f_mutexUnlock( gv_hConMutex); + + return( uiRow); +} + +/**************************************************************************** +Desc: Set the background and foreground colors +****************************************************************************/ +void FLMAPI f_conSetBackFore( + eColorType backColor, + eColorType foreColor) +{ + f_mutexLock( gv_hConMutex); + FTXWinSetBackFore( gv_pConWindow, backColor, foreColor); + f_mutexUnlock( gv_hConMutex); +} + +/**************************************************************************** +Desc : Sets the cursor attributes. +****************************************************************************/ +void FLMAPI f_conSetCursorType( + FLMUINT uiType) +{ + f_mutexLock( gv_hConMutex); + FTXWinSetCursorType( gv_pConWindow, uiType); + f_mutexUnlock( gv_hConMutex); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +void FLMAPI f_conDrawBorder( void) +{ + f_mutexLock( gv_hConMutex); + FTXWinDrawBorder( gv_pConWindow); + f_mutexUnlock( gv_hConMutex); +} + +/**************************************************************************** +Desc: +Not*************************************************************************/ +FLMUINT FLMAPI f_conGetKey( void) +{ + FLMUINT uiChar; + + f_mutexLock( gv_hConMutex); + FTXWinInputChar( gv_pConWindow, &uiChar); + f_mutexUnlock( gv_hConMutex); + + return( uiChar); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +FLMBOOL FLMAPI f_conHaveKey( void) +{ + FLMBOOL bHaveKey; + + f_mutexLock( gv_hConMutex); + bHaveKey = FTXWinTestKB( gv_pConWindow) == NE_FLM_OK ? TRUE : FALSE; + f_mutexUnlock( gv_hConMutex); + + return( bHaveKey); +} diff --git a/ftk/src/ftklock.cpp b/ftk/src/ftklock.cpp index c531dcc..5cb840e 100644 --- a/ftk/src/ftklock.cpp +++ b/ftk/src/ftklock.cpp @@ -89,7 +89,7 @@ public: FLMUINT * puiNumExclQueued, FLMUINT * puiNumSharedQueued, FLMUINT * puiPriorityCount); - + RCODE FLMAPI getLockInfo( IF_LockInfoClient * pLockInfo); @@ -868,7 +868,7 @@ RCODE FLMAPI F_LockObject::getLockInfo( } /**************************************************************************** -Desc: Return the lock waiters for this object. +Desc: ****************************************************************************/ RCODE FLMAPI F_LockObject::getLockInfo( IF_LockInfoClient * pLockInfo) diff --git a/ftk/src/ftklog.cpp b/ftk/src/ftklog.cpp index e86628b..da21cb6 100644 --- a/ftk/src/ftklog.cpp +++ b/ftk/src/ftklog.cpp @@ -86,6 +86,211 @@ FSTATIC void f_logNotHandledFormatter( IF_LogMessageClient * pLogMessage, f_va_list * args); +FSTATIC FLMUINT traceFormatNumber( + FLMUINT64 ui64Number, + FLMINT uiBase, + char * pszDest); + +#define FORMAT_MINUS_FLAG 0x0001 +#define FORMAT_PLUS_FLAG 0x0002 +#define FORMAT_SPACE_FLAG 0x0004 +#define FORMAT_POUND_FLAG 0x0008 +#define FORMAT_ZERO_FLAG 0x0010 +#define FORMAT_SHORT_FLAG 0x0020 +#define FORMAT_LONG_FLAG 0x0040 +#define FORMAT_DOUBLE_FLAG 0x0080 +#define FORMAT_INT64_FLAG 0x0100 + +// Special strings to embed in trace() calls. + +#define FORE_BLACK "%0F" +#define FORE_BLUE "%1F" +#define FORE_GREEN "%2F" +#define FORE_CYAN "%3F" +#define FORE_RED "%4F" +#define FORE_MAGENTA "%5F" +#define FORE_BROWN "%6F" +#define FORE_LIGHTGRAY "%7F" +#define FORE_DARKGRAY "%8F" +#define FORE_LIGHTBLUE "%9F" +#define FORE_LIGHTGREEN "%10F" +#define FORE_LIGHTCYAN "%11F" +#define FORE_LIGHTRED "%12F" +#define FORE_LIGHTMAGENTA "%13F" +#define FORE_YELLOW "%14F" +#define FORE_WHITE "%15F" + +#define BACK_BLACK "%0B" +#define BACK_BLUE "%1B" +#define BACK_GREEN "%2B" +#define BACK_CYAN "%3B" +#define BACK_RED "%4B" +#define BACK_MAGENTA "%5B" +#define BACK_BROWN "%6B" +#define BACK_LIGHTGRAY "%7B" +#define BACK_DARKGRAY "%8B" +#define BACK_LIGHTBLUE "%9B" +#define BACK_LIGHTGREEN "%10B" +#define BACK_LIGHTCYAN "%11B" +#define BACK_LIGHTRED "%12B" +#define BACK_LIGHTMAGENTA "%13B" +#define BACK_YELLOW "%14B" +#define BACK_WHITE "%15B" + +#define PUSH_FORE_COLOR "%+F" +#define POP_FORE_COLOR "%-F" + +#define PUSH_BACK_COLOR "%+B" +#define POP_BACK_COLOR "%-B" + +// Trace categories reserved for users + +#define USER_CATEGORY1 0x8000000 +#define USER_CATEGORY2 0x4000000 +#define USER_CATEGORY3 0x2000000 +#define USER_CATEGORY4 0x1000000 +#define USER_CATEGORY5 0x0800000 +#define USER_CATEGORY6 0x0400000 +#define USER_CATEGORY7 0x0200000 +#define USER_CATEGORY8 0x0100000 + +/**************************************************************************** +Desc: +****************************************************************************/ +class F_Trace : public F_Object +{ +public: + + F_Trace(); + + virtual ~F_Trace(); + + FLMINT FLMAPI AddRef( void); + + FLMINT FLMAPI Release( void); + + FINLINE void enableCategory( + FLMUINT uiCategory) + { + m_uiEnabledCategories |= uiCategory; + } + + FINLINE void disableCategory( + FLMUINT uiCategory) + { + m_uiEnabledCategories &= (~(uiCategory)); + } + + FINLINE FLMBOOL categoryEnabled( + FLMUINT uiCategory) + { + return( ((m_uiEnabledCategories & uiCategory) == uiCategory) + ? TRUE + : FALSE); + } + + FINLINE FLMUINT getEnabledCategories( void) + { + return( m_uiEnabledCategories); + } + + void trace( + FLMUINT uiCategory, + const char * pszFormat, + ...); + + FLMBOOL setMultiThreaded( void); + + void setPipe( + F_Trace * pTracePipe); + + void lock( void); + + void unlock( void); + + void outputText( + FLMUINT uiCategory, + FLMUINT uiForeColor, + FLMUINT uiBackColor, + const char * pszString); + + virtual void outputString( + FLMUINT uiCategory, + FLMUINT uiForeColor, + FLMUINT uiBackColor, + const char * pszString) = 0; + +private: + + void processFieldInfo( + const char ** ppszFormat, + FLMUINT * puiWidth, + FLMUINT * puiPrecision, + FLMUINT * puiFlags, + f_va_list * args); + + void processStringText( + FLMUINT uiLen, + ...); + + void traceOutputArgs( + const char * pszFormat, + f_va_list * args); + + void formatColor( + FLMUINT uiChar, + FLMUINT uiColor, + FLMUINT uiFlags); + + void formatString( + FLMUINT uiFormatChar, + FLMUINT uiWidth, + FLMUINT uiPrecision, + FLMUINT uiFlags, + f_va_list * args); + + void formatNumber( + FLMUINT uiFormatChar, + FLMUINT uiWidth, + FLMUINT uiPrecision, + FLMUINT uiFlags, + f_va_list * args); + + void formatChar( + FLMUINT uiFormatChar, + f_va_list * args); + + void formatNotHandled( void); + + void outputCurrentText( + FLMUINT uiForeColor, + FLMUINT uiBackColor); + + F_MUTEX m_hMutex; + FLMUINT m_uiLockCnt; +#ifdef FLM_DEBUG + FLMUINT m_uiLockThreadId; +#endif + FLMUINT m_uiEnabledCategories; + F_Trace * m_pTracePipe; + + // Variables used to do the printf stuff + +#define MAX_FORMAT_STR_SIZE 1000 + + char m_szDestStr [MAX_FORMAT_STR_SIZE]; + char * m_pszDestStr; + FLMUINT m_uiMaxLen; + FLMUINT m_uiForeColorDepth; + FLMUINT m_uiBackColorDepth; + FLMUINT m_uiForeColorStack [8]; + FLMUINT m_uiBackColorStack [8]; + FLMUINT m_uiCurrentForeColor; + FLMUINT m_uiCurrentBackColor; + FLMUINT m_uiCategory; + +}; + /**************************************************************************** Desc: Handle text portions of the format string ****************************************************************************/ @@ -505,3 +710,722 @@ void FLMAPI f_endLogMessage( f_mutexUnlock( gv_hLoggerMutex); } } + +/**************************************************************************** +Desc: +****************************************************************************/ +F_Trace::F_Trace() +{ + m_hMutex = F_MUTEX_NULL; + m_uiLockCnt = 0; +#ifdef FLM_DEBUG + m_uiLockThreadId = 0; +#endif + m_uiEnabledCategories = 0; + m_pTracePipe = NULL; +} + +/**************************************************************************** +Desc: +****************************************************************************/ +F_Trace::~F_Trace() +{ + flmAssert( m_uiLockCnt == 0); + if (m_hMutex != F_MUTEX_NULL) + { + f_mutexDestroy( &m_hMutex); + } + if (m_pTracePipe) + { + m_pTracePipe->Release(); + } +} + +/**************************************************************************** +Desc: +****************************************************************************/ +FLMINT FLMAPI F_Trace::AddRef( void) +{ + return( f_atomicInc( &m_refCnt)); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +FLMINT FLMAPI F_Trace::Release( void) +{ + FLMINT iRefCnt; + + if( (iRefCnt = f_atomicDec( &m_refCnt)) == 0) + { + delete this; + } + + return( iRefCnt); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +void F_Trace::trace( + FLMUINT uiCategory, + const char * pszFormat, + ... + ) +{ + f_va_list args; + + f_va_start( args, pszFormat); + + // First see if the stuff is enabled. + + if (uiCategory & m_uiEnabledCategories) + { + lock(); + + // Leave room for terminator. + + m_uiMaxLen = sizeof( m_szDestStr) - 1; + m_pszDestStr = &m_szDestStr [0]; + m_uiCurrentForeColor = FLM_CURRENT_COLOR; + m_uiCurrentBackColor = FLM_CURRENT_COLOR; + m_uiForeColorDepth = 0; + m_uiBackColorDepth = 0; + m_uiCategory = uiCategory; + traceOutputArgs( pszFormat, (f_va_list *)&args); + outputCurrentText( m_uiCurrentForeColor, m_uiCurrentBackColor); + unlock(); + } + f_va_end( args); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +FLMBOOL F_Trace::setMultiThreaded( void) +{ + FLMBOOL bOk = TRUE; + + if (m_hMutex == F_MUTEX_NULL) + { + if (RC_BAD( f_mutexCreate( &m_hMutex))) + { + bOk = FALSE; + } + } + return( bOk); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +void F_Trace::setPipe( + F_Trace * pTracePipe) +{ + lock(); + if (m_pTracePipe && m_pTracePipe != pTracePipe) + { + m_pTracePipe->Release(); + } + if ((m_pTracePipe = pTracePipe) != NULL) + { + m_pTracePipe->AddRef(); + } + unlock(); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +void F_Trace::lock( void) +{ + if (m_uiLockCnt) + { +#ifdef FLM_DEBUG + flmAssert( m_uiLockThreadId == f_threadId()); +#endif + m_uiLockCnt++; + } + else if (m_hMutex != F_MUTEX_NULL) + { + f_mutexLock( m_hMutex); + m_uiLockCnt++; +#ifdef FLM_DEBUG + m_uiLockThreadId = f_threadId(); +#endif + } +} + +/**************************************************************************** +Desc: +****************************************************************************/ +void F_Trace::unlock( void) +{ + if (m_uiLockCnt) + { +#ifdef FLM_DEBUG + flmAssert( m_uiLockThreadId == f_threadId()); +#endif + m_uiLockCnt--; + if (!m_uiLockCnt && m_hMutex != F_MUTEX_NULL) + { + f_mutexUnlock( m_hMutex); +#ifdef FLM_DEBUG + m_uiLockThreadId = 0; +#endif + } + } +} + +/**************************************************************************** +Desc: +****************************************************************************/ +void F_Trace::outputText( + FLMUINT uiCategory, + FLMUINT uiForeColor, + FLMUINT uiBackColor, + const char * pszString) +{ + lock(); + outputString( uiCategory, uiForeColor, uiBackColor, pszString); + unlock(); + + if (m_pTracePipe) + { + if (uiCategory & m_pTracePipe->getEnabledCategories()) + { + m_pTracePipe->outputText( uiCategory, uiForeColor, uiBackColor, + pszString); + } + } +} + +/**************************************************************************** +Desc: Parameter 'ppszFormat' points to text following a '%' sign. Process + legal field information. Leave 'ppszFormat' pointing at the format + specifier character. +****************************************************************************/ +void F_Trace::processFieldInfo( + const char ** ppszFormat, + FLMUINT * puiWidth, + FLMUINT * puiPrecision, + FLMUINT * puiFlags, + f_va_list * args) +{ + const char * pszTmp = *ppszFormat; + + // Process flags + + *puiFlags = 0; + for (;;) + { + switch (*pszTmp) + { + case '-': *puiFlags |= FORMAT_MINUS_FLAG; break; + case '+': *puiFlags |= FORMAT_PLUS_FLAG; break; + case ' ': *puiFlags |= FORMAT_SPACE_FLAG; break; + case '#': *puiFlags |= FORMAT_POUND_FLAG; break; + case '0': *puiFlags |= FORMAT_ZERO_FLAG; break; + default: + goto Out1; + } + pszTmp++; + } + +Out1: + + // Process width + + *puiWidth = 0; + if (*pszTmp == '*') + { + *puiWidth = f_va_arg( *args, unsigned int); + ++pszTmp; + } + else while (*pszTmp >= '0' && *pszTmp <= '9') + { + *puiWidth = (*puiWidth * 10) + (*pszTmp - '0'); + ++pszTmp; + } + + // Process precision + + *puiPrecision = 0; + if (*pszTmp == '.') + { + ++pszTmp; + if (*pszTmp == '*') + { + *puiPrecision = f_va_arg( *args, unsigned int); + ++pszTmp; + } + else while (*pszTmp >= '0' && *pszTmp <= '9') + { + *puiPrecision = (*puiPrecision * 10) + (*pszTmp - '0'); + ++pszTmp; + } + } + + // Size modifiers + + switch( *pszTmp) + { + case 'L': *puiFlags |= FORMAT_DOUBLE_FLAG; ++pszTmp; break; + case 'l': *puiFlags |= FORMAT_LONG_FLAG; ++pszTmp; break; + case 'h': *puiFlags |= FORMAT_SHORT_FLAG; ++pszTmp; break; + case 'I': + { + if( pszTmp[1] == '6' && pszTmp[2] == '4') + { + *puiFlags |= FORMAT_INT64_FLAG; + pszTmp += 3; + } + break; + } + } + + *ppszFormat = pszTmp; +} + +/**************************************************************************** +Desc: +****************************************************************************/ +void F_Trace::processStringText( + FLMUINT uiLen, + ...) +{ + f_va_list args; + + f_va_start(args, uiLen); + if (uiLen) + { + formatString( 0, uiLen, uiLen, 0, (f_va_list *)&args); + } + f_va_end(args); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +void F_Trace::traceOutputArgs( + const char * pszFormat, + f_va_list * args) +{ + FLMUINT uiChar; + FLMUINT uiWidth; + FLMUINT uiPrecision; + FLMUINT uiFlags; + const char * pszTextStart = pszFormat; + + while ((uiChar = (FLMUINT)*pszFormat++) != 0) + { + if (uiChar != '%') + { + continue; + } + uiWidth = pszFormat - pszTextStart - 1; + processStringText( uiWidth, pszTextStart); + processFieldInfo( &pszFormat, &uiWidth, &uiPrecision, &uiFlags, args); + uiChar = (FLMUINT)*pszFormat++; + + switch (uiChar) + { + case 'c': + case '%': + formatChar( uiChar, args); + break; + case 'B': + case 'F': + formatColor( uiChar, uiWidth, uiFlags); + break; + case 'd': + case 'o': + case 'u': + case 'x': + case 'X': + formatNumber( uiChar, uiWidth, uiPrecision, uiFlags, args); + break; + case 's': + case 'S': + case 'U': + formatString( uiChar, uiWidth, uiPrecision, uiFlags, args); + break; + + default: + formatNotHandled(); + break; + } + pszTextStart = pszFormat; + } + processStringText( (FLMUINT)(pszFormat - pszTextStart) - 1, pszTextStart); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +void F_Trace::formatColor( + FLMUINT uiChar, + FLMUINT uiColor, + FLMUINT uiFlags) +{ + FLMUINT uiPrevForeColor = m_uiCurrentForeColor; + FLMUINT uiPrevBackColor = m_uiCurrentBackColor; + + if (uiChar == 'F') // Foreground color + { + if ((uiFlags & FORMAT_PLUS_FLAG) && m_uiForeColorDepth < 8) + { + m_uiForeColorStack [m_uiForeColorDepth++] = m_uiCurrentForeColor; + } + else if ((uiFlags & FORMAT_MINUS_FLAG) && m_uiForeColorDepth > 0) + { + m_uiCurrentForeColor = m_uiForeColorStack [--m_uiForeColorDepth]; + } + else + { + m_uiCurrentForeColor = uiColor; + } + } + else // uiChar == 'B' - background color + { + if ((uiFlags & FORMAT_PLUS_FLAG) && m_uiBackColorDepth < 8) + { + m_uiBackColorStack [m_uiBackColorDepth++] = m_uiCurrentBackColor; + } + else if ((uiFlags & FORMAT_MINUS_FLAG) && m_uiBackColorDepth > 0) + { + m_uiCurrentBackColor = m_uiBackColorStack [--m_uiBackColorDepth]; + } + else + { + m_uiCurrentBackColor = uiColor; + } + } + + // If the color changed, output the current text with the last + // colors we had. + + if ((m_uiCurrentForeColor != uiPrevForeColor) || + (m_uiCurrentBackColor != uiPrevBackColor)) + { + outputCurrentText( uiPrevForeColor, uiPrevBackColor); + } +} + +/**************************************************************************** +Desc: String formatter. + Outputs the asciiz string specified by ADDRESS in 's'. + Outputs length preceeded string specified by ADDRESS in 'S'. + Outputs unicode string specified by ADDRESS in 'U'. + Format: %[flags][width][.prec]'s'|'S'|'U' + flags = '-' left justifies if string length < width + width = minimum number of characters to print + prec = maximum number of characters to print +****************************************************************************/ +void F_Trace::formatString( + FLMUINT uiFormatChar, + FLMUINT uiWidth, + FLMUINT uiPrecision, + FLMUINT uiFlags, + f_va_list * args) +{ + F_SPRINTF_INFO info; + + info.pszDestStr = (FLMBYTE *)m_pszDestStr; + f_sprintfStringFormatter( (FLMBYTE)uiFormatChar, uiWidth, + uiPrecision, uiFlags, &info, args); + m_pszDestStr = (char *)info.pszDestStr; +} + +/**************************************************************************** +Desc: This is used by printf and sprintf to output numbers. It uses + recursion to separate the numbers down to individual digits and + output them in the proper order. +****************************************************************************/ +FSTATIC FLMUINT traceFormatNumber( + FLMUINT64 ui64Number, + FLMINT uiBase, + char * pszDest) +{ + char c = (char)(ui64Number % uiBase); + FLMUINT64 ui64Index = ui64Number / uiBase; + + ui64Index = ui64Index + ? traceFormatNumber( ui64Index, uiBase, pszDest) + : 0; + pszDest [ui64Index] = (char)((c > 9) + ? c + 'a' - 10 + : c + '0'); + return (FLMUINT)(ui64Index + 1); +} + +// Percent formating prefixes + +#define P_NONE 0 +#define P_MINUS 1 +#define P_PLUS 2 +#define P_POUND 3 + +/**************************************************************************** +Desc: Number formatter. + Formats the number specified by VALUE in 'd', 'o', 'u', 'x', or 'X' + Format: %[flags][width][.prec]'E' + flags = 'h' value is uint16 + 'l' value is uint32 + '-' left align result + '+' print plus sign if positive + '#' print '0x' in front of hex numbers + '0' zero-fill + width = minimum number of characters to output + prec = maximum number of characters to output (truncates or rounds) +****************************************************************************/ +void F_Trace::formatNumber( + FLMUINT uiFormatChar, + FLMUINT uiWidth, + FLMUINT uiPrecision, + FLMUINT uiFlags, + f_va_list * args) +{ + FLMUINT uiCount; + FLMUINT uiPrefix = P_NONE; + FLMUINT uiLength; + FLMUINT uiBase = 10; + char szNumberBuffer [64]; + char * pszStr; + FLMUINT64 ui64Arg; + + if (uiFlags & FORMAT_SHORT_FLAG) + { + ui64Arg = f_va_arg( *args, int); + } + else if (uiFlags & FORMAT_LONG_FLAG) + { + ui64Arg = f_va_arg( *args, long int); + } + else if ( uiFlags & FORMAT_INT64_FLAG) + { + ui64Arg = f_va_arg( *args, FLMUINT64); + } + else + { + ui64Arg = f_va_arg( *args, int); + } + + switch (uiFormatChar) + { + case 'd': + if ((long)ui64Arg < 0) + { + // handle negatives + + uiPrefix = P_MINUS; + if (uiWidth > 0) + { + uiWidth--; + } + ui64Arg = -(long)ui64Arg; + } + else if (uiFlags & FORMAT_PLUS_FLAG) + { + uiPrefix = P_PLUS; + if (uiWidth > 0) + uiWidth--; + } + break; + + case 'o': + uiBase = 8; + break; + + case 'x': + case 'X': + if (uiFlags & FORMAT_POUND_FLAG && ui64Arg) + { + uiPrefix = P_POUND; + if (uiWidth > 1) + { + uiWidth -= 2; + } + } + uiBase = 16; + break; + } + uiLength = traceFormatNumber( ui64Arg, uiBase, szNumberBuffer); + szNumberBuffer [uiLength] = 0; + if (uiFormatChar == 'X') + { + char * p = &szNumberBuffer [0]; + while (*p) + { + if ((*p >= 'a') && (*p <= 'z')) + { + *p = (char)(*p - 'a' + 'A'); + } + p++; + } + } + if (uiWidth < uiLength) + { + uiWidth = uiLength; + } + + if (uiFlags & FORMAT_ZERO_FLAG) + { + uiPrecision = uiWidth; // zero fill + } + else if (!(uiFlags & FORMAT_MINUS_FLAG)) + { + // Right justify. + + while ((uiWidth > uiLength) && + (uiWidth > uiPrecision)) + { + if (!m_uiMaxLen) + { + outputCurrentText( m_uiCurrentForeColor, m_uiCurrentBackColor); + } + *m_pszDestStr++ = ' '; + m_uiMaxLen--; + --uiWidth; + } + } + + // handle the prefix if any + + if (!m_uiMaxLen) + { + outputCurrentText( m_uiCurrentForeColor, m_uiCurrentBackColor); + } + switch (uiPrefix) + { + case P_MINUS: + *m_pszDestStr++ = '-'; + m_uiMaxLen--; + break; + case P_PLUS: + *m_pszDestStr++ = '+'; + m_uiMaxLen--; + break; + case P_POUND: + *m_pszDestStr++ = '0'; + m_uiMaxLen--; + if (!m_uiMaxLen) + { + outputCurrentText( m_uiCurrentForeColor, m_uiCurrentBackColor); + } + *m_pszDestStr++ = (char)uiFormatChar; + m_uiMaxLen--; + break; + } + + // handle the precision + + while (uiLength < uiPrecision) + { + if (!m_uiMaxLen) + { + outputCurrentText( m_uiCurrentForeColor, m_uiCurrentBackColor); + } + *m_pszDestStr++ = '0'; + m_uiMaxLen--; + --uiPrecision; + --uiWidth; + } + + // print out the number + + for (uiCount = uiLength, pszStr = szNumberBuffer; + uiCount > 0; + uiCount--, m_uiMaxLen--) + { + if (!m_uiMaxLen) + { + outputCurrentText( m_uiCurrentForeColor, m_uiCurrentBackColor); + } + *m_pszDestStr++ = *pszStr++; + } + + if (uiFlags & FORMAT_MINUS_FLAG) + { + while (uiLength < uiWidth) // left justify + { + if (!m_uiMaxLen) + { + outputCurrentText( m_uiCurrentForeColor, m_uiCurrentBackColor); + } + *m_pszDestStr++ = ' '; + m_uiMaxLen--; + --uiWidth; + } + } +} + +/**************************************************************************** +Desc: Character formatter. + FOrmats the character specified by VALUE in 'c', or the '%' character. + Format: %[flags][width][.prec]'c' + flags = + width = + prec = +****************************************************************************/ +void F_Trace::formatChar( + FLMUINT uiFormatChar, + f_va_list * args) +{ + char c = (uiFormatChar == '%') + ? '%' + : f_va_arg( *args, int); + + if (!m_uiMaxLen) + { + outputCurrentText( m_uiCurrentForeColor, m_uiCurrentBackColor); + } + *m_pszDestStr++ = c; + m_uiMaxLen--; +} + + +/**************************************************************************** +Desc: Handles all formatting stuff that is invalid. +****************************************************************************/ +void F_Trace::formatNotHandled( void) +{ + const char * pszNoFormatter = ""; + FLMUINT uiLen = f_strlen( pszNoFormatter); + FLMUINT uiTmpLen; + + while (uiLen) + { + if (!m_uiMaxLen) + { + outputCurrentText( m_uiCurrentForeColor, m_uiCurrentBackColor); + } + if ((uiTmpLen = uiLen) > m_uiMaxLen) + { + uiTmpLen = m_uiMaxLen; + } + f_memcpy( m_pszDestStr, (void *)pszNoFormatter, uiTmpLen); + m_pszDestStr += uiTmpLen; + m_uiMaxLen -= uiTmpLen; + uiLen -= uiTmpLen; + pszNoFormatter += uiTmpLen; + } +} + +/**************************************************************************** +Desc: Outputs the current text that we have buffered. +****************************************************************************/ +void F_Trace::outputCurrentText( + FLMUINT uiForeColor, + FLMUINT uiBackColor) +{ + FLMUINT uiLen = (FLMUINT)(m_pszDestStr - &m_szDestStr [0]); + + if (uiLen) + { + m_szDestStr [uiLen] = 0; + outputText( m_uiCategory, uiForeColor, uiBackColor, m_szDestStr); + m_uiMaxLen = sizeof( m_szDestStr) - 1; + m_pszDestStr = &m_szDestStr [0]; + } +} diff --git a/ftk/src/ftkmisc.cpp b/ftk/src/ftkmisc.cpp index 2eb2249..4ff9cca 100644 --- a/ftk/src/ftkmisc.cpp +++ b/ftk/src/ftkmisc.cpp @@ -25,7 +25,7 @@ #include "ftksys.h" -static FLMUINT gv_uiStartupCount = 0; +static FLMATOMIC gv_startupCount = 0; static FLMUINT gv_uiRandomGenInitCount = 0; static F_MUTEX gv_hRandomGenMutex = F_MUTEX_NULL; static IF_RandomGenerator * gv_pRandomGenerator = NULL; @@ -94,13 +94,25 @@ RCODE FLMAPI ftkStartup( void) { RCODE rc = NE_FLM_OK; - if( ++gv_uiStartupCount > 1) + if( f_atomicInc( &gv_startupCount) > 1) { goto Exit; } + // Sanity check -- make sure we are using the correct + // byte-swap macros for this platform + + flmAssert( FB2UD( "\x0A\x0B\x0C\x0D") == 0x0D0C0B0A); + flmAssert( FB2UW( "\x0A\x0B") == 0x0B0A); + f_memoryInit(); +#if defined( FLM_RING_ZERO_NLM) + if( RC_BAD( rc = f_nssInitialize())) + { + goto Exit; + } +#endif f_assert( sizeof( f_va_list) == sizeof( va_list)); @@ -187,7 +199,7 @@ Desc: ****************************************************************************/ void FLMAPI ftkShutdown( void) { - if( !gv_uiStartupCount || --gv_uiStartupCount > 0) + if( !gv_startupCount || f_atomicDec( &gv_startupCount) > 0) { return; } @@ -213,6 +225,11 @@ void FLMAPI ftkShutdown( void) f_freeRandomGenerator(); f_freeCharMappingTables(); + +#if defined( FLM_RING_ZERO_NLM) + f_nssUninitialize(); +#endif + f_memoryCleanup(); } @@ -2183,9 +2200,8 @@ FLMUINT FLMAPI f_strHashBucket( while (*pszStr) { - if ((uiHashIndex = - (FLMUINT)((pHashTbl [uiHashIndex].uiHashValue) ^ (FLMUINT)(f_toupper( *pszStr)))) >= - uiNumBuckets) + if ((uiHashIndex = (FLMUINT)((pHashTbl [uiHashIndex].uiHashValue) ^ + (FLMUINT)(f_toupper( *pszStr)))) >= uiNumBuckets) { uiHashIndex -= uiNumBuckets; } diff --git a/ftk/src/ftkrset.cpp b/ftk/src/ftkrset.cpp index 047cffa..92f5753 100644 --- a/ftk/src/ftkrset.cpp +++ b/ftk/src/ftkrset.cpp @@ -182,7 +182,7 @@ public: RCODE addEntry( FLMBYTE * pEntry, - FLMUINT uiEntryLength ); + FLMUINT uiEntryLength); RCODE modifyEntry( FLMBYTE * pEntry, diff --git a/ftk/src/ftktext.cpp b/ftk/src/ftktext.cpp index eeb07cd..e2a1116 100644 --- a/ftk/src/ftktext.cpp +++ b/ftk/src/ftktext.cpp @@ -7588,3 +7588,32 @@ Exit: return( rc); } +/**************************************************************************** +Desc: +****************************************************************************/ +RCODE FLMAPI f_strdup( + const char * pszSrc, + char ** ppszDup) +{ + RCODE rc = NE_FLM_OK; + char * pszDup = NULL; + + if( RC_BAD( rc = f_alloc( f_strlen( pszSrc) + 1, &pszDup))) + { + goto Exit; + } + + f_strcpy( pszDup, pszSrc); + *ppszDup = pszDup; + pszDup = NULL; + +Exit: + + if( pszDup) + { + f_free( &pszDup); + } + + return( rc); +} + diff --git a/ftk/src/ftkthrd.cpp b/ftk/src/ftkthrd.cpp index 2f2fc85..e790507 100644 --- a/ftk/src/ftkthrd.cpp +++ b/ftk/src/ftkthrd.cpp @@ -59,6 +59,23 @@ public: RCODE FLMAPI setupThreadMgr( void); + FLMINT FLMAPI AddRef( void) + { + return( f_atomicInc( &m_refCnt)); + } + + FLMINT FLMAPI Release( void) + { + FLMINT iRefCnt = f_atomicDec( &m_refCnt); + + if( !iRefCnt) + { + delete this; + } + + return( iRefCnt); + } + RCODE FLMAPI createThread( IF_Thread ** ppThread, F_THREAD_FUNC fnThread,