//+--------------------------------------------------------------------------- // // 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 #include 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 * 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 & 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