|
|
//+---------------------------------------------------------------------------
//
// 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
|