diff --git a/ftk/Makefile b/ftk/Makefile index 36d51f2..e79bfa9 100644 --- a/ftk/Makefile +++ b/ftk/Makefile @@ -196,7 +196,7 @@ endif # -- Determine if we are only cleaning -- util_targets = -test_targets = basictest +test_targets = ftktest all_targets = rpms install libs all allutils test $(util_targets) $(test_targets) found_targets = $(foreach target,$(MAKECMDGOALS),$(if $(findstring $(target),$(all_targets)),$(target),)) @@ -1178,13 +1178,13 @@ $(sample_exe): $(sample_obj) $(ftk_static_lib) $(call flm_exe_link_cmd,$(sample_dir),sample,$(sample_obj)) $(ec)$(call copycmd,sample/xmlfiles/*.xml,$(sample_dir)) -# -- basictest -- +# -- ftktest -- -.PHONY : basictest -basictest: status clean dircheck $(test_dir)/basictest$(exe_suffix) +.PHONY : ftktest +ftktest: status clean dircheck $(test_dir)/ftktest$(exe_suffix) $(test_dir)/ftktest$(exe_suffix): $(ftk_test_obj) $(ftk_static_lib) $(ec)$(gprintf) "Linking $@ ...\n" - $(call flm_exe_link_cmd,$(test_dir),basictest,$(ftk_test_obj)) + $(call flm_exe_link_cmd,$(test_dir),ftktest,$(ftk_test_obj)) # -- version -- @@ -1486,7 +1486,7 @@ allutils: status dircheck libs $(util_targets) .PHONY : test test: status dircheck $(ftk_static_lib) $(test_targets) - $(ec)$(call runtest,basictest) + $(ec)$(call runtest,ftktest) .PHONY : debug debug: diff --git a/ftk/src/ftk.h b/ftk/src/ftk.h index 547aa68..8aea278 100644 --- a/ftk/src/ftk.h +++ b/ftk/src/ftk.h @@ -155,11 +155,11 @@ // Alignment #if defined( FLM_UNIX) || defined( FLM_64BIT) - #define FLM_ALLOC_ALIGN 0x0007 - #define FLM_ALIGN_SIZE 8 + #define FLM_ALLOC_ALIGN 0x0007 + #define FLM_ALIGN_SIZE 8 #elif defined( FLM_WIN) || defined( FLM_NLM) - #define FLM_ALLOC_ALIGN 0x0003 - #define FLM_ALIGN_SIZE 4 + #define FLM_ALLOC_ALIGN 0x0003 + #define FLM_ALIGN_SIZE 4 #else #error Platform not supported #endif @@ -167,26 +167,26 @@ // Basic type definitions #if defined( FLM_UNIX) - typedef unsigned long FLMUINT; - typedef long FLMINT; - typedef unsigned char FLMBYTE; - typedef unsigned short FLMUNICODE; + typedef unsigned long FLMUINT; + typedef long FLMINT; + typedef unsigned char FLMBYTE; + typedef unsigned short FLMUNICODE; - typedef unsigned long long FLMUINT64; - typedef unsigned int FLMUINT32; - typedef unsigned short FLMUINT16; - typedef unsigned char FLMUINT8; - typedef long long FLMINT64; - typedef int FLMINT32; - typedef short FLMINT16; - typedef signed char FLMINT8; - typedef char * f_va_list; + typedef unsigned long long FLMUINT64; + typedef unsigned int FLMUINT32; + typedef unsigned short FLMUINT16; + typedef unsigned char FLMUINT8; + typedef long long FLMINT64; + typedef int FLMINT32; + typedef short FLMINT16; + typedef signed char FLMINT8; + typedef char * f_va_list; #if defined( FLM_64BIT) || defined( FLM_OSX) || \ defined( FLM_S390) || defined( FLM_HPUX) || defined( FLM_AIX) - typedef unsigned long FLMSIZET; + typedef unsigned long FLMSIZET; #else - typedef unsigned FLMSIZET; + typedef unsigned FLMSIZET; #endif #else @@ -471,6 +471,7 @@ #define FLM_IO_SH_DENYWR 0x0020 #define FLM_IO_SH_DENYNONE 0x0040 #define FLM_IO_DIRECT 0x0080 + #define FLM_IO_DELETE_ON_RELEASE 0x0100 // File Positioning Definitions @@ -697,18 +698,18 @@ typedef struct { - FLMUINT uiLines; - FLMUINT uiChars; - FLMUINT uiAttributes; - FLMUINT uiElements; - FLMUINT uiText; - FLMUINT uiDocuments; - FLMUINT uiErrLineNum; - FLMUINT uiErrLineOffset; // NOTE: This is a zero-based offset - XMLParseError eErrorType; - FLMUINT uiErrLineFilePos; - FLMUINT uiErrLineBytes; - XMLEncoding eXMLEncoding; + FLMUINT uiLines; + FLMUINT uiChars; + FLMUINT uiAttributes; + FLMUINT uiElements; + FLMUINT uiText; + FLMUINT uiDocuments; + FLMUINT uiErrLineNum; + FLMUINT uiErrLineOffset; // NOTE: This is a zero-based offset + XMLParseError eErrorType; + FLMUINT uiErrLineFilePos; + FLMUINT uiErrLineBytes; + XMLEncoding eXMLEncoding; } FLM_IMPORT_STATS; typedef enum @@ -717,11 +718,19 @@ } eXMLStatus; typedef RCODE (* XML_STATUS_HOOK)( - eXMLStatus eStatusType, - void * pvArg1, - void * pvArg2, - void * pvArg3, - void * pvUserData); + eXMLStatus eStatusType, + void * pvArg1, + void * pvArg2, + void * pvArg3, + void * pvUserData); + + /**************************************************************************** + Desc: Startup and shutdown + ****************************************************************************/ + + RCODE FLMAPI ftkStartup( void); + + void FLMAPI ftkShutdown( void); /**************************************************************************** Desc: Reference Counting class @@ -795,7 +804,7 @@ virtual RCODE FLMAPI close( void) = 0; }; - + /**************************************************************************** Desc: ****************************************************************************/ @@ -811,15 +820,45 @@ virtual FLMUINT64 FLMAPI getCurrPosition( void) = 0; }; + /**************************************************************************** + Desc: + ****************************************************************************/ + flminterface IF_BufferIStream : public IF_PosIStream + { + virtual RCODE FLMAPI open( + const FLMBYTE * pucBuffer, + FLMUINT uiLength, + FLMBYTE ** ppucAllocatedBuffer = NULL) = 0; + + virtual FLMUINT64 FLMAPI totalSize( void) = 0; + + virtual FLMUINT64 FLMAPI remainingSize( void) = 0; + + virtual RCODE FLMAPI close( void) = 0; + + virtual RCODE FLMAPI positionTo( + FLMUINT64 ui64Position) = 0; + + virtual FLMUINT64 FLMAPI getCurrPosition( void) = 0; + + virtual RCODE FLMAPI read( + void * pvBuffer, + FLMUINT uiBytesToRead, + FLMUINT * puiBytesRead) = 0; + }; + + RCODE FLMAPI FlmAllocBufferIStream( + IF_BufferIStream ** ppIStream); + /**************************************************************************** Desc: ****************************************************************************/ flminterface IF_OStream : public F_RefCount { virtual RCODE FLMAPI write( - const void * pvBuffer, - FLMUINT uiBytesToWrite, - FLMUINT * puiBytesWritten = NULL) = 0; + const void * pvBuffer, + FLMUINT uiBytesToWrite, + FLMUINT * puiBytesWritten = NULL) = 0; virtual RCODE FLMAPI close( void) = 0; }; @@ -837,7 +876,7 @@ flminterface IF_LoggerClient : public F_RefCount { virtual IF_LogMessageClient * FLMAPI beginMessage( - FLMUINT uiMsgType) = 0; + FLMUINT uiMsgType) = 0; }; /**************************************************************************** @@ -968,27 +1007,15 @@ const char * pszFileName, const char * pszTemplate) = 0; }; + + RCODE FLMAPI FlmGetFileSystem( + IF_FileSystem ** ppFileSystem); /**************************************************************************** Desc: ****************************************************************************/ flminterface IF_FileHdl : public F_RefCount { - virtual RCODE FLMAPI close( void) = 0; - - virtual RCODE FLMAPI create( - const char * pszFileName, - FLMUINT uiIoFlags) = 0; - - virtual RCODE FLMAPI createUnique( - const char * pszDirName, - const char * pszFileExtension, - FLMUINT uiIoFlags) = 0; - - virtual RCODE FLMAPI open( - const char * pszFileName, - FLMUINT uiIoFlags) = 0; - virtual RCODE FLMAPI flush( void) = 0; virtual RCODE FLMAPI read( @@ -1032,6 +1059,8 @@ FLMUINT * puiBytesWrittenRV, FLMBOOL bZeroFill = TRUE) = 0; + virtual RCODE FLMAPI close( void) = 0; + virtual FLMBOOL FLMAPI canDoAsync( void) = 0; virtual void FLMAPI setExtendSize( @@ -1039,56 +1068,61 @@ virtual void FLMAPI setMaxAutoExtendSize( FLMUINT uiMaxAutoExtendSize) = 0; + + virtual void FLMAPI setBlockSize( + FLMUINT uiBlockSize) = 0; + + virtual FLMBOOL FLMAPI isReadOnly( void) = 0; }; - + /**************************************************************************** Desc: ****************************************************************************/ flminterface IF_MultiFileHdl : public F_RefCount { - virtual void FLMAPI close( - FLMBOOL bDelete = FALSE) = 0; - virtual RCODE FLMAPI create( - const char * pszPath) = 0; + const char * pszPath) = 0; virtual RCODE FLMAPI createUnique( - const char * pszPath, - const char * pszFileExtension) = 0; - - virtual RCODE FLMAPI deleteMultiFile( - const char * pszPath) = 0; + const char * pszPath, + const char * pszFileExtension) = 0; virtual RCODE FLMAPI open( - const char * pszPath) = 0; + const char * pszPath) = 0; + + virtual RCODE FLMAPI deleteMultiFile( + const char * pszPath) = 0; virtual RCODE FLMAPI flush( void) = 0; virtual RCODE FLMAPI read( - FLMUINT64 ui64Offset, - FLMUINT uiLength, - void * pvBuffer, - FLMUINT * puiBytesRead) = 0; + FLMUINT64 ui64Offset, + FLMUINT uiLength, + void * pvBuffer, + FLMUINT * puiBytesRead) = 0; virtual RCODE FLMAPI write( - FLMUINT64 ui64Offset, - FLMUINT uiLength, - void * pvBuffer, - FLMUINT * puiBytesWritten) = 0; + FLMUINT64 ui64Offset, + FLMUINT uiLength, + void * pvBuffer, + FLMUINT * puiBytesWritten) = 0; virtual RCODE FLMAPI getPath( - char * pszFilePath) = 0; + char * pszFilePath) = 0; virtual RCODE FLMAPI size( - FLMUINT64 * pui64FileSize) = 0; + FLMUINT64 * pui64FileSize) = 0; virtual RCODE FLMAPI truncate( - FLMUINT64 ui64NewSize) = 0; + FLMUINT64 ui64NewSize) = 0; + + virtual void FLMAPI close( + FLMBOOL bDelete = FALSE) = 0; }; - typedef void (* WRITE_COMPLETION_CB)( - IF_IOBuffer * pWriteBuffer); - + RCODE FLMAPI FlmAllocMultiFileHdl( + IF_MultiFileHdl ** ppFileHdl); + /**************************************************************************** Desc: ****************************************************************************/ @@ -1097,23 +1131,29 @@ virtual RCODE FLMAPI waitForAllPendingIO( void) = 0; virtual void FLMAPI setMaxBuffers( - FLMUINT uiMaxBuffers) = 0; + FLMUINT uiMaxBuffers) = 0; virtual void FLMAPI setMaxBytes( - FLMUINT uiMaxBytes) = 0; + FLMUINT uiMaxBytes) = 0; virtual void FLMAPI enableKeepBuffer( void) = 0; virtual RCODE FLMAPI getBuffer( - IF_IOBuffer ** ppIOBuffer, - FLMUINT uiBufferSize, - FLMUINT uiBlockSize) = 0; + IF_IOBuffer ** ppIOBuffer, + FLMUINT uiBufferSize, + FLMUINT uiBlockSize) = 0; virtual FLMBOOL FLMAPI havePendingIO( void) = 0; virtual FLMBOOL FLMAPI haveUsed( void) = 0; }; + /**************************************************************************** + Desc: + ****************************************************************************/ + typedef void (* WRITE_COMPLETION_CB)( + IF_IOBuffer * pWriteBuffer); + /**************************************************************************** Desc: ****************************************************************************/ @@ -1128,8 +1168,8 @@ } eBufferMgrList; virtual RCODE FLMAPI setupBuffer( - FLMUINT uiBufferSize, - FLMUINT uiBlockSize) = 0; + FLMUINT uiBufferSize, + FLMUINT uiBlockSize) = 0; virtual FLMBYTE * FLMAPI getBuffer( void) = 0; @@ -1138,17 +1178,17 @@ virtual FLMUINT FLMAPI getBlockSize( void) = 0; virtual void FLMAPI notifyComplete( - RCODE rc) = 0; + RCODE rc) = 0; virtual void FLMAPI setCompletionCallback( WRITE_COMPLETION_CB fnCompletion) = 0; virtual void FLMAPI setCompletionCallbackData( - FLMUINT uiBlockNumber, - void * pvData); + FLMUINT uiBlockNumber, + void * pvData); virtual void * FLMAPI getCompletionCallbackData( - FLMUINT uiBlockNumber); + FLMUINT uiBlockNumber); virtual RCODE FLMAPI getCompletionCode( void) = 0; @@ -1173,7 +1213,7 @@ virtual FLMBOOL FLMAPI currentItemIsDir( void) = 0; }; - + /**************************************************************************** Desc: ****************************************************************************/ @@ -1302,27 +1342,30 @@ virtual FLMUINT FLMAPI getBytesAllocated( void) = 0; }; + RCODE FLMAPI FlmAllocPool( + IF_Pool ** ppPool); + /**************************************************************************** Desc: Dynamic buffer ****************************************************************************/ flminterface IF_DynaBuf : public F_RefCount { virtual void FLMAPI truncateData( - FLMUINT uiSize) = 0; + FLMUINT uiSize) = 0; virtual RCODE FLMAPI allocSpace( - FLMUINT uiSize, - void ** ppvPtr) = 0; + FLMUINT uiSize, + void ** ppvPtr) = 0; virtual RCODE FLMAPI appendData( - const void * pvData, - FLMUINT uiSize) = 0; + const void * pvData, + FLMUINT uiSize) = 0; virtual RCODE FLMAPI appendByte( - FLMBYTE ucChar) = 0; + FLMBYTE ucChar) = 0; virtual RCODE FLMAPI appendUniChar( - FLMUNICODE uChar) = 0; + FLMUNICODE uChar) = 0; virtual FLMBYTE * FLMAPI getBufferPtr( void) = 0; @@ -1333,7 +1376,7 @@ virtual FLMUINT FLMAPI getDataLength( void) = 0; virtual RCODE FLMAPI copyFromBuffer( - IF_DynaBuf * pSource) = 0; + IF_DynaBuf * pSource) = 0; }; /**************************************************************************** @@ -1343,7 +1386,7 @@ { virtual void FLMAPI randomize( void) = 0; - virtual void FLMAPI randomSetSeed( + virtual void FLMAPI setSeed( FLMINT32 i32seed) = 0; virtual FLMINT32 FLMAPI getSeed( void) = 0; @@ -1357,58 +1400,62 @@ virtual FLMBOOL FLMAPI getBoolean( void) = 0; }; + RCODE FLMAPI FlmAllocRandomGenerator( + IF_RandomGenerator ** ppRandomGenerator); + /********************************************************************** Desc: Atomic operations **********************************************************************/ FLMINT32 FLMAPI f_atomicInc( - FLMATOMIC * piTarget); + FLMATOMIC * piTarget); FLMINT32 FLMAPI f_atomicDec( - FLMATOMIC * piTarget); + FLMATOMIC * piTarget); FLMINT32 FLMAPI f_atomicExchange( - FLMATOMIC * piTarget, - FLMINT32 i32NewVal); + FLMATOMIC * piTarget, + FLMINT32 i32NewVal); /**************************************************************************** Desc: Mutexes ****************************************************************************/ - typedef void * F_MUTEX; - #define F_MUTEX_NULL NULL + typedef void * F_MUTEX; + #define F_MUTEX_NULL NULL RCODE FLMAPI f_mutexCreate( - F_MUTEX * phMutex); + F_MUTEX * phMutex); void FLMAPI f_mutexDestroy( - F_MUTEX * phMutex); + F_MUTEX * phMutex); void FLMAPI f_mutexLock( - F_MUTEX hMutex); + F_MUTEX hMutex); void FLMAPI f_mutexUnlock( - F_MUTEX hMutex); + F_MUTEX hMutex); void FLMAPI f_assertMutexLocked( - F_MUTEX hMutex); + F_MUTEX hMutex); /**************************************************************************** Desc: Semaphores ****************************************************************************/ - typedef void * F_SEM; - #define F_SEM_NULL NULL + typedef void * F_SEM; + #define F_SEM_NULL NULL + #define F_SEM_WAITFOREVER (0xFFFFFFFF) RCODE FLMAPI f_semCreate( - F_SEM * phSem); + F_SEM * phSem); void FLMAPI f_semDestroy( - F_SEM * phSem); + F_SEM * phSem); RCODE FLMAPI f_semWait( - F_SEM hSem, - FLMUINT uiTimeout); + F_SEM hSem, + FLMUINT uiTimeout); void FLMAPI f_semSignal( - F_SEM hSem); + F_SEM hSem); /**************************************************************************** Desc: Thread manager @@ -1416,32 +1463,45 @@ flminterface IF_ThreadMgr : public F_RefCount { virtual RCODE FLMAPI setupThreadMgr( void) = 0; + + virtual RCODE FLMAPI createThread( + IF_Thread ** ppThread, + F_THREAD_FUNC fnThread, + const char * pszThreadName = NULL, + FLMUINT uiThreadGroup = 0, + FLMUINT uiAppId = 0, + void * pvParm1 = NULL, + void * pvParm2 = NULL, + FLMUINT uiStackSize = F_THREAD_DEFAULT_STACK_SIZE) = 0; virtual void FLMAPI shutdownThreadGroup( - FLMUINT uiThreadGroup) = 0; + FLMUINT uiThreadGroup) = 0; virtual void FLMAPI setThreadShutdownFlag( - FLMUINT uiThreadId) = 0; + FLMUINT uiThreadId) = 0; virtual RCODE FLMAPI findThread( - IF_Thread ** ppThread, - FLMUINT uiThreadGroup, - FLMUINT uiAppId = 0, - FLMBOOL bOkToFindMe = TRUE) = 0; + IF_Thread ** ppThread, + FLMUINT uiThreadGroup, + FLMUINT uiAppId = 0, + FLMBOOL bOkToFindMe = TRUE) = 0; virtual RCODE FLMAPI getNextGroupThread( - IF_Thread ** ppThread, - FLMUINT uiThreadGroup, - FLMUINT * puiThreadId) = 0; + IF_Thread ** ppThread, + FLMUINT uiThreadGroup, + FLMUINT * puiThreadId) = 0; virtual RCODE FLMAPI getThreadInfo( - IF_Pool * pPool, - F_THREAD_INFO ** ppThreadInfo, - FLMUINT * puiNumThreads) = 0; + IF_Pool * pPool, + F_THREAD_INFO ** ppThreadInfo, + FLMUINT * puiNumThreads) = 0; virtual FLMUINT FLMAPI getThreadGroupCount( - FLMUINT uiThreadGroup) = 0; + FLMUINT uiThreadGroup) = 0; }; + + RCODE FLMAPI FlmGetThreadMgr( + IF_ThreadMgr ** ppThreadMgr); /**************************************************************************** Desc: Thread @@ -1449,13 +1509,13 @@ flminterface IF_Thread : public F_RefCount { virtual RCODE FLMAPI startThread( - F_THREAD_FUNC fnThread, - const char * pszThreadName = NULL, - FLMUINT uiThreadGroup = 0, - FLMUINT uiAppId = 0, - void * pvParm1 = NULL, - void * pvParm2 = NULL, - FLMUINT uiStackSize = F_THREAD_DEFAULT_STACK_SIZE) = 0; + F_THREAD_FUNC fnThread, + const char * pszThreadName = NULL, + FLMUINT uiThreadGroup = 0, + FLMUINT uiAppId = 0, + void * pvParm1 = NULL, + void * pvParm2 = NULL, + FLMUINT uiStackSize = F_THREAD_DEFAULT_STACK_SIZE) = 0; virtual void FLMAPI stopThread( void) = 0; @@ -1468,28 +1528,28 @@ virtual void * FLMAPI getParm1( void) = 0; virtual void FLMAPI setParm1( - void * pvParm) = 0; + void * pvParm) = 0; virtual void * FLMAPI getParm2( void) = 0; virtual void FLMAPI setParm2( - void * pvParm) = 0; + void * pvParm) = 0; virtual void FLMAPI setShutdownFlag( void) = 0; virtual FLMBOOL FLMAPI isThreadRunning( void) = 0; virtual void FLMAPI setThreadStatusStr( - const char * pszStatus) = 0; + const char * pszStatus) = 0; virtual void FLMAPI setThreadStatus( - const char * pszBuffer, ...) = 0; + const char * pszBuffer, ...) = 0; virtual void FLMAPI setThreadStatus( - eThreadStatus genericStatus) = 0; + eThreadStatus genericStatus) = 0; virtual void FLMAPI setThreadAppId( - FLMUINT uiAppId) = 0; + FLMUINT uiAppId) = 0; virtual FLMUINT FLMAPI getThreadAppId( void) = 0; @@ -1498,19 +1558,6 @@ virtual void FLMAPI cleanupThread( void) = 0; }; - RCODE FLMAPI f_threadCreate( - IF_Thread ** ppThread, - F_THREAD_FUNC fnThread, - const char * pszThreadName = NULL, - FLMUINT uiThreadGroup = 0, - FLMUINT uiAppId = 0, - void * pvParm1 = NULL, - void * pvParm2 = NULL, - FLMUINT uiStackSize = F_THREAD_DEFAULT_STACK_SIZE); - - void FLMAPI f_threadDestroy( - IF_Thread ** ppThread); - FLMUINT FLMAPI f_threadId( void); /**************************************************************************** @@ -1518,152 +1565,153 @@ ****************************************************************************/ flminterface IF_IniFile : public F_RefCount { - virtual RCODE FLMAPI init( void) = 0; - virtual RCODE FLMAPI read( - const char * pszFileName) = 0; + const char * pszFileName) = 0; virtual RCODE FLMAPI write( void) = 0; virtual FLMBOOL FLMAPI getParam( - const char * pszParamName, - FLMUINT * puiParamVal) = 0; + const char * pszParamName, + FLMUINT * puiParamVal) = 0; virtual FLMBOOL FLMAPI getParam( - const char * pszParamName, - FLMBOOL * pbParamVal) = 0; + const char * pszParamName, + FLMBOOL * pbParamVal) = 0; virtual FLMBOOL FLMAPI getParam( - const char * pszParamName, - char ** ppszParamVal) = 0; + const char * pszParamName, + char ** ppszParamVal) = 0; virtual RCODE FLMAPI setParam( - const char * pszParamName, - FLMUINT uiParamVal) = 0; + const char * pszParamName, + FLMUINT uiParamVal) = 0; virtual RCODE FLMAPI setParam( - const char * pszParamName, - FLMBOOL bParamVal) = 0; + const char * pszParamName, + FLMBOOL bParamVal) = 0; virtual RCODE FLMAPI setParam( - const char * pszParamName, - const char * pszParamVal) = 0; + const char * pszParamName, + const char * pszParamVal) = 0; virtual FLMBOOL FLMAPI testParam( - const char * pszParamName) = 0; + const char * pszParamName) = 0; }; + RCODE FLMAPI FlmAllocIniFile( + IF_IniFile ** ppIniFile); + /**************************************************************************** Desc: Serial numbers ****************************************************************************/ RCODE FLMAPI f_createSerialNumber( - FLMBYTE * pszSerialNumber); + FLMBYTE * pszSerialNumber); /**************************************************************************** Desc: CRC ****************************************************************************/ void FLMAPI f_updateCRC( - const void * pvBuffer, - FLMUINT uiCount, - FLMUINT32 * pui32CRC); + const void * pvBuffer, + FLMUINT uiCount, + FLMUINT32 * pui32CRC); /**************************************************************************** Desc: ****************************************************************************/ char * FLMAPI f_uwtoa( - FLMUINT16 value, - char * ptr); + FLMUINT16 value, + char * ptr); char * FLMAPI f_udtoa( - FLMUINT value, - char * ptr); + FLMUINT value, + char * ptr); char * FLMAPI f_wtoa( - FLMINT16 value, - char * ptr); + FLMINT16 value, + char * ptr); char * FLMAPI f_dtoa( - FLMINT value, - char * ptr); + FLMINT value, + char * ptr); char * FLMAPI f_ui64toa( - FLMUINT64 value, - char * ptr); + FLMUINT64 value, + char * ptr); char * FLMAPI f_i64toa( - FLMINT64 value, - char * ptr); + FLMINT64 value, + char * ptr); FLMINT FLMAPI f_atoi( - const char * ptr); + const char * ptr); FLMINT FLMAPI f_atol( - const char * ptr); + const char * ptr); FLMINT FLMAPI f_atod( - const char * ptr); + const char * ptr); FLMUINT FLMAPI f_atoud( - const char * ptr, - FLMBOOL bAllowUnprefixedHex = FALSE); + const char * ptr, + FLMBOOL bAllowUnprefixedHex = FALSE); FLMUINT64 FLMAPI f_atou64( - const char * pszBuf); + const char * pszBuf); FLMUINT FLMAPI f_unilen( - const FLMUNICODE * puzStr); + const FLMUNICODE * puzStr); FLMUNICODE * FLMAPI f_unicpy( - FLMUNICODE * puzDestStr, - const FLMUNICODE * puzSrcStr); + FLMUNICODE * puzDestStr, + const FLMUNICODE * puzSrcStr); FLMBOOL FLMAPI f_uniIsLower( - FLMUNICODE uzChar); + FLMUNICODE uzChar); FLMBOOL FLMAPI f_uniIsAlpha( - FLMUNICODE uzChar); + FLMUNICODE uzChar); FLMBOOL FLMAPI f_uniIsDecimalDigit( - FLMUNICODE uzChar); + FLMUNICODE uzChar); FLMUNICODE FLMAPI f_unitolower( - FLMUNICODE uChar); + FLMUNICODE uChar); FLMINT FLMAPI f_unicmp( - const FLMUNICODE * puzStr1, - const FLMUNICODE * puzStr2); + const FLMUNICODE * puzStr1, + const FLMUNICODE * puzStr2); FLMINT FLMAPI f_uniicmp( - const FLMUNICODE * puzStr1, - const FLMUNICODE * puzStr2); + const FLMUNICODE * puzStr1, + const FLMUNICODE * puzStr2); FLMINT FLMAPI f_uninativecmp( - const FLMUNICODE * puzStr1, - const char * pszStr2); + const FLMUNICODE * puzStr1, + const char * pszStr2); FLMINT FLMAPI f_uninativencmp( - const FLMUNICODE * puzStr1, - const char * pszStr2, - FLMUINT uiCount); + const FLMUNICODE * puzStr1, + const char * pszStr2, + FLMUINT uiCount); RCODE FLMAPI f_nextUCS2Char( - const FLMBYTE ** ppszUTF8, - const FLMBYTE * pszEndOfUTF8String, - FLMUNICODE * puzChar); + const FLMBYTE ** ppszUTF8, + const FLMBYTE * pszEndOfUTF8String, + FLMUNICODE * puzChar); RCODE FLMAPI f_numUCS2Chars( - const FLMBYTE * pszUTF8, - FLMUINT * puiNumChars); + const FLMBYTE * pszUTF8, + FLMUINT * puiNumChars); RCODE FLMAPI f_readUTF8CharAsUnicode( - IF_IStream * pStream, - FLMUNICODE * puChar); + IF_IStream * pStream, + FLMUNICODE * puChar); RCODE FLMAPI f_formatUTF8Text( - IF_PosIStream * pIStream, - FLMBOOL bAllowEscapes, - FLMUINT uiCompareRules, - IF_DynaBuf * pDynaBuf); + IF_PosIStream * pIStream, + FLMBOOL bAllowEscapes, + FLMUINT uiCompareRules, + IF_DynaBuf * pDynaBuf); /**************************************************************************** Desc: ASCII character constants and macros @@ -1939,7 +1987,18 @@ Desc: Endian macros ****************************************************************************/ - FINLINE FLMUINT32 f_byteToLong( + FINLINE FLMUINT16 f_byteToUINT16( + const FLMBYTE * pucBuf) + { + FLMUINT16 ui16Val = 0; + + ui16Val |= ((FLMUINT16)pucBuf[ 0]) << 8; + ui16Val |= ((FLMUINT16)pucBuf[ 1]); + + return( ui16Val); + } + + FINLINE FLMUINT32 f_byteToUINT32( const FLMBYTE * pucBuf) { FLMUINT32 ui32Val = 0; @@ -1952,7 +2011,7 @@ return( ui32Val); } - FINLINE FLMUINT64 f_byteToLong64( + FINLINE FLMUINT64 f_byteToUINT64( const FLMBYTE * pucBuf) { FLMUINT64 ui64Val = 0; @@ -1969,172 +2028,133 @@ return( ui64Val); } - FLMUINT32 f_byteToInt( const FLMBYTE * ptr); - #define f_byteToInt(p) ( \ - (FLMUINT16) ( ((((FLMBYTE *)(p))[ 0]) << 8) | (((FLMBYTE *)(p))[ 1]) ) ) - - void f_longToByte( FLMINT32 uiNum, FLMBYTE * ptr); - #define f_longToByte( n, p) { \ - FLMUINT32 ui32Temp = (FLMUINT32) (n); FLMBYTE * pTemp = (FLMBYTE *)(p); \ - pTemp[0] = (FLMBYTE) (ui32Temp >> 24); \ - pTemp[1] = (FLMBYTE) (ui32Temp >> 16); \ - pTemp[2] = (FLMBYTE) (ui32Temp >> 8); \ - pTemp[3] = (FLMBYTE) (ui32Temp ); \ - } - - void f_long64ToByte( FLMINT64 uiNum, FLMBYTE * ptr); - #define f_long64ToByte( n, p) { \ - FLMUINT64 ui64Temp = (FLMUINT64) (n); FLMBYTE * pTemp = (FLMBYTE *)(p); \ - pTemp[0] = (FLMBYTE) (ui64Temp >> 56); \ - pTemp[1] = (FLMBYTE) (ui64Temp >> 48); \ - pTemp[2] = (FLMBYTE) (ui64Temp >> 40); \ - pTemp[3] = (FLMBYTE) (ui64Temp >> 32); \ - pTemp[4] = (FLMBYTE) (ui64Temp >> 24); \ - pTemp[5] = (FLMBYTE) (ui64Temp >> 16); \ - pTemp[6] = (FLMBYTE) (ui64Temp >> 8); \ - pTemp[7] = (FLMBYTE) (ui64Temp ); \ - } - - void f_intToByte( FLMINT16 uiNum, FLMBYTE * ptr); - #define f_intToByte( n, p) { \ - FLMUINT16 ui16Temp = (FLMUINT16) (n); FLMBYTE * pTemp = (FLMBYTE *) (p); \ - pTemp[0] = (FLMBYTE) (ui16Temp >> 8); \ - pTemp[1] = (FLMBYTE) (ui16Temp ); \ - } - - #ifndef FLM_BIG_ENDIAN - - #if defined( FLM_SPARC) - #error Wrong endian order selected - #endif + FINLINE void f_UIN16ToByte( + FLMUINT16 ui16Num, + FLMBYTE * pucBuf) + { + pucBuf[ 0] = (FLMBYTE) (ui16Num >> 8); + pucBuf[ 1] = (FLMBYTE) (ui16Num); + } - #define LO(wrd) (*(FLMUINT8 *)&wrd) - #define HI(wrd) (*((FLMUINT8 *)&wrd + 1)) - - #if defined( FLM_STRICT_ALIGNMENT) - - #define FB2UW( bp) \ - ((FLMUINT16)((((FLMUINT16)(((FLMUINT8 *)(bp))[1])) << 8) | \ - (((FLMUINT16)(((FLMUINT8 *)(bp))[0]))))) + FINLINE void f_UIN32ToByte( + FLMUINT32 ui32Num, + FLMBYTE * pucBuf) + { + pucBuf[ 0] = (FLMBYTE) (ui32Num >> 24); + pucBuf[ 1] = (FLMBYTE) (ui32Num >> 16); + pucBuf[ 2] = (FLMBYTE) (ui32Num >> 8); + pucBuf[ 3] = (FLMBYTE) (ui32Num); + } - #define FB2UD( bp) \ - ((FLMUINT32)((((FLMUINT32)(((FLMUINT8 *)(bp))[3]))<< 24) | \ - (((FLMUINT32)(((FLMUINT8 *)(bp))[2]))<< 16) | \ - (((FLMUINT32)(((FLMUINT8 *)(bp))[1]))<< 8) | \ - (((FLMUINT32)(((FLMUINT8 *)(bp))[0]))))) - - #define FB2U64( bp) \ - ((FLMUINT64)((((FLMUINT64)(((FLMUINT8 *)(bp))[7])) << 56) | \ - (((FLMUINT64)(((FLMUINT8 *)(bp))[6])) << 48) | \ - (((FLMUINT64)(((FLMUINT8 *)(bp))[5])) << 40) | \ - (((FLMUINT64)(((FLMUINT8 *)(bp))[4])) << 32) | \ - (((FLMUINT64)(((FLMUINT8 *)(bp))[3])) << 24) | \ - (((FLMUINT64)(((FLMUINT8 *)(bp))[2])) << 16) | \ - (((FLMUINT64)(((FLMUINT8 *)(bp))[1]))<< 8) | \ - (((FLMUINT64)(((FLMUINT8 *)(bp))[0]))))) - - #define UW2FBA( uw, bp) \ - (((FLMUINT8 *)(bp))[0] = ((FLMUINT8)(uw)), \ - ((FLMUINT8 *)(bp))[1] = ((FLMUINT8)((((uw) & 0xff00) >> 8)))) - - #define UD2FBA( udw, bp) \ - (((FLMUINT8 *)(bp))[0] = ((FLMUINT8)((udw) & 0xff)), \ - ((FLMUINT8 *)(bp))[1] = ((FLMUINT8)(((udw) & 0xff00) >> 8)), \ - ((FLMUINT8 *)(bp))[2] = ((FLMUINT8)(((udw) & 0xff0000) >> 16)), \ - ((FLMUINT8 *)(bp))[3] = ((FLMUINT8)(((udw) & 0xff000000) >> 24))) - - #define U642FBA( u64, bp) \ - (((FLMUINT8 *)(bp))[0] = ((FLMUINT8)((u64) & 0xff)), \ - ((FLMUINT8 *)(bp))[1] = ((FLMUINT8)(((u64) & 0xff00) >> 8)), \ - ((FLMUINT8 *)(bp))[2] = ((FLMUINT8)(((u64) & 0xff0000) >> 16)), \ - ((FLMUINT8 *)(bp))[3] = ((FLMUINT8)(((u64) & 0xff000000) >> 24)), \ - ((FLMUINT8 *)(bp))[4] = ((FLMUINT8)(((u64) & 0xff00000000) >> 32)), \ - ((FLMUINT8 *)(bp))[5] = ((FLMUINT8)(((u64) & 0xff0000000000) >> 40)), \ - ((FLMUINT8 *)(bp))[6] = ((FLMUINT8)(((u64) & 0xff000000000000) >> 48)), \ - ((FLMUINT8 *)(bp))[7] = ((FLMUINT8)(((u64) & 0xff00000000000000) >> 56))) - #else - #define FB2UW( fbp) \ - (*((FLMUINT16 *)(fbp))) - - #define FB2UD( fbp) \ - (*((FLMUINT32 *)(fbp))) - - #define FB2U64( fbp) \ - (*((FLMUINT64 *)(fbp))) - - #define UW2FBA( uw, fbp) \ - (*((FLMUINT16 *)(fbp)) = ((FLMUINT16) (uw))) - - #define UD2FBA( uw, fbp) \ - (*((FLMUINT32 *)(fbp)) = ((FLMUINT32) (uw))) - - #define U642FBA( uw, fbp) \ - (*((FLMUINT64 *)(fbp)) = ((FLMUINT64) (uw))) - #endif + FINLINE void f_UIN64ToByte( + FLMUINT64 ui64Num, + FLMBYTE * pucBuf) + { + pucBuf[ 0] = (FLMBYTE) (ui64Num >> 56); + pucBuf[ 1] = (FLMBYTE) (ui64Num >> 48); + pucBuf[ 2] = (FLMBYTE) (ui64Num >> 40); + pucBuf[ 3] = (FLMBYTE) (ui64Num >> 32); + pucBuf[ 4] = (FLMBYTE) (ui64Num >> 24); + pucBuf[ 5] = (FLMBYTE) (ui64Num >> 16); + pucBuf[ 6] = (FLMBYTE) (ui64Num >> 8); + pucBuf[ 7] = (FLMBYTE) (ui64Num); + } - #else - - #if defined( __i386__) - #error Wrong endian order selected - #endif - - #define LO( wrd) \ - (*((FLMUINT8 *)&wrd + 1)) + #if defined( FLM_STRICT_ALIGNMENT) || defined( FLM_BIG_ENDIAN) + + FINLINE FLMUINT16 FB2UW( + const FLMBYTE * pucBuf) + { + FLMUINT16 ui16Val = 0; - #define HI( wrd) \ - (*(FLMUINT8 *)&wrd) + ui16Val |= ((FLMUINT16)pucBuf[ 1]) << 8; + ui16Val |= ((FLMUINT16)pucBuf[ 0]); + + return( ui16Val); + } - #define FB2UW( bp) \ - ((FLMUINT16)((((FLMUINT16)(((FLMUINT8 *)(bp))[1])) << 8) | \ - (((FLMUINT16)(((FLMUINT8 *)(bp))[0]))))) + FINLINE FLMUINT32 FB2UD( + const FLMBYTE * pucBuf) + { + FLMUINT32 ui32Val = 0; + + ui32Val |= ((FLMUINT32)pucBuf[ 3]) << 24; + ui32Val |= ((FLMUINT32)pucBuf[ 2]) << 16; + ui32Val |= ((FLMUINT32)pucBuf[ 1]) << 8; + ui32Val |= ((FLMUINT32)pucBuf[ 0]); + + return( ui32Val); + } + + FINLINE FLMUINT64 FB2U64( + const FLMBYTE * pucBuf) + { + FLMUINT64 ui64Val = 0; + + ui64Val |= ((FLMUINT64)pucBuf[ 7]) << 56; + ui64Val |= ((FLMUINT64)pucBuf[ 6]) << 48; + ui64Val |= ((FLMUINT64)pucBuf[ 5]) << 40; + ui64Val |= ((FLMUINT64)pucBuf[ 4]) << 32; + ui64Val |= ((FLMUINT64)pucBuf[ 3]) << 24; + ui64Val |= ((FLMUINT64)pucBuf[ 2]) << 16; + ui64Val |= ((FLMUINT64)pucBuf[ 1]) << 8; + ui64Val |= ((FLMUINT64)pucBuf[ 0]); + + return( ui64Val); + } + + FINLINE void UW2FBA( + FLMUINT16 ui16Num, + FLMBYTE * pucBuf) + { + pucBuf[ 1] = (FLMBYTE) (ui16Num >> 8); + pucBuf[ 0] = (FLMBYTE) (ui16Num); + } + + FINLINE void UD2FBA( + FLMUINT32 ui32Num, + FLMBYTE * pucBuf) + { + pucBuf[ 3] = (FLMBYTE) (ui32Num >> 24); + pucBuf[ 2] = (FLMBYTE) (ui32Num >> 16); + pucBuf[ 1] = (FLMBYTE) (ui32Num >> 8); + pucBuf[ 0] = (FLMBYTE) (ui32Num); + } + + FINLINE void U642FBA( + FLMUINT64 ui64Num, + FLMBYTE * pucBuf) + { + pucBuf[ 7] = (FLMBYTE) (ui64Num >> 56); + pucBuf[ 6] = (FLMBYTE) (ui64Num >> 48); + pucBuf[ 5] = (FLMBYTE) (ui64Num >> 40); + pucBuf[ 4] = (FLMBYTE) (ui64Num >> 32); + pucBuf[ 3] = (FLMBYTE) (ui64Num >> 24); + pucBuf[ 2] = (FLMBYTE) (ui64Num >> 16); + pucBuf[ 1] = (FLMBYTE) (ui64Num >> 8); + pucBuf[ 0] = (FLMBYTE) (ui64Num); + } + + #else + + #define FB2UW( fbp) \ + (*((FLMUINT16 *)(fbp))) + + #define FB2UD( fbp) \ + (*((FLMUINT32 *)(fbp))) + + #define FB2U64( fbp) \ + (*((FLMUINT64 *)(fbp))) + + #define UW2FBA( uw, fbp) \ + (*((FLMUINT16 *)(fbp)) = ((FLMUINT16) (uw))) + + #define UD2FBA( uw, fbp) \ + (*((FLMUINT32 *)(fbp)) = ((FLMUINT32) (uw))) + + #define U642FBA( uw, fbp) \ + (*((FLMUINT64 *)(fbp)) = ((FLMUINT64) (uw))) - #define FB2UD( bp) \ - ((FLMUINT32)((((FLMUINT32)(((FLMUINT8 *)(bp))[3])) << 24) | \ - (((FLMUINT32)(((FLMUINT8 *)(bp))[2])) << 16) | \ - (((FLMUINT32)(((FLMUINT8 *)(bp))[1])) << 8) | \ - (((FLMUINT32)(((FLMUINT8 *)(bp))[0]))))) - - #define FB2U64( bp) \ - ((FLMUINT64)((((FLMUINT64)(((FLMUINT8 *)(bp))[7])) << 56) | \ - (((FLMUINT64)(((FLMUINT8 *)(bp))[6])) << 48) | \ - (((FLMUINT64)(((FLMUINT8 *)(bp))[5])) << 40) | \ - (((FLMUINT64)(((FLMUINT8 *)(bp))[4])) << 32) | \ - (((FLMUINT64)(((FLMUINT8 *)(bp))[3])) << 24) | \ - (((FLMUINT64)(((FLMUINT8 *)(bp))[2])) << 16) | \ - (((FLMUINT64)(((FLMUINT8 *)(bp))[1])) << 8) | \ - (((FLMUINT64)(((FLMUINT8 *)(bp))[0]))))) - - #define UW2FBA( uw, bp) \ - (((FLMUINT8 *)(bp))[0] = ((FLMUINT8)(uw)), \ - ((FLMUINT8 *)(bp))[1] = ((FLMUINT8)((((uw) & 0xff00) >> 8)))) - - #define UD2FBA( udw, bp) \ - (((FLMUINT8 *)(bp))[0] = ((FLMUINT8)((udw) & 0xff)), \ - ((FLMUINT8 *)(bp))[1] = ((FLMUINT8)(((udw) & 0xff00) >> 8)), \ - ((FLMUINT8 *)(bp))[2] = ((FLMUINT8)(((udw) & 0xff0000) >> 16)), \ - ((FLMUINT8 *)(bp))[3] = ((FLMUINT8)(((udw) & 0xff000000) >> 24))) - - #ifdef FLM_UNIX - #define U642FBA( u64, bp) \ - (((FLMUINT8 *)(bp))[0] = ((FLMUINT8)((u64) & 0xffULL)), \ - ((FLMUINT8 *)(bp))[1] = ((FLMUINT8)(((u64) & 0xff00ULL) >> 8)), \ - ((FLMUINT8 *)(bp))[2] = ((FLMUINT8)(((u64) & 0xff0000ULL) >> 16)), \ - ((FLMUINT8 *)(bp))[3] = ((FLMUINT8)(((u64) & 0xff000000ULL) >> 24)), \ - ((FLMUINT8 *)(bp))[4] = ((FLMUINT8)(((u64) & 0xff00000000ULL) >> 32)), \ - ((FLMUINT8 *)(bp))[5] = ((FLMUINT8)(((u64) & 0xff0000000000ULL) >> 40)), \ - ((FLMUINT8 *)(bp))[6] = ((FLMUINT8)(((u64) & 0xff000000000000ULL) >> 48)), \ - ((FLMUINT8 *)(bp))[7] = ((FLMUINT8)(((u64) & 0xff00000000000000ULL) >> 56))) - #else - #define U642FBA( u64, bp) \ - (((FLMUINT8 *)(bp))[0] = ((FLMUINT8)((u64) & 0xff)), \ - ((FLMUINT8 *)(bp))[1] = ((FLMUINT8)(((u64) & 0xff00) >> 8)), \ - ((FLMUINT8 *)(bp))[2] = ((FLMUINT8)(((u64) & 0xff0000) >> 16)), \ - ((FLMUINT8 *)(bp))[3] = ((FLMUINT8)(((u64) & 0xff000000) >> 24)), \ - ((FLMUINT8 *)(bp))[4] = ((FLMUINT8)(((u64) & 0xff00000000) >> 32)), \ - ((FLMUINT8 *)(bp))[5] = ((FLMUINT8)(((u64) & 0xff0000000000) >> 40)), \ - ((FLMUINT8 *)(bp))[6] = ((FLMUINT8)(((u64) & 0xff000000000000) >> 48)), \ - ((FLMUINT8 *)(bp))[7] = ((FLMUINT8)(((u64) & 0xff00000000000000) >> 56))) - #endif #endif /**************************************************************************** @@ -2194,23 +2214,11 @@ Desc: CPU release and sleep functions ****************************************************************************/ -// #ifdef FLM_NLM -// #define f_yieldCPU() \ -// pthread_yield() -// #else -// #define f_yieldCPU() -// #endif - void FLMAPI f_yieldCPU( void); void FLMAPI f_sleep( FLMUINT uiMilliseconds); -// #ifdef FLM_WIN -// #define f_sleep( uiMilliseconds) \ -// Sleep( (DWORD)uiMilliseconds) -// #endif - /**************************************************************************** Desc: Time, date, timestamp functions ****************************************************************************/ @@ -2302,38 +2310,38 @@ ****************************************************************************/ FLMINT FLMAPI f_vsprintf( - char * pszDestStr, - const char * pszFormat, - f_va_list * args); + char * pszDestStr, + const char * pszFormat, + f_va_list * args); FLMINT FLMAPI f_sprintf( - char * pszDestStr, - const char * pszFormat, + char * pszDestStr, + const char * pszFormat, ...); /**************************************************************************** Desc: ****************************************************************************/ - void FLMAPI f_memcpy( + void * FLMAPI f_memcpy( void * pvDest, const void * pvSrc, - FLMUINT uiLength); + FLMSIZET uiLength); - void FLMAPI f_memmove( + void * FLMAPI f_memmove( void * pvDest, const void * pvSrc, - FLMUINT uiLength); + FLMSIZET uiLength); - void FLMAPI f_memset( + void * FLMAPI f_memset( void * pvDest, unsigned char ucByte, - FLMUINT uiLength); + FLMSIZET uiLength); FLMINT FLMAPI f_memcmp( const void * pvStr1, const void * pvStr2, - FLMUINT uiLength); + FLMSIZET uiLength); FLMINT FLMAPI f_strcat( char * pszDest, @@ -2342,7 +2350,7 @@ FLMINT FLMAPI f_strncat( char * pszDest, const char * pszSrc, - FLMUINT uiLength); + FLMSIZET uiLength); const char * FLMAPI f_strchr( const char * pszStr, @@ -2366,7 +2374,7 @@ FLMINT FLMAPI f_strncmp( const char * pszStr1, const char * pszStr2, - FLMUINT uiLength); + FLMSIZET uiLength); FLMINT FLMAPI f_stricmp( const char * pszStr1, @@ -2375,16 +2383,16 @@ FLMINT FLMAPI f_strnicmp( const char * pszStr1, const char * pszStr2, - FLMUINT uiLength); + FLMSIZET uiLength); - FLMINT FLMAPI f_strcpy( + char * FLMAPI f_strcpy( char * pszDest, const char * pszSrc); - FLMINT FLMAPI f_strncpy( + char * FLMAPI f_strncpy( char * pszDest, const char * pszSrc, - FLMUINT uiLength); + FLMSIZET uiLength); FLMINT FLMAPI f_strlen( const char * pszStr); @@ -2421,50 +2429,52 @@ Desc: Memory ****************************************************************************/ - RCODE FLMAPI f_alloc( + RCODE FLMAPI f_allocImp( FLMUINT uiSize, void ** ppvPtr, - const char * pszFile = __FILE__, - int iLine = __LINE__); + FLMBOOL bFromNewOp, + const char * pszFile, + int iLine); #define f_alloc(s,p) \ - f_alloc((s),(void **)p) + f_allocImp( (s), (void **)p, FALSE, __FILE__, __LINE__) - RCODE FLMAPI f_calloc( + RCODE FLMAPI f_callocImp( FLMUINT uiSize, void ** ppvPtr, - const char * pszFile = __FILE__, - int iLine = __LINE__); + const char * pszFile, + int iLine); #define f_calloc(s,p) \ - f_calloc((s),(void **)p) + f_callocImp( (s), (void **)p, __FILE__, __LINE__) - RCODE FLMAPI f_realloc( + RCODE FLMAPI f_reallocImp( FLMUINT uiSize, void ** ppvPtr, - const char * pszFile = __FILE__, - int iLine = __LINE__); + const char * pszFile, + int iLine); #define f_realloc(s,p) \ - f_realloc((s),(void **)p) + f_reallocImp( (s), (void **)p, __FILE__, __LINE__) - RCODE FLMAPI f_recalloc( + RCODE FLMAPI f_recallocImp( FLMUINT uiSize, void ** ppvPtr, - const char * pszFile = __FILE__, - int iLine = __LINE__); + const char * pszFile, + int iLine); #define f_recalloc(s,p) \ - f_recalloc((s),(void **)p) + f_recallocImp( (s), (void **)p, __FILE__, __LINE__) #define f_new \ new( __FILE__, __LINE__) - RCODE FLMAPI f_free( - void ** ppvPtr); + void FLMAPI f_freeImp( + void ** ppvPtr, + FLMBOOL bFromDelOp); #define f_free(p) \ - f_free( (void **)p) + f_freeImp( (void **)p, FALSE) /**************************************************************************** Desc: Logging @@ -2495,41 +2505,41 @@ virtual RCODE FLMAPI setup( void) = 0; virtual FLMBOOL FLMAPI isPubidChar( - FLMUNICODE uChar) = 0; + FLMUNICODE uChar) = 0; virtual FLMBOOL FLMAPI isQuoteChar( - FLMUNICODE uChar) = 0; + FLMUNICODE uChar) = 0; virtual FLMBOOL FLMAPI isWhitespace( - FLMUNICODE uChar) = 0; + FLMUNICODE uChar) = 0; virtual FLMBOOL FLMAPI isExtender( - FLMUNICODE uChar) = 0; + FLMUNICODE uChar) = 0; virtual FLMBOOL FLMAPI isCombiningChar( - FLMUNICODE uChar) = 0; + FLMUNICODE uChar) = 0; virtual FLMBOOL FLMAPI isNameChar( - FLMUNICODE uChar) = 0; + FLMUNICODE uChar) = 0; virtual FLMBOOL FLMAPI isNCNameChar( - FLMUNICODE uChar) = 0; + FLMUNICODE uChar) = 0; virtual FLMBOOL FLMAPI isIdeographic( - FLMUNICODE uChar) = 0; + FLMUNICODE uChar) = 0; virtual FLMBOOL FLMAPI isBaseChar( - FLMUNICODE uChar) = 0; + FLMUNICODE uChar) = 0; virtual FLMBOOL FLMAPI isDigit( - FLMUNICODE uChar) = 0; + FLMUNICODE uChar) = 0; virtual FLMBOOL FLMAPI isLetter( - FLMUNICODE uChar) = 0; + FLMUNICODE uChar) = 0; virtual FLMBOOL FLMAPI isNameValid( - FLMUNICODE * puzName, - FLMBYTE * pszName) = 0; + FLMUNICODE * puzName, + FLMBYTE * pszName) = 0; }; /**************************************************************************** @@ -2987,16 +2997,16 @@ virtual void FLMAPI reset( void) = 0; virtual RCODE FLMAPI import( - IF_IStream * pStream, - FLMUINT uiFlags, - IF_DOMNode * pNodeToLinkTo, - eNodeInsertLoc eInsertLoc, - IF_DOMNode ** ppNewNode, - FLM_IMPORT_STATS * pImportStats) = 0; + IF_IStream * pStream, + FLMUINT uiFlags, + IF_DOMNode * pNodeToLinkTo, + eNodeInsertLoc eInsertLoc, + IF_DOMNode ** ppNewNode, + FLM_IMPORT_STATS * pImportStats) = 0; virtual void FLMAPI setStatusCallback( - XML_STATUS_HOOK fnStatus, - void * pvUserData) = 0; + XML_STATUS_HOOK fnStatus, + void * pvUserData) = 0; }; /**************************************************************************** @@ -3102,17 +3112,17 @@ virtual FLMUINT FLMAPI getBlockSize( void) = 0; virtual RCODE FLMAPI getBlock( - FLMUINT32 ui32BlockId, - IF_Block ** ppBlock) = 0; + FLMUINT32 ui32BlockId, + IF_Block ** ppBlock) = 0; virtual RCODE FLMAPI createBlock( - IF_Block ** ppBlock) = 0; + IF_Block ** ppBlock) = 0; virtual RCODE FLMAPI freeBlock( - IF_Block ** ppBlock) = 0; + IF_Block ** ppBlock) = 0; virtual RCODE FLMAPI prepareForUpdate( - IF_Block ** ppBlock) = 0; + IF_Block ** ppBlock) = 0; }; /**************************************************************************** @@ -3121,11 +3131,11 @@ flminterface IF_Relocator : public F_RefCount { virtual void FLMAPI relocate( - void * pvOldAlloc, - void * pvNewAlloc) = 0; + void * pvOldAlloc, + void * pvNewAlloc) = 0; virtual FLMBOOL FLMAPI canRelocate( - void * pvOldAlloc) = 0; + void * pvOldAlloc) = 0; }; /**************************************************************************** @@ -3134,20 +3144,20 @@ flminterface IF_SlabManager : public F_RefCount { virtual RCODE FLMAPI setup( - FLMUINT uiPreallocSize) = 0; + FLMUINT uiPreallocSize) = 0; virtual RCODE FLMAPI allocSlab( - void ** ppSlab, - FLMBOOL bMutexLocked) = 0; + void ** ppSlab, + FLMBOOL bMutexLocked) = 0; virtual void FLMAPI freeSlab( - void ** ppSlab, - FLMBOOL bMutexLocked) = 0; + void ** ppSlab, + FLMBOOL bMutexLocked) = 0; virtual RCODE FLMAPI resize( - FLMUINT uiNumBytes, - FLMUINT * puiActualSize = NULL, - FLMBOOL bMutexLocked = FALSE) = 0; + FLMUINT uiNumBytes, + FLMUINT * puiActualSize = NULL, + FLMBOOL bMutexLocked = FALSE) = 0; virtual void FLMAPI incrementTotalBytesAllocated( FLMUINT uiCount, @@ -3168,12 +3178,6 @@ virtual FLMUINT FLMAPI totalBytesAllocated( void) = 0; virtual FLMUINT FLMAPI availSlabs( void) = 0; - - virtual void FLMAPI protectSlab( - void * pSlab) = 0; - - virtual void FLMAPI unprotectSlab( - void * pSlab) = 0; }; /**************************************************************************** @@ -3185,19 +3189,18 @@ virtual RCODE FLMAPI setup( IF_Relocator * pRelocator, IF_SlabManager * pSlabManager, - FLMBOOL bMemProtect, FLMUINT uiCellSize, FLM_SLAB_USAGE * pUsageStats) = 0; virtual void * FLMAPI allocCell( - IF_Relocator * pRelocator, - void * pvInitialData = NULL, - FLMUINT uiDataSize = 0, - FLMBOOL bMutexLocked = FALSE) = 0; + IF_Relocator * pRelocator, + void * pvInitialData = NULL, + FLMUINT uiDataSize = 0, + FLMBOOL bMutexLocked = FALSE) = 0; virtual void FLMAPI freeCell( - void * ptr, - FLMBOOL bMutexLocked) = 0; + void * ptr, + FLMBOOL bMutexLocked) = 0; virtual void FLMAPI freeUnused( void) = 0; @@ -3206,12 +3209,6 @@ virtual FLMUINT FLMAPI getCellSize( void) = 0; virtual void FLMAPI defragmentMemory( void) = 0; - - virtual void FLMAPI protectCell( - void * pvCell) = 0; - - virtual void FLMAPI unprotectCell( - void * pvCell) = 0; }; /**************************************************************************** @@ -3221,33 +3218,32 @@ { virtual RCODE FLMAPI setup( IF_SlabManager * pSlabManager, - FLMBOOL bMemProtect, FLM_SLAB_USAGE * pUsageStats) = 0; virtual RCODE FLMAPI allocBuf( - IF_Relocator * pRelocator, - FLMUINT uiSize, - void * pvInitialData, - FLMUINT uiDataSize, - FLMBYTE ** ppucBuffer, - FLMBOOL * pbAllocatedOnHeap = NULL) = 0; + IF_Relocator * pRelocator, + FLMUINT uiSize, + void * pvInitialData, + FLMUINT uiDataSize, + FLMBYTE ** ppucBuffer, + FLMBOOL * pbAllocatedOnHeap = NULL) = 0; virtual RCODE FLMAPI reallocBuf( - IF_Relocator * pRelocator, - FLMUINT uiOldSize, - FLMUINT uiNewSize, - void * pvInitialData, - FLMUINT uiDataSize, - FLMBYTE ** ppucBuffer, - FLMBOOL * pbAllocatedOnHeap = NULL) = 0; + IF_Relocator * pRelocator, + FLMUINT uiOldSize, + FLMUINT uiNewSize, + void * pvInitialData, + FLMUINT uiDataSize, + FLMBYTE ** ppucBuffer, + FLMBOOL * pbAllocatedOnHeap = NULL) = 0; virtual void FLMAPI freeBuf( - FLMUINT uiSize, - FLMBYTE ** ppucBuffer) = 0; + FLMUINT uiSize, + FLMBYTE ** ppucBuffer) = 0; virtual FLMUINT FLMAPI getTrueSize( - FLMUINT uiSize, - FLMBYTE * pucBuffer) = 0; + FLMUINT uiSize, + FLMBYTE * pucBuffer) = 0; virtual void FLMAPI defragmentMemory( void) = 0; }; @@ -3259,7 +3255,6 @@ { virtual RCODE FLMAPI setup( IF_SlabManager * pSlabManager, - FLMBOOL bMemProtect, FLMUINT * puiCellSizes, FLM_SLAB_USAGE * pUsageStats) = 0; @@ -3283,14 +3278,6 @@ virtual FLMUINT FLMAPI getTrueSize( FLMBYTE * pucBuffer) = 0; - virtual void FLMAPI protectBuffer( - void * pvBuffer, - FLMBOOL bMutexLocked = FALSE) = 0; - - virtual void FLMAPI unprotectBuffer( - void * pvBuffer, - FLMBOOL bMutexLocked = FALSE) = 0; - virtual void FLMAPI lockMutex( void) = 0; virtual void FLMAPI unlockMutex( void) = 0; @@ -3312,20 +3299,20 @@ ((tmp) = (a), (a) = (b), (b) = (tmp)) RCODE FLMAPI f_filecpy( - const char * pszSourceFile, - const char * pszData); + const char * pszSourceFile, + const char * pszData); RCODE FLMAPI f_filecat( - const char * pszSourceFile, - const char * pszData); + const char * pszSourceFile, + const char * pszData); RCODE FLMAPI f_copyPartial( - IF_FileHdl * pSrcFileHdl, - FLMUINT64 ui64SrcOffset, - FLMUINT64 ui64SrcSize, - IF_FileHdl * pDestFileHdl, - FLMUINT64 ui64DestOffset, - FLMUINT64 * pui64BytesCopiedRV); + IF_FileHdl * pSrcFileHdl, + FLMUINT64 ui64SrcOffset, + FLMUINT64 ui64SrcSize, + IF_FileHdl * pDestFileHdl, + FLMUINT64 ui64DestOffset, + FLMUINT64 * pui64BytesCopiedRV); /**************************************************************************** Desc: Status and return codes @@ -3342,7 +3329,7 @@ #define FTK_ERROR_BASE(e) ((RCODE)((int)(0x81055000+(e)))) const char * FLMAPI f_errorString( - RCODE rc); + RCODE rc); /**************************************************************************** Desc: General errors @@ -3388,8 +3375,9 @@ #define NE_FLM_NOT_UNIQUE FTK_ERROR_BASE( 0x124) // Non-unique key #define NE_FLM_BTREE_ERROR FTK_ERROR_BASE( 0x125) // Generic b-tree error #define NE_FLM_BTREE_KEY_SIZE FTK_ERROR_BASE( 0x126) // Invalid b-tree key size - #define NE_FLM_BTREE_FULL FTK_ERROR_BASE( 0x127) // B-tree cannot grow beyond current size - #define NE_FLM_LAST_GENERAL_ERROR FTK_ERROR_BASE( 0x128) // NOTE: This is not an error code - do not document + #define NE_FLM_BTREE_FULL FTK_ERROR_BASE( 0x127) // B-tree cannot grow beyond current size + #define NE_FLM_BTREE_BAD_STATE FTK_ERROR_BASE( 0x128) // B-tree operation cannot be completed + #define NE_FLM_LAST_GENERAL_ERROR FTK_ERROR_BASE( 0x129) // NOTE: This is not an error code - do not document /**************************************************************************** Desc: I/O Errors @@ -3439,8 +3427,7 @@ #define NE_FLM_CHECKING_FILE_EXISTENCE FTK_ERROR_BASE( 0x229) // Unexpected error occurred while checking to see if a file exists. #define NE_FLM_RENAMING_FILE FTK_ERROR_BASE( 0x22A) // Unexpected error occurred while renaming a file. #define NE_FLM_SETTING_FILE_INFO FTK_ERROR_BASE( 0x22B) // Unexpected error occurred while setting a file's information. - #define NE_FLM_BTREE_BAD_STATE FTK_ERROR_BASE( 0x22C) - #define NE_FLM_LAST_IO_ERROR FTK_ERROR_BASE( 0x22D) // NOTE: This is not an error code - do not document + #define NE_FLM_LAST_IO_ERROR FTK_ERROR_BASE( 0x22C) // NOTE: This is not an error code - do not document /**************************************************************************** Desc: Network Errors diff --git a/ftk/src/ftkbtree.cpp b/ftk/src/ftkbtree.cpp index 6cb31d1..02b9ad7 100644 --- a/ftk/src/ftkbtree.cpp +++ b/ftk/src/ftkbtree.cpp @@ -37,6 +37,920 @@ FSTATIC RCODE btGetEntryData( FLMUINT uiBufferSize, FLMUINT * puiLenDataRV); +#define FLM_MAX_KEY_SIZE 1024 + +typedef struct FlmBlockHdrTag +{ + FLMUINT32 ui32BlkAddr; + FLMUINT32 ui32PrevBlkInChain; + FLMUINT32 ui32NextBlkInChain; + FLMUINT32 ui32PriorBlkImgAddr; + FLMUINT64 ui64TransID; + FLMUINT32 ui32BlkCRC; + FLMUINT16 ui16BlkBytesAvail; + FLMUINT8 ui8BlkFlags; + #define BLK_FORMAT_IS_LITTLE_ENDIAN 0x01 + #define BLK_IS_BEFORE_IMAGE 0x02 + #define BLK_IS_ENCRYPTED 0x04 + FLMUINT8 ui8BlkType; + #define BT_FREE 0 // Free block - avail list + #define BT_LFH_BLK 1 // LFH Header block + #define BT_LEAF 2 // New B-Tree Leaf block + #define BT_NON_LEAF 3 // New B-Tree Non-leaf block block - fixed key size + #define BT_NON_LEAF_COUNTS 4 // New B-Tree Non-leaf index with counts + #define BT_LEAF_DATA 5 // New B-Tree Leaf block with Data + #define BT_DATA_ONLY 6 // Data-only block +} F_BLK_HDR; + +#define F_BLK_HDR_ui32BlkAddr_OFFSET 0 +#define F_BLK_HDR_ui32PrevBlkInChain_OFFSET 4 +#define F_BLK_HDR_ui32NextBlkInChain_OFFSET 8 +#define F_BLK_HDR_ui32PriorBlkImgAddr_OFFSET 12 +#define F_BLK_HDR_ui64TransID_OFFSET 16 +#define F_BLK_HDR_ui32BlkCRC_OFFSET 24 +#define F_BLK_HDR_ui16BlkBytesAvail_OFFSET 28 +#define F_BLK_HDR_ui8BlkFlags_OFFSET 30 +#define F_BLK_HDR_ui8BlkType_OFFSET 31 + +typedef struct FlmBTreeBlkHdr +{ + F_BLK_HDR stdBlkHdr; + FLMUINT16 ui16BtreeId; + FLMUINT16 ui16NumKeys; + FLMUINT8 ui8BlkLevel; + #define BH_MAX_LEVELS 8 + #define MAX_LEVELS BH_MAX_LEVELS + FLMUINT8 ui8BTreeFlags; + #define BLK_IS_ROOT 0x01 + #define BLK_IS_INDEX 0x02 + FLMUINT16 ui16HeapSize; +} F_BTREE_BLK_HDR; + +#define F_BTREE_BLK_HDR_stdBlkHdr_OFFSET 0 +#define F_BTREE_BLK_HDR_ui16BtreeId_OFFSET 32 +#define F_BTREE_BLK_HDR_ui16NumKeys_OFFSET 34 +#define F_BTREE_BLK_HDR_ui8BlkLevel_OFFSET 36 +#define F_BTREE_BLK_HDR_ui8BTreeFlags_OFFSET 37 +#define F_BTREE_BLK_HDR_ui16HeapSize_OFFSET 38 + +enum BTREE_ERR_TYPE +{ + NO_ERR = 0, // FYI: Visual Studio already defines NOERROR + BT_HEADER, + KEY_ORDER, + DUPLICATE_KEYS, + INFINITY_MARKER, + CHILD_BLOCK_ADDRESS, + SCA_GET_BLOCK_FAILED, + MISSING_OVERALL_DATA_LENGTH, + NOT_DATA_ONLY_BLOCK, + BAD_DO_BLOCK_LENGTHS, + BAD_COUNTS, + CATASTROPHIC_FAILURE = 999 +}; + +typedef struct +{ + FLMUINT uiKeyCnt; + FLMUINT uiFirstKeyCnt; + FLMUINT uiBlkCnt; + FLMUINT uiBytesUsed; + FLMUINT uiDOBlkCnt; + FLMUINT uiDOBytesUsed; +} BTREE_LEVEL_STATS; + +typedef struct +{ + FLMUINT uiBlkAddr; + FLMUINT uiBlockSize; + FLMUINT uiBlocksChecked; + FLMUINT uiAvgFreeSpace; + FLMUINT uiLevels; + FLMUINT uiNumKeys; + FLMUINT64 ui64FreeSpace; + BTREE_LEVEL_STATS LevelStats[ BH_MAX_LEVELS]; + char szMsg[ 64]; + BTREE_ERR_TYPE type; +} BTREE_ERR_STRUCT; + +typedef struct +{ + FLMUINT uiParentLevel; + FLMUINT uiParentKeyLen; + FLMUINT uiParentChildBlkAddr; + FLMUINT uiNewKeyLen; + FLMUINT uiChildBlkAddr; + FLMUINT uiCounts; + void * pPrev; + FLMBYTE pucParentKey[ FLM_MAX_KEY_SIZE]; + FLMBYTE pucNewKey[ FLM_MAX_KEY_SIZE]; +} BTREE_REPLACE_STRUCT; + +typedef struct +{ + F_BTREE_BLK_HDR * pBlkHdr; + IF_Block * pBlock; + const FLMBYTE * pucKeyBuf; + FLMUINT uiKeyBufSize; + FLMUINT uiKeyLen; + FLMUINT uiCurOffset; + FLMUINT uiLevel; + FLMUINT16 * pui16OffsetArray; + FLMUINT32 ui32BlkAddr; +} F_BTSK; + +typedef enum +{ + ELM_INSERT_DO, + ELM_INSERT, + ELM_REPLACE_DO, + ELM_REPLACE, + ELM_REMOVE, + ELM_BLK_MERGE, + ELM_DONE +} F_ELM_UPD_ACTION; + +// Represent the maximum size for data & key before needing two bytes to +// store the length. + +#define ONE_BYTE_SIZE 0xFF + +// Flag definitions - BT_LEAF_DATA + +#define BTE_LEAF_DATA_OVHD 7 // Offset (2) Flags (1) OA Data (4) +#define BTE_FLAG 0 // Offset to the FLAGS field +#define BTE_FLAG_LAST_ELEMENT 0x04 +#define BTE_FLAG_FIRST_ELEMENT 0x08 +#define BTE_FLAG_DATA_BLOCK 0x10 // Data is stored in a Data-only Block +#define BTE_FLAG_OA_DATA_LEN 0x20 // Overall data length +#define BTE_FLAG_DATA_LEN 0x40 +#define BTE_FLAG_KEY_LEN 0x80 + +// BT_LEAF (no data) + +#define BTE_LEAF_OVHD 4 // Offset (2) KeyLen (2) +#define BTE_KEY_LEN 0 +#define BTE_KEY_START 2 + +// BT_NON_LEAF_DATA + +#define BTE_NON_LEAF_OVHD 8 // Offset (2) Child Blk Addr (4) KeyLen (2) +#define BTE_NL_CHILD_BLOCK_ADDR 0 +#define BTE_NL_KEY_LEN 4 +#define BTE_NL_KEY_START 6 + +// BT_NON_LEAF_COUNTS + +#define BTE_NON_LEAF_COUNTS_OVHD 12 // Offset (2) Child Blk Addr (4) Counts (4) KeyLen (2) +#define BTE_NLC_CHILD_BLOCK_ADDR 0 +#define BTE_NLC_COUNTS 4 +#define BTE_NLC_KEY_LEN 8 +#define BTE_NLC_KEY_START 10 + +// Low water mark for coalescing blocks (as a percentage) + +#define BT_LOW_WATER_MARK 65 + +/**************************************************************************** +Desc: +****************************************************************************/ +class F_Btree : public F_RefCount, public F_Base +{ +public: + + F_Btree( void); + + virtual ~F_Btree( void); + + RCODE btCreate( + IF_BlockMgr * pBlockMgr, + FLMUINT16 ui16BtreeId, + FLMBOOL bCounts, + FLMBOOL bData, + FLMUINT * puiRootBlkAddr); + + + RCODE btOpen( + IF_BlockMgr * pBlockMgr, + FLMUINT uiRootBlkAddr, + FLMBOOL bCounts, + FLMBOOL bData, + IF_ResultSetCompare * pCompare = NULL); + + void btClose( void); + + RCODE btDeleteTree( + IF_DeleteStatus * ifpDeleteStatus); + + RCODE btGetBlockChains( + FLMUINT * puiBlockChains, + FLMUINT * puiNumLevels); + + RCODE btRemoveEntry( + const FLMBYTE * pucKey, + FLMUINT uiKeyBufSize, + FLMUINT uiKeyLen); + + RCODE btInsertEntry( + const FLMBYTE * pucKey, + FLMUINT uiKeyBufSize, + FLMUINT uiKeyLen, + const FLMBYTE * pucData, + FLMUINT uiDataLen, + FLMBOOL bFirst, + FLMBOOL bLast, + FLMUINT32 * pui32BlkAddr = NULL, + FLMUINT * puiOffsetIndex = NULL); + + RCODE btReplaceEntry( + const FLMBYTE * pucKey, + FLMUINT uiKeyBufSize, + FLMUINT uiKeyLen, + const FLMBYTE * pucData, + FLMUINT uiDataLen, + FLMBOOL bFirst, + FLMBOOL bLast, + FLMBOOL bTruncate = TRUE, + FLMUINT32 * pui32BlkAddr = NULL, + FLMUINT * puiOffsetIndex = NULL); + + RCODE btLocateEntry( + FLMBYTE * pucKey, + FLMUINT uiKeyBufSize, + FLMUINT * puiKeyLen, + FLMUINT uiMatch, + FLMUINT * puiPosition = NULL, + FLMUINT * puiDataLength = NULL, + FLMUINT32 * pui32BlkAddr = NULL, + FLMUINT * puiOffsetIndex = NULL); + + RCODE btGetEntry( + FLMBYTE * pucKey, + FLMUINT uiKeyLen, + FLMBYTE * pucData, + FLMUINT uiDataBufSize, + FLMUINT * puiDataLen); + + RCODE btNextEntry( + FLMBYTE * pucKey, + FLMUINT uiKeyBufSize, + FLMUINT * puiKeyLen, + FLMUINT * puiDataLength = NULL, + FLMUINT32 * pui32BlkAddr = NULL, + FLMUINT * puiOffsetIndex = NULL); + + RCODE btPrevEntry( + FLMBYTE * pucKey, + FLMUINT uiKeyBufSize, + FLMUINT * puiKeyLen, + FLMUINT * puiDataLength = NULL, + FLMUINT32 * pui32BlkAddr = NULL, + FLMUINT * puiOffsetIndex = NULL); + + RCODE btFirstEntry( + FLMBYTE * pucKey, + FLMUINT uiKeyBufSize, + FLMUINT * puiKeyLen, + FLMUINT * puiDataLength = NULL, + FLMUINT32 * pui32BlkAddr = NULL, + FLMUINT * puiOffsetIndex = NULL); + + RCODE btLastEntry( + FLMBYTE * pucKey, + FLMUINT uiKeyBufSize, + FLMUINT * puiKeyLen, + FLMUINT * puiDataLength = NULL, + FLMUINT32 * pui32BlkAddr = NULL, + FLMUINT * puiOffsetIndex = NULL); + + RCODE btSetReadPosition( + FLMBYTE * pucKey, + FLMUINT uiKeyLen, + FLMUINT uiPosition); + + RCODE btGetReadPosition( + FLMUINT * puiPosition); + + RCODE btPositionTo( + FLMUINT uiPosition, + FLMBYTE * pucKey, + FLMUINT uiKeyBufSize, + FLMUINT * puiKeyLen); + + RCODE btGetPosition( + FLMUINT * puiPosition); + + RCODE btCheck( + BTREE_ERR_STRUCT * pErrStruct); + + RCODE btRewind( void); + + FINLINE void btRelease( void) + { + releaseBlocks( TRUE); + } + + FINLINE void btResetBtree( void) + { + releaseBlocks( TRUE); + m_bSetupForRead = FALSE; + m_bSetupForWrite = FALSE; + m_bSetupForReplace = FALSE; + m_bOrigInDOBlocks = FALSE; + m_bDataOnlyBlock = FALSE; + m_ui32PrimaryBlkAddr = 0; + m_ui32CurBlkAddr = 0; + m_uiPrimaryOffset = 0; + m_uiCurOffset = 0; + m_uiDataLength = 0; + m_uiPrimaryDataLen = 0; + m_uiOADataLength = 0; + m_uiDataRemaining = 0; + m_uiOADataRemaining = 0; + m_uiOffsetAtStart = 0; + m_uiSearchLevel = BH_MAX_LEVELS; + } + + RCODE btComputeCounts( + F_Btree * pUntilBtree, + FLMUINT * puiBlkCount, + FLMUINT * puiKeyCount, + FLMBOOL * pbTotalsEstimated, + FLMUINT uiAvgBlkFullness); + + FINLINE void btSetSearchLevel( + FLMUINT uiSearchLevel) + { + flmAssert( uiSearchLevel <= BH_MAX_LEVELS); + + btResetBtree(); + + m_uiSearchLevel = uiSearchLevel; + } + + RCODE btMoveBlock( + FLMUINT32 ui32FromBlkAddr, + FLMUINT32 ui32ToBlkAddr); + + FINLINE FLMBOOL btHasCounts( void) + { + return( m_bCounts); + } + + FINLINE FLMBOOL btHasData( void) + { + return( m_bData); + } + + FINLINE FLMBOOL btDbIsOpen( void) + { + return( m_bOpened); + } + + FINLINE FLMBOOL btIsSetupForRead( void) + { + return( m_bSetupForRead); + } + + FINLINE FLMBOOL btIsSetupForWrite( void) + { + return( m_bSetupForWrite); + } + + FINLINE FLMBOOL btIsSetupForReplace( void) + { + return( m_bSetupForReplace); + } + +private: + + RCODE btFreeBlockChain( + FLMUINT uiStartAddr, + FLMUINT uiBlocksToFree, + FLMUINT * puiBlocksFreed, + FLMUINT * puiEndAddr, + IF_DeleteStatus * ifpDeleteStatus); + + FINLINE FLMUINT calcEntrySize( + FLMUINT uiBlkType, + FLMUINT uiFlags, + FLMUINT uiKeyLen, + FLMUINT uiDataLen, + FLMUINT uiOADataLen) + { + switch( uiBlkType) + { + case BT_LEAF: + { + return( uiKeyLen + 2); + } + + case BT_LEAF_DATA: + { + return( 1 + // Flags + (uiKeyLen > ONE_BYTE_SIZE ? 2 : 1) + // KeyLen + (uiDataLen > ONE_BYTE_SIZE ? 2 : 1) + // DataLen + (uiOADataLen && // OA DataLen + (uiFlags & BTE_FLAG_FIRST_ELEMENT) ? 4 : 0) + + uiKeyLen + uiDataLen); + } + + case BT_NON_LEAF: + case BT_NON_LEAF_COUNTS: + { + return( 4 + // Child block address + (uiBlkType == BT_NON_LEAF_COUNTS ? 4 : 0) + // Counts + 2 + // Key length + uiKeyLen); + } + } + + return( 0); + } + + RCODE computeCounts( + F_BTSK * pFromStack, + F_BTSK * pUntilStack, + FLMUINT * puiBlockCount, + FLMUINT * puiKeyCount, + FLMBOOL * pbTotalsEstimated, + FLMUINT uiAvgBlkFullness); + + RCODE blockCounts( + F_BTSK * pStack, + FLMUINT uiFirstOffset, + FLMUINT uiLastOffset, + FLMUINT * puiKeyCount, + FLMUINT * puiElementCount); + + RCODE getStoredCounts( + F_BTSK * pFromStack, + F_BTSK * pUntilStack, + FLMUINT * puiBlockCount, + FLMUINT * puiKeyCount, + FLMBOOL * pbTotalsEstimated, + FLMUINT uiAvgBlkFullness); + + RCODE getCacheBlocks( + F_BTSK * pStack1, + F_BTSK * pStack2); + + FINLINE FLMUINT getAvgKeyCount( + F_BTSK * pFromStack, + F_BTSK * pUntilStack, + FLMUINT uiAvgBlkFullness); + + FINLINE FLMUINT getBlkEntryCount( + FLMBYTE * pBlk) + { + return ((F_BTREE_BLK_HDR *)pBlk)->ui16NumKeys; + } + + FINLINE FLMUINT getBlkAvailSpace( + FLMBYTE * pBlk) + { + return ((F_BLK_HDR *)pBlk)->ui16BlkBytesAvail; + } + + FLMUINT getEntryKeyLength( + FLMBYTE * pucEntry, + FLMUINT uiBlockType, + const FLMBYTE ** ppucKeyRV); + + FLMUINT getEntrySize( + FLMBYTE * pBlk, + FLMUINT uiOffset, + FLMBYTE ** ppucEntry = NULL); + + RCODE calcNewEntrySize( + FLMUINT uiKeyLen, + FLMUINT uiDataLen, + FLMUINT * puiEntrySize, + FLMBOOL * pbHaveRoom, + FLMBOOL * pbDefragBlk); + + RCODE extractEntryData( + FLMBYTE * pucKey, + FLMUINT uiKeyLen, + FLMBYTE * pucBuffer, + FLMUINT uiBufSiz, + FLMUINT * puiDataLen); + + RCODE updateEntry( + const FLMBYTE * pucKey, + FLMUINT uiKeyLen, + const FLMBYTE * pucValue, + FLMUINT uiLen, + F_ELM_UPD_ACTION eAction, + FLMBOOL bTruncate = TRUE); + + RCODE insertEntry( + const FLMBYTE ** ppucKey, + FLMUINT * puiKeyLen, + const FLMBYTE * pucValue, + FLMUINT uiLen, + FLMUINT uiFlags, + FLMUINT * puiChildBlkAddr, + FLMUINT * puiCounts, + const FLMBYTE ** ppucRemainingValue, + FLMUINT * puiRemainingLen, + F_ELM_UPD_ACTION * peAction); + + RCODE storeEntry( + const FLMBYTE * pucKey, + FLMUINT uiKeyLen, + const FLMBYTE * pucValue, + FLMUINT uiLen, + FLMUINT uiFlags, + FLMUINT uiOADataLen, + FLMUINT uiChildBlkAddr, + FLMUINT uiCounts, + FLMUINT uiEntrySize, + FLMBOOL * pbLastEntry); + + RCODE removeEntry( + const FLMBYTE ** ppucKey, + FLMUINT * puiKeyLen, + FLMUINT * puiChildBlkAddr, + FLMUINT * puiCounts, + FLMBOOL * pbMoreToRemove, + F_ELM_UPD_ACTION * peAction); + + RCODE remove( + FLMBOOL bDeleteDOBlocks); + + RCODE removeRange( + FLMUINT uiStartElm, + FLMUINT uiEndElm, + FLMBOOL bDeleteDOBlocks); + + RCODE findEntry( + const FLMBYTE * pucKey, + FLMUINT uiKeyLen, + FLMUINT uiMatch, + FLMUINT * puiPosition = NULL, + FLMUINT32 * pui32BlkAddr = NULL, + FLMUINT * puiOffsetIndex = NULL); + + RCODE findInBlock( + const FLMBYTE * pucKey, + FLMUINT uiKeyLen, + FLMUINT uiMatch, + FLMUINT * uiPosition, + FLMUINT32 * ui32BlkAddr, + FLMUINT * uiOffsetIndex); + + RCODE scanBlock( + F_BTSK * pStack, + FLMUINT uiMatch); + + RCODE compareKeys( + const FLMBYTE * pucKey1, + FLMUINT uiKeyLen1, + const FLMBYTE * pucKey2, + FLMUINT uiKeyLen2, + FLMINT * piCompare); + + FINLINE RCODE compareBlkKeys( + const FLMBYTE * pucBlockKey, + FLMUINT uiBlockKeyLen, + const FLMBYTE * pucTargetKey, + FLMUINT uiTargetKeyLen, + FLMINT * piCompare) + { + flmAssert( uiBlockKeyLen); + + if( !m_pCompare && uiBlockKeyLen == uiTargetKeyLen) + { + *piCompare = f_memcmp( pucBlockKey, pucTargetKey, uiBlockKeyLen); + + return( NE_FLM_OK); + } + + return( compareKeys( pucBlockKey, uiBlockKeyLen, + pucTargetKey, uiTargetKeyLen, piCompare)); + } + + RCODE positionToEntry( + FLMUINT uiPosition); + + RCODE searchBlock( + F_BTREE_BLK_HDR * pBlkHdr, + FLMUINT * puiPrevCounts, + FLMUINT uiPosition, + FLMUINT * puiOffset); + + RCODE defragmentBlock( + IF_Block ** ppBlock); + + RCODE advanceToNextElement( + FLMBOOL bAdvanceStack); + + RCODE backupToPrevElement( + FLMBOOL bBackupStack); + + RCODE replaceEntry( + const FLMBYTE ** ppucKey, + FLMUINT * puiKeyLen, + const FLMBYTE * pucValue, + FLMUINT uiLen, + FLMUINT uiFlags, + FLMUINT * puiChildBlkAddr, + FLMUINT * puiCounts, + const FLMBYTE ** ppucRemainingValue, + FLMUINT * puiRemainingLen, + F_ELM_UPD_ACTION * peAction, + FLMBOOL bTruncate = TRUE); + + RCODE replaceOldEntry( + const FLMBYTE ** ppucKey, + FLMUINT * puiKeyLen, + const FLMBYTE * pucValue, + FLMUINT uiLen, + FLMUINT uiFlags, + FLMUINT uiOADataLen, + FLMUINT * puiChildBlkAddr, + FLMUINT * puiCounts, + const FLMBYTE ** ppucRemainingValue, + FLMUINT * puiRemainingLen, + F_ELM_UPD_ACTION * peAction, + FLMBOOL bTruncate = TRUE); + + RCODE replaceByInsert( + const FLMBYTE ** ppucKey, + FLMUINT * puiKeyLen, + const FLMBYTE * pucDataValue, + FLMUINT uiDataLen, + FLMUINT uiOADataLen, + FLMUINT uiFlags, + FLMUINT * puiChildBlkAddr, + FLMUINT * puiCounts, + const FLMBYTE ** ppucRemainingValue, + FLMUINT * puiRemainingLen, + F_ELM_UPD_ACTION * peAction); + + RCODE replace( + FLMBYTE * pucEntry, + FLMUINT uiEntrySize, + FLMBOOL * pbLastEntry); + + RCODE buildAndStoreEntry( + FLMUINT uiBlkType, + FLMUINT uiFlags, + const FLMBYTE * pucKey, + FLMUINT uiKeyLen, + const FLMBYTE * pucData, + FLMUINT uiDataLen, + FLMUINT uiOADataLen, + FLMUINT uiChildBlkAddr, + FLMUINT uiCounts, + FLMBYTE * pucBuffer, + FLMUINT uiBufferSize, + FLMUINT * puiEntrySize); + + RCODE moveEntriesToPrevBlk( + FLMUINT uiNewEntrySize, + IF_Block ** ppPrevBlock, + FLMBOOL * pbEntriesWereMoved); + + RCODE moveEntriesToNextBlk( + FLMUINT uiEntrySize, + FLMBOOL * pbEntriesWereMoved); + + RCODE splitBlock( + const FLMBYTE * pucKey, + FLMUINT uiKeyLen, + const FLMBYTE * pucValue, + FLMUINT uiLen, + FLMUINT uiFlags, + FLMUINT uiOADataLen, + FLMUINT uiChildBlkAddr, + FLMUINT uiCounts, + const FLMBYTE ** ppucRemainingValue, + FLMUINT * puiRemainingLen, + FLMBOOL * pbBlockSplit); + + RCODE createNewLevel( void); + + RCODE storeDataOnlyBlocks( + const FLMBYTE * pucKey, + FLMUINT uiKeyLen, + FLMBOOL bSaveKey, + const FLMBYTE * pucData, + FLMUINT uiDataLen); + + RCODE replaceDataOnlyBlocks( + const FLMBYTE * pucKey, + FLMUINT uiKeyLen, + FLMBOOL bSaveKey, + const FLMBYTE * pucData, + FLMUINT uiDataLen, + FLMBOOL bLast, + FLMBOOL bTruncate = TRUE); + + RCODE moveToPrev( + FLMUINT uiStart, + FLMUINT uiFinish, + IF_Block ** ppPrevBlock); + + RCODE moveToNext( + FLMUINT uiStart, + FLMUINT uiFinish, + IF_Block ** ppNextBlock); + + RCODE updateParentCounts( + IF_Block * pChildBlock, + IF_Block ** ppParentBlock, + FLMUINT uiParentElm); + + FLMUINT countKeys( + FLMBYTE * pBlk); + + FLMUINT countRangeOfKeys( + F_BTSK * pFromStack, + FLMUINT uiFromOffset, + FLMUINT uiUntilOffset); + + RCODE moveStackToPrev( + IF_Block * pPrevBlock); + + RCODE moveStackToNext( + IF_Block * pBlock, + FLMBOOL bReleaseCurrent = TRUE); + + RCODE calcOptimalDataLength( + FLMUINT uiKeyLen, + FLMUINT uiDataLen, + FLMUINT uiBytesAvail, + FLMUINT * puiNewDataLen); + + RCODE verifyDOBlkChain( + FLMUINT uiDOAddr, + FLMUINT uiDataLength, + BTREE_ERR_STRUCT * localErrStruct); + + RCODE verifyCounts( + BTREE_ERR_STRUCT * pErrStruct); + + void releaseBlocks( + FLMBOOL bResetStack); + + void releaseBtree( void); + + RCODE saveReplaceInfo( + const FLMBYTE * pucKey, + FLMUINT uiKeyLen); + + RCODE restoreReplaceInfo( + const FLMBYTE ** ppucKey, + FLMUINT * puiKeyLen, + FLMUINT * puiChildBlkAddr, + FLMUINT * puiCounts); + + FINLINE RCODE setReturnKey( + FLMBYTE * pucEntry, + FLMUINT uiBlockType, + FLMBYTE * pucKey, + FLMUINT * puiKeyLen, + FLMUINT uiKeyBufSize); + + RCODE setupReadState( + F_BLK_HDR * pBlkHdr, + FLMBYTE * pucEntry); + + RCODE removeRemainingEntries( + const FLMBYTE * pucKey, + FLMUINT uiKeyLen); + + RCODE deleteEmptyBlock( void); + + RCODE removeDOBlocks( + FLMUINT32 ui32OrigDOAddr); + + RCODE replaceMultiples( + const FLMBYTE ** ppucKey, + FLMUINT * puiKeyLen, + const FLMBYTE * pucDataValue, + FLMUINT uiLen, + FLMUINT uiFlags, + FLMUINT * puiChildBlkAddr, + FLMUINT * puiCounts, + const FLMBYTE ** ppucRemainingValue, + FLMUINT * puiRemainingLen, + F_ELM_UPD_ACTION * peAction); + + RCODE replaceMultiNoTruncate( + const FLMBYTE ** ppucKey, + FLMUINT * puiKeyLen, + const FLMBYTE * pucDataValue, + FLMUINT uiLen, + FLMUINT uiFlags, + FLMUINT * puiChildBlkAddr, + FLMUINT * puiCounts, + const FLMBYTE ** ppucRemainingValue, + FLMUINT * puiRemainingLen, + F_ELM_UPD_ACTION * peAction); + + FINLINE RCODE getNextBlock( + IF_Block ** ppBlock); + + FINLINE RCODE getPrevBlock( + IF_Block ** ppBlock); + + FLMBOOL checkContinuedEntry( + const FLMBYTE * pucKey, + FLMUINT uiKeyLen, + FLMBOOL * pbLastElement, + FLMBYTE * pucEntry, + FLMUINT uiBlkType); + + RCODE updateCounts( void); + + RCODE storePartialEntry( + const FLMBYTE * pucKey, + FLMUINT uiKeyLen, + const FLMBYTE * pucValue, + FLMUINT uiLen, + FLMUINT uiFlags, + FLMUINT uiChildBlkAddr, + FLMUINT uiCounts, + const FLMBYTE ** ppucRemainingValue, + FLMUINT * puiRemainingLen, + FLMBOOL bNewBlock = FALSE); + + RCODE mergeBlocks( + FLMBOOL bLastEntry, + FLMBOOL * pbMergedWithPrev, + FLMBOOL * pbMergedWithNext, + F_ELM_UPD_ACTION * peAction); + + RCODE merge( + IF_Block ** ppFromBlock, + IF_Block ** ppToBlock); + + RCODE checkDownLinks( void); + + RCODE verifyChildLinks( + IF_Block * pParentBlock); + + RCODE combineEntries( + F_BTREE_BLK_HDR * pSrcBlkHdr, + FLMUINT uiSrcOffset, + F_BTREE_BLK_HDR * pDstBlkHdr, + FLMUINT uiDstOffset, + FLMBOOL * pbEntriesCombined, + FLMUINT * puiEntrySize, + FLMBYTE * pucTempBlk); + + RCODE moveBtreeBlock( + FLMUINT32 ui32FromBlkAddr, + FLMUINT32 ui32ToBlkAddr); + + RCODE moveDOBlock( + FLMUINT32 ui32FromBlkAddr, + FLMUINT32 ui32ToBlkAddr); + + IF_BlockMgr * m_pBlockMgr; + IF_Pool * m_pPool; + FLMUINT m_uiRootBlkAddr; + FLMBOOL m_bCounts; + FLMBOOL m_bData; + FLMBOOL m_bSetupForRead; + FLMBOOL m_bSetupForWrite; + FLMBOOL m_bSetupForReplace; + FLMBOOL m_bOpened; + FLMBOOL m_bDataOnlyBlock; + FLMBOOL m_bOrigInDOBlocks; + FLMBOOL m_bFirstRead; + FLMBOOL m_bStackSetup; + F_BTSK * m_pStack; + BTREE_REPLACE_STRUCT * m_pReplaceInfo; + BTREE_REPLACE_STRUCT * m_pReplaceStruct; + const FLMBYTE * m_pucDataPtr; + IF_Block * m_pBlock; + F_BTREE_BLK_HDR * m_pBlkHdr; + FLMUINT m_uiBlockSize; + FLMUINT m_uiDefragThreshold; + FLMUINT m_uiOverflowThreshold; + FLMUINT m_uiStackLevels; + FLMUINT m_uiRootLevel; + FLMUINT m_uiReplaceLevels; + FLMUINT m_uiDataLength; + FLMUINT m_uiPrimaryDataLen; + FLMUINT m_uiOADataLength; + FLMUINT m_uiDataRemaining; + FLMUINT m_uiOADataRemaining; + FLMUINT m_uiPrimaryOffset; + FLMUINT m_uiCurOffset; + FLMUINT m_uiSearchLevel; + FLMUINT m_uiOffsetAtStart; + FLMUINT32 m_ui32PrimaryBlkAddr; + FLMUINT32 m_ui32DOBlkAddr; + FLMUINT32 m_ui32CurBlkAddr; + F_BTSK m_Stack[ BH_MAX_LEVELS]; + IF_ResultSetCompare * m_pCompare; +}; + /**************************************************************************** Desc: Encrypted B-Tree block header - on-disk format. ****************************************************************************/ @@ -56,6 +970,90 @@ typedef struct FLMBYTE ucReserved[ 12]; } F_ENC_DO_BLK_HDR; +/*************************************************************************** +Desc: +****************************************************************************/ +FINLINE FLMBOOL bteKeyLenFlag( + FLMBYTE * pucEntry) +{ + return( (pucEntry[ BTE_FLAG] & BTE_FLAG_KEY_LEN) ? TRUE : FALSE); +} + +/*************************************************************************** +Desc: +****************************************************************************/ +FINLINE FLMBOOL bteDataLenFlag( + FLMBYTE * pucEntry) +{ + return( (pucEntry[ BTE_FLAG] & BTE_FLAG_DATA_LEN) ? TRUE : FALSE); +} + +/*************************************************************************** +Desc: +****************************************************************************/ +FINLINE FLMBOOL bteOADataLenFlag( + FLMBYTE * pucEntry) +{ + return( (pucEntry[ BTE_FLAG] & BTE_FLAG_OA_DATA_LEN) ? TRUE : FALSE); +} + +/*************************************************************************** +Desc: +****************************************************************************/ +FINLINE FLMBOOL bteDataBlockFlag( + FLMBYTE * pucEntry) +{ + return( (pucEntry[ BTE_FLAG] & BTE_FLAG_DATA_BLOCK) ? TRUE : FALSE); +} + +/*************************************************************************** +Desc: +****************************************************************************/ +FINLINE FLMBOOL bteFirstElementFlag( + FLMBYTE * pucEntry) +{ + return( (pucEntry[ BTE_FLAG] & BTE_FLAG_FIRST_ELEMENT) ? TRUE : FALSE); +} + +/*************************************************************************** +Desc: +****************************************************************************/ +FINLINE FLMBOOL bteLastElementFlag( + FLMBYTE * pucEntry) +{ + return( (pucEntry[ BTE_FLAG] & BTE_FLAG_LAST_ELEMENT) ? TRUE : FALSE); +} + +/*************************************************************************** +Desc: +****************************************************************************/ +FINLINE FLMUINT32 bteGetBlkAddr( + const FLMBYTE * pucEntry) +{ + return( FB2UD( pucEntry)); +} + +/*************************************************************************** +Desc: +****************************************************************************/ +FINLINE void bteSetEntryOffset( + FLMUINT16 * pui16OffsetArray, + FLMUINT uiOffsetIndex, + FLMUINT ui16Offset) +{ + UW2FBA( ui16Offset, (FLMBYTE *)&pui16OffsetArray[ uiOffsetIndex]); +} + +/*************************************************************************** +Desc: +****************************************************************************/ +FINLINE FLMUINT16 bteGetEntryOffset( + const FLMUINT16 * pui16OffsetArray, + FLMUINT uiOffsetIndex) +{ + return( FB2UW( (FLMBYTE *)&pui16OffsetArray[ uiOffsetIndex])); +} + /*************************************************************************** Desc: ****************************************************************************/ @@ -413,9 +1411,8 @@ RCODE F_Btree::btOpen( m_bSetupForWrite = FALSE; m_bSetupForReplace = FALSE; - if( (m_pPool = f_new F_Pool) == NULL) + if( RC_BAD( rc = FlmAllocPool( &m_pPool))) { - rc = RC_SET( NE_FLM_MEM); goto Exit; } diff --git a/ftk/src/ftkdir.cpp b/ftk/src/ftkdir.cpp index e8014da..dd6cb3a 100644 --- a/ftk/src/ftkdir.cpp +++ b/ftk/src/ftkdir.cpp @@ -30,16 +30,31 @@ #if defined( FLM_WIN) + #define F_IO_FA_NORMAL FILE_ATTRIBUTE_NORMAL // Normal file + #define F_IO_FA_RDONLY FILE_ATTRIBUTE_READONLY // Read only attribute + #define F_IO_FA_HIDDEN FILE_ATTRIBUTE_HIDDEN // Hidden file + #define F_IO_FA_SYSTEM FILE_ATTRIBUTE_SYSTEM // System file + #define F_IO_FA_VOLUME FILE_ATTRIBUTE_VOLUME // Volume label + #define F_IO_FA_DIRECTORY FILE_ATTRIBUTE_DIRECTORY // Directory + #define F_IO_FA_ARCHIVE FILE_ATTRIBUTE_ARCHIVE // Archive + FSTATIC FLMBOOL f_fileMeetsFindCriteria( F_IO_FIND_DATA * pFindData); #elif defined( FLM_UNIX) || defined( FLM_NLM) + #define F_IO_FA_NORMAL 0x01 // Normal file, no attributes + #define F_IO_FA_RDONLY 0x02 // Read only attribute + #define F_IO_FA_HIDDEN 0x04 // Hidden file + #define F_IO_FA_SYSTEM 0x08 // System file + #define F_IO_FA_VOLUME 0x10 // Volume label + #define F_IO_FA_DIRECTORY 0x20 // Directory + #define F_IO_FA_ARCHIVE 0x40 // Archive + FSTATIC int Find1( char * FindTemplate, F_IO_FIND_DATA * DirInfo); - FSTATIC int Find2( F_IO_FIND_DATA * DirStuff); @@ -57,8 +72,37 @@ #endif +RCODE f_fileFindFirst( + char * pszSearchPath, + FLMUINT uiSearchAttrib, + F_IO_FIND_DATA * find_data, + char * pszFoundPath, + FLMUINT * puiFoundAttrib); + +RCODE f_fileFindNext( + F_IO_FIND_DATA * pFindData, + char * pszFoundPath, + FLMUINT * puiFoundAttrib); + +void f_fileFindClose( + F_IO_FIND_DATA * pFindData); + /**************************************************************************** -Desc: Constructor +Desc: +****************************************************************************/ +RCODE f_allocDirHdl( + F_DirHdl ** ppDirHdl) +{ + if( (*ppDirHdl = f_new F_DirHdl) == NULL) + { + return( RC_SET( NE_FLM_MEM)); + } + + return( NE_FLM_OK); +} + +/**************************************************************************** +Desc: ****************************************************************************/ F_DirHdl::F_DirHdl() { @@ -69,6 +113,17 @@ F_DirHdl::F_DirHdl() m_szPattern[ 0] = '\0'; } +/**************************************************************************** +Desc: +****************************************************************************/ +F_DirHdl::~F_DirHdl() +{ + if( m_bFindOpen) + { + f_fileFindClose( &m_FindData); + } +} + /**************************************************************************** Desc: ****************************************************************************/ @@ -190,7 +245,7 @@ Exit: /**************************************************************************** Desc: Open a directory ****************************************************************************/ -RCODE F_DirHdl::openDir( +RCODE FLMAPI F_DirHdl::openDir( const char * pszDirName, const char * pszPattern) { @@ -223,7 +278,7 @@ Exit: /**************************************************************************** Desc: Create a directory (and parent directories if necessary). ****************************************************************************/ -RCODE F_DirHdl::createDir( +RCODE FLMAPI F_DirHdl::createDir( const char * pszDirPath) { char * pszParentDir = NULL; @@ -301,7 +356,7 @@ Exit: Desc: Remove a directory Notes: The directory must be empty. ****************************************************************************/ -RCODE F_DirHdl::removeDir( +RCODE FLMAPI F_DirHdl::removeDir( const char * pszDirName) { #if defined( FLM_WIN) diff --git a/ftk/src/ftkerror.cpp b/ftk/src/ftkerror.cpp index 800ab54..9409244 100644 --- a/ftk/src/ftkerror.cpp +++ b/ftk/src/ftkerror.cpp @@ -25,6 +25,146 @@ #include "ftksys.h" +#define flmErrorCodeEntry(c) { c, #c } + +typedef struct +{ + RCODE rc; + const char * pszErrorStr; +} F_ERROR_CODE_MAP; + +/**************************************************************************** +Desc: +****************************************************************************/ +F_ERROR_CODE_MAP gv_FlmGeneralErrors[ + NE_FLM_LAST_GENERAL_ERROR - NE_FLM_FIRST_GENERAL_ERROR - 1] = +{ + flmErrorCodeEntry( NE_FLM_NOT_IMPLEMENTED), + flmErrorCodeEntry( NE_FLM_MEM), + flmErrorCodeEntry( NE_FLM_INVALID_PARM), + flmErrorCodeEntry( NE_FLM_TIMEOUT), + flmErrorCodeEntry( NE_FLM_NOT_FOUND), + flmErrorCodeEntry( NE_FLM_EXISTS), + flmErrorCodeEntry( NE_FLM_USER_ABORT), + flmErrorCodeEntry( NE_FLM_FAILURE), + flmErrorCodeEntry( NE_FLM_BOF_HIT), + flmErrorCodeEntry( NE_FLM_EOF_HIT), + flmErrorCodeEntry( NE_FLM_END), + flmErrorCodeEntry( NE_FLM_CONV_BAD_DIGIT), + flmErrorCodeEntry( NE_FLM_CONV_DEST_OVERFLOW), + flmErrorCodeEntry( NE_FLM_CONV_ILLEGAL), + flmErrorCodeEntry( NE_FLM_CONV_NULL_SRC), + flmErrorCodeEntry( NE_FLM_CONV_NUM_OVERFLOW), + flmErrorCodeEntry( NE_FLM_CONV_NUM_UNDERFLOW), + flmErrorCodeEntry( NE_FLM_SYNTAX), + flmErrorCodeEntry( NE_FLM_UNSUPPORTED_FEATURE), + flmErrorCodeEntry( NE_FLM_FILE_EXISTS), + flmErrorCodeEntry( NE_FLM_COULD_NOT_CREATE_SEMAPHORE), + flmErrorCodeEntry( NE_FLM_BAD_UTF8), + flmErrorCodeEntry( NE_FLM_ERROR_WAITING_ON_SEMPAHORE), + flmErrorCodeEntry( NE_FLM_BAD_PLATFORM_FORMAT), + flmErrorCodeEntry( NE_FLM_BAD_SEN), + flmErrorCodeEntry( NE_FLM_UNSUPPORTED_INTERFACE), + flmErrorCodeEntry( NE_FLM_BAD_RCODE_TABLE), + flmErrorCodeEntry( NE_FLM_BUFFER_OVERFLOW), + flmErrorCodeEntry( NE_FLM_INVALID_XML), + flmErrorCodeEntry( NE_FLM_ILLEGAL_FLAG), + flmErrorCodeEntry( NE_FLM_ILLEGAL_OP), + flmErrorCodeEntry( NE_FLM_COULD_NOT_START_THREAD), + flmErrorCodeEntry( NE_FLM_BAD_BASE64_ENCODING), + flmErrorCodeEntry( NE_FLM_STREAM_EXISTS), + flmErrorCodeEntry( NE_FLM_MULTIPLE_MATCHES), + flmErrorCodeEntry( NE_FLM_NOT_UNIQUE), + flmErrorCodeEntry( NE_FLM_BTREE_ERROR), + flmErrorCodeEntry( NE_FLM_BTREE_KEY_SIZE), + flmErrorCodeEntry( NE_FLM_BTREE_FULL), + flmErrorCodeEntry( NE_FLM_BTREE_BAD_STATE) +}; + +/**************************************************************************** +Desc: +****************************************************************************/ +F_ERROR_CODE_MAP gv_FlmIoErrors[ + NE_FLM_LAST_IO_ERROR - NE_FLM_FIRST_IO_ERROR - 1] = +{ + flmErrorCodeEntry( NE_FLM_IO_ACCESS_DENIED), + flmErrorCodeEntry( NE_FLM_IO_BAD_FILE_HANDLE), + flmErrorCodeEntry( NE_FLM_IO_COPY_ERR), + flmErrorCodeEntry( NE_FLM_IO_DISK_FULL), + flmErrorCodeEntry( NE_FLM_IO_END_OF_FILE), + flmErrorCodeEntry( NE_FLM_IO_OPEN_ERR), + flmErrorCodeEntry( NE_FLM_IO_SEEK_ERR), + flmErrorCodeEntry( NE_FLM_IO_DIRECTORY_ERR), + flmErrorCodeEntry( NE_FLM_IO_PATH_NOT_FOUND), + flmErrorCodeEntry( NE_FLM_IO_TOO_MANY_OPEN_FILES), + flmErrorCodeEntry( NE_FLM_IO_PATH_TOO_LONG), + flmErrorCodeEntry( NE_FLM_IO_NO_MORE_FILES), + flmErrorCodeEntry( NE_FLM_IO_DELETING_FILE), + flmErrorCodeEntry( NE_FLM_IO_FILE_LOCK_ERR), + flmErrorCodeEntry( NE_FLM_IO_FILE_UNLOCK_ERR), + flmErrorCodeEntry( NE_FLM_IO_PATH_CREATE_FAILURE), + flmErrorCodeEntry( NE_FLM_IO_RENAME_FAILURE), + flmErrorCodeEntry( NE_FLM_IO_INVALID_PASSWORD), + flmErrorCodeEntry( NE_FLM_SETTING_UP_FOR_READ), + flmErrorCodeEntry( NE_FLM_SETTING_UP_FOR_WRITE), + flmErrorCodeEntry( NE_FLM_IO_CANNOT_REDUCE_PATH), + flmErrorCodeEntry( NE_FLM_INITIALIZING_IO_SYSTEM), + flmErrorCodeEntry( NE_FLM_FLUSHING_FILE), + flmErrorCodeEntry( NE_FLM_IO_INVALID_FILENAME), + flmErrorCodeEntry( NE_FLM_IO_CONNECT_ERROR), + flmErrorCodeEntry( NE_FLM_OPENING_FILE), + flmErrorCodeEntry( NE_FLM_DIRECT_OPENING_FILE), + flmErrorCodeEntry( NE_FLM_CREATING_FILE), + flmErrorCodeEntry( NE_FLM_DIRECT_CREATING_FILE), + flmErrorCodeEntry( NE_FLM_READING_FILE), + flmErrorCodeEntry( NE_FLM_DIRECT_READING_FILE), + flmErrorCodeEntry( NE_FLM_WRITING_FILE), + flmErrorCodeEntry( NE_FLM_DIRECT_WRITING_FILE), + flmErrorCodeEntry( NE_FLM_POSITIONING_IN_FILE), + flmErrorCodeEntry( NE_FLM_GETTING_FILE_SIZE), + flmErrorCodeEntry( NE_FLM_TRUNCATING_FILE), + flmErrorCodeEntry( NE_FLM_PARSING_FILE_NAME), + flmErrorCodeEntry( NE_FLM_CLOSING_FILE), + flmErrorCodeEntry( NE_FLM_GETTING_FILE_INFO), + flmErrorCodeEntry( NE_FLM_EXPANDING_FILE), + flmErrorCodeEntry( NE_FLM_CHECKING_FILE_EXISTENCE), + flmErrorCodeEntry( NE_FLM_RENAMING_FILE), + flmErrorCodeEntry( NE_FLM_SETTING_FILE_INFO) +}; + +/**************************************************************************** +Desc: +****************************************************************************/ +F_ERROR_CODE_MAP gv_FlmNetErrors[ + NE_FLM_LAST_NET_ERROR - NE_FLM_FIRST_NET_ERROR - 1] = +{ + flmErrorCodeEntry( NE_FLM_NOIP_ADDR), + flmErrorCodeEntry( NE_FLM_SOCKET_FAIL), + flmErrorCodeEntry( NE_FLM_CONNECT_FAIL), + flmErrorCodeEntry( NE_FLM_BIND_FAIL), + flmErrorCodeEntry( NE_FLM_LISTEN_FAIL), + flmErrorCodeEntry( NE_FLM_ACCEPT_FAIL), + flmErrorCodeEntry( NE_FLM_SELECT_ERR), + flmErrorCodeEntry( NE_FLM_SOCKET_SET_OPT_FAIL), + flmErrorCodeEntry( NE_FLM_SOCKET_DISCONNECT), + flmErrorCodeEntry( NE_FLM_SOCKET_READ_FAIL), + flmErrorCodeEntry( NE_FLM_SOCKET_WRITE_FAIL), + flmErrorCodeEntry( NE_FLM_SOCKET_READ_TIMEOUT), + flmErrorCodeEntry( NE_FLM_SOCKET_WRITE_TIMEOUT), + flmErrorCodeEntry( NE_FLM_SOCKET_ALREADY_CLOSED) +}; + +/**************************************************************************** +Desc: +****************************************************************************/ +F_ERROR_CODE_MAP gv_FlmStreamErrors[ + NE_FLM_LAST_STREAM_ERROR - NE_FLM_FIRST_STREAM_ERROR - 1] = +{ + flmErrorCodeEntry( NE_FLM_STREAM_DECOMPRESS_ERROR), + flmErrorCodeEntry( NE_FLM_STREAM_NOT_COMPRESSED), + flmErrorCodeEntry( NE_FLM_STREAM_TOO_MANY_FILES) +}; + /**************************************************************************** Desc: The primary purpose of this function is to provide a way to easily trap errors when they occur. Just put a breakpoint in this function @@ -101,6 +241,268 @@ Exit: } #endif +/**************************************************************************** +Desc: Returns a pointer to the ASCII string representation + of a return code. +****************************************************************************/ +const char * FLMAPI f_errorString( + RCODE rc) +{ + const char * pszErrorStr; + + if( rc == NE_FLM_OK) + { + pszErrorStr = "NE_FLM_OK"; + } + else if( rc > NE_FLM_FIRST_GENERAL_ERROR && + rc < NE_FLM_LAST_GENERAL_ERROR) + { + pszErrorStr = gv_FlmGeneralErrors[ + rc - NE_FLM_FIRST_GENERAL_ERROR - 1].pszErrorStr; + } + else if( rc > NE_FLM_FIRST_IO_ERROR && + rc < NE_FLM_LAST_IO_ERROR) + { + pszErrorStr = gv_FlmIoErrors[ + rc - NE_FLM_FIRST_IO_ERROR - 1].pszErrorStr; + } + else if( rc > NE_FLM_FIRST_NET_ERROR && + rc < NE_FLM_LAST_NET_ERROR) + { + pszErrorStr = gv_FlmNetErrors[ + rc - NE_FLM_FIRST_NET_ERROR - 1].pszErrorStr; + } + else if( rc > NE_FLM_FIRST_STREAM_ERROR && + rc < NE_FLM_LAST_STREAM_ERROR) + { + pszErrorStr = gv_FlmStreamErrors[ + rc - NE_FLM_FIRST_STREAM_ERROR - 1].pszErrorStr; + } + else + { + pszErrorStr = "Unknown error"; + } + + return( pszErrorStr); +} + +/*************************************************************************** +Desc: Map POSIX errno to Flaim IO errors. +***************************************************************************/ +#if defined( FLM_UNIX) || defined( FLM_NLM) +RCODE MapPlatformError( + FLMINT iError, + RCODE defaultRc) +{ + switch (err) + { + case 0: + { + return( NE_FLM_OK); + } + + case ENOENT: + { + return( RC_SET( NE_FLM_IO_PATH_NOT_FOUND)); + } + + case EACCES: + case EEXIST: + { + return( RC_SET( NE_FLM_IO_ACCESS_DENIED)); + } + + case EINVAL: + { + return( RC_SET( NE_FLM_IO_PATH_TOO_LONG)); + } + + case EIO: + { + return( RC_SET( NE_FLM_IO_DISK_FULL)); + } + + case ENOTDIR: + { + return( RC_SET( NE_FLM_IO_DIRECTORY_ERR)); + } + +#ifdef EBADFD + case EBADFD: + { + return( RC_SET( NE_FLM_IO_BAD_FILE_HANDLE)); + } +#endif + +#ifdef EOF + case EOF: + { + return( RC_SET( NE_FLM_IO_END_OF_FILE)); + } +#endif + + case EMFILE: + { + return( RC_SET( NE_FLM_IO_NO_MORE_FILES)); + } + + default: + { + return( RC_SET( defaultRc)); + } + } +} +#endif + +/*************************************************************************** +Desc: +***************************************************************************/ +#ifdef FLM_WIN +RCODE MapPlatformError( + FLMINT iErrCode, + RCODE defaultRc) +{ + switch( iErrCode) + { + case ERROR_NOT_ENOUGH_MEMORY: + case ERROR_OUTOFMEMORY: + return( RC_SET( NE_FLM_MEM)); + + case ERROR_BAD_NETPATH: + case ERROR_BAD_PATHNAME: + case ERROR_DIRECTORY: + case ERROR_FILE_NOT_FOUND: + case ERROR_INVALID_DRIVE: + case ERROR_INVALID_NAME: + case ERROR_NO_NET_OR_BAD_PATH: + case ERROR_PATH_NOT_FOUND: + return( RC_SET( NE_FLM_IO_PATH_NOT_FOUND)); + + case ERROR_ACCESS_DENIED: + case ERROR_SHARING_VIOLATION: + case ERROR_FILE_EXISTS: + case ERROR_ALREADY_EXISTS: + return( RC_SET( NE_FLM_IO_ACCESS_DENIED)); + + case ERROR_BUFFER_OVERFLOW: + case ERROR_FILENAME_EXCED_RANGE: + return( RC_SET( NE_FLM_IO_PATH_TOO_LONG)); + + case ERROR_DISK_FULL: + case ERROR_HANDLE_DISK_FULL: + return( RC_SET( NE_FLM_IO_DISK_FULL)); + + case ERROR_CURRENT_DIRECTORY: + case ERROR_DIR_NOT_EMPTY: + return( RC_SET( NE_FLM_IO_DIRECTORY_ERR)); + + case ERROR_DIRECT_ACCESS_HANDLE: + case ERROR_INVALID_HANDLE: + case ERROR_INVALID_TARGET_HANDLE: + return( RC_SET( NE_FLM_IO_BAD_FILE_HANDLE)); + + case ERROR_HANDLE_EOF: + return( RC_SET( NE_FLM_IO_END_OF_FILE)); + + case ERROR_OPEN_FAILED: + return( RC_SET( NE_FLM_IO_OPEN_ERR)); + + case ERROR_CANNOT_MAKE: + return( RC_SET( NE_FLM_IO_PATH_CREATE_FAILURE)); + + case ERROR_LOCK_FAILED: + case ERROR_LOCK_VIOLATION: + return( RC_SET( NE_FLM_IO_FILE_LOCK_ERR)); + + case ERROR_NEGATIVE_SEEK: + case ERROR_SEEK: + case ERROR_SEEK_ON_DEVICE: + return( RC_SET( NE_FLM_IO_SEEK_ERR)); + + case ERROR_NO_MORE_FILES: + case ERROR_NO_MORE_SEARCH_HANDLES: + return( RC_SET( NE_FLM_IO_NO_MORE_FILES)); + + case ERROR_TOO_MANY_OPEN_FILES: + return( RC_SET( NE_FLM_IO_TOO_MANY_OPEN_FILES)); + + case NO_ERROR: + return( NE_FLM_OK); + + case ERROR_DISK_CORRUPT: + case ERROR_DISK_OPERATION_FAILED: + case ERROR_FILE_CORRUPT: + case ERROR_FILE_INVALID: + case ERROR_NOT_SAME_DEVICE: + case ERROR_IO_DEVICE: + default: + return( RC_SET( defaultRc)); + + } +} +#endif + +/**************************************************************************** +Desc: Checks the error code mapping tables on startup +****************************************************************************/ +RCODE f_checkErrorCodeTables( void) +{ + RCODE rc = NE_FLM_OK; + FLMUINT uiLoop; + + for( uiLoop = 0; + uiLoop < (NE_FLM_LAST_GENERAL_ERROR - NE_FLM_FIRST_GENERAL_ERROR - 1); + uiLoop++) + { + if( gv_FlmGeneralErrors[ uiLoop].rc != + (RCODE)(uiLoop + NE_FLM_FIRST_GENERAL_ERROR + 1)) + { + rc = RC_SET_AND_ASSERT( NE_FLM_BAD_RCODE_TABLE); + goto Exit; + } + } + + for( uiLoop = 0; + uiLoop < (NE_FLM_LAST_IO_ERROR - NE_FLM_FIRST_IO_ERROR - 1); + uiLoop++) + { + if( gv_FlmIoErrors[ uiLoop].rc != + (RCODE)(uiLoop + NE_FLM_FIRST_IO_ERROR + 1)) + { + rc = RC_SET_AND_ASSERT( NE_FLM_BAD_RCODE_TABLE); + goto Exit; + } + } + + for( uiLoop = 0; + uiLoop < (NE_FLM_LAST_NET_ERROR - NE_FLM_FIRST_NET_ERROR - 1); + uiLoop++) + { + if( gv_FlmNetErrors[ uiLoop].rc != + (RCODE)(uiLoop + NE_FLM_FIRST_NET_ERROR + 1)) + { + rc = RC_SET_AND_ASSERT( NE_FLM_BAD_RCODE_TABLE); + goto Exit; + } + } + + for( uiLoop = 0; + uiLoop < (NE_FLM_LAST_STREAM_ERROR - NE_FLM_FIRST_STREAM_ERROR - 1); + uiLoop++) + { + if( gv_FlmStreamErrors[ uiLoop].rc != + (RCODE)(uiLoop + NE_FLM_FIRST_STREAM_ERROR + 1)) + { + rc = RC_SET_AND_ASSERT( NE_FLM_BAD_RCODE_TABLE); + goto Exit; + } + } + +Exit: + + return( rc); +} + /**************************************************************************** Desc: ****************************************************************************/ diff --git a/ftk/src/ftkfsys.cpp b/ftk/src/ftkfsys.cpp index 7ec0da6..bd276ec 100644 --- a/ftk/src/ftkfsys.cpp +++ b/ftk/src/ftkfsys.cpp @@ -25,6 +25,366 @@ #include "ftksys.h" +/**************************************************************************** +Desc: +****************************************************************************/ +FINLINE void HexToNative( + FLMBYTE ucHexVal, + char * pszNativeChar) +{ + *pszNativeChar = (char)(ucHexVal < 10 + ? ucHexVal + NATIVE_ZERO + : (ucHexVal - 10) + NATIVE_LOWER_A); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +FINLINE void SetUpTime( + FLMUINT * puiBaseTime, + FLMBYTE * pbyHighByte) +{ + FLMUINT uiSdTime = 0; + f_timeGetSeconds( &uiSdTime); + *pbyHighByte = (FLMBYTE)(uiSdTime >> 24); + uiSdTime = uiSdTime << 5; + if( *puiBaseTime < uiSdTime) + *puiBaseTime = uiSdTime; +} + +/**************************************************************************** +Desc: +****************************************************************************/ +class F_FileSystem : public IF_FileSystem, public F_Base +{ +public: + + F_FileSystem() + { + } + + virtual ~F_FileSystem() + { + } + + RCODE FLMAPI createFile( + const char * pszFileName, + FLMUINT uiIoFlags, + IF_FileHdl ** ppFile); + + RCODE FLMAPI createBlockFile( + const char * pszFileName, + FLMUINT uiIoFlags, + FLMUINT uiBlockSize, + IF_FileHdl ** ppFile); + + RCODE FLMAPI createUniqueFile( + const char * pszDirName, + const char * pszFileExtension, + FLMUINT uiIoFlags, + IF_FileHdl ** ppFile); + + RCODE FLMAPI openFile( + const char * pszFileName, + FLMUINT uiIoFlags, + IF_FileHdl ** ppFile); + + RCODE FLMAPI openBlockFile( + const char * pszFileName, + FLMUINT uiIoFlags, + FLMUINT uiBlockSize, + IF_FileHdl ** ppFile); + + RCODE FLMAPI openDir( + const char * pszDirName, + const char * pszPattern, + IF_DirHdl ** ppDir); + + RCODE FLMAPI createDir( + const char * pszDirName); + + RCODE FLMAPI removeDir( + const char * pszDirName, + FLMBOOL bClear = FALSE); + + RCODE FLMAPI doesFileExist( + const char * pszFileName); + + FLMBOOL FLMAPI isDir( + const char * pszFileName); + + RCODE FLMAPI getFileTimeStamp( + const char * pszFileName, + FLMUINT * puiTimeStamp); + + RCODE FLMAPI deleteFile( + const char * pszFileName); + + RCODE FLMAPI copyFile( + const char * pszSrcFileName, + const char * pszDestFileName, + FLMBOOL bOverwrite, + FLMUINT64 * pui64BytesCopied); + + RCODE FLMAPI renameFile( + const char * pszFileName, + const char * pszNewFileName); + + void FLMAPI pathParse( + const char * pszPath, + char * pszServer, + char * pszVolume, + char * pszDirPath, + char * pszFileName); + + RCODE FLMAPI pathReduce( + const char * pszSourcePath, + char * pszDestPath, + char * pszString); + + RCODE FLMAPI pathAppend( + char * pszPath, + const char * pszPathComponent); + + RCODE FLMAPI pathToStorageString( + const char * pszPath, + char * pszString); + + void FLMAPI pathCreateUniqueName( + FLMUINT * puiTime, + char * pszFileName, + const char * pszFileExt, + FLMBYTE * pHighChars, + FLMBOOL bModext); + + FLMBOOL FLMAPI doesFileMatch( + const char * pszFileName, + const char * pszTemplate); + + RCODE FLMAPI getSectorSize( + const char * pszFileName, + FLMUINT * puiSectorSize); + + RCODE setReadOnly( + const char * pszFileName, + FLMBOOL bReadOnly); + +private: + +#if defined( FLM_UNIX) + RCODE unix_RenameSafe( + const char * pszSrcFile, + const char * pszDestFile); + + RCODE unix_TargetIsDir( + const char * tpath, + FLMBOOL * isdir); +#endif +}; + +FSTATIC FLMBOOL f_canReducePath( + const char * pszSource); + +FSTATIC const char * f_findFileNameStart( + const char * pszPath); + +FSTATIC char * f_getPathComponent( + char ** ppszPath, + FLMUINT * puiEndChar); + +/**************************************************************************** +Desc: Returns TRUE if character is a "slash" separator +****************************************************************************/ +FINLINE FLMBOOL f_isSlashSeparator( + char cChar) +{ +#ifdef FLM_UNIX + return( cChar == '/' ? TRUE : FALSE); +#else + return( cChar == '/' || cChar == '\\' ? TRUE : FALSE); +#endif +} + +/**************************************************************************** +Desc: Return a pointer to the next path component in ppszPath. +****************************************************************************/ +FSTATIC char * f_getPathComponent( + char ** ppszPath, + FLMUINT * puiEndChar) +{ + char * pszComponent; + char * pszEnd; + + pszComponent = pszEnd = *ppszPath; + if (f_isSlashSeparator( *pszEnd)) + { + // handle the condition of sys:\system the colon would have terminated + // the previous token, to pComponent would now be pointing at the '\'. + // We need to move past the '\' to find the next token. + + pszEnd++; + } + + // Find the end of the path component + + while (*pszEnd) + { + if (f_isSlashSeparator( *pszEnd) +#ifndef FLM_UNIX + || *pszEnd == ':' +#endif + ) + { + break; + } + pszEnd++; + } + + if (*pszEnd) + { + + // A delimiter was found, assume that there is another path component + // after this one. + // Return a pointer to the beginning of the next path component + + *ppszPath = pszEnd + 1; + + *puiEndChar = *pszEnd; + + // NULL terminate the path component + + *pszEnd = 0; + } + else + { + + // There is no "next path component" so return a pointer to the + // NULL-terminator + + *ppszPath = pszEnd; + *puiEndChar = 0; + } + + // Return the path component + + return( pszComponent); +} + +/**************************************************************************** +Desc: Will determine whether any format of (UNC, drive based, NetWare + UNC) path can be reduced any further. +****************************************************************************/ +FSTATIC FLMBOOL f_canReducePath( + const char * pszSource) +{ +#if defined FLM_UNIX + F_UNREFERENCED_PARM( pszSource); + return( TRUE); +#else + FLMBOOL bCanReduce; + const char * pszTemp = pszSource; + + // Determine whether the passed path is UNC or not + // (UNC format is: \\FileServer\Volume\Path). + + if (f_strncmp( "\\\\", pszSource, 2 ) == 0) + { + FLMUINT uiSlashCount = 0; + + pszTemp += 2; + + // Search forward for at least two slash separators + // If we find at least two, the path can be reduced. + + bCanReduce = FALSE; + while (*pszTemp) + { + pszTemp++; + if (f_isSlashSeparator( *pszTemp)) + { + ++uiSlashCount; + if (uiSlashCount == 2) + { + bCanReduce = TRUE; + break; + } + } + } + } + else + { + bCanReduce = TRUE; + + // Search forward for the colon. + + while (*pszTemp) + { + if (*pszTemp == ':') + { + + // If nothing comes after the colon, + // we can't reduce any more. + + if (*(pszTemp + 1) == 0) + { + bCanReduce = FALSE; + } + break; + } + pszTemp++; + } + } + + return( bCanReduce); +#endif +} + +/**************************************************************************** +Desc: Return pointer to start of filename part of path. + Search for the last slash separator. +****************************************************************************/ +FSTATIC const char * f_findFileNameStart( + const char * pszPath) +{ + const char * pszFileNameStart; + + pszFileNameStart = pszPath; + while (*pszPath) + { + if (f_isSlashSeparator( *pszPath)) + { + pszFileNameStart = pszPath + 1; + } + pszPath++; + } + return( pszFileNameStart); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +RCODE f_allocFileSystem( + IF_FileSystem ** ppFileSystem) +{ + if( (*ppFileSystem = f_new F_FileSystem) == NULL) + { + return( RC_SET( NE_FLM_MEM)); + } + + return( NE_FLM_OK); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +RCODE FLMAPI FlmGetFileSystem( + IF_FileSystem ** ppFileSystem) +{ + *ppFileSystem = gv_pFileSystem; + (*ppFileSystem)->AddRef(); + return( NE_FLM_OK); +} + /**************************************************************************** Desc: Create a file, return a file handle to created file. ****************************************************************************/ @@ -35,23 +395,27 @@ RCODE FLMAPI F_FileSystem::createFile( { RCODE rc = NE_FLM_OK; F_FileHdl * pFileHdl = NULL; - - if ((pFileHdl = f_new F_FileHdl) == NULL) + + if( RC_BAD( rc = f_allocFileHdl( &pFileHdl))) { - rc = RC_SET( NE_FLM_MEM); goto Exit; } if (RC_BAD( rc = pFileHdl->create( pszFileName, uiIoFlags))) { - pFileHdl->Release(); - pFileHdl = NULL; goto Exit; } + + *ppFileHdl = pFileHdl; + pFileHdl = NULL; Exit: - *ppFileHdl = (IF_FileHdl *)pFileHdl; + if( pFileHdl) + { + pFileHdl->Release(); + } + return( rc); } @@ -64,12 +428,11 @@ RCODE FLMAPI F_FileSystem::createBlockFile( FLMUINT uiBlockSize, IF_FileHdl ** ppFileHdl) { - RCODE rc = NE_FLM_OK; - F_FileHdl * pFileHdl = NULL; + RCODE rc = NE_FLM_OK; + F_FileHdl * pFileHdl = NULL; - if ((pFileHdl = f_new F_FileHdl) == NULL) + if( RC_BAD( rc = f_allocFileHdl( &pFileHdl))) { - rc = RC_SET( NE_FLM_MEM); goto Exit; } @@ -77,14 +440,19 @@ RCODE FLMAPI F_FileSystem::createBlockFile( if (RC_BAD( rc = pFileHdl->create( pszFileName, uiIoFlags))) { - pFileHdl->Release(); - pFileHdl = NULL; goto Exit; } + + *ppFileHdl = pFileHdl; + pFileHdl = NULL; Exit: - *ppFileHdl = (IF_FileHdl *)pFileHdl; + if( pFileHdl) + { + pFileHdl->Release(); + } + return( rc); } @@ -97,25 +465,30 @@ RCODE FLMAPI F_FileSystem::createUniqueFile( FLMUINT uiIoFlags, IF_FileHdl ** ppFileHdl) { - RCODE rc; + RCODE rc = NE_FLM_OK; F_FileHdl * pFileHdl = NULL; - if ((pFileHdl = f_new F_FileHdl) == NULL) + if( RC_BAD( rc = f_allocFileHdl( &pFileHdl))) { - rc = RC_SET( NE_FLM_MEM); goto Exit; } + if( RC_BAD( rc = pFileHdl->createUnique( pszDirName, pszFileExtension, uiIoFlags))) { - pFileHdl->Release(); - pFileHdl = NULL; goto Exit; } + + *ppFileHdl = pFileHdl; + pFileHdl = NULL; Exit: - *ppFileHdl = (IF_FileHdl *)pFileHdl; + if( pFileHdl) + { + pFileHdl->Release(); + } + return( rc); } @@ -127,24 +500,29 @@ RCODE FLMAPI F_FileSystem::openFile( FLMUINT uiIoFlags, IF_FileHdl ** ppFileHdl) { - RCODE rc = NE_FLM_OK; - F_FileHdl * pFileHdl = NULL; + RCODE rc = NE_FLM_OK; + F_FileHdl * pFileHdl = NULL; - if ((pFileHdl = f_new F_FileHdl) == NULL) + if( RC_BAD( rc = f_allocFileHdl( &pFileHdl))) { - rc = RC_SET( NE_FLM_MEM); goto Exit; } + if (RC_BAD( rc = pFileHdl->open( pszFileName, uiIoFlags))) { - pFileHdl->Release(); - pFileHdl = NULL; goto Exit; } + + *ppFileHdl = pFileHdl; + pFileHdl = NULL; Exit: - *ppFileHdl = (IF_FileHdl *)pFileHdl; + if( pFileHdl) + { + pFileHdl->Release(); + } + return( rc); } @@ -157,12 +535,11 @@ RCODE FLMAPI F_FileSystem::openBlockFile( FLMUINT uiBlockSize, IF_FileHdl ** ppFileHdl) { - RCODE rc = NE_FLM_OK; - F_FileHdl * pFileHdl = NULL; + RCODE rc = NE_FLM_OK; + F_FileHdl * pFileHdl = NULL; - if ((pFileHdl = f_new F_FileHdl) == NULL) + if( RC_BAD( rc = f_allocFileHdl( &pFileHdl))) { - rc = RC_SET( NE_FLM_MEM); goto Exit; } @@ -170,14 +547,19 @@ RCODE FLMAPI F_FileSystem::openBlockFile( if (RC_BAD( rc = pFileHdl->open( pszFileName, uiIoFlags))) { - pFileHdl->Release(); - pFileHdl = NULL; goto Exit; } + + *ppFileHdl = pFileHdl; + pFileHdl = NULL; Exit: - *ppFileHdl = (IF_FileHdl *)pFileHdl; + if( pFileHdl) + { + pFileHdl->Release(); + } + return( rc); } @@ -189,23 +571,29 @@ RCODE FLMAPI F_FileSystem::openDir( const char * pszPattern, IF_DirHdl ** ppDirHdl) { - RCODE rc = NE_FLM_OK; - F_DirHdl * pDirHdl = NULL; - - if ((pDirHdl = f_new F_DirHdl) == NULL) + RCODE rc = NE_FLM_OK; + F_DirHdl * pDirHdl = NULL; + + if( RC_BAD( rc = f_allocDirHdl( &pDirHdl))) { - rc = RC_SET( NE_FLM_MEM); goto Exit; } - if (RC_BAD( rc = pDirHdl->openDir( pszDirName, pszPattern))) + + if( RC_BAD( rc = pDirHdl->openDir( pszDirName, pszPattern))) { - pDirHdl->Release(); - pDirHdl = NULL; + goto Exit; } + *ppDirHdl = (IF_DirHdl *)pDirHdl; + pDirHdl = NULL; + Exit: - *ppDirHdl = (IF_DirHdl *)pDirHdl; + if( pDirHdl) + { + pDirHdl->Release(); + } + return( rc); } @@ -215,16 +603,18 @@ Desc: Create a directory. RCODE FLMAPI F_FileSystem::createDir( const char * pszDirName) { - RCODE rc = NE_FLM_OK; - F_DirHdl * pDirHdl = NULL; - - if ((pDirHdl = f_new F_DirHdl) == NULL) + RCODE rc = NE_FLM_OK; + F_DirHdl * pDirHdl = NULL; + + if( RC_BAD( rc = f_allocDirHdl( &pDirHdl))) { - rc = RC_SET( NE_FLM_MEM); goto Exit; } - rc = pDirHdl->createDir( pszDirName); + if( RC_BAD( rc = pDirHdl->createDir( pszDirName))) + { + goto Exit; + } Exit: @@ -253,7 +643,7 @@ RCODE FLMAPI F_FileSystem::removeDir( goto Exit; } - for ( rc = pDirHdl->next(); RC_OK( rc) ; rc = pDirHdl->next()) + for( rc = pDirHdl->next(); RC_OK( rc) ; rc = pDirHdl->next()) { pDirHdl->currentItemPath( szFilePath); if( !pDirHdl->currentItemIsDir()) @@ -406,17 +796,20 @@ RCODE FLMAPI F_FileSystem::getFileTimeStamp( goto Exit; } - /* Fill the Time Stamp structure */ + // Fill the time stamp structure + f_memset( &tmstamp, 0, sizeof( F_TMSTAMP)); - tmstamp.hour = (FLMBYTE)stLastFileWriteTime.wHour; - tmstamp.minute = (FLMBYTE)stLastFileWriteTime.wMinute; - tmstamp.second = (FLMBYTE)stLastFileWriteTime.wSecond; + + tmstamp.hour = (FLMBYTE)stLastFileWriteTime.wHour; + tmstamp.minute = (FLMBYTE)stLastFileWriteTime.wMinute; + tmstamp.second = (FLMBYTE)stLastFileWriteTime.wSecond; tmstamp.hundredth = (FLMBYTE)stLastFileWriteTime.wMilliseconds; - tmstamp.year = (FLMUINT16)stLastFileWriteTime.wYear; - tmstamp.month = (FLMBYTE)(stLastFileWriteTime.wMonth - 1); - tmstamp.day = (FLMBYTE)stLastFileWriteTime.wDay; + tmstamp.year = (FLMUINT16)stLastFileWriteTime.wYear; + tmstamp.month = (FLMBYTE)(stLastFileWriteTime.wMonth - 1); + tmstamp.day = (FLMBYTE)stLastFileWriteTime.wDay; - /* Convert and return the file time stamp as seconds since January 1, 1970 */ + // Convert and return the file time stamp as seconds since January 1, 1970 + f_timeDateToSeconds( &tmstamp, puiTimeStamp); Exit: @@ -822,13 +1215,13 @@ RCODE F_FileSystem::setReadOnly( goto Exit; } - if ( bReadOnly) + if( bReadOnly) { - dwAttr |= F_IO_FA_RDONLY; + dwAttr |= FILE_ATTRIBUTE_READONLY; } else { - dwAttr &= ~F_IO_FA_RDONLY; + dwAttr &= ~FILE_ATTRIBUTE_READONLY; } if( !SetFileAttributes( (LPTSTR)pszFileName, dwAttr)) @@ -924,359 +1317,6 @@ Exit: } #endif -/**************************************************************************** -Desc: Initializes variables -****************************************************************************/ -F_FileHdlMgr::F_FileHdlMgr() -{ - m_hMutex = F_MUTEX_NULL; - - m_uiOpenThreshold = 0xFFFF; - FLM_SECS_TO_TIMER_UNITS( 30 * 60, m_uiMaxAvailTime); - m_bIsSetup = FALSE; - - m_uiFileIdCounter = 0; - - m_pFirstAvail = NULL; - m_pLastAvail = NULL; - m_uiNumAvail = 0; - - m_pFirstUsed = NULL; - m_pLastUsed = NULL; - m_uiNumUsed = 0; - -} - -/**************************************************************************** -Desc: Setup the File handle manager. -****************************************************************************/ -RCODE F_FileHdlMgr::setupFileHdlMgr( - FLMUINT uiOpenThreshold, - FLMUINT uiMaxAvailTime) -{ - RCODE rc = NE_FLM_OK; - - if (RC_BAD( rc = f_mutexCreate( &m_hMutex))) - { - goto Exit; - } - - m_uiOpenThreshold = uiOpenThreshold; - m_uiMaxAvailTime = uiMaxAvailTime; - m_bIsSetup = TRUE; - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: Return the next available file handle that matches the uiFileId. -****************************************************************************/ -void F_FileHdlMgr::findAvail( - FLMUINT uiFileId, - FLMBOOL bReadOnlyFlag, - F_FileHdl ** ppFileHdl) -{ - F_FileHdl * pFileHdl; - - lockMutex( FALSE); - pFileHdl = m_pFirstAvail; - while (pFileHdl) - { - if (pFileHdl->m_uiFileId == uiFileId && - pFileHdl->m_bOpenedReadOnly == bReadOnlyFlag) - { - - // Move this file handle out of the available list into - // the used list. - - // NOTE: To prevent this file handle from being freed this code - // performs an AddRef while its being relinked. This reference - // will be kept for the caller. - - pFileHdl->AddRef(); - - removeFromList( TRUE, - pFileHdl, &m_pFirstAvail, &m_pLastAvail, &m_uiNumAvail); - - insertInList( TRUE, pFileHdl, FALSE, - &m_pFirstUsed, &m_pLastUsed, &m_uiNumUsed); - - break; - } - - pFileHdl = pFileHdl->m_pNext; - } - - unlockMutex( FALSE); - *ppFileHdl = pFileHdl; -} - -/**************************************************************************** -Desc: Make the specified F_FileHdl available for someone else to use. -****************************************************************************/ -void F_FileHdlMgr::makeAvailAndRelease( - FLMBOOL bMutexAlreadyLocked, - F_FileHdl * pFileHdl) -{ - pFileHdl->m_uiAvailTime = (FLMUINT)FLM_GET_TIMER(); - - lockMutex( bMutexAlreadyLocked); - - pFileHdl->AddRef(); - - removeFromList( TRUE, - pFileHdl, &m_pFirstUsed, &m_pLastUsed, &m_uiNumUsed); - - insertInList( TRUE, pFileHdl, TRUE, - &m_pFirstAvail, &m_pLastAvail, &m_uiNumAvail); - - pFileHdl->Release(); - pFileHdl->Release(); - - unlockMutex( bMutexAlreadyLocked); -} - -/**************************************************************************** -Desc: Remove (close&free) all FileHdl's that have the specified FileId. - Remove from the avail and used lists. -****************************************************************************/ -void F_FileHdlMgr::removeFileHdls( - FLMUINT uiFileId) -{ - F_FileHdl * pFileHdl; - F_FileHdl * pNextFileHdl; - - lockMutex( FALSE); - - // Free all matching file handles in the available list. - - pFileHdl = m_pFirstAvail; - while (pFileHdl) - { - pNextFileHdl = pFileHdl->m_pNext; - if (pFileHdl->m_uiFileId == uiFileId) - { - removeFromList( TRUE, - pFileHdl, &m_pFirstAvail, &m_pLastAvail, &m_uiNumAvail); - } - - pFileHdl = pNextFileHdl; - } - - // Free all matching file handles in the used list. - - pFileHdl = m_pFirstUsed; - while (pFileHdl) - { - pNextFileHdl = pFileHdl->m_pNext; - if (pFileHdl->m_uiFileId == uiFileId) - { - removeFromList( TRUE, - pFileHdl, &m_pFirstUsed, &m_pLastUsed, &m_uiNumUsed); - } - - pFileHdl = pNextFileHdl; - } - - unlockMutex( FALSE); -} - -/**************************************************************************** -Desc: Remove all handles from the avail list. -****************************************************************************/ -void F_FileHdlMgr::freeAvailList( - FLMBOOL bMutexAlreadyLocked) -{ - F_FileHdl * pFileHdl; - F_FileHdl * pNextFileHdl; - - lockMutex( bMutexAlreadyLocked); - pFileHdl = m_pFirstAvail; - while (pFileHdl) - { - pFileHdl->m_bInList = FALSE; - pNextFileHdl = pFileHdl->m_pNext; - pFileHdl->Release(); - pFileHdl = pNextFileHdl; - } - - m_pFirstAvail = NULL; - m_pLastAvail = NULL; - m_uiNumAvail = 0; - - unlockMutex( bMutexAlreadyLocked); -} - -/**************************************************************************** -Desc: Remove all handles from the used list. -****************************************************************************/ -void F_FileHdlMgr::freeUsedList( - FLMBOOL bMutexAlreadyLocked) -{ - F_FileHdl * pFileHdl; - F_FileHdl * pNextFileHdl; - - lockMutex( bMutexAlreadyLocked); - - pFileHdl = m_pFirstUsed; - while (pFileHdl) - { - pFileHdl->m_bInList = FALSE; - pNextFileHdl = pFileHdl->m_pNext; - pFileHdl->Release(); - pFileHdl = pNextFileHdl; - } - - m_pFirstUsed = NULL; - m_pLastUsed = NULL; - m_uiNumUsed = 0; - - unlockMutex( bMutexAlreadyLocked); -} - -/**************************************************************************** -Desc: Insert a handle into either the avail or used list. -****************************************************************************/ -void F_FileHdlMgr::insertInList( - FLMBOOL bMutexAlreadyLocked, - F_FileHdl * pFileHdl, - FLMBOOL bInsertAtEnd, - F_FileHdl ** ppFirst, - F_FileHdl ** ppLast, - FLMUINT * puiCount) -{ - lockMutex( bMutexAlreadyLocked); - - flmAssert( !pFileHdl->m_bInList); - - if (bInsertAtEnd) - { - pFileHdl->m_pNext = NULL; - if ((pFileHdl->m_pPrev = *ppLast) != NULL) - { - pFileHdl->m_pPrev->m_pNext = pFileHdl; - } - else - { - *ppFirst = pFileHdl; - } - - *ppLast = pFileHdl; - } - else - { - pFileHdl->m_pPrev = NULL; - if ((pFileHdl->m_pNext = *ppFirst) != NULL) - { - pFileHdl->m_pNext->m_pPrev = pFileHdl; - } - else - { - *ppLast = pFileHdl; - } - - *ppFirst = pFileHdl; - } - - (*puiCount)++; - pFileHdl->m_bInList = TRUE; - pFileHdl->AddRef(); - - unlockMutex( bMutexAlreadyLocked); -} - -/**************************************************************************** -Desc: Remove a handle into either the avail or used list. -****************************************************************************/ -void F_FileHdlMgr::removeFromList( - FLMBOOL bMutexAlreadyLocked, - F_FileHdl * pFileHdl, - F_FileHdl ** ppFirst, - F_FileHdl ** ppLast, - FLMUINT * puiCount) -{ - lockMutex( bMutexAlreadyLocked); - - flmAssert( pFileHdl->m_bInList); - if (pFileHdl->m_pNext) - { - pFileHdl->m_pNext->m_pPrev = pFileHdl->m_pPrev; - } - else - { - *ppLast = pFileHdl->m_pPrev; - } - - if (pFileHdl->m_pPrev) - { - pFileHdl->m_pPrev->m_pNext = pFileHdl->m_pNext; - } - else - { - *ppFirst = pFileHdl->m_pNext; - } - - flmAssert( *puiCount); - - (*puiCount)--; - pFileHdl->m_bInList = FALSE; - pFileHdl->Release(); - - unlockMutex( bMutexAlreadyLocked); -} - -/**************************************************************************** -Desc: Check items in the avail list and if over a certain age then - remove them from the avail list. This will cause file handles - that have been opened for a long time to be closed. Also added - code to reduce the total number of file handles if it is more - than the open threshold. -****************************************************************************/ -void F_FileHdlMgr::checkAgedFileHdls( - FLMUINT uiMinTimeOpened) -{ - FLMUINT uiTime; - FLMUINT uiMaxAvailTicks; - - uiTime = (FLMUINT)FLM_GET_TIMER(); - - FLM_SECS_TO_TIMER_UNITS( uiMinTimeOpened, uiMaxAvailTicks); - - lockMutex( FALSE); - - // Loop while the open count is greater than the open threshold. - - while (m_uiNumAvail && (m_uiNumAvail + m_uiNumUsed > m_uiOpenThreshold)) - { - // Release until the threshold is down. - - releaseOneAvail( TRUE); - } - - // Reduce all items older than the specified time. - - while (m_pFirstAvail) - { - // All file handles are in order of oldest first. - // m_uiMaxAvailTime may be a zero value. - - if( FLM_ELAPSED_TIME( uiTime, - m_pFirstAvail->m_uiAvailTime) < uiMaxAvailTicks) - { - // All files are newer so we are done. - - break; - } - - removeFromList( TRUE, - m_pFirstAvail, &m_pFirstAvail, &m_pLastAvail, &m_uiNumAvail); - } - - unlockMutex( FALSE); -} - /**************************************************************************** Desc: Do a partial copy from one file into another file. ****************************************************************************/ @@ -1445,16 +1485,15 @@ RCODE FLMAPI f_filecat( { RCODE rc = NE_FLM_OK; IF_FileHdl * pFileHdl = NULL; - F_FileSystem fileSystem; FLMUINT64 ui64FileSize = 0; FLMUINT uiBytesWritten = 0; - if (RC_BAD( rc = fileSystem.doesFileExist( pszSourceFile))) + if (RC_BAD( rc = gv_pFileSystem->doesFileExist( pszSourceFile))) { if( rc == NE_FLM_IO_PATH_NOT_FOUND) { - if( RC_BAD( rc = fileSystem.createFile( pszSourceFile, FLM_IO_RDWR, - &pFileHdl))) + if( RC_BAD( rc = gv_pFileSystem->createFile( + pszSourceFile, FLM_IO_RDWR, &pFileHdl))) { goto Exit; } @@ -1466,7 +1505,7 @@ RCODE FLMAPI f_filecat( } else { - if( RC_BAD( rc = fileSystem.openFile( pszSourceFile, + if( RC_BAD( rc = gv_pFileSystem->openFile( pszSourceFile, FLM_IO_RDWR, &pFileHdl))) { goto Exit; @@ -1488,10 +1527,553 @@ Exit: if( pFileHdl) { - pFileHdl->close(); pFileHdl->Release(); - pFileHdl = NULL; } return( rc); } + +/**************************************************************************** +Desc: Split the path into its components +Output: + pServer - pointer to a buffer to hold the server name + pVolume - pointer to a buffer to hold the volume name + pDirPath - pointer to a buffer to hold the path + pFileName pointer to a buffer to hold the filename + + All of the output parameters are optional. If you do not want one + of the components, simply give a NULL pointer. + +Note: if the input path has no file name, d:\dir_1 for example, then + pass a NULL pointer for pFileName. Otherwise dir_1 will be returned + as pFileName. + + The server name may be ommitted in the input path: + sys:\system\autoexec.ncf + + UNC paths of the form: + \\server-name\volume-name\dir_1\dir_2\file.ext + are supported. + + DOS paths of the form: + d:\dir_1\dir_2\file.ext + are also supported. + +Example: + Given this input: orm-prod48/sys:\system\autoexec.ncf + The output would be: + pServer = "orm-prod48" + pVolume = "sys:" + pDirPath = "\system" + pFileName "autoexec.ncf" +****************************************************************************/ +void FLMAPI F_FileSystem::pathParse( + const char * pszInputPath, + char * pszServer, + char * pszVolume, + char * pszDirPath, + char * pszFileName) +{ + char szInput[ F_PATH_MAX_SIZE]; + char * pszNext; + char * pszColon; + char * pszComponent; + FLMUINT uiEndChar; + FLMBOOL bUNC = FALSE; + + // Initialize return buffers + + if (pszServer) + { + *pszServer = 0; + } + if (pszVolume) + { + *pszVolume = 0; + } + if (pszDirPath) + { + *pszDirPath = 0; + } + if (pszFileName) + { + + // Get the file name + + *pszFileName = 0; + gv_pFileSystem->pathReduce( pszInputPath, szInput, pszFileName); + } + else + { + f_strcpy( szInput, pszInputPath); + } + + // Split out the rest of the components + + pszComponent = &szInput [0]; + + // Is this a UNC path? + + if (szInput[0] == '\\' && szInput[1] == '\\') + { + + // Yes, assume a UNC path + + pszComponent += 2; + bUNC = TRUE; + } + + pszNext = pszColon = pszComponent; + + // Is there a ':' in the szInput path? + + while (*pszColon && *pszColon != ':') + { + pszColon++; + } + if (*pszColon || bUNC) + { + + // Yes, assume there is a volume in the path + + pszComponent = f_getPathComponent( &pszNext, &uiEndChar); + if (uiEndChar != ':') + { + // Assume that this component is the server + + if (pszServer) + { + f_strcpy( pszServer, pszComponent); + } + + // Get the next component + + pszComponent = f_getPathComponent( &pszNext, &uiEndChar); + } + + // Assume that this component is the volume + + if (pszVolume) + { + char * pszSrc = pszComponent; + char * pszDst = pszVolume; + + while (*pszSrc) + { + *pszDst++ = *pszSrc++; + } + *pszDst++ = ':'; + *pszDst = 0; + } + + // For UNC paths, the leading '\' of the path is set to 0 by + // f_getPathComponent. This code restores the leading '\'. + + if (f_isSlashSeparator( (char)uiEndChar)) + { + *(--pszNext) = (char)uiEndChar; + } + } + + // Assume that all that is left of the input is the path + + if (pszDirPath) + { + f_strcpy( pszDirPath, pszNext); + } +} + +/**************************************************************************** +Desc: This function will strip off the filename or trailing + directory of a path. The stripped component of the path will + be placed into the area pointed at by string. The source + path will not be modified. The dest path will contain the + remainder of the stripped path. A stripped path can be processed + repeatedly by this function until there is no more path to reduce. + If the string is set to NULL, the copying of the stripped portion of + the path will be bypassed by the function. + +Notes: This function handles drive based, UNC, Netware, and UNIX type + paths. +****************************************************************************/ +RCODE FLMAPI F_FileSystem::pathReduce( + const char * pszPath, + char * pszDir, + char * pszPathComponent) +{ + RCODE rc = NE_FLM_OK; + const char * pszFileNameStart; + char szLocalPath[ F_PATH_MAX_SIZE]; + FLMUINT uiLen; + + // Check for valid path pointers + + if( !pszPath || !pszDir) + { + rc = RC_SET( NE_FLM_INVALID_PARM); + goto Exit; + } + + if ((uiLen = f_strlen( pszPath)) == 0) + { + rc = RC_SET( NE_FLM_IO_CANNOT_REDUCE_PATH); + goto Exit; + } + + // Trim out any trailing slash separators + + if( f_isSlashSeparator( pszPath [uiLen - 1])) + { + f_strcpy( szLocalPath, pszPath); + + while( f_isSlashSeparator( szLocalPath[ uiLen - 1])) + { + szLocalPath[ --uiLen] = 0; + if( !uiLen) + { + rc = RC_SET( NE_FLM_IO_CANNOT_REDUCE_PATH); + goto Exit; + } + } + + pszPath = szLocalPath; + } + + if( f_canReducePath( pszPath)) + { + // Search for a slash or beginning of path + + pszFileNameStart = f_findFileNameStart( pszPath); + + // Copy the sliced portion of the path if requested by caller + + if( pszPathComponent) + { + f_strcpy( pszPathComponent, pszFileNameStart); + } + + // Copy the reduced source path to the dir path + + if (pszFileNameStart > pszPath) + { + uiLen = (FLMUINT)(pszFileNameStart - pszPath); + f_memcpy( pszDir, pszPath, uiLen); + + if (uiLen >= 2 && f_isSlashSeparator( pszDir [uiLen - 1]) +#ifndef FLM_UNIX + && pszDir [uiLen - 2] != ':' +#endif + ) + { + // Trim off the trailing path separator + + pszDir [uiLen - 1] = 0; + } + else + { + pszDir [uiLen] = 0; + } + } + else + { + *pszDir = 0; + } + } + else + { + // We've found the drive id or server\volume specifier. + + if (pszPathComponent) + { + f_strcpy( pszPathComponent, pszPath); + } + + *pszDir = 0; + } + +Exit: + + return( rc); +} + +/**************************************************************************** +Desc: Internal function for WpioPathBuild() and WpioPathModify(). + Appends string the path & adds a path delimiter if necessary. +In: *path = pointer to an IO_PATH + *string = pointer to a NULL terminated string + *end_ptr = pointer to the end of the IO_PATH which is being built. +****************************************************************************/ +RCODE FLMAPI F_FileSystem::pathAppend( + char * pszPath, + const char * pszPathComponent) +{ + + // Don't put a slash separator if pszPath is empty + + if (*pszPath) + { + FLMUINT uiStrLen = f_strlen( pszPath); + char * pszEnd = pszPath + uiStrLen - 1; + + if (!f_isSlashSeparator( *pszEnd)) + { + + // Check for maximum path size - 2 is for slash separator + // and null byte. + + if (uiStrLen + 2 + f_strlen( pszPathComponent) > F_PATH_MAX_SIZE) + { + return RC_SET( NE_FLM_IO_PATH_TOO_LONG); + } + + pszEnd++; +#if defined( FLM_UNIX) + *pszEnd = '/'; +#else + *pszEnd = '\\'; +#endif + } + else + { + + // Check for maximum path size +1 is for null byte. + + if (uiStrLen + 1 + f_strlen( pszPathComponent) > F_PATH_MAX_SIZE) + { + return RC_SET( NE_FLM_IO_PATH_TOO_LONG); + } + } + + f_strcpy( pszEnd + 1, pszPathComponent); + } + else + { + f_strcpy( pszPath, pszPathComponent); + } + + return( NE_FLM_OK); +} + +/**************************************************************************** +Desc: Convert an PATH into a fully qualified, storable C string + reference to a file or directory. +In: pszPath - the path to convert. + pszStorageString - a pointer to a string that is atleast + F_PATH_MAX_SIZE in size +****************************************************************************/ +RCODE FLMAPI F_FileSystem::pathToStorageString( + const char * pszPath, + char * pszStorageString) +{ +#ifdef FLM_WIN + char * pszNamePart; + + if (GetFullPathName( (LPCSTR)pszPath, + (DWORD)F_PATH_MAX_SIZE - 1, + (LPSTR)pszStorageString, + (LPSTR *)&pszNamePart) != 0) + { + + } + else + { + // Convert to upper case. + + while (*pszPath) + { + *pszStorageString++ = *pszPath; + pszPath++; + } + *pszStorageString = 0; + } + return NE_FLM_OK; +#else + + char szFile[ F_PATH_MAX_SIZE]; + char szDir[ F_PATH_MAX_SIZE]; + char * pszRealPath = NULL; + RCODE rc = NE_FLM_OK; + + if (RC_BAD( rc = pathReduce( pszPath, szDir, szFile))) + { + goto Exit; + } + + if (!szDir [0]) + { + szDir [0] = '.'; + szDir [1] = '\0'; + } + + if (RC_BAD( rc = f_alloc( (FLMUINT)PATH_MAX, &pszRealPath))) + { + goto Exit; + } + + if (!realpath( (char *)szDir, (char *)pszRealPath)) + { + rc = MapErrnoToFlaimErr( errno, NE_FLM_PARSING_FILE_NAME); + goto Exit; + } + + if (f_strlen( pszRealPath) >= F_PATH_MAX_SIZE) + { + rc = RC_SET( NE_FLM_IO_PATH_TOO_LONG); + goto Exit; + } + + f_strcpy( pszStorageString, pszRealPath); + + if (RC_BAD( rc = pathAppend( pszStorageString, szFile))) + { + goto Exit; + } + +Exit: + + if (pszRealPath) + { + f_free( &pszRealPath); + } + + return( rc); +#endif +} + +/**************************************************************************** +Desc: Generates a file name given a seed and some modifiers, it is built + to be called in a loop until the file can be sucessfully written or + created with the increment being changed every time. +In: bModext -> if TRUE then we will use the extension for collisions. +In\Out: puiTime -> a modified time stamp which is used as the base + filename. To properly set up this value, make sure + the puiTime points to a 0 the first time this routine + is called and it will be set up for you. Thereafter, + do not change it between calls. + pHighChars-> these are the 8 bits that were shifted off the top of + the time struct. It will be set up for you the first + time you call this routine if puiTime points to a 0 + the first time this routine is called. Do not change + this value between calls. + pszFileName -> should be pointing to a null string on the way in. + going out it will be the complete filename. + pszFileExt -> the last char of the ext will be used for collisions, + depending on the bModext flag. If null then + the extension will be .00x where x is the collision + counter. +Notes: The counter on the collision is 0-9, a-z. +****************************************************************************/ +void FLMAPI F_FileSystem::pathCreateUniqueName( + FLMUINT * puiTime, + char * pszFileName, + const char * pszFileExt, + FLMBYTE * pHighChars, + FLMBOOL bModext) +{ + FLMINT iCount, iLength; + FLMUINT uiSdTmp = 0; + FLMUINT uiIncVal = 1; + + SetUpTime( puiTime, pHighChars); + uiSdTmp = *puiTime; + + *(pszFileName + 8) = NATIVE_DOT; + f_memset( (pszFileName + 9), NATIVE_ZERO, 3 ); + + if ( ( pszFileExt != NULL )) + { + if ((iLength = f_strlen(pszFileExt)) > 3) + { + iLength = 3; + } + f_memmove( (pszFileName + 9), pszFileExt, iLength); + } + + if( bModext == TRUE) + { + HexToNative((FLMBYTE)(uiSdTmp & 0x0000001F), pszFileName+(11)); + } + else + { + uiIncVal = 32; + } + + uiSdTmp = uiSdTmp >> 5; + for( iCount = 0; iCount < 6; iCount++) + { + HexToNative((FLMBYTE)(uiSdTmp & 0x0000000F), pszFileName+(7-iCount)); + uiSdTmp = uiSdTmp >> 4; + } + + for( iCount = 0; iCount < 2; iCount++) + { + HexToNative((FLMBYTE)(*pHighChars & 0x0000000F), pszFileName+(1-iCount)); + *pHighChars = *pHighChars >> 4; + } + + *(pszFileName + 12) = '\0'; + *puiTime += uiIncVal; +} + +/**************************************************************************** +Desc: Compares the current file against a pattern template +****************************************************************************/ +FLMBOOL FLMAPI F_FileSystem::doesFileMatch( + const char * pszFileName, + const char * pszTemplate) +{ + FLMUINT uiPattern; + FLMUINT uiChar; + + if( !*pszTemplate) + { + return( TRUE); + } + + while( *pszTemplate) + { + uiPattern = *pszTemplate++; + switch( uiPattern) + { + case NATIVE_WILDCARD: + { + if( *pszTemplate == 0) + { + return( TRUE); + } + + while( *pszFileName) + { + if( doesFileMatch( pszFileName, pszTemplate)) + { + return( TRUE); + } + pszFileName++; + } + + return( FALSE); + } + + case NATIVE_QUESTIONMARK: + { + if( *pszFileName++ == 0) + { + return( FALSE); + } + break; + } + + default: + { + uiChar = *pszFileName++; + if( f_toupper( uiPattern) != f_toupper( uiChar)) + { + return( FALSE); + } + break; + } + } + } + + return( (*pszFileName != 0) ? FALSE : TRUE); +} diff --git a/ftk/src/ftkini.cpp b/ftk/src/ftkini.cpp index 87c1d3a..514fbd9 100644 --- a/ftk/src/ftkini.cpp +++ b/ftk/src/ftkini.cpp @@ -25,6 +25,125 @@ #include "ftksys.h" +/**************************************************************************** +Desc: +****************************************************************************/ +typedef struct INI_LINE +{ + char * pszParamName; + char * pszParamValue; + char * pszComment; + struct INI_LINE * pPrev; + struct INI_LINE * pNext; +} INI_LINE; + +/**************************************************************************** +Desc: +****************************************************************************/ +class F_IniFile : public IF_IniFile, public F_Base +{ +public: + + F_IniFile(); + + virtual ~F_IniFile(); + + RCODE init( void); + + RCODE FLMAPI read( + const char * pszFileName); + + RCODE FLMAPI write( void); + + FLMBOOL FLMAPI getParam( + const char * pszParamName, + FLMUINT * puiParamVal); + + FLMBOOL FLMAPI getParam( + const char * pszParamName, + FLMBOOL * pbParamVal); + + FLMBOOL FLMAPI getParam( + const char * pszParamName, + char ** ppszParamVal); + + RCODE FLMAPI setParam( + const char * pszParamName, + FLMUINT uiParamVal); + + RCODE FLMAPI setParam( + const char * pszParamName, + FLMBOOL bParamVal); + + RCODE FLMAPI setParam( + const char * pszParamName, + const char * pszParamVal); + + FINLINE FLMBOOL FLMAPI testParam( + const char * pszParamName) + { + if( findParam( pszParamName)) + { + return( TRUE); + } + + return( FALSE); + } + +private: + + RCODE readLine( + char * pucBuf, + FLMUINT * puiBytes, + FLMBOOL * pbMore); + + RCODE parseBuffer( + char * pucBuf, + FLMUINT uiNumButes); + + INI_LINE * findParam( + const char * pszParamName); + + RCODE setParamCommon( + INI_LINE ** ppLine, + const char * pszParamName); + + void fromAscii( + FLMUINT * puiVal, + const char * pszParamValue); + + void fromAscii( + FLMBOOL * pbVal, + const char * pszParamValue); + + RCODE toAscii( + char ** ppszParamValue, + FLMUINT puiVal); + + RCODE toAscii( + char ** ppszParamValue, + FLMBOOL pbVal); + + RCODE toAscii( + char ** ppszParamValue, + const char * pszVal); + + FINLINE FLMBOOL isWhiteSpace( + FLMBYTE ucChar) + { + return( ucChar == 32 || ucChar == 9 ? TRUE : FALSE); + } + + IF_Pool * m_pPool; + IF_FileHdl * m_pFileHdl; + char * m_pszFileName; + INI_LINE * m_pFirstLine; + INI_LINE * m_pLastLine; + FLMBOOL m_bReady; + FLMBOOL m_bModified; + FLMUINT m_uiFileOffset; +}; + /**************************************************************************** Desc: ****************************************************************************/ @@ -63,18 +182,51 @@ F_IniFile::~F_IniFile() /**************************************************************************** Desc: ****************************************************************************/ -RCODE FLMAPI F_IniFile::init() +RCODE FLMAPI FlmAllocIniFile( + IF_IniFile ** ppIniFile) +{ + RCODE rc = NE_FLM_OK; + F_IniFile * pIniFile = NULL; + + if( (pIniFile = f_new F_IniFile) == NULL) + { + rc = RC_SET( NE_FLM_MEM); + goto Exit; + } + + if( RC_BAD( rc = pIniFile->init())) + { + goto Exit; + } + + *ppIniFile = pIniFile; + pIniFile = NULL; + +Exit: + + if( pIniFile) + { + pIniFile->Release(); + } + + return( rc); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +RCODE F_IniFile::init() { RCODE rc = NE_FLM_OK; if( m_pPool) { m_pPool->Release(); + m_pPool = NULL; } - if (( m_pPool = f_new F_Pool) == NULL) + if( RC_BAD( rc = FlmAllocPool( &m_pPool))) { - rc = RC_SET( NE_FLM_MEM); goto Exit; } @@ -185,6 +337,7 @@ RCODE FLMAPI F_IniFile::read( { // NumBytes will be 0 if the line was blank. No need // to call parseBuffer in this case + if (RC_BAD( rc = parseBuffer( pszReadBuf, uiBytesInLine))) { if (rc == NE_FLM_SYNTAX) @@ -197,7 +350,7 @@ RCODE FLMAPI F_IniFile::read( } } } - } // end of while (!bEOF) + } Exit: @@ -240,6 +393,7 @@ RCODE FLMAPI F_IniFile::write( void) if (!m_bModified) { // Nothing needs to be written + goto Exit; } @@ -271,6 +425,7 @@ RCODE FLMAPI F_IniFile::write( void) if (pCurLine->pszParamValue) { // Output the "=" and the value + if (RC_BAD (rc = m_pFileHdl->write( uiFileOffset, 1, (void *)"=", &uiBytesWritten))) { @@ -293,6 +448,7 @@ RCODE FLMAPI F_IniFile::write( void) if (pCurLine->pszComment) { // Output the comment + if (pCurLine->pszParamName) { if (RC_BAD (rc = m_pFileHdl->write( uiFileOffset, 2, diff --git a/ftk/src/ftkiobuf.cpp b/ftk/src/ftkiobuf.cpp index 693786b..44c7d73 100644 --- a/ftk/src/ftkiobuf.cpp +++ b/ftk/src/ftkiobuf.cpp @@ -25,6 +25,76 @@ #include "ftksys.h" +/**************************************************************************** +Desc: +****************************************************************************/ +class F_IOBufferMgr : public IF_IOBufferMgr, public F_Base +{ +public: + + F_IOBufferMgr(); + + virtual ~F_IOBufferMgr(); + + RCODE FLMAPI waitForAllPendingIO( void); + + FINLINE void FLMAPI setMaxBuffers( + FLMUINT uiMaxBuffers) + { + m_uiMaxBuffers = uiMaxBuffers; + } + + FINLINE void FLMAPI setMaxBytes( + FLMUINT uiMaxBytes) + { + m_uiMaxBufferBytesToUse = uiMaxBytes; + } + + FINLINE void FLMAPI enableKeepBuffer( void) + { + m_bKeepBuffers = TRUE; + } + + RCODE FLMAPI getBuffer( + IF_IOBuffer ** ppIOBuffer, + FLMUINT uiBufferSize, + FLMUINT uiBlockSize); + + FINLINE FLMBOOL FLMAPI havePendingIO( void) + { + return( m_pFirstPending ? TRUE : FALSE); + } + + FINLINE FLMBOOL FLMAPI haveUsed( void) + { + return( m_pFirstUsed ? TRUE : FALSE); + } + +private: + + // Private methods and variables + + F_IOBuffer * m_pFirstPending; + F_IOBuffer * m_pFirstAvail; + F_IOBuffer * m_pFirstUsed; + FLMUINT m_uiMaxBuffers; + FLMUINT m_uiMaxBufferBytesToUse; + FLMUINT m_uiBufferBytesInUse; + FLMUINT m_uiBuffersInUse; + RCODE m_completionRc; + FLMBOOL m_bKeepBuffers; + + void linkToList( + F_IOBuffer ** ppListHead, + F_IOBuffer * pIOBuffer); + + void unlinkFromList( + F_IOBuffer * pIOBuffer); + +friend class F_IOBuffer; + +}; + /**************************************************************************** Desc: ****************************************************************************/ diff --git a/ftk/src/ftkmem.cpp b/ftk/src/ftkmem.cpp index 6f42089..f953420 100644 --- a/ftk/src/ftkmem.cpp +++ b/ftk/src/ftkmem.cpp @@ -26,12 +26,43 @@ #include "ftksys.h" +// Cell sizes for buffer allocator + +#define CELL_SIZE_0 16 +#define CELL_SIZE_1 32 +#define CELL_SIZE_2 64 +#define CELL_SIZE_3 128 +#define CELL_SIZE_4 192 +#define CELL_SIZE_5 320 +#define CELL_SIZE_6 512 +#define CELL_SIZE_7 672 +#define CELL_SIZE_8 832 +#define CELL_SIZE_9 1088 +#define CELL_SIZE_10 1344 +#define CELL_SIZE_11 1760 +#define CELL_SIZE_12 2176 +#define CELL_SIZE_13 2848 +#define CELL_SIZE_14 3520 +#define CELL_SIZE_15 4608 +#define CELL_SIZE_16 5152 +#define CELL_SIZE_17 5696 +#define CELL_SIZE_18 8164 +#define CELL_SIZE_19 13068 +#define CELL_SIZE_20 16340 +#define CELL_SIZE_21 21796 +#define MAX_CELL_SIZE CELL_SIZE_21 + +#define NUM_BUF_ALLOCATORS 22 + +/************************************************************************ +Desc: +*************************************************************************/ typedef struct F_MemHdrTag { FLMUINT uiDataSize; #ifdef FLM_DEBUG const char * pszFileName; - FLMINT iLineNumber; + int iLineNumber; FLMBOOL bAllocFromNewOp; FLMUINT uiAllocationId; FLMUINT uiAllocCnt; @@ -42,15 +73,27 @@ typedef struct F_MemHdrTag #endif } F_MEM_HDR; +/************************************************************************ +Desc: +*************************************************************************/ #define F_GET_ALLOC_PTR( pDataPtr) \ (FLMBYTE *)((FLMBYTE *)(pDataPtr) - sizeof( F_MEM_HDR)) +/************************************************************************ +Desc: +*************************************************************************/ #define F_GET_DATA_PTR( pAllocPtr) \ (FLMBYTE *)((FLMBYTE *)(pAllocPtr) + sizeof( F_MEM_HDR)) +/************************************************************************ +Desc: +*************************************************************************/ #define F_GET_MEM_DATA_SIZE( pDataPtr) \ (((F_MEM_HDR *)(F_GET_ALLOC_PTR( pDataPtr)))->uiDataSize) +/************************************************************************ +Desc: +*************************************************************************/ #if defined( FLM_UNIX) || defined( FLM_NLM) || defined( FLM_WIN) #define PTR_IN_MBLK(p,bp,offs) \ (((FLMBYTE *)(p) > (FLMBYTE *)(bp)) && \ @@ -59,6 +102,21 @@ typedef struct F_MemHdrTag #error Platform not supported #endif +static FLMBOOL gv_bMemTrackingInitialized = FALSE; +static FLMUINT gv_uiInitThreadId = 0; +static F_MUTEX gv_hMemTrackingMutex = F_MUTEX_NULL; +static FLMUINT gv_uiMemTrackingPtrArraySize = 0; +static FLMBOOL gv_bTrackLeaks = FALSE; +static FLMUINT gv_uiNumMemPtrs = 0; +static void ** gv_ppvMemTrackingPtrs = NULL; +static FLMUINT gv_uiNextMemPtrSlotToUse = 0; +static FLMUINT gv_uiAllocCnt = 0; +static FLMBOOL gv_bStackWalk = FALSE; +static FLMBOOL gv_bLogLeaks = FALSE; +#ifdef FLM_WIN + static HANDLE gv_hMemProcess; +#endif + #define MEM_PTR_INIT_ARRAY_SIZE 512 #define MEM_MAX_STACK_WALK_DEPTH 32 @@ -78,22 +136,6 @@ typedef struct F_MemHdrTag } #endif -static FLMBOOL gv_bMemTrackingInitialized = FALSE; -static FLMUINT gv_uiInitThreadId = 0; -static F_MUTEX gv_hMemTrackingMutex = F_MUTEX_NULL; -static FLMUINT gv_uiMemTrackingPtrArraySize = 0; -static FLMBOOL gv_bTrackLeaks = FALSE; -static FLMUINT gv_uiNumMemPtrs = 0; -static void ** gv_ppvMemTrackingPtrs = NULL; -static FLMUINT gv_uiNextMemPtrSlotToUse = 0; -static FLMUINT gv_uiAllocCnt = 0; -static FLMBOOL gv_bStackWalk = FALSE; -static FLMBOOL gv_bLogLeaks = FALSE; - -#ifdef FLM_WIN - static HANDLE gv_hMemProcess; -#endif - FSTATIC FLMBOOL initMemTracking( void); FSTATIC void saveMemTrackingInfo( @@ -107,6 +149,580 @@ FSTATIC void freeMemTrackingInfo( FLMUINT uiId, FLMUINT * puiStack); +/**************************************************************************** +Desc: +****************************************************************************/ +class F_SlabManager : public IF_SlabManager, public F_Base +{ +public: + + F_SlabManager(); + + virtual ~F_SlabManager(); + + RCODE FLMAPI setup( + FLMUINT uiPreallocSize); + + RCODE FLMAPI allocSlab( + void ** ppSlab, + FLMBOOL bMutexLocked); + + void FLMAPI freeSlab( + void ** ppSlab, + FLMBOOL bMutexLocked); + + RCODE FLMAPI resize( + FLMUINT uiNumBytes, + FLMUINT * puiActualSize = NULL, + FLMBOOL bMutexLocked = FALSE); + + FINLINE void FLMAPI incrementTotalBytesAllocated( + FLMUINT uiCount, + FLMBOOL bMutexLocked) + { + if( !bMutexLocked) + { + lockMutex(); + } + + m_uiTotalBytesAllocated += uiCount; + + if( !bMutexLocked) + { + unlockMutex(); + } + } + + FINLINE void FLMAPI decrementTotalBytesAllocated( + FLMUINT uiCount, + FLMBOOL bMutexLocked) + { + if( !bMutexLocked) + { + lockMutex(); + } + + flmAssert( m_uiTotalBytesAllocated >= uiCount); + m_uiTotalBytesAllocated -= uiCount; + + if( !bMutexLocked) + { + unlockMutex(); + } + } + + FINLINE FLMUINT FLMAPI getSlabSize( void) + { + return( m_uiSlabSize); + } + + FINLINE FLMUINT FLMAPI getTotalSlabs( void) + { + return( m_uiTotalSlabs); + } + + FINLINE void FLMAPI lockMutex( void) + { + f_mutexLock( m_hMutex); + } + + FINLINE void FLMAPI unlockMutex( void) + { + f_mutexUnlock( m_hMutex); + } + + FINLINE FLMUINT FLMAPI totalBytesAllocated( void) + { + return( m_uiTotalBytesAllocated); + } + + FINLINE FLMUINT FLMAPI availSlabs( void) + { + return( m_uiAvailSlabs); + } + +private: + + void freeAllSlabs( void); + + void * allocSlabFromSystem( void); + + void releaseSlabToSystem( + void * pSlab); + + RCODE sortSlabList( void); + + typedef struct + { + void * pPrev; + void * pNext; + } SLABHEADER; + + static FLMINT FLMAPI slabAddrCompareFunc( + void * pvBuffer, + FLMUINT uiPos1, + FLMUINT uiPos2); + + static void FLMAPI slabAddrSwapFunc( + void * pvBuffer, + FLMUINT uiPos1, + FLMUINT uiPos2); + + F_MUTEX m_hMutex; + FLMUINT m_uiTotalBytesAllocated; + void * m_pFirstInSlabList; + void * m_pLastInSlabList; + FLMUINT m_uiSlabSize; + FLMUINT m_uiTotalSlabs; + FLMUINT m_uiAvailSlabs; + FLMUINT m_uiInUseSlabs; + FLMUINT m_uiPreallocSlabs; +#ifdef FLM_SOLARIS + int m_DevZero; +#endif + +friend class F_FixedAlloc; +}; + +/**************************************************************************** +Desc: Class to provide an efficient means of providing many allocations + of a fixed size. +****************************************************************************/ +class F_FixedAlloc : public IF_FixedAlloc, public F_Base +{ +public: + + F_FixedAlloc(); + + virtual ~F_FixedAlloc(); + + RCODE FLMAPI setup( + IF_Relocator * pRelocator, + IF_SlabManager * pSlabManager, + FLMUINT uiCellSize, + FLM_SLAB_USAGE * pUsageStats); + + FINLINE void * FLMAPI allocCell( + IF_Relocator * pRelocator, + void * pvInitialData = NULL, + FLMUINT uiDataSize = 0, + FLMBOOL bMutexLocked = FALSE) + { + void * pvCell; + + flmAssert( pRelocator); + + if( !bMutexLocked) + { + m_pSlabManager->lockMutex(); + } + + if( (pvCell = getCell( pRelocator)) == NULL) + { + goto Exit; + } + + if( uiDataSize == sizeof( FLMUINT *)) + { + *((FLMUINT *)pvCell) = *((FLMUINT *)pvInitialData); + } + else if( uiDataSize) + { + f_memcpy( pvCell, pvInitialData, uiDataSize); + } + + Exit: + + if( !bMutexLocked) + { + m_pSlabManager->unlockMutex(); + } + + return( pvCell); + } + + FINLINE void FLMAPI freeCell( + void * ptr, + FLMBOOL bMutexLocked) + { + freeCell( ptr, bMutexLocked, FALSE, NULL); + } + + void FLMAPI freeUnused( void); + + void FLMAPI freeAll( void); + + FINLINE FLMUINT FLMAPI getCellSize( void) + { + return( m_uiCellSize); + } + + void FLMAPI defragmentMemory( void); + +private: + + typedef struct Slab + { + void * pvAllocator; + Slab * pNext; + Slab * pPrev; + Slab * pNextSlabWithAvailCells; + Slab * pPrevSlabWithAvailCells; + FLMBYTE * pLocalAvailCellListHead; + FLMUINT16 ui16NextNeverUsedCell; + FLMUINT16 ui16AvailCellCount; + FLMUINT16 ui16AllocatedCells; + } SLAB; + + typedef struct CELLHEADER + { + SLAB * pContainingSlab; +#ifdef FLM_DEBUG + FLMUINT * puiStack; +#endif + } CELLHEADER; + + typedef struct CELLHEADER2 + { + CELLHEADER cellHeader; + IF_Relocator * pRelocator; + } CELLHEADER2; + + typedef struct CellAvailNext + { + FLMBYTE * pNextInList; +#ifdef FLM_DEBUG + FLMBYTE szDebugPattern[ 8]; +#endif + } CELLAVAILNEXT; + + void * getCell( + IF_Relocator * pRelocator); + + SLAB * getAnotherSlab( void); + + static FINLINE FLMUINT getAllocAlignedSize( + FLMUINT uiAskedForSize) + { + return( (uiAskedForSize + FLM_ALLOC_ALIGN) & (~FLM_ALLOC_ALIGN)); + } + + void freeSlab( + SLAB * pSlab); + + void freeCell( + void * pCell, + FLMBOOL bMutexLocked, + FLMBOOL bFreeIfEmpty, + FLMBOOL * pbFreedSlab); + +#ifdef FLM_DEBUG + void testForLeaks( void); +#endif + + FINLINE static FLMINT FLMAPI slabAddrCompareFunc( + void * pvBuffer, + FLMUINT uiPos1, + FLMUINT uiPos2) + { + SLAB * pSlab1 = (((SLAB **)pvBuffer)[ uiPos1]); + SLAB * pSlab2 = (((SLAB **)pvBuffer)[ uiPos2]); + + flmAssert( pSlab1 != pSlab2); + + if( pSlab1 < pSlab2) + { + return( -1); + } + + return( 1); + } + + FINLINE static void FLMAPI slabAddrSwapFunc( + void * pvBuffer, + FLMUINT uiPos1, + FLMUINT uiPos2) + { + SLAB ** ppSlab1 = &(((SLAB **)pvBuffer)[ uiPos1]); + SLAB ** ppSlab2 = &(((SLAB **)pvBuffer)[ uiPos2]); + SLAB * pTmp; + + pTmp = *ppSlab1; + *ppSlab1 = *ppSlab2; + *ppSlab2 = pTmp; + } + + IF_SlabManager * m_pSlabManager; + SLAB * m_pFirstSlab; + SLAB * m_pLastSlab; + SLAB * m_pFirstSlabWithAvailCells; + SLAB * m_pLastSlabWithAvailCells; + IF_Relocator * m_pRelocator; + FLMBOOL m_bAvailListSorted; + FLMUINT m_uiSlabsWithAvailCells; + FLMUINT m_uiSlabHeaderSize; + FLMUINT m_uiCellHeaderSize; + FLMUINT m_uiCellSize; + FLMUINT m_uiSizeOfCellAndHeader; + FLMUINT m_uiTotalFreeCells; + FLMUINT m_uiCellsPerSlab; + FLMUINT m_uiSlabSize; + FLM_SLAB_USAGE * m_pUsageStats; + +friend class F_BufferAlloc; +friend class F_MultiAlloc; +}; + +/**************************************************************************** +Desc: +****************************************************************************/ +class F_BufferAlloc : public IF_BufferAlloc, public F_Base +{ +public: + + F_BufferAlloc() + { + f_memset( m_ppAllocators, 0, sizeof( m_ppAllocators)); + m_pSlabManager = NULL; + } + + virtual ~F_BufferAlloc(); + + RCODE FLMAPI setup( + IF_SlabManager * pSlabManager, + FLM_SLAB_USAGE * pUsageStats); + + RCODE FLMAPI allocBuf( + IF_Relocator * pRelocator, + FLMUINT uiSize, + void * pvInitialData, + FLMUINT uiDataSize, + FLMBYTE ** ppucBuffer, + FLMBOOL * pbAllocatedOnHeap = NULL); + + RCODE FLMAPI reallocBuf( + IF_Relocator * pRelocator, + FLMUINT uiOldSize, + FLMUINT uiNewSize, + void * pvInitialData, + FLMUINT uiDataSize, + FLMBYTE ** ppucBuffer, + FLMBOOL * pbAllocatedOnHeap = NULL); + + void FLMAPI freeBuf( + FLMUINT uiSize, + FLMBYTE ** ppucBuffer); + + FLMUINT FLMAPI getTrueSize( + FLMUINT uiSize, + FLMBYTE * pucBuffer); + + void FLMAPI defragmentMemory( void); + +private: + + IF_FixedAlloc * getAllocator( + FLMUINT uiSize); + + IF_SlabManager * m_pSlabManager; + IF_FixedAlloc * m_ppAllocators[ NUM_BUF_ALLOCATORS]; +}; + +/**************************************************************************** +Desc: +****************************************************************************/ +class F_MultiAlloc : public IF_MultiAlloc, public F_Base +{ +public: + + F_MultiAlloc() + { + m_pSlabManager = NULL; + m_puiCellSizes = NULL; + m_ppAllocators = NULL; + } + + ~F_MultiAlloc() + { + cleanup(); + } + + RCODE FLMAPI setup( + F_SlabManager * pSlabManager, + FLMUINT * puiCellSizes, + FLM_SLAB_USAGE * pUsageStats); + + RCODE FLMAPI allocBuf( + IF_Relocator * pRelocator, + FLMUINT uiSize, + FLMBYTE ** ppucBuffer, + FLMBOOL bMutexLocked = FALSE); + + RCODE FLMAPI reallocBuf( + IF_Relocator * pRelocator, + FLMUINT uiNewSize, + FLMBYTE ** ppucBuffer, + FLMBOOL bMutexLocked = FALSE); + + FINLINE void FLMAPI freeBuf( + FLMBYTE ** ppucBuffer) + { + if( ppucBuffer && *ppucBuffer) + { + getAllocator( *ppucBuffer)->freeCell( *ppucBuffer, FALSE); + *ppucBuffer = NULL; + } + } + + void FLMAPI defragmentMemory( void); + + FINLINE FLMUINT FLMAPI getTrueSize( + FLMBYTE * pucBuffer) + { + return( getAllocator( pucBuffer)->getCellSize()); + } + + FINLINE void FLMAPI lockMutex( void) + { + m_pSlabManager->lockMutex(); + } + + FINLINE void FLMAPI unlockMutex( void) + { + m_pSlabManager->unlockMutex(); + } + +private: + + IF_FixedAlloc * getAllocator( + FLMUINT uiSize); + + IF_FixedAlloc * getAllocator( + FLMBYTE * pucBuffer); + + void cleanup( void); + + IF_SlabManager * m_pSlabManager; + FLMUINT * m_puiCellSizes; + IF_FixedAlloc ** m_ppAllocators; +}; + +/**************************************************************************** +Desc: This class is used to do pool memory allocations. +****************************************************************************/ +class F_Pool : public IF_Pool, public F_Base +{ +public: + + typedef struct PoolMemoryBlock + { + PoolMemoryBlock * pPrevBlock; + FLMUINT uiBlockSize; + FLMUINT uiFreeOffset; + FLMUINT uiFreeSize; + } MBLK; + + typedef struct + { + FLMUINT uiAllocBytes; + FLMUINT uiCount; + } POOL_STATS; + + F_Pool() + { + m_uiBytesAllocated = 0; + m_pLastBlock = NULL; + m_pPoolStats = NULL; + m_uiBlockSize = 0; + } + + virtual ~F_Pool(); + + FINLINE void FLMAPI poolInit( + FLMUINT uiBlockSize) + { + m_uiBlockSize = uiBlockSize; + } + + void smartPoolInit( + POOL_STATS * pPoolStats); + + RCODE FLMAPI poolAlloc( + FLMUINT uiSize, + void ** ppvPtr); + + RCODE FLMAPI poolCalloc( + FLMUINT uiSize, + void ** ppvPtr); + + void FLMAPI poolFree( void); + + void FLMAPI poolReset( + void * pvMark, + FLMBOOL bReduceFirstBlock = FALSE); + + FINLINE void * FLMAPI poolMark( void) + { + return (void *)(m_pLastBlock + ? (FLMBYTE *)m_pLastBlock + m_pLastBlock->uiFreeOffset + : NULL); + } + + FINLINE FLMUINT FLMAPI getBlockSize( void) + { + return( m_uiBlockSize); + } + + FINLINE FLMUINT FLMAPI getBytesAllocated( void) + { + return( m_uiBytesAllocated); + } + +private: + + FINLINE void updateSmartPoolStats( void) + { + if (m_uiBytesAllocated) + { + if( (m_pPoolStats->uiAllocBytes + m_uiBytesAllocated) >= 0xFFFF0000) + { + m_pPoolStats->uiAllocBytes = + (m_pPoolStats->uiAllocBytes / m_pPoolStats->uiCount) * 100; + m_pPoolStats->uiCount = 100; + } + else + { + m_pPoolStats->uiAllocBytes += m_uiBytesAllocated; + m_pPoolStats->uiCount++; + } + m_uiBytesAllocated = 0; + } + } + + FINLINE void setInitialSmartPoolBlkSize( void) + { + // Determine starting block size: + // 1) average of bytes allocated / # of frees/resets (average size needed) + // 2) add 10% - to minimize extra allocs + + m_uiBlockSize = (m_pPoolStats->uiAllocBytes / m_pPoolStats->uiCount); + m_uiBlockSize += (m_uiBlockSize / 10); + + if (m_uiBlockSize < 512) + { + m_uiBlockSize = 512; + } + } + + void freeToMark( + void * pvMark); + + PoolMemoryBlock * m_pLastBlock; + FLMUINT m_uiBlockSize; + FLMUINT m_uiBytesAllocated; + POOL_STATS * m_pPoolStats; +}; + /************************************************************************ Desc: *************************************************************************/ @@ -529,8 +1145,6 @@ void logMemLeak( char * pszMessageBuffer; char * pszTmp; IF_FileHdl * pFileHdl = NULL; - F_FileSystem fileSys; - FLMBOOL bClearFileSys = FALSE; FLMBOOL bSaveTrackLeaks = gv_bTrackLeaks; gv_bTrackLeaks = FALSE; @@ -545,12 +1159,6 @@ void logMemLeak( } pszTmp = pszMessageBuffer; - if( !gv_pFileSystem) - { - gv_pFileSystem = &fileSys; - bClearFileSys = TRUE; - } - // Format message to be logged. f_strcpy( pszTmp, "Abort=Debug, Retry=Continue, Ignore=Don't Show\r\n"); @@ -717,9 +1325,8 @@ void logMemLeak( gv_bLogLeaks = TRUE; #endif - if (gv_bLogLeaks) + if (gv_bLogLeaks && gv_pFileSystem) { - F_FileSystem FileSystem; RCODE rc; FLMUINT uiDummy; #ifdef FLM_NLM @@ -728,12 +1335,12 @@ void logMemLeak( const char * pszErrPath = "memtest.ert"; #endif - if (RC_BAD( rc = FileSystem.openFile( pszErrPath, + if (RC_BAD( rc = gv_pFileSystem->openFile( pszErrPath, FLM_IO_RDWR | FLM_IO_SH_DENYNONE, &pFileHdl))) { if (rc == NE_FLM_IO_PATH_NOT_FOUND) { - rc = FileSystem.createFile( pszErrPath, + rc = gv_pFileSystem->createFile( pszErrPath, FLM_IO_RDWR | FLM_IO_SH_DENYNONE, &pFileHdl); } } @@ -763,11 +1370,6 @@ void logMemLeak( pFileHdl->Release(); } - if( bClearFileSys) - { - gv_pFileSystem = NULL; - } - if (pszMessageBuffer != &szTmpBuffer [0]) { free( pszMessageBuffer); @@ -836,18 +1438,12 @@ void f_memoryCleanup( void) /******************************************************************** Desc: Allocate Memory. *********************************************************************/ -#ifdef FLM_DEBUG -RCODE f_allocImp( +RCODE FLMAPI f_allocImp( FLMUINT uiSize, void ** ppvPtr, FLMBOOL bAllocFromNewOp, const char * pszFileName, - FLMINT iLineNumber) -#else -RCODE f_allocImp( - FLMUINT uiSize, - void ** ppvPtr) -#endif + int iLineNumber) { RCODE rc = NE_FLM_OK; F_MEM_HDR * pHdr; @@ -883,19 +1479,11 @@ Exit: /******************************************************************** Desc: Allocate and initialize memory. *********************************************************************/ -#ifdef FLM_DEBUG -RCODE f_callocImp( +RCODE FLMAPI f_callocImp( FLMUINT uiSize, void ** ppvPtr, const char * pszFileName, - FLMINT iLineNumber - ) -#else -RCODE f_callocImp( - FLMUINT uiSize, - void ** ppvPtr - ) -#endif + int iLineNumber) { RCODE rc = NE_FLM_OK; F_MEM_HDR * pHdr; @@ -930,19 +1518,11 @@ Exit: /******************************************************************** Desc: Reallocate memory. *********************************************************************/ -#ifdef FLM_DEBUG -RCODE f_reallocImp( +RCODE FLMAPI f_reallocImp( FLMUINT uiSize, void ** ppvPtr, const char * pszFileName, - FLMINT iLineNumber - ) -#else -RCODE f_reallocImp( - FLMUINT uiSize, - void ** ppvPtr - ) -#endif + int iLineNumber) { RCODE rc = NE_FLM_OK; F_MEM_HDR * pNewHdr; @@ -1029,19 +1609,11 @@ Exit: /******************************************************************** Desc: Reallocate memory, and initialize the new part. *********************************************************************/ -#ifdef FLM_DEBUG -RCODE f_recallocImp( +RCODE FLMAPI f_recallocImp( FLMUINT uiSize, void ** ppvPtr, const char * pszFileName, - FLMINT iLineNumber - ) -#else -RCODE f_recallocImp( - FLMUINT uiSize, - void ** ppvPtr - ) -#endif + int iLineNumber) { RCODE rc = NE_FLM_OK; F_MEM_HDR * pNewHdr; @@ -1135,7 +1707,7 @@ Exit: /******************************************************************** Desc: Free previously allocated memory. *********************************************************************/ -void f_freeImp( +void FLMAPI f_freeImp( void ** ppvPtr, FLMBOOL bFreeFromDeleteOp) { @@ -1189,7 +1761,7 @@ Desc: Reset the stack information for an allocation. void f_resetStackInfoImp( void * pvPtr, const char * pszFileName, - FLMINT iLineNumber) + int iLineNumber) { if (pvPtr) { @@ -1206,6 +1778,20 @@ void f_resetStackInfoImp( } #endif +/************************************************************************ +Desc: +*************************************************************************/ +RCODE FLMAPI FlmAllocPool( + IF_Pool ** ppPool) +{ + if( (*ppPool = f_new F_Pool) == NULL) + { + return( RC_SET( NE_FLM_MEM)); + } + + return( NE_FLM_OK); +} + /************************************************************************ Desc: Destructor *************************************************************************/ @@ -1927,42 +2513,6 @@ void F_SlabManager::releaseSlabToSystem( decrementTotalBytesAllocated( m_uiSlabSize, TRUE); } -/**************************************************************************** -Desc: -****************************************************************************/ -#ifdef FLM_MEM_PROTECT -void F_SlabManager::protectSlab( - void * pSlab) -{ -#ifdef FLM_WIN - (void)pSlab; - DWORD dOldProtect; - VirtualProtect( pSlab, m_uiSlabSize, PAGE_READONLY, &dOldProtect); - flmAssert( dOldProtect == PAGE_READWRITE); -#elif defined( FLM_UNIX) - mprotect( pSlab, m_uiSlabSize, PROT_READ); -#endif -} -#endif - -/**************************************************************************** -Desc: -****************************************************************************/ -#ifdef FLM_MEM_PROTECT -void F_SlabManager::unprotectSlab( - void * pSlab) -{ -#ifdef FLM_WIN - (void)pSlab; - DWORD dOldProtect; - VirtualProtect( pSlab, m_uiSlabSize, PAGE_READWRITE, &dOldProtect); - flmAssert( dOldProtect == PAGE_READONLY); -#elif defined( FLM_UNIX) - mprotect( pSlab, m_uiSlabSize, PROT_READ | PROT_WRITE); -#endif -} -#endif - /**************************************************************************** Desc: ****************************************************************************/ @@ -2113,10 +2663,6 @@ F_FixedAlloc::F_FixedAlloc() m_uiTotalFreeCells = 0; m_uiSlabSize = 0; m_pUsageStats = NULL; - -#ifdef FLM_MEM_PROTECT - m_bMemProtectionEnabled = FALSE; -#endif } /**************************************************************************** @@ -2143,7 +2689,6 @@ Desc: Setup method for any setup that can fail RCODE F_FixedAlloc::setup( IF_Relocator * pRelocator, IF_SlabManager * pSlabManager, - FLMBOOL bMemProtect, FLMUINT uiCellSize, FLM_SLAB_USAGE * pUsageStats) { @@ -2187,12 +2732,6 @@ RCODE F_FixedAlloc::setup( flmAssert( m_uiCellsPerSlab <= FLM_MAX_UINT16); flmAssert( (m_uiCellsPerSlab * m_uiCellSize) < m_uiSlabSize); -#ifdef FLM_MEM_PROTECT - m_bMemProtectionEnabled = bMemProtect; -#else - F_UNREFERENCED_PARM( bMemProtect); -#endif - return( rc); } @@ -2210,10 +2749,6 @@ void * F_FixedAlloc::getCell( if( (pSlab = m_pFirstSlabWithAvailCells) != NULL) { -#ifdef FLM_MEM_PROTECT - unprotectSlab( pSlab, TRUE); -#endif - flmAssert( pSlab->ui16AvailCellCount <= m_uiTotalFreeCells); flmAssert( m_uiTotalFreeCells); flmAssert( pSlab->ui16AllocatedCells < m_uiCellsPerSlab); @@ -2264,17 +2799,8 @@ void * F_FixedAlloc::getCell( if( pSlabToUnlink->pNextSlabWithAvailCells) { -#ifdef FLM_MEM_PROTECT - unprotectSlab( pSlabToUnlink->pNextSlabWithAvailCells, TRUE); -#endif - - pSlabToUnlink-> - pNextSlabWithAvailCells->pPrevSlabWithAvailCells = + pSlabToUnlink->pNextSlabWithAvailCells->pPrevSlabWithAvailCells = pSlabToUnlink->pPrevSlabWithAvailCells; - -#ifdef FLM_MEM_PROTECT - protectSlab( pSlabToUnlink->pNextSlabWithAvailCells, TRUE); -#endif pSlabToUnlink->pNextSlabWithAvailCells = NULL; } @@ -2301,21 +2827,8 @@ void * F_FixedAlloc::getCell( if( m_pFirstSlab) { -#ifdef FLM_MEM_PROTECT - unprotectSlab( pNewSlab, TRUE); -#endif pNewSlab->pNext = m_pFirstSlab; -#ifdef FLM_MEM_PROTECT - protectSlab( pNewSlab, TRUE); -#endif - -#ifdef FLM_MEM_PROTECT - unprotectSlab( m_pFirstSlab, TRUE); -#endif m_pFirstSlab->pPrev = pNewSlab; -#ifdef FLM_MEM_PROTECT - protectSlab( m_pFirstSlab, TRUE); -#endif } else { @@ -2326,16 +2839,8 @@ void * F_FixedAlloc::getCell( } pSlab = m_pFirstSlab; - -#ifdef FLM_MEM_PROTECT - unprotectSlab( pSlab, TRUE); -#endif pSlab->ui16AllocatedCells++; -#ifdef FLM_MEM_PROTECT - flmAssert( pSlab->ui16AllocatedCells <= m_uiCellsPerSlab); -#endif - pHeader = (CELLHEADER *) ((FLMBYTE *)pSlab + m_uiSlabHeaderSize + (m_uiSizeOfCellAndHeader * m_pFirstSlab->ui16NextNeverUsedCell)); @@ -2361,10 +2866,6 @@ void * F_FixedAlloc::getCell( ((CELLHEADER2 *)pHeader)->pRelocator = pRelocator; } -#ifdef FLM_MEM_PROTECT - protectSlab( pSlab, TRUE); -#endif - m_pUsageStats->ui64AllocatedCells++; Exit: @@ -2385,9 +2886,6 @@ void F_FixedAlloc::freeCell( CELLHEADER * pHeader; SLAB * pSlab; FLMBOOL bUnlockMutex = FALSE; -#ifdef FLM_MEM_PROTECT - FLMBOOL bProtectSlab = FALSE; -#endif if( pbFreedSlab) { @@ -2417,12 +2915,8 @@ void F_FixedAlloc::freeCell( goto Exit; } -#ifdef FLM_MEM_PROTECT - unprotectSlab( pSlab, TRUE); - bProtectSlab = TRUE; -#endif - pHeader->pContainingSlab = NULL; + #ifdef FLM_DEBUG if( pHeader->puiStack) { @@ -2474,14 +2968,7 @@ void F_FixedAlloc::freeCell( pSlab->pNextSlabWithAvailCells = m_pFirstSlabWithAvailCells; pSlab->pPrevSlabWithAvailCells = NULL; - -#ifdef FLM_MEM_PROTECT - unprotectSlab( m_pFirstSlabWithAvailCells, TRUE); -#endif m_pFirstSlabWithAvailCells->pPrevSlabWithAvailCells = pSlab; -#ifdef FLM_MEM_PROTECT - protectSlab( m_pFirstSlabWithAvailCells, TRUE); -#endif m_pFirstSlabWithAvailCells = pSlab; m_uiSlabsWithAvailCells++; } @@ -2500,11 +2987,6 @@ void F_FixedAlloc::freeCell( if( m_uiTotalFreeCells >= m_uiCellsPerSlab || bFreeIfEmpty) { -#ifdef FLM_MEM_PROTECT - protectSlab( pSlab, TRUE); - bProtectSlab = FALSE; -#endif - freeSlab( pSlab); if( pbFreedSlab) @@ -2549,13 +3031,6 @@ void F_FixedAlloc::freeCell( Exit: -#ifdef FLM_MEM_PROTECT - if( bProtectSlab) - { - protectSlab( pSlab, TRUE); - } -#endif - if( bUnlockMutex) { m_pSlabManager->unlockMutex(); @@ -2582,125 +3057,11 @@ F_FixedAlloc::SLAB * F_FixedAlloc::getAnotherSlab( void) pSlab->pvAllocator = (void *)this; m_pUsageStats->ui64Slabs++; -#ifdef FLM_MEM_PROTECT - if( m_bMemProtectionEnabled) - { - m_pSlabManager->protectSlab( pSlab); - } -#endif - Exit: return( pSlab); } -/**************************************************************************** -Desc: -****************************************************************************/ -#ifdef FLM_MEM_PROTECT -void F_FixedAlloc::protectSlab( - SLAB * pSlab, - FLMBOOL bMutexLocked) -{ - FLMBOOL bUnlockMutex = FALSE; - - if( !m_bMemProtectionEnabled) - { - return; - } - - if( !bMutexLocked) - { - m_pSlabManager->lockMutex(); - bUnlockMutex = TRUE; - } - - flmAssert( pSlab->pvAllocator == this); - flmAssert( pSlab->ui16UnprotectCount); - - pSlab->ui16UnprotectCount--; - - if( !pSlab->ui16UnprotectCount) - { - m_pSlabManager->protectSlab( pSlab); - } - - if( bUnlockMutex) - { - m_pSlabManager->unlockMutex(); - } -} -#endif - -/**************************************************************************** -Desc: -****************************************************************************/ -#ifdef FLM_MEM_PROTECT -void F_FixedAlloc::unprotectSlab( - SLAB * pSlab, - FLMBOOL bMutexLocked) -{ - FLMBOOL bUnlockMutex = FALSE; - - if( !m_bMemProtectionEnabled) - { - return; - } - - flmAssert( pSlab->pvAllocator == this); - - if( !bMutexLocked) - { - m_pSlabManager->lockMutex(); - bUnlockMutex = TRUE; - } - - if( !pSlab->ui16UnprotectCount) - { - m_pSlabManager->unprotectSlab( pSlab); - } - - pSlab->ui16UnprotectCount++; - - if( bUnlockMutex) - { - m_pSlabManager->unlockMutex(); - } -} -#endif - -/**************************************************************************** -Desc: -****************************************************************************/ -#ifdef FLM_MEM_PROTECT -void F_FixedAlloc::protectCell( - void * pvCell) -{ - CELLHEADER * pCellHeader; - - m_pSlabManager->lockMutex(); - pCellHeader = (CELLHEADER *)((FLMBYTE *)pvCell - m_uiCellHeaderSize); - protectSlab( pCellHeader->pContainingSlab, TRUE); - m_pSlabManager->unlockMutex(); -} -#endif - -/**************************************************************************** -Desc: -****************************************************************************/ -#ifdef FLM_MEM_PROTECT -void F_FixedAlloc::unprotectCell( - void * pvCell) -{ - CELLHEADER * pCellHeader; - - m_pSlabManager->lockMutex(); - pCellHeader = (CELLHEADER *)((FLMBYTE *)pvCell - m_uiCellHeaderSize); - unprotectSlab( pCellHeader->pContainingSlab, TRUE); - m_pSlabManager->unlockMutex(); -} -#endif - /**************************************************************************** Desc: Private internal method to free an unused empty slab back to the OS. ****************************************************************************/ @@ -2713,9 +3074,6 @@ void F_FixedAlloc::freeSlab( #endif flmAssert( pSlab); -#ifdef FLM_MEM_PROTECT - flmAssert( !pSlab->ui16UnprotectCount); -#endif // Memory corruption detected! @@ -2743,13 +3101,7 @@ void F_FixedAlloc::freeSlab( if( pSlab->pNext) { -#ifdef FLM_MEM_PROTECT - unprotectSlab( pSlab->pNext, TRUE); -#endif pSlab->pNext->pPrev = pSlab->pPrev; -#ifdef FLM_MEM_PROTECT - protectSlab( pSlab->pNext, TRUE); -#endif } else { @@ -2758,13 +3110,7 @@ void F_FixedAlloc::freeSlab( if( pSlab->pPrev) { -#ifdef FLM_MEM_PROTECT - unprotectSlab( pSlab->pPrev, TRUE); -#endif pSlab->pPrev->pNext = pSlab->pNext; -#ifdef FLM_MEM_PROTECT - protectSlab( pSlab->pPrev, TRUE); -#endif } else { @@ -2775,14 +3121,8 @@ void F_FixedAlloc::freeSlab( if( pSlab->pNextSlabWithAvailCells) { -#ifdef FLM_MEM_PROTECT - unprotectSlab( pSlab->pNextSlabWithAvailCells, TRUE); -#endif pSlab->pNextSlabWithAvailCells->pPrevSlabWithAvailCells = pSlab->pPrevSlabWithAvailCells; -#ifdef FLM_MEM_PROTECT - protectSlab( pSlab->pNextSlabWithAvailCells, TRUE); -#endif } else { @@ -2791,14 +3131,8 @@ void F_FixedAlloc::freeSlab( if( pSlab->pPrevSlabWithAvailCells) { -#ifdef FLM_MEM_PROTECT - unprotectSlab( pSlab->pPrevSlabWithAvailCells, TRUE); -#endif pSlab->pPrevSlabWithAvailCells->pNextSlabWithAvailCells = pSlab->pNextSlabWithAvailCells; -#ifdef FLM_MEM_PROTECT - protectSlab( pSlab->pPrevSlabWithAvailCells, TRUE); -#endif } else { @@ -2810,10 +3144,6 @@ void F_FixedAlloc::freeSlab( flmAssert( m_uiTotalFreeCells >= pSlab->ui16AvailCellCount); m_uiTotalFreeCells -= pSlab->ui16AvailCellCount; m_pUsageStats->ui64Slabs--; - -#ifdef FLM_MEM_PROTECT - unprotectSlab( pSlab, TRUE); -#endif m_pSlabManager->freeSlab( (void **)&pSlab, TRUE); } @@ -2921,32 +3251,19 @@ void F_FixedAlloc::defragmentMemory( void) for( uiLoop = 0; uiLoop < uiSortEntries; uiLoop++) { pCurSlab = pSortBuf[ uiLoop]; -#ifdef FLM_MEM_PROTECT - unprotectSlab( pCurSlab, TRUE); -#endif - pCurSlab->pNextSlabWithAvailCells = NULL; pCurSlab->pPrevSlabWithAvailCells = NULL; if( pPrevSib) { pCurSlab->pPrevSlabWithAvailCells = pPrevSib; -#ifdef FLM_MEM_PROTECT - unprotectSlab( pPrevSib, TRUE); -#endif pPrevSib->pNextSlabWithAvailCells = pCurSlab; -#ifdef FLM_MEM_PROTECT - protectSlab( pPrevSib, TRUE); -#endif } else { m_pFirstSlabWithAvailCells = pCurSlab; } -#ifdef FLM_MEM_PROTECT - protectSlab( pCurSlab, TRUE); -#endif pPrevSib = pCurSlab; } @@ -3020,19 +3337,9 @@ void F_FixedAlloc::defragmentMemory( void) goto Exit; } -#ifdef FLM_MEM_PROTECT - unprotectSlab( ((CELLHEADER *)(pucReloc - - m_uiCellHeaderSize))->pContainingSlab, TRUE); -#endif - f_memcpy( pucReloc, pucOriginal, m_uiCellSize); pRelocator->relocate( pucOriginal, pucReloc); -#ifdef FLM_MEM_PROTECT - protectSlab( ((CELLHEADER *)(pucReloc - - m_uiCellHeaderSize))->pContainingSlab, TRUE); -#endif - freeCell( pucOriginal, TRUE, TRUE, &bSlabFreed); if( bSlabFreed) @@ -3148,7 +3455,6 @@ Desc: ****************************************************************************/ RCODE F_BufferAlloc::setup( IF_SlabManager * pSlabManager, - FLMBOOL bMemProtect, FLM_SLAB_USAGE * pUsageStats) { RCODE rc = NE_FLM_OK; @@ -3242,7 +3548,7 @@ RCODE F_BufferAlloc::setup( } if (RC_BAD( rc = m_ppAllocators[ uiLoop]->setup( NULL, - pSlabManager, bMemProtect, uiSize, pUsageStats))) + pSlabManager, uiSize, pUsageStats))) { goto Exit; } @@ -3625,7 +3931,6 @@ Desc: ****************************************************************************/ RCODE F_MultiAlloc::setup( F_SlabManager * pSlabManager, - FLMBOOL bMemProtect, FLMUINT * puiCellSizes, FLM_SLAB_USAGE * pUsageStats) { @@ -3684,7 +3989,7 @@ RCODE F_MultiAlloc::setup( } if( RC_BAD( rc = m_ppAllocators[ uiLoop]->setup( NULL, - pSlabManager, bMemProtect, m_puiCellSizes[ uiLoop], pUsageStats))) + pSlabManager, m_puiCellSizes[ uiLoop], pUsageStats))) { goto Exit; } @@ -3898,70 +4203,6 @@ IF_FixedAlloc * F_MultiAlloc::getAllocator( return( pAllocator); } -/**************************************************************************** -Desc: -****************************************************************************/ -#ifdef FLM_MEM_PROTECT -void F_MultiAlloc::protectBuffer( - void * pvBuffer, - FLMBOOL bMutexLocked) -{ - F_FixedAlloc::CELLHEADER * pHeader; - F_FixedAlloc::SLAB * pSlab; - IF_FixedAlloc * pAllocator = NULL; - FLMBYTE * pucBuffer = (FLMBYTE *)pvBuffer; - - if( !bMutexLocked) - { - m_pSlabManager->lockMutex(); - } - - pHeader = (F_FixedAlloc::CELLHEADER *)(pucBuffer - - F_FixedAlloc::getAllocAlignedSize( - sizeof( F_FixedAlloc::CELLHEADER2))); - pSlab = pHeader->pContainingSlab; - pAllocator = (IF_FixedAlloc *)pSlab->pvAllocator; - pAllocator->protectSlab( pSlab, TRUE); - - if( !bMutexLocked) - { - m_pSlabManager->unlockMutex(); - } -} -#endif - -/**************************************************************************** -Desc: -****************************************************************************/ -#ifdef FLM_MEM_PROTECT -void F_MultiAlloc::unprotectBuffer( - void * pvBuffer, - FLMBOOL bMutexLocked) -{ - F_FixedAlloc::CELLHEADER * pHeader; - F_FixedAlloc::SLAB * pSlab; - IF_FixedAlloc * pAllocator = NULL; - FLMBYTE * pucBuffer = (FLMBYTE *)pvBuffer; - - if( !bMutexLocked) - { - m_pSlabManager->lockMutex(); - } - - pHeader = (F_FixedAlloc::CELLHEADER *)(pucBuffer - - F_FixedAlloc::getAllocAlignedSize( - sizeof( F_FixedAlloc::CELLHEADER2))); - pSlab = pHeader->pContainingSlab; - pAllocator = (IF_FixedAlloc *)pSlab->pvAllocator; - pAllocator->unprotectSlab( pSlab, TRUE); - - if( !bMutexLocked) - { - m_pSlabManager->unlockMutex(); - } -} -#endif - #undef new #undef delete /**************************************************************************** diff --git a/ftk/src/ftkmfh.cpp b/ftk/src/ftkmfh.cpp index f5e5602..5bc0249 100644 --- a/ftk/src/ftkmfh.cpp +++ b/ftk/src/ftkmfh.cpp @@ -25,6 +25,174 @@ #include "ftksys.h" +#define F_MULTI_FHDL_LIST_SIZE 8 +#define F_MULTI_FHDL_DEFAULT_MAX_FILE_SIZE ((FLMUINT)0xFFFFFFFF) + +/**************************************************************************** +Desc: +****************************************************************************/ +typedef struct +{ + IF_FileHdl * pFileHdl; + FLMUINT uiFileNum; + FLMBOOL bDirty; +} FH_INFO; + +/**************************************************************************** +Desc: +****************************************************************************/ +class F_MultiFileHdl : public IF_MultiFileHdl, public F_Base +{ +public: + + F_MultiFileHdl( + FLMUINT uiMaxFileSize = F_MULTI_FHDL_DEFAULT_MAX_FILE_SIZE); + + virtual ~F_MultiFileHdl(); + + void FLMAPI close( + FLMBOOL bDelete = FALSE); + + + RCODE FLMAPI create( + const char * pszPath); + + RCODE FLMAPI createUnique( + const char * pszPath, + const char * pszFileExtension); + + RCODE FLMAPI deleteMultiFile( + const char * pszPath); + + RCODE FLMAPI open( + const char * pszPath); + + RCODE FLMAPI flush( void); + + RCODE FLMAPI read( + FLMUINT64 ui64Offset, + FLMUINT uiLength, + void * pvBuffer, + FLMUINT * puiBytesRead); + + RCODE FLMAPI write( + FLMUINT64 ui64Offset, + FLMUINT uiLength, + void * pvBuffer, + FLMUINT * puiBytesWritten); + + RCODE FLMAPI getPath( + char * pszFilePath); + + FINLINE RCODE FLMAPI size( + FLMUINT64 * pui64FileSize) + { + *pui64FileSize = m_ui64EOF; + return( NE_FLM_OK); + } + + RCODE FLMAPI truncate( + FLMUINT64 ui64NewSize); + +private: + + RCODE getFileHdl( + FLMUINT uiFileNum, + FLMBOOL bGetForWrite, + IF_FileHdl ** ppFileHdl); + + RCODE createLockFile( + const char * pszBasePath); + + FINLINE void releaseLockFile( + const char * pszBasePath, + FLMBOOL bDelete) + { +#ifndef FLM_UNIX + F_UNREFERENCED_PARM( bDelete); + F_UNREFERENCED_PARM( pszBasePath); +#endif + + if( m_pLockFileHdl) + { + + // Release the lock file + + (void)m_pLockFileHdl->close(); + m_pLockFileHdl->Release(); + m_pLockFileHdl = NULL; + +#ifdef FLM_UNIX + if( bDelete) + { + char szTmpPath[ F_PATH_MAX_SIZE]; + + // Delete the lock file + + f_strcpy( szTmpPath, pszBasePath); + gv_pFileSystem->pathAppend( szTmpPath, "64.LCK"); + gv_pFileSystem->Delete( szTmpPath); + } +#endif + } + } + + FINLINE void formatFileNum( + FLMUINT uiFileNum, + char * pszStr) + { + f_sprintf( pszStr, "%08X.64", (unsigned)uiFileNum); + } + + RCODE getFileNum( + const char * pszFileName, + FLMUINT * puiFileNum); + + FINLINE void dataFilePath( + FLMUINT uiFileNum, + char * pszPath) + { + char szFileName[ 13]; + + f_strcpy( pszPath, m_szPath); + formatFileNum( uiFileNum, szFileName); + gv_pFileSystem->pathAppend( pszPath, szFileName); + } + + FINLINE FLMUINT getFileNum( + FLMUINT64 ui64Offset) + { + return( (FLMUINT)(ui64Offset / m_uiMaxFileSize)); + } + + FINLINE FLMUINT getFileOffset( + FLMUINT64 ui64Offset) + { + return( (FLMUINT)(ui64Offset % m_uiMaxFileSize)); + } + + FH_INFO m_pFileHdlList[ F_MULTI_FHDL_LIST_SIZE]; + char m_szPath[ F_PATH_MAX_SIZE]; + FLMBOOL m_bOpen; + FLMUINT64 m_ui64EOF; + FLMUINT m_uiMaxFileSize; + IF_FileHdl * m_pLockFileHdl; +}; + +/**************************************************************************** +Desc: +****************************************************************************/ +RCODE FLMAPI FlmAllocMultiFileHdl( + IF_MultiFileHdl ** ppFileHdl) +{ + if( (*ppFileHdl = f_new F_MultiFileHdl) == NULL) + { + return( RC_SET( NE_FLM_MEM)); + } + + return( NE_FLM_OK); +} + /**************************************************************************** Desc: ****************************************************************************/ @@ -495,9 +663,7 @@ RCODE F_MultiFileHdl::read( IF_FileHdl * pFileHdl; RCODE rc = NE_FLM_OK; - /* - Handle the case of a 0-byte read - */ + // Handle the case of a 0-byte read if( !uiLength) { @@ -508,9 +674,7 @@ RCODE F_MultiFileHdl::read( goto Exit; } - /* - Read the data file(s), moving to new files as needed. - */ + // Read the data file(s), moving to new files as needed. for( ;;) { @@ -531,10 +695,8 @@ RCODE F_MultiFileHdl::read( { if( rc == NE_FLM_IO_PATH_NOT_FOUND) { - /* - Handle the case of a sparse file by filling the unread - portion of the buffer with zeros. - */ + // Handle the case of a sparse file by filling the unread + // portion of the buffer with zeros. f_memset( pvBuffer, 0, uiBytesToRead); uiTmp = uiBytesToRead; @@ -552,10 +714,8 @@ RCODE F_MultiFileHdl::read( { if( rc == NE_FLM_IO_END_OF_FILE) { - /* - Handle the case of a sparse file by filling the unread - portion of the buffer with zeros. - */ + // Handle the case of a sparse file by filling the unread + // portion of the buffer with zeros. f_memset( &(((FLMBYTE *)(pvBuffer))[ uiTmp]), 0, (FLMUINT)(uiBytesToRead - uiTmp)); @@ -576,9 +736,7 @@ RCODE F_MultiFileHdl::read( break; } - /* - Set up for next read - */ + // Set up for next read pvBuffer = ((FLMBYTE *)pvBuffer) + uiTmp; ui64Offset += uiTmp; @@ -601,6 +759,7 @@ RCODE F_MultiFileHdl::write( void * pvBuffer, // Buffer that contains bytes to be written FLMUINT * puiBytesWritten) // Number of bytes written. { + RCODE rc = NE_FLM_OK; FLMUINT uiFileNum = getFileNum( ui64Offset); FLMUINT uiFileOffset = getFileOffset( ui64Offset); FLMUINT uiTmp; @@ -608,17 +767,12 @@ RCODE F_MultiFileHdl::write( FLMUINT uiBytesToWrite; FLMUINT uiMaxWriteLen; IF_FileHdl * pFileHdl; - RCODE rc = NE_FLM_OK; - /* - Don't allow zero-length writes - */ + // Don't allow zero-length writes flmAssert( uiLength); - /* - Write to the data file(s), moving to new files as needed. - */ + // Write to the data file(s), moving to new files as needed. for( ;;) { @@ -648,9 +802,7 @@ RCODE F_MultiFileHdl::write( break; } - /* - Set up for next write - */ + // Set up for next write pvBuffer = ((FLMBYTE *)pvBuffer) + uiTmp; uiFileNum = getFileNum( ui64Offset); @@ -779,10 +931,6 @@ RCODE F_MultiFileHdl::getFileNum( } else { - /* - Invalid character found in the file name - */ - rc = RC_SET( NE_FLM_IO_INVALID_FILENAME); goto Exit; } @@ -810,36 +958,30 @@ RCODE F_MultiFileHdl::createLockFile( RCODE rc = NE_FLM_OK; char szLockPath [F_PATH_MAX_SIZE]; F_FileHdl * pLockFileHdl = NULL; + FLMUINT uiIoFlags = FLM_IO_RDWR | FLM_IO_EXCL | FLM_IO_SH_DENYRW; f_strcpy( szLockPath, pszBasePath); gv_pFileSystem->pathAppend( szLockPath, "64.LCK"); - /* - Attempt to create the lock file. If it fails, the lock file - may have been left because of a crash. Hence, we first try - to delete the file. If that succeeds, we then attempt to - create the file again. If it, or the 2nd create fail, we simply - return an access denied error. - */ - - if ((pLockFileHdl = f_new F_FileHdl) == NULL) + // Attempt to create the lock file. If it fails, the lock file + // may have been left because of a crash. Hence, we first try + // to delete the file. If that succeeds, we then attempt to + // create the file again. If it, or the 2nd create fail, we simply + // return an access denied error. + + if( RC_BAD( rc = f_allocFileHdl( &pLockFileHdl))) { - rc = RC_SET( NE_FLM_MEM); goto Exit; } #ifndef FLM_UNIX - pLockFileHdl->setupFileHdl( 0, TRUE); -#else - // On Unix, we do not want to delete the file because it // will succeed even if someone else has the file open. - - pLockFileHdl->setupFileHdl( 0, FALSE); + + uiIoFlags |= FLM_IO_DELETE_ON_RELEASE; #endif - if( RC_BAD( pLockFileHdl->create( szLockPath, - FLM_IO_RDWR | FLM_IO_EXCL | FLM_IO_SH_DENYRW))) + if( RC_BAD( pLockFileHdl->create( szLockPath, uiIoFlags))) { #ifndef FLM_UNIX if (RC_BAD( gv_pFileSystem->deleteFile( szLockPath))) @@ -847,17 +989,14 @@ RCODE F_MultiFileHdl::createLockFile( rc = RC_SET( NE_FLM_IO_ACCESS_DENIED); goto Exit; } - else if (RC_BAD( pLockFileHdl->create( szLockPath, - FLM_IO_RDWR | FLM_IO_EXCL | - FLM_IO_SH_DENYRW))) + else if (RC_BAD( pLockFileHdl->create( szLockPath, uiIoFlags))) { rc = RC_SET( NE_FLM_IO_ACCESS_DENIED); goto Exit; } #else - if( RC_BAD( pLockFileHdl->open( szLockPath, - FLM_IO_RDWR | FLM_IO_SH_DENYRW))) + if( RC_BAD( pLockFileHdl->open( szLockPath, uiIoFlags))) { rc = RC_SET( NE_FLM_IO_ACCESS_DENIED); goto Exit; @@ -910,6 +1049,5 @@ RCODE F_MultiFileHdl::truncate( Exit: - return rc; - + return( rc); } diff --git a/ftk/src/ftkmisc.cpp b/ftk/src/ftkmisc.cpp index 1455af6..6f4955b 100644 --- a/ftk/src/ftkmisc.cpp +++ b/ftk/src/ftkmisc.cpp @@ -25,49 +25,103 @@ #include "ftksys.h" -// Global data - +FLMUINT gv_uiStartupCount = 0; FLMUINT gv_uiSerialInitCount = 0; F_MUTEX gv_hSerialMutex = F_MUTEX_NULL; +IF_FileSystem * gv_pFileSystem = NULL; +IF_RandomGenerator * gv_pSerialRandom = NULL; +IF_ThreadMgr * gv_pThreadMgr = NULL; -#ifdef FLM_UNIX - F_RandomGenerator gv_SerialRandom; +FSTATIC RCODE f_initSerialNumberGenerator( void); + +FSTATIC void f_freeSerialNumberGenerator( void); + +#ifdef FLM_AIX + #ifndef nsleep + extern "C" + { + extern int nsleep( struct timestruc_t *, struct timestruc_t *); + } + #endif #endif -#ifdef FLM_NLM - void f_sleep( - FLMUINT uiMilliseconds) +/**************************************************************************** +Desc: +****************************************************************************/ +RCODE FLMAPI ftkStartup( void) +{ + RCODE rc = NE_FLM_OK; + + if( ++gv_uiStartupCount > 1) { - if( ! uiMilliseconds ) - { - kYieldThread(); - } - else - { - kDelayThread( uiMilliseconds); - } + goto Exit; } -#endif + f_memoryInit(); + + if( RC_BAD( rc = f_allocFileSystem( &gv_pFileSystem))) + { + goto Exit; + } + + if( RC_BAD( rc = f_allocThreadMgr( &gv_pThreadMgr))) + { + goto Exit; + } + + if( RC_BAD( rc = f_initSerialNumberGenerator())) + { + goto Exit; + } + + if( RC_BAD( rc = f_checkErrorCodeTables())) + { + goto Exit; + } -#if defined( FLM_UNIX) +Exit: - #ifdef FLM_AIX - #ifndef nsleep - extern "C" - { - extern int nsleep( struct timestruc_t *, struct timestruc_t *); - } - #endif - #endif + if( RC_BAD( rc)) + { + ftkShutdown(); + } + + return( rc); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +void FLMAPI ftkShutdown( void) +{ + if( !gv_uiStartupCount || --gv_uiStartupCount > 0) + { + return; + } + + if( gv_pThreadMgr) + { + gv_pThreadMgr->Release(); + gv_pThreadMgr = NULL; + } + + if( gv_pFileSystem) + { + gv_pFileSystem->Release(); + gv_pFileSystem = NULL; + } + + f_freeSerialNumberGenerator(); + f_memoryCleanup(); +} /**************************************************************************** Desc: This routine causes the calling process to delay the given number of milliseconds. Due to the nature of the call, the actual sleep time is almost guaranteed to be different from requested sleep time. -In: milliseconds - the number of milliseconds to delay ****************************************************************************/ -void f_sleep( +#ifdef FLM_UNIX +void FLMAPI f_sleep( FLMUINT uiMilliseconds) { #ifdef FLM_AIX @@ -88,70 +142,31 @@ void f_sleep( } #endif -/*************************************************************************** -Desc: Map POSIX errno to Flaim IO errors. -***************************************************************************/ -#if defined( FLM_UNIX) || defined( FLM_NLM) -RCODE MapPlatformError( - FLMINT iError, - RCODE defaultRc) +/**************************************************************************** +Desc: +****************************************************************************/ +#ifdef FLM_WIN +void FLMAPI f_sleep( + FLMUINT uiMilliseconds) { - switch (err) + Sleep( (DWORD)uiMilliseconds); +} +#endif + +/**************************************************************************** +Desc: +****************************************************************************/ +#ifdef FLM_NLM +void FLMAPI f_sleep( + FLMUINT uiMilliseconds) +{ + if( !uiMilliseconds ) { - case 0: - { - return( NE_FLM_OK); - } - - case ENOENT: - { - return( RC_SET( NE_FLM_IO_PATH_NOT_FOUND)); - } - - case EACCES: - case EEXIST: - { - return( RC_SET( NE_FLM_IO_ACCESS_DENIED)); - } - - case EINVAL: - { - return( RC_SET( NE_FLM_IO_PATH_TOO_LONG)); - } - - case EIO: - { - return( RC_SET( NE_FLM_IO_DISK_FULL)); - } - - case ENOTDIR: - { - return( RC_SET( NE_FLM_IO_DIRECTORY_ERR)); - } - -#ifdef EBADFD - case EBADFD: - { - return( RC_SET( NE_FLM_IO_BAD_FILE_HANDLE)); - } -#endif - -#ifdef EOF - case EOF: - { - return( RC_SET( NE_FLM_IO_END_OF_FILE)); - } -#endif - - case EMFILE: - { - return( RC_SET( NE_FLM_IO_NO_MORE_FILES)); - } - - default: - { - return( RC_SET( defaultRc)); - } + kYieldThread(); + } + else + { + kDelayThread( uiMilliseconds); } } #endif @@ -162,7 +177,7 @@ Desc: This routine initializes the serial number generator. If the O/S routines fail for some reason, a pseudo-GUID will be generated. Notes: This routine should only be called once by the process. ****************************************************************************/ -RCODE f_initSerialNumberGenerator( void) +FSTATIC RCODE f_initSerialNumberGenerator( void) { FLMUINT uiTime; RCODE rc = NE_FLM_OK; @@ -180,7 +195,13 @@ RCODE f_initSerialNumberGenerator( void) f_timeGetSeconds( &uiTime ); #if defined( FLM_UNIX) - gv_SerialRandom.randomSetSeed( (FLMUINT32)(uiTime ^ (FLMUINT)getpid())); + + if( RC_BAD( rc = FlmAllocRandomGenerator( &gv_pSerialRandom))) + { + goto Exit; + } + + gv_pSerialRandom->randomSetSeed( (FLMUINT32)(uiTime ^ (FLMUINT)getpid())); #endif Exit: @@ -188,6 +209,28 @@ Exit: return( rc); } +/**************************************************************************** +Desc: +****************************************************************************/ +FSTATIC void f_freeSerialNumberGenerator( void) +{ + if( (--gv_uiSerialInitCount) > 0) + { + return; + } + + if( gv_pSerialRandom) + { + gv_pSerialRandom->Release(); + gv_pSerialRandom = NULL; + } + + if( gv_hSerialMutex != F_MUTEX_NULL) + { + f_mutexDestroy( &gv_hSerialMutex); + } +} + /**************************************************************************** Desc: This routine will use the operating system calls to generate a "globally unique" identifier. Typically, this is based on the @@ -239,10 +282,10 @@ RCODE FLMAPI f_createSerialNumber( f_mutexLock( gv_hSerialMutex); - UD2FBA( (FLMUINT32)gv_SerialRandom.randomLong(), &pszSerialNum[ 0]); - UD2FBA( (FLMUINT32)gv_SerialRandom.randomLong(), &pszSerialNum[ 4]); - UD2FBA( (FLMUINT32)gv_SerialRandom.randomLong(), &pszSerialNum[ 8]); - UD2FBA( (FLMUINT32)gv_SerialRandom.randomLong(), &pszSerialNum[ 12]); + UD2FBA( (FLMUINT32)gv_pSerialRandom->randomLong(), &pszSerialNum[ 0]); + UD2FBA( (FLMUINT32)gv_pSerialRandom->randomLong(), &pszSerialNum[ 4]); + UD2FBA( (FLMUINT32)gv_pSerialRandom->randomLong(), &pszSerialNum[ 8]); + UD2FBA( (FLMUINT32)gv_pSerialRandom->randomLong(), &pszSerialNum[ 12]); f_mutexUnlock( gv_hSerialMutex); @@ -255,22 +298,6 @@ Exit: return( rc); } -/**************************************************************************** -Notes: This routine should only be called once by the process. -****************************************************************************/ -void f_freeSerialNumberGenerator( void) -{ - if( (--gv_uiSerialInitCount) > 0) - { - return; - } - - if( gv_hSerialMutex != F_MUTEX_NULL) - { - f_mutexDestroy( &gv_hSerialMutex); - } -} - /**************************************************************************** Desc: Generates a table of remainders for each 8-bit byte. The resulting table is used by flmUpdateCRC to calculate a CRC value. The table @@ -535,7 +562,7 @@ Iterate_Larger_Half: /*************************************************************************** Desc: ****************************************************************************/ -FLMINT flmQSortUINTCompare( +FLMINT FLMAPI f_qsortUINTCompare( void * pvBuffer, FLMUINT uiPos1, FLMUINT uiPos2) @@ -558,7 +585,7 @@ FLMINT flmQSortUINTCompare( /*************************************************************************** Desc: ****************************************************************************/ -void flmQSortUINTSwap( +void FLMAPI f_qsortUINTSwap( void * pvBuffer, FLMUINT uiPos1, FLMUINT uiPos2) diff --git a/ftk/src/ftkntab.cpp b/ftk/src/ftkntab.cpp index 6e11292..880e69d 100644 --- a/ftk/src/ftkntab.cpp +++ b/ftk/src/ftkntab.cpp @@ -28,6 +28,15 @@ #define MAX_ELEMENTS_TO_LOAD 0xFFFF #define MAX_ATTRIBUTES_TO_LOAD 0xFFFF +typedef struct +{ + FLMUINT uiType; + FLMUNICODE * puzTagName; + FLMUINT uiTagNum; + FLMUINT uiDataType; + FLMUNICODE * puzNamespace; +} FLM_TAG_INFO; + typedef FLMINT (* TAG_COMPARE_FUNC)( FLM_TAG_INFO * pTagInfo1, FLM_TAG_INFO * pTagInfo2); @@ -51,12 +60,159 @@ FSTATIC void sortTagTbl( FLMUINT uiUpperBounds, TAG_COMPARE_FUNC fnTagCompare); +/**************************************************************************** +Desc: Class for name/number lookup. +****************************************************************************/ +class F_NameTable : public IF_NameTable, public F_Base +{ +public: + + F_NameTable(); + + virtual ~F_NameTable(); + + RCODE FLMAPI setupNameTable( void); + + void FLMAPI clearTable( + FLMUINT uiPoolBlkSize); + + RCODE FLMAPI getNextTagTypeAndNumOrder( + FLMUINT uiType, + FLMUINT * puiNextPos, + FLMUNICODE * puzTagName = NULL, + char * pszTagName = NULL, + FLMUINT uiNameBufSize = 0, + FLMUINT * puiTagNum = NULL, + FLMUINT * puiDataType = NULL, + FLMUNICODE * puzNamespace = NULL, + FLMUINT uiNamespaceBufSize = 0, + FLMBOOL bTruncatedNamesOk = TRUE); + + RCODE FLMAPI getNextTagTypeAndNameOrder( + FLMUINT uiType, + FLMUINT * puiNextPos, + FLMUNICODE * puzTagName = NULL, + char * pszTagName = NULL, + FLMUINT uiNameBufSize = 0, + FLMUINT * puiTagNum = NULL, + FLMUINT * puiDataType = NULL, + FLMUNICODE * puzNamespace = NULL, + FLMUINT uiNamespaceBufSize = 0, + FLMBOOL bTruncatedNamesOk = TRUE); + + RCODE FLMAPI getFromTagTypeAndName( + FLMUINT uiType, + const FLMUNICODE * puzTagName, + const char * pszTagName, + FLMBOOL bMatchNamespace, + const FLMUNICODE * puzNamespace = NULL, + FLMUINT * puiTagNum = NULL, + FLMUINT * puiDataType = NULL); + + RCODE FLMAPI getFromTagTypeAndNum( + FLMUINT uiType, + FLMUINT uiTagNum, + FLMUNICODE * puzTagName = NULL, + char * pszTagName = NULL, + FLMUINT * puiNameBufSize = NULL, + FLMUINT * puiDataType = NULL, + FLMUNICODE * puzNamespace = NULL, + char * pszNamespace = NULL, + FLMUINT * puiNamespaceBufSize = NULL, + FLMBOOL bTruncatedNamesOk = TRUE); + + RCODE FLMAPI addTag( + FLMUINT uiType, + FLMUNICODE * puzTagName, + const char * pszTagName, + FLMUINT uiTagNum, + FLMUINT uiDataType = 0, + FLMUNICODE * puzNamespace = NULL, + FLMBOOL bCheckDuplicates = TRUE); + + void FLMAPI removeTag( + FLMUINT uiType, + FLMUINT uiTagNum); + + RCODE FLMAPI cloneNameTable( + IF_NameTable * pSrcNameTable); + + RCODE FLMAPI importFromNameTable( + IF_NameTable * pSrcNameTable); + + FLMINT FLMAPI AddRef( void); + + FLMINT FLMAPI Release( void); + +private: + + void sortTags( void); + + RCODE allocTag( + FLMUINT uiType, + FLMUNICODE * puzTagName, + const char * pszTagName, + FLMUINT uiTagNum, + FLMUINT uiDataType, + FLMUNICODE * puzNamespace, + FLM_TAG_INFO ** ppTagInfo); + + RCODE reallocSortTables( + FLMUINT uiNewTblSize); + + RCODE copyTagName( + FLMUNICODE * puzDestTagName, + char * pszDestTagName, + FLMUINT * puiDestBufSize, + FLMUNICODE * puzSrcTagName, + FLMBOOL bTruncatedNamesOk); + + FLM_TAG_INFO * findTagByTypeAndNum( + FLMUINT uiType, + FLMUINT uiTagNum, + FLMUINT * puiInsertPos = NULL); + + FLM_TAG_INFO * findTagByTypeAndName( + FLMUINT uiType, + const FLMUNICODE * puzTagName, + const char * pszTagName, + FLMBOOL bMatchNamespace, + const FLMUNICODE * puzNamespace, + FLMBOOL * pbAmbiguous, + FLMUINT * puiInsertPos = NULL); + + RCODE insertTagInTables( + FLM_TAG_INFO * pTagInfo, + FLMUINT uiTagTypeAndNameTblInsertPos, + FLMUINT uiTagTypeAndNumTblInsertPos); + + FLMUNICODE * findNamespace( + FLMUNICODE * puzNamespace, + FLMUINT * puiInsertPos); + + RCODE insertNamespace( + FLMUNICODE * puzNamespace, + FLMUINT uiInsertPos); + + IF_Pool * m_pPool; + FLMUINT m_uiMemoryAllocated; + FLM_TAG_INFO ** m_ppSortedByTagTypeAndName; + FLM_TAG_INFO ** m_ppSortedByTagTypeAndNum; + FLMUINT m_uiTblSize; + FLMUINT m_uiNumTags; + FLMBOOL m_bTablesSorted; + FLMUNICODE ** m_ppuzNamespaces; + FLMUINT m_uiNamespaceTblSize; + FLMUINT m_uiNumNamespaces; + F_MUTEX m_hRefMutex; +}; + /**************************************************************************** Desc: ****************************************************************************/ F_NameTable::F_NameTable() { - m_pool.poolInit( 1024); + m_pPool = NULL; m_uiMemoryAllocated = 0; m_ppSortedByTagTypeAndName = NULL; m_ppSortedByTagTypeAndNum = NULL; @@ -76,6 +232,11 @@ F_NameTable::~F_NameTable() { clearTable( 0); + if( m_pPool) + { + m_pPool->Release(); + } + if( m_hRefMutex) { f_mutexDestroy( &m_hRefMutex); @@ -88,20 +249,18 @@ Desc: Setup name table. This routine should be called immediately after ****************************************************************************/ RCODE FLMAPI F_NameTable::setupNameTable( void) { -#ifndef FLM_HAVE_ATOMICS RCODE rc = NE_FLM_OK; - - if( RC_BAD( rc = f_mutexCreate( &m_hRefMutex))) + + if( RC_BAD( rc = FlmAllocPool( &m_pPool))) { goto Exit; } + m_pPool->poolInit( 1024); + Exit: - + return( rc); -#else - return( NE_FLM_OK); -#endif } /**************************************************************************** @@ -110,11 +269,11 @@ Desc: Free everything in the table void FLMAPI F_NameTable::clearTable( FLMUINT uiPoolBlkSize) { - m_pool.poolFree(); + m_pPool->poolFree(); if (uiPoolBlkSize) { - m_pool.poolInit( uiPoolBlkSize); + m_pPool->poolInit( uiPoolBlkSize); } m_uiMemoryAllocated = 0; @@ -996,9 +1155,9 @@ RCODE F_NameTable::allocTag( // Create a new tag info structure. - pvMark = m_pool.poolMark(); + pvMark = m_pPool->poolMark(); uiSaveMemoryAllocated = m_uiMemoryAllocated; - if (RC_BAD( rc = m_pool.poolCalloc( sizeof( FLM_TAG_INFO), + if (RC_BAD( rc = m_pPool->poolCalloc( sizeof( FLM_TAG_INFO), (void **)&pTagInfo))) { goto Exit; @@ -1010,7 +1169,7 @@ RCODE F_NameTable::allocTag( if (puzTagName) { uiNameSize = (f_unilen( puzTagName) + 1) * sizeof( FLMUNICODE); - if (RC_BAD( rc = m_pool.poolAlloc( uiNameSize, + if (RC_BAD( rc = m_pPool->poolAlloc( uiNameSize, (void **)&pTagInfo->puzTagName))) { goto Exit; @@ -1021,7 +1180,7 @@ RCODE F_NameTable::allocTag( else { uiNameSize = (f_strlen( pszTagName) + 1) * sizeof( FLMUNICODE); - if (RC_BAD( rc = m_pool.poolAlloc( uiNameSize, + if (RC_BAD( rc = m_pPool->poolAlloc( uiNameSize, (void **)&pTagInfo->puzTagName))) { goto Exit; @@ -1050,7 +1209,7 @@ RCODE F_NameTable::allocTag( &uiNamespaceInsertPos)) == NULL) { uiNameSize = (f_unilen( puzNamespace) + 1) * sizeof( FLMUNICODE); - if (RC_BAD( rc = m_pool.poolAlloc( uiNameSize, + if (RC_BAD( rc = m_pPool->poolAlloc( uiNameSize, (void **)&puzTblNamespace))) { goto Exit; @@ -1068,7 +1227,7 @@ RCODE F_NameTable::allocTag( // allocated if the pool is reset at Exit due to a later // error. - pvMark = m_pool.poolMark(); + pvMark = m_pPool->poolMark(); uiSaveMemoryAllocated = m_uiMemoryAllocated; } @@ -1079,7 +1238,7 @@ Exit: if (RC_BAD( rc)) { - m_pool.poolReset( pvMark); + m_pPool->poolReset( pvMark); m_uiMemoryAllocated = uiSaveMemoryAllocated; pTagInfo = NULL; } diff --git a/ftk/src/ftkpath.cpp b/ftk/src/ftkpath.cpp index f358dfa..148f8cd 100644 --- a/ftk/src/ftkpath.cpp +++ b/ftk/src/ftkpath.cpp @@ -25,751 +25,3 @@ #include "ftksys.h" -FSTATIC FLMBOOL f_canReducePath( - const char * pszSource); - -FSTATIC const char * f_findFileNameStart( - const char * pszPath); - -FSTATIC char * f_getPathComponent( - char ** ppszPath, - FLMUINT * puiEndChar); - -/**************************************************************************** -Desc: Returns TRUE if character is a "slash" separator -****************************************************************************/ -FINLINE FLMBOOL f_isSlashSeparator( - char cChar) -{ -#ifdef FLM_UNIX - return( cChar == '/' ? TRUE : FALSE); -#else - return( cChar == '/' || cChar == '\\' ? TRUE : FALSE); -#endif -} - -/**************************************************************************** -Desc: Return a pointer to the next path component in ppszPath. -****************************************************************************/ -FSTATIC char * f_getPathComponent( - char ** ppszPath, - FLMUINT * puiEndChar) -{ - char * pszComponent; - char * pszEnd; - - pszComponent = pszEnd = *ppszPath; - if (f_isSlashSeparator( *pszEnd)) - { - // handle the condition of sys:\system the colon would have terminated - // the previous token, to pComponent would now be pointing at the '\'. - // We need to move past the '\' to find the next token. - - pszEnd++; - } - - // Find the end of the path component - - while (*pszEnd) - { - if (f_isSlashSeparator( *pszEnd) -#ifndef FLM_UNIX - || *pszEnd == ':' -#endif - ) - { - break; - } - pszEnd++; - } - - if (*pszEnd) - { - - // A delimiter was found, assume that there is another path component - // after this one. - // Return a pointer to the beginning of the next path component - - *ppszPath = pszEnd + 1; - - *puiEndChar = *pszEnd; - - // NULL terminate the path component - - *pszEnd = 0; - } - else - { - - // There is no "next path component" so return a pointer to the - // NULL-terminator - - *ppszPath = pszEnd; - *puiEndChar = 0; - } - - // Return the path component - - return( pszComponent); -} - -/**************************************************************************** -Desc: Split the path into its components -Output: - pServer - pointer to a buffer to hold the server name - pVolume - pointer to a buffer to hold the volume name - pDirPath - pointer to a buffer to hold the path - pFileName pointer to a buffer to hold the filename - - All of the output parameters are optional. If you do not want one - of the components, simply give a NULL pointer. - -Note: if the input path has no file name, d:\dir_1 for example, then - pass a NULL pointer for pFileName. Otherwise dir_1 will be returned - as pFileName. - - The server name may be ommitted in the input path: - sys:\system\autoexec.ncf - - UNC paths of the form: - \\server-name\volume-name\dir_1\dir_2\file.ext - are supported. - - DOS paths of the form: - d:\dir_1\dir_2\file.ext - are also supported. - -Example: - Given this input: orm-prod48/sys:\system\autoexec.ncf - The output would be: - pServer = "orm-prod48" - pVolume = "sys:" - pDirPath = "\system" - pFileName "autoexec.ncf" -****************************************************************************/ -void FLMAPI F_FileSystem::pathParse( - const char * pszInputPath, - char * pszServer, - char * pszVolume, - char * pszDirPath, - char * pszFileName) -{ - char szInput[ F_PATH_MAX_SIZE]; - char * pszNext; - char * pszColon; - char * pszComponent; - FLMUINT uiEndChar; - FLMBOOL bUNC = FALSE; - - // Initialize return buffers - - if (pszServer) - { - *pszServer = 0; - } - if (pszVolume) - { - *pszVolume = 0; - } - if (pszDirPath) - { - *pszDirPath = 0; - } - if (pszFileName) - { - - // Get the file name - - *pszFileName = 0; - gv_pFileSystem->pathReduce( pszInputPath, szInput, pszFileName); - } - else - { - f_strcpy( szInput, pszInputPath); - } - - // Split out the rest of the components - - pszComponent = &szInput [0]; - - // Is this a UNC path? - - if (szInput[0] == '\\' && szInput[1] == '\\') - { - - // Yes, assume a UNC path - - pszComponent += 2; - bUNC = TRUE; - } - - pszNext = pszColon = pszComponent; - - // Is there a ':' in the szInput path? - - while (*pszColon && *pszColon != ':') - { - pszColon++; - } - if (*pszColon || bUNC) - { - - // Yes, assume there is a volume in the path - - pszComponent = f_getPathComponent( &pszNext, &uiEndChar); - if (uiEndChar != ':') - { - // Assume that this component is the server - - if (pszServer) - { - f_strcpy( pszServer, pszComponent); - } - - // Get the next component - - pszComponent = f_getPathComponent( &pszNext, &uiEndChar); - } - - // Assume that this component is the volume - - if (pszVolume) - { - char * pszSrc = pszComponent; - char * pszDst = pszVolume; - - while (*pszSrc) - { - *pszDst++ = *pszSrc++; - } - *pszDst++ = ':'; - *pszDst = 0; - } - - // For UNC paths, the leading '\' of the path is set to 0 by - // f_getPathComponent. This code restores the leading '\'. - - if (f_isSlashSeparator( (char)uiEndChar)) - { - *(--pszNext) = (char)uiEndChar; - } - } - - // Assume that all that is left of the input is the path - - if (pszDirPath) - { - f_strcpy( pszDirPath, pszNext); - } -} - -/**************************************************************************** -Desc: Will determine whether any format of (UNC, drive based, NetWare - UNC) path can be reduced any further. -****************************************************************************/ -FSTATIC FLMBOOL f_canReducePath( - const char * pszSource) -{ -#if defined FLM_UNIX - F_UNREFERENCED_PARM( pszSource); - return( TRUE); -#else - FLMBOOL bCanReduce; - const char * pszTemp = pszSource; - - // Determine whether the passed path is UNC or not - // (UNC format is: \\FileServer\Volume\Path). - - if (f_strncmp( "\\\\", pszSource, 2 ) == 0) - { - FLMUINT uiSlashCount = 0; - - pszTemp += 2; - - // Search forward for at least two slash separators - // If we find at least two, the path can be reduced. - - bCanReduce = FALSE; - while (*pszTemp) - { - pszTemp++; - if (f_isSlashSeparator( *pszTemp)) - { - ++uiSlashCount; - if (uiSlashCount == 2) - { - bCanReduce = TRUE; - break; - } - } - } - } - else - { - bCanReduce = TRUE; - - // Search forward for the colon. - - while (*pszTemp) - { - if (*pszTemp == ':') - { - - // If nothing comes after the colon, - // we can't reduce any more. - - if (*(pszTemp + 1) == 0) - { - bCanReduce = FALSE; - } - break; - } - pszTemp++; - } - } - - return( bCanReduce); -#endif -} - -/**************************************************************************** -Desc: Return pointer to start of filename part of path. - Search for the last slash separator. -****************************************************************************/ -FSTATIC const char * f_findFileNameStart( - const char * pszPath) -{ - const char * pszFileNameStart; - - pszFileNameStart = pszPath; - while (*pszPath) - { - if (f_isSlashSeparator( *pszPath)) - { - pszFileNameStart = pszPath + 1; - } - pszPath++; - } - return( pszFileNameStart); -} - -/**************************************************************************** -Desc: This function will strip off the filename or trailing - directory of a path. The stripped component of the path will - be placed into the area pointed at by string. The source - path will not be modified. The dest path will contain the - remainder of the stripped path. A stripped path can be processed - repeatedly by this function until there is no more path to reduce. - If the string is set to NULL, the copying of the stripped portion of - the path will be bypassed by the function. - -Notes: This function handles drive based, UNC, Netware, and UNIX type - paths. -****************************************************************************/ -RCODE FLMAPI F_FileSystem::pathReduce( - const char * pszPath, - char * pszDir, - char * pszPathComponent) -{ - RCODE rc = NE_FLM_OK; - const char * pszFileNameStart; - char szLocalPath[ F_PATH_MAX_SIZE]; - FLMUINT uiLen; - - // Check for valid path pointers - - if( !pszPath || !pszDir) - { - rc = RC_SET( NE_FLM_INVALID_PARM); - goto Exit; - } - - if ((uiLen = f_strlen( pszPath)) == 0) - { - rc = RC_SET( NE_FLM_IO_CANNOT_REDUCE_PATH); - goto Exit; - } - - // Trim out any trailing slash separators - - if( f_isSlashSeparator( pszPath [uiLen - 1])) - { - f_strcpy( szLocalPath, pszPath); - - while( f_isSlashSeparator( szLocalPath[ uiLen - 1])) - { - szLocalPath[ --uiLen] = 0; - if( !uiLen) - { - rc = RC_SET( NE_FLM_IO_CANNOT_REDUCE_PATH); - goto Exit; - } - } - - pszPath = szLocalPath; - } - - if( f_canReducePath( pszPath)) - { - // Search for a slash or beginning of path - - pszFileNameStart = f_findFileNameStart( pszPath); - - // Copy the sliced portion of the path if requested by caller - - if( pszPathComponent) - { - f_strcpy( pszPathComponent, pszFileNameStart); - } - - // Copy the reduced source path to the dir path - - if (pszFileNameStart > pszPath) - { - uiLen = (FLMUINT)(pszFileNameStart - pszPath); - f_memcpy( pszDir, pszPath, uiLen); - - if (uiLen >= 2 && f_isSlashSeparator( pszDir [uiLen - 1]) -#ifndef FLM_UNIX - && pszDir [uiLen - 2] != ':' -#endif - ) - { - // Trim off the trailing path separator - - pszDir [uiLen - 1] = 0; - } - else - { - pszDir [uiLen] = 0; - } - } - else - { - *pszDir = 0; - } - } - else - { - // We've found the drive id or server\volume specifier. - - if (pszPathComponent) - { - f_strcpy( pszPathComponent, pszPath); - } - - *pszDir = 0; - } - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: Internal function for WpioPathBuild() and WpioPathModify(). - Appends string the path & adds a path delimiter if necessary. -In: *path = pointer to an IO_PATH - *string = pointer to a NULL terminated string - *end_ptr = pointer to the end of the IO_PATH which is being built. -****************************************************************************/ -RCODE FLMAPI F_FileSystem::pathAppend( - char * pszPath, - const char * pszPathComponent) -{ - - // Don't put a slash separator if pszPath is empty - - if (*pszPath) - { - FLMUINT uiStrLen = f_strlen( pszPath); - char * pszEnd = pszPath + uiStrLen - 1; - - if (!f_isSlashSeparator( *pszEnd)) - { - - // Check for maximum path size - 2 is for slash separator - // and null byte. - - if (uiStrLen + 2 + f_strlen( pszPathComponent) > F_PATH_MAX_SIZE) - { - return RC_SET( NE_FLM_IO_PATH_TOO_LONG); - } - - pszEnd++; -#if defined( FLM_UNIX) - *pszEnd = '/'; -#else - *pszEnd = '\\'; -#endif - } - else - { - - // Check for maximum path size +1 is for null byte. - - if (uiStrLen + 1 + f_strlen( pszPathComponent) > F_PATH_MAX_SIZE) - { - return RC_SET( NE_FLM_IO_PATH_TOO_LONG); - } - } - - f_strcpy( pszEnd + 1, pszPathComponent); - } - else - { - f_strcpy( pszPath, pszPathComponent); - } - - return( NE_FLM_OK); -} - -/**************************************************************************** -Desc: Convert an PATH into a fully qualified, storable C string - reference to a file or directory. -In: pszPath - the path to convert. - pszStorageString - a pointer to a string that is atleast - F_PATH_MAX_SIZE in size -****************************************************************************/ -RCODE FLMAPI F_FileSystem::pathToStorageString( - const char * pszPath, - char * pszStorageString) -{ -#ifdef FLM_WIN - char * pszNamePart; - - if (GetFullPathName( (LPCSTR)pszPath, - (DWORD)F_PATH_MAX_SIZE - 1, - (LPSTR)pszStorageString, - (LPSTR *)&pszNamePart) != 0) - { - - } - else - { - // Convert to upper case. - - while (*pszPath) - { - *pszStorageString++ = *pszPath; - pszPath++; - } - *pszStorageString = 0; - } - return NE_FLM_OK; -#else - - char szFile[ F_PATH_MAX_SIZE]; - char szDir[ F_PATH_MAX_SIZE]; - char * pszRealPath = NULL; - RCODE rc = NE_FLM_OK; - - if (RC_BAD( rc = pathReduce( pszPath, szDir, szFile))) - { - goto Exit; - } - - if (!szDir [0]) - { - szDir [0] = '.'; - szDir [1] = '\0'; - } - - if (RC_BAD( rc = f_alloc( (FLMUINT)PATH_MAX, &pszRealPath))) - { - goto Exit; - } - - if (!realpath( (char *)szDir, (char *)pszRealPath)) - { - rc = MapErrnoToFlaimErr( errno, NE_FLM_PARSING_FILE_NAME); - goto Exit; - } - - if (f_strlen( pszRealPath) >= F_PATH_MAX_SIZE) - { - rc = RC_SET( NE_FLM_IO_PATH_TOO_LONG); - goto Exit; - } - - f_strcpy( pszStorageString, pszRealPath); - - if (RC_BAD( rc = pathAppend( pszStorageString, szFile))) - { - goto Exit; - } - -Exit: - - if (pszRealPath) - { - f_free( &pszRealPath); - } - - return( rc); -#endif -} - -/**************************************************************************** -Desc: -****************************************************************************/ -FINLINE void HexToNative( - FLMBYTE ucHexVal, - char * pszNativeChar) -{ - *pszNativeChar = (char)(ucHexVal < 10 - ? ucHexVal + NATIVE_ZERO - : (ucHexVal - 10) + NATIVE_LOWER_A); -} - -/**************************************************************************** -Desc: -****************************************************************************/ -FINLINE void SetUpTime( - FLMUINT * puiBaseTime, - FLMBYTE * pbyHighByte) -{ - FLMUINT uiSdTime = 0; - f_timeGetSeconds( &uiSdTime); - *pbyHighByte = (FLMBYTE)(uiSdTime >> 24); - uiSdTime = uiSdTime << 5; - if( *puiBaseTime < uiSdTime) - *puiBaseTime = uiSdTime; -} - -/**************************************************************************** -Desc: Generates a file name given a seed and some modifiers, it is built - to be called in a loop until the file can be sucessfully written or - created with the increment being changed every time. -In: bModext -> if TRUE then we will use the extension for collisions. -In\Out: puiTime -> a modified time stamp which is used as the base - filename. To properly set up this value, make sure - the puiTime points to a 0 the first time this routine - is called and it will be set up for you. Thereafter, - do not change it between calls. - pHighChars-> these are the 8 bits that were shifted off the top of - the time struct. It will be set up for you the first - time you call this routine if puiTime points to a 0 - the first time this routine is called. Do not change - this value between calls. - pszFileName -> should be pointing to a null string on the way in. - going out it will be the complete filename. - pszFileExt -> the last char of the ext will be used for collisions, - depending on the bModext flag. If null then - the extension will be .00x where x is the collision - counter. -Notes: The counter on the collision is 0-9, a-z. -****************************************************************************/ -void FLMAPI F_FileSystem::pathCreateUniqueName( - FLMUINT * puiTime, - char * pszFileName, - const char * pszFileExt, - FLMBYTE * pHighChars, - FLMBOOL bModext) -{ - FLMINT iCount, iLength; - FLMUINT uiSdTmp = 0; - FLMUINT uiIncVal = 1; - - SetUpTime( puiTime, pHighChars); - uiSdTmp = *puiTime; - - /* Add on the filename extension if passed from the caller */ - *(pszFileName + 8) = NATIVE_DOT; - f_memset( (pszFileName + 9), NATIVE_ZERO, 3 ); - if ( ( pszFileExt != NULL )) - { - if ((iLength = f_strlen(pszFileExt)) > 3) - { - iLength = 3; - } - f_memmove( (pszFileName + 9), pszFileExt, iLength); - } - - if( bModext == TRUE) - { - HexToNative((FLMBYTE)(uiSdTmp & 0x0000001F), pszFileName+(11)); - } - else - { - uiIncVal = 32; - } - uiSdTmp = uiSdTmp >> 5; - for( iCount = 0; iCount < 6; iCount++) /* set pos 2-7 of filename */ - { - HexToNative((FLMBYTE)(uiSdTmp & 0x0000000F), pszFileName+(7-iCount)); - uiSdTmp = uiSdTmp >> 4; - } /* End for() */ - - for( iCount = 0; iCount < 2; iCount++) /* set pos 0-1 of filename */ - { - HexToNative((FLMBYTE)(*pHighChars & 0x0000000F), pszFileName+(1-iCount)); - *pHighChars = *pHighChars >> 4; - } /* End for() */ - - /* Append on a NULL terminator */ - *(pszFileName + 12) = '\0'; - *puiTime += uiIncVal; - - return; -} - -/**************************************************************************** -Desc: Compares the current file against a pattern template -****************************************************************************/ -FLMBOOL FLMAPI f_doesFileMatch( - const char * pszFileName, - const char * pszTemplate) -{ - FLMUINT uiPattern; - FLMUINT uiChar; - - if( !*pszTemplate) - { - return( TRUE); - } - - while( *pszTemplate) - { - uiPattern = *pszTemplate++; - switch( uiPattern) - { - case NATIVE_WILDCARD: - /* if the match_template ends in an asterisk, then we match the*/ - /* remaining string by default, return a match. */ - - if( *pszTemplate == 0) - { - return( TRUE); - } - - /* Found an asterisk somewhere in the match_template, now let's - see if we match anywhere on the remaining input string. */ - - while( *pszFileName) - { - if( f_doesFileMatch( pszFileName, pszTemplate)) - { - return( TRUE); /* found a match, return */ - } - pszFileName++; - } - return( FALSE); /* did not find match, return */ - case NATIVE_QUESTIONMARK: - if( *pszFileName++ == 0) /* skip one character for '?' */ - { - return( FALSE); - } - break; - default: - uiChar = *pszFileName++; - if( f_toupper( uiPattern) != f_toupper( uiChar)) - { - return( FALSE); - } - break; - } - } - - return( (*pszFileName != 0) ? FALSE : TRUE ); -} diff --git a/ftk/src/ftkrand.cpp b/ftk/src/ftkrand.cpp index 646d7d0..ec5ef50 100644 --- a/ftk/src/ftkrand.cpp +++ b/ftk/src/ftkrand.cpp @@ -61,6 +61,52 @@ implement SWB, nor does he give any simple test to determine whether an SWB implementation is correct. ****************************************************************************/ +#define MAX_RANDOM 2147483646L + +/**************************************************************************** +Desc: +****************************************************************************/ +class F_RandomGenerator : public IF_RandomGenerator, public F_Base +{ +public: + + void FLMAPI randomize( void); + + void FLMAPI setSeed( + FLMINT32 i32seed); + + FLMINT32 FLMAPI getInt32( void); + + FLMINT32 FLMAPI getInt32( + FLMINT32 i32Low, + FLMINT32 i32High); + + FLMBOOL FLMAPI getBoolean( void); + + FLMINT32 FLMAPI getSeed( void) + { + return( m_i32Seed); + } + +private: + + FLMINT32 m_i32Seed; +}; + +/**************************************************************************** +Desc: +****************************************************************************/ +RCODE FLMAPI FlmAllocRandomGenerator( + IF_RandomGenerator ** ppRandomGenerator) +{ + if( (*ppRandomGenerator = f_new F_RandomGenerator) == NULL) + { + return( RC_SET( NE_FLM_MEM)); + } + + return( NE_FLM_OK); +} + /************************************************************************* Desc: Set the seed from the date and time *************************************************************************/ @@ -69,7 +115,7 @@ void F_RandomGenerator::randomize( void) FLMUINT uiTime; f_timeGetSeconds( &uiTime ); - randomSetSeed( (FLMUINT32)(((FLMUINT32)uiTime % MAX_RANDOM) + 1)); + setSeed( (FLMUINT32)(((FLMUINT32)uiTime % MAX_RANDOM) + 1)); } /************************************************************************* @@ -84,7 +130,7 @@ void F_RandomGenerator::setSeed( } else { - randomSetSeed( (FLMUINT32) + setSeed( (FLMUINT32) (i32Seed < 1 ? i32Seed + MAX_RANDOM : i32Seed - MAX_RANDOM)); diff --git a/ftk/src/ftkrset.cpp b/ftk/src/ftkrset.cpp index 4e1d9a6..bbc1a5e 100644 --- a/ftk/src/ftkrset.cpp +++ b/ftk/src/ftkrset.cpp @@ -25,10 +25,6 @@ #include "ftksys.h" -// Make sure that the extension is in lower case characters. - -#define FRSET_FILENAME_EXTENSION "frs" - /* ** Sorting Result Sets: ** @@ -104,6 +100,437 @@ 9 9 */ +#define FRSET_FILENAME_EXTENSION "frs" +#define RSBLK_UNSET_FILE_POS (~((FLMUINT64)0)) +#define RS_BLOCK_SIZE (1024 * 512) +#define RS_POSITION_NOT_SET FLM_MAX_UINT64 +#define RS_MAX_FIXED_ENTRY_SIZE 64 + +/***************************************************************************** +Desc: +*****************************************************************************/ +typedef struct +{ + FLMUINT32 ui32Offset; + FLMUINT32 ui32Length; +} F_VAR_HEADER; + +/***************************************************************************** +Desc: +*****************************************************************************/ +typedef struct +{ + FLMUINT64 ui64FilePos; + FLMUINT uiEntryCount; + FLMUINT uiBlockSize; + FLMBOOL bFirstBlock; + FLMBOOL bLastBlock; +} F_BLOCK_HEADER; + +/**************************************************************************** +Desc: +****************************************************************************/ +class F_ResultSetBlk : public F_RefCount, public F_Base +{ +public: + + F_ResultSetBlk(); + + FINLINE ~F_ResultSetBlk() + { + if (m_pNext) + { + m_pNext->m_pPrev = m_pPrev; + } + + if( m_pPrev) + { + m_pPrev->m_pNext = m_pNext; + } + + if (m_pCompare) + { + m_pCompare->Release(); + } + } + + void reset( void); + + void setup( + IF_MultiFileHdl ** ppMultiFileHdl, + IF_ResultSetCompare * pCompare, + FLMUINT uiEntrySize, + FLMBOOL bFirstInList, + FLMBOOL bDropDuplicates, + FLMBOOL bEntriesInOrder); + + RCODE setBuffer( + FLMBYTE * pBuffer, + FLMUINT uiBufferSize = RS_BLOCK_SIZE); + + FINLINE FLMUINT bytesUsedInBuffer( void) + { + if (m_bEntriesInOrder) + { + return( m_BlockHeader.uiBlockSize); + } + else + { + return( m_BlockHeader.uiBlockSize - m_uiLengthRemaining); + } + } + + RCODE addEntry( + FLMBYTE * pEntry, + FLMUINT uiEntryLength ); + + RCODE modifyEntry( + FLMBYTE * pEntry, + FLMUINT uiEntryLength = 0); + + FINLINE RCODE finalize( + FLMBOOL bForceWrite) + { + return( flush( TRUE, bForceWrite)); + } + + RCODE flush( + FLMBOOL bLastBlockInList, + FLMBOOL bForceWrite); + + RCODE getCurrent( + FLMBYTE * pBuffer, + FLMUINT uiBufferLength, + FLMUINT * puiReturnLength); + + FINLINE RCODE getNext( + FLMBYTE * pucBuffer, + FLMUINT uiBufferLength, + FLMUINT * puiReturnLength) + { + // Are we on the last entry or past the last entry? + + if (m_iEntryPos + 1 >= (FLMINT)m_BlockHeader.uiEntryCount) + { + m_iEntryPos = (FLMINT) m_BlockHeader.uiEntryCount; + return RC_SET( NE_FLM_EOF_HIT); + } + + m_iEntryPos++; + return( copyCurrentEntry( pucBuffer, uiBufferLength, puiReturnLength)); + } + + RCODE getNextPtr( + FLMBYTE ** ppBuffer, + FLMUINT * puiReturnLength); + + RCODE getPrev( + FLMBYTE * pBuffer, + FLMUINT uiBufferLength, + FLMUINT * puiReturnLength); + + FINLINE FLMUINT64 getPosition( void) + { + return( (!m_bPositioned || + m_iEntryPos == -1 || + m_iEntryPos == (FLMINT)m_BlockHeader.uiEntryCount + ? RS_POSITION_NOT_SET + : m_ui64BlkEntryPosition + (FLMUINT64)m_iEntryPos)); + } + + RCODE setPosition( + FLMUINT64 ui64Position ); + + RCODE findMatch( + FLMBYTE * pMatchEntry, + FLMUINT uiMatchEntryLength, + FLMBYTE * pFoundEntry, + FLMUINT * puiFoundEntryLength, + FLMINT * piCompare); + + void adjustState( + FLMUINT uiBlkBufferSize); + + RCODE truncate( + FLMBYTE * pszPath); + +private: + + RCODE addEntry( + FLMBYTE * pucEntry); + + void squeezeSpace( void); + + RCODE sortAndRemoveDups( void); + + void removeEntry( + FLMBYTE * pucEntry); + + RCODE quickSort( + FLMUINT uiLowerBounds, + FLMUINT uiUpperBounds); + + FINLINE RCODE entryCompare( + FLMBYTE * pucLeftEntry, + FLMBYTE * pucRightEntry, + FLMINT * piCompare) + { + RCODE rc; + + if( m_bFixedEntrySize) + { + rc = m_pCompare->compare( pucLeftEntry, m_uiEntrySize, + pucRightEntry, m_uiEntrySize, piCompare); + } + else + { + rc = m_pCompare->compare( + m_pucBlockBuf + ((F_VAR_HEADER *)pucLeftEntry)->ui32Offset, + ((F_VAR_HEADER *)pucLeftEntry)->ui32Length, + m_pucBlockBuf + ((F_VAR_HEADER *)pucRightEntry)->ui32Offset, + ((F_VAR_HEADER *)pucRightEntry)->ui32Length, + piCompare); + } + if (*piCompare == 0) + { + m_bDuplicateFound = TRUE; + } + + return( rc); + } + + RCODE copyCurrentEntry( + FLMBYTE * pBuffer, + FLMUINT uiBufferLength, + FLMUINT * puiReturnLength); + + RCODE compareEntry( + FLMBYTE * pMatchEntry, + FLMUINT uiMatchEntryLength, + FLMUINT uiEntryPos, + FLMINT * piCompare); + + RCODE write(); + + RCODE read(); + + F_BLOCK_HEADER m_BlockHeader; + IF_ResultSetCompare * m_pCompare; + FLMBYTE * m_pucBlockBuf; + FLMBYTE * m_pucEndPoint; + F_ResultSetBlk * m_pNext; + F_ResultSetBlk * m_pPrev; + IF_MultiFileHdl ** m_ppMultiFileHdl; + FLMUINT64 m_ui64BlkEntryPosition; + FLMUINT m_uiLengthRemaining; + FLMINT m_iEntryPos; + FLMUINT m_uiEntrySize; + FLMBOOL m_bEntriesInOrder; + FLMBOOL m_bFixedEntrySize; + FLMBOOL m_bPositioned; + FLMBOOL m_bModifiedEntry; + FLMBOOL m_bDuplicateFound; + FLMBOOL m_bDropDuplicates; + + friend class F_ResultSet; +}; + +/***************************************************************************** +Desc: +*****************************************************************************/ +class F_ResultSet : public IF_ResultSet, public F_Base +{ +public: + + F_ResultSet(); + + F_ResultSet( + FLMUINT uiBlkSize); + + virtual ~F_ResultSet(); + + RCODE FLMAPI setupResultSet( + const char * pszPath, + IF_ResultSetCompare * pCompare, + FLMUINT uiEntrySize, + FLMBOOL bDropDuplicates = TRUE, + FLMBOOL bEntriesInOrder = FALSE, + const char * pszInputFileName = NULL); + + FINLINE void FLMAPI setSortStatus( + IF_ResultSetSortStatus * pSortStatus) + { + if (m_pSortStatus) + { + m_pSortStatus->Release(); + m_pSortStatus = NULL; + } + + if ((m_pSortStatus = pSortStatus) != NULL) + { + m_pSortStatus->AddRef(); + } + } + + FINLINE FLMUINT64 FLMAPI getTotalEntries( void) + { + F_ResultSetBlk * pBlk = m_pFirstRSBlk; + FLMUINT64 ui64TotalEntries = 0; + + for( pBlk = m_pFirstRSBlk; pBlk; pBlk = pBlk->m_pNext) + { + ui64TotalEntries += pBlk->m_BlockHeader.uiEntryCount; + } + + return( ui64TotalEntries); + } + + RCODE FLMAPI addEntry( + const void * pvEntry, + FLMUINT uiEntryLength = 0); + + RCODE FLMAPI finalizeResultSet( + FLMUINT64 * pui64TotalEntries = NULL); + + RCODE FLMAPI getFirst( + void * pvEntryBuffer, + FLMUINT uiBufferLength = 0, + FLMUINT * puiEntryLength = NULL); + + RCODE FLMAPI getNext( + void * pvEntryBuffer, + FLMUINT uiBufferLength = 0, + FLMUINT * puiEntryLength = NULL); + + RCODE FLMAPI getLast( + void * pvEntryBuffer, + FLMUINT uiBufferLength = 0, + FLMUINT * puiEntryLength = NULL); + + RCODE FLMAPI getPrev( + void * pvEntryBuffer, + FLMUINT uiBufferLength = 0, + FLMUINT * puiEntryLength = NULL); + + RCODE FLMAPI getCurrent( + void * pvEntryBuffer, + FLMUINT uiBufferLength = 0, + FLMUINT * puiEntryLength = NULL); + + FINLINE RCODE FLMAPI modifyCurrent( + const void * pvEntry, + FLMUINT uiEntryLength = 0) + { + return( m_pCurRSBlk->modifyEntry( (FLMBYTE *)pvEntry, uiEntryLength)); + } + + FINLINE RCODE FLMAPI findMatch( + const void * pvMatchEntry, + void * pvFoundEntry) + { + return( findMatch( pvMatchEntry, m_uiEntrySize, + pvFoundEntry, NULL)); + } + + RCODE FLMAPI findMatch( + const void * pvMatchEntry, + FLMUINT uiMatchEntryLength, + void * pvFoundEntry, + FLMUINT * puiFoundEntryLength); + + FINLINE FLMUINT64 FLMAPI getPosition( void) + { + return( (!m_pCurRSBlk + ? RS_POSITION_NOT_SET + : m_pCurRSBlk->getPosition())); + } + + RCODE FLMAPI setPosition( + FLMUINT64 ui64Position); + + RCODE FLMAPI resetResultSet( + FLMBOOL bDelete = TRUE); + + RCODE FLMAPI flushToFile( void); + +private: + + FINLINE FLMUINT64 numberOfBlockChains( void) + { + FLMUINT64 ui64Count = 0; + F_ResultSetBlk * pBlk = m_pFirstRSBlk; + + for (; pBlk ; pBlk = pBlk->m_pNext) + { + if (pBlk->m_BlockHeader.bFirstBlock) + { + ui64Count++; + } + } + + return( ui64Count); + } + + RCODE mergeSort(); + + RCODE getNextPtr( + F_ResultSetBlk ** ppCurBlk, + FLMBYTE * * ppBuffer, + FLMUINT * puiReturnLength); + + RCODE unionBlkLists( + F_ResultSetBlk * pLeftBlk, + F_ResultSetBlk * pRightBlk = NULL); + + RCODE copyRemainingItems( + F_ResultSetBlk * pCurBlk); + + void closeFile( + IF_MultiFileHdl ** ppMultiFileHdl, + FLMBOOL bDelete = TRUE); + + RCODE openFile( + IF_MultiFileHdl ** ppMultiFileHdl); + + F_ResultSetBlk * selectMidpoint( + F_ResultSetBlk * pLowBlk, + F_ResultSetBlk * pHighBlk, + FLMBOOL bPickHighIfNeighbors); + + RCODE setupFromFile( void); + + IF_ResultSetCompare * m_pCompare; + IF_ResultSetSortStatus * m_pSortStatus; + FLMUINT64 m_ui64EstTotalUnits; + FLMUINT64 m_ui64UnitsDone; + FLMUINT m_uiEntrySize; + FLMUINT64 m_ui64TotalEntries; + F_ResultSetBlk * m_pCurRSBlk; + F_ResultSetBlk * m_pFirstRSBlk; + F_ResultSetBlk * m_pLastRSBlk; + char m_szIoDefaultPath[ F_PATH_MAX_SIZE]; + char m_szIoFilePath1[ F_PATH_MAX_SIZE]; + char m_szIoFilePath2[ F_PATH_MAX_SIZE]; + IF_MultiFileHdl * m_pMultiFileHdl1; + IF_MultiFileHdl * m_pMultiFileHdl2; + FLMBYTE * m_pucBlockBuf1; + FLMBYTE * m_pucBlockBuf2; + FLMBYTE * m_pucBlockBuf3; + FLMUINT m_uiBlockBuf1Len; + FLMBOOL m_bFile1Opened; + FLMBOOL m_bFile2Opened; + FLMBOOL m_bOutput2ndFile; + FLMBOOL m_bInitialAdding; + FLMBOOL m_bFinalizeCalled; + FLMBOOL m_bSetupCalled; + FLMBOOL m_bDropDuplicates; + FLMBOOL m_bAppAddsInOrder; + FLMBOOL m_bEntriesInOrder; + FLMUINT m_uiBlkSize; + + friend class F_ResultSetBlk; +}; + /***************************************************************************** Desc: *****************************************************************************/ @@ -442,10 +869,9 @@ RCODE F_ResultSet::setupFromFile( void) F_BLOCK_HEADER BlkHdr; flmAssert( !m_bSetupCalled); - - if( (m_pMultiFileHdl1 = f_new F_MultiFileHdl) == NULL) + + if( RC_BAD( rc = FlmAllocMultiFileHdl( &m_pMultiFileHdl1))) { - rc = RC_SET( NE_FLM_MEM); goto Exit; } @@ -1923,9 +2349,8 @@ RCODE F_ResultSet::openFile( f_strcpy( pszDirPath, m_szIoDefaultPath); - if( (*ppMultiFileHdl = f_new F_MultiFileHdl) == NULL) + if( RC_BAD( rc = FlmAllocMultiFileHdl( ppMultiFileHdl))) { - rc = RC_SET( NE_FLM_MEM); goto Exit; } diff --git a/ftk/src/ftksem.cpp b/ftk/src/ftksem.cpp index b6e4a33..ff38c60 100644 --- a/ftk/src/ftksem.cpp +++ b/ftk/src/ftksem.cpp @@ -25,20 +25,6 @@ #include "ftksys.h" -#ifdef FLM_WIN - - typedef struct - { - FLMATOMIC locked; -#ifdef FLM_DEBUG - FLMUINT uiThreadId; - FLMATOMIC lockedCount; - FLMATOMIC waitCount; -#endif - } F_INTERLOCK; - -#endif - /**************************************************************************** Desc: ****************************************************************************/ diff --git a/ftk/src/ftkstrm.cpp b/ftk/src/ftkstrm.cpp index 61c8ac0..71b4d86 100644 --- a/ftk/src/ftkstrm.cpp +++ b/ftk/src/ftkstrm.cpp @@ -35,26 +35,509 @@ #define MULTI_FILE_OUT_STREAM_MIN_FILE_SIZE 1048510 #define MULTI_FILE_OUT_STREAM_MAX_FILE_SIZE 2147483647 -FLMBYTE F_Base64EncoderIStream::m_ucEncodeTable[ 64] = +/**************************************************************************** +Desc: +****************************************************************************/ +class F_IStream : public IF_IStream, public F_Base { - ASCII_UPPER_A, ASCII_UPPER_B, ASCII_UPPER_C, ASCII_UPPER_D, - ASCII_UPPER_E, ASCII_UPPER_F, ASCII_UPPER_G, ASCII_UPPER_H, - ASCII_UPPER_I, ASCII_UPPER_J, ASCII_UPPER_K, ASCII_UPPER_L, - ASCII_UPPER_M, ASCII_UPPER_N, ASCII_UPPER_O, ASCII_UPPER_P, - ASCII_UPPER_Q, ASCII_UPPER_R, ASCII_UPPER_S, ASCII_UPPER_T, - ASCII_UPPER_U, ASCII_UPPER_V, ASCII_UPPER_W, ASCII_UPPER_X, - ASCII_UPPER_Y, ASCII_UPPER_Z, ASCII_LOWER_A, ASCII_LOWER_B, - ASCII_LOWER_C, ASCII_LOWER_D, ASCII_LOWER_E, ASCII_LOWER_F, - ASCII_LOWER_G, ASCII_LOWER_H, ASCII_LOWER_I, ASCII_LOWER_J, - ASCII_LOWER_K, ASCII_LOWER_L, ASCII_LOWER_M, ASCII_LOWER_N, - ASCII_LOWER_O, ASCII_LOWER_P, ASCII_LOWER_Q, ASCII_LOWER_R, - ASCII_LOWER_S, ASCII_LOWER_T, ASCII_LOWER_U, ASCII_LOWER_V, - ASCII_LOWER_W, ASCII_LOWER_X, ASCII_LOWER_Y, ASCII_LOWER_Z, - ASCII_ZERO, ASCII_ONE, ASCII_TWO, ASCII_THREE, - ASCII_FOUR, ASCII_FIVE, ASCII_SIX, ASCII_SEVEN, - ASCII_EIGHT, ASCII_NINE, ASCII_PLUS, ASCII_SLASH +public: + + F_IStream(); + + virtual ~F_IStream(); }; +/**************************************************************************** +Desc: +****************************************************************************/ +class F_OStream : public IF_OStream, public F_Base +{ +public: + + F_OStream(); + + virtual ~F_OStream(); + +}; + +/**************************************************************************** +Desc: +****************************************************************************/ +class F_PosIStream : public IF_PosIStream, public F_Base +{ +public: + + F_PosIStream(); + + virtual ~F_PosIStream(); + +}; + +/**************************************************************************** +Desc: +****************************************************************************/ +class F_BufferIStream : public IF_BufferIStream, public F_Base +{ +public: + + F_BufferIStream() + { + m_pucBuffer = NULL; + m_uiBufferLen = 0; + m_uiOffset = 0; + m_bAllocatedBuffer = FALSE; + m_bIsOpen = FALSE; + } + + virtual ~F_BufferIStream(); + + RCODE FLMAPI open( + const FLMBYTE * pucBuffer, + FLMUINT uiLength, + FLMBYTE ** ppucAllocatedBuffer = NULL); + + FINLINE FLMUINT64 FLMAPI totalSize( void) + { + flmAssert( m_bIsOpen); + return( m_uiBufferLen); + } + + FINLINE FLMUINT64 FLMAPI remainingSize( void) + { + flmAssert( m_bIsOpen); + return( m_uiBufferLen - m_uiOffset); + } + + RCODE FLMAPI close( void); + + FINLINE RCODE FLMAPI positionTo( + FLMUINT64 ui64Position) + { + flmAssert( m_bIsOpen); + + if( ui64Position < m_uiBufferLen) + { + m_uiOffset = (FLMUINT)ui64Position; + } + else + { + m_uiOffset = m_uiBufferLen; + } + + return( NE_FLM_OK); + } + + FINLINE FLMUINT64 FLMAPI getCurrPosition( void) + { + flmAssert( m_bIsOpen); + return( m_uiOffset); + } + + RCODE FLMAPI read( + void * pvBuffer, + FLMUINT uiBytesToRead, + FLMUINT * puiBytesRead); + + FINLINE const FLMBYTE * getBuffer( void) + { + flmAssert( m_bIsOpen); + return( m_pucBuffer); + } + + FINLINE const FLMBYTE * getBufferAtCurrentOffset( void) + { + flmAssert( m_bIsOpen); + return( m_pucBuffer ? &m_pucBuffer[ m_uiOffset] : NULL); + } + + FINLINE void truncate( + FLMUINT uiOffset) + { + flmAssert( m_bIsOpen); + flmAssert( uiOffset >= m_uiOffset); + flmAssert( uiOffset <= m_uiBufferLen); + + m_uiBufferLen = uiOffset; + } + + FINLINE FLMBOOL isOpen( void) + { + return( m_bIsOpen); + } + +private: + + const FLMBYTE * m_pucBuffer; + FLMUINT m_uiBufferLen; + FLMUINT m_uiOffset; + FLMBOOL m_bAllocatedBuffer; + FLMBOOL m_bIsOpen; +}; + +/**************************************************************************** +Desc: +****************************************************************************/ +class F_FileIStream : public F_PosIStream +{ +public: + + F_FileIStream() + { + m_pFileHdl = NULL; + m_ui64FileOffset = 0; + } + + virtual ~F_FileIStream() + { + if( m_pFileHdl) + { + m_pFileHdl->Release(); + } + } + + RCODE FLMAPI open( + const char * pszPath); + + RCODE FLMAPI close( void); + + RCODE FLMAPI positionTo( + FLMUINT64 ui64Position); + + FLMUINT64 FLMAPI totalSize( void); + + FLMUINT64 FLMAPI remainingSize( void); + + FLMUINT64 FLMAPI getCurrPosition( void); + + RCODE FLMAPI read( + void * pvBuffer, + FLMUINT uiBytesToRead, + FLMUINT * puiBytesRead); + +private: + + IF_FileHdl * m_pFileHdl; + FLMUINT64 m_ui64FileOffset; +}; + +/**************************************************************************** +Desc: +****************************************************************************/ +class F_BufferedIStream : public F_PosIStream +{ +public: + + F_BufferedIStream() + { + m_pIStream = NULL; + m_pucBuffer = NULL; + } + + virtual ~F_BufferedIStream() + { + close(); + } + + RCODE FLMAPI open( + IF_IStream * pIStream, + FLMUINT uiBufferSize); + + RCODE FLMAPI read( + void * pvBuffer, + FLMUINT uiBytesToRead, + FLMUINT * puiBytesRead); + + RCODE FLMAPI close( void); + + FINLINE FLMUINT64 FLMAPI totalSize( void) + { + if (!m_pIStream) + { + flmAssert( 0); + return( 0); + } + + return( m_uiBytesAvail); + } + + FINLINE FLMUINT64 FLMAPI remainingSize( void) + { + if( !m_pIStream) + { + flmAssert( 0); + return( 0); + } + + return( m_uiBytesAvail - m_uiBufferOffset); + } + + FINLINE RCODE FLMAPI positionTo( + FLMUINT64 ui64Position) + { + if( !m_pIStream) + { + flmAssert( 0); + return( RC_SET( NE_FLM_ILLEGAL_OP)); + } + + if( ui64Position < m_uiBytesAvail) + { + m_uiBufferOffset = (FLMUINT)ui64Position; + } + else + { + m_uiBufferOffset = m_uiBytesAvail; + } + + return( NE_FLM_OK); + } + + FINLINE FLMUINT64 FLMAPI getCurrPosition( void) + { + if( !m_pIStream) + { + flmAssert( 0); + return( 0); + } + + return( m_uiBufferOffset); + } + +private: + + IF_IStream * m_pIStream; + FLMBYTE * m_pucBuffer; + FLMUINT m_uiBufferSize; + FLMUINT m_uiBufferOffset; + FLMUINT m_uiBytesAvail; +}; + +/**************************************************************************** +Desc: +****************************************************************************/ +class F_BufferedOStream : public F_OStream +{ +public: + + F_BufferedOStream() + { + m_pOStream = NULL; + m_pucBuffer = NULL; + } + + virtual ~F_BufferedOStream() + { + close(); + } + + RCODE FLMAPI open( + IF_OStream * pOStream, + FLMUINT uiBufferSize); + + RCODE FLMAPI write( + const void * pvBuffer, + FLMUINT uiBytesToWrite, + FLMUINT * puiBytesWritten); + + RCODE FLMAPI close( void); + + RCODE FLMAPI flush( void); + +private: + + IF_OStream * m_pOStream; + FLMBYTE * m_pucBuffer; + FLMUINT m_uiBufferSize; + FLMUINT m_uiBufferOffset; +}; + +/**************************************************************************** +Desc: +****************************************************************************/ +class F_FileOStream : public F_OStream +{ +public: + + F_FileOStream() + { + m_pFileHdl = NULL; + } + + virtual ~F_FileOStream() + { + close(); + } + + RCODE FLMAPI open( + const char * pszFilePath, + FLMBOOL bTruncateIfExists); + + RCODE FLMAPI write( + const void * pvBuffer, + FLMUINT uiBytesToWrite, + FLMUINT * puiBytesWritten); + + RCODE FLMAPI close( void); + +private: + + IF_FileHdl * m_pFileHdl; + FLMUINT64 m_ui64FileOffset; +}; + +/**************************************************************************** +Desc: +****************************************************************************/ +class F_MultiFileIStream : public F_IStream +{ +public: + + F_MultiFileIStream() + { + m_pIStream = NULL; + m_bOpen = FALSE; + } + + virtual ~F_MultiFileIStream() + { + close(); + } + + RCODE FLMAPI open( + const char * pszDirectory, + const char * pszBaseName); + + RCODE FLMAPI read( + void * pvBuffer, + FLMUINT uiBytesToRead, + FLMUINT * puiBytesRead); + + RCODE FLMAPI close( void); + +private: + + RCODE rollToNextFile( void); + + IF_IStream * m_pIStream; + FLMBOOL m_bOpen; + FLMBOOL m_bEndOfStream; + FLMUINT m_uiFileNum; + FLMUINT64 m_ui64FileOffset; + char m_szDirectory[ F_PATH_MAX_SIZE + 1]; + char m_szBaseName[ F_PATH_MAX_SIZE + 1]; +}; + +/**************************************************************************** +Desc: +****************************************************************************/ +class F_MultiFileOStream : public F_OStream +{ +public: + + F_MultiFileOStream() + { + m_pOStream = NULL; + m_bOpen = FALSE; + } + + virtual ~F_MultiFileOStream() + { + close(); + } + + RCODE create( + const char * pszDirectory, + const char * pszBaseName, + FLMUINT uiMaxFileSize, + FLMBOOL bOkToOverwrite); + + RCODE FLMAPI write( + const void * pvBuffer, + FLMUINT uiBytesToWrite, + FLMUINT * puiBytesWritten); + + RCODE FLMAPI close( void); + +private: + + RCODE rollToNextFile( void); + + RCODE processDirectory( + const char * pszDirectory, + const char * pszBaseName, + FLMBOOL bOkToDelete); + + F_OStream * m_pOStream; + FLMBOOL m_bOpen; + FLMUINT m_uiFileNum; + FLMUINT64 m_ui64MaxFileSize; + FLMUINT64 m_ui64FileOffset; + char m_szDirectory[ F_PATH_MAX_SIZE + 1]; + char m_szBaseName[ F_PATH_MAX_SIZE + 1]; + + friend class F_DbSystem; +}; + +/**************************************************************************** +Desc: Decodes an ASCII base64 stream to binary +****************************************************************************/ +class F_Base64DecoderIStream : public F_IStream +{ +public: + + F_Base64DecoderIStream() + { + m_pIStream = NULL; + m_uiBufOffset = 0; + m_uiAvailBytes = 0; + } + + virtual ~F_Base64DecoderIStream() + { + close(); + } + + RCODE FLMAPI open( + IF_IStream * pIStream); + + RCODE FLMAPI read( + void * pvBuffer, + FLMUINT uiBytesToRead, + FLMUINT * puiBytesRead); + + FINLINE RCODE FLMAPI close( void) + { + RCODE rc = NE_FLM_OK; + + if( m_pIStream) + { + if( m_pIStream->getRefCount() == 1) + { + rc = m_pIStream->close(); + } + + m_pIStream->Release(); + m_pIStream = NULL; + } + + m_uiAvailBytes = 0; + m_uiBufOffset = 0; + + return( rc); + } + +private: + + IF_IStream * m_pIStream; + FLMUINT m_uiBufOffset; + FLMUINT m_uiAvailBytes; + FLMBYTE m_ucBuffer[ 8]; + static FLMBYTE m_ucDecodeTable[ 256]; +}; + +/**************************************************************************** +Desc: +****************************************************************************/ FLMBYTE F_Base64DecoderIStream::m_ucDecodeTable[ 256] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0 .. 7 @@ -91,6 +574,312 @@ FLMBYTE F_Base64DecoderIStream::m_ucDecodeTable[ 256] = 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF // 248 .. 255 }; +/**************************************************************************** +Desc: Encodes a binary input stream into ASCII base64. +****************************************************************************/ +class F_Base64EncoderIStream : public F_IStream +{ +public: + + F_Base64EncoderIStream() + { + m_pIStream = NULL; + } + + virtual ~F_Base64EncoderIStream() + { + close(); + } + + RCODE FLMAPI open( + IF_IStream * pIStream, + FLMBOOL bLineBreaks); + + RCODE FLMAPI read( + void * pvBuffer, + FLMUINT uiBytesToRead, + FLMUINT * puiBytesRead); + + FINLINE RCODE FLMAPI close( void) + { + RCODE rc = NE_FLM_OK; + + if( m_pIStream) + { + if( m_pIStream->getRefCount() == 1) + { + rc = m_pIStream->close(); + } + + m_pIStream->Release(); + m_pIStream = NULL; + } + + return( rc); + } + +private: + + IF_IStream * m_pIStream; + FLMBOOL m_bInputExhausted; + FLMBOOL m_bLineBreaks; + FLMBOOL m_bPriorLineEnd; + FLMUINT m_uiBase64Count; + FLMUINT m_uiBufOffset; + FLMUINT m_uiAvailBytes; + FLMBYTE m_ucBuffer[ 8]; + static FLMBYTE m_ucEncodeTable[ 64]; +}; + +/**************************************************************************** +Desc: +****************************************************************************/ +FLMBYTE F_Base64EncoderIStream::m_ucEncodeTable[ 64] = +{ + ASCII_UPPER_A, ASCII_UPPER_B, ASCII_UPPER_C, ASCII_UPPER_D, + ASCII_UPPER_E, ASCII_UPPER_F, ASCII_UPPER_G, ASCII_UPPER_H, + ASCII_UPPER_I, ASCII_UPPER_J, ASCII_UPPER_K, ASCII_UPPER_L, + ASCII_UPPER_M, ASCII_UPPER_N, ASCII_UPPER_O, ASCII_UPPER_P, + ASCII_UPPER_Q, ASCII_UPPER_R, ASCII_UPPER_S, ASCII_UPPER_T, + ASCII_UPPER_U, ASCII_UPPER_V, ASCII_UPPER_W, ASCII_UPPER_X, + ASCII_UPPER_Y, ASCII_UPPER_Z, ASCII_LOWER_A, ASCII_LOWER_B, + ASCII_LOWER_C, ASCII_LOWER_D, ASCII_LOWER_E, ASCII_LOWER_F, + ASCII_LOWER_G, ASCII_LOWER_H, ASCII_LOWER_I, ASCII_LOWER_J, + ASCII_LOWER_K, ASCII_LOWER_L, ASCII_LOWER_M, ASCII_LOWER_N, + ASCII_LOWER_O, ASCII_LOWER_P, ASCII_LOWER_Q, ASCII_LOWER_R, + ASCII_LOWER_S, ASCII_LOWER_T, ASCII_LOWER_U, ASCII_LOWER_V, + ASCII_LOWER_W, ASCII_LOWER_X, ASCII_LOWER_Y, ASCII_LOWER_Z, + ASCII_ZERO, ASCII_ONE, ASCII_TWO, ASCII_THREE, + ASCII_FOUR, ASCII_FIVE, ASCII_SIX, ASCII_SEVEN, + ASCII_EIGHT, ASCII_NINE, ASCII_PLUS, ASCII_SLASH +}; + +/**************************************************************************** +Desc: +****************************************************************************/ +typedef struct LZWODictItem +{ + LZWODictItem * pNext; + FLMUINT16 ui16Code; + FLMUINT16 ui16ParentCode; + FLMBYTE ucChar; +} LZWODictItem; + +/**************************************************************************** +Desc: +****************************************************************************/ +class F_CompressingOStream : public F_OStream +{ +public: + + F_CompressingOStream() + { + m_pPool = NULL; + m_pOStream = NULL; + m_ppHashTbl = NULL; + } + + virtual ~F_CompressingOStream() + { + close(); + } + + RCODE FLMAPI open( + IF_OStream * pOStream); + + RCODE FLMAPI write( + const void * pvBuffer, + FLMUINT uiBytesToWrite, + FLMUINT * puiBytesWritten); + + RCODE FLMAPI close( void); + +private: + + FINLINE FLMUINT getHashBucket( + FLMUINT16 ui16CurrentCode, + FLMBYTE ucChar) + { + return( ((((FLMUINT)ui16CurrentCode) << 8) | + ((FLMUINT)ucChar)) % m_uiHashTblSize); + } + + LZWODictItem * findDictEntry( + FLMUINT16 ui16CurrentCode, + FLMBYTE ucChar); + + IF_Pool * m_pPool; + IF_OStream * m_pOStream; + LZWODictItem ** m_ppHashTbl; + FLMUINT m_uiHashTblSize; + FLMUINT m_uiLastRatio; + FLMUINT m_uiBestRatio; + FLMUINT m_uiCurrentBytesIn; + FLMUINT m_uiTotalBytesIn; + FLMUINT m_uiCurrentBytesOut; + FLMUINT m_uiTotalBytesOut; + FLMBOOL m_bStopCompression; + FLMUINT16 m_ui16CurrentCode; + FLMUINT16 m_ui16FreeCode; +}; + +typedef struct LZWIDictItem +{ + LZWODictItem * pNext; + FLMUINT16 ui16ParentCode; + FLMBYTE ucChar; +} LZWIDictItem; + +/**************************************************************************** +Desc: +****************************************************************************/ +class F_UncompressingIStream : public F_IStream +{ +public: + + F_UncompressingIStream() + { + m_pIStream = NULL; + m_pDict = NULL; + m_pucDecodeBuffer = NULL; + } + + virtual ~F_UncompressingIStream() + { + close(); + } + + RCODE FLMAPI open( + IF_IStream * pIStream); + + RCODE FLMAPI read( + void * pvBuffer, + FLMUINT uiBytesToRead, + FLMUINT * puiBytesRead); + + RCODE FLMAPI close( void); + +private: + + RCODE readCode( + FLMUINT16 * pui16Code); + + RCODE decodeToBuffer( + FLMUINT16 ui16Code); + + IF_IStream * m_pIStream; + LZWIDictItem * m_pDict; + FLMBYTE * m_pucDecodeBuffer; + FLMUINT m_uiDecodeBufferSize; + FLMUINT m_uiDecodeBufferOffset; + FLMUINT16 m_ui16FreeCode; + FLMUINT16 m_ui16LastCode; + FLMBOOL m_bStopCompression; + FLMBOOL m_bEndOfStream; +}; + +/**************************************************************************** +Desc: +****************************************************************************/ +class F_TCPStream : public F_IStream, public F_OStream +{ +public: + + F_TCPStream( void); + + virtual ~F_TCPStream( void); + + RCODE openConnection( + const char * pucHostAddress, + FLMUINT uiPort, + FLMUINT uiConnectTimeout = 3, + FLMUINT uiDataTimeout = 15); + + RCODE FLMAPI read( + void * pvBuffer, + FLMUINT uiBytesToRead, + FLMUINT * puiBytesRead); + + RCODE FLMAPI write( + const void * pvBuffer, + FLMUINT uiBytesToWrite, + FLMUINT * puiBytesWritten); + + FINLINE RCODE socketPeekWrite( + FLMINT iTimeOut) + { + return( socketPeek( iTimeOut, FALSE)); + } + + FINLINE RCODE socketPeekRead( + FLMINT iTimeOut) + { + return( socketPeek( iTimeOut, TRUE)); + }; + + FINLINE const char * getName( void) + { + getLocalInfo(); + return( (const char *)m_pszName); + }; + + FINLINE const char * getAddr( void) + { + getLocalInfo(); + return( (const char *)m_pszIp); + }; + + FINLINE const char * getPeerName( void) + { + getRemoteInfo(); + return( (const char *)m_pszPeerName); + }; + + FINLINE const char * getPeerAddr( void) + { + getRemoteInfo(); + return( (const char *)m_pszPeerIp); + }; + + RCODE readNoWait( + void * pvBuffer, + FLMUINT uiCount, + FLMUINT * puiReadRead); + + RCODE readAll( + void * pvBuffer, + FLMUINT uiCount, + FLMUINT * puiBytesRead); + + RCODE setTcpDelay( + FLMBOOL bOn); + + RCODE FLMAPI close( void); + +private: + + RCODE getLocalInfo( void); + + RCODE getRemoteInfo( void); + + RCODE socketPeek( + FLMINT iTimoutVal, + FLMBOOL bPeekRead); + +#ifndef FLM_UNIX + WSADATA m_wsaData; +#endif + FLMBOOL m_bInitialized; + SOCKET m_iSocket; + FLMUINT m_uiIOTimeout; + FLMBOOL m_bConnected; + char m_pszIp[ 256]; + char m_pszName[ 256]; + char m_pszPeerIp[ 256]; + char m_pszPeerName[ 256]; + unsigned long m_ulRemoteAddr; +}; + /**************************************************************************** Desc: ****************************************************************************/ @@ -1198,6 +1987,20 @@ RCODE FLMAPI F_BufferedOStream::close( void) return( rc); } +/***************************************************************************** +Desc: +******************************************************************************/ +RCODE FLMAPI FlmAllocBufferIStream( + IF_BufferIStream ** ppIStream) +{ + if( (*ppIStream = f_new F_BufferIStream) == NULL) + { + return( RC_SET( NE_FLM_MEM)); + } + + return( NE_FLM_OK); +} + /***************************************************************************** Desc: ******************************************************************************/ @@ -1631,6 +2434,15 @@ RCODE FLMAPI F_CompressingOStream::open( { goto Exit; } + + // Create a pool for temporary allocations + + if( RC_BAD( rc = FlmAllocPool( &m_pPool))) + { + goto Exit; + } + + m_pPool->poolInit( 64 * 1024); f_memset( m_ppHashTbl, 0, sizeof( LZWODictItem *) * m_uiHashTblSize); @@ -1753,7 +2565,7 @@ RCODE FLMAPI F_CompressingOStream::write( if( m_ui16FreeCode < LZW_MAX_CODE) { uiBucket = getHashBucket( m_ui16CurrentCode, *pucBuffer); - if( RC_BAD( rc = m_pool.poolAlloc( + if( RC_BAD( rc = m_pPool->poolAlloc( sizeof( LZWODictItem), (void **)&pDictItem))) { goto Exit; @@ -1828,7 +2640,7 @@ RCODE FLMAPI F_CompressingOStream::write( // Reset the dictionary - m_pool.poolReset( NULL); + m_pPool->poolReset( NULL); f_memset( m_ppHashTbl, 0, sizeof( LZWODictItem *) * m_uiHashTblSize); m_ui16FreeCode = LZW_START_CODE; } @@ -1915,8 +2727,13 @@ RCODE FLMAPI F_CompressingOStream::close( void) f_free( &m_ppHashTbl); m_uiHashTblSize = 0; } + + if( m_pPool) + { + m_pPool->Release(); + m_pPool = NULL; + } - m_pool.poolReset( NULL); return( rc); } diff --git a/ftk/src/ftksys.h b/ftk/src/ftksys.h index 1b32714..1acaeb9 100644 --- a/ftk/src/ftksys.h +++ b/ftk/src/ftksys.h @@ -29,352 +29,53 @@ #include "ftk.h" - #ifndef FLM_PLATFORM_CONFIGURED - #error Platform not configured - #endif - class F_Thread; class F_ThreadMgr; - class F_IOBuffer; + class F_IOBufferMgr; class F_FileSystem; class F_ThreadMgr; class F_ResultSet; class F_ResultSetBlk; - #define RS_BLOCK_SIZE (1024 * 512) - #define RS_POSITION_NOT_SET FLM_MAX_UINT64 - #define RS_MAX_FIXED_ENTRY_SIZE 64 - - // Cell sizes for buffer allocator - - #define CELL_SIZE_0 16 - #define CELL_SIZE_1 32 - #define CELL_SIZE_2 64 - #define CELL_SIZE_3 128 - #define CELL_SIZE_4 192 - #define CELL_SIZE_5 320 - #define CELL_SIZE_6 512 - #define CELL_SIZE_7 672 - #define CELL_SIZE_8 832 - #define CELL_SIZE_9 1088 - #define CELL_SIZE_10 1344 - #define CELL_SIZE_11 1760 - #define CELL_SIZE_12 2176 - #define CELL_SIZE_13 2848 - #define CELL_SIZE_14 3520 - #define CELL_SIZE_15 4608 - #define CELL_SIZE_16 5152 - #define CELL_SIZE_17 5696 - #define CELL_SIZE_18 8164 - #define CELL_SIZE_19 13068 - #define CELL_SIZE_20 16340 - #define CELL_SIZE_21 21796 - #define MAX_CELL_SIZE CELL_SIZE_21 - - #define NUM_BUF_ALLOCATORS 22 - /**************************************************************************** Desc: Global data ****************************************************************************/ #ifndef ALLOCATE_SYS_DATA - extern F_FileSystem * gv_pFileSystem; - extern F_ThreadMgr * gv_pThreadMgr; + extern IF_FileSystem * gv_pFileSystem; + extern IF_ThreadMgr * gv_pThreadMgr; #else - F_FileSystem * gv_pFileSystem; - F_ThreadMgr * gv_pThreadMgr; + IF_FileSystem * gv_pFileSystem; + IF_ThreadMgr * gv_pThreadMgr; #endif - FINLINE RCODE MapPlatformError( - FLMINT iError, - RCODE defaultRc); - - #define F_MULTI_FHDL_LIST_SIZE 8 - #define F_MULTI_FHDL_DEFAULT_MAX_FILE_SIZE ((FLMUINT)0xFFFFFFFF) - - typedef struct - { - IF_FileHdl * pFileHdl; - FLMUINT uiFileNum; - FLMBOOL bDirty; - } FH_INFO; - - typedef struct xmlChar - { - FLMBYTE ucFlags; - } XMLCHAR; - - #define FLM_MAX_KEY_SIZE 1024 - - typedef struct FlmBlockHdrTag - { - FLMUINT32 ui32BlkAddr; // BH_ADDR - FLMUINT32 ui32PrevBlkInChain; // BH_PREV_BLK - FLMUINT32 ui32NextBlkInChain; // BH_NEXT_BLK - FLMUINT32 ui32PriorBlkImgAddr; // BH_PREV_BLK_ADDR - FLMUINT64 ui64TransID; // BH_TRANS_ID - FLMUINT32 ui32BlkCRC; // Block CRC - FLMUINT16 ui16BlkBytesAvail; // BH_BLK_END, BH_ELM_END - FLMUINT8 ui8BlkFlags; // Flags for the block - #define BLK_FORMAT_IS_LITTLE_ENDIAN 0x01 - #define BLK_IS_BEFORE_IMAGE 0x02 - // This bit gets ORed into type if the - // block is a Before Image block that - // should be restored on transaction - // abort. This is only set when a block - // is written to the log, so it only - // needs to be unset when the block is - // read back from the log. - #define BLK_IS_ENCRYPTED 0x04 - - - FLMUINT8 ui8BlkType; // BH_TYPE - #define BT_FREE 0 // Free block - avail list - #define BT_LFH_BLK 1 // LFH Header block - #define BT_LEAF 2 // New B-Tree Leaf block - #define BT_NON_LEAF 3 // New B-Tree Non-leaf block block - fixed key size - #define BT_NON_LEAF_COUNTS 4 // New B-Tree Non-leaf index with counts - #define BT_LEAF_DATA 5 // New B-Tree Leaf block with Data - #define BT_DATA_ONLY 6 // Data-only block - // NOTE: IF adding more types, may need to modify the blkIsNewBTree function - // below. - - // IMPORTANT NOTE: If anything is changed in here, need to make - // corresponding changes to convertBlkHdr routine and - // flmVerifyDiskStructOffsets routine. - - #define F_BLK_HDR_ui32BlkAddr_OFFSET 0 - #define F_BLK_HDR_ui32PrevBlkInChain_OFFSET 4 - #define F_BLK_HDR_ui32NextBlkInChain_OFFSET 8 - #define F_BLK_HDR_ui32PriorBlkImgAddr_OFFSET 12 - #define F_BLK_HDR_ui64TransID_OFFSET 16 - #define F_BLK_HDR_ui32BlkCRC_OFFSET 24 - #define F_BLK_HDR_ui16BlkBytesAvail_OFFSET 28 - #define F_BLK_HDR_ui8BlkFlags_OFFSET 30 - #define F_BLK_HDR_ui8BlkType_OFFSET 31 - } F_BLK_HDR; - - typedef struct FlmBTreeBlkHdr - { - F_BLK_HDR stdBlkHdr; // Standard block header - FLMUINT16 ui16BtreeId; // BH_LOG_FILE_NUM - FLMUINT16 ui16NumKeys; // Number of keys - FLMUINT8 ui8BlkLevel; // BH_LEVEL - #define BH_MAX_LEVELS 8 // Max allowable b-tree levels - #define MAX_LEVELS BH_MAX_LEVELS - FLMUINT8 ui8BTreeFlags; // Flags for BTree - #define BLK_IS_ROOT 0x01 - #define BLK_IS_INDEX 0x02 - FLMUINT16 ui16HeapSize; // Contiguous available space - #define F_BTREE_BLK_HDR_stdBlkHdr_OFFSET 0 - #define F_BTREE_BLK_HDR_ui16BtreeId_OFFSET 32 - #define F_BTREE_BLK_HDR_ui16NumKeys_OFFSET 34 - #define F_BTREE_BLK_HDR_ui8BlkLevel_OFFSET 36 - #define F_BTREE_BLK_HDR_ui8BTreeFlags_OFFSET 37 - #define F_BTREE_BLK_HDR_ui16HeapSize_OFFSET 38 - } F_BTREE_BLK_HDR; - - enum BTREE_ERR_TYPE - { - NO_ERR = 0, // FYI: Visual Studio already defines NOERROR - BT_HEADER, - KEY_ORDER, - DUPLICATE_KEYS, - INFINITY_MARKER, - CHILD_BLOCK_ADDRESS, - SCA_GET_BLOCK_FAILED, - MISSING_OVERALL_DATA_LENGTH, - NOT_DATA_ONLY_BLOCK, - BAD_DO_BLOCK_LENGTHS, - BAD_COUNTS, - CATASTROPHIC_FAILURE = 999 - }; - - typedef struct - { - FLMUINT uiKeyCnt; - FLMUINT uiFirstKeyCnt; - FLMUINT uiBlkCnt; - FLMUINT uiBytesUsed; - FLMUINT uiDOBlkCnt; - FLMUINT uiDOBytesUsed; - } BTREE_LEVEL_STATS; - - typedef struct - { - FLMUINT uiBlkAddr; - FLMUINT uiBlockSize; - FLMUINT uiBlocksChecked; - FLMUINT uiAvgFreeSpace; - FLMUINT uiLevels; - FLMUINT uiNumKeys; - FLMUINT64 ui64FreeSpace; - BTREE_LEVEL_STATS LevelStats[ BH_MAX_LEVELS]; - char szMsg[ 64]; - BTREE_ERR_TYPE type; - } BTREE_ERR_STRUCT; - - typedef struct - { - FLMUINT uiParentLevel; - FLMUINT uiParentKeyLen; - FLMUINT uiParentChildBlkAddr; - FLMUINT uiNewKeyLen; - FLMUINT uiChildBlkAddr; - FLMUINT uiCounts; - void * pPrev; - FLMBYTE pucParentKey[ FLM_MAX_KEY_SIZE]; - FLMBYTE pucNewKey[ FLM_MAX_KEY_SIZE]; - } BTREE_REPLACE_STRUCT; - - typedef struct - { - F_BTREE_BLK_HDR * pBlkHdr; - IF_Block * pBlock; - const FLMBYTE * pucKeyBuf; - FLMUINT uiKeyBufSize; - FLMUINT uiKeyLen; - FLMUINT uiCurOffset; - FLMUINT uiLevel; - FLMUINT16 * pui16OffsetArray; - FLMUINT32 ui32BlkAddr; - } F_BTSK; - - typedef enum - { - ELM_INSERT_DO, - ELM_INSERT, - ELM_REPLACE_DO, - ELM_REPLACE, - ELM_REMOVE, - ELM_BLK_MERGE, - ELM_DONE - } F_ELM_UPD_ACTION; - - // Represent the maximum size for data & key before needing two bytes to - // store the length. - - #define ONE_BYTE_SIZE 0xFF - - // Flag definitions - BT_LEAF_DATA - - #define BTE_LEAF_DATA_OVHD 7 // Offset (2) Flags (1) OA Data (4) - - #define BTE_FLAG 0 // Offset to the FLAGS field - #define BTE_FLAG_LAST_ELEMENT 0x04 - #define BTE_FLAG_FIRST_ELEMENT 0x08 - #define BTE_FLAG_DATA_BLOCK 0x10 // Data is stored in a Data-only Block - #define BTE_FLAG_OA_DATA_LEN 0x20 // Overall data length - #define BTE_FLAG_DATA_LEN 0x40 - #define BTE_FLAG_KEY_LEN 0x80 - - // BT_LEAF (no data) - - #define BTE_LEAF_OVHD 4 // Offset (2) KeyLen (2) - #define BTE_KEY_LEN 0 - #define BTE_KEY_START 2 - - // BT_NON_LEAF_DATA - - #define BTE_NON_LEAF_OVHD 8 // Offset (2) Child Blk Addr (4) KeyLen (2) - #define BTE_NL_CHILD_BLOCK_ADDR 0 - #define BTE_NL_KEY_LEN 4 - #define BTE_NL_KEY_START 6 - - // BT_NON_LEAF_COUNTS - - #define BTE_NON_LEAF_COUNTS_OVHD 12 // Offset (2) Child Blk Addr (4) Counts (4) KeyLen (2) - #define BTE_NLC_CHILD_BLOCK_ADDR 0 - #define BTE_NLC_COUNTS 4 - #define BTE_NLC_KEY_LEN 8 - #define BTE_NLC_KEY_START 10 - - // Low water mark for coalescing blocks (as a percentage) - - #define BT_LOW_WATER_MARK 65 - - FINLINE FLMBOOL bteKeyLenFlag( - FLMBYTE * pucEntry) - { - return( (pucEntry[ BTE_FLAG] & BTE_FLAG_KEY_LEN) ? TRUE : FALSE); - } - - FINLINE FLMBOOL bteDataLenFlag( - FLMBYTE * pucEntry) - { - return( (pucEntry[ BTE_FLAG] & BTE_FLAG_DATA_LEN) ? TRUE : FALSE); - } - - FINLINE FLMBOOL bteOADataLenFlag( - FLMBYTE * pucEntry) - { - return( (pucEntry[ BTE_FLAG] & BTE_FLAG_OA_DATA_LEN) ? TRUE : FALSE); - } - - FINLINE FLMBOOL bteDataBlockFlag( - FLMBYTE * pucEntry) - { - return( (pucEntry[ BTE_FLAG] & BTE_FLAG_DATA_BLOCK) ? TRUE : FALSE); - } - - FINLINE FLMBOOL bteFirstElementFlag( - FLMBYTE * pucEntry) - { - return( (pucEntry[ BTE_FLAG] & BTE_FLAG_FIRST_ELEMENT) ? TRUE : FALSE); - } - - FINLINE FLMBOOL bteLastElementFlag( - FLMBYTE * pucEntry) - { - return( (pucEntry[ BTE_FLAG] & BTE_FLAG_LAST_ELEMENT) ? TRUE : FALSE); - } - - FINLINE FLMUINT32 bteGetBlkAddr( - const FLMBYTE * pucEntry) - { - return( FB2UD( pucEntry)); - } - - FINLINE void bteSetEntryOffset( - FLMUINT16 * pui16OffsetArray, - FLMUINT uiOffsetIndex, - FLMUINT ui16Offset) - { - UW2FBA( ui16Offset, (FLMBYTE *)&pui16OffsetArray[ uiOffsetIndex]); - } - - FINLINE FLMUINT16 bteGetEntryOffset( - const FLMUINT16 * pui16OffsetArray, - FLMUINT uiOffsetIndex) - { - return( FB2UW( (FLMBYTE *)&pui16OffsetArray[ uiOffsetIndex])); - } - /**************************************************************************** - Desc: Internal return code macros + Desc: Errors ****************************************************************************/ #ifdef FLM_DEBUG - RCODE flmMakeErr( + RCODE f_makeErr( RCODE rc, const char * pszFile, int iLine, FLMBOOL bAssert); #define RC_SET( rc) \ - flmMakeErr( rc, __FILE__, __LINE__, FALSE) + f_makeErr( rc, __FILE__, __LINE__, FALSE) #define RC_SET_AND_ASSERT( rc) \ - flmMakeErr( rc, __FILE__, __LINE__, TRUE) + f_makeErr( rc, __FILE__, __LINE__, TRUE) #define RC_UNEXPECTED_ASSERT( rc) \ - flmMakeErr( rc, __FILE__, __LINE__, TRUE) + f_makeErr( rc, __FILE__, __LINE__, TRUE) #else #define RC_SET( rc) (rc) #define RC_SET_AND_ASSERT( rc) (rc) #define RC_UNEXPECTED_ASSERT( rc) #endif - #define F_SEM_WAITFOREVER (0xFFFFFFFF) + RCODE MapPlatformError( + FLMINT iError, + RCODE defaultRc); /**************************************************************************** Desc: NLM @@ -487,62 +188,12 @@ extern "C" ERROR kMutexUnlock( MUTEX MutexHandle); - // External Netware Symbols - extern "C" FLMUINT f_getNLMHandle( void); extern "C" RCODE f_netwareStartup( void); extern "C" void f_netwareShutdown( void); -// #define f_stricmp(str1,str2) \ -// strcasecmp((char *)(str1),(char *)(str2)) -// -// #define f_strnicmp(str1,str2,size_t) \ -// strncasecmp((char *)(str1),(char *)(str2),size_t) -// -// #define f_memmove( dest, src, len) \ -// memmove( (void*)(dest), (void*)(src), len) -// -// #define f_memset( src, chr, size) \ -// memset((void *)(src),(chr),(size_t)(size)) -// -// #define f_memcmp( str1, str2, length) \ -// memcmp((void *)(str1), (void *)(str2),(size_t)(length)) -// -// #define f_strcat( dest, src) \ -// strcat( (char*)(dest), (char*)(src)) -// -// #define f_strchr( str, value) \ -// strchr( (char*)str, (int)value) -// -// #define f_strcmp( str1, str2) \ -// strcmp( (char*)(str1), (char*)(str2)) -// -// #define f_strcpy( dest, src) \ -// strcpy( (char*)(dest), (char*)(src)) -// -// #define f_strncpy( dest, src, length) \ -// strncpy( (char*)(dest), (char*)(src), (size_t)(length)) -// -// #define f_strlen( str) \ -// strlen( (char*)(str)) -// -// #define f_strncmp( str1, str2, size) \ -// strncmp( (char*)(str1), (char*)(str2), (size_t)(size)) -// -// #define f_strrchr( str, value ) \ -// strrchr( (char*)(str), (int)value) -// -// #define f_strstr( str1, str2) \ -// (char *)strstr( (char*)(str1), (char*)(str2)) -// -// #define f_strncat( str1, str2, n) \ -// strncat( (char *)(str1), (char *)(str2), n) -// -// #define f_strupr( str) \ -// strupr( (char *)(str)) - #endif /**************************************************************************** @@ -587,59 +238,10 @@ #define FSTATIC static #define ENDLINE ENDLINE_CRLF -// #define f_va_list va_list #define f_va_start va_start #define f_va_arg va_arg #define f_va_end va_end - -// #define f_stricmp( str1, str2) \ -// _stricmp((char *)(str1), (char *)(str2)) -// -// #define f_strnicmp( str1, str2, size) \ -// _strnicmp((char *)(str1), (char *)(str2),(size_t)(size)) -// -// #define f_memmove( dest, src, length) \ -// memmove((void *)(dest), (void *)(src),(size_t)(length)) -// -// #define f_memset( src, chr, size) \ -// memset((void *)(src),(chr),(size_t)(size)) -// -// #define f_memcmp( str1, str2, length) \ -// memcmp((void *)(str1), (void *)(str2),(size_t)(length)) -// -// #define f_strcat( dest, src) \ -// strcat( (char*)(dest), (char*)(src)) -// -// #define f_strchr( str, value) \ -// strchr( (char*)str, (int)value) -// -// #define f_strcmp( str1, str2) \ -// strcmp( (char*)(str1), (char*)(str2)) -// -// #define f_strcpy( dest, src) \ -// strcpy( (char*)(dest), (char*)(src)) -// -// #define f_strncpy( dest, src, length) \ -// strncpy( (char*)(dest), (char*)(src), (size_t)(length)) -// -// #define f_strlen( str) \ -// strlen( (char*)(str)) -// -// #define f_strncmp( str1, str2, size) \ -// strncmp( (char*)(str1), (char*)(str2), (size_t)(size)) -// -// #define f_strrchr( str, value ) \ -// strrchr( (char*)(str), (int)value) -// -// #define f_strstr( str1, str2) \ -// (char *)strstr( (char*)(str1), (char*)(str2)) -// -// #define f_strncat( str1, str2, n) \ -// strncat( (char *)(str1), (char *)(str2), n) -// -// #define f_strupr( str) \ -// _strupr( (char *)(str)) - + #endif /**************************************************************************** @@ -696,62 +298,13 @@ #include #endif -// #define f_stricmp(str1,str2) \ -// strcasecmp((char *)(str1),(char *)(str2)) -// -// #define f_strnicmp(str1,str2,size_t) \ -// strncasecmp((char *)(str1),(char *)(str2),size_t) -// -// #define f_memmove( dest, src, len) \ -// memmove( (void*)(dest), (void*)(src), len) -// -// #define f_memset( src, chr, size) \ -// memset((void *)(src),(chr),(size_t)(size)) -// -// #define f_memcmp( str1, str2, length) \ -// memcmp((void *)(str1), (void *)(str2),(size_t)(length)) -// -// #define f_strcat( dest, src) \ -// strcat( (char*)(dest), (char*)(src)) -// -// #define f_strchr( str, value) \ -// strchr( (char*)str, (int)value) -// -// #define f_strcmp( str1, str2) \ -// strcmp( (char*)(str1), (char*)(str2)) -// -// #define f_strcpy( dest, src) \ -// strcpy( (char*)(dest), (char*)(src)) -// -// #define f_strncpy( dest, src, length) \ -// strncpy( (char*)(dest), (char*)(src), (size_t)(length)) -// -// #define f_strlen( str) \ -// strlen( (char*)(str)) -// -// #define f_strncmp( str1, str2, size) \ -// strncmp( (char*)(str1), (char*)(str2), (size_t)(size)) -// -// #define f_strrchr( str, value ) \ -// strrchr( (char*)(str), (int)value) -// -// #define f_strstr( str1, str2) \ -// (char *)strstr( (char*)(str1), (char*)(str2)) -// -// #define f_strncat( str1, str2, n) \ -// strncat( (char *)(str1), (char *)(str2), n) -// -// #define f_strupr( str) \ -// strupr( (char *)(str)) - -// #define f_va_list va_list #define f_va_start va_start #define f_va_arg va_arg #define f_va_end va_end -// typedef pthread_mutex_t * F_MUTEX; -// typedef F_MUTEX * F_MUTEX_p; -// #define F_MUTEX_NULL NULL + typedef pthread_mutex_t * F_MUTEX; + typedef F_MUTEX * F_MUTEX_p; + #define F_MUTEX_NULL NULL typedef struct { @@ -770,22 +323,138 @@ #endif /**************************************************************************** - Desc: Cross-platform inline functions + Desc: ****************************************************************************/ -// FINLINE void f_memcpy( -// void * pvDest, -// const void * pvSrc, -// FLMSIZET iSize) -// { -// if( iSize == 1) -// { -// *((FLMBYTE *)pvDest) = *((FLMBYTE *)pvSrc); -// } -// else -// { -// (void)memcpy( pvDest, pvSrc, iSize); -// } -// } + FINLINE void * FLMAPI f_memcpy( + void * pvDest, + const void * pvSrc, + FLMSIZET iSize) + { + if( iSize == 1) + { + *((FLMBYTE *)pvDest) = *((FLMBYTE *)pvSrc); + return( pvDest); + } + else + { + return( memcpy( pvDest, pvSrc, iSize)); + } + } + + /**************************************************************************** + Desc: + ****************************************************************************/ + FINLINE void * FLMAPI f_memmove( + void * pvDest, + const void * pvSrc, + FLMSIZET uiLength) + { + return( memmove( pvDest, pvSrc, uiLength)); + } + + /**************************************************************************** + Desc: + ****************************************************************************/ + FINLINE void * FLMAPI f_memset( + void * pvDest, + unsigned char ucByte, + FLMSIZET uiLength) + { + return( memset( pvDest, ucByte, uiLength)); + } + + /**************************************************************************** + Desc: + ****************************************************************************/ + FINLINE FLMINT FLMAPI f_memcmp( + const void * pvMem1, + const void * pvMem2, + FLMSIZET uiLength) + { + return( memcmp( pvMem1, pvMem2, uiLength)); + } + + /**************************************************************************** + Desc: + ****************************************************************************/ + FINLINE char * FLMAPI f_strcpy( + char * pszDest, + const char * pszSrc) + { + return( strcpy( pszDest, pszSrc)); + } + + /**************************************************************************** + Desc: + ****************************************************************************/ + FINLINE FLMINT FLMAPI f_strlen( + const char * pszStr) + { + return( strlen( pszStr)); + } + + /**************************************************************************** + Desc: + ****************************************************************************/ + FINLINE FLMINT FLMAPI f_strcmp( + const char * pvStr1, + const char * pvStr2) + { + return( strcmp( pvStr1, pvStr2)); + } + + /**************************************************************************** + Desc: + ****************************************************************************/ + FINLINE FLMINT FLMAPI f_stricmp( + const char * pvStr1, + const char * pvStr2) + { + return( _stricmp( pvStr1, pvStr2)); + } + + /**************************************************************************** + Desc: + ****************************************************************************/ + FINLINE FLMINT FLMAPI f_strncmp( + const char * pvStr1, + const char * pvStr2, + FLMSIZET uiLength) + { + return( strncmp( pvStr1, pvStr2, uiLength)); + } + + /**************************************************************************** + Desc: + ****************************************************************************/ + FINLINE FLMINT FLMAPI f_strnicmp( + const char * pvStr1, + const char * pvStr2, + FLMSIZET uiLength) + { + return( _strnicmp( pvStr1, pvStr2, uiLength)); + } + +// #define f_strcat( dest, src) \ +// strcat( (char*)(dest), (char*)(src)) +// +// #define f_strchr( str, value) \ +// strchr( (char*)str, (int)value) +// +// #define f_strncpy( dest, src, length) \ +// strncpy( (char*)(dest), (char*)(src), (size_t)(length)) +// +// #define f_strrchr( str, value ) \ +// strrchr( (char*)(str), (int)value) +// +// #define f_strstr( str1, str2) \ +// (char *)strstr( (char*)(str1), (char*)(str2)) +// +// #define f_strncat( str1, str2, n) \ +// strncat( (char *)(str1), (char *)(str2), n) +// +// #define f_strupr( str) \ +// _strupr( (char *)(str)) #if defined( __va_copy) #define f_va_copy(to, from) __va_copy(to, from) @@ -793,15 +462,6 @@ #define f_va_copy(to, from) ((to) = (from)) #endif - typedef struct IniLine - { - char * pszParamName; - char * pszParamValue; - char * pszComment; - struct IniLine * pPrev; - struct IniLine * pNext; - } INI_LINE; - /**************************************************************************** Desc: Internal base class ****************************************************************************/ @@ -912,162 +572,27 @@ }; /**************************************************************************** - Desc: This class is used to do pool memory allocations. - ****************************************************************************/ - class F_Pool : public IF_Pool, public F_Base - { - public: - - typedef struct PoolMemoryBlock - { - PoolMemoryBlock * pPrevBlock; - FLMUINT uiBlockSize; - FLMUINT uiFreeOffset; - FLMUINT uiFreeSize; - } MBLK; - - typedef struct - { - FLMUINT uiAllocBytes; - FLMUINT uiCount; - } POOL_STATS; - - F_Pool() - { - m_uiBytesAllocated = 0; - m_pLastBlock = NULL; - m_pPoolStats = NULL; - m_uiBlockSize = 0; - } - - virtual ~F_Pool(); - - FINLINE void FLMAPI poolInit( - FLMUINT uiBlockSize) - { - m_uiBlockSize = uiBlockSize; - } - - void smartPoolInit( - POOL_STATS * pPoolStats); - - RCODE FLMAPI poolAlloc( - FLMUINT uiSize, - void ** ppvPtr); - - RCODE FLMAPI poolCalloc( - FLMUINT uiSize, - void ** ppvPtr); - - void FLMAPI poolFree( void); - - void FLMAPI poolReset( - void * pvMark, - FLMBOOL bReduceFirstBlock = FALSE); - - FINLINE void * FLMAPI poolMark( void) - { - return (void *)(m_pLastBlock - ? (FLMBYTE *)m_pLastBlock + m_pLastBlock->uiFreeOffset - : NULL); - } - - FINLINE FLMUINT FLMAPI getBlockSize( void) - { - return( m_uiBlockSize); - } - - FINLINE FLMUINT FLMAPI getBytesAllocated( void) - { - return( m_uiBytesAllocated); - } - - private: - - FINLINE void updateSmartPoolStats( void) - { - if (m_uiBytesAllocated) - { - if( (m_pPoolStats->uiAllocBytes + m_uiBytesAllocated) >= 0xFFFF0000) - { - m_pPoolStats->uiAllocBytes = - (m_pPoolStats->uiAllocBytes / m_pPoolStats->uiCount) * 100; - m_pPoolStats->uiCount = 100; - } - else - { - m_pPoolStats->uiAllocBytes += m_uiBytesAllocated; - m_pPoolStats->uiCount++; - } - m_uiBytesAllocated = 0; - } - } - - FINLINE void setInitialSmartPoolBlkSize( void) - { - // Determine starting block size: - // 1) average of bytes allocated / # of frees/resets (average size needed) - // 2) add 10% - to minimize extra allocs - - m_uiBlockSize = (m_pPoolStats->uiAllocBytes / m_pPoolStats->uiCount); - m_uiBlockSize += (m_uiBlockSize / 10); - - if (m_uiBlockSize < 512) - { - m_uiBlockSize = 512; - } - } - - void freeToMark( - void * pvMark); - - PoolMemoryBlock * m_pLastBlock; - FLMUINT m_uiBlockSize; - FLMUINT m_uiBytesAllocated; - POOL_STATS * m_pPoolStats; - }; - - /**************************************************************************** - FLAIM's Assert Layer - - This section contains prototypes and macros for FLAIM's assert. This layer - enables FLAIM to redirect assert calls. + Desc: Asserts ****************************************************************************/ #ifdef FLM_DEBUG - #ifdef FLM_DBG_LOG - void flmDbgLogFlush( void); - #endif - #if defined( FLM_WIN) - #ifdef FLM_DBG_LOG - #define flmAssert( exp) \ - (void)( (exp) || (flmDbgLogFlush(), DebugBreak(), 0)) - #else - #define flmAssert( exp) \ - (void)( (exp) || (DebugBreak(), 0)) - #endif + + #define flmAssert( exp) \ + (void)( (exp) || (DebugBreak(), 0)) #elif defined( FLM_NLM) + extern "C" void EnterDebugger(void); - #ifdef FLM_DBG_LOG - #define flmAssert( exp) \ - (void)( (exp) || (flmDbgLogFlush(), EnterDebugger(), 0)) - #else - #define flmAssert( exp) \ - (void)( (exp) || ( EnterDebugger(), 0)) - #endif + #define flmAssert( exp) \ + (void)( (exp) || ( EnterDebugger(), 0)) #elif defined( FLM_UNIX) - #ifdef FLM_DBG_LOG - #define flmAssert( exp) \ - (void)( (exp) || (flmDbgLogFlush(), assert(0), 0)) - #else - #define flmAssert( exp) \ - (void)( (exp) || (assert(0), 0)) - #endif + + #define flmAssert( exp) \ + (void)( (exp) || (assert(0), 0)) #else #define flmAssert( exp) @@ -1077,1393 +602,464 @@ #define flmAssert( exp) #endif - FLMUINT f_breakpoint( - FLMUINT uiBreakFlag); - - /**************************************************************************** - Random Numbers - ****************************************************************************/ - - #define MAX_RANDOM 2147483646L - - class F_RandomGenerator : public IF_RandomGenerator, public F_Base + /********************************************************************** + Desc: + **********************************************************************/ + #if defined( FLM_SOLARIS) && defined( FLM_SPARC) && !defined( FLM_GNUC) + extern "C" FLMINT32 sparc_atomic_add_32( + volatile FLMINT32 * piTarget, + FLMINT32 iDelta); + #endif + + /********************************************************************** + Desc: + **********************************************************************/ + #if defined( FLM_SOLARIS) && defined( FLM_SPARC) && !defined( FLM_GNUC) + extern "C" FLMINT32 sparc_atomic_xchg_32( + volatile FLMINT32 * piTarget, + FLMINT32 iNewValue); + #endif + + /********************************************************************** + Desc: + **********************************************************************/ + #if defined( FLM_AIX) + FINLINE int aix_atomic_add( + volatile int * piTarget, + int iDelta) { - public: - - void FLMAPI randomize( void); - - void FLMAPI setSeed( - FLMINT32 i32seed); - - FLMINT32 FLMAPI getInt32( void); - - FLMINT32 FLMAPI getInt32( - FLMINT32 i32Low, - FLMINT32 i32High); - - FLMBOOL FLMAPI getBoolean( void); - - FLMINT32 FLMAPI getSeed( void) + return( fetch_and_add( (int *)piTarget, iDelta) + iDelta); + } + #endif + + /********************************************************************** + Desc: + **********************************************************************/ + #if defined( FLM_UNIX) + extern "C" FLMINT32 posix_atomic_add_32( + volatile FLMINT32 * piTarget, + FLMINT32 iDelta); + #endif + + /********************************************************************** + Desc: + **********************************************************************/ + #if defined( FLM_UNIX) + extern "C" FLMINT32 posix_atomic_xchg_32( + volatile FLMINT32 * piTarget, + FLMINT32 iNewValue); + #endif + + /********************************************************************** + Desc: + **********************************************************************/ + FINLINE FLMINT32 FLMAPI f_atomicInc( + FLMATOMIC * piTarget) + { + #if defined( FLM_NLM) { - return( m_i32Seed); + return( (FLMINT32)nlm_AtomicIncrement( (volatile LONG *)piTarget)); } + #elif defined( FLM_WIN) + { + return( (FLMINT32)InterlockedIncrement( (volatile LONG *)piTarget)); + } + #elif defined( FLM_AIX) + { + return( (FLMINT32)aix_atomic_add( piTarget, 1)); + } + #elif defined( FLM_OSX) + { + return( (FLMINT32)OSAtomicIncrement32( (int32_t *)piTarget)); + } + #elif defined( FLM_SOLARIS) && defined( FLM_SPARC) && !defined( FLM_GNUC) + { + return( sparc_atomic_add_32( piTarget, 1)); + } + #elif (defined( __i386__) || defined( __x86_64__)) && defined( FLM_GNUC) + { + FLMINT32 i32Tmp; + + __asm__ __volatile__ ( + "lock;" + "xaddl %0, %1" + : "=r" (i32Tmp), "=m" (*piTarget) + : "0" (1), "m" (*piTarget)); + + return( i32Tmp + 1); + } + #elif defined( FLM_UNIX) + return( posix_atomic_add_32( piTarget, 1)); + #else + #error Atomic operations aren't supported + #endif + } + + /********************************************************************** + Desc: + **********************************************************************/ + FINLINE FLMINT32 FLMAPI f_atomicDec( + FLMATOMIC * piTarget) + { + #if defined( FLM_NLM) + { + return( (FLMINT32)nlm_AtomicDecrement( (volatile LONG *)piTarget)); + } + #elif defined( FLM_WIN) + { + return( (FLMINT32)InterlockedDecrement( (volatile LONG *)piTarget)); + } + #elif defined( FLM_AIX) + { + return( (FLMINT32)aix_atomic_add( piTarget, -1)); + } + #elif defined( FLM_OSX) + { + return( (FLMINT32)OSAtomicDecrement32( (int32_t *)piTarget)); + } + #elif defined( FLM_SOLARIS) && defined( FLM_SPARC) && !defined( FLM_GNUC) + { + return( sparc_atomic_add_32( piTarget, -1)); + } + #elif (defined( __i386__) || defined( __x86_64__)) && defined( FLM_GNUC) + { + FLMINT32 i32Tmp; + + __asm__ __volatile__ ( + "lock;" + "xaddl %0, %1" + : "=r" (i32Tmp), "=m" (*piTarget) + : "0" (-1), "m" (*piTarget)); + + return( i32Tmp - 1); + } + #elif defined( FLM_UNIX) + return( posix_atomic_add_32( piTarget, -1)); + #else + #error Atomic operations aren't supported + #endif + } + + /********************************************************************** + Desc: + **********************************************************************/ + FINLINE FLMINT32 FLMAPI f_atomicExchange( + FLMATOMIC * piTarget, + FLMINT32 i32NewVal) + { + #if defined( FLM_NLM) + { + return( (FLMINT32)nlm_AtomicExchange( + (volatile LONG *)piTarget, i32NewVal)); + } + #elif defined( FLM_WIN) + { + return( (FLMINT32)InterlockedExchange( (volatile LONG *)piTarget, + i32NewVal)); + } + #elif defined( FLM_AIX) + { + int iOldVal; + + for( ;;) + { + iOldVal = (int)*piTarget; + + if( compare_and_swap( (int *)piTarget, &iOldVal, i32NewVal)) + { + break; + } + } + + return( (FLMINT32)iOldVal); + } + #elif defined( FLM_OSX) + { + int32_t iOldVal; - private: + for( ;;) + { + iOldVal = (int32_t)*piTarget; - FLMINT32 m_i32Seed; - }; - -// /********************************************************************** -// Desc: Atomic Increment, Decrement, Exchange -// Note: Some of this code is derived from the Ximian source code contained -// in that Mono project's atomic.h file. -// **********************************************************************/ -// #ifndef FLM_HAVE_ATOMICS -// #define FLM_HAVE_ATOMICS -// #endif -// -// /********************************************************************** -// Desc: -// **********************************************************************/ -// #if defined( FLM_SOLARIS) && defined( FLM_SPARC) && !defined( FLM_GNUC) -// extern "C" FLMINT32 sparc_atomic_add_32( -// volatile FLMINT32 * piTarget, -// FLMINT32 iDelta); -// #endif -// -// /********************************************************************** -// Desc: -// **********************************************************************/ -// #if defined( FLM_SOLARIS) && defined( FLM_SPARC) && !defined( FLM_GNUC) -// extern "C" FLMINT32 sparc_atomic_xchg_32( -// volatile FLMINT32 * piTarget, -// FLMINT32 iNewValue); -// #endif -// -// /********************************************************************** -// Desc: -// **********************************************************************/ -// #if defined( FLM_AIX) -// FINLINE int aix_atomic_add( -// volatile int * piTarget, -// int iDelta) -// { -// return( fetch_and_add( (int *)piTarget, iDelta) + iDelta); -// } -// #endif -// -// /********************************************************************** -// Desc: -// **********************************************************************/ -// FINLINE FLMINT32 _flmAtomicInc( -// FLMATOMIC * piTarget) -// { -// #if defined( FLM_NLM) -// { -// return( (FLMINT32)nlm_AtomicIncrement( (volatile LONG *)piTarget)); -// } -// #elif defined( FLM_WIN) -// { -// return( (FLMINT32)InterlockedIncrement( (volatile LONG *)piTarget)); -// } -// #elif defined( FLM_AIX) -// { -// return( (FLMINT32)aix_atomic_add( piTarget, 1)); -// } -// #elif defined( FLM_OSX) -// { -// return( (FLMINT32)OSAtomicIncrement32( (int32_t *)piTarget)); -// } -// #elif defined( FLM_SOLARIS) && defined( FLM_SPARC) && !defined( FLM_GNUC) -// { -// return( sparc_atomic_add_32( piTarget, 1)); -// } -// #elif (defined( __i386__) || defined( __x86_64__)) && defined( FLM_GNUC) -// { -// FLMINT32 i32Tmp; -// -// __asm__ __volatile__ ( -// "lock;" -// "xaddl %0, %1" -// : "=r" (i32Tmp), "=m" (*piTarget) -// : "0" (1), "m" (*piTarget)); -// -// return( i32Tmp + 1); -// } -// #else -// #ifdef FLM_HAVE_ATOMICS -// #undef FLM_HAVE_ATOMICS -// #endif -// -// F_UNREFERENCED_PARM( piTarget); -// -// flmAssert( 0); -// return( 0); -// #endif -// } -// -// /********************************************************************** -// Desc: -// **********************************************************************/ -// FINLINE FLMINT32 _flmAtomicDec( -// FLMATOMIC * piTarget) -// { -// #if defined( FLM_NLM) -// { -// return( (FLMINT32)nlm_AtomicDecrement( (volatile LONG *)piTarget)); -// } -// #elif defined( FLM_WIN) -// { -// return( (FLMINT32)InterlockedDecrement( (volatile LONG *)piTarget)); -// } -// #elif defined( FLM_AIX) -// { -// return( (FLMINT32)aix_atomic_add( piTarget, -1)); -// } -// #elif defined( FLM_OSX) -// { -// return( (FLMINT32)OSAtomicDecrement32( (int32_t *)piTarget)); -// } -// #elif defined( FLM_SOLARIS) && defined( FLM_SPARC) && !defined( FLM_GNUC) -// { -// return( sparc_atomic_add_32( piTarget, -1)); -// } -// #elif (defined( __i386__) || defined( __x86_64__)) && defined( FLM_GNUC) -// { -// FLMINT32 i32Tmp; -// -// __asm__ __volatile__ ( -// "lock;" -// "xaddl %0, %1" -// : "=r" (i32Tmp), "=m" (*piTarget) -// : "0" (-1), "m" (*piTarget)); -// -// return( i32Tmp - 1); -// } -// #else -// #ifdef FLM_HAVE_ATOMICS -// #undef FLM_HAVE_ATOMICS -// #endif -// -// F_UNREFERENCED_PARM( piTarget); -// -// flmAssert( 0); -// return( 0); -// #endif -// } -// -// /********************************************************************** -// Desc: -// **********************************************************************/ -// FINLINE FLMINT32 _flmAtomicExchange( -// FLMATOMIC * piTarget, -// FLMINT32 i32NewVal) -// { -// #if defined( FLM_NLM) -// { -// return( (FLMINT32)nlm_AtomicExchange( -// (volatile LONG *)piTarget, i32NewVal)); -// } -// #elif defined( FLM_WIN) -// { -// return( (FLMINT32)InterlockedExchange( (volatile LONG *)piTarget, -// i32NewVal)); -// } -// #elif defined( FLM_AIX) -// { -// int iOldVal; -// -// for( ;;) -// { -// iOldVal = (int)*piTarget; -// -// if( compare_and_swap( (int *)piTarget, &iOldVal, i32NewVal)) -// { -// break; -// } -// } -// -// return( (FLMINT32)iOldVal); -// } -// #elif defined( FLM_OSX) -// { -// int32_t iOldVal; -// -// for( ;;) -// { -// iOldVal = (int32_t)*piTarget; -// -// if( OSAtomicCompareAndSwap32( iOldVal, i32NewVal, -// (int32_t *)piTarget)) -// { -// break; -// } -// } -// -// return( (FLMINT32)iOldVal); -// } -// #elif defined( FLM_SOLARIS) && defined( FLM_SPARC) && !defined( FLM_GNUC) -// { -// return( sparc_atomic_xchg_32( piTarget, i32NewVal)); -// } -// #elif (defined( __i386__) || defined( __x86_64__)) && defined( FLM_GNUC) -// { -// FLMINT32 i32OldVal; -// -// __asm__ __volatile__ ( -// "1: lock;" -// " cmpxchgl %2, %0;" -// " jne 1b" -// : "=m" (*piTarget), "=a" (i32OldVal) -// : "r" (i32NewVal), "m" (*piTarget), "a" (*piTarget)); -// -// return( i32OldVal); -// } -// #else -// #ifdef FLM_HAVE_ATOMICS -// #undef FLM_HAVE_ATOMICS -// #endif -// -// F_UNREFERENCED_PARM( piTarget); -// F_UNREFERENCED_PARM( i32NewVal); -// -// flmAssert( 0); -// return( 0); -// #endif -// } -// -// /********************************************************************** -// Desc: -// **********************************************************************/ -// FINLINE FLMINT32 flmAtomicInc( -// FLMATOMIC * piTarget, -// F_MUTEX hMutex = F_MUTEX_NULL, -// FLMBOOL bMutexAlreadyLocked = FALSE) -// { -// #ifdef FLM_HAVE_ATOMICS -// { -// F_UNREFERENCED_PARM( bMutexAlreadyLocked); -// F_UNREFERENCED_PARM( hMutex); -// -// return( _flmAtomicInc( piTarget)); -// } -// #else -// { -// FLMINT32 i32NewVal; -// -// flmAssert( hMutex != F_MUTEX_NULL); -// -// if( !bMutexAlreadyLocked) -// { -// f_mutexLock( hMutex); -// } -// -// i32NewVal = (FLMINT32)(++(*piTarget)); -// -// if( !bMutexAlreadyLocked) -// { -// f_mutexUnlock( hMutex); -// } -// -// return( i32NewVal); -// } -// #endif -// } -// -// /********************************************************************** -// Desc: -// **********************************************************************/ -// FINLINE FLMINT32 flmAtomicDec( -// FLMATOMIC * piTarget, -// F_MUTEX hMutex = F_MUTEX_NULL, -// FLMBOOL bMutexAlreadyLocked = FALSE) -// { -// #ifdef FLM_HAVE_ATOMICS -// { -// F_UNREFERENCED_PARM( bMutexAlreadyLocked); -// F_UNREFERENCED_PARM( hMutex); -// -// return( _flmAtomicDec( piTarget)); -// } -// #else -// { -// FLMINT32 i32NewVal; -// -// flmAssert( hMutex != F_MUTEX_NULL); -// -// if( !bMutexAlreadyLocked) -// { -// f_mutexLock( hMutex); -// } -// -// i32NewVal = (FLMINT32)(--(*piTarget)); -// -// if( !bMutexAlreadyLocked) -// { -// f_mutexUnlock( hMutex); -// } -// -// return( i32NewVal); -// } -// #endif -// } -// -// /********************************************************************** -// Desc: -// **********************************************************************/ -// FINLINE FLMINT32 flmAtomicExchange( -// FLMATOMIC * piTarget, -// FLMINT32 i32NewVal, -// F_MUTEX hMutex = F_MUTEX_NULL, -// FLMBOOL bMutexAlreadyLocked = FALSE) -// { -// #ifdef FLM_HAVE_ATOMICS -// { -// F_UNREFERENCED_PARM( bMutexAlreadyLocked); -// F_UNREFERENCED_PARM( hMutex); -// -// return( _flmAtomicExchange( piTarget, i32NewVal)); -// } -// #else -// { -// FLMINT32 i32OldVal; -// -// flmAssert( hMutex != F_MUTEX_NULL); -// -// if( !bMutexAlreadyLocked) -// { -// f_mutexLock( hMutex); -// } -// -// i32OldVal = (FLMINT32)*piTarget; -// *piTarget = i32NewVal; -// -// if( !bMutexAlreadyLocked) -// { -// f_mutexUnlock( hMutex); -// } -// -// return( i32OldVal); -// } -// #endif -// } + if( OSAtomicCompareAndSwap32( iOldVal, i32NewVal, + (int32_t *)piTarget)) + { + break; + } + } + + return( (FLMINT32)iOldVal); + } + #elif defined( FLM_SOLARIS) && defined( FLM_SPARC) && !defined( FLM_GNUC) + { + return( sparc_atomic_xchg_32( piTarget, i32NewVal)); + } + #elif (defined( __i386__) || defined( __x86_64__)) && defined( FLM_GNUC) + { + FLMINT32 i32OldVal; + + __asm__ __volatile__ ( + "1: lock;" + " cmpxchgl %2, %0;" + " jne 1b" + : "=m" (*piTarget), "=a" (i32OldVal) + : "r" (i32NewVal), "m" (*piTarget), "a" (*piTarget)); + + return( i32OldVal); + } + #elif defined( FLM_UNIX) + return( posix_atomic_xchg_32( piTarget, i32NewVal)); + #else + #error Atomic operations aren't supported + #endif + } /**************************************************************************** Desc: Mutex and semaphore routines ****************************************************************************/ -// #ifdef FLM_NLM -// FINLINE RCODE f_mutexCreate( -// F_MUTEX * phMutex) -// { -// if( (*phMutex = (F_MUTEX)kMutexAlloc( (BYTE *)"NOVDB")) == F_MUTEX_NULL) -// { -// return RC_SET( NE_FLM_MEM); -// } -// -// return NE_FLM_OK; -// } -// -// FINLINE void f_mutexDestroy( -// F_MUTEX * phMutex) -// { -// if (*phMutex != F_MUTEX_NULL) -// { -// if( kMutexFree( (MUTEX)(*phMutex))) -// { -// flmAssert( 0); -// } -// -// *phMutex = F_MUTEX_NULL; -// } -// } -// -// FINLINE void f_mutexLock( -// F_MUTEX hMutex) -// { -// (void)kMutexLock( (MUTEX)hMutex); -// } -// -// FINLINE void f_mutexUnlock( -// F_MUTEX hMutex) -// { -// (void)kMutexUnlock( (MUTEX)hMutex); -// } -// -// FINLINE void f_assertMutexLocked( -// F_MUTEX) -// { -// } -// -// typedef SEMAPHORE F_SEM; -// typedef SEMAPHORE * F_SEM_p; -// #define F_SEM_NULL 0 -// -// FINLINE RCODE f_semCreate( -// F_SEM * phSem) -// { -// if( (*phSem = (F_SEM)kSemaphoreAlloc( (BYTE *)"NOVDB", 0)) == F_SEM_NULL) -// { -// return RC_SET( NE_FLM_MEM); -// } -// -// return NE_FLM_OK; -// } -// -// FINLINE void f_semDestroy( -// F_SEM * phSem) -// { -// if (*phSem != F_SEM_NULL) -// { -// (void)kSemaphoreFree( (SEMAPHORE)(*phSem)); -// *phSem = F_SEM_NULL; -// } -// } -// -// FINLINE RCODE f_semWait( -// F_SEM hSem, -// FLMUINT uiTimeout) -// { -// RCODE rc = NE_FLM_OK; -// -// if( uiTimeout == F_SEM_WAITFOREVER) -// { -// if( kSemaphoreWait( (SEMAPHORE)hSem) != 0) -// { -// rc = RC_SET( NE_FLM_ERROR_WAITING_ON_SEMPAHORE); -// } -// } -// else -// { -// if( kSemaphoreTimedWait( (SEMAPHORE)hSem, (UINT)uiTimeout) != 0) -// { -// rc = RC_SET( NE_FLM_ERROR_WAITING_ON_SEMPAHORE); -// } -// } -// -// return( rc); -// } -// -// FINLINE void f_semSignal( -// F_SEM hSem) -// { -// (void)kSemaphoreSignal( (SEMAPHORE)hSem); -// } -// -// #elif defined( FLM_WIN) -// -// RCODE f_mutexCreate( -// F_MUTEX * phMutex); -// -// void f_mutexDestroy( -// F_MUTEX * phMutex); -// -// FINLINE void f_mutexLock( -// F_MUTEX hMutex) -// { -// while( flmAtomicExchange( -// &(((F_INTERLOCK *)hMutex)->locked), 1) != 0) -// { -// #ifdef FLM_DEBUG -// flmAtomicInc( &(((F_INTERLOCK *)hMutex)->waitCount)); -// #endif -// Sleep( 0); -// } -// -// #ifdef FLM_DEBUG -// flmAssert( ((F_INTERLOCK *)hMutex)->uiThreadId == 0); -// ((F_INTERLOCK *)hMutex)->uiThreadId = _threadid; -// flmAtomicInc( &(((F_INTERLOCK *)hMutex)->lockedCount)); -// #endif -// } -// -// FINLINE void f_mutexUnlock( -// F_MUTEX hMutex) -// { -// flmAssert( ((F_INTERLOCK *)hMutex)->locked == 1); -// #ifdef FLM_DEBUG -// flmAssert( ((F_INTERLOCK *)hMutex)->uiThreadId == _threadid); -// ((F_INTERLOCK *)hMutex)->uiThreadId = 0; -// #endif -// flmAtomicExchange( &(((F_INTERLOCK *)hMutex)->locked), 0); -// } -// -// FINLINE void f_assertMutexLocked( -// F_MUTEX hMutex) -// { -// #ifdef FLM_DEBUG -// flmAssert( ((F_INTERLOCK *)hMutex)->locked == 1); -// flmAssert( ((F_INTERLOCK *)hMutex)->uiThreadId == _threadid); -// #else -// F_UNREFERENCED_PARM( hMutex); -// #endif -// } -// -// FINLINE RCODE f_semCreate( -// F_SEM * phSem) -// { -// if( (*phSem = CreateSemaphore( (LPSECURITY_ATTRIBUTES)NULL, -// 0, 10000, NULL )) == NULL) -// { -// return( RC_SET( NE_FLM_COULD_NOT_CREATE_SEMAPHORE)); -// } -// -// return NE_FLM_OK; -// } -// -// FINLINE void f_semDestroy( -// F_SEM * phSem) -// { -// if (*phSem != F_SEM_NULL) -// { -// CloseHandle( *phSem); -// *phSem = F_SEM_NULL; -// } -// } -// -// FINLINE RCODE f_semWait( -// F_SEM hSem, -// FLMUINT uiTimeout) -// { -// if( WaitForSingleObject( hSem, uiTimeout ) == WAIT_OBJECT_0) -// { -// return( NE_FLM_OK); -// } -// else -// { -// return( RC_SET( NE_FLM_ERROR_WAITING_ON_SEMPAHORE)); -// } -// } -// -// FINLINE void f_semSignal( -// F_SEM hSem) -// { -// (void)ReleaseSemaphore( hSem, 1, NULL); -// } -// #elif defined( FLM_UNIX) -// RCODE f_mutexCreate( -// F_MUTEX * phMutex); -// -// void f_mutexDestroy( -// F_MUTEX * phMutex); -// -// FINLINE void f_mutexLock( -// F_MUTEX hMutex) -// { -// (void)pthread_mutex_lock( hMutex); -// } -// -// FINLINE void f_mutexUnlock( -// F_MUTEX hMutex) -// { -// (void)pthread_mutex_unlock( hMutex); -// } -// -// FINLINE void f_assertMutexLocked( -// F_MUTEX) -// { -// } -// -// int sema_signal( -// sema_t * sem); -// -// void f_semDestroy( -// F_SEM * phSem); -// -// RCODE f_semCreate( -// F_SEM * phSem); -// -// RCODE f_semWait( -// F_SEM hSem, -// FLMUINT uiTimeout); -// -// FINLINE void f_semSignal( -// F_SEM hSem) -// { -// (void)sema_signal( hSem); -// } -// -// #endif - - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_IStream : public IF_IStream, public F_Base - { - public: - - F_IStream(); - - virtual ~F_IStream(); - }; - - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_OStream : public IF_OStream, public F_Base - { - public: - - F_OStream(); - - virtual ~F_OStream(); - - }; - - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_PosIStream : public IF_PosIStream, public F_Base - { - public: - - F_PosIStream(); - - virtual ~F_PosIStream(); - - }; - - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_BufferIStream : public F_PosIStream - { - public: - - F_BufferIStream() + #ifdef FLM_NLM + FINLINE RCODE FLMAPI f_mutexCreate( + F_MUTEX * phMutex) { - m_pucBuffer = NULL; - m_uiBufferLen = 0; - m_uiOffset = 0; - m_bAllocatedBuffer = FALSE; - m_bIsOpen = FALSE; - } - - virtual ~F_BufferIStream(); - - RCODE FLMAPI open( - const FLMBYTE * pucBuffer, - FLMUINT uiLength, - FLMBYTE ** ppucAllocatedBuffer = NULL); - - FINLINE FLMUINT64 FLMAPI totalSize( void) - { - flmAssert( m_bIsOpen); - return( m_uiBufferLen); - } - - FINLINE FLMUINT64 FLMAPI remainingSize( void) - { - flmAssert( m_bIsOpen); - return( m_uiBufferLen - m_uiOffset); - } - - RCODE FLMAPI close( void); - - FINLINE RCODE FLMAPI positionTo( - FLMUINT64 ui64Position) - { - flmAssert( m_bIsOpen); - - if( ui64Position < m_uiBufferLen) + if( (*phMutex = (F_MUTEX)kMutexAlloc( (BYTE *)"NOVDB")) == F_MUTEX_NULL) { - m_uiOffset = (FLMUINT)ui64Position; + return RC_SET( NE_FLM_MEM); + } + + return NE_FLM_OK; + } + + FINLINE void FLMAPI f_mutexDestroy( + F_MUTEX * phMutex) + { + if (*phMutex != F_MUTEX_NULL) + { + if( kMutexFree( (MUTEX)(*phMutex))) + { + flmAssert( 0); + } + + *phMutex = F_MUTEX_NULL; + } + } + + FINLINE void FLMAPI f_mutexLock( + F_MUTEX hMutex) + { + (void)kMutexLock( (MUTEX)hMutex); + } + + FINLINE void FLMAPI f_mutexUnlock( + F_MUTEX hMutex) + { + (void)kMutexUnlock( (MUTEX)hMutex); + } + + FINLINE void FLMAPI f_assertMutexLocked( + F_MUTEX) + { + } + + typedef SEMAPHORE F_SEM; + typedef SEMAPHORE * F_SEM_p; + #define F_SEM_NULL 0 + + FINLINE RCODE FLMAPI f_semCreate( + F_SEM * phSem) + { + if( (*phSem = (F_SEM)kSemaphoreAlloc( (BYTE *)"NOVDB", 0)) == F_SEM_NULL) + { + return RC_SET( NE_FLM_MEM); + } + + return NE_FLM_OK; + } + + FINLINE void FLMAPI f_semDestroy( + F_SEM * phSem) + { + if (*phSem != F_SEM_NULL) + { + (void)kSemaphoreFree( (SEMAPHORE)(*phSem)); + *phSem = F_SEM_NULL; + } + } + + FINLINE RCODE FLMAPI f_semWait( + F_SEM hSem, + FLMUINT uiTimeout) + { + RCODE rc = NE_FLM_OK; + + if( uiTimeout == F_SEM_WAITFOREVER) + { + if( kSemaphoreWait( (SEMAPHORE)hSem) != 0) + { + rc = RC_SET( NE_FLM_ERROR_WAITING_ON_SEMPAHORE); + } } else { - m_uiOffset = m_uiBufferLen; - } - - return( NE_FLM_OK); - } - - FINLINE FLMUINT64 FLMAPI getCurrPosition( void) - { - flmAssert( m_bIsOpen); - return( m_uiOffset); - } - - RCODE FLMAPI read( - void * pvBuffer, - FLMUINT uiBytesToRead, - FLMUINT * puiBytesRead); - - FINLINE const FLMBYTE * getBuffer( void) - { - flmAssert( m_bIsOpen); - return( m_pucBuffer); - } - - FINLINE const FLMBYTE * getBufferAtCurrentOffset( void) - { - flmAssert( m_bIsOpen); - return( m_pucBuffer ? &m_pucBuffer[ m_uiOffset] : NULL); - } - - FINLINE void truncate( - FLMUINT uiOffset) - { - flmAssert( m_bIsOpen); - flmAssert( uiOffset >= m_uiOffset); - flmAssert( uiOffset <= m_uiBufferLen); - - m_uiBufferLen = uiOffset; - } - - FINLINE FLMBOOL isOpen( void) - { - return( m_bIsOpen); - } - - private: - - const FLMBYTE * m_pucBuffer; - FLMUINT m_uiBufferLen; - FLMUINT m_uiOffset; - FLMBOOL m_bAllocatedBuffer; - FLMBOOL m_bIsOpen; - }; - - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_FileIStream : public F_PosIStream - { - public: - - F_FileIStream() - { - m_pFileHdl = NULL; - m_ui64FileOffset = 0; - } - - virtual ~F_FileIStream() - { - if( m_pFileHdl) - { - m_pFileHdl->Release(); - } - } - - RCODE FLMAPI open( - const char * pszPath); - - RCODE FLMAPI close( void); - - RCODE FLMAPI positionTo( - FLMUINT64 ui64Position); - - FLMUINT64 FLMAPI totalSize( void); - - FLMUINT64 FLMAPI remainingSize( void); - - FLMUINT64 FLMAPI getCurrPosition( void); - - RCODE FLMAPI read( - void * pvBuffer, - FLMUINT uiBytesToRead, - FLMUINT * puiBytesRead); - - private: - - IF_FileHdl * m_pFileHdl; - FLMUINT64 m_ui64FileOffset; - }; - - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_BufferedIStream : public F_PosIStream - { - public: - - F_BufferedIStream() - { - m_pIStream = NULL; - m_pucBuffer = NULL; - } - - virtual ~F_BufferedIStream() - { - close(); - } - - RCODE FLMAPI open( - IF_IStream * pIStream, - FLMUINT uiBufferSize); - - RCODE FLMAPI read( - void * pvBuffer, - FLMUINT uiBytesToRead, - FLMUINT * puiBytesRead); - - RCODE FLMAPI close( void); - - FINLINE FLMUINT64 FLMAPI totalSize( void) - { - if (!m_pIStream) - { - flmAssert( 0); - return( 0); - } - - return( m_uiBytesAvail); - } - - FINLINE FLMUINT64 FLMAPI remainingSize( void) - { - if( !m_pIStream) - { - flmAssert( 0); - return( 0); - } - - return( m_uiBytesAvail - m_uiBufferOffset); - } - - FINLINE RCODE FLMAPI positionTo( - FLMUINT64 ui64Position) - { - if( !m_pIStream) - { - flmAssert( 0); - return( RC_SET( NE_FLM_ILLEGAL_OP)); - } - - if( ui64Position < m_uiBytesAvail) - { - m_uiBufferOffset = (FLMUINT)ui64Position; - } - else - { - m_uiBufferOffset = m_uiBytesAvail; - } - - return( NE_FLM_OK); - } - - FINLINE FLMUINT64 FLMAPI getCurrPosition( void) - { - if( !m_pIStream) - { - flmAssert( 0); - return( 0); - } - - return( m_uiBufferOffset); - } - - private: - - IF_IStream * m_pIStream; - FLMBYTE * m_pucBuffer; - FLMUINT m_uiBufferSize; - FLMUINT m_uiBufferOffset; - FLMUINT m_uiBytesAvail; - }; - - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_BufferedOStream : public F_OStream - { - public: - - F_BufferedOStream() - { - m_pOStream = NULL; - m_pucBuffer = NULL; - } - - virtual ~F_BufferedOStream() - { - close(); - } - - RCODE FLMAPI open( - IF_OStream * pOStream, - FLMUINT uiBufferSize); - - RCODE FLMAPI write( - const void * pvBuffer, - FLMUINT uiBytesToWrite, - FLMUINT * puiBytesWritten); - - RCODE FLMAPI close( void); - - RCODE FLMAPI flush( void); - - private: - - IF_OStream * m_pOStream; - FLMBYTE * m_pucBuffer; - FLMUINT m_uiBufferSize; - FLMUINT m_uiBufferOffset; - }; - - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_FileOStream : public F_OStream - { - public: - - F_FileOStream() - { - m_pFileHdl = NULL; - } - - virtual ~F_FileOStream() - { - close(); - } - - RCODE FLMAPI open( - const char * pszFilePath, - FLMBOOL bTruncateIfExists); - - RCODE FLMAPI write( - const void * pvBuffer, - FLMUINT uiBytesToWrite, - FLMUINT * puiBytesWritten); - - RCODE FLMAPI close( void); - - private: - - IF_FileHdl * m_pFileHdl; - FLMUINT64 m_ui64FileOffset; - }; - - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_MultiFileIStream : public F_IStream - { - public: - - F_MultiFileIStream() - { - m_pIStream = NULL; - m_bOpen = FALSE; - } - - virtual ~F_MultiFileIStream() - { - close(); - } - - RCODE FLMAPI open( - const char * pszDirectory, - const char * pszBaseName); - - RCODE FLMAPI read( - void * pvBuffer, - FLMUINT uiBytesToRead, - FLMUINT * puiBytesRead); - - RCODE FLMAPI close( void); - - private: - - RCODE rollToNextFile( void); - - IF_IStream * m_pIStream; - FLMBOOL m_bOpen; - FLMBOOL m_bEndOfStream; - FLMUINT m_uiFileNum; - FLMUINT64 m_ui64FileOffset; - char m_szDirectory[ F_PATH_MAX_SIZE + 1]; - char m_szBaseName[ F_PATH_MAX_SIZE + 1]; - }; - - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_MultiFileOStream : public F_OStream - { - public: - - F_MultiFileOStream() - { - m_pOStream = NULL; - m_bOpen = FALSE; - } - - virtual ~F_MultiFileOStream() - { - close(); - } - - RCODE create( - const char * pszDirectory, - const char * pszBaseName, - FLMUINT uiMaxFileSize, - FLMBOOL bOkToOverwrite); - - RCODE FLMAPI write( - const void * pvBuffer, - FLMUINT uiBytesToWrite, - FLMUINT * puiBytesWritten); - - RCODE FLMAPI close( void); - - private: - - RCODE rollToNextFile( void); - - RCODE processDirectory( - const char * pszDirectory, - const char * pszBaseName, - FLMBOOL bOkToDelete); - - F_OStream * m_pOStream; - FLMBOOL m_bOpen; - FLMUINT m_uiFileNum; - FLMUINT64 m_ui64MaxFileSize; - FLMUINT64 m_ui64FileOffset; - char m_szDirectory[ F_PATH_MAX_SIZE + 1]; - char m_szBaseName[ F_PATH_MAX_SIZE + 1]; - - friend class F_DbSystem; - }; - - /**************************************************************************** - Desc: Decodes an ASCII base64 stream to binary - ****************************************************************************/ - class F_Base64DecoderIStream : public F_IStream - { - public: - - F_Base64DecoderIStream() - { - m_pIStream = NULL; - m_uiBufOffset = 0; - m_uiAvailBytes = 0; - } - - virtual ~F_Base64DecoderIStream() - { - close(); - } - - RCODE FLMAPI open( - IF_IStream * pIStream); - - RCODE FLMAPI read( - void * pvBuffer, - FLMUINT uiBytesToRead, - FLMUINT * puiBytesRead); - - FINLINE RCODE FLMAPI close( void) - { - RCODE rc = NE_FLM_OK; - - if( m_pIStream) - { - if( m_pIStream->getRefCount() == 1) + if( kSemaphoreTimedWait( (SEMAPHORE)hSem, (UINT)uiTimeout) != 0) { - rc = m_pIStream->close(); + rc = RC_SET( NE_FLM_ERROR_WAITING_ON_SEMPAHORE); } - - m_pIStream->Release(); - m_pIStream = NULL; } - - m_uiAvailBytes = 0; - m_uiBufOffset = 0; - + return( rc); } - - private: - - IF_IStream * m_pIStream; - FLMUINT m_uiBufOffset; - FLMUINT m_uiAvailBytes; - FLMBYTE m_ucBuffer[ 8]; - static FLMBYTE m_ucDecodeTable[ 256]; - }; - - /**************************************************************************** - Desc: Encodes a binary input stream into ASCII base64. - ****************************************************************************/ - class F_Base64EncoderIStream : public F_IStream - { - public: - - F_Base64EncoderIStream() - { - m_pIStream = NULL; - } - - virtual ~F_Base64EncoderIStream() - { - close(); - } - - RCODE FLMAPI open( - IF_IStream * pIStream, - FLMBOOL bLineBreaks); - - RCODE FLMAPI read( - void * pvBuffer, - FLMUINT uiBytesToRead, - FLMUINT * puiBytesRead); - - FINLINE RCODE FLMAPI close( void) - { - RCODE rc = NE_FLM_OK; - - if( m_pIStream) - { - if( m_pIStream->getRefCount() == 1) - { - rc = m_pIStream->close(); - } - - m_pIStream->Release(); - m_pIStream = NULL; - } - - return( rc); - } - - private: - - IF_IStream * m_pIStream; - FLMBOOL m_bInputExhausted; - FLMBOOL m_bLineBreaks; - FLMBOOL m_bPriorLineEnd; - FLMUINT m_uiBase64Count; - FLMUINT m_uiBufOffset; - FLMUINT m_uiAvailBytes; - FLMBYTE m_ucBuffer[ 8]; - static FLMBYTE m_ucEncodeTable[ 64]; - }; - - typedef struct LZWODictItem - { - LZWODictItem * pNext; - FLMUINT16 ui16Code; - FLMUINT16 ui16ParentCode; - FLMBYTE ucChar; - } LZWODictItem; - - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_CompressingOStream : public F_OStream - { - public: - - F_CompressingOStream() - { - m_pOStream = NULL; - m_ppHashTbl = NULL; - m_pool.poolInit( 64 * 1024); - } - - virtual ~F_CompressingOStream() - { - close(); - } - - RCODE FLMAPI open( - IF_OStream * pOStream); - - RCODE FLMAPI write( - const void * pvBuffer, - FLMUINT uiBytesToWrite, - FLMUINT * puiBytesWritten); - - RCODE FLMAPI close( void); - - private: - - FINLINE FLMUINT getHashBucket( - FLMUINT16 ui16CurrentCode, - FLMBYTE ucChar) - { - return( ((((FLMUINT)ui16CurrentCode) << 8) | - ((FLMUINT)ucChar)) % m_uiHashTblSize); - } - - LZWODictItem * findDictEntry( - FLMUINT16 ui16CurrentCode, - FLMBYTE ucChar); - - IF_OStream * m_pOStream; - LZWODictItem ** m_ppHashTbl; - FLMUINT m_uiHashTblSize; - FLMUINT m_uiLastRatio; - FLMUINT m_uiBestRatio; - FLMUINT m_uiCurrentBytesIn; - FLMUINT m_uiTotalBytesIn; - FLMUINT m_uiCurrentBytesOut; - FLMUINT m_uiTotalBytesOut; - FLMBOOL m_bStopCompression; - FLMUINT16 m_ui16CurrentCode; - FLMUINT16 m_ui16FreeCode; - F_Pool m_pool; - }; - - typedef struct LZWIDictItem - { - LZWODictItem * pNext; - FLMUINT16 ui16ParentCode; - FLMBYTE ucChar; - } LZWIDictItem; - - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_UncompressingIStream : public F_IStream - { - public: - - F_UncompressingIStream() - { - m_pIStream = NULL; - m_pDict = NULL; - m_pucDecodeBuffer = NULL; - } - - virtual ~F_UncompressingIStream() - { - close(); - } - - RCODE FLMAPI open( - IF_IStream * pIStream); - - RCODE FLMAPI read( - void * pvBuffer, - FLMUINT uiBytesToRead, - FLMUINT * puiBytesRead); - - RCODE FLMAPI close( void); - - private: - - RCODE readCode( - FLMUINT16 * pui16Code); - - RCODE decodeToBuffer( - FLMUINT16 ui16Code); - - IF_IStream * m_pIStream; - LZWIDictItem * m_pDict; - FLMBYTE * m_pucDecodeBuffer; - FLMUINT m_uiDecodeBufferSize; - FLMUINT m_uiDecodeBufferOffset; - FLMUINT16 m_ui16FreeCode; - FLMUINT16 m_ui16LastCode; - FLMBOOL m_bStopCompression; - FLMBOOL m_bEndOfStream; - }; - - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_TCPStream : public F_IStream, public F_OStream - { - public: - F_TCPStream( void); - - virtual ~F_TCPStream( void); - - RCODE openConnection( - const char * pucHostAddress, - FLMUINT uiPort, - FLMUINT uiConnectTimeout = 3, - FLMUINT uiDataTimeout = 15); - - RCODE FLMAPI read( - void * pvBuffer, - FLMUINT uiBytesToRead, - FLMUINT * puiBytesRead); - - RCODE FLMAPI write( - const void * pvBuffer, - FLMUINT uiBytesToWrite, - FLMUINT * puiBytesWritten); - - FINLINE RCODE socketPeekWrite( - FLMINT iTimeOut) + FINLINE void FLMAPI f_semSignal( + F_SEM hSem) { - return( socketPeek( iTimeOut, FALSE)); + (void)kSemaphoreSignal( (SEMAPHORE)hSem); } - - FINLINE RCODE socketPeekRead( - FLMINT iTimeOut) - { - return( socketPeek( iTimeOut, TRUE)); - }; - - FINLINE const char * getName( void) - { - getLocalInfo(); - return( (const char *)m_pszName); - }; - - FINLINE const char * getAddr( void) - { - getLocalInfo(); - return( (const char *)m_pszIp); - }; - - FINLINE const char * getPeerName( void) - { - getRemoteInfo(); - return( (const char *)m_pszPeerName); - }; - - FINLINE const char * getPeerAddr( void) - { - getRemoteInfo(); - return( (const char *)m_pszPeerIp); - }; - - RCODE readNoWait( - void * pvBuffer, - FLMUINT uiCount, - FLMUINT * puiReadRead); - - RCODE readAll( - void * pvBuffer, - FLMUINT uiCount, - FLMUINT * puiBytesRead); - - RCODE setTcpDelay( - FLMBOOL bOn); - - RCODE FLMAPI close( void); - private: + #elif defined( FLM_WIN) - RCODE getLocalInfo( void); - - RCODE getRemoteInfo( void); - - RCODE socketPeek( - FLMINT iTimoutVal, - FLMBOOL bPeekRead); - - #ifndef FLM_UNIX - WSADATA m_wsaData; + typedef struct + { + FLMATOMIC locked; + #ifdef FLM_DEBUG + FLMUINT uiThreadId; + FLMATOMIC lockedCount; + FLMATOMIC waitCount; #endif - FLMBOOL m_bInitialized; - SOCKET m_iSocket; - FLMUINT m_uiIOTimeout; - FLMBOOL m_bConnected; - char m_pszIp[ 256]; - char m_pszName[ 256]; - char m_pszPeerIp[ 256]; - char m_pszPeerName[ 256]; - unsigned long m_ulRemoteAddr; - }; + } F_INTERLOCK; + + RCODE FLMAPI f_mutexCreate( + F_MUTEX * phMutex); + void FLMAPI f_mutexDestroy( + F_MUTEX * phMutex); + + FINLINE void FLMAPI f_mutexLock( + F_MUTEX hMutex) + { + while( f_atomicExchange( + &(((F_INTERLOCK *)hMutex)->locked), 1) != 0) + { + #ifdef FLM_DEBUG + f_atomicInc( &(((F_INTERLOCK *)hMutex)->waitCount)); + #endif + Sleep( 0); + } + + #ifdef FLM_DEBUG + flmAssert( ((F_INTERLOCK *)hMutex)->uiThreadId == 0); + ((F_INTERLOCK *)hMutex)->uiThreadId = _threadid; + f_atomicInc( &(((F_INTERLOCK *)hMutex)->lockedCount)); + #endif + } + + FINLINE void FLMAPI f_mutexUnlock( + F_MUTEX hMutex) + { + flmAssert( ((F_INTERLOCK *)hMutex)->locked == 1); + #ifdef FLM_DEBUG + flmAssert( ((F_INTERLOCK *)hMutex)->uiThreadId == _threadid); + ((F_INTERLOCK *)hMutex)->uiThreadId = 0; + #endif + f_atomicExchange( &(((F_INTERLOCK *)hMutex)->locked), 0); + } + + FINLINE void FLMAPI f_assertMutexLocked( + F_MUTEX hMutex) + { + #ifdef FLM_DEBUG + flmAssert( ((F_INTERLOCK *)hMutex)->locked == 1); + flmAssert( ((F_INTERLOCK *)hMutex)->uiThreadId == _threadid); + #else + F_UNREFERENCED_PARM( hMutex); + #endif + } + + FINLINE RCODE FLMAPI f_semCreate( + F_SEM * phSem) + { + if( (*phSem = CreateSemaphore( (LPSECURITY_ATTRIBUTES)NULL, + 0, 10000, NULL )) == NULL) + { + return( RC_SET( NE_FLM_COULD_NOT_CREATE_SEMAPHORE)); + } + + return NE_FLM_OK; + } + + FINLINE void FLMAPI f_semDestroy( + F_SEM * phSem) + { + if (*phSem != F_SEM_NULL) + { + CloseHandle( *phSem); + *phSem = F_SEM_NULL; + } + } + + FINLINE RCODE FLMAPI f_semWait( + F_SEM hSem, + FLMUINT uiTimeout) + { + if( WaitForSingleObject( hSem, uiTimeout ) == WAIT_OBJECT_0) + { + return( NE_FLM_OK); + } + else + { + return( RC_SET( NE_FLM_ERROR_WAITING_ON_SEMPAHORE)); + } + } + + FINLINE void FLMAPI f_semSignal( + F_SEM hSem) + { + (void)ReleaseSemaphore( hSem, 1, NULL); + } + #elif defined( FLM_UNIX) + RCODE FLMAPI f_mutexCreate( + F_MUTEX * phMutex); + + void f_mutexDestroy( + F_MUTEX * phMutex); + + FINLINE void FLMAPI f_mutexLock( + F_MUTEX hMutex) + { + (void)pthread_mutex_lock( hMutex); + } + + FINLINE void FLMAPI f_mutexUnlock( + F_MUTEX hMutex) + { + (void)pthread_mutex_unlock( hMutex); + } + + FINLINE void FLMAPI f_assertMutexLocked( + F_MUTEX) + { + } + + int sema_signal( + sema_t * sem); + + void FLMAPI f_semDestroy( + F_SEM * phSem); + + RCODE FLMAPI f_semCreate( + F_SEM * phSem); + + RCODE FLMAPI f_semWait( + F_SEM hSem, + FLMUINT uiTimeout); + + FINLINE void FLMAPI f_semSignal( + F_SEM hSem) + { + (void)sema_signal( hSem); + } + + #endif + /**************************************************************************** Misc. ****************************************************************************/ @@ -2573,20 +1169,15 @@ f_sprintf ****************************************************************************/ - typedef struct - { - FLMBYTE * pszDestStr; - } F_SPRINTF_INFO; - // Percent formating prefixes - + #define FLM_PREFIX_NONE 0 #define FLM_PREFIX_MINUS 1 #define FLM_PREFIX_PLUS 2 #define FLM_PREFIX_POUND 3 - + // Width and Precision flags - + #define FLM_PRINTF_MINUS_FLAG 0x0001 #define FLM_PRINTF_PLUS_FLAG 0x0002 #define FLM_PRINTF_SPACE_FLAG 0x0004 @@ -2598,6 +1189,11 @@ #define FLM_PRINTF_INT64_FLAG 0x0100 #define FLM_PRINTF_COMMA_FLAG 0x0200 + typedef struct + { + FLMBYTE * pszDestStr; + } F_SPRINTF_INFO; + void f_sprintfProcessFieldInfo( FLMBYTE ** ppszFormat, FLMUINT * puiWidth, @@ -2645,135 +1241,6 @@ F_SPRINTF_INFO * pInfo, f_va_list * args); - #if defined( FLM_WIN) - - typedef struct - { - HANDLE findHandle; - WIN32_FIND_DATA findBuffer; - char szSearchPath[ F_PATH_MAX_SIZE]; - FLMUINT uiSearchAttrib; - } F_IO_FIND_DATA; - - #define F_IO_FA_NORMAL FILE_ATTRIBUTE_NORMAL // Normal file - #define F_IO_FA_RDONLY FILE_ATTRIBUTE_READONLY // Read only attribute - #define F_IO_FA_HIDDEN FILE_ATTRIBUTE_HIDDEN // Hidden file - #define F_IO_FA_SYSTEM FILE_ATTRIBUTE_SYSTEM // System file - #define F_IO_FA_VOLUME FILE_ATTRIBUTE_VOLUME // Volume label - #define F_IO_FA_DIRECTORY FILE_ATTRIBUTE_DIRECTORY // Directory - #define F_IO_FA_ARCHIVE FILE_ATTRIBUTE_ARCHIVE // Archive - - #elif defined( FLM_UNIX) || defined( FLM_NLM) - - typedef struct _DirInfo - { - mode_t mode_flag; - struct stat FileStat; - char name[ F_PATH_MAX_SIZE+1]; - char search_path[ F_PATH_MAX_SIZE+1]; - char full_path[ F_PATH_MAX_SIZE]; - char pattern_str[ F_PATH_MAX_SIZE]; - char dirpath[ F_PATH_MAX_SIZE]; - glob_t globbuf; - } F_IO_FIND_DATA; - - #define F_IO_FA_NORMAL 0x01 // Normal file, no attributes - #define F_IO_FA_RDONLY 0x02 // Read only attribute - #define F_IO_FA_HIDDEN 0x04 // Hidden file - #define F_IO_FA_SYSTEM 0x08 // System file - #define F_IO_FA_VOLUME 0x10 // Volume label - #define F_IO_FA_DIRECTORY 0x20 // Directory - #define F_IO_FA_ARCHIVE 0x40 // Archive - - #else - #error Platform not supported - #endif - - RCODE f_fileFindFirst( - char * pszSearchPath, - FLMUINT uiSearchAttrib, - F_IO_FIND_DATA * find_data, - char * pszFoundPath, - FLMUINT * puiFoundAttrib); - - RCODE f_fileFindNext( - F_IO_FIND_DATA * pFindData, - char * pszFoundPath, - FLMUINT * puiFoundAttrib); - - void f_fileFindClose( - F_IO_FIND_DATA * pFindData); - - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_IOBufferMgr : public IF_IOBufferMgr, public F_Base - { - public: - - F_IOBufferMgr(); - - virtual ~F_IOBufferMgr(); - - RCODE FLMAPI waitForAllPendingIO( void); - - FINLINE void FLMAPI setMaxBuffers( - FLMUINT uiMaxBuffers) - { - m_uiMaxBuffers = uiMaxBuffers; - } - - FINLINE void FLMAPI setMaxBytes( - FLMUINT uiMaxBytes) - { - m_uiMaxBufferBytesToUse = uiMaxBytes; - } - - FINLINE void FLMAPI enableKeepBuffer( void) - { - m_bKeepBuffers = TRUE; - } - - RCODE FLMAPI getBuffer( - IF_IOBuffer ** ppIOBuffer, - FLMUINT uiBufferSize, - FLMUINT uiBlockSize); - - FINLINE FLMBOOL FLMAPI havePendingIO( void) - { - return( m_pFirstPending ? TRUE : FALSE); - } - - FINLINE FLMBOOL FLMAPI haveUsed( void) - { - return( m_pFirstUsed ? TRUE : FALSE); - } - - private: - - // Private methods and variables - - F_IOBuffer * m_pFirstPending; - F_IOBuffer * m_pFirstAvail; - F_IOBuffer * m_pFirstUsed; - FLMUINT m_uiMaxBuffers; - FLMUINT m_uiMaxBufferBytesToUse; - FLMUINT m_uiBufferBytesInUse; - FLMUINT m_uiBuffersInUse; - RCODE m_completionRc; - FLMBOOL m_bKeepBuffers; - - void linkToList( - F_IOBuffer ** ppListHead, - F_IOBuffer * pIOBuffer); - - void unlinkFromList( - F_IOBuffer * pIOBuffer); - - friend class F_IOBuffer; - - }; - /**************************************************************************** Desc: ****************************************************************************/ @@ -2871,7 +1338,7 @@ // Only called by the buffer manager RCODE setupIOBuffer( - F_IOBufferMgr * pIOBufferMgr); + IF_IOBufferMgr * pIOBufferMgr); FLMBOOL isIOComplete( void); @@ -2906,1226 +1373,6 @@ friend class F_IOBufferMgr; }; - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_DirHdl : public IF_DirHdl, public F_Base - { - public: - - F_DirHdl(); - - virtual ~F_DirHdl() - { - if( m_bFindOpen) - { - f_fileFindClose( &m_FindData); - } - } - - RCODE openDir( - const char * pszDirName, - const char * pszPattern); - - RCODE createDir( - const char * pszDirName); - - RCODE removeDir( - const char * pszDirPath); - - RCODE FLMAPI next( void); - - const char * FLMAPI currentItemName( void); - - void FLMAPI currentItemPath( - char * pszPath); - - FLMUINT64 FLMAPI currentItemSize( void); - - FLMBOOL FLMAPI currentItemIsDir( void); - - private: - - char m_szDirectoryPath[ F_PATH_MAX_SIZE]; - char m_szPattern[ F_PATH_MAX_SIZE]; - FLMUINT32 m_ui32RefCount; - RCODE m_rc; - FLMBOOL m_bFirstTime; - FLMBOOL m_bFindOpen; - FLMBOOL m_EOF; - char m_szFileName[ F_PATH_MAX_SIZE]; - FLMUINT m_uiAttrib; - F_IO_FIND_DATA m_FindData; - }; - - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_FileSystem : public IF_FileSystem, public F_Base - { - public: - - F_FileSystem() - { - } - - virtual ~F_FileSystem() - { - } - - RCODE FLMAPI createFile( - const char * pszFileName, - FLMUINT uiIoFlags, - IF_FileHdl ** ppFile); - - RCODE FLMAPI createBlockFile( - const char * pszFileName, - FLMUINT uiIoFlags, - FLMUINT uiBlockSize, - IF_FileHdl ** ppFile); - - RCODE FLMAPI createUniqueFile( - const char * pszDirName, - const char * pszFileExtension, - FLMUINT uiIoFlags, - IF_FileHdl ** ppFile); - - RCODE FLMAPI openFile( - const char * pszFileName, - FLMUINT uiIoFlags, - IF_FileHdl ** ppFile); - - RCODE FLMAPI openBlockFile( - const char * pszFileName, - FLMUINT uiIoFlags, - FLMUINT uiBlockSize, - IF_FileHdl ** ppFile); - - RCODE FLMAPI openDir( - const char * pszDirName, - const char * pszPattern, - IF_DirHdl ** ppDir); - - RCODE FLMAPI createDir( - const char * pszDirName); - - RCODE FLMAPI removeDir( - const char * pszDirName, - FLMBOOL bClear = FALSE); - - RCODE FLMAPI doesFileExist( - const char * pszFileName); - - FLMBOOL FLMAPI isDir( - const char * pszFileName); - - RCODE FLMAPI getFileTimeStamp( - const char * pszFileName, - FLMUINT * puiTimeStamp); - - RCODE FLMAPI deleteFile( - const char * pszFileName); - - RCODE FLMAPI copyFile( - const char * pszSrcFileName, - const char * pszDestFileName, - FLMBOOL bOverwrite, - FLMUINT64 * pui64BytesCopied); - - RCODE FLMAPI renameFile( - const char * pszFileName, - const char * pszNewFileName); - - void FLMAPI pathParse( - const char * pszPath, - char * pszServer, - char * pszVolume, - char * pszDirPath, - char * pszFileName); - - RCODE FLMAPI pathReduce( - const char * pszSourcePath, - char * pszDestPath, - char * pszString); - - RCODE FLMAPI pathAppend( - char * pszPath, - const char * pszPathComponent); - - RCODE FLMAPI pathToStorageString( - const char * pszPath, - char * pszString); - - void FLMAPI pathCreateUniqueName( - FLMUINT * puiTime, - char * pszFileName, - const char * pszFileExt, - FLMBYTE * pHighChars, - FLMBOOL bModext); - - FLMBOOL FLMAPI doesFileMatch( - const char * pszFileName, - const char * pszTemplate); - - RCODE FLMAPI getSectorSize( - const char * pszFileName, - FLMUINT * puiSectorSize); - - RCODE setReadOnly( - const char * pszFileName, - FLMBOOL bReadOnly); - - private: - - #if defined( FLM_UNIX) - RCODE unix_RenameSafe( - const char * pszSrcFile, - const char * pszDestFile); - - RCODE unix_TargetIsDir( - const char * tpath, - FLMBOOL * isdir); - #endif - }; - - /*************************************************************************** - Desc: - ***************************************************************************/ - #ifdef FLM_WIN - class F_FileHdl : public IF_FileHdl, public F_Base - { - public: - - F_FileHdl(); - - virtual ~F_FileHdl(); - - RCODE FLMAPI close( void); - - RCODE FLMAPI create( - const char * pszFileName, - FLMUINT uiIoFlags); - - RCODE FLMAPI createUnique( - const char * pszDirName, - const char * pszFileExtension, - FLMUINT uiIoFlags); - - RCODE FLMAPI open( - const char * pszFileName, - FLMUINT uiIoFlags); - - RCODE FLMAPI flush( void); - - RCODE FLMAPI read( - FLMUINT64 ui64Offset, - FLMUINT uiLength, - void * pvBuffer, - FLMUINT * puiBytesRead); - - RCODE FLMAPI seek( - FLMUINT64 ui64Offset, - FLMINT iWhence, - FLMUINT64 * pui64NewOffset); - - RCODE FLMAPI size( - FLMUINT64 * pui64Size); - - RCODE FLMAPI tell( - FLMUINT64 * pui64Offset); - - RCODE FLMAPI truncate( - FLMUINT64 ui64Size); - - RCODE FLMAPI write( - FLMUINT64 ui64Offset, - FLMUINT uiLength, - const void * pvBuffer, - FLMUINT * puiBytesWritten); - - FINLINE RCODE FLMAPI sectorRead( - FLMUINT64 ui64ReadOffset, - FLMUINT uiBytesToRead, - void * pvBuffer, - FLMUINT * puiBytesReadRV) - { - if (m_bDoDirectIO) - { - return( directRead( ui64ReadOffset, uiBytesToRead, - pvBuffer, TRUE, puiBytesReadRV)); - } - else - { - return( read( ui64ReadOffset, uiBytesToRead, pvBuffer, puiBytesReadRV)); - } - } - - FINLINE RCODE FLMAPI sectorWrite( - FLMUINT64 ui64WriteOffset, - FLMUINT uiBytesToWrite, - const void * pvBuffer, - FLMUINT uiBufferSize, - void * pvBufferObj, - FLMUINT * puiBytesWrittenRV, - FLMBOOL bZeroFill = TRUE) - { - F_UNREFERENCED_PARM( uiBufferSize); - - if (m_bDoDirectIO) - { - return( directWrite( ui64WriteOffset, uiBytesToWrite, - pvBuffer, (F_IOBuffer *)pvBufferObj, TRUE, - bZeroFill, puiBytesWrittenRV)); - } - else - { - flmAssert( pvBufferObj == NULL); - return( write( ui64WriteOffset, uiBytesToWrite, pvBuffer, - puiBytesWrittenRV)); - } - } - - FINLINE FLMBOOL FLMAPI canDoAsync( void) - { - return( m_bCanDoAsync); - } - - FINLINE void FLMAPI setExtendSize( - FLMUINT uiExtendSize) - { - m_uiExtendSize = uiExtendSize; - } - - FINLINE void FLMAPI setMaxAutoExtendSize( - FLMUINT uiMaxAutoExtendSize) - { - m_uiMaxAutoExtendSize = uiMaxAutoExtendSize; - } - - FINLINE void setupFileHdl( - FLMUINT uiFileId, - FLMBOOL bDeleteOnRelease) - { - m_uiFileId = uiFileId; - m_bDeleteOnRelease = bDeleteOnRelease; - } - - FINLINE FLMUINT getFileId( void) - { - return( m_uiFileId); - } - - FINLINE FLMUINT getSectorSize( void) - { - return( m_uiBytesPerSector); - } - - FINLINE void setBlockSize( - FLMUINT uiBlockSize) - { - m_uiBlockSize = uiBlockSize; - } - - FINLINE HANDLE getFileHandle( void) - { - return m_FileHandle; - } - - private: - - RCODE openOrCreate( - const char * pszFileName, - FLMUINT uiAccess, - FLMBOOL bCreateFlag); - - RCODE allocAlignBuffer( void); - - RCODE doOneRead( - FLMUINT64 ui64Offset, - FLMUINT uiLength, - void * pvBuffer, - FLMUINT * puiBytesRead); - - RCODE directRead( - FLMUINT64 uiOffset, - FLMUINT uiLength, - void * pvBuffer, - FLMBOOL bBuffHasFullSectors, - FLMUINT * puiBytesRead); - - RCODE directWrite( - FLMUINT64 uiOffset, - FLMUINT uiLength, - const void * pvBuffer, - F_IOBuffer * pBufferObj, - FLMBOOL bBuffHasFullSectors, - FLMBOOL bZeroFill, - FLMUINT * puiBytesWritten); - - FINLINE FLMUINT64 roundToNextSector( - FLMUINT64 ui64Bytes) - { - return( (ui64Bytes + m_ui64NotOnSectorBoundMask) & - m_ui64GetSectorBoundMask); - } - - FINLINE FLMUINT64 truncateToPrevSector( - FLMUINT64 ui64Offset) - { - return( ui64Offset & m_ui64GetSectorBoundMask); - } - - RCODE extendFile( - FLMUINT64 ui64EndOfLastWrite, - FLMUINT uiMaxBytesToExtend, - FLMBOOL bFlush); - - F_FileHdl * m_pNext; - F_FileHdl * m_pPrev; - FLMBOOL m_bInList; - FLMBOOL m_bFileOpened; - FLMUINT m_uiAvailTime; - FLMUINT m_uiFileId; - FLMBOOL m_bDeleteOnRelease; - FLMBOOL m_bOpenedReadOnly; - FLMBOOL m_bOpenedExclusive; - char * m_pszFileName; - HANDLE m_FileHandle; - FLMUINT m_uiBlockSize; - FLMUINT m_uiBytesPerSector; - FLMUINT64 m_ui64NotOnSectorBoundMask; - FLMUINT64 m_ui64GetSectorBoundMask; - FLMBOOL m_bDoDirectIO; - FLMUINT m_uiExtendSize; - FLMUINT m_uiMaxAutoExtendSize; - FLMBYTE * m_pucAlignedBuff; - FLMUINT m_uiAlignedBuffSize; - FLMUINT64 m_ui64CurrentPos; - FLMBOOL m_bCanDoAsync; - OVERLAPPED m_Overlapped; - - friend class F_FileHdlMgr; - friend class F_FileHdlMgr; - }; - #endif - - /*************************************************************************** - Desc: - ***************************************************************************/ - #ifdef FLM_UNIX - class F_FileHdl : public IF_FileHdl, public F_Base - { - public: - - F_FileHdl(); - - ~F_FileHdl(); - - RCODE FLMAPI setup( - FLMUINT uiFileId); - - RCODE FLMAPI close( void); - - RCODE FLMAPI create( - const char * pszFileName, - FLMUINT uiIoFlags); - - RCODE FLMAPI createUnique( - const char * pszDirName, - const char * pszFileExtension, - FLMUINT uiIoFlags); - - RCODE FLMAPI open( - const char * pszFileName, - FLMUINT uiIoFlags); - - RCODE FLMAPI flush( void); - - RCODE FLMAPI read( - FLMUINT64 ui64Offset, - FLMUINT uiLength, - void * pvBuffer, - FLMUINT * puiBytesRead); - - RCODE FLMAPI seek( - FLMUINT64 ui64Offset, - FLMINT iWhence, - FLMUINT64 * pui64NewOffset); - - RCODE FLMAPI size( - FLMUINT64 * pui64Size); - - RCODE FLMAPI tell( - FLMUINT64 * pui64Offset); - - RCODE FLMAPI truncate( - FLMUINT64 ui64Size); - - RCODE FLMAPI write( - FLMUINT64 ui64Offset, - FLMUINT uiLength, - const void * pvBuffer, - FLMUINT * puiBytesWritten); - - RCODE FLMAPI sectorRead( - FLMUINT64 ui64ReadOffset, - FLMUINT uiBytesToRead, - void * pvBuffer, - FLMUINT * puiBytesReadRV); - - RCODE FLMAPI sectorWrite( - FLMUINT64 ui64WriteOffset, - FLMUINT uiBytesToWrite, - const void * pvBuffer, - FLMUINT uiBufferSize, - void * pvBufferObj, - FLMUINT * puiBytesWrittenRV, - FLMBOOL bZeroFill = TRUE) - { - if( m_bDoDirectIO) - { - return( DirectWrite( ui64WriteOffset, uiBytesToWrite, - pvBuffer, uiBufferSize, (F_IOBuffer *)pvBufferObj, - puiBytesWrittenRV, TRUE, bZeroFill)); - } - else - { - return( Write( ui64WriteOffset, uiBytesToWrite, - pvBuffer, puiBytesWrittenRV)); - } - } - - FLMBOOL FLMAPI canDoAsync( void); - - FINLINE FLMBOOL FLMAPI usingDirectIo( void) - { - return( m_bDoDirectIO); - } - - FINLINE void FLMAPI setExtendSize( - FLMUINT uiExtendSize) - { - m_uiExtendSize = uiExtendSize; - } - - FINLINE void FLMAPI setMaxAutoExtendSize( - FLMUINT uiMaxAutoExtendSize) - { - m_uiMaxAutoExtendSize = uiMaxAutoExtendSize; - } - - RCODE FLMAPI lock( void); - - RCODE FLMAPI unlock( void); - - FINLINE void FLMAPI setBlockSize( - FLMUINT uiBlockSize) - { - m_uiBlockSize = uiBlockSize; - } - - FINLINE FLMUINT FLMAPI getSectorSize( void) - { - return( m_uiBytesPerSector); - } - - FINLINE void setupFileHdl( - FLMUINT uiFileId, - FLMBOOL bDeleteOnRelease) - { - m_uiFileId = uiFileId; - m_bDeleteOnRelease = bDeleteOnRelease; - } - - FINLINE FLMUINT getFileId( void) - { - return m_uiFileId; - } - - private: - - RCODE openOrCreate( - const char * pszFileName, - FLMUINT uiAccess, - FLMBOOL bCreateFlag); - - FINLINE FLMUINT64 roundUpToSectorMultiple( - FLMUINT64 ui64Bytes) - { - return( (ui64Bytes + m_ui64NotOnSectorBoundMask) & - m_ui64GetSectorBoundMask); - } - - FINLINE FLMUINT64 getSectorStartOffset( - FLMUINT64 ui64Offset) - { - return( ui64Offset & m_ui64GetSectorBoundMask); - } - - RCODE directRead( - FLMUINT64 ui64ReadOffset, - FLMUINT uiBytesToRead, - void * pvBuffer, - FLMBOOL bBuffHasFullSectors, - FLMUINT * puiBytesRead); - - RCODE directWrite( - FLMUINT64 ui64WriteOffset, - FLMUINT uiBytesToWrite, - const void * pvBuffer, - FLMUINT uiBufferSize, - F_IOBuffer * pBufferObj, - FLMUINT * puiBytesWrittenRV, - FLMBOOL bBuffHasFullSectors, - FLMBOOL bZeroFill); - - RCODE allocAlignBuffer( void); - - F_FileHdl * m_pNext; - F_FileHdl * m_pPrev; - FLMBOOL m_bInList; - FLMBOOL m_bFileOpened; - FLMUINT m_uiAvailTime; - FLMUINT m_uiFileId; - FLMBOOL m_bDeleteOnRelease; - FLMBOOL m_bOpenedReadOnly; - FLMBOOL m_bOpenedExclusive; - char * m_pszFileName; - int m_fd; - FLMUINT m_uiBlockSize; - FLMUINT m_uiBytesPerSector; - FLMUINT64 m_ui64NotOnSectorBoundMask; - FLMUINT64 m_ui64GetSectorBoundMask; - FLMUINT64 m_ui64CurrentPos; - FLMUINT m_uiExtendSize; - FLMUINT m_uiMaxAutoExtendSize; - FLMBOOL m_bCanDoAsync; - FLMBOOL m_bDoDirectIO; - FLMBYTE * m_pucAlignedBuff; - FLMUINT m_uiAlignedBuffSize; - - friend class F_FileHdlMgr; - }; - #endif - - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_FileHdlMgr : public F_Base - { - public: - - F_FileHdlMgr(); - - virtual ~F_FileHdlMgr() - { - if( m_hMutex != F_MUTEX_NULL) - { - lockMutex( FALSE); - freeUsedList( TRUE); - freeAvailList( TRUE); - unlockMutex( FALSE); - f_mutexDestroy( &m_hMutex); - } - } - - RCODE setupFileHdlMgr( - FLMUINT uiOpenThreshold = 64, - FLMUINT uiMaxAvailTime = 120); - - FINLINE void setOpenThreshold( - FLMUINT uiOpenThreshold) - { - if (m_bIsSetup) - { - lockMutex( FALSE); - m_uiOpenThreshold = uiOpenThreshold; - unlockMutex( FALSE); - } - } - - FINLINE void setMaxAvailTime( - FLMUINT uiMaxAvailTime) - { - if (m_bIsSetup) - { - lockMutex( FALSE); - m_uiMaxAvailTime = uiMaxAvailTime; - unlockMutex( FALSE); - } - } - - FINLINE FLMUINT getUniqueId( void) - { - FLMUINT uiTemp; - - lockMutex( FALSE); - uiTemp = ++m_uiFileIdCounter; - unlockMutex( FALSE); - return( uiTemp); - } - - void findAvail( - FLMUINT uiFileId, - FLMBOOL bReadOnlyFlag, - F_FileHdl ** ppFileHdl); - - void makeAvailAndRelease( - FLMBOOL bMutexAlreadyLocked, - F_FileHdl * pFileHdl); - - void removeFileHdls( - FLMUINT uiFileId); - - void checkAgedFileHdls( - FLMUINT uiMinSecondsOpened); - - void FINLINE releaseOneAvail( - FLMBOOL bMutexAlreadyLocked) - { - lockMutex( bMutexAlreadyLocked); - if (m_pFirstAvail) - { - removeFromList( TRUE, - m_pFirstAvail, &m_pFirstAvail, &m_pLastAvail, &m_uiNumAvail); - } - unlockMutex( bMutexAlreadyLocked); - } - - FINLINE FLMUINT getOpenThreshold( void) - { - return m_uiOpenThreshold; - } - - FINLINE FLMUINT getOpenedFiles( void) - { - FLMUINT uiTemp; - - lockMutex( FALSE); - uiTemp = m_uiNumUsed + m_uiNumAvail; - unlockMutex( FALSE); - return( uiTemp); - } - - FINLINE FLMUINT getMaxAvailTime( void) - { - return m_uiMaxAvailTime; - } - - void freeAvailList( - FLMBOOL bMutexAlreadyLocked); - - void freeUsedList( - FLMBOOL bMutexAlreadyLocked); - - FINLINE void insertInUsedList( - FLMBOOL bMutexAlreadyLocked, - F_FileHdl * pFileHdl, - FLMBOOL bInsertAtEnd) - { - insertInList( bMutexAlreadyLocked, - pFileHdl, bInsertAtEnd, - &m_pFirstUsed, &m_pLastUsed, &m_uiNumUsed); - } - - private: - - void insertInList( - FLMBOOL bMutexAlreadyLocked, - F_FileHdl * pFileHdl, - FLMBOOL bInsertAtEnd, - F_FileHdl ** ppFirst, - F_FileHdl ** ppLast, - FLMUINT * puiCount); - - void removeFromList( - FLMBOOL bMutexAlreadyLocked, - F_FileHdl * pFileHdl, - F_FileHdl ** ppFirst, - F_FileHdl ** ppLast, - FLMUINT * puiCount); - - FINLINE void lockMutex( - FLMBOOL bMutexAlreadyLocked) - { - if (m_hMutex != F_MUTEX_NULL && !bMutexAlreadyLocked) - { - f_mutexLock( m_hMutex); - } - } - - FINLINE void unlockMutex( - FLMBOOL bMutexAlreadyLocked) - { - if (m_hMutex != F_MUTEX_NULL && !bMutexAlreadyLocked) - { - f_mutexUnlock( m_hMutex); - } - } - - F_MUTEX m_hMutex; - FLMUINT m_uiOpenThreshold; - FLMUINT m_uiMaxAvailTime; - F_FileHdl * m_pFirstUsed; - F_FileHdl * m_pLastUsed; - FLMUINT m_uiNumUsed; - F_FileHdl * m_pFirstAvail; - F_FileHdl * m_pLastAvail; - FLMUINT m_uiNumAvail; - FLMBOOL m_bIsSetup; - FLMUINT m_uiFileIdCounter; - }; - - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_MultiFileHdl : public IF_MultiFileHdl, public F_Base - { - public: - - F_MultiFileHdl( - FLMUINT uiMaxFileSize = F_MULTI_FHDL_DEFAULT_MAX_FILE_SIZE); - - virtual ~F_MultiFileHdl(); - - void FLMAPI close( - FLMBOOL bDelete = FALSE); - - - RCODE FLMAPI create( - const char * pszPath); - - RCODE FLMAPI createUnique( - const char * pszPath, - const char * pszFileExtension); - - RCODE FLMAPI deleteMultiFile( - const char * pszPath); - - RCODE FLMAPI open( - const char * pszPath); - - RCODE FLMAPI flush( void); - - RCODE FLMAPI read( - FLMUINT64 ui64Offset, - FLMUINT uiLength, - void * pvBuffer, - FLMUINT * puiBytesRead); - - RCODE FLMAPI write( - FLMUINT64 ui64Offset, - FLMUINT uiLength, - void * pvBuffer, - FLMUINT * puiBytesWritten); - - RCODE FLMAPI getPath( - char * pszFilePath); - - FINLINE RCODE FLMAPI size( - FLMUINT64 * pui64FileSize) - { - *pui64FileSize = m_ui64EOF; - return( NE_FLM_OK); - } - - RCODE FLMAPI truncate( - FLMUINT64 ui64NewSize); - - private: - - RCODE getFileHdl( - FLMUINT uiFileNum, - FLMBOOL bGetForWrite, - IF_FileHdl ** ppFileHdl); - - RCODE createLockFile( - const char * pszBasePath); - - FINLINE void releaseLockFile( - const char * pszBasePath, - FLMBOOL bDelete) - { - #ifndef FLM_UNIX - F_UNREFERENCED_PARM( bDelete); - F_UNREFERENCED_PARM( pszBasePath); - #endif - - if( m_pLockFileHdl) - { - - // Release the lock file - - (void)m_pLockFileHdl->close(); - m_pLockFileHdl->Release(); - m_pLockFileHdl = NULL; - - #ifdef FLM_UNIX - if( bDelete) - { - char szTmpPath[ F_PATH_MAX_SIZE]; - - // Delete the lock file - - f_strcpy( szTmpPath, pszBasePath); - gv_pFileSystem->pathAppend( szTmpPath, "64.LCK"); - gv_pFileSystem->Delete( szTmpPath); - } - #endif - } - } - - FINLINE void formatFileNum( - FLMUINT uiFileNum, - char * pszStr) - { - f_sprintf( pszStr, "%08X.64", (unsigned)uiFileNum); - } - - RCODE getFileNum( - const char * pszFileName, - FLMUINT * puiFileNum); - - FINLINE void dataFilePath( - FLMUINT uiFileNum, - char * pszPath) - { - char szFileName[ 13]; - - f_strcpy( pszPath, m_szPath); - formatFileNum( uiFileNum, szFileName); - gv_pFileSystem->pathAppend( pszPath, szFileName); - } - - FINLINE FLMUINT getFileNum( - FLMUINT64 ui64Offset) - { - return( (FLMUINT)(ui64Offset / m_uiMaxFileSize)); - } - - FINLINE FLMUINT getFileOffset( - FLMUINT64 ui64Offset) - { - return( (FLMUINT)(ui64Offset % m_uiMaxFileSize)); - } - - FH_INFO m_pFileHdlList[ F_MULTI_FHDL_LIST_SIZE]; - char m_szPath[ F_PATH_MAX_SIZE]; - FLMBOOL m_bOpen; - FLMUINT64 m_ui64EOF; - FLMUINT m_uiMaxFileSize; - IF_FileHdl * m_pLockFileHdl; - }; - - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_ThreadMgr : public IF_ThreadMgr, public F_Base - { - public: - - F_ThreadMgr() - { - m_hMutex = F_MUTEX_NULL; - m_pThreadList = NULL; - m_uiNumThreads = 0; - } - - virtual ~F_ThreadMgr(); - - RCODE FLMAPI setupThreadMgr( void); - - void FLMAPI shutdownThreadGroup( - FLMUINT uiThreadGroup); - - void FLMAPI setThreadShutdownFlag( - FLMUINT uiThreadId); - - RCODE FLMAPI findThread( - IF_Thread ** ppThread, - FLMUINT uiThreadGroup, - FLMUINT uiAppId = 0, - FLMBOOL bOkToFindMe = TRUE); - - RCODE FLMAPI getNextGroupThread( - IF_Thread ** ppThread, - FLMUINT uiThreadGroup, - FLMUINT * puiThreadId); - - RCODE FLMAPI getThreadInfo( - IF_Pool * pPool, - F_THREAD_INFO ** ppThreadInfo, - FLMUINT * puiNumThreads); - - FLMUINT FLMAPI getThreadGroupCount( - FLMUINT uiThreadGroup); - - inline void lockMutex( void) - { - f_mutexLock( m_hMutex); - } - - inline void unlockMutex( void) - { - f_mutexUnlock( m_hMutex); - } - - void unlinkThread( - IF_Thread * pThread, - FLMBOOL bMutexLocked); - - private: - - F_MUTEX m_hMutex; - F_Thread * m_pThreadList; - FLMUINT m_uiNumThreads; - - friend class F_Thread; - }; - - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_Thread : public IF_Thread, public F_Base - { - public: - - F_Thread() - { - m_hMutex = F_MUTEX_NULL; - m_pszThreadName = NULL; - m_pszThreadStatus = NULL; - m_uiStatusBufLen = 0; - m_pPrev = NULL; - m_pNext = NULL; - cleanupThread(); - } - - virtual ~F_Thread() - { - stopThread(); - cleanupThread(); - } - - FLMINT FLMAPI AddRef( void); - - FLMINT FLMAPI Release( void); - - RCODE FLMAPI startThread( - F_THREAD_FUNC fnThread, - const char * pszThreadName = NULL, - FLMUINT uiThreadGroup = 0, - FLMUINT uiAppId = 0, - void * pvParm1 = NULL, - void * pvParm2 = NULL, - FLMUINT uiStackSize = F_THREAD_DEFAULT_STACK_SIZE); - - void FLMAPI stopThread( void); - - FINLINE FLMUINT FLMAPI getThreadId( void) - { - return( m_uiThreadId); - } - - FINLINE FLMBOOL FLMAPI getShutdownFlag( void) - { - return( m_bShutdown); - } - - FINLINE RCODE FLMAPI getExitCode( void) - { - return( m_exitRc); - } - - FINLINE void * FLMAPI getParm1( void) - { - return( m_pvParm1); - } - - FINLINE void FLMAPI setParm1( - void * pvParm) - { - m_pvParm1 = pvParm; - } - - FINLINE void * FLMAPI getParm2( void) - { - return( m_pvParm2); - } - - FINLINE void FLMAPI setParm2( - void * pvParm) - { - m_pvParm2 = pvParm; - } - - FINLINE void FLMAPI setShutdownFlag( void) - { - m_bShutdown = TRUE; - } - - FINLINE FLMBOOL FLMAPI isThreadRunning( void) - { - return( m_bRunning); - } - - void FLMAPI setThreadStatusStr( - const char * pszStatus); - - void FLMAPI setThreadStatus( - const char * pszBuffer, ...); - - void FLMAPI setThreadStatus( - eThreadStatus genericStatus); - - FINLINE void FLMAPI setThreadAppId( - FLMUINT uiAppId) - { - f_mutexLock( m_hMutex); - m_uiAppId = uiAppId; - f_mutexUnlock( m_hMutex); - } - - FINLINE FLMUINT FLMAPI getThreadAppId( void) - { - return( m_uiAppId); - } - - FINLINE FLMUINT FLMAPI getThreadGroup( void) - { - return( m_uiThreadGroup); - } - - void FLMAPI cleanupThread( void); - - F_MUTEX m_hMutex; - F_Thread * m_pPrev; - F_Thread * m_pNext; - char * m_pszThreadName; - char * m_pszThreadStatus; - FLMUINT m_uiStatusBufLen; - FLMBOOL m_bShutdown; - F_THREAD_FUNC m_fnThread; - FLMBOOL m_bRunning; - FLMUINT m_uiStackSize; - void * m_pvParm1; - void * m_pvParm2; - FLMUINT m_uiThreadId; - FLMUINT m_uiThreadGroup; - FLMUINT m_uiAppId; - FLMUINT m_uiStartTime; - RCODE m_exitRc; - - friend class F_ThreadMgr; - }; - - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_IniFile : public IF_IniFile, public F_Base - { - public: - - F_IniFile(); - - virtual ~F_IniFile(); - - RCODE FLMAPI init( void); - - RCODE FLMAPI read( - const char * pszFileName); - - RCODE FLMAPI write( void); - - FLMBOOL FLMAPI getParam( - const char * pszParamName, - FLMUINT * puiParamVal); - - FLMBOOL FLMAPI getParam( - const char * pszParamName, - FLMBOOL * pbParamVal); - - FLMBOOL FLMAPI getParam( - const char * pszParamName, - char ** ppszParamVal); - - RCODE FLMAPI setParam( - const char * pszParamName, - FLMUINT uiParamVal); - - RCODE FLMAPI setParam( - const char * pszParamName, - FLMBOOL bParamVal); - - RCODE FLMAPI setParam( - const char * pszParamName, - const char * pszParamVal); - - FINLINE FLMBOOL FLMAPI testParam( - const char * pszParamName) - { - if( findParam( pszParamName)) - { - return( TRUE); - } - - return( FALSE); - } - - private: - - RCODE readLine( - char * pucBuf, - FLMUINT * puiBytes, - FLMBOOL * pbMore); - - RCODE parseBuffer( - char * pucBuf, - FLMUINT uiNumButes); - - INI_LINE * findParam( - const char * pszParamName); - - RCODE setParamCommon( - INI_LINE ** ppLine, - const char * pszParamName); - - void fromAscii( - FLMUINT * puiVal, - const char * pszParamValue); - - void fromAscii( - FLMBOOL * pbVal, - const char * pszParamValue); - - RCODE toAscii( - char ** ppszParamValue, - FLMUINT puiVal); - - RCODE toAscii( - char ** ppszParamValue, - FLMBOOL pbVal); - - RCODE toAscii( - char ** ppszParamValue, - const char * pszVal); - - FINLINE FLMBOOL isWhiteSpace( - FLMBYTE ucChar) - { - return( ucChar == 32 || ucChar == 9 ? TRUE : FALSE); - } - - IF_Pool * m_pPool; - IF_FileHdl * m_pFileHdl; - char * m_pszFileName; - INI_LINE * m_pFirstLine; - INI_LINE * m_pLastLine; - FLMBOOL m_bReady; - FLMBOOL m_bModified; - FLMUINT m_uiFileOffset; - }; - /**************************************************************************** Desc: *****************************************************************************/ @@ -4349,427 +1596,296 @@ FLMUINT m_uiOffset; }; - typedef struct + /*************************************************************************** + Desc: + ***************************************************************************/ + #ifdef FLM_WIN + class F_FileHdl : public IF_FileHdl, public F_Base { - FLMUINT32 ui32Offset; - FLMUINT32 ui32Length; - } F_VAR_HEADER; + public: - typedef struct - { - FLMUINT64 ui64FilePos; - FLMUINT uiEntryCount; - FLMUINT uiBlockSize; - FLMBOOL bFirstBlock; - FLMBOOL bLastBlock; - } F_BLOCK_HEADER; + F_FileHdl(); - #define RSBLK_UNSET_FILE_POS (~((FLMUINT64)0)) + virtual ~F_FileHdl(); + + RCODE FLMAPI close( void); + + RCODE FLMAPI flush( void); + + RCODE FLMAPI read( + FLMUINT64 ui64Offset, + FLMUINT uiLength, + void * pvBuffer, + FLMUINT * puiBytesRead); + + RCODE FLMAPI seek( + FLMUINT64 ui64Offset, + FLMINT iWhence, + FLMUINT64 * pui64NewOffset); + + RCODE FLMAPI size( + FLMUINT64 * pui64Size); + + RCODE FLMAPI tell( + FLMUINT64 * pui64Offset); + + RCODE FLMAPI truncate( + FLMUINT64 ui64Size); + + RCODE FLMAPI write( + FLMUINT64 ui64Offset, + FLMUINT uiLength, + const void * pvBuffer, + FLMUINT * puiBytesWritten); + + FINLINE RCODE FLMAPI sectorRead( + FLMUINT64 ui64ReadOffset, + FLMUINT uiBytesToRead, + void * pvBuffer, + FLMUINT * puiBytesReadRV) + { + if (m_bDoDirectIO) + { + return( directRead( ui64ReadOffset, uiBytesToRead, + pvBuffer, TRUE, puiBytesReadRV)); + } + else + { + return( read( ui64ReadOffset, uiBytesToRead, + pvBuffer, puiBytesReadRV)); + } + } + + FINLINE RCODE FLMAPI sectorWrite( + FLMUINT64 ui64WriteOffset, + FLMUINT uiBytesToWrite, + const void * pvBuffer, + FLMUINT uiBufferSize, + void * pvBufferObj, + FLMUINT * puiBytesWrittenRV, + FLMBOOL bZeroFill = TRUE) + { + F_UNREFERENCED_PARM( uiBufferSize); + + if (m_bDoDirectIO) + { + return( directWrite( ui64WriteOffset, uiBytesToWrite, + pvBuffer, (F_IOBuffer *)pvBufferObj, TRUE, + bZeroFill, puiBytesWrittenRV)); + } + else + { + flmAssert( pvBufferObj == NULL); + return( write( ui64WriteOffset, uiBytesToWrite, pvBuffer, + puiBytesWrittenRV)); + } + } + + FINLINE FLMBOOL FLMAPI canDoAsync( void) + { + return( m_bCanDoAsync); + } + + FINLINE void FLMAPI setExtendSize( + FLMUINT uiExtendSize) + { + m_uiExtendSize = uiExtendSize; + } + + FINLINE void FLMAPI setMaxAutoExtendSize( + FLMUINT uiMaxAutoExtendSize) + { + m_uiMaxAutoExtendSize = uiMaxAutoExtendSize; + } + + FINLINE FLMBOOL FLMAPI isReadOnly( void) + { + return( m_bOpenedReadOnly); + } + + FINLINE void FLMAPI setBlockSize( + FLMUINT uiBlockSize) + { + m_uiBlockSize = uiBlockSize; + } + + private: + + RCODE create( + const char * pszFileName, + FLMUINT uiIoFlags); + + RCODE createUnique( + const char * pszDirName, + const char * pszFileExtension, + FLMUINT uiIoFlags); + + RCODE open( + const char * pszFileName, + FLMUINT uiIoFlags); + + FINLINE FLMUINT getSectorSize( void) + { + return( m_uiBytesPerSector); + } + + FINLINE HANDLE getFileHandle( void) + { + return m_FileHandle; + } + + RCODE openOrCreate( + const char * pszFileName, + FLMUINT uiAccess, + FLMBOOL bCreateFlag); + + RCODE allocAlignBuffer( void); + + RCODE doOneRead( + FLMUINT64 ui64Offset, + FLMUINT uiLength, + void * pvBuffer, + FLMUINT * puiBytesRead); + + RCODE directRead( + FLMUINT64 uiOffset, + FLMUINT uiLength, + void * pvBuffer, + FLMBOOL bBuffHasFullSectors, + FLMUINT * puiBytesRead); + + RCODE directWrite( + FLMUINT64 uiOffset, + FLMUINT uiLength, + const void * pvBuffer, + F_IOBuffer * pBufferObj, + FLMBOOL bBuffHasFullSectors, + FLMBOOL bZeroFill, + FLMUINT * puiBytesWritten); + + FINLINE FLMUINT64 roundToNextSector( + FLMUINT64 ui64Bytes) + { + return( (ui64Bytes + m_ui64NotOnSectorBoundMask) & + m_ui64GetSectorBoundMask); + } + + FINLINE FLMUINT64 truncateToPrevSector( + FLMUINT64 ui64Offset) + { + return( ui64Offset & m_ui64GetSectorBoundMask); + } + + RCODE extendFile( + FLMUINT64 ui64EndOfLastWrite, + FLMUINT uiMaxBytesToExtend, + FLMBOOL bFlush); + + FLMBOOL m_bFileOpened; + FLMBOOL m_bDeleteOnRelease; + FLMBOOL m_bOpenedReadOnly; + FLMBOOL m_bOpenedExclusive; + char * m_pszFileName; + HANDLE m_FileHandle; + FLMUINT m_uiBlockSize; + FLMUINT m_uiBytesPerSector; + FLMUINT64 m_ui64NotOnSectorBoundMask; + FLMUINT64 m_ui64GetSectorBoundMask; + FLMBOOL m_bDoDirectIO; + FLMUINT m_uiExtendSize; + FLMUINT m_uiMaxAutoExtendSize; + FLMBYTE * m_pucAlignedBuff; + FLMUINT m_uiAlignedBuffSize; + FLMUINT64 m_ui64CurrentPos; + FLMBOOL m_bCanDoAsync; + OVERLAPPED m_Overlapped; + + friend class F_FileSystem; + friend class F_MultiFileHdl; + }; + #endif /**************************************************************************** - Desc: Result set block + Desc: ****************************************************************************/ - class F_ResultSetBlk : public F_RefCount, public F_Base + + #if defined( FLM_WIN) + + typedef struct + { + HANDLE findHandle; + WIN32_FIND_DATA findBuffer; + char szSearchPath[ F_PATH_MAX_SIZE]; + FLMUINT uiSearchAttrib; + } F_IO_FIND_DATA; + + #elif defined( FLM_UNIX) || defined( FLM_NLM) + + typedef struct + { + mode_t mode_flag; + struct stat FileStat; + char name[ F_PATH_MAX_SIZE+1]; + char search_path[ F_PATH_MAX_SIZE+1]; + char full_path[ F_PATH_MAX_SIZE]; + char pattern_str[ F_PATH_MAX_SIZE]; + char dirpath[ F_PATH_MAX_SIZE]; + glob_t globbuf; + } F_IO_FIND_DATA; + #else + + #error Platform not supported + + #endif + + /**************************************************************************** + Desc: + ****************************************************************************/ + class F_DirHdl : public IF_DirHdl, public F_Base { public: - F_ResultSetBlk(); + F_DirHdl(); - FINLINE ~F_ResultSetBlk() - { - if (m_pNext) - { - m_pNext->m_pPrev = m_pPrev; - } - - if( m_pPrev) - { - m_pPrev->m_pNext = m_pNext; - } - - if (m_pCompare) - { - m_pCompare->Release(); - } - } + virtual ~F_DirHdl(); - void reset( void); + RCODE FLMAPI next( void); - void setup( - IF_MultiFileHdl ** ppMultiFileHdl, - IF_ResultSetCompare * pCompare, - FLMUINT uiEntrySize, - FLMBOOL bFirstInList, - FLMBOOL bDropDuplicates, - FLMBOOL bEntriesInOrder); + const char * FLMAPI currentItemName( void); - RCODE setBuffer( - FLMBYTE * pBuffer, - FLMUINT uiBufferSize = RS_BLOCK_SIZE); + void FLMAPI currentItemPath( + char * pszPath); - FINLINE FLMUINT bytesUsedInBuffer( void) - { - if (m_bEntriesInOrder) - { - return( m_BlockHeader.uiBlockSize); - } - else - { - return( m_BlockHeader.uiBlockSize - m_uiLengthRemaining); - } - } + FLMUINT64 FLMAPI currentItemSize( void); - RCODE addEntry( - FLMBYTE * pEntry, - FLMUINT uiEntryLength ); - - RCODE modifyEntry( - FLMBYTE * pEntry, - FLMUINT uiEntryLength = 0); - - FINLINE RCODE finalize( - FLMBOOL bForceWrite) - { - return( flush( TRUE, bForceWrite)); - } - - RCODE flush( - FLMBOOL bLastBlockInList, - FLMBOOL bForceWrite); - - RCODE getCurrent( - FLMBYTE * pBuffer, - FLMUINT uiBufferLength, - FLMUINT * puiReturnLength); - - FINLINE RCODE getNext( - FLMBYTE * pucBuffer, - FLMUINT uiBufferLength, - FLMUINT * puiReturnLength) - { - // Are we on the last entry or past the last entry? - - if (m_iEntryPos + 1 >= (FLMINT)m_BlockHeader.uiEntryCount) - { - m_iEntryPos = (FLMINT) m_BlockHeader.uiEntryCount; - return RC_SET( NE_FLM_EOF_HIT); - } - - m_iEntryPos++; - return( copyCurrentEntry( pucBuffer, uiBufferLength, puiReturnLength)); - } - - RCODE getNextPtr( - FLMBYTE ** ppBuffer, - FLMUINT * puiReturnLength); - - RCODE getPrev( - FLMBYTE * pBuffer, - FLMUINT uiBufferLength, - FLMUINT * puiReturnLength); - - FINLINE FLMUINT64 getPosition( void) - { - return( (!m_bPositioned || - m_iEntryPos == -1 || - m_iEntryPos == (FLMINT)m_BlockHeader.uiEntryCount - ? RS_POSITION_NOT_SET - : m_ui64BlkEntryPosition + (FLMUINT64)m_iEntryPos)); - } - - RCODE setPosition( - FLMUINT64 ui64Position ); - - RCODE findMatch( - FLMBYTE * pMatchEntry, - FLMUINT uiMatchEntryLength, - FLMBYTE * pFoundEntry, - FLMUINT * puiFoundEntryLength, - FLMINT * piCompare); - - void adjustState( - FLMUINT uiBlkBufferSize); - - RCODE truncate( - FLMBYTE * pszPath); + FLMBOOL FLMAPI currentItemIsDir( void); private: - RCODE addEntry( - FLMBYTE * pucEntry); + RCODE FLMAPI openDir( + const char * pszDirName, + const char * pszPattern); - void squeezeSpace( void); + RCODE FLMAPI createDir( + const char * pszDirName); - RCODE sortAndRemoveDups( void); + RCODE FLMAPI removeDir( + const char * pszDirPath); - void removeEntry( - FLMBYTE * pucEntry); - - RCODE quickSort( - FLMUINT uiLowerBounds, - FLMUINT uiUpperBounds); - - FINLINE RCODE entryCompare( - FLMBYTE * pucLeftEntry, - FLMBYTE * pucRightEntry, - FLMINT * piCompare) - { - RCODE rc; - - if( m_bFixedEntrySize) - { - rc = m_pCompare->compare( pucLeftEntry, m_uiEntrySize, - pucRightEntry, m_uiEntrySize, piCompare); - } - else - { - rc = m_pCompare->compare( - m_pucBlockBuf + ((F_VAR_HEADER *)pucLeftEntry)->ui32Offset, - ((F_VAR_HEADER *)pucLeftEntry)->ui32Length, - m_pucBlockBuf + ((F_VAR_HEADER *)pucRightEntry)->ui32Offset, - ((F_VAR_HEADER *)pucRightEntry)->ui32Length, - piCompare); - } - if (*piCompare == 0) - { - m_bDuplicateFound = TRUE; - } - - return( rc); - } - - RCODE copyCurrentEntry( - FLMBYTE * pBuffer, - FLMUINT uiBufferLength, - FLMUINT * puiReturnLength); - - RCODE compareEntry( - FLMBYTE * pMatchEntry, - FLMUINT uiMatchEntryLength, - FLMUINT uiEntryPos, - FLMINT * piCompare); - - RCODE write(); + char m_szDirectoryPath[ F_PATH_MAX_SIZE]; + char m_szPattern[ F_PATH_MAX_SIZE]; + FLMUINT32 m_ui32RefCount; + RCODE m_rc; + FLMBOOL m_bFirstTime; + FLMBOOL m_bFindOpen; + FLMBOOL m_EOF; + char m_szFileName[ F_PATH_MAX_SIZE]; + FLMUINT m_uiAttrib; + F_IO_FIND_DATA m_FindData; - RCODE read(); - - F_BLOCK_HEADER m_BlockHeader; - IF_ResultSetCompare * m_pCompare; - FLMBYTE * m_pucBlockBuf; - FLMBYTE * m_pucEndPoint; - F_ResultSetBlk * m_pNext; - F_ResultSetBlk * m_pPrev; - IF_MultiFileHdl ** m_ppMultiFileHdl; - FLMUINT64 m_ui64BlkEntryPosition; - FLMUINT m_uiLengthRemaining; - FLMINT m_iEntryPos; - FLMUINT m_uiEntrySize; - FLMBOOL m_bEntriesInOrder; - FLMBOOL m_bFixedEntrySize; - FLMBOOL m_bPositioned; - FLMBOOL m_bModifiedEntry; - FLMBOOL m_bDuplicateFound; - FLMBOOL m_bDropDuplicates; - - friend class F_ResultSet; + friend class F_FileSystem; }; - /***************************************************************************** - Desc: Result set - *****************************************************************************/ - class F_ResultSet : public IF_ResultSet, public F_Base - { - public: - - F_ResultSet(); - - F_ResultSet( - FLMUINT uiBlkSize); - - virtual ~F_ResultSet(); - - RCODE FLMAPI setupResultSet( - const char * pszPath, - IF_ResultSetCompare * pCompare, - FLMUINT uiEntrySize, - FLMBOOL bDropDuplicates = TRUE, - FLMBOOL bEntriesInOrder = FALSE, - const char * pszInputFileName = NULL); - - FINLINE void FLMAPI setSortStatus( - IF_ResultSetSortStatus * pSortStatus) - { - if (m_pSortStatus) - { - m_pSortStatus->Release(); - m_pSortStatus = NULL; - } - - if ((m_pSortStatus = pSortStatus) != NULL) - { - m_pSortStatus->AddRef(); - } - } - - FINLINE FLMUINT64 FLMAPI getTotalEntries( void) - { - F_ResultSetBlk * pBlk = m_pFirstRSBlk; - FLMUINT64 ui64TotalEntries = 0; - - for( pBlk = m_pFirstRSBlk; pBlk; pBlk = pBlk->m_pNext) - { - ui64TotalEntries += pBlk->m_BlockHeader.uiEntryCount; - } - - return( ui64TotalEntries); - } - - RCODE FLMAPI addEntry( - const void * pvEntry, - FLMUINT uiEntryLength = 0); - - RCODE FLMAPI finalizeResultSet( - FLMUINT64 * pui64TotalEntries = NULL); - - RCODE FLMAPI getFirst( - void * pvEntryBuffer, - FLMUINT uiBufferLength = 0, - FLMUINT * puiEntryLength = NULL); - - RCODE FLMAPI getNext( - void * pvEntryBuffer, - FLMUINT uiBufferLength = 0, - FLMUINT * puiEntryLength = NULL); - - RCODE FLMAPI getLast( - void * pvEntryBuffer, - FLMUINT uiBufferLength = 0, - FLMUINT * puiEntryLength = NULL); - - RCODE FLMAPI getPrev( - void * pvEntryBuffer, - FLMUINT uiBufferLength = 0, - FLMUINT * puiEntryLength = NULL); - - RCODE FLMAPI getCurrent( - void * pvEntryBuffer, - FLMUINT uiBufferLength = 0, - FLMUINT * puiEntryLength = NULL); - - FINLINE RCODE FLMAPI modifyCurrent( - const void * pvEntry, - FLMUINT uiEntryLength = 0) - { - return( m_pCurRSBlk->modifyEntry( (FLMBYTE *)pvEntry, uiEntryLength)); - } - - FINLINE RCODE FLMAPI findMatch( - const void * pvMatchEntry, - void * pvFoundEntry) - { - return( findMatch( pvMatchEntry, m_uiEntrySize, - pvFoundEntry, NULL)); - } - - RCODE FLMAPI findMatch( - const void * pvMatchEntry, - FLMUINT uiMatchEntryLength, - void * pvFoundEntry, - FLMUINT * puiFoundEntryLength); - - FINLINE FLMUINT64 FLMAPI getPosition( void) - { - return( (!m_pCurRSBlk - ? RS_POSITION_NOT_SET - : m_pCurRSBlk->getPosition())); - } - - RCODE FLMAPI setPosition( - FLMUINT64 ui64Position); - - RCODE FLMAPI resetResultSet( - FLMBOOL bDelete = TRUE); - - RCODE FLMAPI flushToFile( void); - - private: - - FINLINE FLMUINT64 numberOfBlockChains( void) - { - FLMUINT64 ui64Count = 0; - F_ResultSetBlk * pBlk = m_pFirstRSBlk; - - for (; pBlk ; pBlk = pBlk->m_pNext) - { - if (pBlk->m_BlockHeader.bFirstBlock) - { - ui64Count++; - } - } - - return( ui64Count); - } - - RCODE mergeSort(); - - RCODE getNextPtr( - F_ResultSetBlk ** ppCurBlk, - FLMBYTE * * ppBuffer, - FLMUINT * puiReturnLength); - - RCODE unionBlkLists( - F_ResultSetBlk * pLeftBlk, - F_ResultSetBlk * pRightBlk = NULL); - - RCODE copyRemainingItems( - F_ResultSetBlk * pCurBlk); - - void closeFile( - IF_MultiFileHdl ** ppMultiFileHdl, - FLMBOOL bDelete = TRUE); - - RCODE openFile( - IF_MultiFileHdl ** ppMultiFileHdl); - - F_ResultSetBlk * selectMidpoint( - F_ResultSetBlk * pLowBlk, - F_ResultSetBlk * pHighBlk, - FLMBOOL bPickHighIfNeighbors); - - RCODE setupFromFile( void); - - IF_ResultSetCompare * m_pCompare; - IF_ResultSetSortStatus * m_pSortStatus; - FLMUINT64 m_ui64EstTotalUnits; - FLMUINT64 m_ui64UnitsDone; - FLMUINT m_uiEntrySize; - FLMUINT64 m_ui64TotalEntries; - F_ResultSetBlk * m_pCurRSBlk; - F_ResultSetBlk * m_pFirstRSBlk; - F_ResultSetBlk * m_pLastRSBlk; - char m_szIoDefaultPath[ F_PATH_MAX_SIZE]; - char m_szIoFilePath1[ F_PATH_MAX_SIZE]; - char m_szIoFilePath2[ F_PATH_MAX_SIZE]; - IF_MultiFileHdl * m_pMultiFileHdl1; - IF_MultiFileHdl * m_pMultiFileHdl2; - FLMBYTE * m_pucBlockBuf1; - FLMBYTE * m_pucBlockBuf2; - FLMBYTE * m_pucBlockBuf3; - FLMUINT m_uiBlockBuf1Len; - FLMBOOL m_bFile1Opened; - FLMBOOL m_bFile2Opened; - FLMBOOL m_bOutput2ndFile; - FLMBOOL m_bInitialAdding; - FLMBOOL m_bFinalizeCalled; - FLMBOOL m_bSetupCalled; - FLMBOOL m_bDropDuplicates; - FLMBOOL m_bAppAddsInOrder; - FLMBOOL m_bEntriesInOrder; - FLMUINT m_uiBlkSize; - - friend class F_ResultSetBlk; - }; - /**************************************************************************** Desc: Logging ****************************************************************************/ @@ -4873,1990 +1989,7 @@ : (FLMUINT)((0xFFFFFFFF - (uiEarlierTime)) + (uiLaterTime))) /**************************************************************************** - Desc: XML - ****************************************************************************/ - class F_XML : public IF_XML, public virtual F_Base - { - public: - - F_XML(); - - virtual ~F_XML(); - - RCODE FLMAPI setup( void); - - FLMBOOL FLMAPI isPubidChar( - FLMUNICODE uChar); - - FLMBOOL FLMAPI isQuoteChar( - FLMUNICODE uChar); - - FLMBOOL FLMAPI isWhitespace( - FLMUNICODE uChar); - - FLMBOOL FLMAPI isExtender( - FLMUNICODE uChar); - - FLMBOOL FLMAPI isCombiningChar( - FLMUNICODE uChar); - - FLMBOOL FLMAPI isNameChar( - FLMUNICODE uChar); - - FLMBOOL FLMAPI isNCNameChar( - FLMUNICODE uChar); - - FLMBOOL FLMAPI isIdeographic( - FLMUNICODE uChar); - - FLMBOOL FLMAPI isBaseChar( - FLMUNICODE uChar); - - FLMBOOL FLMAPI isDigit( - FLMUNICODE uChar); - - FLMBOOL FLMAPI isLetter( - FLMUNICODE uChar); - - FLMBOOL FLMAPI isNameValid( - FLMUNICODE * puzName, - FLMBYTE * pszName); - - private: - - void setCharFlag( - FLMUNICODE uLowChar, - FLMUNICODE uHighChar, - FLMUINT16 ui16Flag); - - XMLCHAR * m_pCharTable; - }; - - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_XMLNamespace : public F_RefCount, public F_Base - { - public: - - FINLINE F_XMLNamespace() - { - m_puzPrefix = NULL; - m_puzURI = NULL; - m_pNext = NULL; - } - - virtual FINLINE ~F_XMLNamespace() - { - flmAssert( !m_pNext); - - if( m_puzPrefix) - { - f_free( &m_puzPrefix); - } - - if( m_puzURI) - { - f_free( &m_puzURI); - } - } - - RCODE setPrefix( - FLMUNICODE * puzPrefix); - - RCODE setURI( - FLMUNICODE * puzURI); - - RCODE setup( - FLMUNICODE * puzPrefix, - FLMUNICODE * puzURI, - F_XMLNamespace * pNext); - - FINLINE FLMUNICODE * getPrefixPtr( void) - { - return( m_puzPrefix); - } - - FINLINE FLMUNICODE * getURIPtr( void) - { - return( m_puzURI); - } - - private: - - FLMUNICODE * m_puzPrefix; - FLMUNICODE * m_puzURI; - F_XMLNamespace * m_pNext; - - friend class F_XMLNamespaceMgr; - }; - - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_XMLNamespaceMgr : public F_RefCount, public virtual F_Base - { - public: - - F_XMLNamespaceMgr(); - - virtual ~F_XMLNamespaceMgr(); - - RCODE findNamespace( - FLMUNICODE * puzPrefix, - F_XMLNamespace ** ppNamespace, - FLMUINT uiMaxSearchSize = ~((FLMUINT)0)); - - RCODE pushNamespace( - FLMUNICODE * puzPrefix, - FLMUNICODE * puzNamespaceURI); - - RCODE pushNamespace( - F_XMLNamespace * pNamespace); - - void popNamespaces( - FLMUINT uiCount); - - FLMUINT getNamespaceCount( void) - { - return( m_uiNamespaceCount); - } - - private: - - F_XMLNamespace * m_pFirstNamespace; - FLMUINT m_uiNamespaceCount; - }; - - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_XMLParser : public F_XML, public F_XMLNamespaceMgr - { - public: - - F_XMLParser(); - - ~F_XMLParser(); - - RCODE FLMAPI setup( void); - - void FLMAPI reset( void); - - RCODE FLMAPI import( - IF_IStream * pStream, - FLMUINT uiFlags, - IF_DOMNode * pNodeToLinkTo, - eNodeInsertLoc eInsertLoc, - IF_DOMNode ** ppNewNode, - FLM_IMPORT_STATS * pImportStats); - - FINLINE void FLMAPI setStatusCallback( - XML_STATUS_HOOK fnStatus, - void * pvUserData) - { - m_fnStatus = fnStatus; - m_pvCallbackData = pvUserData; - } - - private: - - #define F_DEFAULT_NS_DECL 0x01 - #define F_PREFIXED_NS_DECL 0x02 - - typedef struct xmlattr - { - FLMUINT uiLineNum; - FLMUINT uiLineOffset; - FLMUINT uiLineFilePos; - FLMUINT uiLineBytes; - FLMUINT uiValueLineNum; - FLMUINT uiValueLineOffset; - FLMUNICODE * puzPrefix; - FLMUNICODE * puzLocalName; - FLMUNICODE * puzVal; - FLMUINT uiFlags; - xmlattr * pPrev; - xmlattr * pNext; - } XML_ATTR; - - // Methods - - RCODE getFieldTagAndType( - FLMUNICODE * puzName, - FLMBOOL bOkToAdd, - FLMUINT * puiTagNum, - FLMUINT * puiDataType); - - RCODE getByte( - FLMBYTE * pucByte); - - FINLINE void ungetByte( - FLMBYTE ucByte) - { - // Can only unget a single byte. - - flmAssert( !m_ucUngetByte); - m_ucUngetByte = ucByte; - m_importStats.uiChars--; - } - - RCODE getLine( void); - - FINLINE FLMUNICODE getChar( void) - { - if (m_uiCurrLineOffset == m_uiCurrLineNumChars) - { - return( (FLMUNICODE)0); - } - else - { - return( m_puzCurrLineBuf [m_uiCurrLineOffset++]); - } - } - - FINLINE FLMUNICODE peekChar( void) - { - if (m_uiCurrLineOffset == m_uiCurrLineNumChars) - { - return( (FLMUNICODE)0); - } - else - { - return( m_puzCurrLineBuf [m_uiCurrLineOffset]); - } - } - - FINLINE void ungetChar( void) - { - flmAssert( m_uiCurrLineOffset); - m_uiCurrLineOffset--; - } - - RCODE getName( - FLMUINT * puiChars); - - RCODE getQualifiedName( - FLMUINT * puiChars, - FLMUNICODE ** ppuzPrefix, - FLMUNICODE ** ppuzLocal, - FLMBOOL * pbNamespaceDecl, - FLMBOOL * pbDefaultNamespaceDecl); - - void getNmtoken( - FLMUINT * puiChars); - - RCODE getPubidLiteral( void); - - RCODE getSystemLiteral( void); - - RCODE getElementValue( - FLMUNICODE * puBuf, - FLMUINT * puiMaxChars, - FLMBOOL * pbEntity); - - RCODE processEntityValue( void); - - RCODE getEntity( - FLMUNICODE * puBuf, - FLMUINT * puiChars, - FLMBOOL * pbTranslated, - FLMUNICODE * puTransChar); - - RCODE processReference( - FLMUNICODE * puChar = NULL); - - RCODE processCDATA( - IF_DOMNode * pParent, - FLMUINT uiSavedLineNum, - FLMUINT uiSavedOffset, - FLMUINT uiSavedFilePos, - FLMUINT uiSavedLineBytes); - - RCODE processAttributeList( void); - - RCODE processComment( - IF_DOMNode * pParent, - FLMUINT uiSavedLineNum, - FLMUINT uiSavedOffset, - FLMUINT uiSavedFilePos, - FLMUINT uiSavedLineBytes); - - RCODE processProlog( void); - - RCODE processXMLDecl( void); - - RCODE processVersion( void); - - RCODE processEncodingDecl( void); - - RCODE processSDDecl( void); - - RCODE processMisc( void); - - RCODE processDocTypeDecl( void); - - RCODE processPI( - IF_DOMNode * pParent, - FLMUINT uiSavedLineNum, - FLMUINT uiSavedOffset, - FLMUINT uiSavedFilePos, - FLMUINT uiSavedLineBytes); - - RCODE processElement( - IF_DOMNode * pNodeToLinkTo, - eNodeInsertLoc eInsertLoc, - IF_DOMNode ** ppNewNode); - - RCODE unicodeToNumber64( - FLMUNICODE * puzVal, - FLMUINT64 * pui64Val, - FLMBOOL * pbNeg); - - RCODE flushElementValue( - IF_DOMNode * pParent, - FLMBYTE * pucValue, - FLMUINT uiValueLen); - - RCODE getBinaryVal( - FLMUINT * puiLength); - - RCODE fixNamingTag( - IF_DOMNode * pNode); - - FLMBOOL lineHasToken( - const char * pszToken); - - RCODE processMarkupDecl( void); - - RCODE processPERef( void); - - RCODE processElementDecl( void); - - RCODE processEntityDecl( void); - - RCODE processNotationDecl( void); - - RCODE processAttListDecl( void); - - RCODE processContentSpec( void); - - RCODE processMixedContent( void); - - RCODE processChildContent( void); - - RCODE processAttDef( void); - - RCODE processAttType( void); - - RCODE processAttValue( - XML_ATTR * pAttr); - - RCODE processDefaultDecl( void); - - RCODE processID( - FLMBOOL bPublicId); - - RCODE processSTag( - IF_DOMNode * pNodeToLinkTo, - eNodeInsertLoc eInsertLoc, - FLMBOOL * pbHasContent, - IF_DOMNode ** ppElement); - - RCODE skipWhitespace( - FLMBOOL bRequired); - - RCODE resizeValBuffer( - FLMUINT uiSize); - - // Attribute management - - void resetAttrList( void) - { - m_pFirstAttr = NULL; - m_pLastAttr = NULL; - m_attrPool.poolReset( NULL); - } - - RCODE allocAttribute( - XML_ATTR ** ppAttr) - { - XML_ATTR * pAttr = NULL; - RCODE rc = NE_FLM_OK; - - if( RC_BAD( rc = m_attrPool.poolCalloc( - sizeof( XML_ATTR), (void **)&pAttr))) - { - goto Exit; - } - - if( (pAttr->pPrev = m_pLastAttr) == NULL) - { - m_pFirstAttr = pAttr; - } - else - { - m_pLastAttr->pNext = pAttr; - } - - m_pLastAttr = pAttr; - - Exit: - - *ppAttr = pAttr; - return( rc); - } - - RCODE setPrefix( - XML_ATTR * pAttr, - FLMUNICODE * puzPrefix) - { - RCODE rc = NE_FLM_OK; - FLMUINT uiStrLen; - - if( !puzPrefix) - { - pAttr->puzPrefix = NULL; - goto Exit; - } - - uiStrLen = f_unilen( puzPrefix); - - if( RC_BAD( rc = m_attrPool.poolAlloc( - sizeof( FLMUNICODE) * (uiStrLen + 1), (void **)&pAttr->puzPrefix))) - { - goto Exit; - } - - f_memcpy( pAttr->puzPrefix, puzPrefix, - sizeof( FLMUNICODE) * (uiStrLen + 1)); - - Exit: - - return( rc); - } - - RCODE setLocalName( - XML_ATTR * pAttr, - FLMUNICODE * puzLocalName) - { - RCODE rc = NE_FLM_OK; - FLMUINT uiStrLen; - - if( !puzLocalName) - { - pAttr->puzLocalName = NULL; - goto Exit; - } - - uiStrLen = f_unilen( puzLocalName); - - if( RC_BAD( rc = m_attrPool.poolAlloc( - sizeof( FLMUNICODE) * (uiStrLen + 1), - (void **)&pAttr->puzLocalName))) - { - goto Exit; - } - - f_memcpy( pAttr->puzLocalName, puzLocalName, - sizeof( FLMUNICODE) * (uiStrLen + 1)); - - Exit: - - return( rc); - } - - RCODE setUnicode( - XML_ATTR * pAttr, - FLMUNICODE * puzUnicode) - { - RCODE rc = NE_FLM_OK; - FLMUINT uiStrLen; - - if( !puzUnicode) - { - pAttr->puzVal = NULL; - goto Exit; - } - - uiStrLen = f_unilen( puzUnicode); - - if( RC_BAD( rc = m_attrPool.poolAlloc( - sizeof( FLMUNICODE) * (uiStrLen + 1), - (void **)&pAttr->puzVal))) - { - goto Exit; - } - - f_memcpy( pAttr->puzVal, puzUnicode, - sizeof( FLMUNICODE) * (uiStrLen + 1)); - - Exit: - - return( rc); - } - - RCODE addAttributesToElement( - IF_DOMNode * pElement); - - FINLINE void setErrInfo( - FLMUINT uiErrLineNum, - FLMUINT uiErrLineOffset, - XMLParseError eErrorType, - FLMUINT uiErrLineFilePos, - FLMUINT uiErrLineBytes) - { - m_importStats.uiErrLineNum = uiErrLineNum; - m_importStats.uiErrLineOffset = uiErrLineOffset; - m_importStats.eErrorType = eErrorType; - m_importStats.uiErrLineFilePos = uiErrLineFilePos; - m_importStats.uiErrLineBytes = uiErrLineBytes; - } - - FLMBYTE m_ucUngetByte; - FLMUNICODE * m_puzCurrLineBuf; - FLMUINT m_uiCurrLineBufMaxChars; - FLMUINT m_uiCurrLineNumChars; - FLMUINT m_uiCurrLineOffset; - FLMUINT m_uiCurrLineNum; - FLMUINT m_uiCurrLineFilePos; - FLMUINT m_uiCurrLineBytes; - #define FLM_XML_MAX_CHARS 128 - FLMUNICODE m_uChars[ FLM_XML_MAX_CHARS]; - FLMBOOL m_bSetup; - IF_IStream * m_pStream; - FLMBYTE * m_pucValBuf; - FLMUINT m_uiValBufSize; // Number of Unicode characters - FLMUINT m_uiFlags; - FLMBOOL m_bExtendDictionary; - XMLEncoding m_eXMLEncoding; - XML_STATUS_HOOK m_fnStatus; - void * m_pvCallbackData; - FLM_IMPORT_STATS m_importStats; - F_Pool m_tmpPool; - XML_ATTR * m_pFirstAttr; - XML_ATTR * m_pLastAttr; - F_Pool m_attrPool; - }; - - #define FLM_XML_EXTEND_DICT_FLAG 0x00000001 - #define FLM_XML_COMPRESS_WHITESPACE_FLAG 0x00000002 - #define FLM_XML_TRANSLATE_ESC_FLAG 0x00000004 - - FINLINE FLMBOOL isXMLNS( - FLMUNICODE * puzName) - { - return( (puzName [0] == FLM_UNICODE_x || puzName [0] == FLM_UNICODE_X) && - (puzName [1] == FLM_UNICODE_m || puzName [1] == FLM_UNICODE_M) && - (puzName [2] == FLM_UNICODE_l || puzName [2] == FLM_UNICODE_L) && - (puzName [3] == FLM_UNICODE_n || puzName [3] == FLM_UNICODE_N) && - (puzName [4] == FLM_UNICODE_s || puzName [4] == FLM_UNICODE_S) - ? TRUE - : FALSE); - } - - /**************************************************************************** - Stuff for F_NameTable class - ****************************************************************************/ - - typedef struct FlmTagInfoTag - { - FLMUINT uiType; - FLMUNICODE * puzTagName; - FLMUINT uiTagNum; - FLMUINT uiDataType; - FLMUNICODE * puzNamespace; - } FLM_TAG_INFO; - - /**************************************************************************** - Desc: Class for name/number lookup. - ****************************************************************************/ - class F_NameTable : public IF_NameTable, public F_Base - { - public: - - F_NameTable(); - - virtual ~F_NameTable(); - - RCODE FLMAPI setupNameTable( void); - - void FLMAPI clearTable( - FLMUINT uiPoolBlkSize); - - RCODE FLMAPI getNextTagTypeAndNumOrder( - FLMUINT uiType, - FLMUINT * puiNextPos, - FLMUNICODE * puzTagName = NULL, - char * pszTagName = NULL, - FLMUINT uiNameBufSize = 0, - FLMUINT * puiTagNum = NULL, - FLMUINT * puiDataType = NULL, - FLMUNICODE * puzNamespace = NULL, - FLMUINT uiNamespaceBufSize = 0, - FLMBOOL bTruncatedNamesOk = TRUE); - - RCODE FLMAPI getNextTagTypeAndNameOrder( - FLMUINT uiType, - FLMUINT * puiNextPos, - FLMUNICODE * puzTagName = NULL, - char * pszTagName = NULL, - FLMUINT uiNameBufSize = 0, - FLMUINT * puiTagNum = NULL, - FLMUINT * puiDataType = NULL, - FLMUNICODE * puzNamespace = NULL, - FLMUINT uiNamespaceBufSize = 0, - FLMBOOL bTruncatedNamesOk = TRUE); - - RCODE FLMAPI getFromTagTypeAndName( - FLMUINT uiType, - const FLMUNICODE * puzTagName, - const char * pszTagName, - FLMBOOL bMatchNamespace, - const FLMUNICODE * puzNamespace = NULL, - FLMUINT * puiTagNum = NULL, - FLMUINT * puiDataType = NULL); - - RCODE FLMAPI getFromTagTypeAndNum( - FLMUINT uiType, - FLMUINT uiTagNum, - FLMUNICODE * puzTagName = NULL, - char * pszTagName = NULL, - FLMUINT * puiNameBufSize = NULL, - FLMUINT * puiDataType = NULL, - FLMUNICODE * puzNamespace = NULL, - char * pszNamespace = NULL, - FLMUINT * puiNamespaceBufSize = NULL, - FLMBOOL bTruncatedNamesOk = TRUE); - - RCODE FLMAPI addTag( - FLMUINT uiType, - FLMUNICODE * puzTagName, - const char * pszTagName, - FLMUINT uiTagNum, - FLMUINT uiDataType = 0, - FLMUNICODE * puzNamespace = NULL, - FLMBOOL bCheckDuplicates = TRUE); - - void FLMAPI removeTag( - FLMUINT uiType, - FLMUINT uiTagNum); - - RCODE FLMAPI cloneNameTable( - IF_NameTable * pSrcNameTable); - - RCODE FLMAPI importFromNameTable( - IF_NameTable * pSrcNameTable); - - FLMINT FLMAPI AddRef( void); - - FLMINT FLMAPI Release( void); - - private: - - void sortTags( void); - - RCODE allocTag( - FLMUINT uiType, - FLMUNICODE * puzTagName, - const char * pszTagName, - FLMUINT uiTagNum, - FLMUINT uiDataType, - FLMUNICODE * puzNamespace, - FLM_TAG_INFO ** ppTagInfo); - - RCODE reallocSortTables( - FLMUINT uiNewTblSize); - - RCODE copyTagName( - FLMUNICODE * puzDestTagName, - char * pszDestTagName, - FLMUINT * puiDestBufSize, - FLMUNICODE * puzSrcTagName, - FLMBOOL bTruncatedNamesOk); - - FLM_TAG_INFO * findTagByTypeAndNum( - FLMUINT uiType, - FLMUINT uiTagNum, - FLMUINT * puiInsertPos = NULL); - - FLM_TAG_INFO * findTagByTypeAndName( - FLMUINT uiType, - const FLMUNICODE * puzTagName, - const char * pszTagName, - FLMBOOL bMatchNamespace, - const FLMUNICODE * puzNamespace, - FLMBOOL * pbAmbiguous, - FLMUINT * puiInsertPos = NULL); - - RCODE insertTagInTables( - FLM_TAG_INFO * pTagInfo, - FLMUINT uiTagTypeAndNameTblInsertPos, - FLMUINT uiTagTypeAndNumTblInsertPos); - - FLMUNICODE * findNamespace( - FLMUNICODE * puzNamespace, - FLMUINT * puiInsertPos); - - RCODE insertNamespace( - FLMUNICODE * puzNamespace, - FLMUINT uiInsertPos); - - F_Pool m_pool; - FLMUINT m_uiMemoryAllocated; - FLM_TAG_INFO ** m_ppSortedByTagTypeAndName; - FLM_TAG_INFO ** m_ppSortedByTagTypeAndNum; - FLMUINT m_uiTblSize; - FLMUINT m_uiNumTags; - FLMBOOL m_bTablesSorted; - FLMUNICODE ** m_ppuzNamespaces; - FLMUINT m_uiNamespaceTblSize; - FLMUINT m_uiNumNamespaces; - F_MUTEX m_hRefMutex; - }; - - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_Btree : public F_RefCount, public F_Base - { - public: - - F_Btree( void); - - virtual ~F_Btree( void); - - RCODE btCreate( - IF_BlockMgr * pBlockMgr, - FLMUINT16 ui16BtreeId, - FLMBOOL bCounts, - FLMBOOL bData, - FLMUINT * puiRootBlkAddr); - - - RCODE btOpen( - IF_BlockMgr * pBlockMgr, - FLMUINT uiRootBlkAddr, - FLMBOOL bCounts, - FLMBOOL bData, - IF_ResultSetCompare * pCompare = NULL); - - void btClose( void); - - RCODE btDeleteTree( - IF_DeleteStatus * ifpDeleteStatus); - - RCODE btGetBlockChains( - FLMUINT * puiBlockChains, - FLMUINT * puiNumLevels); - - RCODE btRemoveEntry( - const FLMBYTE * pucKey, - FLMUINT uiKeyBufSize, - FLMUINT uiKeyLen); - - RCODE btInsertEntry( - const FLMBYTE * pucKey, - FLMUINT uiKeyBufSize, - FLMUINT uiKeyLen, - const FLMBYTE * pucData, - FLMUINT uiDataLen, - FLMBOOL bFirst, - FLMBOOL bLast, - FLMUINT32 * pui32BlkAddr = NULL, - FLMUINT * puiOffsetIndex = NULL); - - RCODE btReplaceEntry( - const FLMBYTE * pucKey, - FLMUINT uiKeyBufSize, - FLMUINT uiKeyLen, - const FLMBYTE * pucData, - FLMUINT uiDataLen, - FLMBOOL bFirst, - FLMBOOL bLast, - FLMBOOL bTruncate = TRUE, - FLMUINT32 * pui32BlkAddr = NULL, - FLMUINT * puiOffsetIndex = NULL); - - RCODE btLocateEntry( - FLMBYTE * pucKey, - FLMUINT uiKeyBufSize, - FLMUINT * puiKeyLen, - FLMUINT uiMatch, - FLMUINT * puiPosition = NULL, - FLMUINT * puiDataLength = NULL, - FLMUINT32 * pui32BlkAddr = NULL, - FLMUINT * puiOffsetIndex = NULL); - - RCODE btGetEntry( - FLMBYTE * pucKey, - FLMUINT uiKeyLen, - FLMBYTE * pucData, - FLMUINT uiDataBufSize, - FLMUINT * puiDataLen); - - RCODE btNextEntry( - FLMBYTE * pucKey, - FLMUINT uiKeyBufSize, - FLMUINT * puiKeyLen, - FLMUINT * puiDataLength = NULL, - FLMUINT32 * pui32BlkAddr = NULL, - FLMUINT * puiOffsetIndex = NULL); - - RCODE btPrevEntry( - FLMBYTE * pucKey, - FLMUINT uiKeyBufSize, - FLMUINT * puiKeyLen, - FLMUINT * puiDataLength = NULL, - FLMUINT32 * pui32BlkAddr = NULL, - FLMUINT * puiOffsetIndex = NULL); - - RCODE btFirstEntry( - FLMBYTE * pucKey, - FLMUINT uiKeyBufSize, - FLMUINT * puiKeyLen, - FLMUINT * puiDataLength = NULL, - FLMUINT32 * pui32BlkAddr = NULL, - FLMUINT * puiOffsetIndex = NULL); - - RCODE btLastEntry( - FLMBYTE * pucKey, - FLMUINT uiKeyBufSize, - FLMUINT * puiKeyLen, - FLMUINT * puiDataLength = NULL, - FLMUINT32 * pui32BlkAddr = NULL, - FLMUINT * puiOffsetIndex = NULL); - - RCODE btSetReadPosition( - FLMBYTE * pucKey, - FLMUINT uiKeyLen, - FLMUINT uiPosition); - - RCODE btGetReadPosition( - FLMUINT * puiPosition); - - RCODE btPositionTo( - FLMUINT uiPosition, - FLMBYTE * pucKey, - FLMUINT uiKeyBufSize, - FLMUINT * puiKeyLen); - - RCODE btGetPosition( - FLMUINT * puiPosition); - - RCODE btCheck( - BTREE_ERR_STRUCT * pErrStruct); - - RCODE btRewind( void); - - FINLINE void btRelease( void) - { - releaseBlocks( TRUE); - } - - FINLINE void btResetBtree( void) - { - releaseBlocks( TRUE); - m_bSetupForRead = FALSE; - m_bSetupForWrite = FALSE; - m_bSetupForReplace = FALSE; - m_bOrigInDOBlocks = FALSE; - m_bDataOnlyBlock = FALSE; - m_ui32PrimaryBlkAddr = 0; - m_ui32CurBlkAddr = 0; - m_uiPrimaryOffset = 0; - m_uiCurOffset = 0; - m_uiDataLength = 0; - m_uiPrimaryDataLen = 0; - m_uiOADataLength = 0; - m_uiDataRemaining = 0; - m_uiOADataRemaining = 0; - m_uiOffsetAtStart = 0; - m_uiSearchLevel = BH_MAX_LEVELS; - } - - RCODE btComputeCounts( - F_Btree * pUntilBtree, - FLMUINT * puiBlkCount, - FLMUINT * puiKeyCount, - FLMBOOL * pbTotalsEstimated, - FLMUINT uiAvgBlkFullness); - - FINLINE void btSetSearchLevel( - FLMUINT uiSearchLevel) - { - flmAssert( uiSearchLevel <= BH_MAX_LEVELS); - - btResetBtree(); - - m_uiSearchLevel = uiSearchLevel; - } - - RCODE btMoveBlock( - FLMUINT32 ui32FromBlkAddr, - FLMUINT32 ui32ToBlkAddr); - - FINLINE FLMBOOL btHasCounts( void) - { - return( m_bCounts); - } - - FINLINE FLMBOOL btHasData( void) - { - return( m_bData); - } - - FINLINE FLMBOOL btDbIsOpen( void) - { - return( m_bOpened); - } - - FINLINE FLMBOOL btIsSetupForRead( void) - { - return( m_bSetupForRead); - } - - FINLINE FLMBOOL btIsSetupForWrite( void) - { - return( m_bSetupForWrite); - } - - FINLINE FLMBOOL btIsSetupForReplace( void) - { - return( m_bSetupForReplace); - } - - private: - - RCODE btFreeBlockChain( - FLMUINT uiStartAddr, - FLMUINT uiBlocksToFree, - FLMUINT * puiBlocksFreed, - FLMUINT * puiEndAddr, - IF_DeleteStatus * ifpDeleteStatus); - - FINLINE FLMUINT calcEntrySize( - FLMUINT uiBlkType, - FLMUINT uiFlags, - FLMUINT uiKeyLen, - FLMUINT uiDataLen, - FLMUINT uiOADataLen) - { - switch( uiBlkType) - { - case BT_LEAF: - { - return( uiKeyLen + 2); - } - - case BT_LEAF_DATA: - { - return( 1 + // Flags - (uiKeyLen > ONE_BYTE_SIZE ? 2 : 1) + // KeyLen - (uiDataLen > ONE_BYTE_SIZE ? 2 : 1) + // DataLen - (uiOADataLen && // OA DataLen - (uiFlags & BTE_FLAG_FIRST_ELEMENT) ? 4 : 0) + - uiKeyLen + uiDataLen); - } - - case BT_NON_LEAF: - case BT_NON_LEAF_COUNTS: - { - return( 4 + // Child block address - (uiBlkType == BT_NON_LEAF_COUNTS ? 4 : 0) + // Counts - 2 + // Key length - uiKeyLen); - } - } - - return( 0); - } - - RCODE computeCounts( - F_BTSK * pFromStack, - F_BTSK * pUntilStack, - FLMUINT * puiBlockCount, - FLMUINT * puiKeyCount, - FLMBOOL * pbTotalsEstimated, - FLMUINT uiAvgBlkFullness); - - RCODE blockCounts( - F_BTSK * pStack, - FLMUINT uiFirstOffset, - FLMUINT uiLastOffset, - FLMUINT * puiKeyCount, - FLMUINT * puiElementCount); - - RCODE getStoredCounts( - F_BTSK * pFromStack, - F_BTSK * pUntilStack, - FLMUINT * puiBlockCount, - FLMUINT * puiKeyCount, - FLMBOOL * pbTotalsEstimated, - FLMUINT uiAvgBlkFullness); - - RCODE getCacheBlocks( - F_BTSK * pStack1, - F_BTSK * pStack2); - - FINLINE FLMUINT getAvgKeyCount( - F_BTSK * pFromStack, - F_BTSK * pUntilStack, - FLMUINT uiAvgBlkFullness); - - FINLINE FLMUINT getBlkEntryCount( - FLMBYTE * pBlk) - { - return ((F_BTREE_BLK_HDR *)pBlk)->ui16NumKeys; - } - - FINLINE FLMUINT getBlkAvailSpace( - FLMBYTE * pBlk) - { - return ((F_BLK_HDR *)pBlk)->ui16BlkBytesAvail; - } - - FLMUINT getEntryKeyLength( - FLMBYTE * pucEntry, - FLMUINT uiBlockType, - const FLMBYTE ** ppucKeyRV); - - FLMUINT getEntrySize( - FLMBYTE * pBlk, - FLMUINT uiOffset, - FLMBYTE ** ppucEntry = NULL); - - RCODE calcNewEntrySize( - FLMUINT uiKeyLen, - FLMUINT uiDataLen, - FLMUINT * puiEntrySize, - FLMBOOL * pbHaveRoom, - FLMBOOL * pbDefragBlk); - - RCODE extractEntryData( - FLMBYTE * pucKey, - FLMUINT uiKeyLen, - FLMBYTE * pucBuffer, - FLMUINT uiBufSiz, - FLMUINT * puiDataLen); - - RCODE updateEntry( - const FLMBYTE * pucKey, - FLMUINT uiKeyLen, - const FLMBYTE * pucValue, - FLMUINT uiLen, - F_ELM_UPD_ACTION eAction, - FLMBOOL bTruncate = TRUE); - - RCODE insertEntry( - const FLMBYTE ** ppucKey, - FLMUINT * puiKeyLen, - const FLMBYTE * pucValue, - FLMUINT uiLen, - FLMUINT uiFlags, - FLMUINT * puiChildBlkAddr, - FLMUINT * puiCounts, - const FLMBYTE ** ppucRemainingValue, - FLMUINT * puiRemainingLen, - F_ELM_UPD_ACTION * peAction); - - RCODE storeEntry( - const FLMBYTE * pucKey, - FLMUINT uiKeyLen, - const FLMBYTE * pucValue, - FLMUINT uiLen, - FLMUINT uiFlags, - FLMUINT uiOADataLen, - FLMUINT uiChildBlkAddr, - FLMUINT uiCounts, - FLMUINT uiEntrySize, - FLMBOOL * pbLastEntry); - - RCODE removeEntry( - const FLMBYTE ** ppucKey, - FLMUINT * puiKeyLen, - FLMUINT * puiChildBlkAddr, - FLMUINT * puiCounts, - FLMBOOL * pbMoreToRemove, - F_ELM_UPD_ACTION * peAction); - - RCODE remove( - FLMBOOL bDeleteDOBlocks); - - RCODE removeRange( - FLMUINT uiStartElm, - FLMUINT uiEndElm, - FLMBOOL bDeleteDOBlocks); - - RCODE findEntry( - const FLMBYTE * pucKey, - FLMUINT uiKeyLen, - FLMUINT uiMatch, - FLMUINT * puiPosition = NULL, - FLMUINT32 * pui32BlkAddr = NULL, - FLMUINT * puiOffsetIndex = NULL); - - RCODE findInBlock( - const FLMBYTE * pucKey, - FLMUINT uiKeyLen, - FLMUINT uiMatch, - FLMUINT * uiPosition, - FLMUINT32 * ui32BlkAddr, - FLMUINT * uiOffsetIndex); - - RCODE scanBlock( - F_BTSK * pStack, - FLMUINT uiMatch); - - RCODE compareKeys( - const FLMBYTE * pucKey1, - FLMUINT uiKeyLen1, - const FLMBYTE * pucKey2, - FLMUINT uiKeyLen2, - FLMINT * piCompare); - - FINLINE RCODE compareBlkKeys( - const FLMBYTE * pucBlockKey, - FLMUINT uiBlockKeyLen, - const FLMBYTE * pucTargetKey, - FLMUINT uiTargetKeyLen, - FLMINT * piCompare) - { - flmAssert( uiBlockKeyLen); - - if( !m_pCompare && uiBlockKeyLen == uiTargetKeyLen) - { - *piCompare = f_memcmp( pucBlockKey, pucTargetKey, uiBlockKeyLen); - - return( NE_FLM_OK); - } - - return( compareKeys( pucBlockKey, uiBlockKeyLen, - pucTargetKey, uiTargetKeyLen, piCompare)); - } - - RCODE positionToEntry( - FLMUINT uiPosition); - - RCODE searchBlock( - F_BTREE_BLK_HDR * pBlkHdr, - FLMUINT * puiPrevCounts, - FLMUINT uiPosition, - FLMUINT * puiOffset); - - RCODE defragmentBlock( - IF_Block ** ppBlock); - - RCODE advanceToNextElement( - FLMBOOL bAdvanceStack); - - RCODE backupToPrevElement( - FLMBOOL bBackupStack); - - RCODE replaceEntry( - const FLMBYTE ** ppucKey, - FLMUINT * puiKeyLen, - const FLMBYTE * pucValue, - FLMUINT uiLen, - FLMUINT uiFlags, - FLMUINT * puiChildBlkAddr, - FLMUINT * puiCounts, - const FLMBYTE ** ppucRemainingValue, - FLMUINT * puiRemainingLen, - F_ELM_UPD_ACTION * peAction, - FLMBOOL bTruncate = TRUE); - - RCODE replaceOldEntry( - const FLMBYTE ** ppucKey, - FLMUINT * puiKeyLen, - const FLMBYTE * pucValue, - FLMUINT uiLen, - FLMUINT uiFlags, - FLMUINT uiOADataLen, - FLMUINT * puiChildBlkAddr, - FLMUINT * puiCounts, - const FLMBYTE ** ppucRemainingValue, - FLMUINT * puiRemainingLen, - F_ELM_UPD_ACTION * peAction, - FLMBOOL bTruncate = TRUE); - - RCODE replaceByInsert( - const FLMBYTE ** ppucKey, - FLMUINT * puiKeyLen, - const FLMBYTE * pucDataValue, - FLMUINT uiDataLen, - FLMUINT uiOADataLen, - FLMUINT uiFlags, - FLMUINT * puiChildBlkAddr, - FLMUINT * puiCounts, - const FLMBYTE ** ppucRemainingValue, - FLMUINT * puiRemainingLen, - F_ELM_UPD_ACTION * peAction); - - RCODE replace( - FLMBYTE * pucEntry, - FLMUINT uiEntrySize, - FLMBOOL * pbLastEntry); - - RCODE buildAndStoreEntry( - FLMUINT uiBlkType, - FLMUINT uiFlags, - const FLMBYTE * pucKey, - FLMUINT uiKeyLen, - const FLMBYTE * pucData, - FLMUINT uiDataLen, - FLMUINT uiOADataLen, - FLMUINT uiChildBlkAddr, - FLMUINT uiCounts, - FLMBYTE * pucBuffer, - FLMUINT uiBufferSize, - FLMUINT * puiEntrySize); - - RCODE moveEntriesToPrevBlk( - FLMUINT uiNewEntrySize, - IF_Block ** ppPrevBlock, - FLMBOOL * pbEntriesWereMoved); - - RCODE moveEntriesToNextBlk( - FLMUINT uiEntrySize, - FLMBOOL * pbEntriesWereMoved); - - RCODE splitBlock( - const FLMBYTE * pucKey, - FLMUINT uiKeyLen, - const FLMBYTE * pucValue, - FLMUINT uiLen, - FLMUINT uiFlags, - FLMUINT uiOADataLen, - FLMUINT uiChildBlkAddr, - FLMUINT uiCounts, - const FLMBYTE ** ppucRemainingValue, - FLMUINT * puiRemainingLen, - FLMBOOL * pbBlockSplit); - - RCODE createNewLevel( void); - - RCODE storeDataOnlyBlocks( - const FLMBYTE * pucKey, - FLMUINT uiKeyLen, - FLMBOOL bSaveKey, - const FLMBYTE * pucData, - FLMUINT uiDataLen); - - RCODE replaceDataOnlyBlocks( - const FLMBYTE * pucKey, - FLMUINT uiKeyLen, - FLMBOOL bSaveKey, - const FLMBYTE * pucData, - FLMUINT uiDataLen, - FLMBOOL bLast, - FLMBOOL bTruncate = TRUE); - - RCODE moveToPrev( - FLMUINT uiStart, - FLMUINT uiFinish, - IF_Block ** ppPrevBlock); - - RCODE moveToNext( - FLMUINT uiStart, - FLMUINT uiFinish, - IF_Block ** ppNextBlock); - - RCODE updateParentCounts( - IF_Block * pChildBlock, - IF_Block ** ppParentBlock, - FLMUINT uiParentElm); - - FLMUINT countKeys( - FLMBYTE * pBlk); - - FLMUINT countRangeOfKeys( - F_BTSK * pFromStack, - FLMUINT uiFromOffset, - FLMUINT uiUntilOffset); - - RCODE moveStackToPrev( - IF_Block * pPrevBlock); - - RCODE moveStackToNext( - IF_Block * pBlock, - FLMBOOL bReleaseCurrent = TRUE); - - RCODE calcOptimalDataLength( - FLMUINT uiKeyLen, - FLMUINT uiDataLen, - FLMUINT uiBytesAvail, - FLMUINT * puiNewDataLen); - - // Performs an integrity check on a chain of data-only blocks - - RCODE verifyDOBlkChain( - FLMUINT uiDOAddr, - FLMUINT uiDataLength, - BTREE_ERR_STRUCT * localErrStruct); - - // Performs a check to verify that the counts in the DB match. - RCODE verifyCounts( - BTREE_ERR_STRUCT * pErrStruct); - - void releaseBlocks( - FLMBOOL bResetStack); - - void releaseBtree( void); - - RCODE saveReplaceInfo( - const FLMBYTE * pucKey, - FLMUINT uiKeyLen); - - RCODE restoreReplaceInfo( - const FLMBYTE ** ppucKey, - FLMUINT * puiKeyLen, - FLMUINT * puiChildBlkAddr, - FLMUINT * puiCounts); - - FINLINE RCODE setReturnKey( - FLMBYTE * pucEntry, - FLMUINT uiBlockType, - FLMBYTE * pucKey, - FLMUINT * puiKeyLen, - FLMUINT uiKeyBufSize); - - RCODE setupReadState( - F_BLK_HDR * pBlkHdr, - FLMBYTE * pucEntry); - - RCODE removeRemainingEntries( - const FLMBYTE * pucKey, - FLMUINT uiKeyLen); - - RCODE deleteEmptyBlock( void); - - RCODE removeDOBlocks( - FLMUINT32 ui32OrigDOAddr); - - RCODE replaceMultiples( - const FLMBYTE ** ppucKey, - FLMUINT * puiKeyLen, - const FLMBYTE * pucDataValue, - FLMUINT uiLen, - FLMUINT uiFlags, - FLMUINT * puiChildBlkAddr, - FLMUINT * puiCounts, - const FLMBYTE ** ppucRemainingValue, - FLMUINT * puiRemainingLen, - F_ELM_UPD_ACTION * peAction); - - RCODE replaceMultiNoTruncate( - const FLMBYTE ** ppucKey, - FLMUINT * puiKeyLen, - const FLMBYTE * pucDataValue, - FLMUINT uiLen, - FLMUINT uiFlags, - FLMUINT * puiChildBlkAddr, - FLMUINT * puiCounts, - const FLMBYTE ** ppucRemainingValue, - FLMUINT * puiRemainingLen, - F_ELM_UPD_ACTION * peAction); - - FINLINE RCODE getNextBlock( - IF_Block ** ppBlock); - - FINLINE RCODE getPrevBlock( - IF_Block ** ppBlock); - - FLMBOOL checkContinuedEntry( - const FLMBYTE * pucKey, - FLMUINT uiKeyLen, - FLMBOOL * pbLastElement, - FLMBYTE * pucEntry, - FLMUINT uiBlkType); - - RCODE updateCounts( void); - - RCODE storePartialEntry( - const FLMBYTE * pucKey, - FLMUINT uiKeyLen, - const FLMBYTE * pucValue, - FLMUINT uiLen, - FLMUINT uiFlags, - FLMUINT uiChildBlkAddr, - FLMUINT uiCounts, - const FLMBYTE ** ppucRemainingValue, - FLMUINT * puiRemainingLen, - FLMBOOL bNewBlock = FALSE); - - RCODE mergeBlocks( - FLMBOOL bLastEntry, - FLMBOOL * pbMergedWithPrev, - FLMBOOL * pbMergedWithNext, - F_ELM_UPD_ACTION * peAction); - - RCODE merge( - IF_Block ** ppFromBlock, - IF_Block ** ppToBlock); - - RCODE checkDownLinks( void); - - RCODE verifyChildLinks( - IF_Block * pParentBlock); - - RCODE combineEntries( - F_BTREE_BLK_HDR * pSrcBlkHdr, - FLMUINT uiSrcOffset, - F_BTREE_BLK_HDR * pDstBlkHdr, - FLMUINT uiDstOffset, - FLMBOOL * pbEntriesCombined, - FLMUINT * puiEntrySize, - FLMBYTE * pucTempBlk); - - RCODE moveBtreeBlock( - FLMUINT32 ui32FromBlkAddr, - FLMUINT32 ui32ToBlkAddr); - - RCODE moveDOBlock( - FLMUINT32 ui32FromBlkAddr, - FLMUINT32 ui32ToBlkAddr); - - IF_BlockMgr * m_pBlockMgr; - F_Pool * m_pPool; - FLMUINT m_uiRootBlkAddr; - FLMBOOL m_bCounts; - FLMBOOL m_bData; - FLMBOOL m_bSetupForRead; - FLMBOOL m_bSetupForWrite; - FLMBOOL m_bSetupForReplace; - FLMBOOL m_bOpened; - FLMBOOL m_bDataOnlyBlock; - FLMBOOL m_bOrigInDOBlocks; - FLMBOOL m_bFirstRead; - FLMBOOL m_bStackSetup; - F_BTSK * m_pStack; - BTREE_REPLACE_STRUCT * m_pReplaceInfo; - BTREE_REPLACE_STRUCT * m_pReplaceStruct; - const FLMBYTE * m_pucDataPtr; - IF_Block * m_pBlock; - F_BTREE_BLK_HDR * m_pBlkHdr; - FLMUINT m_uiBlockSize; - FLMUINT m_uiDefragThreshold; - FLMUINT m_uiOverflowThreshold; - FLMUINT m_uiStackLevels; - FLMUINT m_uiRootLevel; - FLMUINT m_uiReplaceLevels; - FLMUINT m_uiDataLength; - FLMUINT m_uiPrimaryDataLen; - FLMUINT m_uiOADataLength; - FLMUINT m_uiDataRemaining; - FLMUINT m_uiOADataRemaining; - FLMUINT m_uiPrimaryOffset; - FLMUINT m_uiCurOffset; - FLMUINT m_uiSearchLevel; - FLMUINT m_uiOffsetAtStart; - FLMUINT32 m_ui32PrimaryBlkAddr; - FLMUINT32 m_ui32DOBlkAddr; - FLMUINT32 m_ui32CurBlkAddr; - F_BTSK m_Stack[ BH_MAX_LEVELS]; - IF_ResultSetCompare * m_pCompare; - }; - - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_SlabManager : public IF_SlabManager, public F_Base - { - public: - - F_SlabManager(); - - virtual ~F_SlabManager(); - - RCODE FLMAPI setup( - FLMUINT uiPreallocSize); - - RCODE FLMAPI allocSlab( - void ** ppSlab, - FLMBOOL bMutexLocked); - - void FLMAPI freeSlab( - void ** ppSlab, - FLMBOOL bMutexLocked); - - RCODE FLMAPI resize( - FLMUINT uiNumBytes, - FLMUINT * puiActualSize = NULL, - FLMBOOL bMutexLocked = FALSE); - - FINLINE void FLMAPI incrementTotalBytesAllocated( - FLMUINT uiCount, - FLMBOOL bMutexLocked) - { - if( !bMutexLocked) - { - lockMutex(); - } - - m_uiTotalBytesAllocated += uiCount; - - if( !bMutexLocked) - { - unlockMutex(); - } - } - - FINLINE void FLMAPI decrementTotalBytesAllocated( - FLMUINT uiCount, - FLMBOOL bMutexLocked) - { - if( !bMutexLocked) - { - lockMutex(); - } - - flmAssert( m_uiTotalBytesAllocated >= uiCount); - m_uiTotalBytesAllocated -= uiCount; - - if( !bMutexLocked) - { - unlockMutex(); - } - } - - FINLINE FLMUINT FLMAPI getSlabSize( void) - { - return( m_uiSlabSize); - } - - FINLINE FLMUINT FLMAPI getTotalSlabs( void) - { - return( m_uiTotalSlabs); - } - - FINLINE void FLMAPI lockMutex( void) - { - f_mutexLock( m_hMutex); - } - - FINLINE void FLMAPI unlockMutex( void) - { - f_mutexUnlock( m_hMutex); - } - - FINLINE FLMUINT FLMAPI totalBytesAllocated( void) - { - return( m_uiTotalBytesAllocated); - } - - FINLINE FLMUINT FLMAPI availSlabs( void) - { - return( m_uiAvailSlabs); - } - - void FLMAPI protectSlab( - void * pSlab); - - void FLMAPI unprotectSlab( - void * pSlab); - - private: - - void freeAllSlabs( void); - - void * allocSlabFromSystem( void); - - void releaseSlabToSystem( - void * pSlab); - - RCODE sortSlabList( void); - - typedef struct - { - void * pPrev; - void * pNext; - } SLABHEADER; - - static FLMINT FLMAPI slabAddrCompareFunc( - void * pvBuffer, - FLMUINT uiPos1, - FLMUINT uiPos2); - - static void FLMAPI slabAddrSwapFunc( - void * pvBuffer, - FLMUINT uiPos1, - FLMUINT uiPos2); - - F_MUTEX m_hMutex; - FLMUINT m_uiTotalBytesAllocated; - void * m_pFirstInSlabList; - void * m_pLastInSlabList; - FLMUINT m_uiSlabSize; - FLMUINT m_uiTotalSlabs; - FLMUINT m_uiAvailSlabs; - FLMUINT m_uiInUseSlabs; - FLMUINT m_uiPreallocSlabs; - #ifdef FLM_SOLARIS - int m_DevZero; - #endif - - friend class F_FixedAlloc; - }; - - /**************************************************************************** - Desc: Class to provide an efficient means of providing many allocations - of a fixed size. - ****************************************************************************/ - class F_FixedAlloc : public IF_FixedAlloc, public F_Base - { - public: - - F_FixedAlloc(); - - virtual ~F_FixedAlloc(); - - RCODE FLMAPI setup( - IF_Relocator * pRelocator, - IF_SlabManager * pSlabManager, - FLMBOOL bMemProtect, - FLMUINT uiCellSize, - FLM_SLAB_USAGE * pUsageStats); - - FINLINE void * FLMAPI allocCell( - IF_Relocator * pRelocator, - void * pvInitialData = NULL, - FLMUINT uiDataSize = 0, - FLMBOOL bMutexLocked = FALSE) - { - void * pvCell; - - flmAssert( pRelocator); - - if( !bMutexLocked) - { - m_pSlabManager->lockMutex(); - } - - if( (pvCell = getCell( pRelocator)) == NULL) - { - goto Exit; - } - - if( uiDataSize == sizeof( FLMUINT *)) - { - *((FLMUINT *)pvCell) = *((FLMUINT *)pvInitialData); - } - else if( uiDataSize) - { - f_memcpy( pvCell, pvInitialData, uiDataSize); - } - - Exit: - - if( !bMutexLocked) - { - m_pSlabManager->unlockMutex(); - } - - return( pvCell); - } - - FINLINE void FLMAPI freeCell( - void * ptr, - FLMBOOL bMutexLocked) - { - freeCell( ptr, bMutexLocked, FALSE, NULL); - } - - void FLMAPI freeUnused( void); - - void FLMAPI freeAll( void); - - FINLINE FLMUINT FLMAPI getCellSize( void) - { - return( m_uiCellSize); - } - - void FLMAPI defragmentMemory( void); - - void FLMAPI protectCell( - void * pvCell); - - void FLMAPI unprotectCell( - void * pvCell); - - private: - - typedef struct Slab - { - void * pvAllocator; - Slab * pNext; - Slab * pPrev; - Slab * pNextSlabWithAvailCells; - Slab * pPrevSlabWithAvailCells; - FLMBYTE * pLocalAvailCellListHead; - FLMUINT16 ui16NextNeverUsedCell; - FLMUINT16 ui16AvailCellCount; - FLMUINT16 ui16AllocatedCells; - #ifdef FLM_CACHE_PROTECT - FLMUINT32 ui16UnprotectCount; - #endif - } SLAB; - - typedef struct CELLHEADER - { - SLAB * pContainingSlab; - #ifdef FLM_DEBUG - FLMUINT * puiStack; - #endif - } CELLHEADER; - - typedef struct CELLHEADER2 - { - CELLHEADER cellHeader; - IF_Relocator * pRelocator; - } CELLHEADER2; - - typedef struct CellAvailNext - { - FLMBYTE * pNextInList; - #ifdef FLM_DEBUG - FLMBYTE szDebugPattern[ 8]; - #endif - } CELLAVAILNEXT; - - #ifdef FLM_CACHE_PROTECT - void protectSlab( - SLAB * pSlab, - FLMBOOL bMutexLocked); - - void unprotectSlab( - SLAB * pSlab, - FLMBOOL bMutexLocked); - #endif - - void * getCell( - IF_Relocator * pRelocator); - - SLAB * getAnotherSlab( void); - - static FINLINE FLMUINT getAllocAlignedSize( - FLMUINT uiAskedForSize) - { - return( (uiAskedForSize + FLM_ALLOC_ALIGN) & (~FLM_ALLOC_ALIGN)); - } - - void freeSlab( - SLAB * pSlab); - - void freeCell( - void * pCell, - FLMBOOL bMutexLocked, - FLMBOOL bFreeIfEmpty, - FLMBOOL * pbFreedSlab); - - #ifdef FLM_DEBUG - void testForLeaks( void); - #endif - - FINLINE static FLMINT FLMAPI slabAddrCompareFunc( - void * pvBuffer, - FLMUINT uiPos1, - FLMUINT uiPos2) - { - SLAB * pSlab1 = (((SLAB **)pvBuffer)[ uiPos1]); - SLAB * pSlab2 = (((SLAB **)pvBuffer)[ uiPos2]); - - flmAssert( pSlab1 != pSlab2); - - if( pSlab1 < pSlab2) - { - return( -1); - } - - return( 1); - } - - FINLINE static void FLMAPI slabAddrSwapFunc( - void * pvBuffer, - FLMUINT uiPos1, - FLMUINT uiPos2) - { - SLAB ** ppSlab1 = &(((SLAB **)pvBuffer)[ uiPos1]); - SLAB ** ppSlab2 = &(((SLAB **)pvBuffer)[ uiPos2]); - SLAB * pTmp; - - pTmp = *ppSlab1; - *ppSlab1 = *ppSlab2; - *ppSlab2 = pTmp; - } - - IF_SlabManager * m_pSlabManager; - SLAB * m_pFirstSlab; - SLAB * m_pLastSlab; - SLAB * m_pFirstSlabWithAvailCells; - SLAB * m_pLastSlabWithAvailCells; - IF_Relocator * m_pRelocator; - FLMBOOL m_bAvailListSorted; - FLMUINT m_uiSlabsWithAvailCells; - FLMUINT m_uiSlabHeaderSize; - FLMUINT m_uiCellHeaderSize; - FLMUINT m_uiCellSize; - FLMUINT m_uiSizeOfCellAndHeader; - FLMUINT m_uiTotalFreeCells; - FLMUINT m_uiCellsPerSlab; - FLMUINT m_uiSlabSize; - FLM_SLAB_USAGE * m_pUsageStats; - #ifdef FLM_CACHE_PROTECT - FLMBOOL m_bMemProtectionEnabled; - #endif - - friend class F_BufferAlloc; - friend class F_MultiAlloc; - }; - - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_BufferAlloc : public IF_BufferAlloc, public F_Base - { - public: - - F_BufferAlloc() - { - f_memset( m_ppAllocators, 0, sizeof( m_ppAllocators)); - m_pSlabManager = NULL; - } - - virtual ~F_BufferAlloc(); - - RCODE FLMAPI setup( - IF_SlabManager * pSlabManager, - FLMBOOL bMemProtect, - FLM_SLAB_USAGE * pUsageStats); - - RCODE FLMAPI allocBuf( - IF_Relocator * pRelocator, - FLMUINT uiSize, - void * pvInitialData, - FLMUINT uiDataSize, - FLMBYTE ** ppucBuffer, - FLMBOOL * pbAllocatedOnHeap = NULL); - - RCODE FLMAPI reallocBuf( - IF_Relocator * pRelocator, - FLMUINT uiOldSize, - FLMUINT uiNewSize, - void * pvInitialData, - FLMUINT uiDataSize, - FLMBYTE ** ppucBuffer, - FLMBOOL * pbAllocatedOnHeap = NULL); - - void FLMAPI freeBuf( - FLMUINT uiSize, - FLMBYTE ** ppucBuffer); - - FLMUINT FLMAPI getTrueSize( - FLMUINT uiSize, - FLMBYTE * pucBuffer); - - void FLMAPI defragmentMemory( void); - - private: - - IF_FixedAlloc * getAllocator( - FLMUINT uiSize); - - IF_SlabManager * m_pSlabManager; - IF_FixedAlloc * m_ppAllocators[ NUM_BUF_ALLOCATORS]; - }; - - /**************************************************************************** - Desc: - ****************************************************************************/ - class F_MultiAlloc : public IF_MultiAlloc, public F_Base - { - public: - - F_MultiAlloc() - { - m_pSlabManager = NULL; - m_puiCellSizes = NULL; - m_ppAllocators = NULL; - } - - ~F_MultiAlloc() - { - cleanup(); - } - - RCODE FLMAPI setup( - F_SlabManager * pSlabManager, - FLMBOOL bMemProtect, - FLMUINT * puiCellSizes, - FLM_SLAB_USAGE * pUsageStats); - - RCODE FLMAPI allocBuf( - IF_Relocator * pRelocator, - FLMUINT uiSize, - FLMBYTE ** ppucBuffer, - FLMBOOL bMutexLocked = FALSE); - - RCODE FLMAPI reallocBuf( - IF_Relocator * pRelocator, - FLMUINT uiNewSize, - FLMBYTE ** ppucBuffer, - FLMBOOL bMutexLocked = FALSE); - - FINLINE void FLMAPI freeBuf( - FLMBYTE ** ppucBuffer) - { - if( ppucBuffer && *ppucBuffer) - { - getAllocator( *ppucBuffer)->freeCell( *ppucBuffer, FALSE); - *ppucBuffer = NULL; - } - } - - void FLMAPI defragmentMemory( void); - - FINLINE FLMUINT FLMAPI getTrueSize( - FLMBYTE * pucBuffer) - { - return( getAllocator( pucBuffer)->getCellSize()); - } - - void FLMAPI protectBuffer( - void * pvBuffer, - FLMBOOL bMutexLocked = FALSE); - - void FLMAPI unprotectBuffer( - void * pvBuffer, - FLMBOOL bMutexLocked = FALSE); - - FINLINE void FLMAPI lockMutex( void) - { - m_pSlabManager->lockMutex(); - } - - FINLINE void FLMAPI unlockMutex( void) - { - m_pSlabManager->unlockMutex(); - } - - private: - - IF_FixedAlloc * getAllocator( - FLMUINT uiSize); - - IF_FixedAlloc * getAllocator( - FLMBYTE * pucBuffer); - - void cleanup( void); - - IF_SlabManager * m_pSlabManager; - FLMUINT * m_puiCellSizes; - IF_FixedAlloc ** m_ppAllocators; - }; - - /**************************************************************************** - Desc: + Desc: Misc. ****************************************************************************/ FLMUINT flmGetFSBlockSize( FLMBYTE * pszFileName); @@ -6874,4 +2007,22 @@ FLMUINT64 * pui64AvailMem); #endif + void f_memoryInit( void); + + void f_memoryCleanup( void); + + RCODE f_checkErrorCodeTables( void); + + RCODE f_allocFileSystem( + IF_FileSystem ** ppFileSystem); + + RCODE f_allocThreadMgr( + IF_ThreadMgr ** ppThreadMgr); + + RCODE f_allocFileHdl( + F_FileHdl ** ppFileHdl); + + RCODE f_allocDirHdl( + F_DirHdl ** ppDirHdl); + #endif // FTKSYS_H diff --git a/ftk/src/ftktext.cpp b/ftk/src/ftktext.cpp index e892b78..08722af 100644 --- a/ftk/src/ftktext.cpp +++ b/ftk/src/ftktext.cpp @@ -7246,9 +7246,14 @@ RCODE f_verifyMetaphoneRoutines( void) { RCODE rc = NE_FLM_OK; METAPHONE_MAPPING * pMetaMap = gv_MetaTestTable; - F_BufferIStream bufferStream; + IF_BufferIStream * pBufferStream = NULL; FLMUINT uiMeta; FLMUINT uiAltMeta; + + if( RC_BAD( rc = FlmAllocBufferIStream( &pBufferStream))) + { + goto Exit; + } for( ;;) { @@ -7257,13 +7262,13 @@ RCODE f_verifyMetaphoneRoutines( void) break; } - if( RC_BAD( rc = bufferStream.open( + if( RC_BAD( rc = pBufferStream->open( (FLMBYTE *)pMetaMap->pszWord, f_strlen( pMetaMap->pszWord)))) { goto Exit; } - if( RC_BAD( rc = f_getNextMetaphone( &bufferStream, + if( RC_BAD( rc = f_getNextMetaphone( pBufferStream, &uiMeta, &uiAltMeta))) { goto Exit; @@ -7276,12 +7281,17 @@ RCODE f_verifyMetaphoneRoutines( void) goto Exit; } - bufferStream.close(); + pBufferStream->close(); pMetaMap++; } Exit: + if( pBufferStream) + { + pBufferStream->Release(); + } + flmAssert( RC_OK( rc)); return( rc); } diff --git a/ftk/src/ftkthrd.cpp b/ftk/src/ftkthrd.cpp index cf80d54..55ec3d7 100644 --- a/ftk/src/ftkthrd.cpp +++ b/ftk/src/ftkthrd.cpp @@ -36,6 +36,245 @@ void * pvThread); #endif +static F_ThreadMgr * gv_pThreadMgrImp = (F_ThreadMgr *)gv_pThreadMgr; + +/**************************************************************************** +Desc: +****************************************************************************/ +class F_ThreadMgr : public IF_ThreadMgr, public F_Base +{ +public: + + F_ThreadMgr() + { + m_hMutex = F_MUTEX_NULL; + m_pThreadList = NULL; + m_uiNumThreads = 0; + } + + virtual ~F_ThreadMgr(); + + RCODE FLMAPI setupThreadMgr( void); + + RCODE FLMAPI createThread( + IF_Thread ** ppThread, + F_THREAD_FUNC fnThread, + const char * pszThreadName, + FLMUINT uiThreadGroup, + FLMUINT uiAppId, + void * pvParm1, + void * pvParm2, + FLMUINT uiStackSize); + + void FLMAPI shutdownThreadGroup( + FLMUINT uiThreadGroup); + + void FLMAPI setThreadShutdownFlag( + FLMUINT uiThreadId); + + RCODE FLMAPI findThread( + IF_Thread ** ppThread, + FLMUINT uiThreadGroup, + FLMUINT uiAppId = 0, + FLMBOOL bOkToFindMe = TRUE); + + RCODE FLMAPI getNextGroupThread( + IF_Thread ** ppThread, + FLMUINT uiThreadGroup, + FLMUINT * puiThreadId); + + RCODE FLMAPI getThreadInfo( + IF_Pool * pPool, + F_THREAD_INFO ** ppThreadInfo, + FLMUINT * puiNumThreads); + + FLMUINT FLMAPI getThreadGroupCount( + FLMUINT uiThreadGroup); + + inline void lockMutex( void) + { + f_mutexLock( m_hMutex); + } + + inline void unlockMutex( void) + { + f_mutexUnlock( m_hMutex); + } + + void unlinkThread( + IF_Thread * pThread, + FLMBOOL bMutexLocked); + +private: + + F_MUTEX m_hMutex; + F_Thread * m_pThreadList; + FLMUINT m_uiNumThreads; + +friend class F_Thread; +}; + +/**************************************************************************** +Desc: +****************************************************************************/ +class F_Thread : public IF_Thread, public F_Base +{ +public: + + F_Thread() + { + m_hMutex = F_MUTEX_NULL; + m_pszThreadName = NULL; + m_pszThreadStatus = NULL; + m_uiStatusBufLen = 0; + m_pPrev = NULL; + m_pNext = NULL; + cleanupThread(); + } + + virtual ~F_Thread() + { + stopThread(); + cleanupThread(); + } + + FLMINT FLMAPI AddRef( void); + + FLMINT FLMAPI Release( void); + + RCODE FLMAPI startThread( + F_THREAD_FUNC fnThread, + const char * pszThreadName = NULL, + FLMUINT uiThreadGroup = 0, + FLMUINT uiAppId = 0, + void * pvParm1 = NULL, + void * pvParm2 = NULL, + FLMUINT uiStackSize = F_THREAD_DEFAULT_STACK_SIZE); + + void FLMAPI stopThread( void); + + FINLINE FLMUINT FLMAPI getThreadId( void) + { + return( m_uiThreadId); + } + + FINLINE FLMBOOL FLMAPI getShutdownFlag( void) + { + return( m_bShutdown); + } + + FINLINE RCODE FLMAPI getExitCode( void) + { + return( m_exitRc); + } + + FINLINE void * FLMAPI getParm1( void) + { + return( m_pvParm1); + } + + FINLINE void FLMAPI setParm1( + void * pvParm) + { + m_pvParm1 = pvParm; + } + + FINLINE void * FLMAPI getParm2( void) + { + return( m_pvParm2); + } + + FINLINE void FLMAPI setParm2( + void * pvParm) + { + m_pvParm2 = pvParm; + } + + FINLINE void FLMAPI setShutdownFlag( void) + { + m_bShutdown = TRUE; + } + + FINLINE FLMBOOL FLMAPI isThreadRunning( void) + { + return( m_bRunning); + } + + void FLMAPI setThreadStatusStr( + const char * pszStatus); + + void FLMAPI setThreadStatus( + const char * pszBuffer, ...); + + void FLMAPI setThreadStatus( + eThreadStatus genericStatus); + + FINLINE void FLMAPI setThreadAppId( + FLMUINT uiAppId) + { + f_mutexLock( m_hMutex); + m_uiAppId = uiAppId; + f_mutexUnlock( m_hMutex); + } + + FINLINE FLMUINT FLMAPI getThreadAppId( void) + { + return( m_uiAppId); + } + + FINLINE FLMUINT FLMAPI getThreadGroup( void) + { + return( m_uiThreadGroup); + } + + void FLMAPI cleanupThread( void); + + F_MUTEX m_hMutex; + F_Thread * m_pPrev; + F_Thread * m_pNext; + char * m_pszThreadName; + char * m_pszThreadStatus; + FLMUINT m_uiStatusBufLen; + FLMBOOL m_bShutdown; + F_THREAD_FUNC m_fnThread; + FLMBOOL m_bRunning; + FLMUINT m_uiStackSize; + void * m_pvParm1; + void * m_pvParm2; + FLMUINT m_uiThreadId; + FLMUINT m_uiThreadGroup; + FLMUINT m_uiAppId; + FLMUINT m_uiStartTime; + RCODE m_exitRc; + +friend class F_ThreadMgr; +}; + +/**************************************************************************** +Desc: +****************************************************************************/ +RCODE f_allocThreadMgr( + IF_ThreadMgr ** ppThreadMgr) +{ + if( (*ppThreadMgr = f_new F_ThreadMgr) == NULL) + { + return( RC_SET( NE_FLM_MEM)); + } + + return( NE_FLM_OK); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +RCODE FLMAPI FlmGetThreadMgr( + IF_ThreadMgr ** ppThreadMgr) +{ + *ppThreadMgr = gv_pThreadMgr; + (*ppThreadMgr)->AddRef(); + return( NE_FLM_OK); +} + /**************************************************************************** Desc: Add a Reference to this object. ****************************************************************************/ @@ -137,24 +376,24 @@ RCODE FLMAPI F_Thread::startThread( // Lock the thread manager's mutex. - f_mutexLock( gv_pThreadMgr->m_hMutex); + f_mutexLock( gv_pThreadMgrImp->m_hMutex); bManagerMutexLocked = TRUE; // Increment the active thread count - gv_pThreadMgr->m_uiNumThreads++; + gv_pThreadMgrImp->m_uiNumThreads++; // Link the thread into the manager's list. We can't link threads in order // by thread ID at this point, because we don't know what the new thread's // ID will be. - if( gv_pThreadMgr->m_pThreadList) + if( gv_pThreadMgrImp->m_pThreadList) { - gv_pThreadMgr->m_pThreadList->m_pPrev = this; + gv_pThreadMgrImp->m_pThreadList->m_pPrev = this; } - m_pNext = gv_pThreadMgr->m_pThreadList; - gv_pThreadMgr->m_pThreadList = this; + m_pNext = gv_pThreadMgrImp->m_pThreadList; + gv_pThreadMgrImp->m_pThreadList = this; // Increment the reference count of the thread object now // that it is linked into the thread manager's list. @@ -221,7 +460,7 @@ RCODE FLMAPI F_Thread::startThread( // Unlock the thread manager's mutex. - f_mutexUnlock( gv_pThreadMgr->m_hMutex); + f_mutexUnlock( gv_pThreadMgrImp->m_hMutex); bManagerMutexLocked = FALSE; Exit: @@ -231,7 +470,7 @@ Exit: // Unlink the thread from the manager's list. This call // won't do anything if the thread was not linked above. - gv_pThreadMgr->unlinkThread( this, bManagerMutexLocked); + gv_pThreadMgrImp->unlinkThread( this, bManagerMutexLocked); // Reset the thread object back to its initial state @@ -240,7 +479,7 @@ Exit: if( bManagerMutexLocked) { - f_mutexUnlock( gv_pThreadMgr->m_hMutex); + f_mutexUnlock( gv_pThreadMgrImp->m_hMutex); } return( rc); @@ -292,7 +531,7 @@ void * threadStub( // Lock the manager's mutex - gv_pThreadMgr->lockMutex(); + gv_pThreadMgrImp->lockMutex(); // At this point, the thread ID must match. @@ -304,7 +543,7 @@ void * threadStub( // Unlock the manager's mutex - gv_pThreadMgr->unlockMutex(); + gv_pThreadMgrImp->unlockMutex(); // Call the thread's function @@ -318,7 +557,7 @@ void * threadStub( // Unlink the thread from the thread manager. - gv_pThreadMgr->unlinkThread( pThread, FALSE); + gv_pThreadMgrImp->unlinkThread( pThread, FALSE); // Set the running flag to FALSE @@ -932,7 +1171,7 @@ FLMUINT FLMAPI F_ThreadMgr::getThreadGroupCount( /**************************************************************************** Desc: Allocate a thread object and start the thread ****************************************************************************/ -RCODE FLMAPI f_threadCreate( +RCODE FLMAPI F_ThreadMgr::createThread( IF_Thread ** ppThread, F_THREAD_FUNC fnThread, const char * pszThreadName, @@ -942,8 +1181,8 @@ RCODE FLMAPI f_threadCreate( void * pvParm2, FLMUINT uiStackSize) { - RCODE rc = NE_FLM_OK; - F_Thread * pThread = NULL; + RCODE rc = NE_FLM_OK; + F_Thread * pThread = NULL; if( ppThread) { @@ -985,22 +1224,6 @@ Exit: return( rc); } -/**************************************************************************** -Desc: Deletes a thread object and sets the passed-in pointer to NULL -Notes: Should not be used on threads that were started with the - auto-destroy flag set to TRUE -****************************************************************************/ -void FLMAPI f_threadDestroy( - IF_Thread ** ppThread) -{ - if( *ppThread != NULL) - { - (*ppThread)->stopThread(); - (*ppThread)->Release(); - *ppThread = NULL; - } -} - /**************************************************************************** Desc: ****************************************************************************/ diff --git a/ftk/src/ftkunix.cpp b/ftk/src/ftkunix.cpp index b7f890e..3b51c0c 100644 --- a/ftk/src/ftkunix.cpp +++ b/ftk/src/ftkunix.cpp @@ -59,6 +59,183 @@ #include #endif +/*************************************************************************** +Desc: +***************************************************************************/ +class F_FileHdl : public IF_FileHdl, public F_Base +{ +public: + + F_FileHdl(); + + ~F_FileHdl(); + + RCODE FLMAPI setup( + FLMUINT uiFileId); + + RCODE FLMAPI close( void); + + RCODE FLMAPI create( + const char * pszFileName, + FLMUINT uiIoFlags); + + RCODE FLMAPI createUnique( + const char * pszDirName, + const char * pszFileExtension, + FLMUINT uiIoFlags); + + RCODE FLMAPI open( + const char * pszFileName, + FLMUINT uiIoFlags); + + RCODE FLMAPI flush( void); + + RCODE FLMAPI read( + FLMUINT64 ui64Offset, + FLMUINT uiLength, + void * pvBuffer, + FLMUINT * puiBytesRead); + + RCODE FLMAPI seek( + FLMUINT64 ui64Offset, + FLMINT iWhence, + FLMUINT64 * pui64NewOffset); + + RCODE FLMAPI size( + FLMUINT64 * pui64Size); + + RCODE FLMAPI tell( + FLMUINT64 * pui64Offset); + + RCODE FLMAPI truncate( + FLMUINT64 ui64Size); + + RCODE FLMAPI write( + FLMUINT64 ui64Offset, + FLMUINT uiLength, + const void * pvBuffer, + FLMUINT * puiBytesWritten); + + RCODE FLMAPI sectorRead( + FLMUINT64 ui64ReadOffset, + FLMUINT uiBytesToRead, + void * pvBuffer, + FLMUINT * puiBytesReadRV); + + RCODE FLMAPI sectorWrite( + FLMUINT64 ui64WriteOffset, + FLMUINT uiBytesToWrite, + const void * pvBuffer, + FLMUINT uiBufferSize, + void * pvBufferObj, + FLMUINT * puiBytesWrittenRV, + FLMBOOL bZeroFill = TRUE) + { + if( m_bDoDirectIO) + { + return( DirectWrite( ui64WriteOffset, uiBytesToWrite, + pvBuffer, uiBufferSize, (F_IOBuffer *)pvBufferObj, + puiBytesWrittenRV, TRUE, bZeroFill)); + } + else + { + return( Write( ui64WriteOffset, uiBytesToWrite, + pvBuffer, puiBytesWrittenRV)); + } + } + + FLMBOOL FLMAPI canDoAsync( void); + + FINLINE FLMBOOL FLMAPI usingDirectIo( void) + { + return( m_bDoDirectIO); + } + + FINLINE void FLMAPI setExtendSize( + FLMUINT uiExtendSize) + { + m_uiExtendSize = uiExtendSize; + } + + FINLINE void FLMAPI setMaxAutoExtendSize( + FLMUINT uiMaxAutoExtendSize) + { + m_uiMaxAutoExtendSize = uiMaxAutoExtendSize; + } + + RCODE FLMAPI lock( void); + + RCODE FLMAPI unlock( void); + + FINLINE void FLMAPI setBlockSize( + FLMUINT uiBlockSize) + { + m_uiBlockSize = uiBlockSize; + } + + FINLINE FLMUINT FLMAPI getSectorSize( void) + { + return( m_uiBytesPerSector); + } + +private: + + RCODE openOrCreate( + const char * pszFileName, + FLMUINT uiAccess, + FLMBOOL bCreateFlag); + + FINLINE FLMUINT64 roundUpToSectorMultiple( + FLMUINT64 ui64Bytes) + { + return( (ui64Bytes + m_ui64NotOnSectorBoundMask) & + m_ui64GetSectorBoundMask); + } + + FINLINE FLMUINT64 getSectorStartOffset( + FLMUINT64 ui64Offset) + { + return( ui64Offset & m_ui64GetSectorBoundMask); + } + + RCODE directRead( + FLMUINT64 ui64ReadOffset, + FLMUINT uiBytesToRead, + void * pvBuffer, + FLMBOOL bBuffHasFullSectors, + FLMUINT * puiBytesRead); + + RCODE directWrite( + FLMUINT64 ui64WriteOffset, + FLMUINT uiBytesToWrite, + const void * pvBuffer, + FLMUINT uiBufferSize, + F_IOBuffer * pBufferObj, + FLMUINT * puiBytesWrittenRV, + FLMBOOL bBuffHasFullSectors, + FLMBOOL bZeroFill); + + RCODE allocAlignBuffer( void); + + FLMBOOL m_bFileOpened; + FLMBOOL m_bDeleteOnRelease; + FLMBOOL m_bOpenedReadOnly; + FLMBOOL m_bOpenedExclusive; + char * m_pszFileName; + int m_fd; + FLMUINT m_uiBlockSize; + FLMUINT m_uiBytesPerSector; + FLMUINT64 m_ui64NotOnSectorBoundMask; + FLMUINT64 m_ui64GetSectorBoundMask; + FLMUINT64 m_ui64CurrentPos; + FLMUINT m_uiExtendSize; + FLMUINT m_uiMaxAutoExtendSize; + FLMBOOL m_bCanDoAsync; + FLMBOOL m_bDoDirectIO; + FLMBYTE * m_pucAlignedBuff; + FLMUINT m_uiAlignedBuffSize; +}; + /****************************************************************************** Desc: *******************************************************************************/ diff --git a/ftk/src/ftkwin.cpp b/ftk/src/ftkwin.cpp index 5b0a652..bce44f9 100644 --- a/ftk/src/ftkwin.cpp +++ b/ftk/src/ftkwin.cpp @@ -27,111 +27,28 @@ #if defined( FLM_WIN) -RCODE MapWinErrorToFlaim( - DWORD udErrCode, - RCODE defaultRc); - FSTATIC RCODE _DeleteFile( char * path); -/*************************************************************************** -Desc: Maps WIN errors to IO errors. -***************************************************************************/ -RCODE MapWinErrorToFlaim( - DWORD udErrCode, - RCODE defaultRc) +/**************************************************************************** +Desc: +****************************************************************************/ +RCODE f_allocFileHdl( + F_FileHdl ** ppFileHdl) { - - // Switch on passed in error code value - - switch( udErrCode) + if( (*ppFileHdl = f_new F_FileHdl) == NULL) { - case ERROR_NOT_ENOUGH_MEMORY: - case ERROR_OUTOFMEMORY: - return( RC_SET( NE_FLM_MEM)); - - case ERROR_BAD_NETPATH: - case ERROR_BAD_PATHNAME: - case ERROR_DIRECTORY: - case ERROR_FILE_NOT_FOUND: - case ERROR_INVALID_DRIVE: - case ERROR_INVALID_NAME: - case ERROR_NO_NET_OR_BAD_PATH: - case ERROR_PATH_NOT_FOUND: - return( RC_SET( NE_FLM_IO_PATH_NOT_FOUND)); - - case ERROR_ACCESS_DENIED: - case ERROR_SHARING_VIOLATION: - case ERROR_FILE_EXISTS: - case ERROR_ALREADY_EXISTS: - return( RC_SET( NE_FLM_IO_ACCESS_DENIED)); - - case ERROR_BUFFER_OVERFLOW: - case ERROR_FILENAME_EXCED_RANGE: - return( RC_SET( NE_FLM_IO_PATH_TOO_LONG)); - - case ERROR_DISK_FULL: - case ERROR_HANDLE_DISK_FULL: - return( RC_SET( NE_FLM_IO_DISK_FULL)); - - case ERROR_CURRENT_DIRECTORY: - case ERROR_DIR_NOT_EMPTY: - return( RC_SET( NE_FLM_IO_DIRECTORY_ERR)); - - case ERROR_DIRECT_ACCESS_HANDLE: - case ERROR_INVALID_HANDLE: - case ERROR_INVALID_TARGET_HANDLE: - return( RC_SET( NE_FLM_IO_BAD_FILE_HANDLE)); - - case ERROR_HANDLE_EOF: - return( RC_SET( NE_FLM_IO_END_OF_FILE)); - - case ERROR_OPEN_FAILED: - return( RC_SET( NE_FLM_IO_OPEN_ERR)); - - case ERROR_CANNOT_MAKE: - return( RC_SET( NE_FLM_IO_PATH_CREATE_FAILURE)); - - case ERROR_LOCK_FAILED: - case ERROR_LOCK_VIOLATION: - return( RC_SET( NE_FLM_IO_FILE_LOCK_ERR)); - - case ERROR_NEGATIVE_SEEK: - case ERROR_SEEK: - case ERROR_SEEK_ON_DEVICE: - return( RC_SET( NE_FLM_IO_SEEK_ERR)); - - case ERROR_NO_MORE_FILES: - case ERROR_NO_MORE_SEARCH_HANDLES: - return( RC_SET( NE_FLM_IO_NO_MORE_FILES)); - - case ERROR_TOO_MANY_OPEN_FILES: - return( RC_SET( NE_FLM_IO_TOO_MANY_OPEN_FILES)); - - case NO_ERROR: - return( NE_FLM_OK); - - case ERROR_DISK_CORRUPT: - case ERROR_DISK_OPERATION_FAILED: - case ERROR_FILE_CORRUPT: - case ERROR_FILE_INVALID: - case ERROR_NOT_SAME_DEVICE: - case ERROR_IO_DEVICE: - default: - return( RC_SET( defaultRc)); - - } + return( RC_SET( NE_FLM_MEM)); + } + + return( NE_FLM_OK); } - + /**************************************************************************** Desc: ****************************************************************************/ F_FileHdl::F_FileHdl() { - m_pNext = NULL; - m_pPrev = NULL; - m_bInList = FALSE; - m_uiAvailTime = 0; m_bFileOpened = FALSE; m_bDeleteOnRelease = FALSE; m_bOpenedReadOnly = FALSE; @@ -144,7 +61,7 @@ F_FileHdl::F_FileHdl() m_ui64GetSectorBoundMask = 0; m_bDoDirectIO = FALSE; m_uiExtendSize = 0; -// m_uiMaxAutoExtendSize = gv_XFlmSysData.uiMaxFileSize; + m_uiMaxAutoExtendSize = FLM_MAXIMUM_FILE_SIZE; m_pucAlignedBuff = NULL; m_uiAlignedBuffSize = 0; m_ui64CurrentPos = 0; @@ -198,7 +115,7 @@ RCODE F_FileHdl::openOrCreate( m_bDoDirectIO = (uiAccess & FLM_IO_DIRECT) ? TRUE : FALSE; - /* Save the file name in case we have to create the directory. */ + // Save the file name in case we have to create the directory if ((bCreateFlag) && (uiAccess & FLM_IO_CREATE_DIR)) { @@ -318,7 +235,8 @@ Retry_Create: // Remove the file name for which we are creating the directory. - if( RC_OK( gv_pFileSystem->pathReduce( szSaveFileName, szDirPath, szTemp))) + if( RC_OK( gv_pFileSystem->pathReduce( szSaveFileName, + szDirPath, szTemp))) { if( RC_OK( rc = gv_pFileSystem->createDir( szDirPath))) { @@ -331,7 +249,7 @@ Retry_Create: } } - rc = MapWinErrorToFlaim( udErrCode, + rc = MapPlatformError( udErrCode, (RCODE)(bCreateFlag ? (RCODE)(m_bDoDirectIO ? (RCODE)NE_FLM_DIRECT_CREATING_FILE @@ -355,19 +273,16 @@ Exit: /**************************************************************************** Desc: Create a file ****************************************************************************/ -RCODE FLMAPI F_FileHdl::create( +RCODE F_FileHdl::create( const char * pszFileName, - FLMUINT uiIoFlags ) + FLMUINT uiIoFlags) { RCODE rc = NE_FLM_OK; flmAssert( m_bFileOpened == FALSE); - if( m_bDeleteOnRelease) + if( uiIoFlags & FLM_IO_DELETE_ON_RELEASE) { - // This file handle had better not been used for another file - // before. Otherwise, we will get a memory leak. - flmAssert( m_pszFileName == NULL); if( RC_BAD( rc = f_alloc( F_PATH_MAX_SIZE, &m_pszFileName))) @@ -376,6 +291,11 @@ RCODE FLMAPI F_FileHdl::create( } f_strcpy( m_pszFileName, pszFileName); + m_bDeleteOnRelease = TRUE; + } + else + { + m_bDeleteOnRelease = FALSE; } if( RC_BAD( rc = openOrCreate( pszFileName, uiIoFlags, TRUE))) @@ -400,7 +320,7 @@ Exit: /**************************************************************************** Desc: Create a unique file name in the specified directory ****************************************************************************/ -RCODE FLMAPI F_FileHdl::createUnique( +RCODE F_FileHdl::createUnique( const char * pszDirName, const char * pszFileExtension, FLMUINT uiIoFlags) @@ -419,20 +339,19 @@ RCODE FLMAPI F_FileHdl::createUnique( szTmpPath[0] = '\0'; flmAssert( m_bFileOpened == FALSE); - if( m_bDeleteOnRelease) + if( uiIoFlags & FLM_IO_DELETE_ON_RELEASE) { - - // This file handle had better not been used for another file - // before. Otherwise, we will get a memory leak. - flmAssert( m_pszFileName == NULL); - + m_bDeleteOnRelease = TRUE; } + else + { + m_bDeleteOnRelease = FALSE; + } + f_strcpy( szDirPath, pszDirName); - /* - Search backwards replacing trailing spaces with NULLs. - */ + // Search backwards replacing trailing spaces with NULLs. pszTmp = (char *) szDirPath; pszTmp += (f_strlen( pszTmp) - 1); @@ -442,7 +361,7 @@ RCODE FLMAPI F_FileHdl::createUnique( pszTmp--; } - /* Append a backslash if one isn't already there. */ + // Append a backslash if one isn't already there if (pszTmp >= (char *) szDirPath && *pszTmp != '\\') { @@ -463,10 +382,9 @@ RCODE FLMAPI F_FileHdl::createUnique( uiCount = 0; do { - gv_pFileSystem->pathCreateUniqueName( &uiBaseTime, szFileName, pszFileExtension, - &ucHighByte, bModext); + gv_pFileSystem->pathCreateUniqueName( &uiBaseTime, szFileName, + pszFileExtension, &ucHighByte, bModext); - //need to strcpy to the buffer b/c it is uninitialized f_strcpy( szTmpPath, szDirPath); gv_pFileSystem->pathAppend( szTmpPath, szFileName); if( m_pszFileName) @@ -486,7 +404,7 @@ RCODE FLMAPI F_FileHdl::createUnique( } } while ((rc != NE_FLM_OK) && (uiCount++ < 10)); - /* Check if the path was created. */ + // Check if the path was created if ((uiCount >= 10) && (rc != NE_FLM_OK)) { @@ -496,7 +414,8 @@ RCODE FLMAPI F_FileHdl::createUnique( m_bFileOpened = TRUE; m_bOpenedExclusive = (uiIoFlags & FLM_IO_SH_DENYRW) ? TRUE : FALSE; - // Created file name needs to be returned. + // Created file name needs to be returned + f_strcpy( (char *)pszDirName, szTmpPath); Exit: @@ -512,7 +431,7 @@ Exit: /**************************************************************************** Desc: Open a file ****************************************************************************/ -RCODE FLMAPI F_FileHdl::open( +RCODE F_FileHdl::open( const char * pszFileName, FLMUINT uiIoFlags) { @@ -520,12 +439,8 @@ RCODE FLMAPI F_FileHdl::open( flmAssert( m_bFileOpened == FALSE); - if( m_bDeleteOnRelease) + if( uiIoFlags & FLM_IO_DELETE_ON_RELEASE) { - - // This file handle had better not been used for another file - // before. Otherwise, we will get a memory leak. - flmAssert( m_pszFileName == NULL); if( RC_BAD( rc = f_alloc( F_PATH_MAX_SIZE, &m_pszFileName))) @@ -534,6 +449,11 @@ RCODE FLMAPI F_FileHdl::open( } f_strcpy( m_pszFileName, pszFileName); + m_bDeleteOnRelease = TRUE; + } + else + { + m_bDeleteOnRelease = FALSE; } // Loop on error open conditions. @@ -581,14 +501,14 @@ RCODE FLMAPI F_FileHdl::close( void) if (!CloseHandle( m_FileHandle)) { - rc = MapWinErrorToFlaim( GetLastError(), NE_FLM_CLOSING_FILE); + rc = MapPlatformError( GetLastError(), NE_FLM_CLOSING_FILE); goto Exit; } m_FileHandle = INVALID_HANDLE_VALUE; m_bFileOpened = m_bOpenedReadOnly = m_bOpenedExclusive = FALSE; - if (m_bDeleteOnRelease ) + if (m_bDeleteOnRelease) { flmAssert( NULL != m_pszFileName ); @@ -596,6 +516,7 @@ RCODE FLMAPI F_FileHdl::close( void) { (void)_DeleteFile( m_pszFileName); } + m_bDeleteOnRelease = FALSE; f_free( &m_pszFileName); } @@ -616,7 +537,7 @@ RCODE FLMAPI F_FileHdl::flush( void) { if( !FlushFileBuffers( m_FileHandle)) { - rc = MapWinErrorToFlaim( GetLastError(), NE_FLM_FLUSHING_FILE); + rc = MapPlatformError( GetLastError(), NE_FLM_FLUSHING_FILE); } } return( rc); @@ -639,7 +560,7 @@ RCODE F_FileHdl::allocAlignBuffer( void) (DWORD)m_uiAlignedBuffSize, MEM_COMMIT, PAGE_READWRITE)) == NULL) { - rc = MapWinErrorToFlaim( GetLastError(), NE_FLM_MEM); + rc = MapPlatformError( GetLastError(), NE_FLM_MEM); goto Exit; } @@ -668,7 +589,7 @@ RCODE F_FileHdl::doOneRead( liTmp.QuadPart = ui64ReadOffset; if( !SetFilePointerEx( m_FileHandle, liTmp, NULL, FILE_BEGIN)) { - rc = MapWinErrorToFlaim( GetLastError(), NE_FLM_POSITIONING_IN_FILE); + rc = MapPlatformError( GetLastError(), NE_FLM_POSITIONING_IN_FILE); goto Exit; } @@ -681,7 +602,7 @@ RCODE F_FileHdl::doOneRead( if ((m_Overlapped.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL)) == NULL) { - rc = MapWinErrorToFlaim( GetLastError(), + rc = MapPlatformError( GetLastError(), NE_FLM_SETTING_UP_FOR_READ); goto Exit; } @@ -693,7 +614,7 @@ RCODE F_FileHdl::doOneRead( if( !ResetEvent( pOverlapped->hEvent)) { - rc = MapWinErrorToFlaim( GetLastError(), NE_FLM_SETTING_UP_FOR_READ); + rc = MapPlatformError( GetLastError(), NE_FLM_SETTING_UP_FOR_READ); goto Exit; } } @@ -710,13 +631,13 @@ RCODE F_FileHdl::doOneRead( if( !GetOverlappedResult( m_FileHandle, pOverlapped, puiBytesRead, TRUE)) { - rc = MapWinErrorToFlaim( GetLastError(), NE_FLM_READING_FILE); + rc = MapPlatformError( GetLastError(), NE_FLM_READING_FILE); goto Exit; } } else { - rc = MapWinErrorToFlaim( udErr, NE_FLM_READING_FILE); + rc = MapPlatformError( udErr, NE_FLM_READING_FILE); goto Exit; } } @@ -993,7 +914,7 @@ RCODE FLMAPI F_FileHdl::size( if( !GetFileSizeEx( m_FileHandle, &liTmp)) { - rc = MapWinErrorToFlaim( GetLastError(), NE_FLM_GETTING_FILE_SIZE); + rc = MapPlatformError( GetLastError(), NE_FLM_GETTING_FILE_SIZE); goto Exit; } @@ -1032,7 +953,7 @@ RCODE FLMAPI F_FileHdl::truncate( liTmp.QuadPart = ui64Size; if( !SetFilePointerEx( m_FileHandle, liTmp, NULL, FILE_BEGIN)) { - rc = MapWinErrorToFlaim( GetLastError(), NE_FLM_POSITIONING_IN_FILE); + rc = MapPlatformError( GetLastError(), NE_FLM_POSITIONING_IN_FILE); goto Exit; } @@ -1040,7 +961,7 @@ RCODE FLMAPI F_FileHdl::truncate( if( !SetEndOfFile( m_FileHandle)) { - rc = MapWinErrorToFlaim( GetLastError(), NE_FLM_TRUNCATING_FILE); + rc = MapPlatformError( GetLastError(), NE_FLM_TRUNCATING_FILE); goto Exit; } @@ -1116,7 +1037,7 @@ RCODE F_FileHdl::extendFile( liTmp.QuadPart = ui64EndOfLastWrite; if( !SetFilePointerEx( m_FileHandle, liTmp, NULL, FILE_BEGIN)) { - rc = MapWinErrorToFlaim( GetLastError(), + rc = MapPlatformError( GetLastError(), NE_FLM_POSITIONING_IN_FILE); goto Exit; } @@ -1131,7 +1052,7 @@ RCODE F_FileHdl::extendFile( if ((pOverlapped->hEvent = CreateEvent( NULL, TRUE, FALSE, NULL)) == NULL) { - rc = MapWinErrorToFlaim( GetLastError(), + rc = MapPlatformError( GetLastError(), NE_FLM_SETTING_UP_FOR_WRITE); goto Exit; } @@ -1142,7 +1063,7 @@ RCODE F_FileHdl::extendFile( if (!ResetEvent( pOverlapped->hEvent)) { - rc = MapWinErrorToFlaim( GetLastError(), + rc = MapPlatformError( GetLastError(), NE_FLM_SETTING_UP_FOR_WRITE); goto Exit; } @@ -1153,7 +1074,7 @@ RCODE F_FileHdl::extendFile( if( !WriteFile( m_FileHandle, m_pucAlignedBuff, uiBytesToWrite, &uiBytesWritten, pOverlapped)) { - rc = MapWinErrorToFlaim( GetLastError(), NE_FLM_WRITING_FILE); + rc = MapPlatformError( GetLastError(), NE_FLM_WRITING_FILE); // Don't care if it is a disk full error, because // extending the file is optional work. @@ -1187,7 +1108,7 @@ RCODE F_FileHdl::extendFile( { if( !FlushFileBuffers( m_FileHandle)) { - rc = MapWinErrorToFlaim( GetLastError(), NE_FLM_FLUSHING_FILE); + rc = MapPlatformError( GetLastError(), NE_FLM_FLUSHING_FILE); goto Exit; } } @@ -1252,7 +1173,7 @@ RCODE F_FileHdl::directWrite( if( !GetFileSizeEx( m_FileHandle, &liTmp)) { - rc = MapWinErrorToFlaim( GetLastError(), NE_FLM_GETTING_FILE_SIZE); + rc = MapPlatformError( GetLastError(), NE_FLM_GETTING_FILE_SIZE); goto Exit; } @@ -1410,7 +1331,7 @@ RCODE F_FileHdl::directWrite( liTmp.QuadPart = ui64LastWriteOffset; if( !SetFilePointerEx( m_FileHandle, liTmp, NULL, FILE_BEGIN)) { - rc = MapWinErrorToFlaim( GetLastError(), + rc = MapPlatformError( GetLastError(), NE_FLM_POSITIONING_IN_FILE); goto Exit; } @@ -1434,7 +1355,7 @@ RCODE F_FileHdl::directWrite( if ((pOverlapped->hEvent = CreateEvent( NULL, TRUE, FALSE, NULL)) == NULL) { - rc = MapWinErrorToFlaim( GetLastError(), + rc = MapPlatformError( GetLastError(), NE_FLM_SETTING_UP_FOR_WRITE); goto Exit; } @@ -1445,7 +1366,7 @@ RCODE F_FileHdl::directWrite( if (!ResetEvent( pOverlapped->hEvent)) { - rc = MapWinErrorToFlaim( GetLastError(), + rc = MapPlatformError( GetLastError(), NE_FLM_SETTING_UP_FOR_WRITE); goto Exit; } @@ -1478,14 +1399,14 @@ RCODE F_FileHdl::directWrite( if (!GetOverlappedResult( m_FileHandle, pOverlapped, &uiBytesWritten, TRUE)) { - rc = MapWinErrorToFlaim( GetLastError(), + rc = MapPlatformError( GetLastError(), NE_FLM_WRITING_FILE); goto Exit; } } else { - rc = MapWinErrorToFlaim( udErr, NE_FLM_WRITING_FILE); + rc = MapPlatformError( udErr, NE_FLM_WRITING_FILE); goto Exit; } } @@ -1583,7 +1504,7 @@ RCODE FLMAPI F_FileHdl::write( liTmp.QuadPart = ui64WriteOffset; if( !SetFilePointerEx( m_FileHandle, liTmp, NULL, FILE_BEGIN)) { - rc = MapWinErrorToFlaim( GetLastError(), + rc = MapPlatformError( GetLastError(), NE_FLM_POSITIONING_IN_FILE); goto Exit; } @@ -1597,7 +1518,7 @@ RCODE FLMAPI F_FileHdl::write( if ((m_Overlapped.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL)) == NULL) { - rc = MapWinErrorToFlaim( GetLastError(), + rc = MapPlatformError( GetLastError(), NE_FLM_SETTING_UP_FOR_WRITE); goto Exit; } @@ -1609,7 +1530,7 @@ RCODE FLMAPI F_FileHdl::write( if( !ResetEvent( pOverlapped->hEvent)) { - rc = MapWinErrorToFlaim( GetLastError(), + rc = MapPlatformError( GetLastError(), NE_FLM_SETTING_UP_FOR_WRITE); goto Exit; } @@ -1625,13 +1546,13 @@ RCODE FLMAPI F_FileHdl::write( if (!GetOverlappedResult( m_FileHandle, pOverlapped, &uiBytesWritten, TRUE)) { - rc = MapWinErrorToFlaim( GetLastError(), NE_FLM_WRITING_FILE); + rc = MapPlatformError( GetLastError(), NE_FLM_WRITING_FILE); goto Exit; } } else { - rc = MapWinErrorToFlaim( udErr, NE_FLM_WRITING_FILE); + rc = MapPlatformError( udErr, NE_FLM_WRITING_FILE); goto Exit; } } @@ -1663,7 +1584,7 @@ FSTATIC RCODE _DeleteFile( if( DeleteFile( (LPTSTR)pszPath) == FALSE) { - rc = MapWinErrorToFlaim( GetLastError(), NE_FLM_IO_DELETING_FILE); + rc = MapPlatformError( GetLastError(), NE_FLM_IO_DELETING_FILE); } return rc; diff --git a/ftk/src/ftkxml.cpp b/ftk/src/ftkxml.cpp index 41ce3ff..d519343 100644 --- a/ftk/src/ftkxml.cpp +++ b/ftk/src/ftkxml.cpp @@ -25,8 +25,6 @@ #include "ftksys.h" -// Constants - #define FLM_XML_BASE_CHAR 0x01 #define FLM_XML_IDEOGRAPHIC 0x02 #define FLM_XML_COMBINING_CHAR 0x04 @@ -34,16 +32,17 @@ #define FLM_XML_EXTENDER 0x10 #define FLM_XML_WHITESPACE 0x20 -// Local typedefs - +typedef struct xmlChar +{ + FLMBYTE ucFlags; +} XMLCHAR; + typedef struct { char * pszEntity; FLMUINT uiValue; } CharEntity; -// Global data - static FLMUNICODE gv_puzNamespaceDeclPrefix[] = { FLM_UNICODE_x, @@ -470,6 +469,589 @@ FSTATIC RCODE exportUniValue( FLMBOOL bEncodeSpecialChars, FLMUINT uiIndentCount); +/**************************************************************************** +Desc: XML +****************************************************************************/ +class F_XML : public IF_XML, public virtual F_Base +{ +public: + + F_XML(); + + virtual ~F_XML(); + + RCODE FLMAPI setup( void); + + FLMBOOL FLMAPI isPubidChar( + FLMUNICODE uChar); + + FLMBOOL FLMAPI isQuoteChar( + FLMUNICODE uChar); + + FLMBOOL FLMAPI isWhitespace( + FLMUNICODE uChar); + + FLMBOOL FLMAPI isExtender( + FLMUNICODE uChar); + + FLMBOOL FLMAPI isCombiningChar( + FLMUNICODE uChar); + + FLMBOOL FLMAPI isNameChar( + FLMUNICODE uChar); + + FLMBOOL FLMAPI isNCNameChar( + FLMUNICODE uChar); + + FLMBOOL FLMAPI isIdeographic( + FLMUNICODE uChar); + + FLMBOOL FLMAPI isBaseChar( + FLMUNICODE uChar); + + FLMBOOL FLMAPI isDigit( + FLMUNICODE uChar); + + FLMBOOL FLMAPI isLetter( + FLMUNICODE uChar); + + FLMBOOL FLMAPI isNameValid( + FLMUNICODE * puzName, + FLMBYTE * pszName); + +private: + + void setCharFlag( + FLMUNICODE uLowChar, + FLMUNICODE uHighChar, + FLMUINT16 ui16Flag); + + XMLCHAR * m_pCharTable; +}; + +/**************************************************************************** +Desc: +****************************************************************************/ +class F_XMLNamespace : public F_RefCount, public F_Base +{ +public: + + FINLINE F_XMLNamespace() + { + m_puzPrefix = NULL; + m_puzURI = NULL; + m_pNext = NULL; + } + + virtual FINLINE ~F_XMLNamespace() + { + flmAssert( !m_pNext); + + if( m_puzPrefix) + { + f_free( &m_puzPrefix); + } + + if( m_puzURI) + { + f_free( &m_puzURI); + } + } + + RCODE setPrefix( + FLMUNICODE * puzPrefix); + + RCODE setURI( + FLMUNICODE * puzURI); + + RCODE setup( + FLMUNICODE * puzPrefix, + FLMUNICODE * puzURI, + F_XMLNamespace * pNext); + + FINLINE FLMUNICODE * getPrefixPtr( void) + { + return( m_puzPrefix); + } + + FINLINE FLMUNICODE * getURIPtr( void) + { + return( m_puzURI); + } + +private: + + FLMUNICODE * m_puzPrefix; + FLMUNICODE * m_puzURI; + F_XMLNamespace * m_pNext; + +friend class F_XMLNamespaceMgr; +}; + +/**************************************************************************** +Desc: +****************************************************************************/ +class F_XMLNamespaceMgr : public F_RefCount, public virtual F_Base +{ +public: + + F_XMLNamespaceMgr(); + + virtual ~F_XMLNamespaceMgr(); + + RCODE findNamespace( + FLMUNICODE * puzPrefix, + F_XMLNamespace ** ppNamespace, + FLMUINT uiMaxSearchSize = ~((FLMUINT)0)); + + RCODE pushNamespace( + FLMUNICODE * puzPrefix, + FLMUNICODE * puzNamespaceURI); + + RCODE pushNamespace( + F_XMLNamespace * pNamespace); + + void popNamespaces( + FLMUINT uiCount); + + FLMUINT getNamespaceCount( void) + { + return( m_uiNamespaceCount); + } + +private: + + F_XMLNamespace * m_pFirstNamespace; + FLMUINT m_uiNamespaceCount; +}; + +/**************************************************************************** +Desc: +****************************************************************************/ +class F_XMLParser : public F_XML, public F_XMLNamespaceMgr +{ +public: + + F_XMLParser(); + + ~F_XMLParser(); + + RCODE FLMAPI setup( void); + + void FLMAPI reset( void); + + RCODE FLMAPI import( + IF_IStream * pStream, + FLMUINT uiFlags, + IF_DOMNode * pNodeToLinkTo, + eNodeInsertLoc eInsertLoc, + IF_DOMNode ** ppNewNode, + FLM_IMPORT_STATS * pImportStats); + + FINLINE void FLMAPI setStatusCallback( + XML_STATUS_HOOK fnStatus, + void * pvUserData) + { + m_fnStatus = fnStatus; + m_pvCallbackData = pvUserData; + } + +private: + + #define F_DEFAULT_NS_DECL 0x01 + #define F_PREFIXED_NS_DECL 0x02 + + typedef struct xmlattr + { + FLMUINT uiLineNum; + FLMUINT uiLineOffset; + FLMUINT uiLineFilePos; + FLMUINT uiLineBytes; + FLMUINT uiValueLineNum; + FLMUINT uiValueLineOffset; + FLMUNICODE * puzPrefix; + FLMUNICODE * puzLocalName; + FLMUNICODE * puzVal; + FLMUINT uiFlags; + xmlattr * pPrev; + xmlattr * pNext; + } XML_ATTR; + + // Methods + + RCODE getFieldTagAndType( + FLMUNICODE * puzName, + FLMBOOL bOkToAdd, + FLMUINT * puiTagNum, + FLMUINT * puiDataType); + + RCODE getByte( + FLMBYTE * pucByte); + + FINLINE void ungetByte( + FLMBYTE ucByte) + { + // Can only unget a single byte. + + flmAssert( !m_ucUngetByte); + m_ucUngetByte = ucByte; + m_importStats.uiChars--; + } + + RCODE getLine( void); + + FINLINE FLMUNICODE getChar( void) + { + if (m_uiCurrLineOffset == m_uiCurrLineNumChars) + { + return( (FLMUNICODE)0); + } + else + { + return( m_puzCurrLineBuf [m_uiCurrLineOffset++]); + } + } + + FINLINE FLMUNICODE peekChar( void) + { + if (m_uiCurrLineOffset == m_uiCurrLineNumChars) + { + return( (FLMUNICODE)0); + } + else + { + return( m_puzCurrLineBuf [m_uiCurrLineOffset]); + } + } + + FINLINE void ungetChar( void) + { + flmAssert( m_uiCurrLineOffset); + m_uiCurrLineOffset--; + } + + RCODE getName( + FLMUINT * puiChars); + + RCODE getQualifiedName( + FLMUINT * puiChars, + FLMUNICODE ** ppuzPrefix, + FLMUNICODE ** ppuzLocal, + FLMBOOL * pbNamespaceDecl, + FLMBOOL * pbDefaultNamespaceDecl); + + void getNmtoken( + FLMUINT * puiChars); + + RCODE getPubidLiteral( void); + + RCODE getSystemLiteral( void); + + RCODE getElementValue( + FLMUNICODE * puBuf, + FLMUINT * puiMaxChars, + FLMBOOL * pbEntity); + + RCODE processEntityValue( void); + + RCODE getEntity( + FLMUNICODE * puBuf, + FLMUINT * puiChars, + FLMBOOL * pbTranslated, + FLMUNICODE * puTransChar); + + RCODE processReference( + FLMUNICODE * puChar = NULL); + + RCODE processCDATA( + IF_DOMNode * pParent, + FLMUINT uiSavedLineNum, + FLMUINT uiSavedOffset, + FLMUINT uiSavedFilePos, + FLMUINT uiSavedLineBytes); + + RCODE processAttributeList( void); + + RCODE processComment( + IF_DOMNode * pParent, + FLMUINT uiSavedLineNum, + FLMUINT uiSavedOffset, + FLMUINT uiSavedFilePos, + FLMUINT uiSavedLineBytes); + + RCODE processProlog( void); + + RCODE processXMLDecl( void); + + RCODE processVersion( void); + + RCODE processEncodingDecl( void); + + RCODE processSDDecl( void); + + RCODE processMisc( void); + + RCODE processDocTypeDecl( void); + + RCODE processPI( + IF_DOMNode * pParent, + FLMUINT uiSavedLineNum, + FLMUINT uiSavedOffset, + FLMUINT uiSavedFilePos, + FLMUINT uiSavedLineBytes); + + RCODE processElement( + IF_DOMNode * pNodeToLinkTo, + eNodeInsertLoc eInsertLoc, + IF_DOMNode ** ppNewNode); + + RCODE unicodeToNumber64( + FLMUNICODE * puzVal, + FLMUINT64 * pui64Val, + FLMBOOL * pbNeg); + + RCODE flushElementValue( + IF_DOMNode * pParent, + FLMBYTE * pucValue, + FLMUINT uiValueLen); + + RCODE getBinaryVal( + FLMUINT * puiLength); + + RCODE fixNamingTag( + IF_DOMNode * pNode); + + FLMBOOL lineHasToken( + const char * pszToken); + + RCODE processMarkupDecl( void); + + RCODE processPERef( void); + + RCODE processElementDecl( void); + + RCODE processEntityDecl( void); + + RCODE processNotationDecl( void); + + RCODE processAttListDecl( void); + + RCODE processContentSpec( void); + + RCODE processMixedContent( void); + + RCODE processChildContent( void); + + RCODE processAttDef( void); + + RCODE processAttType( void); + + RCODE processAttValue( + XML_ATTR * pAttr); + + RCODE processDefaultDecl( void); + + RCODE processID( + FLMBOOL bPublicId); + + RCODE processSTag( + IF_DOMNode * pNodeToLinkTo, + eNodeInsertLoc eInsertLoc, + FLMBOOL * pbHasContent, + IF_DOMNode ** ppElement); + + RCODE skipWhitespace( + FLMBOOL bRequired); + + RCODE resizeValBuffer( + FLMUINT uiSize); + + // Attribute management + + void resetAttrList( void) + { + m_pFirstAttr = NULL; + m_pLastAttr = NULL; + m_pAttrPool->poolReset( NULL); + } + + RCODE allocAttribute( + XML_ATTR ** ppAttr) + { + XML_ATTR * pAttr = NULL; + RCODE rc = NE_FLM_OK; + + if( RC_BAD( rc = m_pAttrPool->poolCalloc( + sizeof( XML_ATTR), (void **)&pAttr))) + { + goto Exit; + } + + if( (pAttr->pPrev = m_pLastAttr) == NULL) + { + m_pFirstAttr = pAttr; + } + else + { + m_pLastAttr->pNext = pAttr; + } + + m_pLastAttr = pAttr; + + Exit: + + *ppAttr = pAttr; + return( rc); + } + + RCODE setPrefix( + XML_ATTR * pAttr, + FLMUNICODE * puzPrefix) + { + RCODE rc = NE_FLM_OK; + FLMUINT uiStrLen; + + if( !puzPrefix) + { + pAttr->puzPrefix = NULL; + goto Exit; + } + + uiStrLen = f_unilen( puzPrefix); + + if( RC_BAD( rc = m_pAttrPool->poolAlloc( + sizeof( FLMUNICODE) * (uiStrLen + 1), (void **)&pAttr->puzPrefix))) + { + goto Exit; + } + + f_memcpy( pAttr->puzPrefix, puzPrefix, + sizeof( FLMUNICODE) * (uiStrLen + 1)); + + Exit: + + return( rc); + } + + RCODE setLocalName( + XML_ATTR * pAttr, + FLMUNICODE * puzLocalName) + { + RCODE rc = NE_FLM_OK; + FLMUINT uiStrLen; + + if( !puzLocalName) + { + pAttr->puzLocalName = NULL; + goto Exit; + } + + uiStrLen = f_unilen( puzLocalName); + + if( RC_BAD( rc = m_pAttrPool->poolAlloc( + sizeof( FLMUNICODE) * (uiStrLen + 1), + (void **)&pAttr->puzLocalName))) + { + goto Exit; + } + + f_memcpy( pAttr->puzLocalName, puzLocalName, + sizeof( FLMUNICODE) * (uiStrLen + 1)); + + Exit: + + return( rc); + } + + RCODE setUnicode( + XML_ATTR * pAttr, + FLMUNICODE * puzUnicode) + { + RCODE rc = NE_FLM_OK; + FLMUINT uiStrLen; + + if( !puzUnicode) + { + pAttr->puzVal = NULL; + goto Exit; + } + + uiStrLen = f_unilen( puzUnicode); + + if( RC_BAD( rc = m_pAttrPool->poolAlloc( + sizeof( FLMUNICODE) * (uiStrLen + 1), + (void **)&pAttr->puzVal))) + { + goto Exit; + } + + f_memcpy( pAttr->puzVal, puzUnicode, + sizeof( FLMUNICODE) * (uiStrLen + 1)); + + Exit: + + return( rc); + } + + RCODE addAttributesToElement( + IF_DOMNode * pElement); + + FINLINE void setErrInfo( + FLMUINT uiErrLineNum, + FLMUINT uiErrLineOffset, + XMLParseError eErrorType, + FLMUINT uiErrLineFilePos, + FLMUINT uiErrLineBytes) + { + m_importStats.uiErrLineNum = uiErrLineNum; + m_importStats.uiErrLineOffset = uiErrLineOffset; + m_importStats.eErrorType = eErrorType; + m_importStats.uiErrLineFilePos = uiErrLineFilePos; + m_importStats.uiErrLineBytes = uiErrLineBytes; + } + + FLMBYTE m_ucUngetByte; + FLMUNICODE * m_puzCurrLineBuf; + FLMUINT m_uiCurrLineBufMaxChars; + FLMUINT m_uiCurrLineNumChars; + FLMUINT m_uiCurrLineOffset; + FLMUINT m_uiCurrLineNum; + FLMUINT m_uiCurrLineFilePos; + FLMUINT m_uiCurrLineBytes; +#define FLM_XML_MAX_CHARS 128 + FLMUNICODE m_uChars[ FLM_XML_MAX_CHARS]; + FLMBOOL m_bSetup; + IF_IStream * m_pStream; + FLMBYTE * m_pucValBuf; + FLMUINT m_uiValBufSize; // Number of Unicode characters + FLMUINT m_uiFlags; + FLMBOOL m_bExtendDictionary; + XMLEncoding m_eXMLEncoding; + XML_STATUS_HOOK m_fnStatus; + void * m_pvCallbackData; + FLM_IMPORT_STATS m_importStats; + XML_ATTR * m_pFirstAttr; + XML_ATTR * m_pLastAttr; + IF_Pool * m_pTmpPool; + IF_Pool * m_pAttrPool; +}; + +#define FLM_XML_EXTEND_DICT_FLAG 0x00000001 +#define FLM_XML_COMPRESS_WHITESPACE_FLAG 0x00000002 +#define FLM_XML_TRANSLATE_ESC_FLAG 0x00000004 + +FINLINE FLMBOOL isXMLNS( + FLMUNICODE * puzName) +{ + return( (puzName [0] == FLM_UNICODE_x || puzName [0] == FLM_UNICODE_X) && + (puzName [1] == FLM_UNICODE_m || puzName [1] == FLM_UNICODE_M) && + (puzName [2] == FLM_UNICODE_l || puzName [2] == FLM_UNICODE_L) && + (puzName [3] == FLM_UNICODE_n || puzName [3] == FLM_UNICODE_N) && + (puzName [4] == FLM_UNICODE_s || puzName [4] == FLM_UNICODE_S) + ? TRUE + : FALSE); +} + /**************************************************************************** Desc: ****************************************************************************/ @@ -787,10 +1369,11 @@ F_XMLParser::F_XMLParser() m_bSetup = FALSE; m_fnStatus = NULL; m_pvCallbackData = NULL; - m_tmpPool.poolInit( 4096); - m_attrPool.poolInit( 4096); m_puzCurrLineBuf = NULL; m_uiCurrLineBufMaxChars = 0; + m_pTmpPool = NULL; + m_pAttrPool = NULL; + reset(); } @@ -805,10 +1388,21 @@ F_XMLParser::~F_XMLParser() { f_free( &m_pucValBuf); } + if (m_puzCurrLineBuf) { f_free( &m_puzCurrLineBuf); } + + if( m_pTmpPool) + { + m_pTmpPool->Release(); + } + + if( m_pAttrPool) + { + m_pAttrPool->Release(); + } } /**************************************************************************** @@ -828,7 +1422,7 @@ void FLMAPI F_XMLParser::reset( void) f_memset( &m_importStats, 0, sizeof( FLM_IMPORT_STATS)); popNamespaces( getNamespaceCount()); - m_tmpPool.poolReset( NULL); + m_pTmpPool->poolReset( NULL); resetAttrList(); } @@ -850,7 +1444,20 @@ RCODE FLMAPI F_XMLParser::setup( void) { goto Exit; } - + + if( RC_BAD( rc = FlmAllocPool( &m_pTmpPool))) + { + goto Exit; + } + + m_pTmpPool->poolInit( 4096); + + if( RC_BAD( rc = FlmAllocPool( &m_pAttrPool))) + { + goto Exit; + } + + m_pAttrPool->poolInit( 4096); m_bSetup = TRUE; Exit: @@ -1592,7 +2199,7 @@ RCODE F_XMLParser::processSTag( FLMUNICODE * puzLocal = NULL; FLMUINT uiNameId = 0; FLMUINT uiAllocSize; - void * pvMark = m_tmpPool.poolMark(); + void * pvMark = m_pTmpPool->poolMark(); FLMBOOL bNamespaceDecl; FLMUINT uiSavedLineNum; FLMUINT uiSavedOffset; @@ -1636,7 +2243,7 @@ RCODE F_XMLParser::processSTag( } uiAllocSize = (f_unilen( puzTmpLocal) + 1) * sizeof( FLMUNICODE); - if( RC_BAD( rc = m_tmpPool.poolAlloc( uiAllocSize, (void **)&puzLocal))) + if( RC_BAD( rc = m_pTmpPool->poolAlloc( uiAllocSize, (void **)&puzLocal))) { goto Exit; } @@ -1649,7 +2256,7 @@ RCODE F_XMLParser::processSTag( // continues, the scratch buffer will be overwritten uiAllocSize = (f_unilen( puzTmpPrefix) + 1) * sizeof( FLMUNICODE); - if( RC_BAD( rc = m_tmpPool.poolAlloc( uiAllocSize, (void **)&puzPrefix))) + if( RC_BAD( rc = m_pTmpPool->poolAlloc( uiAllocSize, (void **)&puzPrefix))) { goto Exit; } @@ -1821,7 +2428,7 @@ Exit: pNamespace->Release(); } - m_tmpPool.poolReset( pvMark); + m_pTmpPool->poolReset( pvMark); return( rc); }