/**************************************************************************** Desc: ****************************************************************************/ RCODE JNIBackupClient::WriteData( const void * pvBuffer, FLMUINT uiBytesToWrite) { RCODE rc = NE_XFLM_OK; JNIEnv * pEnv; jclass Cls; jmethodID MId; jbyteArray jBuff = NULL; void * pvBuff; FLMBOOL bMustDetach = FALSE; if (m_pJvm->GetEnv( (void **)&pEnv, JNI_VERSION_1_2) != JNI_OK) { if (m_pJvm->AttachCurrentThread( (void **)&pEnv, NULL) != 0) { rc = RC_SET( NE_XFLM_FAILURE); goto Exit; } bMustDetach = TRUE; } Cls = pEnv->GetObjectClass( m_jClient); MId = pEnv->GetMethodID( Cls, "WriteData", "([B)I"); flmAssert( MId); if ((jBuff = pEnv->NewByteArray( (jsize)uiBytesToWrite)) == NULL) { rc = RC_SET( NE_XFLM_MEM); goto Exit; } pvBuff = pEnv->GetPrimitiveArrayCritical(jBuff, NULL); f_memcpy(pvBuff, pvBuffer, uiBytesToWrite); pEnv->ReleasePrimitiveArrayCritical( jBuff, pvBuff, 0); if( RC_BAD( rc = (RCODE)pEnv->CallIntMethod( m_jClient, MId, jBuff))) { goto Exit; } Exit: if (jBuff) { pEnv->DeleteLocalRef( jBuff); } if (bMustDetach) { if (m_pJvm->DetachCurrentThread() != 0) { flmAssert( 0); rc = RC_SET( NE_XFLM_FAILURE); } } return( rc); }
/**************************************************************************** Desc: ****************************************************************************/ void FlagSet::init( FLMBYTE ** ppucElemArray, FLMUINT uiNumElems) { reset(); if( RC_BAD( f_alloc( sizeof( FLMBYTE *) * uiNumElems, &m_ppucElemArray))) { flmAssert( 0); } if( RC_BAD( f_alloc( sizeof( FLMBOOL) * uiNumElems, &m_pbFlagArray))) { flmAssert( 0); } f_memset( m_pbFlagArray, 0, sizeof( FLMBOOL) * uiNumElems); for( FLMUINT uiLoop = 0; uiLoop < uiNumElems; uiLoop++) { if( RC_BAD( f_alloc( f_strlen( (char *)ppucElemArray[ uiLoop]) + 1, &m_ppucElemArray[ uiLoop]))) { flmAssert( 0); } f_strcpy( (char *)m_ppucElemArray[uiLoop], (char *)ppucElemArray[uiLoop]); } m_uiNumElems = uiNumElems; }
/***************************************************************************** Desc: Remove a node from the node list. If it is not there, it is ok. ******************************************************************************/ void F_NodeList::removeNode( FLMUINT uiCollection, FLMUINT64 ui64Document, FLMUINT64 ui64NodeId) { FLMUINT uiPos; // Cannot allow collection or document to be zero flmAssert( uiCollection && ui64Document); if( m_uiLastCollection == uiCollection && m_ui64LastDocument == ui64Document && m_ui64LastNodeId == ui64NodeId) { flmAssert( m_uiLastPosition < m_uiNumNodes); removeNode( m_uiLastPosition); } else { if( findNode( uiCollection, ui64Document, ui64NodeId, &uiPos)) { flmAssert( uiPos < m_uiNumNodes); removeNode( uiPos); } } }
/**************************************************************************** Desc: ****************************************************************************/ FlagSet::FlagSet( const FlagSet& fs) { if( RC_BAD( f_alloc( sizeof( FLMBYTE *) * fs.m_uiNumElems, &m_ppucElemArray))) { flmAssert( 0); } if( RC_BAD( f_alloc( sizeof( FLMBOOL) * fs.m_uiNumElems, &m_pbFlagArray))) { flmAssert( 0); } f_memset( m_pbFlagArray, 0, sizeof( FLMBOOL) * fs.m_uiNumElems); for( FLMUINT uiLoop = 0; uiLoop < fs.m_uiNumElems; uiLoop++) { if( RC_BAD( f_alloc( f_strlen( (char *)fs.m_ppucElemArray[uiLoop]) + 1, &m_ppucElemArray[ uiLoop]))) { flmAssert( 0); } f_strcpy( (char *)m_ppucElemArray[uiLoop], (char *)fs.m_ppucElemArray[uiLoop]); } m_uiNumElems = fs.m_uiNumElems; }
/**************************************************************************** Desc: ****************************************************************************/ RCODE F_FSRestore::openBackupSet( void) { RCODE rc = NE_SFLM_OK; flmAssert( m_bSetupCalled); flmAssert( !m_pMultiFileHdl); if( RC_BAD( rc = FlmAllocMultiFileHdl( &m_pMultiFileHdl))) { goto Exit; } if( RC_BAD( rc = m_pMultiFileHdl->openFile( m_szBackupSetPath))) { m_pMultiFileHdl->Release(); m_pMultiFileHdl = NULL; goto Exit; } m_ui64Offset = 0; m_bOpen = TRUE; Exit: return( rc); }
JNIBackupStatus( jobject jStatus, JavaVM * pJvm) { flmAssert(jStatus); flmAssert(pJvm); m_jStatus = jStatus; m_pJvm = pJvm; }
JNIBackupClient( jobject jClient, JavaVM * pJvm) { flmAssert( jClient); flmAssert( pJvm); m_jClient = jClient; m_pJvm = pJvm; }
/**************************************************************************** Desc: ****************************************************************************/ FSTATIC void _flmDbgLogFlush( void) { FLMUINT uiBytesToWrite; FLMUINT uiBytesWritten; char * pszBufPtr = g_pszLogBuf; FLMUINT uiTotalToWrite = g_uiLogBufOffset; RCODE rc = NE_SFLM_OK; FLMUINT uiBufferSize = DBG_LOG_BUFFER_SIZE + 1024; while( uiTotalToWrite) { if( uiTotalToWrite > 0xFE00) { uiBytesToWrite = 0xFE00; } else { uiBytesToWrite = uiTotalToWrite; } if( RC_BAD( rc = g_pLogFile->SectorWrite( g_uiLogFileOffset, uiBytesToWrite, pszBufPtr, uiBufferSize, NULL, &uiBytesWritten, FALSE))) { goto Exit; } flmAssert( uiBytesToWrite == uiBytesWritten); g_uiLogFileOffset += uiBytesWritten; pszBufPtr += uiBytesWritten; uiBufferSize -= uiBytesWritten; uiTotalToWrite -= uiBytesWritten; } if (g_uiLogBufOffset & 0x1FF) { if (g_uiLogBufOffset > 512) { f_memcpy( g_pszLogBuf, &g_pszLogBuf [g_uiLogBufOffset & 0xFFFFFE00], 512); g_uiLogBufOffset &= 0x1FF; } g_uiLogFileOffset -= g_uiLogBufOffset; } else { g_uiLogBufOffset = 0; } Exit: flmAssert( RC_OK( rc)); }
/*************************************************************************** Desc: *****************************************************************************/ RCODE F_Database::startMaintThread( void) { RCODE rc = NE_SFLM_OK; char szThreadName[ F_PATH_MAX_SIZE]; char szBaseName[ 32]; flmAssert( !m_pMaintThrd); flmAssert( m_hMaintSem == F_SEM_NULL); // Generate the thread name if( RC_BAD( rc = gv_SFlmSysData.pFileSystem->pathReduce( m_pszDbPath, szThreadName, szBaseName))) { goto Exit; } f_sprintf( (char *)szThreadName, "Maintenance (%s)", (char *)szBaseName); // Create the maintenance semaphore if( RC_BAD( rc = f_semCreate( &m_hMaintSem))) { goto Exit; } // Start the thread. if( RC_BAD( rc = gv_SFlmSysData.pThreadMgr->createThread( &m_pMaintThrd, F_Database::maintenanceThread, szThreadName, 0, 0, this, NULL, 32000))) { goto Exit; } // Signal the thread to check for any queued work f_semSignal( m_hMaintSem); Exit: if( RC_BAD( rc)) { if( m_hMaintSem != F_SEM_NULL) { f_semDestroy( &m_hMaintSem); } } return( rc); }
/**************************************************************************** Desc: ****************************************************************************/ FlagSet FlagSet::crossProduct( FlagSet& fs2) { FlagSet fsCross; FLMUINT uiLoop1; FLMUINT uiCrossProductElems = this->getNumElements() * fs2.getNumElements(); FLMBYTE ** ppszCross = NULL; if( RC_BAD( f_alloc( sizeof( FLMBYTE *) * uiCrossProductElems, &ppszCross))) { flmAssert( 0); goto Exit; } for( uiLoop1 = 0; uiLoop1 < this->getNumElements(); uiLoop1++) { for( FLMUINT uiLoop2 = 0; uiLoop2 < fs2.getNumElements(); uiLoop2++) { FLMUINT uiIndex = uiLoop1 * fs2.getNumElements() + uiLoop2; if( RC_BAD( f_alloc( f_strlen((char *)this->m_ppucElemArray[ uiLoop1]) + f_strlen((char *)fs2.m_ppucElemArray[ uiLoop2]) + 1, &ppszCross[ uiIndex]))) { flmAssert( 0); } f_strcpy( (char *)ppszCross[ uiIndex], (char *)this->m_ppucElemArray[ uiLoop1]); f_strcat( (char *)ppszCross[ uiIndex], (char *)fs2.m_ppucElemArray[ uiLoop2]); } } fsCross.init( ppszCross, uiCrossProductElems); for( uiLoop1 = 0; uiLoop1 < uiCrossProductElems; uiLoop1++) { f_free( &ppszCross[ uiLoop1]); } f_free( &ppszCross); Exit: return( fsCross); }
/*************************************************************************** Desc: This routine changed a database header to native platform format. *****************************************************************************/ void convertDbHdr( XFLM_DB_HDR * pDbHdr ) { // This routine should only be called to convert a header to native // format. flmAssert( hdrIsNonNativeFormat( pDbHdr)); convert16( &pDbHdr->ui16BlockSize); convert32( &pDbHdr->ui32DbVersion); convert64( &pDbHdr->ui64LastRflCommitID); convert32( &pDbHdr->ui32RflLastFileNumDeleted); convert32( &pDbHdr->ui32RflCurrFileNum); convert32( &pDbHdr->ui32RflLastTransOffset); convert32( &pDbHdr->ui32RflLastCPFileNum); convert32( &pDbHdr->ui32RflLastCPOffset); convert64( &pDbHdr->ui64RflLastCPTransID); convert32( &pDbHdr->ui32RflMinFileSize); convert32( &pDbHdr->ui32RflMaxFileSize); convert64( &pDbHdr->ui64CurrTransID); convert64( &pDbHdr->ui64TransCommitCnt); convert32( &pDbHdr->ui32RblEOF); convert32( &pDbHdr->ui32RblFirstCPBlkAddr); convert32( &pDbHdr->ui32FirstAvailBlkAddr); convert32( &pDbHdr->ui32FirstLFBlkAddr); convert32( &pDbHdr->ui32LogicalEOF); convert32( &pDbHdr->ui32MaxFileSize); convert64( &pDbHdr->ui64LastBackupTransID); convert32( &pDbHdr->ui32IncBackupSeqNum); convert32( &pDbHdr->ui32BlksChangedSinceBackup); convert32( &pDbHdr->ui32HdrCRC); pDbHdr->ui8IsLittleEndian = XFLM_NATIVE_IS_LITTLE_ENDIAN; }
/**************************************************************************** Desc: See if any F_INDEX structures need indexing in the background. ****************************************************************************/ RCODE F_Db::startBackgroundIndexing( void) { RCODE rc = NE_SFLM_OK; FLMBOOL bStartedTrans = FALSE; FLMUINT uiIndexNum; F_INDEX * pIndex; if (RC_BAD( rc = checkState( __FILE__, __LINE__))) { goto Exit; } if (m_eTransType != SFLM_NO_TRANS) { if (!okToCommitTrans()) { rc = RC_SET( NE_SFLM_ABORT_TRANS); goto Exit; } } else { // Need to have at least a read transaction going. if (RC_BAD( rc = beginTrans( SFLM_READ_TRANS))) { goto Exit; } bStartedTrans = TRUE; } for (uiIndexNum = 1, pIndex = m_pDict->m_pIndexTbl; uiIndexNum <= m_pDict->m_uiHighestIndexNum; uiIndexNum++, pIndex++) { // Restart any indexes that are off-line but not suspended if ((pIndex->uiFlags & (IXD_OFFLINE | IXD_SUSPENDED)) == IXD_OFFLINE) { flmAssert( flmBackgroundIndexGet( m_pDatabase, uiIndexNum, FALSE) == NULL); if (RC_BAD( rc = startIndexBuild( uiIndexNum))) { goto Exit; } } } Exit: if (bStartedTrans) { (void)abortTrans(); } return( rc); }
/**************************************************************************** Desc: Returns the next B-Tree information that was collected during the database check. ****************************************************************************/ void XFLAPI F_DbInfo::getBTreeInfo( FLMUINT uiNthLogicalFile, FLMUINT * puiLfNum, eLFileType * peLfType, FLMUINT * puiRootBlkAddress, FLMUINT * puiNumLevels ) { LF_HDR * pLfHdr; if (uiNthLogicalFile < m_uiNumLogicalFiles) { pLfHdr = &m_pLogicalFiles[ uiNthLogicalFile]; *puiLfNum = pLfHdr->uiLfNum; *peLfType = pLfHdr->eLfType; *puiRootBlkAddress = pLfHdr->uiRootBlk; *puiNumLevels = pLfHdr->uiNumLevels; } else { flmAssert( 0); *puiLfNum = 0; *puiRootBlkAddress = 0; *puiNumLevels = 0; } }
/**************************************************************************** Desc: After each unit test call this to record the unit test status to a CSV file. uTD - contains the configuration information pszTestName - a unique name for this unit test. bPassed - Did unit test pass? pszFailInfo - If unit test failed, reason is here ****************************************************************************/ RCODE recordUnitTestResults( unitTestData * uTD, const char * pszTestName, FLMBOOL bPassed, const char * pszFailInfo) { RCODE rc = FERR_OK; char buffer[ MAX_BUFFER_SIZE]; flmAssert( pszTestName && uTD); if( uTD->csvFilename[ 0]) { f_sprintf( buffer, "%s,%s,%s,%s,%s,%s,%s,%s,"/*%s,*/"%s,%s\n", pszTestName, uTD->userName, pszTestName, pszTestName, uTD->buildNumber, (const char *)(bPassed ? "PASS" : "FAIL"), uTD->environment, pszFailInfo, uTD->attrs, uTD->folder); if( RC_BAD( rc = f_filecat( uTD->csvFilename, buffer))) { goto Exit; } } Exit: return( rc); }
/**************************************************************************** Desc: Add the index to the start list of background threads. ****************************************************************************/ RCODE flmAddToStartList( FDB * pDb, FLMUINT uiIndexNum) { RCODE rc = FERR_OK; F_BKGND_IX * pBackgroundIx; F_BKGND_IX * pNextBackgroundIx; // We'd better not be replaying the RFL flmAssert( !(pDb->uiFlags & FDB_REPLAYING_RFL)); // Look in the start list to make sure we don't already // have an entry for this index. We don't want to // start more than one thread per index. The background // indexing code is not structured to handle multiple build // threads on the same index. // NOTE: We don't want to remove any entries in the stop // list corresponding to this index. The reason for this // is the index may have been deleted, re-added, deleted, // modified, etc. several times during the transaction. // We want to make sure that an existing background indexing // thread is terminated and a new one is started. The stop // list is always processed first at transaction commit time. // Then new indexing threads (in the start list) are started. for( pBackgroundIx = pDb->pIxStartList; pBackgroundIx; pBackgroundIx = pNextBackgroundIx) { pNextBackgroundIx = pBackgroundIx->pNext; if( pBackgroundIx->indexStatus.uiIndexNum == uiIndexNum) { goto Exit; // Should return FERR_OK } } // Allocate and add the thread structure to the pDb thread list. if( RC_BAD( rc = f_calloc( (FLMUINT)( sizeof( F_BKGND_IX)), &pBackgroundIx))) { goto Exit; } pBackgroundIx->indexStatus.uiIndexNum = uiIndexNum; pBackgroundIx->pPrev = NULL; if( (pBackgroundIx->pNext = pDb->pIxStartList) != NULL) { pDb->pIxStartList->pPrev = pBackgroundIx; } pDb->pIxStartList = pBackgroundIx; Exit: return( rc); }
/**************************************************************************** Desc: Adds a field path to the selection criteria of a given cursor. A field path is the fully qualified context of a field within a record. ****************************************************************************/ FLMEXP RCODE FLMAPI FlmCursorAddFieldPath( HFCURSOR hCursor, FLMUINT * puiFldPath, FLMUINT uiFlags) { RCODE rc = FERR_OK; FQNODE * pTmpQNode; CURSOR * pCursor = (CURSOR *)hCursor; if (!pCursor) { flmAssert( 0); rc = RC_SET( FERR_INVALID_PARM); goto Exit; } if (RC_BAD( rc = pCursor->rc)) { goto Exit; } // If a read operation has already been performed on this query, no // selection criteria may be added. if (pCursor->bOptimized) { rc = RC_SET( FERR_ILLEGAL_OP); goto Exit; } if (!( pCursor->QTInfo.uiExpecting & FLM_Q_OPERAND)) { rc = RC_SET( FERR_CURSOR_SYNTAX); goto Exit; } if (RC_OK( rc = flmCurMakeQNode( &pCursor->QueryPool, FLM_FLD_PATH, puiFldPath, 0, pCursor->QTInfo.uiFlags, &pTmpQNode))) { pTmpQNode->pQAtom->uiFlags |= uiFlags; pCursor->QTInfo.pCurAtomNode = pTmpQNode; if (pCursor->QTInfo.pCurOpNode) { flmCurLinkLastChild( pCursor->QTInfo.pCurOpNode, pCursor->QTInfo.pCurAtomNode); } pCursor->QTInfo.uiExpecting &= ~FLM_Q_OPERAND; pCursor->QTInfo.uiExpecting |= FLM_Q_OPERATOR; } Exit: if (pCursor) { pCursor->rc = rc; } return( rc); }
/**************************************************************************** Desc: ****************************************************************************/ RCODE F_FSRestore::openIncFile( FLMUINT uiFileNum) { char szIncPath[ F_PATH_MAX_SIZE]; char szIncFile[ F_FILENAME_SIZE]; RCODE rc = NE_SFLM_OK; flmAssert( m_bSetupCalled); flmAssert( !m_pMultiFileHdl); // Since this is a non-interactive restore, we will "guess" // that incremental backups are located in the same parent // directory as the main backup set. We will further assume // that the incremental backup sets have been named XXXXXXXX.INC, // where X is a hex digit. if( RC_BAD( rc = gv_SFlmSysData.pFileSystem->pathReduce( m_szBackupSetPath, szIncPath, NULL))) { goto Exit; } f_sprintf( szIncFile, "%08X.INC", (unsigned)uiFileNum); gv_SFlmSysData.pFileSystem->pathAppend( szIncPath, szIncFile); if( RC_BAD( rc = FlmAllocMultiFileHdl( &m_pMultiFileHdl))) { goto Exit; } if( RC_BAD( rc = m_pMultiFileHdl->openFile( szIncPath))) { m_pMultiFileHdl->Release(); m_pMultiFileHdl = NULL; goto Exit; } m_ui64Offset = 0; m_bOpen = TRUE; Exit: return( rc); }
/****************************************************************** Desc: Implements the addChar function of the DynamicBuffer class *******************************************************************/ RCODE F_DynamicBuffer::addChar( char ucCharacter) { RCODE rc = FERR_OK; if (!m_bSetup) { flmAssert( 0); rc = RC_SET( FERR_FAILURE); goto Exit; } f_mutexLock( m_hMutex); // Is there room for just one more character plus a terminator? if ((m_uiBuffSize - m_uiUsedChars) > 1) { m_pucBuffer[ m_uiUsedChars++] = ucCharacter; m_pucBuffer[ m_uiUsedChars] = 0; } else { // Allocate a new buffer or increase the size of the existing one. if( !m_uiBuffSize) { if( RC_BAD( rc = f_alloc( 50, &m_pucBuffer))) { goto Exit; } m_uiBuffSize = 50; } else { if( RC_BAD( rc = f_realloc( m_uiBuffSize + 50, &m_pucBuffer))) { goto Exit; } m_uiBuffSize += 50; } m_pucBuffer[ m_uiUsedChars++] = ucCharacter; m_pucBuffer[ m_uiUsedChars] = 0; } Exit: if ( m_bSetup) { f_mutexUnlock( m_hMutex); } return( rc); }
/**************************************************************************** Desc: Get a pointer to the UTF8 - no conversions are done. ****************************************************************************/ RCODE XFLAPI F_DataVector::getUTF8Ptr( FLMUINT uiElementNumber, const FLMBYTE ** ppszUTF8, FLMUINT * puiBufLen) { RCODE rc = NE_XFLM_OK; F_VECTOR_ELEMENT * pVector = getVector( uiElementNumber, VECT_SLOT_HAS_DATA); void * pvValue; FLMUINT uiStorageLen; FLMUINT uiSenLen; if (!pVector) { *ppszUTF8 = NULL; if (puiBufLen) { *puiBufLen = 0; } goto Exit; } if (pVector->uiDataType != XFLM_TEXT_TYPE) { rc = RC_SET( NE_XFLM_BAD_DATA_TYPE); goto Exit; } if ((pvValue = getDataPtr( pVector)) != NULL) { *ppszUTF8 = (FLMBYTE *)pvValue; uiStorageLen = pVector->uiDataLength; if( RC_BAD( rc = flmGetCharCountFromStorageBuf( ppszUTF8, uiStorageLen, NULL, &uiSenLen))) { goto Exit; } flmAssert( uiStorageLen > uiSenLen); uiStorageLen -= uiSenLen; } else { *ppszUTF8 = NULL; uiStorageLen = 0; } if (puiBufLen) { *puiBufLen = uiStorageLen; } Exit: return( rc); }
/**************************************************************************** Desc: ****************************************************************************/ void flmDbgLogInit( void) { char szLogPath[ 256]; RCODE rc = NE_SFLM_OK; flmAssert( g_hDbgLogMutex == F_MUTEX_NULL); // Allocate a buffer for the log if (RC_BAD( rc = f_alloc( DBG_LOG_BUFFER_SIZE + 1024, &g_pszLogBuf))) { goto Exit; } // Create the mutex if (RC_BAD( rc = f_mutexCreate( &g_hDbgLogMutex))) { goto Exit; } // Build the file path #ifdef FLM_NLM f_strcpy( szLogPath, "SYS:\\FLMDBG.LOG"); #else f_sprintf( szLogPath, "FLMDBG.LOG"); #endif // Create the file - truncate if it exists already. if( RC_BAD( rc = gv_SFlmSysData.pFileSystem->Create( szLogPath, XFLM_IO_RDWR | XFLM_IO_SH_DENYNONE | XFLM_IO_DIRECT, &g_pLogFile))) { goto Exit; } Exit: flmAssert( RC_OK( rc)); }
/**************************************************************************** Desc: ****************************************************************************/ RCODE JNIBackupStatus::backupStatus( FLMUINT64 ui64BytesToDo, FLMUINT64 ui64BytesDone) { RCODE rc = NE_XFLM_OK; JNIEnv * pEnv; jclass Cls; jmethodID MId; FLMBOOL bMustDetach = FALSE; if (m_pJvm->GetEnv( (void **)&pEnv, JNI_VERSION_1_2) != JNI_OK) { if (m_pJvm->AttachCurrentThread( (void **)&pEnv, NULL) != 0) { rc = RC_SET(NE_XFLM_FAILURE); goto Exit; } bMustDetach = TRUE; } Cls = pEnv->GetObjectClass( m_jStatus); MId = pEnv->GetMethodID( Cls, "backupStatus", "(JJ)I"); flmAssert( MId); rc = (RCODE)pEnv->CallIntMethod( m_jStatus, MId, (jlong)ui64BytesToDo, (jlong)ui64BytesDone); Exit: if (bMustDetach) { if (m_pJvm->DetachCurrentThread() != 0) { flmAssert( 0); rc = RC_SET( NE_XFLM_FAILURE); } } return( rc); }
/**************************************************************************** Name: refresh Desc: *****************************************************************************/ void F_DynamicList::refresh( void) { DLIST_NODE * pTmp; FLMUINT uiLoop; FTX_SCREEN * pScreen = NULL; if( !m_bChanged) { return; } if( RC_BAD( FTXWinGetScreen( m_pListWin, &pScreen))) { flmAssert( 0); goto Exit; } FTXSetRefreshState( TRUE); pTmp = m_pCur; uiLoop = m_uiRow; while( pTmp && uiLoop > 0) { pTmp = pTmp->pPrev; uiLoop--; } if( !pTmp) { pTmp = m_pFirst; } uiLoop = 0; while( pTmp && uiLoop < m_uiListRows) { pTmp->pDispHook( m_pListWin, (FLMBOOL)(pTmp == m_pCur ? TRUE : FALSE), uiLoop, pTmp->uiKey, pTmp->pvData, pTmp->uiDataLen, this); pTmp = pTmp->pNext; uiLoop++; f_yieldCPU(); } if( uiLoop < m_uiListRows) { FTXWinClearXY( m_pListWin, 0, uiLoop); } FTXSetRefreshState( FALSE); m_bChanged = FALSE; Exit: ; }
/**************************************************************************** Desc: ****************************************************************************/ RCODE F_FSRestore::setup( const char * pszDbPath, const char * pszBackupSetPath, const char * pszRflDir) { flmAssert( !m_bSetupCalled); flmAssert( pszDbPath); flmAssert( pszBackupSetPath); f_strcpy( m_szDbPath, pszDbPath); f_strcpy( m_szBackupSetPath, pszBackupSetPath); if( pszRflDir) { f_strcpy( m_szRflDir, pszRflDir); } m_bSetupCalled = TRUE; return( NE_SFLM_OK); }
/**************************************************************************** Desc: Insert the entry into the buffer. ****************************************************************************/ RCODE F_BtreeBlk::insertEntry( void * pvEntry, FLMUINT uiChildAddr) { RCODE rc = NE_FLM_OK; FLMBYTE * pucCurEntry; FLMUINT uiShiftBytes; // Always shift down if( entryCount() >= m_uiNumSlots) { rc = RC_SET( NE_FLM_FAILURE); goto Exit; } flmAssert( m_uiPosition != DYNSSET_POSITION_NOT_SET); pucCurEntry = ENTRY_POS( m_uiPosition); if ((uiShiftBytes = (entryCount() - m_uiPosition) * (m_uiEntrySize + m_uiEntryOvhd)) != 0) { // Big hairy assert. Finds coding bugs and corruptions. flmAssert( m_uiPosition * (m_uiEntrySize + m_uiEntryOvhd) + uiShiftBytes < DYNSSET_BLOCK_SIZE - sizeof( FixedBlkHdr)); f_memmove( pucCurEntry + m_uiEntrySize + m_uiEntryOvhd, pucCurEntry, uiShiftBytes); } f_memcpy( pucCurEntry, pvEntry, m_uiEntrySize); if( m_uiEntryOvhd) { UD2FBA( (FLMUINT32)uiChildAddr, &pucCurEntry[m_uiEntrySize]); } entryCount( entryCount() + 1); m_uiPosition++; m_bDirty = TRUE; Exit: return( rc); }
/**************************************************************************** Desc: ****************************************************************************/ RCODE F_FSRestore::read( FLMUINT uiLength, void * pvBuffer, FLMUINT * puiBytesRead) { FLMUINT uiBytesRead = 0; RCODE rc = NE_SFLM_OK; flmAssert( m_bSetupCalled); flmAssert( m_pFileHdl || m_pMultiFileHdl); if( m_pMultiFileHdl) { if( RC_BAD( rc = m_pMultiFileHdl->read( m_ui64Offset, uiLength, pvBuffer, &uiBytesRead))) { goto Exit; } } else { if( RC_BAD( rc = m_pFileHdl->read( (FLMUINT)m_ui64Offset, uiLength, pvBuffer, &uiBytesRead))) { goto Exit; } } Exit: m_ui64Offset += uiBytesRead; if( puiBytesRead) { *puiBytesRead = uiBytesRead; } return( rc); }
/**************************************************************************** Desc: Ends a logging message ****************************************************************************/ void flmEndLogMessage( IF_LogMessageClient ** ppLogMessage) { if( *ppLogMessage) { f_mutexLock( gv_XFlmSysData.hLoggerMutex); flmAssert( gv_XFlmSysData.uiPendingLogMessages); (*ppLogMessage)->endMessage(); (*ppLogMessage)->Release(); *ppLogMessage = NULL; gv_XFlmSysData.uiPendingLogMessages--; f_mutexUnlock( gv_XFlmSysData.hLoggerMutex); } }
/**************************************************************************** Desc: ****************************************************************************/ RCODE F_DbCheck::createAndOpenResultSetDb( void) { RCODE rc = NE_XFLM_OK; XFLM_CREATE_OPTS createOpts; if (m_pResultSetDb) { if (RC_BAD( rc = closeAndDeleteResultSetDb())) { goto Exit; } } f_memset( &createOpts, 0, sizeof( XFLM_CREATE_OPTS)); for (;;) { // Generate a random file name f_sprintf( m_szResultSetDibName, "%d.db", (int)m_pRandGen->getUINT32( 100, 20000)); if (RC_OK( rc = gv_pXFlmDbSystem->dbCreate( m_szResultSetDibName, NULL, NULL, NULL, NULL, &createOpts, TRUE, (IF_Db **)&m_pResultSetDb))) { break; } if (rc == NE_XFLM_FILE_EXISTS || rc == NE_FLM_IO_ACCESS_DENIED) { rc = NE_XFLM_OK; } else { goto Exit; } } // Shouldn't have an RFL object - don't want anything // logged by this database. flmAssert( !m_pResultSetDb->getDatabase()->m_pRfl); Exit: return rc; }
/**************************************************************************** Desc: Put a value in an FQATOM node - so we can call it from SMI. Can only be used for values, not field paths. Cannot be used for unknown values. ****************************************************************************/ RCODE flmPutValInAtom( void * pAtom, QTYPES eValType, void * pvVal, FLMUINT uiValLen, FLMUINT uiFlags ) { RCODE rc = FERR_OK; FQATOM * pQAtom = (FQATOM *)pAtom; pQAtom->uiFlags = uiFlags; pQAtom->eType = eValType; switch (eValType) { case FLM_BOOL_VAL: pQAtom->val.uiBool = *((FLMUINT *)pvVal); break; case FLM_UINT32_VAL: case FLM_REC_PTR_VAL: pQAtom->val.ui32Val = *((FLMUINT32 *)pvVal); break; case FLM_UINT64_VAL: pQAtom->val.ui64Val = *((FLMUINT64 *)pvVal); break; case FLM_INT32_VAL: pQAtom->val.i32Val = *((FLMINT32 *)pvVal); break; case FLM_INT64_VAL: pQAtom->val.i64Val = *((FLMINT64 *)pvVal); break; case FLM_BINARY_VAL: case FLM_TEXT_VAL: pQAtom->val.pucBuf = (FLMBYTE *)pvVal; pQAtom->uiBufLen = uiValLen; break; case FLM_UNKNOWN: break; default: flmAssert( 0); rc = RC_SET( FERR_CURSOR_SYNTAX); goto Exit; } Exit: return( rc); }
/**************************************************************************** Desc: ****************************************************************************/ RCODE ArgList::expandFileArgs( const char * pszFilename) { RCODE rc = FERR_OK; char token[64]; IF_FileHdl * pFileHdl = NULL; if( RC_BAD( rc = gv_FlmSysData.pFileSystem->openFile( pszFilename, FLM_IO_RDWR, &pFileHdl))) { goto Exit; } while( RC_OK( rc = getTokenFromFile(token, pFileHdl))) { if( token[0] == '@') { if( RC_BAD( rc = expandFileArgs( &token[1]))) { goto Exit; } } else { flmAssert(*token); if( RC_BAD( rc = addArg( token))) { goto Exit; } } } if( rc == FERR_IO_END_OF_FILE) { rc = FERR_OK; } Exit: if( pFileHdl) { pFileHdl->Release(); } return( rc); }
/**************************************************************************** Desc: Copies an existing dictionary to a new dictionary. ****************************************************************************/ RCODE F_Db::dictClone( void) { RCODE rc = NE_SFLM_OK; F_Dict * pNewDict = NULL; // Allocate a new FDICT structure if ((pNewDict = f_new F_Dict) == NULL) { rc = RC_SET( NE_SFLM_MEM); goto Exit; } // Nothing to do is not a legal state. if (!m_pDict) { flmAssert( 0); m_pDict = pNewDict; goto Exit; } // Copy the dictionary. if (RC_BAD( rc = pNewDict->cloneDict( m_pDict))) { goto Exit; } m_pDatabase->lockMutex(); unlinkFromDict(); m_pDatabase->unlockMutex(); m_pDict = pNewDict; pNewDict = NULL; m_uiFlags |= FDB_UPDATED_DICTIONARY; Exit: if (RC_BAD( rc) && pNewDict) { pNewDict->Release(); } return( rc); }