278 lines
7.6 KiB
C++
278 lines
7.6 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1995 - 2000.
|
|
//
|
|
// File: tbrowkey.cxx
|
|
//
|
|
// Contents:
|
|
//
|
|
// Classes:
|
|
//
|
|
// Functions:
|
|
//
|
|
// History: 2-15-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
|
#include "pch.cxx"
|
|
#pragma hdrstop
|
|
|
|
#include <objcur.hxx>
|
|
#include <tableseg.hxx>
|
|
|
|
CTableRowKey::CTableRowKey( CSortSet const & sortSet )
|
|
: _cCols(sortSet.Count()), _sortSet(sortSet),
|
|
_acbVariants( _cCols ), _apVariants( _cCols )
|
|
{
|
|
Win4Assert( sizeof(CInlineVariant) == sizeof(CTableVariant) );
|
|
|
|
for ( unsigned i = 0; i < _cCols; i++ )
|
|
{
|
|
_acbVariants[i] = 0;
|
|
_apVariants[i] = 0;
|
|
}
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Method: CTableRowKey ~dtor
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Modifies:
|
|
//
|
|
// History: 2-15-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
CTableRowKey::~CTableRowKey()
|
|
{
|
|
for ( unsigned i = 0; i < _cCols; i++ )
|
|
delete [] (BYTE *) _apVariants[i];
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Method: CTableRowKey::ReAlloc
|
|
//
|
|
// Synopsis: Reallocates memory for the indicated column. Note that
|
|
// the old contents may be tossed out.
|
|
//
|
|
// Arguments: [i] - The column for which reallocation is needed.
|
|
// [vt] - Variant type of the variant
|
|
// [cb] - Number of bytes needed for the variant.
|
|
//
|
|
// History: 2-15-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void CTableRowKey::ReAlloc( unsigned i, VARTYPE vt, unsigned cb )
|
|
{
|
|
Win4Assert( i < _cCols );
|
|
|
|
const ULONG cbHeader = sizeof(CInlineVariant);
|
|
ULONG cbTotal = cb;
|
|
Win4Assert( cbTotal >= cbHeader );
|
|
|
|
if ( _acbVariants[i] < cbTotal )
|
|
{
|
|
delete [] (BYTE *) _apVariants[i];
|
|
_apVariants[i] = 0;
|
|
_acbVariants[i] = 0;
|
|
|
|
ULONG cbToAlloc = cbTotal;
|
|
|
|
_apVariants[i] = (CInlineVariant *) new BYTE [cbToAlloc];
|
|
_acbVariants[i] = cbToAlloc;
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Method: CTableRowKey::Init
|
|
//
|
|
// Synopsis: Initialized the column "i" with the source variant.
|
|
//
|
|
// Arguments: [i] - Column to be initialized.
|
|
// [src] - Source variant
|
|
// [pbSrcBias] - Bais of the data allocation in the source
|
|
// variant.
|
|
//
|
|
// History: 2-15-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
|
void CTableRowKey::Init( unsigned i, CTableVariant & src, BYTE * pbSrcBias )
|
|
{
|
|
Win4Assert( i < _cCols );
|
|
|
|
const ULONG cbHeader = sizeof(CInlineVariant);
|
|
ULONG cbVarData = src.VarDataSize();
|
|
ULONG cbTotal = cbVarData + cbHeader;
|
|
|
|
if ( _acbVariants[i] < cbTotal )
|
|
ReAlloc( i, src.vt, cbTotal );
|
|
|
|
Win4Assert( _acbVariants[i] >= cbTotal );
|
|
Win4Assert( _acbVariants[i]-cbHeader >= cbVarData );
|
|
|
|
CVarBufferAllocator bufAlloc( _apVariants[i]->GetVarBuffer(), cbVarData );
|
|
bufAlloc.SetBase(0);
|
|
|
|
src.Copy( _apVariants[i], bufAlloc, (USHORT) cbVarData, pbSrcBias );
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: assignemnt operator
|
|
//
|
|
// Synopsis: Copies the contents of the source bucket row into this.
|
|
//
|
|
// Arguments: [src] - The source bucket row.
|
|
//
|
|
// Returns: A reference to this bucket row.
|
|
//
|
|
// History: 2-15-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
|
CTableRowKey & CTableRowKey::operator=( CTableRowKey & src )
|
|
{
|
|
Win4Assert( src._cCols == _cCols );
|
|
|
|
for ( unsigned i = 0; i < _cCols; i++ )
|
|
Init( i, *(src._apVariants[i]) );
|
|
|
|
return *this;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Method: CTableRowKey::PreSet
|
|
//
|
|
// Synopsis: Get ready for use later.
|
|
//
|
|
// Arguments: [pObj] - value retriever for the object
|
|
// [pInfoSortKey] - sort info
|
|
//
|
|
// History: 8-20-98 dlee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void CTableRowKey::PreSet(
|
|
CRetriever * pObj,
|
|
XArray<VARTYPE> * pInfoSortKey )
|
|
{
|
|
_pObj = pObj;
|
|
_pVarType = pInfoSortKey;
|
|
} //PreSet
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Method: CTableRowKey::MakeReady
|
|
//
|
|
// Synopsis: Retrieves the sort key values
|
|
//
|
|
// History: 8-20-98 dlee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void CTableRowKey::MakeReady()
|
|
{
|
|
Set( *_pObj, *_pVarType );
|
|
} //MakeReady
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Method: CTableRowKey::Set
|
|
//
|
|
// Synopsis: Given a "row" and the "obj" for a row, it
|
|
// fills the "row" with the data from the "obj". It retrieves
|
|
// only the columns in the sort key.
|
|
//
|
|
// Arguments: [row] - The row to fill
|
|
// [obj] - Retriever for the columns.
|
|
//
|
|
// History: 2-15-95 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void CTableRowKey::Set( CRetriever & obj, XArray<VARTYPE> & vtInfoSortKey )
|
|
{
|
|
Win4Assert( _sortSet.Count() == _cCols );
|
|
|
|
for ( ULONG i = 0; i < _cCols; i++ )
|
|
{
|
|
SSortKey & key = _sortSet.Get(i);
|
|
PROPID pid = key.pidColumn;
|
|
|
|
ULONG cbVarnt;
|
|
CTableVariant * pvarnt = Get(i, cbVarnt);
|
|
GetValueResult eGvr;
|
|
VARTYPE vt = vtInfoSortKey.Get()[i];
|
|
|
|
if ( 0 == pvarnt )
|
|
{
|
|
//
|
|
// This is the first time we are setting the value of this
|
|
// variant. Determine its type and allocate the optimum amount
|
|
// of memory.
|
|
//
|
|
CTableVariant varnt;
|
|
cbVarnt = sizeof(varnt);
|
|
pvarnt = &varnt;
|
|
eGvr = obj.GetPropertyValue( pid, pvarnt, &cbVarnt );
|
|
if ( GVRSuccess != eGvr &&
|
|
GVRNotEnoughSpace != eGvr &&
|
|
GVRSharingViolation != eGvr )
|
|
{
|
|
if ( eGvr == GVRNotSupported || eGvr == GVRNotAvailable )
|
|
{
|
|
THROW( CException( QUERY_E_INVALIDSORT ) );
|
|
}
|
|
else
|
|
{
|
|
THROW( CException(CRetriever::NtStatusFromGVR(eGvr)) );
|
|
}
|
|
}
|
|
|
|
if ( ( GVRSharingViolation == eGvr ) ||
|
|
( 0 == cbVarnt ) )
|
|
cbVarnt = sizeof varnt;
|
|
|
|
ReAlloc( i, vt, cbVarnt );
|
|
pvarnt = Get( i, cbVarnt );
|
|
}
|
|
|
|
Win4Assert( 0 != pvarnt );
|
|
eGvr = obj.GetPropertyValue( pid, pvarnt, &cbVarnt );
|
|
|
|
if ( GVRNotEnoughSpace == eGvr )
|
|
{
|
|
//
|
|
// This path should be executed very rarely because for strings
|
|
// we over-allocate the memory and for "fixed" length variants
|
|
// the correct length must have been allocated the first time.
|
|
//
|
|
ReAlloc( i, vt, cbVarnt );
|
|
pvarnt = Get( i, cbVarnt );
|
|
eGvr = obj.GetPropertyValue( pid, pvarnt, &cbVarnt );
|
|
}
|
|
|
|
if ( GVRSharingViolation == eGvr )
|
|
pvarnt->vt = VT_EMPTY;
|
|
else if ( GVRSuccess != eGvr )
|
|
THROW( CException(CRetriever::NtStatusFromGVR(eGvr)) );
|
|
}
|
|
} //Set
|
|
|
|
|