git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@729 0109f412-320b-0410-ab79-c3e0c5ffbbe6
1420 lines
32 KiB
C++
1420 lines
32 KiB
C++
//------------------------------------------------------------------------------
|
|
// Desc: Contains the code for the F_DataVector class.
|
|
//
|
|
// Tabs: 3
|
|
//
|
|
// Copyright (c) 2003-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$
|
|
//------------------------------------------------------------------------------
|
|
|
|
#include "flaimsys.h"
|
|
|
|
#if defined( FLM_WATCOM_NLM)
|
|
// Disable "Warning! W549: col(XX) 'sizeof' operand contains
|
|
// compiler generated information"
|
|
#pragma warning 549 9
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
Desc:
|
|
****************************************************************************/
|
|
F_DataVector::F_DataVector()
|
|
{
|
|
m_pVectorElements = &m_VectorArray [0];
|
|
m_uiVectorArraySize = MIN_VECTOR_ELEMENTS;
|
|
m_pucDataBuf = m_ucIntDataBuf;
|
|
m_uiDataBufLength = sizeof( m_ucIntDataBuf);
|
|
reset();
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc:
|
|
****************************************************************************/
|
|
F_DataVector::~F_DataVector()
|
|
{
|
|
if (m_pVectorElements != &m_VectorArray [0])
|
|
{
|
|
f_free( &m_pVectorElements);
|
|
}
|
|
if (m_pucDataBuf && m_pucDataBuf != m_ucIntDataBuf)
|
|
{
|
|
f_free( &m_pucDataBuf);
|
|
}
|
|
reset();
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Desc: Clear the data vector, but don't free any buffers that have been
|
|
allocated. That will only happen in the destructor. The reset()
|
|
method is so that we can get efficient re-use of the vector. So, if
|
|
it has allocated buffers, etc. we don't want to free them.
|
|
****************************************************************************/
|
|
void F_DataVector::reset( void)
|
|
{
|
|
m_ui64RowId = 0;
|
|
m_uiNumElements = 0;
|
|
m_uiDataBufOffset = 0;
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Make sure the vector array is allocated at least up to the element
|
|
number that is passed in.
|
|
****************************************************************************/
|
|
RCODE F_DataVector::allocVectorArray(
|
|
FLMUINT uiElementNumber)
|
|
{
|
|
RCODE rc = NE_SFLM_OK;
|
|
|
|
if (uiElementNumber >= m_uiNumElements)
|
|
{
|
|
|
|
// May need to allocate a new vector array
|
|
|
|
if (uiElementNumber >= m_uiVectorArraySize)
|
|
{
|
|
FLMUINT uiNewArraySize = uiElementNumber + 32;
|
|
F_VECTOR_ELEMENT * pNewVector;
|
|
|
|
if (m_pVectorElements == &m_VectorArray [0])
|
|
{
|
|
if (RC_BAD( rc = f_alloc( uiNewArraySize * sizeof( F_VECTOR_ELEMENT),
|
|
&pNewVector)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
if (m_uiNumElements)
|
|
{
|
|
f_memcpy( pNewVector, m_pVectorElements,
|
|
m_uiNumElements * sizeof( F_VECTOR_ELEMENT));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pNewVector = m_pVectorElements;
|
|
|
|
if (RC_BAD( rc = f_realloc( uiNewArraySize * sizeof( F_VECTOR_ELEMENT),
|
|
&pNewVector)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
}
|
|
m_pVectorElements = pNewVector;
|
|
m_uiVectorArraySize = uiNewArraySize;
|
|
}
|
|
|
|
// Initialized everything between the old last element and
|
|
// the new element, including the new element, to zeroes.
|
|
|
|
f_memset( &m_pVectorElements [m_uiNumElements], 0,
|
|
sizeof( F_VECTOR_ELEMENT) *
|
|
(uiElementNumber - m_uiNumElements + 1));
|
|
|
|
m_uiNumElements = uiElementNumber + 1;
|
|
}
|
|
|
|
Exit:
|
|
|
|
return( rc);
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Store a data value into its vector element.
|
|
****************************************************************************/
|
|
RCODE F_DataVector::storeValue(
|
|
FLMINT uiElementNumber,
|
|
eDataType eDataTyp,
|
|
const FLMBYTE * pucData,
|
|
FLMUINT uiDataLen,
|
|
FLMBYTE ** ppucDataPtr)
|
|
{
|
|
RCODE rc = NE_SFLM_OK;
|
|
F_VECTOR_ELEMENT * pVector;
|
|
FLMBYTE * pucDataPtr;
|
|
FLMUINT uiTemp;
|
|
|
|
// Find or allocate space for the vector
|
|
|
|
if (RC_BAD( rc = allocVectorArray( uiElementNumber)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
pVector = &m_pVectorElements [uiElementNumber];
|
|
|
|
// Will the data fit inside uiDataOffset?
|
|
|
|
if (uiDataLen <= sizeof( FLMUINT))
|
|
{
|
|
pucDataPtr = (FLMBYTE *)&pVector->uiDataOffset;
|
|
}
|
|
else if (uiDataLen <= pVector->uiDataLength)
|
|
{
|
|
|
|
// New data will fit in original space. Simply reuse it.
|
|
|
|
pucDataPtr = m_pucDataBuf + pVector->uiDataOffset;
|
|
}
|
|
else
|
|
{
|
|
|
|
// New data will not fit in originally allocated space.
|
|
// Must allocate new space.
|
|
|
|
// Always align the new allocation so that if it gets
|
|
// reused later for binary data it will be properly aligned.
|
|
|
|
if ((m_uiDataBufOffset & FLM_ALLOC_ALIGN) != 0)
|
|
{
|
|
uiTemp = (FLM_ALLOC_ALIGN + 1) - (m_uiDataBufOffset & FLM_ALLOC_ALIGN);
|
|
m_uiDataBufOffset += uiTemp;
|
|
}
|
|
|
|
if (uiDataLen + m_uiDataBufOffset > m_uiDataBufLength)
|
|
{
|
|
// Re-allocate the data buffer.
|
|
|
|
if( m_pucDataBuf == m_ucIntDataBuf)
|
|
{
|
|
if (RC_BAD( rc = f_alloc(
|
|
m_uiDataBufOffset + uiDataLen + 512,
|
|
&m_pucDataBuf)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
f_memcpy( m_pucDataBuf, m_ucIntDataBuf, m_uiDataBufOffset);
|
|
}
|
|
else
|
|
{
|
|
if (RC_BAD( rc = f_realloc(
|
|
m_uiDataBufOffset + uiDataLen + 512,
|
|
&m_pucDataBuf)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
m_uiDataBufLength = m_uiDataBufOffset + uiDataLen + 512;
|
|
}
|
|
pucDataPtr = m_pucDataBuf + m_uiDataBufOffset;
|
|
pVector->uiDataOffset = m_uiDataBufOffset;
|
|
m_uiDataBufOffset += uiDataLen;
|
|
}
|
|
|
|
// Store the data - may be zero length.
|
|
|
|
if( pucData)
|
|
{
|
|
if( uiDataLen > 1)
|
|
{
|
|
f_memcpy( pucDataPtr, pucData, uiDataLen);
|
|
}
|
|
else if( uiDataLen)
|
|
{
|
|
*pucDataPtr = *pucData;
|
|
}
|
|
}
|
|
|
|
pVector->uiFlags |= VECT_SLOT_HAS_DATA;
|
|
pVector->uiDataLength = uiDataLen;
|
|
pVector->eDataTyp = eDataTyp;
|
|
|
|
if( ppucDataPtr)
|
|
{
|
|
*ppucDataPtr = pucDataPtr;
|
|
}
|
|
|
|
Exit:
|
|
|
|
return( rc);
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Set the column number for a vector element.
|
|
****************************************************************************/
|
|
RCODE F_DataVector::setColumnNum(
|
|
FLMUINT uiElementNumber,
|
|
FLMUINT uiColumnNum,
|
|
FLMBOOL bIsData)
|
|
{
|
|
RCODE rc = NE_SFLM_OK;
|
|
F_VECTOR_ELEMENT * pVector;
|
|
|
|
// Find or allocate space for the vector element
|
|
|
|
if (RC_BAD( rc = allocVectorArray( uiElementNumber)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
pVector = &m_pVectorElements [uiElementNumber];
|
|
|
|
pVector->uiFlags |= VECT_SLOT_HAS_COLUMN_NUM;
|
|
if (bIsData)
|
|
{
|
|
pVector->uiFlags |= VECT_SLOT_IS_DATA;
|
|
}
|
|
else
|
|
{
|
|
pVector->uiFlags &= (~(VECT_SLOT_IS_DATA));
|
|
}
|
|
pVector->uiColumnNum = uiColumnNum;
|
|
|
|
Exit:
|
|
|
|
return( rc);
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Set a FLMINT value for a vector element.
|
|
****************************************************************************/
|
|
RCODE F_DataVector::setINT(
|
|
FLMUINT uiElementNumber,
|
|
FLMINT iNum)
|
|
{
|
|
RCODE rc = NE_SFLM_OK;
|
|
FLMBYTE ucStorageBuf [FLM_MAX_NUM_BUF_SIZE];
|
|
FLMUINT uiStorageLen;
|
|
FLMBOOL bNeg = FALSE;
|
|
|
|
if (iNum < 0)
|
|
{
|
|
bNeg = TRUE;
|
|
iNum = -iNum;
|
|
}
|
|
|
|
uiStorageLen = sizeof( ucStorageBuf);
|
|
if( ((FLMUINT)iNum) <= gv_uiMaxUInt32Val)
|
|
{
|
|
if( RC_BAD( rc = flmNumber64ToStorage( (FLMUINT64)iNum,
|
|
&uiStorageLen, ucStorageBuf, bNeg, FALSE)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( RC_BAD( rc = flmNumber64ToStorage( (FLMUINT64)iNum,
|
|
&uiStorageLen, ucStorageBuf, bNeg, FALSE)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
if (RC_BAD( rc = storeValue( uiElementNumber,
|
|
SFLM_NUMBER_TYPE, ucStorageBuf, uiStorageLen)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
Exit:
|
|
|
|
return( rc);
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Set a FLMINT64 value for a vector element.
|
|
****************************************************************************/
|
|
RCODE F_DataVector::setINT64(
|
|
FLMUINT uiElementNumber,
|
|
FLMINT64 i64Num)
|
|
{
|
|
RCODE rc = NE_SFLM_OK;
|
|
FLMBYTE ucStorageBuf [FLM_MAX_NUM_BUF_SIZE];
|
|
FLMUINT uiStorageLen;
|
|
FLMBOOL bNeg = FALSE;
|
|
|
|
if (i64Num < 0)
|
|
{
|
|
bNeg = TRUE;
|
|
i64Num = -i64Num;
|
|
}
|
|
|
|
uiStorageLen = sizeof( ucStorageBuf);
|
|
if (RC_BAD( rc = flmNumber64ToStorage( i64Num, &uiStorageLen,
|
|
ucStorageBuf, bNeg, FALSE)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
if (RC_BAD( rc = storeValue( uiElementNumber,
|
|
SFLM_NUMBER_TYPE, ucStorageBuf, uiStorageLen)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
Exit:
|
|
|
|
return( rc);
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Set a FLMUINT value for a vector element.
|
|
****************************************************************************/
|
|
RCODE F_DataVector::setUINT(
|
|
FLMUINT uiElementNumber,
|
|
FLMUINT uiNum)
|
|
{
|
|
RCODE rc = NE_SFLM_OK;
|
|
FLMBYTE ucStorageBuf [FLM_MAX_NUM_BUF_SIZE];
|
|
FLMUINT uiStorageLen;
|
|
|
|
uiStorageLen = sizeof( ucStorageBuf);
|
|
if (uiNum <= gv_uiMaxUInt32Val)
|
|
{
|
|
if (RC_BAD( rc = flmNumber64ToStorage( uiNum,
|
|
&uiStorageLen, ucStorageBuf, FALSE, FALSE)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (RC_BAD( rc = flmNumber64ToStorage( uiNum,
|
|
&uiStorageLen, ucStorageBuf, FALSE, FALSE)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
if (RC_BAD( rc = storeValue( uiElementNumber,
|
|
SFLM_NUMBER_TYPE, ucStorageBuf, uiStorageLen)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
Exit:
|
|
|
|
return( rc);
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Set a FLMUINT64 value for a vector element.
|
|
****************************************************************************/
|
|
RCODE F_DataVector::setUINT64(
|
|
FLMUINT uiElementNumber,
|
|
FLMUINT64 ui64Num)
|
|
{
|
|
RCODE rc = NE_SFLM_OK;
|
|
FLMBYTE ucStorageBuf [FLM_MAX_NUM_BUF_SIZE];
|
|
FLMUINT uiStorageLen;
|
|
|
|
uiStorageLen = sizeof( ucStorageBuf);
|
|
if (RC_BAD( rc = flmNumber64ToStorage( ui64Num,
|
|
&uiStorageLen, ucStorageBuf, FALSE, FALSE)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
if (RC_BAD( rc = storeValue( uiElementNumber,
|
|
SFLM_NUMBER_TYPE, ucStorageBuf, uiStorageLen)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
Exit:
|
|
|
|
return( rc);
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Set a FLMUNICODE value for a vector element.
|
|
****************************************************************************/
|
|
RCODE F_DataVector::setUnicode(
|
|
FLMUINT uiElementNumber,
|
|
const FLMUNICODE * puzUnicode)
|
|
{
|
|
RCODE rc = NE_SFLM_OK;
|
|
FLMBYTE * pucDataPtr;
|
|
FLMUINT uiLen;
|
|
FLMUINT uiCharCount;
|
|
FLMBYTE ucTmpBuf [64];
|
|
|
|
// A NULL or empty puzUnicode string is allowed - on those cases
|
|
// just set the data type.
|
|
|
|
if (puzUnicode == NULL || *puzUnicode == 0)
|
|
{
|
|
rc = storeValue( uiElementNumber, SFLM_STRING_TYPE, NULL, 0);
|
|
goto Exit;
|
|
}
|
|
|
|
// See if it will fit in our temporary buffer on the stack.
|
|
|
|
uiLen = sizeof( ucTmpBuf);
|
|
if (RC_OK( rc = flmUnicode2Storage( puzUnicode, 0, ucTmpBuf,
|
|
&uiLen, &uiCharCount)))
|
|
{
|
|
if (RC_BAD( rc = storeValue( uiElementNumber,
|
|
SFLM_STRING_TYPE, ucTmpBuf, uiLen)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
else if (rc != NE_SFLM_CONV_DEST_OVERFLOW)
|
|
{
|
|
goto Exit;
|
|
}
|
|
else
|
|
{
|
|
|
|
// Determine the length needed.
|
|
|
|
if (RC_BAD( rc = flmUnicode2Storage( puzUnicode, 0, NULL,
|
|
&uiLen, &uiCharCount)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Allocate space for it in the vector and get a pointer
|
|
// back so we can then store it.
|
|
|
|
if (RC_BAD( rc = storeValue( uiElementNumber,
|
|
SFLM_STRING_TYPE, NULL, uiLen, &pucDataPtr)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Store it out to the space we just allocated.
|
|
|
|
if (RC_BAD( rc = flmUnicode2Storage( puzUnicode, uiCharCount,
|
|
pucDataPtr, &uiLen, NULL)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
|
|
return( rc);
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Set a UTF8 value for a vector element.
|
|
****************************************************************************/
|
|
RCODE F_DataVector::setUTF8(
|
|
FLMUINT uiElementNumber,
|
|
const FLMBYTE * pszUTF8,
|
|
FLMUINT uiBytesInBuffer)
|
|
{
|
|
RCODE rc = NE_SFLM_OK;
|
|
FLMBYTE * pucDataPtr;
|
|
FLMUINT uiLen;
|
|
FLMBYTE ucTmpBuf [64];
|
|
|
|
// A NULL or empty pszNative string is allowed - on those cases
|
|
// just set the data type.
|
|
|
|
if (pszUTF8 == NULL || *pszUTF8 == 0)
|
|
{
|
|
rc = storeValue( uiElementNumber, SFLM_STRING_TYPE, NULL, 0);
|
|
goto Exit;
|
|
}
|
|
|
|
// See if it will fit in our temporary buffer on the stack.
|
|
|
|
uiLen = sizeof( ucTmpBuf);
|
|
if (RC_OK( rc = flmUTF8ToStorage(
|
|
pszUTF8, uiBytesInBuffer, ucTmpBuf, &uiLen)))
|
|
{
|
|
if (RC_BAD( rc = storeValue( uiElementNumber,
|
|
SFLM_STRING_TYPE, ucTmpBuf, uiLen)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
else if (rc != NE_SFLM_CONV_DEST_OVERFLOW)
|
|
{
|
|
goto Exit;
|
|
}
|
|
else
|
|
{
|
|
// Determine the length needed.
|
|
|
|
if (RC_BAD( rc = flmUTF8ToStorage(
|
|
pszUTF8, uiBytesInBuffer, NULL, &uiLen)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Allocate space for it in the vector and get a pointer
|
|
// back so we can then store it.
|
|
|
|
if (RC_BAD( rc = storeValue( uiElementNumber,
|
|
SFLM_STRING_TYPE, NULL, uiLen, &pucDataPtr)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Store it out to the space we just allocated.
|
|
|
|
if (RC_BAD( rc = flmUTF8ToStorage(
|
|
pszUTF8, uiBytesInBuffer, pucDataPtr, &uiLen)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
|
|
return( rc);
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Get a pointer to the UTF8 - no conversions are done.
|
|
****************************************************************************/
|
|
RCODE F_DataVector::getUTF8Ptr(
|
|
FLMUINT uiElementNumber,
|
|
const FLMBYTE ** ppszUTF8,
|
|
FLMUINT * puiBufLen)
|
|
{
|
|
RCODE rc = NE_SFLM_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->eDataTyp != SFLM_STRING_TYPE)
|
|
{
|
|
rc = RC_SET( NE_SFLM_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: Allocate data for a unicode element and retrieve it.
|
|
****************************************************************************/
|
|
RCODE F_DataVector::getUnicode(
|
|
FLMUINT uiElementNumber,
|
|
FLMUNICODE ** ppuzUnicode)
|
|
{
|
|
RCODE rc = NE_SFLM_OK;
|
|
FLMUINT uiLen;
|
|
|
|
// Get the unicode length (does not include NULL terminator)
|
|
|
|
if (RC_BAD( rc = getUnicode( uiElementNumber, NULL, &uiLen)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
if (uiLen)
|
|
{
|
|
|
|
// Account for NULL character.
|
|
|
|
uiLen += sizeof( FLMUNICODE);
|
|
|
|
if( RC_BAD( rc = f_alloc( uiLen, ppuzUnicode)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
if (RC_BAD( rc = getUnicode( uiElementNumber, *ppuzUnicode,
|
|
&uiLen)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*ppuzUnicode = NULL;
|
|
}
|
|
|
|
Exit:
|
|
|
|
return( rc);
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Compose a key buffer from the vector's components.
|
|
****************************************************************************/
|
|
RCODE F_DataVector::outputKey(
|
|
F_Db * pDb,
|
|
FLMUINT uiIndexNum,
|
|
FLMUINT uiMatchFlags,
|
|
FLMBYTE * pucKeyBuf,
|
|
FLMUINT uiKeyBufSize,
|
|
FLMUINT * puiKeyLen,
|
|
FLMUINT uiSearchKeyFlag)
|
|
{
|
|
RCODE rc = NE_SFLM_OK;
|
|
ICD * pIcd;
|
|
F_Dict * pDict = pDb->getDict();
|
|
F_INDEX * pIndex = pDict->getIndex( uiIndexNum);
|
|
F_TABLE * pTable = pDict->getTable( pIndex->uiTableNum);
|
|
F_COLUMN * pColumn;
|
|
FLMBYTE * pucToKey;
|
|
FLMBYTE * pucKeyLenPos;
|
|
FLMUINT uiToKeyLen;
|
|
FLMUINT uiKeyLen;
|
|
FLMUINT uiKeyComponent;
|
|
FLMBOOL bDataTruncated;
|
|
eDataType eDataTyp;
|
|
FLMUINT uiLanguage;
|
|
F_VECTOR_ELEMENT * pVector = NULL;
|
|
FLMBYTE ucIDBuf [10];
|
|
FLMUINT uiIDLen = 0;
|
|
FLMUINT uiMaxKeySize;
|
|
FLMUINT uiDataLen;
|
|
const FLMBYTE * pucDataPtr;
|
|
FLMUINT uiIDMatchFlags = uiMatchFlags & FLM_MATCH_ROW_ID;
|
|
F_BufferIStream bufferIStream;
|
|
|
|
if (uiIDMatchFlags)
|
|
{
|
|
pucToKey = &ucIDBuf [0];
|
|
uiIDLen = f_encodeSEN( m_ui64RowId, &pucToKey);
|
|
if (uiIDLen >= uiKeyBufSize)
|
|
{
|
|
rc = RC_SET( NE_SFLM_CONV_DEST_OVERFLOW);
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
// Output the key components
|
|
|
|
uiMaxKeySize = uiKeyBufSize - uiIDLen;
|
|
uiLanguage = pIndex->uiLanguage;
|
|
uiKeyLen = 0;
|
|
pucToKey = pucKeyBuf;
|
|
for (uiKeyComponent = 0, pIcd = pIndex->pKeyIcds;
|
|
uiKeyComponent < pIndex->uiNumKeyComponents;
|
|
uiKeyComponent++, pIcd++)
|
|
{
|
|
pucKeyLenPos = pucToKey;
|
|
pucToKey += 2;
|
|
uiKeyLen += 2;
|
|
pColumn = pDict->getColumn( pTable, pIcd->uiColumnNum);
|
|
|
|
eDataTyp = pColumn->eDataTyp;
|
|
|
|
// Find matching node in the tree - if not found skip and continue.
|
|
|
|
if ((pVector = getVector( uiKeyComponent, VECT_SLOT_HAS_DATA)) == NULL)
|
|
{
|
|
UW2FBA( 0, pucKeyLenPos);
|
|
}
|
|
else
|
|
{
|
|
uiToKeyLen = 0;
|
|
bDataTruncated = FALSE;
|
|
|
|
// Take the dictionary number and make it the key
|
|
|
|
if (pIcd->uiFlags & ICD_PRESENCE)
|
|
{
|
|
// Output the column number
|
|
|
|
if (uiKeyLen + 4 > uiMaxKeySize)
|
|
{
|
|
rc = RC_SET( NE_SFLM_CONV_DEST_OVERFLOW);
|
|
goto Exit;
|
|
}
|
|
|
|
f_UINT32ToBigEndian( (FLMUINT32)pIcd->uiColumnNum, pucToKey);
|
|
uiToKeyLen = 4;
|
|
}
|
|
else if (pIcd->uiFlags & ICD_METAPHONE)
|
|
{
|
|
FLMUINT uiMeta;
|
|
FLMBYTE ucStorageBuf[ FLM_MAX_NUM_BUF_SIZE];
|
|
FLMUINT uiStorageLen;
|
|
|
|
if (eDataTyp != SFLM_STRING_TYPE)
|
|
{
|
|
rc = RC_SET_AND_ASSERT( NE_SFLM_BAD_DATA_TYPE);
|
|
goto Exit;
|
|
}
|
|
|
|
if (pVector->eDataTyp == SFLM_STRING_TYPE)
|
|
{
|
|
if (RC_BAD( rc = getUTF8Ptr( uiKeyComponent,
|
|
&pucDataPtr, &uiDataLen)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
if (RC_BAD( rc = bufferIStream.openStream(
|
|
(const char *)pucDataPtr, uiDataLen)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
if (RC_BAD( rc = f_getNextMetaphone( &bufferIStream, &uiMeta)))
|
|
{
|
|
if( rc == NE_SFLM_EOF_HIT)
|
|
{
|
|
rc = RC_SET( NE_SFLM_BAD_DATA_TYPE);
|
|
}
|
|
goto Exit;
|
|
}
|
|
|
|
bufferIStream.closeStream();
|
|
}
|
|
else if (pVector->eDataTyp == SFLM_NUMBER_TYPE)
|
|
{
|
|
if( RC_BAD( rc = getUINT( uiKeyComponent, &uiMeta)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rc = RC_SET_AND_ASSERT( NE_SFLM_BAD_DATA_TYPE);
|
|
goto Exit;
|
|
}
|
|
|
|
if (uiMeta)
|
|
{
|
|
uiStorageLen = FLM_MAX_NUM_BUF_SIZE;
|
|
if( RC_BAD( rc = flmNumber64ToStorage( uiMeta,
|
|
&uiStorageLen, ucStorageBuf, FALSE, FALSE)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
if (RC_BAD( rc = bufferIStream.openStream(
|
|
(const char *)ucStorageBuf, uiStorageLen)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Output the metaphone key piece
|
|
|
|
uiToKeyLen = uiMaxKeySize - uiKeyLen;
|
|
if( RC_BAD( rc = KYCollateValue( pucToKey, &uiToKeyLen,
|
|
&bufferIStream, SFLM_NUMBER_TYPE,
|
|
pIcd->uiFlags, pIcd->uiCompareRules, pIcd->uiLimit,
|
|
NULL, NULL, uiLanguage,
|
|
FALSE, FALSE, &bDataTruncated, NULL)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
bufferIStream.closeStream();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (eDataTyp == SFLM_STRING_TYPE)
|
|
{
|
|
if (RC_BAD( rc = getUTF8Ptr( uiKeyComponent,
|
|
&pucDataPtr, &uiDataLen)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pucDataPtr = (FLMBYTE *)getDataPtr( pVector);
|
|
uiDataLen = pVector->uiDataLength;
|
|
}
|
|
|
|
if (uiDataLen)
|
|
{
|
|
|
|
if (RC_BAD( rc = bufferIStream.openStream(
|
|
(const char *)pucDataPtr, uiDataLen)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
uiToKeyLen = uiMaxKeySize - uiKeyLen;
|
|
if( RC_BAD( rc = KYCollateValue( pucToKey, &uiToKeyLen,
|
|
&bufferIStream, eDataTyp,
|
|
pIcd->uiFlags, pIcd->uiCompareRules, pIcd->uiLimit,
|
|
NULL, NULL, uiLanguage,
|
|
(FLMBOOL) ((pIcd->uiFlags & ICD_SUBSTRING)
|
|
? (isLeftTruncated( pVector)
|
|
? FALSE : TRUE)
|
|
: FALSE),
|
|
isRightTruncated( pVector),
|
|
&bDataTruncated, NULL)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
bufferIStream.closeStream();
|
|
}
|
|
}
|
|
|
|
if (uiToKeyLen)
|
|
{
|
|
|
|
// Increment total key length
|
|
|
|
pucToKey += uiToKeyLen;
|
|
uiKeyLen += uiToKeyLen;
|
|
}
|
|
if (!bDataTruncated)
|
|
{
|
|
UW2FBA( (FLMUINT16)(uiToKeyLen | uiSearchKeyFlag),
|
|
pucKeyLenPos);
|
|
}
|
|
else
|
|
{
|
|
UW2FBA( (FLMUINT16)(uiToKeyLen | TRUNCATED_FLAG |
|
|
uiSearchKeyFlag), pucKeyLenPos);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Output the row ID, if requested.
|
|
|
|
if (uiIDMatchFlags)
|
|
{
|
|
|
|
// There will always be room at this point for the
|
|
// row ID - because it was subtracted out above.
|
|
|
|
f_memcpy( pucToKey, ucIDBuf, uiIDLen);
|
|
}
|
|
*puiKeyLen = uiKeyLen + uiIDLen;
|
|
|
|
Exit:
|
|
|
|
return( rc);
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Populate a vector's components from the key part of an index key.
|
|
****************************************************************************/
|
|
RCODE F_DataVector::inputKey(
|
|
F_Db * pDb,
|
|
FLMUINT uiIndexNum,
|
|
const FLMBYTE * pucKey,
|
|
FLMUINT uiKeyLen)
|
|
{
|
|
RCODE rc = NE_SFLM_OK;
|
|
F_Dict * pDict = pDb->getDict();
|
|
F_INDEX * pIndex = pDict->getIndex( uiIndexNum);
|
|
F_TABLE * pTable = pDict->getTable( pIndex->uiTableNum);
|
|
F_COLUMN * pColumn;
|
|
const FLMBYTE * pucKeyEnd = pucKey + uiKeyLen;
|
|
FLMBYTE ucDataBuf [SFLM_MAX_KEY_SIZE];
|
|
FLMUINT uiDataLen;
|
|
ICD * pIcd;
|
|
FLMUINT uiLanguage = pIndex->uiLanguage;
|
|
FLMUINT uiComponentLen;
|
|
eDataType eDataTyp;
|
|
FLMBOOL bDataRightTruncated;
|
|
FLMBOOL bFirstSubstring;
|
|
FLMBOOL bIsText;
|
|
FLMUINT uiComponent;
|
|
FLMUINT uiColumnNum;
|
|
|
|
flmAssert( uiKeyLen);
|
|
|
|
// Loop for each compound piece of key
|
|
|
|
for (uiComponent = 0, pIcd = pIndex->pKeyIcds;
|
|
uiComponent < pIndex->uiNumKeyComponents;
|
|
pIcd++, uiComponent++)
|
|
{
|
|
if (uiKeyLen < 2)
|
|
{
|
|
rc = RC_SET_AND_ASSERT( NE_SFLM_BTREE_ERROR);
|
|
goto Exit;
|
|
}
|
|
uiColumnNum = pIcd->uiColumnNum;
|
|
pColumn = pDict->getColumn( pTable, uiColumnNum);
|
|
|
|
uiComponentLen = getKeyComponentLength( pucKey);
|
|
bDataRightTruncated = isKeyComponentTruncated( pucKey);
|
|
uiKeyLen -= 2;
|
|
pucKey += 2;
|
|
|
|
if (uiComponentLen > uiKeyLen)
|
|
{
|
|
rc = RC_SET_AND_ASSERT( NE_SFLM_BTREE_ERROR);
|
|
goto Exit;
|
|
}
|
|
|
|
bFirstSubstring = FALSE;
|
|
eDataTyp = pColumn->eDataTyp;
|
|
bIsText = (eDataTyp == SFLM_STRING_TYPE &&
|
|
!(pIcd->uiFlags & (ICD_PRESENCE | ICD_METAPHONE)))
|
|
? TRUE
|
|
: FALSE;
|
|
|
|
if (uiComponentLen)
|
|
{
|
|
if (pIcd->uiFlags & ICD_PRESENCE)
|
|
{
|
|
FLMUINT uiNum;
|
|
|
|
if (uiComponentLen != 4 || bDataRightTruncated)
|
|
{
|
|
rc = RC_SET_AND_ASSERT( NE_SFLM_BTREE_ERROR);
|
|
goto Exit;
|
|
}
|
|
uiNum = (FLMUINT)f_bigEndianToUINT32( pucKey);
|
|
|
|
// What is stored in the key better match the column
|
|
// number of the ICD.
|
|
|
|
if (uiNum != uiColumnNum)
|
|
{
|
|
rc = RC_SET_AND_ASSERT( NE_SFLM_BTREE_ERROR);
|
|
goto Exit;
|
|
}
|
|
if (RC_BAD( rc = setUINT( uiComponent, uiNum)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
else if (pIcd->uiFlags & ICD_METAPHONE)
|
|
{
|
|
uiDataLen = sizeof( ucDataBuf);
|
|
|
|
if (uiComponentLen)
|
|
{
|
|
if( RC_BAD( rc = flmCollationNum2StorageNum( pucKey,
|
|
uiComponentLen, ucDataBuf, &uiDataLen)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
uiDataLen = 0;
|
|
}
|
|
|
|
if (bDataRightTruncated)
|
|
{
|
|
rc = RC_SET_AND_ASSERT( NE_SFLM_BTREE_ERROR);
|
|
goto Exit;
|
|
}
|
|
|
|
// Allocate and copy value into the component. NOTE:
|
|
// storeValue handles zero length data.
|
|
|
|
if (RC_BAD( rc = storeValue( uiComponent, SFLM_NUMBER_TYPE,
|
|
ucDataBuf, uiDataLen)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
// Grab only the Nth section of key if compound key
|
|
|
|
switch (eDataTyp)
|
|
{
|
|
case SFLM_STRING_TYPE:
|
|
{
|
|
FLMBOOL bTmpTruncated = FALSE;
|
|
|
|
if (uiComponentLen)
|
|
{
|
|
uiDataLen = sizeof( ucDataBuf);
|
|
if (RC_BAD( rc = flmColText2StorageText( pucKey,
|
|
uiComponentLen,
|
|
ucDataBuf, &uiDataLen, uiLanguage,
|
|
&bTmpTruncated, &bFirstSubstring)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
if (bTmpTruncated != bDataRightTruncated)
|
|
{
|
|
rc = RC_SET_AND_ASSERT( NE_SFLM_BTREE_ERROR);
|
|
goto Exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
uiDataLen = 0;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case SFLM_NUMBER_TYPE:
|
|
{
|
|
if (uiComponentLen)
|
|
{
|
|
uiDataLen = sizeof( ucDataBuf);
|
|
if( RC_BAD( rc = flmCollationNum2StorageNum( pucKey,
|
|
uiComponentLen, ucDataBuf, &uiDataLen)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
uiDataLen = 0;
|
|
}
|
|
|
|
if (bDataRightTruncated)
|
|
{
|
|
rc = RC_SET_AND_ASSERT( NE_SFLM_BTREE_ERROR);
|
|
goto Exit;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case SFLM_BINARY_TYPE:
|
|
{
|
|
uiDataLen = uiComponentLen;
|
|
if (uiComponentLen > sizeof( ucDataBuf))
|
|
{
|
|
rc = RC_SET( NE_SFLM_CONV_DEST_OVERFLOW);
|
|
goto Exit;
|
|
}
|
|
if (uiComponentLen)
|
|
{
|
|
f_memcpy( ucDataBuf, pucKey, uiComponentLen);
|
|
}
|
|
break;
|
|
}
|
|
|
|
default:
|
|
rc = RC_SET( NE_SFLM_DATA_ERROR);
|
|
goto Exit;
|
|
}
|
|
|
|
// Allocate and copy value into the component. NOTE:
|
|
// storeValue handles zero length data.
|
|
|
|
if (RC_BAD( rc = storeValue( uiComponent, eDataTyp, ucDataBuf,
|
|
uiDataLen)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Set first sub-string and truncated flags.
|
|
|
|
if ((pIcd->uiFlags & ICD_SUBSTRING) && !bFirstSubstring)
|
|
{
|
|
setLeftTruncated( uiComponent);
|
|
}
|
|
if (bDataRightTruncated)
|
|
{
|
|
setRightTruncated( uiComponent);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Store the column number
|
|
|
|
if (RC_BAD( rc = setColumnNum( uiComponent, uiColumnNum, FALSE)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Position to the end of this component
|
|
|
|
flmAssert( uiKeyLen >= uiComponentLen);
|
|
pucKey += uiComponentLen;
|
|
uiKeyLen -= uiComponentLen;
|
|
}
|
|
|
|
// See if we have a row ID.
|
|
|
|
if (RC_BAD( rc = f_decodeSEN64( &pucKey, pucKeyEnd, &m_ui64RowId)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// Store the column numbers for the data components, if any.
|
|
|
|
for (uiComponent = 0, pIcd = pIndex->pDataIcds;
|
|
uiComponent < pIndex->uiNumDataComponents;
|
|
pIcd++, uiComponent++)
|
|
{
|
|
|
|
// Store the column number
|
|
|
|
if (RC_BAD( rc = setColumnNum( uiComponent + pIndex->uiNumKeyComponents,
|
|
pIcd->uiColumnNum, TRUE)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
|
|
return( rc);
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Compose a data buffer from the vector's components.
|
|
****************************************************************************/
|
|
RCODE F_DataVector::outputData(
|
|
F_Db * pDb,
|
|
FLMUINT uiIndexNum,
|
|
FLMBYTE * pucDataBuf,
|
|
FLMUINT uiDataBufSize,
|
|
FLMUINT * puiDataLen)
|
|
{
|
|
RCODE rc = NE_SFLM_OK;
|
|
F_Dict * pDict = pDb->getDict();
|
|
F_INDEX * pIndex = pDict->getIndex( uiIndexNum);
|
|
F_TABLE * pTable = pDict->getTable( pIndex->uiTableNum);
|
|
F_COLUMN * pColumn;
|
|
ICD * pIcd;
|
|
FLMUINT uiDataComponent;
|
|
F_VECTOR_ELEMENT * pVector;
|
|
FLMBYTE * pucData;
|
|
FLMUINT uiDataLength;
|
|
FLMUINT uiTotalLength = 0;
|
|
FLMBYTE ucTmpSen [32];
|
|
FLMBYTE * pucTmpSen = &ucTmpSen [0];
|
|
FLMUINT uiSENLen;
|
|
FLMUINT uiLastDataLen = 0;
|
|
|
|
// Loop for each data component of key
|
|
|
|
for (uiDataComponent = 0, pIcd = pIndex->pDataIcds;
|
|
uiDataComponent < pIndex->uiNumDataComponents;
|
|
pIcd++, uiDataComponent++)
|
|
{
|
|
pColumn = pDict->getColumn( pTable, pIcd->uiColumnNum);
|
|
if ((pVector = getVector( uiDataComponent + pIndex->uiNumKeyComponents,
|
|
VECT_SLOT_HAS_DATA)) != NULL)
|
|
{
|
|
|
|
// Cannot do data conversions right now.
|
|
|
|
flmAssert( pVector->eDataTyp == pColumn->eDataTyp);
|
|
uiDataLength = pVector->uiDataLength;
|
|
pucData = (FLMBYTE *)getDataPtr( pVector);
|
|
}
|
|
else
|
|
{
|
|
uiDataLength = 0;
|
|
pucData = NULL;
|
|
}
|
|
|
|
// Output the length of the data as a SEN value
|
|
|
|
uiSENLen = f_encodeSEN( uiDataLength, &pucTmpSen);
|
|
if (uiTotalLength + uiSENLen > uiDataBufSize)
|
|
{
|
|
rc = RC_SET( NE_SFLM_CONV_DEST_OVERFLOW);
|
|
goto Exit;
|
|
}
|
|
f_memcpy( pucDataBuf, ucTmpSen, uiSENLen);
|
|
pucDataBuf += uiSENLen;
|
|
uiTotalLength += uiSENLen;
|
|
|
|
// Output the data
|
|
|
|
if (uiDataLength)
|
|
{
|
|
if (uiTotalLength + uiDataLength > uiDataBufSize)
|
|
{
|
|
rc = RC_SET( NE_SFLM_CONV_DEST_OVERFLOW);
|
|
goto Exit;
|
|
}
|
|
f_memcpy( pucDataBuf, pucData, uiDataLength);
|
|
pucDataBuf += uiDataLength;
|
|
uiTotalLength += uiDataLength;
|
|
uiLastDataLen = uiTotalLength;
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
|
|
// Even if rc == NE_SFLM_CONV_DEST_OVERFLOW, return a length
|
|
|
|
*puiDataLen = uiLastDataLen;
|
|
|
|
return( rc);
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Populate a vector's data components from the data part of a key.
|
|
****************************************************************************/
|
|
RCODE F_DataVector::inputData(
|
|
F_Db * pDb,
|
|
FLMUINT uiIndexNum,
|
|
const FLMBYTE * pucData,
|
|
FLMUINT uiInputLen)
|
|
{
|
|
RCODE rc = NE_SFLM_OK;
|
|
F_Dict * pDict = pDb->getDict();
|
|
F_INDEX * pIndex = pDict->getIndex( uiIndexNum);
|
|
F_TABLE * pTable = pDict->getTable( pIndex->uiTableNum);
|
|
F_COLUMN * pColumn;
|
|
ICD * pIcd;
|
|
FLMUINT uiDataComponent = 0;
|
|
FLMUINT uiDataLength;
|
|
FLMUINT uiSENLen;
|
|
|
|
// Loop for each data component of key
|
|
|
|
for (uiDataComponent = 0, pIcd = pIndex->pDataIcds;
|
|
uiDataComponent < pIndex->uiNumDataComponents;
|
|
pIcd++, uiDataComponent++)
|
|
{
|
|
pColumn = pDict->getColumn( pTable, pIcd->uiColumnNum);
|
|
if (RC_BAD( rc = setColumnNum( uiDataComponent + pIndex->uiNumKeyComponents,
|
|
pIcd->uiColumnNum, TRUE)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
if (!uiInputLen)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Get the data length - it is stored as a SEN
|
|
|
|
uiSENLen = f_getSENLength( *pucData);
|
|
if (uiSENLen > uiInputLen)
|
|
{
|
|
rc = RC_SET( NE_SFLM_DATA_ERROR);
|
|
goto Exit;
|
|
}
|
|
|
|
if( RC_BAD( rc = f_decodeSEN( &pucData,
|
|
&pucData[ uiSENLen], &uiDataLength)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
uiInputLen -= uiSENLen;
|
|
if (uiDataLength > uiInputLen)
|
|
{
|
|
rc = RC_SET( NE_SFLM_DATA_ERROR);
|
|
goto Exit;
|
|
}
|
|
|
|
// Store the data into the vector.
|
|
|
|
if (RC_BAD( rc = storeValue( uiDataComponent + pIndex->uiNumKeyComponents,
|
|
pColumn->eDataTyp,
|
|
pucData, uiDataLength, NULL)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
pucData += uiDataLength;
|
|
uiInputLen -= uiDataLength;
|
|
}
|
|
|
|
Exit:
|
|
|
|
return( rc);
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Copy one data vector into another.
|
|
****************************************************************************/
|
|
RCODE F_DataVector::copyVector(
|
|
F_DataVector * pSrcVector)
|
|
{
|
|
RCODE rc = NE_SFLM_OK;
|
|
|
|
m_ui64RowId = pSrcVector->m_ui64RowId;
|
|
|
|
// If none of the elements are populated, there is nothing that
|
|
// needs to be done.
|
|
|
|
if ((m_uiNumElements = pSrcVector->m_uiNumElements) > 0)
|
|
{
|
|
if (RC_BAD( rc = allocVectorArray( pSrcVector->m_uiNumElements - 1)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
f_memcpy( m_pVectorElements, pSrcVector->m_pVectorElements,
|
|
sizeof( F_VECTOR_ELEMENT) * m_uiNumElements);
|
|
|
|
// Make sure we have enough room in our data buffer.
|
|
|
|
if (pSrcVector->m_uiDataBufOffset > m_uiDataBufLength)
|
|
{
|
|
if (m_pucDataBuf == &m_ucIntDataBuf [0])
|
|
{
|
|
if (RC_BAD( rc = f_alloc( pSrcVector->m_uiDataBufOffset,
|
|
&m_pucDataBuf)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
if (RC_BAD( rc = f_realloc( pSrcVector->m_uiDataBufOffset,
|
|
&m_pucDataBuf)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
m_uiDataBufLength = pSrcVector->m_uiDataBufOffset;
|
|
}
|
|
|
|
// Copy the source data buffer into ours.
|
|
|
|
m_uiDataBufOffset = pSrcVector->m_uiDataBufOffset;
|
|
f_memcpy( m_pucDataBuf, pSrcVector->m_pucDataBuf,
|
|
pSrcVector->m_uiDataBufOffset);
|
|
}
|
|
else
|
|
{
|
|
m_uiDataBufOffset = 0;
|
|
}
|
|
|
|
Exit:
|
|
|
|
return( rc);
|
|
}
|
|
|