Files
mars-flaim/sql/src/fnumber.cpp
dsandersoremutah ffe3cb6975 Changed Id property
git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@482 0109f412-320b-0410-ab79-c3e0c5ffbbe6
2006-05-30 22:00:45 +00:00

1002 lines
20 KiB
C++

//------------------------------------------------------------------------------
// Desc: Routines that do conversions between internal number and numeric
// key format to platform number types.
//
// Tabs: 3
//
// Copyright (c) 2002-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$
//------------------------------------------------------------------------------
#define DEFINE_NUMBER_MAXIMUMS
#include "flaimsys.h"
/****************************************************************************
Desc: Converts a UINT to its storage value
*****************************************************************************/
RCODE FlmUINT2Storage(
FLMUINT uiNum,
FLMUINT * puiBufLen, // In (buffer size) / Out (bytes used)
FLMBYTE * pucBuf)
{
RCODE rc = NE_SFLM_OK;
if( RC_BAD( rc = flmNumber64ToStorage( uiNum, puiBufLen,
pucBuf, FALSE, FALSE)))
{
goto Exit;
}
Exit:
return( rc);
}
/****************************************************************************
Desc: Converts an INT to its storage value
*****************************************************************************/
RCODE FlmINT2Storage(
FLMINT iNum,
FLMUINT * puiBufLen, // In (buffer size) / Out (bytes used)
FLMBYTE * pucBuf)
{
FLMBOOL bNeg = FALSE;
RCODE rc = NE_SFLM_OK;
if( iNum < 0)
{
iNum = -iNum;
bNeg = TRUE;
}
if( RC_BAD( rc = flmNumber64ToStorage( (FLMUINT64)iNum,
puiBufLen, pucBuf, bNeg, FALSE)))
{
goto Exit;
}
Exit:
return( rc);
}
/****************************************************************************
Desc: Converts a number to its storage or collation format
Notes: Changes to this code must also be made to flmUINT32ToStorage
*****************************************************************************/
RCODE flmNumber64ToStorage(
FLMUINT64 ui64Num,
FLMUINT * puiBufLen,
FLMBYTE * pucBuf,
FLMBOOL bNegative,
FLMBOOL bCollation)
{
RCODE rc = NE_SFLM_OK;
FLMUINT uiByteCount = 0;
FLMUINT32 ui32Low = (FLMUINT32)ui64Num;
FLMUINT32 ui32High = (FLMUINT32)(ui64Num >> 32);
if( *puiBufLen < FLM_MAX_NUM_BUF_SIZE)
{
rc = RC_SET_AND_ASSERT( NE_SFLM_CONV_DEST_OVERFLOW);
goto Exit;
}
// Negative flag should not be set if the number is 0
if( !ui64Num && bNegative)
{
rc = RC_SET_AND_ASSERT( NE_SFLM_ILLEGAL_OP);
goto Exit;
}
// Build the storage format, either for an index key (if bCollation
// is TRUE) or for a data element.
if( !bCollation)
{
// Build the data storage representation of the number
// Numbers are stored in a little-endian format
do
{
*pucBuf++ = (FLMBYTE)ui32Low;
ui32Low >>= 8;
uiByteCount++;
} while (ui32Low);
if( ui32High)
{
for( ; uiByteCount < 4; uiByteCount++)
{
*pucBuf++ = 0;
}
for( ; ui32High; uiByteCount++)
{
*pucBuf++ = (FLMBYTE)ui32High;
ui32High >>= 8;
}
}
// If a number is negative, the high bit of the right-most
// byte needs to be set. If the value of the number is such
// that its positive representation already has the high-bit
// set, we need to store an additional sign byte.
if( !bNegative)
{
if( *(pucBuf - 1) & 0x80)
{
*pucBuf++ = 0;
uiByteCount++;
}
}
else
{
if( (*(pucBuf - 1) & 0x80) == 0)
{
*(pucBuf - 1) |= 0x80;
}
else
{
*pucBuf++ = 0x80;
uiByteCount++;
}
}
}
else
{
FLMBYTE * pucStart = pucBuf++;
if( ui32High)
{
if( ui32High & 0xFF000000)
{
*pucBuf++ = (FLMBYTE)(ui32High >> 24);
*pucBuf++ = (FLMBYTE)(ui32High >> 16);
*pucBuf++ = (FLMBYTE)(ui32High >> 8);
*pucBuf++ = (FLMBYTE)ui32High;
uiByteCount += 4;
}
else if( ui32High & 0x00FF0000)
{
*pucBuf++ = (FLMBYTE)(ui32High >> 16);
*pucBuf++ = (FLMBYTE)(ui32High >> 8);
*pucBuf++ = (FLMBYTE)ui32High;
uiByteCount += 3;
}
else if( ui32High & 0x0000FF00)
{
*pucBuf++ = (FLMBYTE)(ui32High >> 8);
*pucBuf++ = (FLMBYTE)ui32High;
uiByteCount += 2;
}
else if( ui32High)
{
*pucBuf++ = (FLMBYTE)ui32High;
uiByteCount++;
}
}
if( ui32Low)
{
if( ui32Low & 0xFF000000)
{
*pucBuf++ = (FLMBYTE)(ui32Low >> 24);
*pucBuf++ = (FLMBYTE)(ui32Low >> 16);
*pucBuf++ = (FLMBYTE)(ui32Low >> 8);
*pucBuf++ = (FLMBYTE)ui32Low;
uiByteCount += 4;
}
else if( ui32Low & 0x00FF0000)
{
*pucBuf++ = (FLMBYTE)(ui32Low >> 16);
*pucBuf++ = (FLMBYTE)(ui32Low >> 8);
*pucBuf++ = (FLMBYTE)ui32Low;
uiByteCount += 3;
}
else if( ui32Low & 0x0000FF00)
{
*pucBuf++ = (FLMBYTE)(ui32Low >> 8);
*pucBuf++ = (FLMBYTE)ui32Low;
uiByteCount += 2;
}
else if( ui32Low)
{
*pucBuf++ = (FLMBYTE)ui32Low;
uiByteCount++;
}
}
else if( !ui32High)
{
*pucBuf++ = 0;
uiByteCount++;
}
if( !bNegative)
{
// Positive numbers must collate after negative numbers,
// so all positive numbers will start with a byte
// in the range of 0xC8 - 0xCF.
*pucStart = (FLMBYTE)(0xC8 + (uiByteCount - 1));
uiByteCount++;
}
else
{
FLMBYTE * pucTmp = pucStart + 1;
while( pucTmp < pucBuf)
{
*pucTmp = ~(*pucTmp);
pucTmp++;
}
// Negative numbers must collate before positive numbers,
// so all negative numbers will start with a byte
// in the range of 0xC0 - 0xC7.
*pucStart = (FLMBYTE)(0xC8 - uiByteCount);
uiByteCount++;
}
}
// Set the number of bytes in the buffer before returning.
*puiBufLen = uiByteCount;
Exit:
return( rc);
}
/****************************************************************************
Desc: Converts a storage value back into a number
Notes: Changes to this code must also be made to flmStorage2Number64
*****************************************************************************/
RCODE flmStorage2Number(
eDataType eDataTyp,
FLMUINT uiBufLen,
const FLMBYTE * pucBuf,
FLMUINT * puiNum,
FLMINT * piNum)
{
RCODE rc = NE_SFLM_OK;
FLMUINT uiLoop;
FLMUINT uiNum = 0;
FLMBOOL bNeg = FALSE;
if( !uiBufLen)
{
if( puiNum)
{
*puiNum = 0;
}
else
{
*piNum = 0;
}
goto Exit;
}
if( !pucBuf)
{
rc = RC_SET( NE_SFLM_CONV_NULL_SRC);
goto Exit;
}
switch( eDataTyp)
{
case SFLM_NUMBER_TYPE :
{
// Make sure the number buffer does not exceed the
// max length. If there is an extra byte for the
// sign (byte 9) make sure it has a value of either
// 0x80 or 0 (by masking of the high bit).
if( uiBufLen > FLM_MAX_NUM_BUF_SIZE ||
(uiBufLen == FLM_MAX_NUM_BUF_SIZE &&
(pucBuf[ uiBufLen - 1] & 0x7F) != 0))
{
rc = RC_SET( NE_SFLM_CONV_NUM_OVERFLOW);
goto Exit;
}
// Look at the high bit of the most-significant byte
// to determine if the number is signed
if( pucBuf[ uiBufLen - 1] & 0x80)
{
if( puiNum)
{
rc = RC_SET( NE_SFLM_CONV_NUM_UNDERFLOW);
goto Exit;
}
bNeg = TRUE;
}
uiNum = pucBuf[ uiBufLen - 1] & 0x7F;
uiBufLen--;
for( uiLoop = 1; uiLoop <= uiBufLen; uiLoop++)
{
if( gv_b32BitPlatform && (uiNum & 0xFF000000))
{
rc = RC_SET( NE_SFLM_CONV_NUM_OVERFLOW);
goto Exit;
}
uiNum = (uiNum << 8) + pucBuf[ uiBufLen - uiLoop];
}
break;
}
case SFLM_STRING_TYPE:
{
FLMBYTE ucNumBuf[ 64];
FLMUINT uiNumBufLen = sizeof( ucNumBuf);
FLMBYTE * pucTmp;
if( RC_BAD( rc = flmStorage2UTF8( SFLM_STRING_TYPE, uiBufLen, pucBuf,
&uiNumBufLen, ucNumBuf)))
{
goto Exit;
}
pucTmp = &ucNumBuf[ 0];
if( *pucTmp == ASCII_DASH)
{
if( puiNum)
{
rc = RC_SET( NE_SFLM_CONV_NUM_UNDERFLOW);
goto Exit;
}
bNeg = TRUE;
pucTmp++;
}
while( *pucTmp)
{
if( *pucTmp < ASCII_ZERO || *pucTmp > ASCII_NINE)
{
break;
}
if( uiNum > (~(FLMUINT)0) / 10)
{
rc = RC_SET( NE_SFLM_CONV_NUM_OVERFLOW);
goto Exit;
}
uiNum *= (FLMUINT)10;
if( uiNum > (~(FLMUINT)0) - (FLMUINT)(*pucTmp - ASCII_ZERO))
{
rc = RC_SET( NE_SFLM_CONV_NUM_OVERFLOW);
goto Exit;
}
uiNum += (FLMUINT)(*pucTmp - ASCII_ZERO);
pucTmp++;
}
break;
}
default :
{
rc = RC_SET_AND_ASSERT( NE_SFLM_CONV_ILLEGAL);
goto Exit;
}
}
if( puiNum)
{
if( bNeg)
{
rc = RC_SET( NE_SFLM_CONV_NUM_UNDERFLOW);
goto Exit;
}
*puiNum = uiNum;
}
else
{
flmAssert( piNum);
if( bNeg)
{
if( uiNum > gv_uiMaxSignedIntVal + 1)
{
rc = RC_SET( NE_SFLM_CONV_NUM_UNDERFLOW);
goto Exit;
}
*piNum = -(FLMINT)uiNum;
}
else
{
if( uiNum > gv_uiMaxSignedIntVal)
{
rc = RC_SET( NE_SFLM_CONV_NUM_OVERFLOW);
goto Exit;
}
*piNum = (FLMINT)uiNum;
}
}
Exit:
return( rc);
}
/****************************************************************************
Desc: Converts a storage value back into a number
Notes: Changes to this code must also be made to flmStorage2Number
*****************************************************************************/
RCODE flmStorage2Number64(
FLMUINT eDataTyp,
FLMUINT uiBufLen,
const FLMBYTE * pucBuf,
FLMUINT64 * pui64Num,
FLMINT64 * pi64Num)
{
RCODE rc = NE_SFLM_OK;
FLMUINT uiLoop;
FLMUINT64 ui64Num = 0;
FLMBOOL bNeg = FALSE;
if( !uiBufLen)
{
if( pui64Num)
{
*pui64Num = 0;
}
else
{
*pi64Num = 0;
}
goto Exit;
}
if( !pucBuf)
{
rc = RC_SET( NE_SFLM_CONV_NULL_SRC);
goto Exit;
}
switch( eDataTyp)
{
case SFLM_NUMBER_TYPE :
{
// Make sure the number buffer does not exceed the
// max length. If there is an extra byte for the
// sign (byte 9) make sure it has a value of either
// 0x80 or 0 (by masking of the high bit).
if( uiBufLen > FLM_MAX_NUM_BUF_SIZE ||
(uiBufLen == FLM_MAX_NUM_BUF_SIZE &&
(pucBuf[ uiBufLen - 1] & 0x7F) != 0))
{
rc = RC_SET( NE_SFLM_CONV_NUM_OVERFLOW);
goto Exit;
}
// Look at the high bit of the most-significant byte
// to determine if the number is signed
if( pucBuf[ uiBufLen - 1] & 0x80)
{
if( pui64Num)
{
rc = RC_SET( NE_SFLM_CONV_NUM_UNDERFLOW);
goto Exit;
}
bNeg = TRUE;
}
ui64Num = pucBuf[ uiBufLen - 1] & 0x7F;
uiBufLen--;
for( uiLoop = 1; uiLoop <= uiBufLen; uiLoop++)
{
ui64Num = (ui64Num << 8) + pucBuf[ uiBufLen - uiLoop];
}
break;
}
case SFLM_STRING_TYPE :
{
FLMBYTE ucNumBuf[ 64];
FLMUINT uiNumBufLen = sizeof( ucNumBuf);
FLMBYTE * pucTmp;
if( RC_BAD( rc = flmStorage2UTF8( SFLM_NUMBER_TYPE, uiBufLen, pucBuf,
&uiNumBufLen, ucNumBuf)))
{
goto Exit;
}
pucTmp = &ucNumBuf[ 0];
if( *pucTmp == ASCII_DASH)
{
if( pui64Num)
{
rc = RC_SET( NE_SFLM_CONV_NUM_UNDERFLOW);
goto Exit;
}
bNeg = TRUE;
pucTmp++;
}
while( *pucTmp)
{
if( *pucTmp < ASCII_ZERO || *pucTmp > ASCII_NINE)
{
break;
}
if( ui64Num > (~(FLMUINT64)0) / 10)
{
rc = RC_SET( NE_SFLM_CONV_NUM_OVERFLOW);
goto Exit;
}
ui64Num *= (FLMUINT64)10;
if( ui64Num > (~(FLMUINT64)0) - (FLMUINT64)(*pucTmp - ASCII_ZERO))
{
rc = RC_SET( NE_SFLM_CONV_NUM_OVERFLOW);
goto Exit;
}
ui64Num += (FLMUINT64)(*pucTmp - ASCII_ZERO);
pucTmp++;
}
break;
}
default :
{
rc = RC_SET_AND_ASSERT( NE_SFLM_CONV_ILLEGAL);
goto Exit;
}
}
if( pui64Num)
{
*pui64Num = ui64Num;
}
else
{
flmAssert( pi64Num);
if( bNeg)
{
if( ui64Num > gv_ui64MaxSignedIntVal + 1)
{
rc = RC_SET( NE_SFLM_CONV_NUM_UNDERFLOW);
goto Exit;
}
*pi64Num = -(FLMINT64)ui64Num;
}
else
{
if( ui64Num > gv_ui64MaxSignedIntVal)
{
rc = RC_SET( NE_SFLM_CONV_NUM_OVERFLOW);
goto Exit;
}
*pi64Num = (FLMINT64)ui64Num;
}
}
Exit:
return( rc);
}
/****************************************************************************
Desc: Converts a numeric storage value into a collation value
*****************************************************************************/
RCODE flmStorageNum2CollationNum(
const FLMBYTE * pucStorageBuf,
FLMUINT uiStorageLen,
FLMBYTE * pucCollBuf,
FLMUINT * puiCollLen)
{
FLMUINT uiLoop;
FLMUINT uiOffset;
FLMUINT uiMaxLen = *puiCollLen;
FLMBYTE ucVal;
FLMBOOL bNegative = FALSE;
RCODE rc = NE_SFLM_OK;
if( !pucStorageBuf || !uiStorageLen)
{
rc = RC_SET_AND_ASSERT( NE_SFLM_INVALID_PARM);
goto Exit;
}
// Look at the high bit of the most-significant byte
// to determine if the number is signed
if( pucStorageBuf[ uiStorageLen - 1] & 0x80)
{
bNegative = TRUE;
}
uiOffset = 1;
if( (ucVal = pucStorageBuf[ uiStorageLen - 1] & 0x7F) != 0 ||
uiStorageLen == 1) // Handle the special case of zero
{
if( bNegative)
{
ucVal = ~ucVal;
}
if( uiOffset >= uiMaxLen)
{
rc = RC_SET( NE_SFLM_CONV_DEST_OVERFLOW);
goto Exit;
}
pucCollBuf[ uiOffset++] = ucVal;
}
uiStorageLen--;
// Check for overflow
if( uiOffset + uiStorageLen >= uiMaxLen)
{
rc = RC_SET( NE_SFLM_CONV_DEST_OVERFLOW);
goto Exit;
}
// Map the little-endian storage format to the big-endian
// collation format
if( !bNegative)
{
for( uiLoop = 1; uiLoop <= uiStorageLen; uiLoop++)
{
pucCollBuf[ uiOffset++] = pucStorageBuf[ uiStorageLen - uiLoop];
}
}
else
{
for( uiLoop = 1; uiLoop <= uiStorageLen; uiLoop++)
{
pucCollBuf[ uiOffset++] = ~pucStorageBuf[ uiStorageLen - uiLoop];
}
}
flmAssert( uiOffset >= 2);
// Store the numeric collation marker and byte count
if( !bNegative)
{
// Positive numbers must collate after negative numbers,
// so all positive numbers will start with a byte
// in the range of 0xC8 - 0xCF.
pucCollBuf[ 0] = (FLMBYTE)(0xC8 + (uiOffset - 2));
}
else
{
// Negative numbers must collate before positive numbers,
// so all negative numbers will start with a byte
// in the range of 0xC0 - 0xC7.
pucCollBuf[ 0] = (FLMBYTE)(0xC8 - (uiOffset - 1));
}
// Set the key length
*puiCollLen = uiOffset;
Exit:
return( rc);
}
/****************************************************************************
Desc: Converts a numeric collation value into a storage value
*****************************************************************************/
RCODE flmCollationNum2StorageNum(
const FLMBYTE * pucCollBuf,
FLMUINT uiCollLen,
FLMBYTE * pucStorageBuf,
FLMUINT * puiStorageLen)
{
FLMUINT uiLoop;
FLMUINT uiOffset;
FLMUINT uiMaxOffset = *puiStorageLen;
FLMUINT uiNumKeyBytes;
FLMBOOL bNegative = FALSE;
RCODE rc = NE_SFLM_OK;
if( !pucCollBuf || !uiCollLen)
{
rc = RC_SET_AND_ASSERT( NE_SFLM_INVALID_PARM);
goto Exit;
}
// Make sure this looks like a valid numeric key piece
if( (pucCollBuf[ 0] & 0xC0) != 0xC0)
{
rc = RC_SET( NE_SFLM_DATA_ERROR);
goto Exit;
}
// Get the byte count
if( (uiNumKeyBytes = (FLMUINT)(pucCollBuf[ 0] & 0x0F)) >= 8)
{
uiNumKeyBytes -= 7;
}
else
{
uiNumKeyBytes = 8 - uiNumKeyBytes;
bNegative = TRUE;
}
pucCollBuf++;
uiCollLen--;
// Make sure the buffer has at least the number of bytes
// we need
if( uiCollLen != uiNumKeyBytes)
{
rc = RC_SET_AND_ASSERT( NE_SFLM_DATA_ERROR);
goto Exit;
}
if( uiNumKeyBytes >= uiMaxOffset)
{
rc = RC_SET( NE_SFLM_CONV_DEST_OVERFLOW);
goto Exit;
}
// Translate the collation value into a numeric value
if( !bNegative)
{
for( uiLoop = 0; uiLoop < uiNumKeyBytes; uiLoop++)
{
pucStorageBuf[ uiNumKeyBytes - uiLoop - 1] = pucCollBuf[ uiLoop];
}
}
else
{
for( uiLoop = 0; uiLoop < uiNumKeyBytes; uiLoop++)
{
pucStorageBuf[ uiNumKeyBytes - uiLoop - 1] = ~pucCollBuf[ uiLoop];
}
}
uiOffset = uiNumKeyBytes;
// If a number is negative, the high bit of the right-most
// byte needs to be set. If the value of the number is such
// that its positive representation already has the high-bit
// set, we need to store an additional sign byte.
if( !bNegative)
{
if( pucStorageBuf[ uiOffset - 1] & 0x80)
{
if( uiOffset >= uiMaxOffset)
{
rc = RC_SET( NE_SFLM_CONV_DEST_OVERFLOW);
goto Exit;
}
pucStorageBuf[ uiOffset++] = 0;
}
}
else
{
if( (pucStorageBuf[ uiOffset - 1] & 0x80) == 0)
{
pucStorageBuf[ uiOffset - 1] |= 0x80;
}
else
{
if( uiOffset >= uiMaxOffset)
{
rc = RC_SET( NE_SFLM_CONV_DEST_OVERFLOW);
goto Exit;
}
pucStorageBuf[ uiOffset++] = 0x80;
}
}
// Set the storage length
*puiStorageLen = uiOffset;
Exit:
return( rc);
}
/****************************************************************************
Desc: Converts a collation value (numeric only) to a number
*****************************************************************************/
RCODE flmCollation2Number(
FLMUINT uiBufLen,
const FLMBYTE * pucBuf,
FLMUINT64 * pui64Num,
FLMBOOL * pbNeg,
FLMUINT * puiBytesProcessed)
{
RCODE rc = NE_SFLM_OK;
FLMUINT uiLoop;
FLMUINT uiNumBytes;
FLMUINT64 ui64Num;
FLMBOOL bNeg = FALSE;
*pui64Num = 0;
if( !uiBufLen)
{
goto Exit;
}
if( !pucBuf)
{
rc = RC_SET( NE_SFLM_CONV_NULL_SRC);
goto Exit;
}
// Make sure this looks like a valid numeric key piece
if( (pucBuf[ 0] & 0xC0) != 0xC0)
{
rc = RC_SET( NE_SFLM_DATA_ERROR);
goto Exit;
}
// Get the byte count
if( (uiNumBytes = (FLMUINT)(pucBuf[ 0] & 0x0F)) >= 8)
{
uiNumBytes -= 7;
}
else
{
uiNumBytes = 8 - uiNumBytes;
bNeg = TRUE;
}
pucBuf++;
uiBufLen--;
// Make sure the buffer has at least the number of bytes
// we need
if( uiBufLen < uiNumBytes)
{
rc = RC_SET_AND_ASSERT( NE_SFLM_DATA_ERROR);
goto Exit;
}
// Reconstruct the number
ui64Num = 0;
if( !bNeg)
{
for( uiLoop = 0; uiLoop < uiNumBytes; uiLoop++)
{
ui64Num += (((FLMUINT64)pucBuf[ uiLoop]) <<
(8 * ((uiNumBytes - uiLoop) - 1)));
}
}
else
{
for( uiLoop = 0; uiLoop < uiNumBytes; uiLoop++)
{
ui64Num += (((FLMUINT64)((FLMBYTE)~pucBuf[ uiLoop])) <<
(8 * ((uiNumBytes - uiLoop) - 1)));
}
}
*pui64Num = ui64Num;
if( puiBytesProcessed)
{
*puiBytesProcessed = uiNumBytes + 1;
}
if( pbNeg)
{
*pbNeg = bNeg;
}
Exit:
return( rc);
}
/*****************************************************************************
Desc:
******************************************************************************/
RCODE flmStorageNumberToNumber(
const FLMBYTE * pucNumBuf,
FLMUINT uiNumBufLen,
FLMUINT64 * pui64Number,
FLMBOOL * pbNeg)
{
RCODE rc = NE_SFLM_OK;
FLMUINT uiLoop;
FLMUINT64 ui64Num = 0;
FLMBOOL bNeg = FALSE;
if( !uiNumBufLen)
{
goto Exit;
}
// Make sure the number buffer does not exceed the
// max length. If there is an extra byte for the
// sign (byte 9) make sure it has a value of either
// 0x80 or 0 (by masking of the high bit).
if( uiNumBufLen > FLM_MAX_NUM_BUF_SIZE ||
(uiNumBufLen == FLM_MAX_NUM_BUF_SIZE &&
(pucNumBuf[ uiNumBufLen - 1] & 0x7F) != 0))
{
rc = RC_SET_AND_ASSERT( NE_SFLM_CONV_NUM_OVERFLOW);
goto Exit;
}
// Look at the high bit of the most-significant byte
// to determine if the number is signed
if( pucNumBuf[ uiNumBufLen - 1] & 0x80)
{
bNeg = TRUE;
}
ui64Num = pucNumBuf[ uiNumBufLen - 1] & 0x7F;
uiNumBufLen--;
for( uiLoop = 1; uiLoop <= uiNumBufLen; uiLoop++)
{
ui64Num = (ui64Num << 8) + pucNumBuf[ uiNumBufLen - uiLoop];
}
Exit:
*pui64Number = ui64Num;
*pbNeg = bNeg;
return( rc);
}