|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1999.
//
// File: Restrict.cxx
//
// Contents: C++ wrappers for restrictions.
//
// History: 31-Dec-92 KyleP Created
// 28-Jul-94 KyleP Hand marshalling
//
//--------------------------------------------------------------------------
#include <pch.cxx>
#pragma hdrstop
#include <pidmap.hxx>
#include <coldesc.hxx>
#include <pickle.hxx>
//+-------------------------------------------------------------------------
//
// Member: CFullPropSpec::CFullPropSpec, public
//
// Synopsis: Copy constructor
//
// Arguments: [src] -- Source property spec
//
// History: 17-Jul-93 KyleP Created
//
//--------------------------------------------------------------------------
CFullPropSpec::CFullPropSpec( CFullPropSpec const & src ) : _guidPropSet( src._guidPropSet ) { _psProperty.ulKind = src._psProperty.ulKind;
if ( _psProperty.ulKind == PRSPEC_LPWSTR ) { if ( src._psProperty.lpwstr ) { _psProperty.ulKind = PRSPEC_PROPID; SetProperty( src._psProperty.lpwstr ); } else _psProperty.lpwstr = 0; } else { _psProperty.propid = src._psProperty.propid; } }
void CFullPropSpec::Marshall( PSerStream & stm ) const { stm.PutGUID( _guidPropSet ); stm.PutULong( _psProperty.ulKind );
switch( _psProperty.ulKind ) { case PRSPEC_PROPID: stm.PutULong( _psProperty.propid ); break;
case PRSPEC_LPWSTR: { ULONG cc = wcslen( _psProperty.lpwstr ); stm.PutULong( cc ); stm.PutWChar( _psProperty.lpwstr, cc ); break; }
default: Win4Assert( !"Invalid PROPSPEC" ); break; } }
CFullPropSpec::CFullPropSpec( PDeSerStream & stm ) { stm.GetGUID( _guidPropSet ); _psProperty.ulKind = stm.GetULong();
switch( _psProperty.ulKind ) { case PRSPEC_PROPID: _psProperty.propid = stm.GetULong(); break;
case PRSPEC_LPWSTR: { _psProperty.lpwstr = UnMarshallWideString( stm ); break; }
default: Win4Assert( !"Invalid PROPSPEC" );
// Make the fullpropspec look invalid, so the later check fails.
_psProperty.ulKind = PRSPEC_LPWSTR; _psProperty.lpwstr = 0; break; } }
void CFullPropSpec::SetProperty( PROPID pidProperty ) { if ( _psProperty.ulKind == PRSPEC_LPWSTR && 0 != _psProperty.lpwstr ) { CoTaskMemFree( _psProperty.lpwstr ); }
_psProperty.ulKind = PRSPEC_PROPID; _psProperty.propid = pidProperty; }
BOOL CFullPropSpec::SetProperty( WCHAR const * wcsProperty ) { if ( _psProperty.ulKind == PRSPEC_LPWSTR && 0 != _psProperty.lpwstr ) { CoTaskMemFree( _psProperty.lpwstr ); }
_psProperty.ulKind = PRSPEC_LPWSTR;
int len = (wcslen( wcsProperty ) + 1) * sizeof( WCHAR );
_psProperty.lpwstr = (WCHAR *)CoTaskMemAlloc( len );
if ( 0 != _psProperty.lpwstr ) { memcpy( _psProperty.lpwstr, wcsProperty, len ); return( TRUE ); } else { _psProperty.lpwstr = 0; return( FALSE ); } }
//
// Methods for CColumns
//
CColumns::CColumns( unsigned size ) : _size( size ), _cCol( 0 ), _aCol( 0 ) { Win4Assert( OFFSETS_MATCH( COLUMNSET, cCol, CColumns, _cCol ) ); Win4Assert( OFFSETS_MATCH( COLUMNSET, aCol, CColumns, _aCol ) );
//
// Avoid nasty boundary condition for ::IsValid
//
if ( _size == 0 ) _size = 8;
_aCol = new CFullPropSpec [ _size ];
memset( _aCol, PRSPEC_PROPID, _size * sizeof( CFullPropSpec ) ); }
CColumns::CColumns( CColumns const & src ) : _size( src._cCol ), _cCol( 0 ) { Win4Assert( OFFSETS_MATCH( COLUMNSET, cCol, CColumns, _cCol ) ); Win4Assert( OFFSETS_MATCH( COLUMNSET, aCol, CColumns, _aCol ) );
//
// Avoid nasty boundary condition for ::IsValid
//
if ( _size == 0 ) _size = 1;
_aCol = new CFullPropSpec [ _size ];
if ( 0 == _aCol ) THROW( CException( E_OUTOFMEMORY ) );
memset( _aCol, PRSPEC_PROPID, _size * sizeof( CFullPropSpec ) );
// Add does not throw since the array has been sized already
while ( _cCol < src._cCol ) { Add( src.Get( _cCol ), _cCol ); if ( !Get( _cCol-1 ).IsValid() ) { delete [] _aCol; _aCol = 0; THROW( CException( E_OUTOFMEMORY ) ); } } }
CColumns::~CColumns() { delete [] _aCol; }
void CColumns::Marshall( PSerStream & stm ) const { stm.PutULong( _cCol );
for ( unsigned i = 0; i < _cCol; i++ ) { _aCol[i].Marshall( stm ); } }
CColumns::CColumns( PDeSerStream & stm ) { _size = stm.GetULong();
//
// Avoid nasty boundary condition for ::IsValid
//
// Guard against attack
if ( _size == 0 ) _size = 1; else if ( _size > 1000 ) THROW( CException( E_INVALIDARG ) );
XArray< CFullPropSpec > xCol( _size );
_aCol = xCol.GetPointer();
for( _cCol = 0; _cCol < _size; _cCol++ ) { CFullPropSpec ps(stm); Add( ps, _cCol ); }
xCol.Acquire(); }
void CColumns::Add( CFullPropSpec const & Property, unsigned pos ) { if ( pos >= _size ) { unsigned cNew = (_size > 0) ? (_size * 2) : 8; while ( pos >= cNew ) cNew = cNew * 2;
CFullPropSpec * aNew = new CFullPropSpec[cNew];
if ( _aCol ) { memcpy( aNew, _aCol, _cCol * sizeof( CFullPropSpec ) ); memset( _aCol, PRSPEC_PROPID, _size * sizeof CFullPropSpec ); delete [] _aCol; }
memset( aNew + _cCol, PRSPEC_PROPID, (cNew - _cCol) * sizeof( CFullPropSpec ) );
_aCol = aNew; _size = cNew; }
_aCol[pos] = Property;
if ( pos >= _cCol ) _cCol = pos + 1; }
void CColumns::Remove( unsigned pos ) { if ( pos < _cCol ) { _aCol[pos].CFullPropSpec::~CFullPropSpec();
_cCol--; RtlMoveMemory( _aCol + pos, _aCol + pos + 1, (_cCol - pos) * sizeof( CFullPropSpec ) ); } }
//
// Methods for CSort
//
CSort::CSort( unsigned size ) : _size( size ), _csk( 0 ), _ask( 0 ) { Win4Assert( OFFSETS_MATCH( SORTSET, cCol, CSort, _csk ) ); Win4Assert( OFFSETS_MATCH( SORTSET, aCol, CSort, _ask ) );
if ( _size > 0 ) { _ask = new CSortKey[_size];
memset( _ask, PRSPEC_PROPID, _size * sizeof( CSortKey ) ); } }
CSort::CSort( CSort const & src ) : _size( src._csk ), _csk( 0 ), _ask( 0 ) { Win4Assert( OFFSETS_MATCH( SORTSET, cCol, CSort, _csk ) ); Win4Assert( OFFSETS_MATCH( SORTSET, aCol, CSort, _ask ) );
if ( _size > 0 ) { _ask = new CSortKey[ _size ];
memset( _ask, PRSPEC_PROPID, _size * sizeof( CSortKey ) ); while( _csk < src._csk ) { Add( src.Get( _csk ), _csk ); } } }
void CSortKey::Marshall( PSerStream & stm ) const { //
// NOTE: Order is important!
//
_property.Marshall( stm ); stm.PutULong( _dwOrder ); }
CSortKey::CSortKey( PDeSerStream & stm ) : _property( stm ), _dwOrder( stm.GetULong() ) { if ( !_property.IsValid() ) THROW( CException( E_OUTOFMEMORY ) ); }
CSort::~CSort() { delete [] _ask; }
void CSort::Marshall( PSerStream & stm ) const { stm.PutULong( _csk );
for ( unsigned i = 0; i < _csk; i++ ) { _ask[i].Marshall( stm ); } }
CSort::CSort( PDeSerStream & stm ) : _csk( stm.GetULong() ), _size( _csk ) { XPtr<CSortKey> xSortKey( new CSortKey[ _csk ] );
_ask = xSortKey.GetPointer();
for ( unsigned i = 0; i < _csk; i++ ) { CSortKey sk( stm );
Add( sk, i ); }
xSortKey.Acquire(); }
void CSort::Add( CSortKey const & sk, unsigned pos ) { if ( pos >= _size ) { unsigned cNew = (_size > 0) ? (_size * 2) : 4; while ( pos >= cNew ) { cNew = cNew * 2; }
CSortKey * aNew = new CSortKey[ cNew ];
if ( _ask ) { memcpy( aNew, _ask, _csk * sizeof( CSortKey ) ); memset( _ask, PRSPEC_PROPID, _size * sizeof CSortKey ); delete [] _ask; }
memset( aNew + _csk, PRSPEC_PROPID, (cNew - _csk) * sizeof( CSortKey ) );
_ask = aNew; _size = cNew; }
_ask[pos] = sk;
if ( !_ask[pos].IsValid() ) THROW( CException( E_OUTOFMEMORY ) );
if ( pos >= _csk ) { _csk = pos + 1; } }
void CSort::Add( CFullPropSpec const & property, ULONG dwOrder, unsigned pos ) { CSortKey sk( property, dwOrder );
Add(sk, pos); }
void CSort::Remove( unsigned pos ) { if ( pos < _csk ) { _ask[pos].GetProperty().CFullPropSpec::~CFullPropSpec(); _csk--; RtlMoveMemory( _ask + pos, _ask + pos + 1, (_csk - pos) * sizeof( CSortKey ) ); } }
//
// Methods for CRestriction
//
//+-------------------------------------------------------------------------
//
// Member: CRestriction::~CRestriction(), public
//
// Synopsis: Destroy restriction. See Notes below.
//
// History: 31-Dec-92 KyleP Created
//
// Notes: This destructor simulates virtual destruction. A
// virtual destructor is not possible in CRestriction
// because it maps directly to the C structure SRestriction.
//
// Classes derived from CRestriction must be sure to set their
// restriction type to RTNone in their destructor, so when the
// base destructor below is called the derived destructor is
// not called a second time.
//
//--------------------------------------------------------------------------
CRestriction::~CRestriction() { //
// It would be nice to assert in constructor but it's inline and
// Win4Assert is not a public export.
//
Win4Assert( OFFSETS_MATCH( RESTRICTION, rt, CRestriction, _ulType ) ); Win4Assert( OFFSETS_MATCH( RESTRICTION, weight, CRestriction, _lWeight ) );
switch ( Type() ) { case RTNone: break;
case RTAnd: case RTOr: case RTProximity: case RTVector: case RTPhrase:
CastToNode()->CNodeRestriction::~CNodeRestriction(); break;
case RTNot: ((CNotRestriction *)this)-> CNotRestriction::~CNotRestriction(); break;
case RTProperty: ((CPropertyRestriction *)this)-> CPropertyRestriction::~CPropertyRestriction(); break;
case RTContent: ((CContentRestriction *)this)-> CContentRestriction::~CContentRestriction(); break;
case RTNatLanguage: ((CNatLanguageRestriction *)this)-> CNatLanguageRestriction::~CNatLanguageRestriction(); break;
case RTScope: ((CScopeRestriction *)this)->CScopeRestriction::~CScopeRestriction(); break;
case RTWord: ((CWordRestriction *)this)->CWordRestriction::~CWordRestriction(); break;
case RTSynonym: ((CSynRestriction *)this)->CSynRestriction::~CSynRestriction(); break;
case RTRange: ((CRangeRestriction *)this)->CRangeRestriction::~CRangeRestriction(); break;
case RTInternalProp: ((CInternalPropertyRestriction *)this)-> CInternalPropertyRestriction::~CInternalPropertyRestriction(); break;
default: ciDebugOut(( DEB_ERROR, "Unhandled child (%d) of class CRestriction\n", Type() )); Win4Assert( !"Unhandled child class of CRestriction" ); break; } }
//+-------------------------------------------------------------------------
//
// Member: CRestriction::TreeCount(), public
//
// Synopsis: Returns the number of items in the tree
//
// History: 15-Jul-96 dlee Created
//
//--------------------------------------------------------------------------
ULONG CRestriction::TreeCount() const { ULONG cItems = 1;
switch ( Type() ) { case RTNone: break;
case RTAnd: case RTOr: case RTProximity: case RTVector: case RTPhrase: { CNodeRestriction * p = CastToNode(); for ( ULONG x = 0; x < p->Count(); x++ ) { cItems += p->GetChild( x )->TreeCount(); } break; } case RTNot: { CNotRestriction * p = (CNotRestriction *) this;
cItems += p->GetChild()->TreeCount(); break; }
case RTProperty: case RTContent: case RTNatLanguage: case RTScope: case RTWord: case RTSynonym: case RTRange: case RTInternalProp: break;
default: ciDebugOut(( DEB_ERROR, "Unhandled child (%d) of class CRestriction\n", Type() )); Win4Assert( !"Unhandled child class of CRestriction" ); break; }
return cItems; }
//+-------------------------------------------------------------------------
//
// Member: CRestriction::IsValid(), public
//
// History: 14-Nov-95 KyleP Created
//
// Returns: TRUE if all memory allocations, etc. succeeded.
//
//--------------------------------------------------------------------------
BOOL CRestriction::IsValid() const { BOOL fValid = TRUE;
switch ( Type() ) { case RTNone: break;
case RTAnd: case RTOr: case RTProximity: case RTVector: case RTPhrase:
fValid = CastToNode()->CNodeRestriction::IsValid(); break;
case RTNot: fValid = ((CNotRestriction *)this)-> CNotRestriction::IsValid(); break;
case RTProperty: fValid = ((CPropertyRestriction *)this)-> CPropertyRestriction::IsValid(); break;
case RTContent: fValid = ((CContentRestriction *)this)-> CContentRestriction::IsValid(); break;
case RTNatLanguage: fValid = ((CNatLanguageRestriction *)this)-> CNatLanguageRestriction::IsValid(); break;
case RTScope: fValid = ((CScopeRestriction *)this)-> CScopeRestriction::IsValid(); break;
case RTWord: fValid = ((CWordRestriction *)this)-> CWordRestriction::IsValid(); break;
case RTSynonym: fValid = ((CSynRestriction *)this)-> CSynRestriction::IsValid(); break;
case RTRange: fValid = ((CRangeRestriction *)this)-> CRangeRestriction::IsValid(); break;
case RTInternalProp: fValid = ((CInternalPropertyRestriction *)this)-> CInternalPropertyRestriction::IsValid(); break;
default: ciDebugOut(( DEB_ERROR, "Unhandled child (%d) of class CRestriction\n", Type() )); Win4Assert( !"Unhandled child class of CRestriction" ); fValid = FALSE; break; }
return fValid; }
void CRestriction::Marshall( PSerStream & stm ) const { stm.PutULong( Type() ); stm.PutLong( Weight() );
switch ( Type() ) { case RTNone: break;
case RTAnd: case RTOr: case RTProximity: case RTPhrase: ((CNodeRestriction *)this)->Marshall( stm ); break;
case RTVector: ((CVectorRestriction *)this)->Marshall( stm ); break;
case RTNot: ((CNotRestriction *)this)->Marshall( stm ); break;
case RTProperty: ((CPropertyRestriction *)this)->Marshall( stm ); break;
case RTContent: ((CContentRestriction *)this)->Marshall( stm ); break;
case RTNatLanguage: ((CNatLanguageRestriction *)this)->Marshall( stm ); break;
case RTScope: ((CScopeRestriction *)this)->Marshall( stm ); break;
case RTWord: case RTSynonym: ((COccRestriction *)this)->Marshall( stm ); break;
case RTRange: ((CRangeRestriction *)this)->Marshall( stm ); break;
case RTInternalProp: ((CInternalPropertyRestriction *)this)->Marshall( stm ); break;
default: ciDebugOut(( DEB_ERROR, "Unhandled child (%d) of class CRestriction\n", Type() )); Win4Assert( !"Unhandled child class of CRestriction" ); break; } }
CRestriction * CRestriction::UnMarshall( PDeSerStream & stm ) { ULONG ulType = stm.GetULong(); LONG lWeight = stm.GetLong();
switch ( ulType ) { case RTNone: return new CRestriction( ulType, lWeight );
case RTAnd: case RTOr: case RTProximity: return new CNodeRestriction( ulType, lWeight, stm ); break;
case RTPhrase: return new CPhraseRestriction( lWeight, stm ); break;
case RTVector: return new CVectorRestriction( lWeight, stm ); break;
case RTNot: return new CNotRestriction( lWeight, stm ); break;
case RTProperty: return new CPropertyRestriction( lWeight, stm ); break;
case RTContent: return new CContentRestriction( lWeight, stm ); break;
case RTNatLanguage: return new CNatLanguageRestriction( lWeight, stm ); break;
case RTScope: return new CScopeRestriction( lWeight, stm ); break;
case RTWord: return new CWordRestriction( lWeight, stm ); break;
case RTSynonym: return new CSynRestriction( lWeight, stm ); break;
case RTRange: return new CRangeRestriction( lWeight, stm ); break;
case RTInternalProp: return new CInternalPropertyRestriction( lWeight, stm ); break;
default: ciDebugOut(( DEB_ERROR, "Unhandled child (%d) of class CRestriction during unmarshalling\n", ulType )); Win4Assert( !"Unhandled child class of CRestriction" ); THROW( CException( E_INVALIDARG ) ); break; }
return( 0 ); }
//+-------------------------------------------------------------------------
//
// Member: CRestriction::IsLeaf, public
//
// Returns: TRUE if node is a leaf node
//
// History: 12-Feb-93 KyleP Moved from .hxx
//
//--------------------------------------------------------------------------
BOOL CRestriction::IsLeaf() const { switch( Type() ) { case RTAnd: case RTOr: case RTNot: case RTProximity: case RTVector: case RTPhrase: return( FALSE );
default: return( TRUE ); } }
CRestriction *CRestriction::Clone() const { switch ( Type() ) { case RTAnd: case RTOr: case RTProximity: case RTPhrase: return ( (CNodeRestriction *) this)->Clone();
case RTVector: return ( (CVectorRestriction *) this)->Clone();
case RTNot: return ( (CNotRestriction *) this)->Clone();
case RTInternalProp: return ( (CInternalPropertyRestriction *) this)->Clone();
case RTContent: return ( (CContentRestriction *) this)->Clone();
case RTWord: return ( (CWordRestriction *) this)->Clone();
case RTSynonym: return ( (CSynRestriction *) this)->Clone();
case RTRange: return( (CRangeRestriction *) this)->Clone();
case RTScope: return ((CScopeRestriction *) this)->Clone();
case RTNone: return new CRestriction;
default: ciDebugOut(( DEB_ERROR, "No clone method for restriction type - %d\n", Type() )); Win4Assert( !"CRestriction: Clone method should be overridden in child class" );
return 0; } }
CNodeRestriction::CNodeRestriction( ULONG NodeType, unsigned cInitAllocated ) : CRestriction( NodeType, MAX_QUERY_RANK ), _cNode( 0 ), _paNode( 0 ), _cNodeAllocated( cInitAllocated ) { Win4Assert( OFFSETS_MATCH( RESTRICTION, res.ar.cRes, CNodeRestriction, _cNode ) ); Win4Assert( OFFSETS_MATCH( RESTRICTION, res.ar.paRes, CNodeRestriction, _paNode ) ); Win4Assert( OFFSETS_MATCH( RESTRICTION, res.ar.reserved, CNodeRestriction, _cNodeAllocated ) );
Win4Assert( OFFSETS_MATCH( RESTRICTION, res.or.cRes, CNodeRestriction, _cNode ) ); Win4Assert( OFFSETS_MATCH( RESTRICTION, res.or.paRes, CNodeRestriction, _paNode ) ); Win4Assert( OFFSETS_MATCH( RESTRICTION, res.or.reserved, CNodeRestriction, _cNodeAllocated ) );
Win4Assert( OFFSETS_MATCH( RESTRICTION, res.pxr.cRes, CNodeRestriction, _cNode ) ); Win4Assert( OFFSETS_MATCH( RESTRICTION, res.pxr.paRes, CNodeRestriction, _paNode ) ); Win4Assert( OFFSETS_MATCH( RESTRICTION, res.pxr.reserved, CNodeRestriction, _cNodeAllocated ) );
Win4Assert( OFFSETS_MATCH( RESTRICTION, res.vr.Node.cRes, CNodeRestriction, _cNode ) ); Win4Assert( OFFSETS_MATCH( RESTRICTION, res.vr.Node.paRes, CNodeRestriction, _paNode ) ); Win4Assert( OFFSETS_MATCH( RESTRICTION, res.vr.Node.reserved, CNodeRestriction, _cNodeAllocated ) );
if ( _cNodeAllocated > 0 ) { _paNode = new CRestriction * [ _cNodeAllocated ]; } }
CNodeRestriction::CNodeRestriction( const CNodeRestriction& nodeRst ) : CRestriction( nodeRst.Type(), nodeRst.Weight() ), _cNode( nodeRst.Count() ), _cNodeAllocated( nodeRst.Count() ), _paNode( 0 ) { if ( _cNodeAllocated > 0 ) { _paNode = new CRestriction * [ _cNodeAllocated ]; RtlZeroMemory( _paNode, _cNodeAllocated * sizeof( CRestriction * ) );
for ( unsigned i=0; i<_cNode; i++ ) _paNode[i] = nodeRst.GetChild( i )->Clone(); } }
//+-------------------------------------------------------------------------
//
// Member: CNodeRestriction::~CNodeRestriction(), public
//
// Synopsis: Destroy node restriction. See Notes below.
//
// History: 31-Dec-92 KyleP Created
//
// Notes: This destructor simulates virtual destruction. A
// virtual destructor is not possible in CNodeRestriction
// because it maps directly to a C structure.
//
// Classes derived from CNodeRestriction must be sure to set their
// restriction type to RTNone in their destructor, so when the
// base destructor below is called the derived destructor is
// not called a second time.
//
//--------------------------------------------------------------------------
CNodeRestriction::~CNodeRestriction() { switch( Type() ) { case RTNone: break;
case RTAnd: case RTOr: case RTProximity: case RTVector: { if ( 0 != _paNode ) { for ( unsigned i = 0; i < _cNode; i++ ) delete _paNode[i];
delete [] _paNode; }
SetType( RTNone ); // Avoid recursion.
break; }
case RTPhrase: (( CPhraseRestriction *)this)->CPhraseRestriction::~CPhraseRestriction(); break;
case RTScope: (( CScopeRestriction *)this)->CScopeRestriction::~CScopeRestriction(); break;
default: ciDebugOut(( DEB_ERROR, "Unhandled child (%d) of class CNodeRestriction\n", Type() )); Win4Assert( !"Unhandled child of class CNodeRestriction" ); break; } }
//+-------------------------------------------------------------------------
//
// Member: CNodeRestriction::IsValid(), public
//
// History: 14-Nov-95 KyleP Created
//
// Returns: TRUE if all memory allocations, etc. succeeded.
//
//--------------------------------------------------------------------------
BOOL CNodeRestriction::IsValid() const { if ( 0 == _paNode ) return FALSE;
for ( unsigned i = 0; i < _cNode; i++ ) { if ( 0 == _paNode[i] || !_paNode[i]->IsValid() ) return FALSE; }
return TRUE; }
void CNodeRestriction::Marshall( PSerStream & stm ) const { #if CIDBG == 1
if ( Type() == RTPhrase ) { for ( unsigned i = 0; i < _cNode; i++ ) Win4Assert( _paNode[i]->Type() == RTWord || _paNode[i]->Type() == RTSynonym ); } #endif
stm.PutULong( _cNode ); for ( unsigned i = 0; i < _cNode; i++ ) { _paNode[i]->Marshall( stm ); } }
CNodeRestriction::CNodeRestriction( ULONG ulType, LONG lWeight, PDeSerStream & stm ) : CRestriction( ulType, lWeight ), _cNode( 0 ), _paNode( 0 ), _cNodeAllocated( 0 ) { ULONG cNodeAllocated = stm.GetULong();
// Note: this is an arbitrary limit intended to protect against attack
if ( cNodeAllocated > 65536 ) THROW( CException( E_INVALIDARG ) );
_cNodeAllocated = cNodeAllocated;
//
// Note: the destructor will be called if the constructor doesn't finish,
// from ~CRestriction. So _paNode will be freed if AddChild fails.
//
_paNode = new CRestriction * [ _cNodeAllocated ];
RtlZeroMemory( _paNode, _cNodeAllocated * sizeof( CRestriction * ) );
for ( unsigned i = 0; i < _cNodeAllocated; i++ ) AddChild( CRestriction::UnMarshall( stm ) ); }
void CNodeRestriction::AddChild( CRestriction * presChild, unsigned & pos ) { if ( _cNode == _cNodeAllocated ) Grow();
_paNode[_cNode] = presChild; pos = _cNode; _cNode++; }
CRestriction * CNodeRestriction::RemoveChild( unsigned pos ) { if ( pos < _cNode ) { CRestriction * prstRemoved = _paNode[pos];
//
// A memcpy would be nice, but is dangerous with overlapping
// regions.
//
for ( pos++; pos < _cNode; pos++ ) { _paNode[pos-1] = _paNode[pos]; }
_cNode--;
return( prstRemoved ); } else { return( 0 ); } }
void CNodeRestriction::Grow() { int count = (_cNodeAllocated != 0) ? _cNodeAllocated * 2 : 2;
CRestriction ** paNew= new CRestriction * [ count ]; RtlZeroMemory( paNew, count * sizeof( CRestriction * ) );
memcpy( paNew, _paNode, _cNode * sizeof( CRestriction * ) );
delete (BYTE *) _paNode;
_paNode = paNew; _cNodeAllocated = count; }
CNodeRestriction *CNodeRestriction::Clone() const { return new CNodeRestriction( *this ); }
CNotRestriction::CNotRestriction( CNotRestriction const & notRst ) : CRestriction( RTNot, notRst.Weight() ), _pres( 0 ) { CRestriction *pChildRst = notRst.GetChild();
if ( pChildRst ) _pres = pChildRst->Clone(); }
CNotRestriction::~CNotRestriction() { delete _pres; SetType( RTNone ); // Avoid recursion.
}
void CNotRestriction::Marshall( PSerStream & stm ) const { _pres->Marshall( stm ); }
CNotRestriction::CNotRestriction( LONG lWeight, PDeSerStream & stm ) : CRestriction( RTNot, lWeight ), _pres( 0 ) { _pres = CRestriction::UnMarshall( stm ); }
CNotRestriction *CNotRestriction::Clone() const { return new CNotRestriction( *this ); }
void CVectorRestriction::Marshall( PSerStream & stm ) const { CNodeRestriction::Marshall( stm ); stm.PutULong( _ulRankMethod ); }
CVectorRestriction::CVectorRestriction( LONG lWeight, PDeSerStream & stm ) : CNodeRestriction( RTVector, lWeight, stm ), _ulRankMethod( stm.GetULong() ) { }
CVectorRestriction *CVectorRestriction::Clone() const { return new CVectorRestriction( *this ); }
CContentRestriction::CContentRestriction( WCHAR const * pwcsPhrase, CFullPropSpec const & Property, ULONG ulGenerateMethod, LCID lcid )
: CRestriction( RTContent, MAX_QUERY_RANK ), _pwcsPhrase( 0 ), _Property( Property ), _lcid( lcid ), _ulGenerateMethod( ulGenerateMethod ) { Win4Assert( OFFSETS_MATCH( RESTRICTION, res.cr.prop, CContentRestriction, _Property ) ); Win4Assert( OFFSETS_MATCH( RESTRICTION, res.cr.pwcsPhrase, CContentRestriction, _pwcsPhrase ) ); Win4Assert( OFFSETS_MATCH( RESTRICTION, res.cr.lcid, CContentRestriction, _lcid ) ); Win4Assert( OFFSETS_MATCH( RESTRICTION, res.cr.ulGenerateMethod, CContentRestriction, _ulGenerateMethod ) );
if ( !_Property.IsValid() ) THROW( CException( E_OUTOFMEMORY ) );
SetPhrase( pwcsPhrase ); }
CContentRestriction::CContentRestriction( CContentRestriction const & contentRst ) : CRestriction( RTContent, contentRst.Weight() ), _pwcsPhrase( 0 ), _Property( contentRst.GetProperty() ), _lcid( contentRst.GetLocale() ), _ulGenerateMethod( contentRst.GenerateMethod() ) { if ( !_Property.IsValid() ) THROW( CException( E_OUTOFMEMORY ) ); SetPhrase( contentRst.GetPhrase() ); }
CContentRestriction::~CContentRestriction() { delete [] _pwcsPhrase;
SetType( RTNone ); // Avoid recursion.
}
void CContentRestriction::Marshall( PSerStream & stm ) const { _Property.Marshall( stm ); ULONG cc = wcslen( _pwcsPhrase ); stm.PutULong( cc ); stm.PutWChar( _pwcsPhrase, cc ); stm.PutULong( _lcid ); stm.PutULong( _ulGenerateMethod ); }
CContentRestriction::CContentRestriction( LONG lWeight, PDeSerStream & stm ) : CRestriction( RTContent, lWeight ), _Property( stm ) { // set to 0 in case allocation fails, since ~CRestriction will call
// ~CNatLanguageRestriction
_pwcsPhrase = 0;
if ( !_Property.IsValid() ) THROW( CException( E_OUTOFMEMORY ) );
XPtrST<WCHAR> xPhrase( UnMarshallWideStringNew( stm ) );
_lcid = stm.GetULong(); _ulGenerateMethod = stm.GetULong();
_pwcsPhrase = xPhrase.Acquire(); }
void CContentRestriction::SetPhrase( WCHAR const * pwcsPhrase ) { delete [] _pwcsPhrase; _pwcsPhrase = 0;
int len = ( wcslen( pwcsPhrase ) + 1 ) * sizeof( WCHAR );
_pwcsPhrase = new WCHAR[len]; memcpy( _pwcsPhrase, pwcsPhrase, len ); }
CContentRestriction *CContentRestriction::Clone() const { return new CContentRestriction( *this ); }
CNatLanguageRestriction::CNatLanguageRestriction( WCHAR const * pwcsPhrase, CFullPropSpec const & Property, LCID lcid ) : CRestriction( RTNatLanguage, MAX_QUERY_RANK ), _pwcsPhrase( 0 ), _Property( Property ), _lcid( lcid ) { if ( !_Property.IsValid() ) THROW( CException( E_OUTOFMEMORY ) );
Win4Assert( OFFSETS_MATCH( RESTRICTION, res.nlr.prop, CNatLanguageRestriction, _Property ) ); Win4Assert( OFFSETS_MATCH( RESTRICTION, res.nlr.pwcsPhrase, CNatLanguageRestriction, _pwcsPhrase ) ); Win4Assert( OFFSETS_MATCH( RESTRICTION, res.nlr.lcid, CNatLanguageRestriction, _lcid ) );
SetPhrase( pwcsPhrase ); }
CNatLanguageRestriction::~CNatLanguageRestriction() { delete [] _pwcsPhrase;
SetType( RTNone ); // Avoid recursion.
}
void CNatLanguageRestriction::Marshall( PSerStream & stm ) const { _Property.Marshall( stm ); ULONG cc = wcslen( _pwcsPhrase ); stm.PutULong( cc ); stm.PutWChar( _pwcsPhrase, cc ); stm.PutULong( _lcid ); }
CNatLanguageRestriction::CNatLanguageRestriction( LONG lWeight, PDeSerStream & stm ) : CRestriction( RTNatLanguage, lWeight ), _Property( stm ) { // set to 0 in case allocation fails, since ~CRestriction will call
// ~CNatLanguageRestriction
_pwcsPhrase = 0;
if ( !_Property.IsValid() ) THROW( CException( E_OUTOFMEMORY ) );
XPtrST<WCHAR> xPhrase( UnMarshallWideStringNew( stm ) );
_lcid = stm.GetULong();
_pwcsPhrase = xPhrase.Acquire(); }
void CNatLanguageRestriction::SetPhrase( WCHAR const * pwcsPhrase ) { delete [] _pwcsPhrase; _pwcsPhrase = 0;
int len = ( wcslen( pwcsPhrase ) + 1 ) * sizeof( WCHAR );
_pwcsPhrase = new WCHAR[len];
RtlCopyMemory( _pwcsPhrase, pwcsPhrase, len ); }
CPropertyRestriction::CPropertyRestriction() : CRestriction( RTProperty, MAX_QUERY_RANK ) { Win4Assert( OFFSETS_MATCH( RESTRICTION, res.pr.rel, CPropertyRestriction, _relop ) ); Win4Assert( OFFSETS_MATCH( RESTRICTION, res.pr.prop, CPropertyRestriction, _Property ) ); Win4Assert( OFFSETS_MATCH( RESTRICTION, res.pr.prval, CPropertyRestriction, _prval ) ); }
CPropertyRestriction::CPropertyRestriction( ULONG relop, CFullPropSpec const & Property, CStorageVariant const & prval ) : CRestriction( RTProperty, MAX_QUERY_RANK ), _relop( relop ), _Property( Property ), _prval( prval ) { if ( !_Property.IsValid() || !_prval.IsValid() ) THROW( CException( E_OUTOFMEMORY ) );
Win4Assert( OFFSETS_MATCH( RESTRICTION, res.pr.rel, CPropertyRestriction, _relop ) ); Win4Assert( OFFSETS_MATCH( RESTRICTION, res.pr.prop, CPropertyRestriction, _Property ) ); Win4Assert( OFFSETS_MATCH( RESTRICTION, res.pr.prval, CPropertyRestriction, _prval ) );
}
CPropertyRestriction::~CPropertyRestriction() { SetType( RTNone ); // Avoid recursion.
}
void CPropertyRestriction::Marshall( PSerStream & stm ) const { stm.PutULong( _relop ); _Property.Marshall( stm ); _prval.Marshall( stm ); }
CPropertyRestriction::CPropertyRestriction( LONG lWeight, PDeSerStream & stm ) : CRestriction( RTProperty, lWeight ), _relop( stm.GetULong() ), _Property( stm ), _prval( stm ) { if ( !_Property.IsValid() || !_prval.IsValid() ) THROW( CException( E_OUTOFMEMORY ) ); }
void CPropertyRestriction::SetValue( WCHAR * pwcsValue ) { _prval = pwcsValue; }
void CPropertyRestriction::SetValue( BLOB & bValue ) { _prval = bValue; }
void CPropertyRestriction::SetValue( GUID * pguidValue ) { _prval = pguidValue; }
CSortKey::CSortKey( CFullPropSpec const & ps, ULONG dwOrder ) : _property( ps ), _dwOrder( dwOrder ) { if ( !_property.IsValid() ) THROW( CException( E_OUTOFMEMORY ) ); }
CSortKey::CSortKey( CFullPropSpec const & ps, ULONG dwOrder, LCID locale ) : _property( ps ), _dwOrder( dwOrder ), _locale ( locale ) { if ( !_property.IsValid() ) THROW( CException( E_OUTOFMEMORY ) ); }
|