832 lines
23 KiB
C++
Executable File
832 lines
23 KiB
C++
Executable File
/*===========================================================================
|
|
FILE:
|
|
DataPacker.cpp
|
|
|
|
DESCRIPTION:
|
|
Implementation of sUnpackedField and cDataPacker
|
|
|
|
PUBLIC CLASSES AND METHODS:
|
|
sUnpackedField
|
|
Structure to represent a single unpacked (input) field - i.e. the
|
|
field value as a string and an optional field name (either fully
|
|
qualified) or partial
|
|
|
|
cDataPacker
|
|
Class to pack bit/byte specified fields into a buffer accordinging
|
|
to a database description, uses cProtocolEntityNav to navigate the DB
|
|
definition
|
|
|
|
Copyright (c) 2011, Code Aurora Forum. All rights reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions are met:
|
|
* Redistributions of source code must retain the above copyright
|
|
notice, this list of conditions and the following disclaimer.
|
|
* Redistributions in binary form must reproduce the above copyright
|
|
notice, this list of conditions and the following disclaimer in the
|
|
documentation and/or other materials provided with the distribution.
|
|
* Neither the name of Code Aurora Forum nor
|
|
the names of its contributors may be used to endorse or promote
|
|
products derived from this software without specific prior written
|
|
permission.
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
POSSIBILITY OF SUCH DAMAGE.
|
|
===========================================================================*/
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Include Files
|
|
//---------------------------------------------------------------------------
|
|
#include "StdAfx.h"
|
|
#include "DataPacker.h"
|
|
|
|
#include "CoreDatabase.h"
|
|
#include "DB2Utilities.h"
|
|
|
|
#include <climits>
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Definitions
|
|
//---------------------------------------------------------------------------
|
|
|
|
/*=========================================================================*/
|
|
// cDataPacker Methods
|
|
/*=========================================================================*/
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
cDataPacker (Public Method)
|
|
|
|
DESCRIPTION:
|
|
Constructor
|
|
|
|
PARAMETERS:
|
|
db [ I ] - Database to use
|
|
key [ I ] - Key into protocol entity table
|
|
fields [ I ] - Fields to pack into buffer
|
|
|
|
RETURN VALUE:
|
|
None
|
|
===========================================================================*/
|
|
cDataPacker::cDataPacker(
|
|
const cCoreDatabase & db,
|
|
const std::vector <ULONG> & key,
|
|
const std::list <sUnpackedField> & fields )
|
|
: cProtocolEntityNav( db ),
|
|
mKey( key ),
|
|
mbValuesOnly( true ),
|
|
mProcessedFields( 0 ),
|
|
mbPacked( false )
|
|
{
|
|
// Initialize internal buffer
|
|
memset( &mBuffer[0], 0, (SIZE_T)MAX_SHARED_BUFFER_SIZE );
|
|
|
|
// Compute bits left in buffer
|
|
ULONG bits = MAX_SHARED_BUFFER_SIZE * BITS_PER_BYTE;
|
|
if (mKey.size() > 0)
|
|
{
|
|
eDB2EntityType et = (eDB2EntityType)mKey[0];
|
|
bits = DB2GetMaxBufferSize( et ) * BITS_PER_BYTE;
|
|
}
|
|
|
|
// Setup the bit packer
|
|
mBitsy.SetData( mBuffer, bits );
|
|
|
|
// Copy fields/set value only flag
|
|
std::list <sUnpackedField>::const_iterator pIter = fields.begin();
|
|
while (pIter != fields.end())
|
|
{
|
|
if (pIter->mName.size() > 0)
|
|
{
|
|
mbValuesOnly = false;
|
|
}
|
|
|
|
mFields.push_back( *pIter );
|
|
pIter++;
|
|
}
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
~cDataPacker (Public Method)
|
|
|
|
DESCRIPTION:
|
|
Destructor
|
|
|
|
RETURN VALUE:
|
|
None
|
|
===========================================================================*/
|
|
cDataPacker::~cDataPacker()
|
|
{
|
|
// Ask bit packer to release data
|
|
mBitsy.ReleaseData();
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
Pack (Public Method)
|
|
|
|
DESCRIPTION:
|
|
Pack the buffer
|
|
|
|
RETURN VALUE:
|
|
bool
|
|
===========================================================================*/
|
|
bool cDataPacker::Pack()
|
|
{
|
|
// Process (pack) the protocol entity
|
|
if (mbPacked == false)
|
|
{
|
|
mbPacked = ProcessEntity( mKey );
|
|
if (mbPacked == false)
|
|
{
|
|
// Failed due to no structure ID?
|
|
if (mEntity.IsValid() == true && mEntity.mStructID == -1)
|
|
{
|
|
// Yes, for us that means instant success (no payload to pack)
|
|
mbPacked = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return mbPacked;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
GetBuffer (Public Method)
|
|
|
|
DESCRIPTION:
|
|
Get packed buffer contents
|
|
|
|
PARAMETERS:
|
|
bufferLen [ O ] - Length of packed buffer (in bytes)
|
|
|
|
RETURN VALUE:
|
|
const BYTE * - Packed buffer (0 upon error)
|
|
===========================================================================*/
|
|
const BYTE * cDataPacker::GetBuffer( ULONG & bufferLen )
|
|
{
|
|
if (mbPacked == false)
|
|
{
|
|
bufferLen = 0;
|
|
return 0;
|
|
}
|
|
|
|
// Payload size in bytes
|
|
bufferLen = mBitsy.GetTotalBitsWritten() + BITS_PER_BYTE - 1;
|
|
bufferLen /= BITS_PER_BYTE;
|
|
|
|
// Payload is our buffer
|
|
const BYTE * pBuffer = 0;
|
|
if (bufferLen > 0)
|
|
{
|
|
pBuffer = (const BYTE *)&mBuffer[0];
|
|
}
|
|
|
|
return pBuffer;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
LoadValues (Static Public Method)
|
|
|
|
DESCRIPTION:
|
|
Load values by parsing a 'summary' string of values, an example of
|
|
which would be:
|
|
|
|
0 1 100 "Foo Foo Foo" 15 -1
|
|
|
|
PARAMETERS:
|
|
vals [ I ] - Value string
|
|
|
|
RETURN VALUE:
|
|
std::list <sUnpackedField>
|
|
===========================================================================*/
|
|
std::list <sUnpackedField> cDataPacker::LoadValues( const std::string & vals )
|
|
{
|
|
std::list <sUnpackedField> retList;
|
|
if (vals.size() <= 0)
|
|
{
|
|
return retList;
|
|
}
|
|
|
|
std::vector <std::string> tokens;
|
|
ParseCommandLine( vals, tokens );
|
|
|
|
std::string name = "";
|
|
std::string val = "";
|
|
|
|
std::vector <std::string>::const_iterator pIter = tokens.begin();
|
|
while (pIter != tokens.end())
|
|
{
|
|
val = *pIter++;
|
|
|
|
sUnpackedField entry( name, val );
|
|
retList.push_back( entry );
|
|
}
|
|
|
|
return retList;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
LoadValues (Static Public Method)
|
|
|
|
DESCRIPTION:
|
|
Load values by parsing a vector of string values, an example of
|
|
which would be:
|
|
|
|
[0] 0
|
|
[1] 1
|
|
[2] 100
|
|
[3] "Foo Foo Foo"
|
|
[4] 15
|
|
[5] -1
|
|
|
|
PARAMETERS:
|
|
vals [ I ] - Vector of values
|
|
startIndex [ I ] - Where in above vector values start
|
|
|
|
RETURN VALUE:
|
|
std::list <sUnpackedField>
|
|
===========================================================================*/
|
|
std::list <sUnpackedField> cDataPacker::LoadValues(
|
|
std::vector <std::string> & vals,
|
|
ULONG startIndex )
|
|
{
|
|
std::list <sUnpackedField> retList;
|
|
|
|
ULONG sz = (ULONG)vals.size();
|
|
if (startIndex >= sz)
|
|
{
|
|
return retList;
|
|
}
|
|
|
|
std::string name = "";
|
|
std::string val = "";
|
|
|
|
for (ULONG v = startIndex; v < sz; v++)
|
|
{
|
|
val = vals[v];
|
|
|
|
sUnpackedField entry( name, val );
|
|
retList.push_back( entry );
|
|
}
|
|
|
|
return retList;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
GetLastValue (Internal Method)
|
|
|
|
DESCRIPTION:
|
|
Working from the back of the current value list find and return the
|
|
value for the specified field ID as a LONGLONG (field type must have
|
|
been able to fit in a LONGLONG for a value to be stored in value list
|
|
and thus returned)
|
|
|
|
PARAMETERS:
|
|
fieldID [ I ] - Field ID we are looking for
|
|
val [ O ] - The value
|
|
|
|
RETURN VALUE:
|
|
bool
|
|
===========================================================================*/
|
|
bool cDataPacker::GetLastValue(
|
|
ULONG fieldID,
|
|
LONGLONG & val )
|
|
{
|
|
// Assume failure
|
|
bool bRC = false;
|
|
|
|
std::list < std::pair <ULONG, LONGLONG> >::reverse_iterator pValues;
|
|
pValues = mValues.rbegin();
|
|
while (pValues != mValues.rend())
|
|
{
|
|
std::pair <ULONG, LONGLONG> & entry = *pValues;
|
|
if (entry.first == fieldID)
|
|
{
|
|
val = entry.second;
|
|
|
|
// Success!
|
|
bRC = true;
|
|
break;
|
|
}
|
|
|
|
pValues++;
|
|
}
|
|
|
|
return bRC;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
GetValueString (Internal Method)
|
|
|
|
DESCRIPTION:
|
|
For the given field return the (input) value string
|
|
|
|
PARAMETERS:
|
|
field [ I ] - The field being processed
|
|
fieldName [ I ] - Partial (or fully qualified) field name
|
|
pValueString [ O ] - Value string
|
|
|
|
RETURN VALUE:
|
|
bool
|
|
===========================================================================*/
|
|
bool cDataPacker::GetValueString(
|
|
const sDB2Field & field,
|
|
const std::string & fieldName,
|
|
LPCSTR & pValueString )
|
|
{
|
|
// Assume failure
|
|
pValueString = 0;
|
|
|
|
// Create fully qualified field name
|
|
std::string fullName = GetFullFieldName( fieldName );
|
|
|
|
std::vector <sUnpackedField>::const_iterator pVals = mFields.begin();
|
|
while (pVals != mFields.end())
|
|
{
|
|
const std::string & inName = pVals->mName;
|
|
if (fieldName == inName || fullName == inName)
|
|
{
|
|
pValueString = (LPCSTR)pVals->mValueString.c_str();
|
|
break;
|
|
}
|
|
|
|
pVals++;
|
|
}
|
|
|
|
// Value provided?
|
|
if (pValueString == 0)
|
|
{
|
|
// No, are we in value only mode?
|
|
if (mbValuesOnly == true)
|
|
{
|
|
if (mProcessedFields < (ULONG)mFields.size())
|
|
{
|
|
sUnpackedField & upf = mFields[mProcessedFields++];
|
|
|
|
// Set field name (partial)
|
|
upf.mName = fieldName;
|
|
|
|
// Grab field value
|
|
pValueString = (LPCSTR)upf.mValueString.c_str();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Value provided?
|
|
if (pValueString == 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Meaningful value provided?
|
|
if (pValueString[0] == 0)
|
|
{
|
|
// No value provided for field? Is it a string?
|
|
if (field.mType == eDB2_FIELD_STD)
|
|
{
|
|
if ( (field.mTypeVal != eDB2_FIELD_STDTYPE_STRING_A)
|
|
&& (field.mTypeVal != eDB2_FIELD_STDTYPE_STRING_U)
|
|
&& (field.mTypeVal != eDB2_FIELD_STDTYPE_STRING_U8)
|
|
&& (field.mTypeVal != eDB2_FIELD_STDTYPE_STRING_ANT)
|
|
&& (field.mTypeVal != eDB2_FIELD_STDTYPE_STRING_UNT)
|
|
&& (field.mTypeVal != eDB2_FIELD_STDTYPE_STRING_U8NT) )
|
|
{
|
|
// No, unable to proceed
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
PackString (Internal Method)
|
|
|
|
DESCRIPTION:
|
|
Pack the string (described by the given arguments) into the buffer
|
|
|
|
PARAMETERS:
|
|
numChars [ I ] - Number of characters to pack (0 = NULL terminated)
|
|
pStr [ I ] - String to pack
|
|
|
|
RETURN VALUE:
|
|
bool
|
|
===========================================================================*/
|
|
bool cDataPacker::PackString(
|
|
ULONG numChars,
|
|
LPCSTR pStr )
|
|
{
|
|
// Sanity check string pointer
|
|
if (pStr == 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Assume success
|
|
bool bOK = true;
|
|
|
|
// Convert native string type to desired output type
|
|
const BYTE * pTmp = (const BYTE *)pStr;
|
|
|
|
// Have we reached the practical end of a fixed length string?
|
|
ULONG numBytes = 0;
|
|
|
|
numBytes = (ULONG)strlen( (LPCSTR)pTmp );
|
|
if (numChars == 0)
|
|
{
|
|
// We pack the string plus the NULL character
|
|
numChars = (ULONG)strlen( (LPCSTR)pTmp ) + 1;
|
|
}
|
|
|
|
// String size too long?
|
|
if (numBytes > numChars)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Pack the string one byte at a time
|
|
for (ULONG c = 0; c < numChars; c++)
|
|
{
|
|
BYTE val = 0;
|
|
if (c < numBytes)
|
|
{
|
|
val = pTmp[c];
|
|
}
|
|
|
|
DWORD rc = mBitsy.Set( BITS_PER_BYTE, val );
|
|
if (rc != NO_ERROR)
|
|
{
|
|
bOK = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return bOK;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
ProcessField (Internal Method)
|
|
|
|
DESCRIPTION:
|
|
Process the given field (described by the given arguments) by packing
|
|
the value into the buffer
|
|
|
|
PARAMETERS:
|
|
pField [ I ] - The field being processed
|
|
fieldName [ I ] - Field name (partial)
|
|
arrayIndex [ I ] - Not used
|
|
|
|
RETURN VALUE:
|
|
bool
|
|
===========================================================================*/
|
|
bool cDataPacker::ProcessField(
|
|
const sDB2Field * pField,
|
|
const std::string & fieldName,
|
|
LONGLONG /* arrayIndex */ )
|
|
{
|
|
// Assume failure
|
|
bool bOK = false;
|
|
if (pField == 0)
|
|
{
|
|
return bOK;
|
|
}
|
|
|
|
// Find given value for field
|
|
LPCSTR pVal = 0;
|
|
bool bVal = GetValueString( *pField, fieldName, pVal );
|
|
if (bVal == false)
|
|
{
|
|
return bOK;
|
|
}
|
|
|
|
// Grab field ID
|
|
ULONG id = pField->mID;
|
|
|
|
// What type is this field?
|
|
switch (pField->mType)
|
|
{
|
|
case eDB2_FIELD_STD:
|
|
{
|
|
// Standard field, what kind?
|
|
eDB2StdFieldType ft = (eDB2StdFieldType)pField->mTypeVal;
|
|
switch (ft)
|
|
{
|
|
// Field is a boolean (0/1, false/true)/8-bit unsigned integer
|
|
case eDB2_FIELD_STDTYPE_BOOL:
|
|
case eDB2_FIELD_STDTYPE_UINT8:
|
|
{
|
|
// We pack as a UCHAR
|
|
UCHAR val = 0;
|
|
bool bVal = ::FromString( pVal, val );
|
|
if (bVal == true)
|
|
{
|
|
if (ft == eDB2_FIELD_STDTYPE_BOOL && val > 1)
|
|
{
|
|
val = 1;
|
|
}
|
|
|
|
DWORD rc = mBitsy.Set( pField->mSize, val );
|
|
if (rc == NO_ERROR)
|
|
{
|
|
// Success!
|
|
std::pair <ULONG, LONGLONG> entry( id, (LONGLONG)val );
|
|
mValues.push_back( entry );
|
|
bOK = true;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
// Field is 8-bit signed integer
|
|
case eDB2_FIELD_STDTYPE_INT8:
|
|
{
|
|
// We pack as a CHAR
|
|
CHAR val = 0;
|
|
bool bVal = ::FromString( pVal, val );
|
|
if (bVal == true)
|
|
{
|
|
DWORD rc = mBitsy.Set( pField->mSize, val );
|
|
if (rc == NO_ERROR)
|
|
{
|
|
// Success!
|
|
std::pair <ULONG, LONGLONG> entry( id, (LONGLONG)val );
|
|
mValues.push_back( entry );
|
|
bOK = true;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
// Field is 16-bit signed integer
|
|
case eDB2_FIELD_STDTYPE_INT16:
|
|
{
|
|
// We pack as a SHORT
|
|
SHORT val = 0;
|
|
bool bVal = ::FromString( pVal, val );
|
|
if (bVal == true)
|
|
{
|
|
DWORD rc = mBitsy.Set( pField->mSize, val );
|
|
if (rc == NO_ERROR)
|
|
{
|
|
// Success!
|
|
std::pair <ULONG, LONGLONG> entry( id, (LONGLONG)val );
|
|
mValues.push_back( entry );
|
|
bOK = true;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
// Field is 16-bit unsigned integer
|
|
case eDB2_FIELD_STDTYPE_UINT16:
|
|
{
|
|
// We pack as a USHORT
|
|
USHORT val = 0;
|
|
bool bVal = ::FromString( pVal, val );
|
|
if (bVal == true)
|
|
{
|
|
DWORD rc = mBitsy.Set( pField->mSize, val );
|
|
if (rc == NO_ERROR)
|
|
{
|
|
// Success!
|
|
std::pair <ULONG, LONGLONG> entry( id, (LONGLONG)val );
|
|
mValues.push_back( entry );
|
|
bOK = true;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
// Field is 32-bit signed integer
|
|
case eDB2_FIELD_STDTYPE_INT32:
|
|
{
|
|
// We pack as a LONG
|
|
LONG val = 0;
|
|
bool bVal = ::FromString( pVal, val );
|
|
if (bVal == true)
|
|
{
|
|
DWORD rc = mBitsy.Set( pField->mSize, val );
|
|
if (rc == NO_ERROR)
|
|
{
|
|
// Success!
|
|
std::pair <ULONG, LONGLONG> entry( id, (LONGLONG)val );
|
|
mValues.push_back( entry );
|
|
bOK = true;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
// Field is 32-bit unsigned integer
|
|
case eDB2_FIELD_STDTYPE_UINT32:
|
|
{
|
|
// We pack as a ULONG
|
|
ULONG val = 0;
|
|
bool bVal = ::FromString( pVal, val );
|
|
if (bVal == true)
|
|
{
|
|
DWORD rc = mBitsy.Set( pField->mSize, val );
|
|
if (rc == NO_ERROR)
|
|
{
|
|
// Success!
|
|
std::pair <ULONG, LONGLONG> entry( id, (LONGLONG)val );
|
|
mValues.push_back( entry );
|
|
bOK = true;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
// Field is 64-bit signed integer
|
|
case eDB2_FIELD_STDTYPE_INT64:
|
|
{
|
|
// We pack as a LONGLONG
|
|
LONGLONG val = 0;
|
|
bool bVal = ::FromString( pVal, val );
|
|
if (bVal == true)
|
|
{
|
|
DWORD rc = mBitsy.Set( pField->mSize, val );
|
|
if (rc == NO_ERROR)
|
|
{
|
|
// Success!
|
|
std::pair <ULONG, LONGLONG> entry( id, val );
|
|
mValues.push_back( entry );
|
|
bOK = true;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
// Field is 64-bit unsigned integer
|
|
case eDB2_FIELD_STDTYPE_UINT64:
|
|
{
|
|
// We pack as a ULONGLONG
|
|
ULONGLONG val = 0;
|
|
bool bVal = ::FromString( pVal, val );
|
|
if (bVal == true)
|
|
{
|
|
DWORD rc = mBitsy.Set( pField->mSize, val );
|
|
if (rc == NO_ERROR)
|
|
{
|
|
// Success!
|
|
if (val <= LLONG_MAX)
|
|
{
|
|
std::pair <ULONG, LONGLONG> entry( id, (LONGLONG)val );
|
|
mValues.push_back( entry );
|
|
}
|
|
|
|
bOK = true;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
// ANSI/UNICODE strings
|
|
case eDB2_FIELD_STDTYPE_STRING_A:
|
|
case eDB2_FIELD_STDTYPE_STRING_U:
|
|
case eDB2_FIELD_STDTYPE_STRING_ANT:
|
|
case eDB2_FIELD_STDTYPE_STRING_UNT:
|
|
{
|
|
// Set the character size
|
|
ULONG charSz = sizeof(CHAR);
|
|
if ( (ft == eDB2_FIELD_STDTYPE_STRING_U)
|
|
|| (ft == eDB2_FIELD_STDTYPE_STRING_UNT) )
|
|
{
|
|
charSz = sizeof(USHORT);
|
|
}
|
|
|
|
// Compute the number of characters?
|
|
ULONG numChars = 0;
|
|
if ( (ft == eDB2_FIELD_STDTYPE_STRING_A)
|
|
|| (ft == eDB2_FIELD_STDTYPE_STRING_U) )
|
|
{
|
|
numChars = (pField->mSize / BITS_PER_BYTE) / charSz;
|
|
}
|
|
|
|
// Pack the string
|
|
bOK = PackString( numChars, pVal );
|
|
}
|
|
break;
|
|
|
|
// UTF-8 strings
|
|
case eDB2_FIELD_STDTYPE_STRING_U8:
|
|
case eDB2_FIELD_STDTYPE_STRING_U8NT:
|
|
{
|
|
// Unsupported in the Linux adaptation
|
|
bOK = false;
|
|
}
|
|
break;
|
|
|
|
// Field is 32-bit floating point value
|
|
case eDB2_FIELD_STDTYPE_FLOAT32:
|
|
{
|
|
// We pack as a ULONG
|
|
FLOAT val = (float)atof( (LPCSTR)pVal );
|
|
ULONG * pTmp = (ULONG *)&val;
|
|
|
|
DWORD rc = mBitsy.Set( pField->mSize, *pTmp );
|
|
if (rc == NO_ERROR)
|
|
{
|
|
// Success!
|
|
bOK = true;
|
|
}
|
|
}
|
|
break;
|
|
|
|
// Field is 64-bit floating point value
|
|
case eDB2_FIELD_STDTYPE_FLOAT64:
|
|
{
|
|
// We pack as a ULONGLONG
|
|
double val = atof( (LPCSTR)pVal );
|
|
ULONGLONG * pTmp = (ULONGLONG *)&val;
|
|
|
|
DWORD rc = mBitsy.Set( pField->mSize, *pTmp );
|
|
if (rc == NO_ERROR)
|
|
{
|
|
// Success!
|
|
bOK = true;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
{
|
|
bOK = false;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case eDB2_FIELD_ENUM_UNSIGNED:
|
|
{
|
|
// We pack as a ULONG
|
|
ULONG val = 0;
|
|
bool bVal = ::FromString( pVal, val );
|
|
if (bVal == true)
|
|
{
|
|
DWORD rc = mBitsy.Set( pField->mSize, val );
|
|
if (rc == NO_ERROR)
|
|
{
|
|
// Success!
|
|
std::pair <ULONG, LONGLONG> entry( id, (LONGLONG)val );
|
|
mValues.push_back( entry );
|
|
bOK = true;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case eDB2_FIELD_ENUM_SIGNED:
|
|
{
|
|
// We pack as a LONG
|
|
LONG val = 0;
|
|
bool bVal = ::FromString( pVal, val );
|
|
if (bVal == true)
|
|
{
|
|
DWORD rc = mBitsy.Set( pField->mSize, val );
|
|
if (rc == NO_ERROR)
|
|
{
|
|
// Success!
|
|
std::pair <ULONG, LONGLONG> entry( id, (LONGLONG)val );
|
|
mValues.push_back( entry );
|
|
bOK = true;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
{
|
|
bOK = false;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return bOK;
|
|
}
|