Files
mars-flaim/flaim/src/fsrecget.cpp
ahodgkinson a060eb3330 Added typecasts for Solaris.
git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@209 0109f412-320b-0410-ab79-c3e0c5ffbbe6
2006-03-23 22:51:01 +00:00

859 lines
21 KiB
C++

//-------------------------------------------------------------------------
// Desc: Read a record from the database.
// Tabs: 3
//
// Copyright (c) 1991-2006 Novell, Inc. All Rights Reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of version 2 of the GNU General Public
// License as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, contact Novell, Inc.
//
// To contact Novell about this file by physical or electronic mail,
// you may find current contact information at www.novell.com
//
// $Id: fsrecget.cpp 12329 2006-01-20 17:49:30 -0700 (Fri, 20 Jan 2006) ahodgkinson $
//-------------------------------------------------------------------------
#include "flaimsys.h"
typedef struct Field_State
{
// State information to position to the field within the element
FLMBYTE * pElement; // Points to the element within block
FLMUINT uiFieldType; // Storage field type
FLMUINT uiFieldLen; // Length of storage if known
FLMUINT uiPosInElm; // Position within the element
FLMUINT uiTagNum; // Field tag/data dictionary number
FLMUINT uiLevel; // Current level number
FLMUINT uiEncId; // EncDef ID if encrypted
FLMUINT uiEncFieldLen; // Encrypted field length
} FSTATE;
typedef struct Data_Piece
{ // Data is garbage when uiFieldLen is 0.
FLMBYTE * pData; // Points to data within the block.
FLMUINT uiLength; // Length of this data piece
struct Data_Piece * pNext; // Next data piece or NULL
} DATAPIECE;
typedef struct Temporary_Field
{
FLMUINT uiLevel;
FLMUINT uiFieldID;
FLMUINT uiFieldType;
FLMUINT uiFieldLen;
FLMUINT uiEncId;
FLMUINT uiEncFieldLen;
DATAPIECE DataPiece;
} TEMPFIELD;
#define NUM_FIELDS_IN_ARRAY 16
typedef struct Field_Group
{
TEMPFIELD pFields[ NUM_FIELDS_IN_ARRAY]; // Allocated array of fields
struct Field_Group * pNext; // Next temporary field group
} FLDGROUP;
typedef struct Locked_Block
{
SCACHE * pSCache;
struct Locked_Block *pNext;
} LOCKED_BLOCK;
FSTATIC RCODE FSGetFldOverhead(
FDB_p pDb,
FSTATE * fState);
/***************************************************************************
Desc: Retrieves a record given a DRN
*****************************************************************************/
RCODE FSReadRecord( // Was FSRecordGet
FDB_p pDb,
LFILE * pLFile,
FLMUINT uiDrn,
FlmRecord ** ppRecord, // [out] returned record
FLMUINT * puiRecTransId, // [out] record's transaction ID
FLMBOOL * pbMostCurrent) // [out] true if record is most current
{
RCODE rc;
BTSK stackBuf[ BH_MAX_LEVELS ];
BTSK_p pStack = NULL;
FLMBYTE pKeyBuf[ DIN_KEY_SIZ ];
FLMBYTE pDrnBuf[ DIN_KEY_SIZ ];
FSInitStackCache( &stackBuf [0], BH_MAX_LEVELS);
pStack = stackBuf; // Initialize the stack
pStack->pKeyBuf = pKeyBuf;
// Search the B-TREE for the record
flmUINT32ToBigEndian( (FLMUINT32)uiDrn, pDrnBuf);
if( RC_OK( rc = FSBtSearch( pDb, pLFile, &pStack, pDrnBuf, 4, 0)))
{
rc = RC_SET( FERR_NOT_FOUND);
if( ( pStack->uiCmpStatus == BT_EQ_KEY) && (uiDrn != DRN_LAST_MARKER))
{
rc = FSReadElement( pDb, &pDb->TempPool, pLFile, uiDrn, pStack,
TRUE, ppRecord, puiRecTransId, pbMostCurrent);
}
}
FSReleaseStackCache( stackBuf, BH_MAX_LEVELS, FALSE);
return( rc );
}
/**************************************************************************
Desc: Low level routine to retrieve and build an internal tree record.
The caller is responsible for freeing memory that the record
is placed into. This routine is called by FSRecordGet()
Ret: FERR_OK (0)
FERR_NOT_FOUND - field not found
FERR_MEM - ran out of memeory
FERR_DATA_ERROR - the data is somehow corrupt
**************************************************************************/
RCODE FSReadElement(
FDB_p pDb,
POOL * pPool,
LFILE * pLFile,
FLMUINT uiDrn,
BTSK_p pStack,
FLMBOOL bOkToPreallocSpace,
FlmRecord ** ppRecord, // [out] returned record
FLMUINT * puiRecTransId, // [out] record's transaction ID
FLMBOOL * pbMostCurrent) // [out] true if record is most current
{
RCODE rc = FERR_OK;
FlmRecord * pRecord = NULL;
FLMBYTE * pCurElm; // Points to the current element
void * pvPoolMark = GedPoolMark( pPool);
FLMUINT uiElmRecLen; // Length of element's record
FLMUINT uiFieldLen; // Length of the field
FLMUINT uiLowestTransId; // Lowest transaction ID.
FLMUINT uiFieldCount;
FLMUINT uiTrueDataSpace;
FLMUINT uiFieldPos;
FLMBOOL bMostCurrent;
TEMPFIELD * pField;
FLDGROUP * pFldGroup = NULL;
FLDGROUP * pFirstFldGroup = NULL;
DATAPIECE * pDataPiece;
LOCKED_BLOCK * pLockedBlock = NULL;
FSTATE fState;
FLMUINT uiEncFieldLen;
#ifdef FLM_DBG_LOG
char szTmpBuf[ 80];
#endif
#ifdef FLM_DBG_LOG
flmAssert( pStack->uiKeyLen == DIN_KEY_SIZ &&
flmBigEndianToUINT32( pStack->pKeyBuf) == uiDrn);
#endif
// Initialize variables
fState.uiLevel = 0;
uiFieldCount = 0;
uiTrueDataSpace = 0;
uiFieldPos = NUM_FIELDS_IN_ARRAY;
// Check to make sure we are positioned at the first element.
pCurElm = CURRENT_ELM( pStack );
if( !BBE_IS_FIRST( pCurElm))
{
rc = RC_SET( FERR_DATA_ERROR);
goto Exit;
}
uiLowestTransId = FB2UD( &pStack->pBlk[ BH_TRANS_ID]);
bMostCurrent = (pStack->pSCache->uiHighTransID == 0xFFFFFFFF) ? TRUE : FALSE;
#ifdef FLM_DBG_LOG
f_sprintf( szTmpBuf, "Rd1:L%X,H%X",
(unsigned)uiLowestTransId, (unsigned)pStack->pSCache->uiHighTransID);
flmDbgLogWrite( pDb->pFile->uiFFileId, pStack->pSCache->uiBlkAddress, uiDrn,
pDb->LogHdr.uiCurrTransID, szTmpBuf);
#endif
// Loop on each element in the record
for( ;;)
{
// Setup all variables to process the current element
uiElmRecLen = BBE_GET_RL( pCurElm );
if( uiElmRecLen == 0)
{
rc = RC_SET( FERR_EOF_HIT);
break;
}
pCurElm += BBE_REC_OFS( pCurElm );
fState.uiPosInElm = 0;
// Loop on each field within this element.
while( fState.uiPosInElm < uiElmRecLen)
{
fState.pElement = pCurElm;
if( RC_BAD( rc = FSGetFldOverhead( pDb, &fState)))
{
goto Exit;
}
uiFieldLen = fState.uiFieldLen;
uiEncFieldLen = fState.uiEncFieldLen;
// Old record info data - skip past for now
if( fState.uiTagNum == 0)
{
fState.uiPosInElm += (uiEncFieldLen ? uiEncFieldLen : uiFieldLen);
continue;
}
if( !pRecord)
{
// Create a new data record or use the existing data record.
if( *ppRecord)
{
if( (*ppRecord)->isReadOnly())
{
(*ppRecord)->Release();
*ppRecord = NULL;
if( (pRecord = f_new FlmRecord) == NULL)
{
rc = RC_SET( FERR_MEM);
goto Exit;
}
}
else
{
// Reuse the existing FlmRecord object.
pRecord = *ppRecord;
*ppRecord = NULL;
pRecord->clear();
}
}
else
{
if( (pRecord = f_new FlmRecord) == NULL)
{
rc = RC_SET( FERR_MEM);
goto Exit;
}
}
pRecord->setContainerID( pLFile->uiLfNum);
pRecord->setID( uiDrn);
if (pLFile->bMakeFieldIdTable)
{
pRecord->enableFieldIdTable();
}
}
// Check if out of fields in the tempoary field group.
if( uiFieldPos >= NUM_FIELDS_IN_ARRAY)
{
FLDGROUP * pTempFldGroup;
uiFieldPos = 0;
// Allocate the first field group from the pool.
if( (pTempFldGroup = (FLDGROUP *) GedPoolAlloc(
pPool, sizeof( FLDGROUP))) == NULL)
{
rc = RC_SET( FERR_MEM);
goto Exit;
}
pTempFldGroup->pNext = NULL;
if( pFldGroup)
{
pFldGroup->pNext = pTempFldGroup;
}
else
{
pFirstFldGroup = pTempFldGroup;
}
pFldGroup = pTempFldGroup;
}
uiFieldCount++;
pField = &pFldGroup->pFields[ uiFieldPos++];
pField->uiLevel = fState.uiLevel;
pField->uiFieldID = fState.uiTagNum;
pField->uiFieldType = fState.uiFieldType;
pField->uiFieldLen = fState.uiFieldLen;
pField->uiEncId = fState.uiEncId;
pField->uiEncFieldLen = fState.uiEncFieldLen;
pDataPiece = &pField->DataPiece;
if( uiFieldLen || uiEncFieldLen)
{
FLMUINT uiDataPos = 0;
if( fState.uiEncFieldLen)
{
uiTrueDataSpace += FLM_ENC_FLD_OVERHEAD;
// Binary data needs to account for alignment issues.
if (fState.uiFieldType == FLM_BINARY_TYPE)
{
// Adjust for the decrypted data.
uiTrueDataSpace = ((uiTrueDataSpace + FLM_ALLOC_ALIGN) &
(~(FLM_ALLOC_ALIGN) & 0x7FFFFFFF));
}
uiTrueDataSpace += fState.uiFieldLen + fState.uiEncFieldLen;
// Store the encrypted field length rather than the decrypted field length
// This will allow the gathering of the encrypted or decrypted field data
// to use the same code.
uiFieldLen = uiEncFieldLen;
}
else if( fState.uiFieldLen > 4)
{
// Binary data needs to account for alignment issues.
if (fState.uiFieldType == FLM_BINARY_TYPE)
{
if( fState.uiFieldLen >= 0xFF)
{
// Align so that the data is aligned - not the length
uiTrueDataSpace += sizeof( FLMUINT16);
uiTrueDataSpace = ((uiTrueDataSpace + FLM_ALLOC_ALIGN) &
(~(FLM_ALLOC_ALIGN) & 0x7FFFFFFF));
uiTrueDataSpace -= sizeof( FLMUINT16);
}
else
{
uiTrueDataSpace = ((uiTrueDataSpace + FLM_ALLOC_ALIGN) &
(~(FLM_ALLOC_ALIGN) & 0x7FFFFFFF));
}
}
uiTrueDataSpace += fState.uiFieldLen;
// Field values with lengths greater than 255 bytes are
// stored length-preceded. A single byte flags field precedes the length.
if (fState.uiFieldLen >= 0xFF)
{
uiTrueDataSpace += sizeof( FLMUINT16) + 1;
}
}
// Value may start in the next element.
while( uiDataPos < uiFieldLen)
{
// Need to read next element for the value portion?
if( fState.uiPosInElm >= uiElmRecLen)
{
if( BBE_IS_LAST( CURRENT_ELM( pStack )))
{
rc = RC_SET( FERR_DATA_ERROR);
goto Exit;
}
// If we are going to the next block, lock down this block
// beacause data pointers are pointing to it.
if( RC_BAD( FSBlkNextElm( pStack))) // Better be FERR_BT_END_OF_DATA
{
LOCKED_BLOCK * pLastLockedBlock = pLockedBlock;
if( (pLockedBlock = (LOCKED_BLOCK *) GedPoolAlloc( pPool,
sizeof( LOCKED_BLOCK))) == NULL)
{
rc = RC_SET( FERR_MEM);
goto Exit;
}
ScaHoldCache( pStack->pSCache);
pLockedBlock->pSCache = pStack->pSCache;
pLockedBlock->pNext = pLastLockedBlock;
if( RC_BAD(rc = FSBtNextElm( pDb, pLFile, pStack)))
{
rc = (rc == FERR_BT_END_OF_DATA)
? RC_SET( FERR_DATA_ERROR)
: rc;
goto Exit;
}
if( uiLowestTransId > FB2UD( &pStack->pBlk[ BH_TRANS_ID]))
{
uiLowestTransId = FB2UD( &pStack->pBlk[ BH_TRANS_ID]);
}
if( !bMostCurrent)
{
bMostCurrent = (pStack->pSCache->uiHighTransID ==
0xFFFFFFFF) ? TRUE : FALSE;
}
#ifdef FLM_DBG_LOG
f_sprintf( szTmpBuf, "Rd2:L%X,H%X",
(unsigned)FB2UD( &pStack->pBlk[ BH_TRANS_ID]),
(unsigned)pStack->pSCache->uiHighTransID);
flmDbgLogWrite( pDb->pFile->uiFFileId,
pStack->pSCache->uiBlkAddress, uiDrn,
pDb->LogHdr.uiCurrTransID, szTmpBuf);
#endif
}
pCurElm = CURRENT_ELM( pStack);
uiElmRecLen = BBE_GET_RL( pCurElm);
pCurElm += BBE_REC_OFS( pCurElm);
fState.uiPosInElm = 0;
}
// Compare number of bytes left if value <= # bytes left in element
if( uiFieldLen - uiDataPos <= uiElmRecLen - fState.uiPosInElm)
{
FLMUINT uiDelta = uiFieldLen - uiDataPos;
pDataPiece->pData = &pCurElm[ fState.uiPosInElm];
pDataPiece->uiLength = uiDelta;
fState.uiPosInElm += uiDelta;
pDataPiece->pNext = NULL;
break;
}
else
{
// Take what is there and get next element to grab some more.
FLMUINT uiBytesToMove = uiElmRecLen - fState.uiPosInElm;
DATAPIECE * pNextDataPiece;
pDataPiece->pData = &pCurElm[ fState.uiPosInElm];
pDataPiece->uiLength = uiBytesToMove;
fState.uiPosInElm += uiBytesToMove;
uiDataPos += uiBytesToMove;
if( (pNextDataPiece = (DATAPIECE *)
GedPoolAlloc( pPool, sizeof( DATAPIECE))) == NULL)
{
rc = RC_SET( FERR_MEM);
goto Exit;
}
pDataPiece->pNext = pNextDataPiece;
pDataPiece = pNextDataPiece;
}
}
} // End if uiFieldLen
} // End of while( fState.uiPosInElm < uiElmRecLen)
// Done?
if( BBE_IS_LAST( CURRENT_ELM( pStack)))
{
break;
}
// Position to next element
if( RC_BAD( FSBlkNextElm( pStack))) // Better be FERR_BT_END_OF_DATA
{
LOCKED_BLOCK * pLastLockedBlock = pLockedBlock;
if( (pLockedBlock = (LOCKED_BLOCK *) GedPoolAlloc( pPool,
sizeof( LOCKED_BLOCK))) == NULL)
{
rc = RC_SET( FERR_MEM);
goto Exit;
}
ScaHoldCache( pStack->pSCache);
pLockedBlock->pSCache = pStack->pSCache;
pLockedBlock->pNext = pLastLockedBlock;
if( RC_BAD(rc = FSBtNextElm( pDb, pLFile, pStack)))
{
if (rc == FERR_BT_END_OF_DATA)
{
rc = RC_SET( FERR_DATA_ERROR);
}
goto Exit;
}
if( uiLowestTransId > FB2UD( &pStack->pBlk[ BH_TRANS_ID]))
{
uiLowestTransId = FB2UD( &pStack->pBlk[ BH_TRANS_ID]);
}
if( !bMostCurrent)
{
bMostCurrent = (pStack->pSCache->uiHighTransID ==
0xFFFFFFFF) ? TRUE : FALSE;
}
#ifdef FLM_DBG_LOG
f_sprintf( szTmpBuf, "Rd3:L%X,H%X",
(unsigned)FB2UD( &pStack->pBlk[ BH_TRANS_ID]),
(unsigned)pStack->pSCache->uiHighTransID);
flmDbgLogWrite( pDb->pFile->uiFFileId,
pStack->pSCache->uiBlkAddress, uiDrn,
pDb->LogHdr.uiCurrTransID, szTmpBuf);
#endif
}
// Corruption Check.
pCurElm = CURRENT_ELM( pStack );
if( BBE_IS_FIRST( pCurElm))
{
rc = RC_SET( FERR_DATA_ERROR);
goto Exit;
}
}
if( pRecord)
{
void * pvField;
if( bOkToPreallocSpace)
{
if( RC_BAD( rc = pRecord->preallocSpace( uiFieldCount, uiTrueDataSpace)))
{
goto Exit;
}
}
pFldGroup = pFirstFldGroup;
for( uiFieldPos = 0; uiFieldCount--; uiFieldPos++)
{
if( uiFieldPos >= NUM_FIELDS_IN_ARRAY)
{
uiFieldPos = 0;
if( (pFldGroup = pFldGroup->pNext) == NULL)
break;
}
pField = &pFldGroup->pFields[ uiFieldPos];
if( RC_BAD( rc = pRecord->insertLast( pField->uiLevel,
pField->uiFieldID, pField->uiFieldType, &pvField)))
{
goto Exit;
}
if( pField->uiFieldLen)
{
FLMBYTE * pDataPtr;
FLMBYTE * pEncDataPtr;
pDataPiece = &pField->DataPiece;
if (RC_BAD( rc = pRecord->allocStorageSpace(
pvField,
pField->uiFieldType,
pField->uiFieldLen,
pField->uiEncFieldLen,
pField->uiEncId,
(pField->uiEncId
? FLD_HAVE_ENCRYPTED_DATA
: 0),
&pDataPtr,
&pEncDataPtr)))
{
goto Exit;
}
do
{
if (pField->uiEncId)
{
f_memcpy( pEncDataPtr, pDataPiece->pData, pDataPiece->uiLength);
pEncDataPtr += pDataPiece->uiLength;
}
else
{
f_memcpy( pDataPtr, pDataPiece->pData, pDataPiece->uiLength);
pDataPtr += pDataPiece->uiLength;
}
pDataPiece = pDataPiece->pNext;
} while( pDataPiece);
// If the field is encrypted, then we must decrypt it here.
if (pField->uiEncId && !pDb->pFile->bInLimitedMode)
{
if (RC_BAD( rc = flmDecryptField( pDb->pDict,
pRecord,
pvField,
pField->uiEncId,
&pDb->TempPool)))
{
goto Exit;
}
}
}
}
}
if( puiRecTransId)
{
*puiRecTransId = uiLowestTransId;
}
if( pbMostCurrent)
{
*pbMostCurrent = bMostCurrent;
}
if( *ppRecord)
{
// We shouldn't hit this case, but in case we do we will deal
// with it.
flmAssert( 0);
(*ppRecord)->Release();
}
pRecord->sortFieldIdTable();
*ppRecord = pRecord;
pRecord = NULL;
Exit:
// Release all locked down blocks except the current block.
while( pLockedBlock)
{
ScaReleaseCache( pLockedBlock->pSCache, FALSE);
pLockedBlock = pLockedBlock->pNext;
}
GedPoolReset( pPool, pvPoolMark);
if( pRecord)
{
pRecord->Release();
}
// You are now positioned to the last element in the record
return( rc);
}
/**************************************************************************
Desc: Read field overhead (level, field drn, and length information.
This isolates the complexity of the storage formats.
Out: fstate updated according to data
Ret: FERR_OK or FERR_NOT_FOUND if the field is not found
Notes:The entire field overhead MUST always be together (not split).
The data may be in another element.
**************************************************************************/
FSTATIC RCODE FSGetFldOverhead(
FDB_p pDb,
FSTATE * fState)
{
RCODE rc = FERR_OK;
FLMBYTE * pFieldOvhd = &fState->pElement[ fState->uiPosInElm ];
FLMBYTE * pElement = fState->pElement;
FLMBOOL bDoesntHaveFieldDef = TRUE;
FLMUINT uiFieldLen;
FLMUINT uiFieldType = 0;
FLMUINT uiTagNum;
FLMBYTE byTemp;
FLMUINT uiEncId = 0;
FLMUINT uiEncFieldLen = 0;
/**
*** See FO_xxx_FLD definitions in FS.H
*** If maintaining, see also FSRecUpd.c to see how codes were written.
**/
if( FOP_IS_STANDARD( pFieldOvhd))
{
if( FSTA_LEVEL( pFieldOvhd))
{
fState->uiLevel++;
}
uiFieldLen = FSTA_FLD_LEN( pFieldOvhd );
uiTagNum = FSTA_FLD_NUM( pFieldOvhd );
pFieldOvhd += FSTA_OVHD;
}
else if( FOP_IS_OPEN( pFieldOvhd))
{
if( FOPE_LEVEL( pFieldOvhd))
{
fState->uiLevel++;
}
byTemp = (FLMBYTE)(FOP_GET_FLD_FLAGS( pFieldOvhd++ ));
uiTagNum = (FLMUINT) *pFieldOvhd++;
if( FOP_2BYTE_FLDNUM(byTemp))
{
uiTagNum += ((FLMUINT) *pFieldOvhd++) << 8;
}
uiFieldLen = (FLMUINT) *pFieldOvhd++;
if( FOP_2BYTE_FLDLEN( byTemp ))
{
uiFieldLen += ((FLMUINT) *pFieldOvhd++) << 8;
}
}
else if( FOP_IS_NO_VALUE( pFieldOvhd))
{
if( FNOV_LEVEL( pFieldOvhd ))
{
fState->uiLevel++;
}
byTemp = (FLMBYTE)(FOP_GET_FLD_FLAGS( pFieldOvhd++ ));
uiTagNum = (FLMUINT) *pFieldOvhd++;
if( FOP_2BYTE_FLDNUM(byTemp))
{
uiTagNum += ((FLMUINT) *pFieldOvhd++) << 8;
}
uiFieldLen= uiFieldType = 0;
}
else if( FOP_IS_SET_LEVEL( pFieldOvhd))
{
// SET THE LEVEL
//
// Must be continuous with the next field
fState->uiLevel -= FSLEV_GET( pFieldOvhd++);
fState->uiPosInElm = (FLMUINT)(pFieldOvhd - pElement);
rc = FSGetFldOverhead( pDb, fState);
goto Exit;
}
else if( FOP_IS_TAGGED( pFieldOvhd))
{
bDoesntHaveFieldDef = FALSE;
if( FTAG_LEVEL( pFieldOvhd))
{
fState->uiLevel++;
}
byTemp = (FLMBYTE)(FOP_GET_FLD_FLAGS( pFieldOvhd));
uiFieldType = (FLMUINT)(FTAG_FLD_TYPE( pFieldOvhd ));
pFieldOvhd += FTAG_OVHD;
uiTagNum = (FLMUINT) *pFieldOvhd++;
if( FOP_2BYTE_FLDNUM(byTemp))
{
uiTagNum += ((FLMUINT) *pFieldOvhd++) << 8;
}
// When storing the unregistered fields we cleared the high bit
// to save on storage for VER11. The problem is that if a tag that is
// not in the unregistered range (FLAIM TAGS) cannot be represented.
// SO, we will XOR the high bit so 0x0111 is stored as 0x8111 and
// 0x8222 is stored as 0x0222.
uiTagNum ^= 0x8000;
uiFieldLen = (FLMUINT) *pFieldOvhd++;
if( FOP_2BYTE_FLDLEN( byTemp))
{
uiFieldLen += ((FLMUINT) *pFieldOvhd++) << 8;
}
}
else if( FOP_IS_RECORD_INFO( pFieldOvhd))
{
bDoesntHaveFieldDef = FALSE;
byTemp = *pFieldOvhd++;
uiFieldLen = *pFieldOvhd++;
if( FOP_2BYTE_FLDLEN( byTemp ))
uiFieldLen += ((FLMUINT) *pFieldOvhd++) << 8;
uiTagNum = 0;
}
else if (FOP_IS_ENCRYPTED( pFieldOvhd))
{
FLMBOOL bTagSz;
FLMBOOL bLenSz;
FLMBOOL bENumSz;
FLMBOOL bELenSz;
bDoesntHaveFieldDef = FALSE;
if( FENC_LEVEL( pFieldOvhd ))
{
fState->uiLevel++;
}
uiFieldType = (FLMUINT)(FENC_FLD_TYPE( pFieldOvhd ));
bTagSz = FENC_TAG_SZ( pFieldOvhd);
bLenSz = FENC_LEN_SZ( pFieldOvhd);
bENumSz = FENC_ETAG_SZ( pFieldOvhd);
bELenSz = FENC_ELEN_SZ( pFieldOvhd);
pFieldOvhd += 2;
uiTagNum = (FLMUINT) *pFieldOvhd++;
if ( bTagSz)
{
uiTagNum += ((FLMUINT) *pFieldOvhd++) << 8;
}
uiFieldLen = (FLMUINT)*pFieldOvhd++;
if (bLenSz)
{
uiFieldLen += ((FLMUINT) *pFieldOvhd++) << 8;
}
uiEncId = (FLMUINT) *pFieldOvhd++;
if (bENumSz)
{
uiEncId += ((FLMUINT) *pFieldOvhd++) << 8;
}
uiEncFieldLen = (FLMUINT) *pFieldOvhd++;
if (bELenSz)
{
uiEncFieldLen += ((FLMUINT) *pFieldOvhd++) << 8;
}
}
else
{
flmAssert( 0);
rc = RC_SET( FERR_DATA_ERROR);
goto Exit;
}
if( bDoesntHaveFieldDef)
{
// Get the field's storage type.
if( RC_BAD( fdictGetField( pDb->pDict, uiTagNum, &uiFieldType,
NULL, NULL)))
{
rc = RC_SET( FERR_DATA_ERROR);
goto Exit;
}
}
// Set the fState return values
fState->uiFieldType = uiFieldType;
fState->uiFieldLen = uiFieldLen;
fState->uiPosInElm = (FLMUINT) (pFieldOvhd - pElement);
fState->uiTagNum = uiTagNum;
fState->uiEncId = uiEncId;
fState->uiEncFieldLen = uiEncFieldLen;
Exit:
return( rc);
}