//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1991 - 2000. // // File: IRest.cxx // // Contents: Internal (non-public) restrictions. // // Classes: CInternalPropertyRestriction // COccRestriction // CWordRestriction // CSynRestriction // CRangeRestriction // CUnfilteredRestriction // CScopeRestriction // CPhraseRestriction // // History: 19-Sep-91 BartoszM Implemented. // 29-Aug-92 MikeHew Added serialization routines // 30-Nov-92 KyleP Removed CPhraseXpr // 14-Jan-93 KyleP Converted from expressions // //---------------------------------------------------------------------------- #include #pragma hdrstop #include #include #include //+------------------------------------------------------------------------- // // Function: UnMarshallWideString // // Synopsis: Unmarshalls a wide string into a CoTaskMemAlloc'ed buffer. // This can't be in memdeser since it calls CoTaskMemAlloc, // which isn't available in ntdll.dll. // // Arguments: [stm] -- stream from which string is deserialized // // History: 22-Nov-95 dlee Created from a few copies // //-------------------------------------------------------------------------- WCHAR * UnMarshallWideString( PDeSerStream & stm ) { ULONG cc = stm.GetULong(); // Protect against attack. We know our named pipes are < 64k if ( cc >= ( 65536 / sizeof WCHAR ) ) return 0; XCoMem xString( (WCHAR *) CoTaskMemAlloc( (cc + 1) * sizeof WCHAR ) ); if ( xString.IsNull() ) { // just eat the string WCHAR wc[10]; while ( cc > 0 ) { if ( cc >= 10 ) { stm.GetWChar( wc, 10 ); cc -= 10; } else { stm.GetWChar( wc, cc ); cc = 0; } } } else { WCHAR * pwc = xString.GetPointer(); stm.GetWChar( pwc, cc ); pwc[cc] = 0; } return xString.Acquire(); } //UnMarshallWideString WCHAR * UnMarshallWideStringNew( PDeSerStream & stm ) { ULONG cc = stm.GetULong(); // Protect against attack. We know our named pipes are < 64k if ( cc >= ( 65536 / sizeof WCHAR ) ) THROW( CException( E_INVALIDARG ) ); XArray xString( cc + 1 ); stm.GetWChar( xString.GetPointer(), cc ); xString[cc] = 0; return xString.Acquire(); } //UnMarshallWideStringNew //+------------------------------------------------------------------------- // // Member: CInternalPropertyRestriction::CInternalPropertyRestriction // // Synopsis: Creates property restriction // // Arguments: [relop] -- Relational operator (<, >, etc.) // [pid] -- Property id // [prval] -- Property value // [pcrst] -- 'Helper' content restriction // // History: 07-Mar-93 KyleP Created // //-------------------------------------------------------------------------- CInternalPropertyRestriction::CInternalPropertyRestriction( ULONG relop, PROPID pid, CStorageVariant const & prval, CRestriction * pcrst ) : CRestriction( RTInternalProp, MAX_QUERY_RANK ), _relop( relop ), _pid( pid ), _prval( prval ), _pcrst( pcrst ) { if ( !_prval.IsValid() ) THROW( CException( E_OUTOFMEMORY ) ); } //+--------------------------------------------------------------------------- // // Member: CInternalPropertyRestriction::CInternalPropertyRestriction // // Synopsis: Copy constructor // // History: 30-May-95 SitaramR Created. // //---------------------------------------------------------------------------- CInternalPropertyRestriction::CInternalPropertyRestriction( CInternalPropertyRestriction const & intPropRst ) : CRestriction( RTInternalProp, intPropRst.Weight() ), _relop( intPropRst.Relation() ), _pid( intPropRst.Pid() ), _prval( intPropRst.Value() ), _pcrst( 0 ) { if ( !_prval.IsValid() ) THROW( CException( E_OUTOFMEMORY ) ); CRestriction *pHelperRst = intPropRst.GetContentHelper(); if ( pHelperRst ) _pcrst = pHelperRst->Clone(); } //+------------------------------------------------------------------------- // // Member: CInternalPropertyRestriction::~CInternalPropertyRestriction // // Synopsis: Cleanup restriction // // History: 01-Feb-93 KyleP Created // //-------------------------------------------------------------------------- CInternalPropertyRestriction::~CInternalPropertyRestriction() { delete _pcrst; SetType( RTNone ); // Avoid recursion. } void CInternalPropertyRestriction::Marshall( PSerStream & stm ) const { stm.PutULong( _relop ); stm.PutULong( _pid ); _prval.Marshall( stm ); if ( 0 == _pcrst ) stm.PutByte( 0 ); else { stm.PutByte( 1 ); _pcrst->Marshall( stm ); } } CInternalPropertyRestriction::CInternalPropertyRestriction( ULONG ulWeight, PDeSerStream & stm ) : CRestriction( RTInternalProp, ulWeight ), _relop( stm.GetULong() ), _pid( stm.GetULong() ), _prval( stm ) { if ( !_prval.IsValid() ) THROW( CException( E_OUTOFMEMORY ) ); BYTE fRst = stm.GetByte(); if ( fRst ) _pcrst = CRestriction::UnMarshall( stm ); else _pcrst = 0; } //+--------------------------------------------------------------------------- // // Member: CInternalPropertyRestriction::Clone, public // // Synopsis: Clones an internal property restriction // // History: 30-May-95 SitaramR Created. // //---------------------------------------------------------------------------- CInternalPropertyRestriction *CInternalPropertyRestriction::Clone() const { return new CInternalPropertyRestriction( *this ); } //+--------------------------------------------------------------------------- // // Member: COccRestriction::COccRestriction, public // // Synopsis: Creates occurrence restriction // // Arguments: [ulType] -- type of restriction // [ulWeight] -- weight // [occ] -- occurrence // [cPrevNoiseWords] -- count of previous noise words skipped // [cPostNoiseWords] -- count of post noise words skipped // // History: 29-Nov-94 SitaramR Created. // //---------------------------------------------------------------------------- COccRestriction::COccRestriction( ULONG ulType, ULONG ulWeight, OCCURRENCE occ, ULONG cPrevNoiseWords, ULONG cPostNoiseWords ) : CRestriction( ulType, ulWeight ), _occ( occ ), _cPrevNoiseWords( cPrevNoiseWords), _cPostNoiseWords( cPostNoiseWords ) { } //+------------------------------------------------------------------------- // // Member: COccRestriction::~COccRestriction, public // // Synopsis: Cleanup occurrence restriction // // Notes: This destructor simulates virtual destruction. // // Classes derived from COccRestriction 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. // // History: 29-Nov-94 SitaramR Created // //-------------------------------------------------------------------------- COccRestriction::~COccRestriction() { switch ( Type() ) { case RTNone: break; case RTWord: ((CWordRestriction *)this)->CWordRestriction::~CWordRestriction(); break; case RTSynonym: ((CSynRestriction *)this)->CSynRestriction::~CSynRestriction(); break; default: ciDebugOut(( DEB_ERROR, "Unhandled child (%d) of class COccRestriction\n", Type() )); Win4Assert( !"Unhandled child of class COccRestriction" ); break; } } //+------------------------------------------------------------------------- // // Member: COccRestriction::IsValid(), public // // History: 14-Nov-95 KyleP Created // // Returns: TRUE if all memory allocations, etc. succeeded. // //-------------------------------------------------------------------------- BOOL COccRestriction::IsValid() const { BOOL fValid = TRUE; switch ( Type() ) { case RTWord: fValid = ((CWordRestriction *)this)->CWordRestriction::IsValid(); break; case RTSynonym: fValid = ((CSynRestriction *)this)->CSynRestriction::IsValid(); break; default: ciDebugOut(( DEB_ERROR, "Unhandled child (%d) of class COccRestriction\n", Type() )); Win4Assert( !"Unhandled child of class COccRestriction" ); fValid = FALSE; break; } return fValid; } //+------------------------------------------------------------------------- // // Member: COccRestriction::Marshall, public // // Synopsis: Serialize occurrence restriction // // Arguments: [stm] -- stream to serialize to // // History: 29-Nov-94 SitaramR Created // //-------------------------------------------------------------------------- void COccRestriction::Marshall( PSerStream& stm ) const { stm.PutULong( _occ ); stm.PutULong( _cPrevNoiseWords ); stm.PutULong( _cPostNoiseWords ); switch ( Type() ) { case RTWord: ((CWordRestriction *)this)->Marshall( stm ); break; case RTSynonym: ((CSynRestriction *)this)->Marshall( stm ); break; default: ciDebugOut(( DEB_ERROR, "Unhandled child (%d) of class COccRestriction\n", Type() )); Win4Assert( !"Unhandled child of class COccRestriction" ); break; } } //+------------------------------------------------------------------------- // // Member: COccRestriction::COccRestriction, public // // Synopsis: De-serialize occurrence restriction // // Arguments: [ulType] -- type of occurrence restriction // [ulWeight] -- weight of occurrence restriction // [stm] -- stream to serialize from // // History: 29-Nov-94 SitaramR Created // //-------------------------------------------------------------------------- COccRestriction::COccRestriction( ULONG ulType, ULONG ulWeight, PDeSerStream& stm ) : CRestriction( ulType, ulWeight ) { _occ = stm.GetULong(); _cPrevNoiseWords = stm.GetULong(); _cPostNoiseWords = stm.GetULong(); } //+------------------------------------------------------------------------- // // Member: COccRestriction::Clone, public // // Synopsis: Clone occurrence restriction // // History: 29-Nov-94 SitaramR Created // //-------------------------------------------------------------------------- COccRestriction *COccRestriction::Clone() const { switch ( Type() ) { case RTWord: return ((CWordRestriction *)this)->Clone(); break; case RTSynonym: return ((CSynRestriction *)this)->Clone(); break; default: ciDebugOut(( DEB_ERROR, "Unhandled child (%d) of class COccRestriction\n", Type() )); Win4Assert( !"Unhandled child of class COccRestriction" ); return 0; break; } } //+--------------------------------------------------------------------------- // // Member: CWordRestriction::CWordRestriction, public // // Synopsis: Creates word expression // // Arguments: [keyBuf] -- key to be matched // [occ] -- occurrence (if in phrase) // [isRange] -- TRUE if key is a prefix // // History: 19-Sep-91 BartoszM Created. // //---------------------------------------------------------------------------- CWordRestriction::CWordRestriction ( const CKeyBuf& keyBuf, OCCURRENCE occ, ULONG cPrevNoiseWords, ULONG cPostNoiseWords, BOOL isRange ) : COccRestriction( RTWord, MAX_QUERY_RANK, occ, cPrevNoiseWords, cPostNoiseWords ), _isRange(isRange) { // copy after init to 0 in case new fails and ~CWordRestriction is // called from ~CRestriction _key = keyBuf; } //+--------------------------------------------------------------------------- // // Member: CWordRestriction::CWordRestriction, public // // Synopsis: Copy constuctor // // Arguments: [wordRst] -- word restriction to be copied // // History: 29-Nov-94 SitaramR Created. // //---------------------------------------------------------------------------- CWordRestriction::CWordRestriction( const CWordRestriction& wordRst ) : COccRestriction( RTWord, wordRst.Weight(), wordRst.Occurrence(), wordRst.CountPrevNoiseWords(), wordRst.CountPostNoiseWords() ), _isRange( wordRst.IsRange() ) { // copy after init to 0 in case new fails and ~CWordRestriction is // called from ~CRestriction _key = *wordRst.GetKey(); } //+------------------------------------------------------------------------- // // Member: CWordRestriction::~CWordRestriction, public // // Synopsis: Cleanup restriction // // History: 01-Feb-93 KyleP Created // //-------------------------------------------------------------------------- CWordRestriction::~CWordRestriction() { SetType( RTNone ); // Avoid recursion. } void CWordRestriction::Marshall( PSerStream & stm ) const { _key.Marshall( stm ); stm.PutByte( (BYTE)_isRange ); } CWordRestriction::CWordRestriction( ULONG ulWeight, PDeSerStream & stm ) : COccRestriction( RTWord, ulWeight, stm ), _key( stm ), _isRange( stm.GetByte() ) { } //+--------------------------------------------------------------------------- // // Member: CWordRestriction::Clone, public // // Synopsis: Clone restriction // // History: 29-Nov-94 SitaramR Created. // //---------------------------------------------------------------------------- CWordRestriction *CWordRestriction::Clone() const { return new CWordRestriction( *this ); } //+--------------------------------------------------------------------------- // // Member: CSynRestriction::CSynRestriction, public // // Synopsis: Creates Syn expression // // Arguments: [occ] -- occurrence (if in phrase) // [isRange] -- is it range? // // History: 07-Feb-92 BartoszM Created. // //---------------------------------------------------------------------------- const int cSynonyms = 2; // default initial count of synonyms CSynRestriction::CSynRestriction ( const CKey& key, OCCURRENCE occ, ULONG cPrevNoiseWords, ULONG cPostNoiseWords, BOOL isRange ) : COccRestriction( RTNone, MAX_QUERY_RANK, occ, cPrevNoiseWords, cPostNoiseWords ), _keyArray( cSynonyms, TRUE ), _isRange(isRange) { _keyArray.Add ( key ); SetType( RTSynonym ); } //+--------------------------------------------------------------------------- // // Member: CSynRestriction::CSynRestriction, public // // Synopsis: Copy constuctor // // Arguments: [synRst] -- synonym restriction to be copied // // History: 29-Nov-94 SitaramR Created. // //---------------------------------------------------------------------------- CSynRestriction::CSynRestriction( CSynRestriction& synRst ) : COccRestriction( RTNone, synRst.Weight(), synRst.Occurrence(), synRst.CountPrevNoiseWords(), synRst.CountPostNoiseWords() ), _keyArray( synRst.GetKeys(), TRUE ), _isRange( synRst.IsRange() ) { SetType( RTSynonym ); } //+------------------------------------------------------------------------- // // Member: CSynRestriction::~CSynRestriction, public // // Synopsis: Cleanup restriction // // History: 01-Feb-93 KyleP Created // //-------------------------------------------------------------------------- CSynRestriction::~CSynRestriction() { SetType( RTNone ); // Avoid recursion. } void CSynRestriction::Marshall( PSerStream & stm ) const { _keyArray.Marshall( stm ); stm.PutByte( (BYTE)_isRange ); } CSynRestriction::CSynRestriction( ULONG ulWeight, PDeSerStream & stm ) : COccRestriction( RTNone, ulWeight, stm), _keyArray( stm, TRUE ), _isRange( stm.GetByte() ) { SetType( RTSynonym ); } //+--------------------------------------------------------------------------- // // Member: CSynRestriction::Clone, public // // Synopsis: Clone restriction // // History: 29-Nov-94 SitaramR Created. // //---------------------------------------------------------------------------- CSynRestriction *CSynRestriction::Clone() const { return new CSynRestriction( *(CSynRestriction *)this ); } //+--------------------------------------------------------------------------- // // Member: CSynRestriction::AddKey, public // // Synopsis: Adds synonym key // // Arguments: [keyBuf] -- key // // History: 07-Feb-92 BartoszM Created. // //---------------------------------------------------------------------------- void CSynRestriction::AddKey ( const CKeyBuf& Key ) { _keyArray.Add ( Key ); } //+--------------------------------------------------------------------------- // // Member: CRangeRestriction::CRangeRestriction, public // // Synopsis: Creates word expression // // Arguments: [pid] -- property id // [keyStart] -- starting key // [keyEnd] -- ending key // // History: 24-Sep-92 BartoszM Created. // //---------------------------------------------------------------------------- CRangeRestriction::CRangeRestriction() : CRestriction( RTRange, MAX_QUERY_RANK ) { } //+--------------------------------------------------------------------------- // // Member: CRangeRestriction::CRangeRestriction // // Synopsis: Copy constructor // // History: 30-May-95 SitaramR Created // //---------------------------------------------------------------------------- CRangeRestriction::CRangeRestriction( const CRangeRestriction& rangeRst ) : CRestriction( RTNone, rangeRst.Weight() ) { const CKey *pKeyStart = rangeRst.GetStartKey(); if ( pKeyStart ) _keyStart = *pKeyStart; const CKey *pKeyEnd = rangeRst.GetEndKey(); if ( pKeyEnd ) _keyEnd = *pKeyEnd; SetType( RTRange ); } //+------------------------------------------------------------------------- // // Member: CRangeRestriction::~CRangeRestriction, public // // Synopsis: Cleanup restriction // // History: 01-Feb-93 KyleP Created // //-------------------------------------------------------------------------- CRangeRestriction::~CRangeRestriction() { SetType( RTNone ); // Avoid recursion. } void CRangeRestriction::Marshall( PSerStream & stm ) const { _keyStart.Marshall( stm ); _keyEnd.Marshall( stm ); } CRangeRestriction::CRangeRestriction( ULONG ulWeight, PDeSerStream & stm ) : CRestriction( RTNone, ulWeight ), _keyStart( stm ), _keyEnd( stm ) { SetType( RTRange ); } //+--------------------------------------------------------------------------- // // Member: CRangeRestriction::SetStartKey, public // // Arguments: [keyStart] -- starting key // // History: 24-Sep-92 BartoszM Created. // //---------------------------------------------------------------------------- void CRangeRestriction::SetStartKey ( const CKeyBuf& keyStart ) { _keyStart = keyStart; } //+--------------------------------------------------------------------------- // // Member: CRangeRestriction::SetEndKey, public // // Arguments: [keyEnd] -- Ending key // // History: 24-Sep-92 BartoszM Created. // //---------------------------------------------------------------------------- void CRangeRestriction::SetEndKey ( const CKeyBuf& keyEnd ) { _keyEnd = keyEnd; } //+--------------------------------------------------------------------------- // // Member: CRangeRestriction::Clone // // Synopsis: Clones a range restriction // // History: 30-May-95 SitaramR Created // //---------------------------------------------------------------------------- CRangeRestriction *CRangeRestriction::Clone() const { return new CRangeRestriction( *this ); } //+--------------------------------------------------------------------------- // // Member: CUnfilteredRestriction::CUnfilteredRestriction, public // // History: 10-Nov-94 KyleP Created. // // Notes: This restriction is just a very special case of range // restriction that searches only for a particular value. // Standard procedure to create a range restriction is // sidetracked to save code. // //---------------------------------------------------------------------------- CUnfilteredRestriction::CUnfilteredRestriction() { static const BYTE abUnfiltered[] = { VT_UI1, (BYTE)(pidUnfiltered >> 24), (BYTE)(pidUnfiltered >> 16), (BYTE)(pidUnfiltered >> 8), (BYTE) pidUnfiltered, 0, 1 }; static CKeyBuf keyUnfilteredRange( pidUnfiltered, abUnfiltered, sizeof(abUnfiltered) ); SetStartKey( keyUnfilteredRange ); SetEndKey( keyUnfilteredRange ); #if DBG == 1 && CIDBG == 1 CRangeKeyRepository krep; CValueNormalizer norm( krep ); OCCURRENCE occ = 1; CStorageVariant var; var.SetBOOL( (VARIANT_BOOL)0xFFFF ); norm.PutValue( pidUnfiltered, occ, var ); norm.PutValue( pidUnfiltered, occ, var ); CRestriction * prst = krep.AcqRst(); Win4Assert( prst->Type() == RTRange ); CRangeRestriction * pRange = (CRangeRestriction *)prst; Win4Assert( pRange->GetStartKey()->Compare( *GetStartKey() ) == 0 ); Win4Assert( pRange->GetEndKey()->Compare( *GetEndKey() ) == 0 ); delete prst; #endif } //+--------------------------------------------------------------------------- // // Member: CPhraseRestriction::CPhraseRestriction, public // // Synopsis: Deserializes phrase restriction // // Arguments: [ulWeight] -- restriction weight // [stm] -- stream to deserialize from // // History: 29-Nov-94 SitaramR Created. // //---------------------------------------------------------------------------- CPhraseRestriction::CPhraseRestriction( ULONG ulWeight, PDeSerStream& stm ) : CNodeRestriction( RTPhrase, ulWeight, stm ) { #if CIDBG == 1 for ( unsigned i = 0; i < _cNode; i++ ) Win4Assert( _paNode[i]->Type() == RTWord || _paNode[i]->Type() == RTSynonym ); #endif } //+--------------------------------------------------------------------------- // // Member: CPhraseRestriction::~CPhraseRestriction, public // // History: 29-Nov-94 SitaramR Created. // //---------------------------------------------------------------------------- CPhraseRestriction::~CPhraseRestriction() { if ( 0 != _paNode ) { for ( unsigned i = 0; i < _cNode; i++ ) { #if CIDBG == 1 if ( 0 != _paNode[i] ) { Win4Assert( _paNode[i]->Type() == RTWord || _paNode[i]->Type() == RTSynonym ); } #endif // CIDBG delete (COccRestriction *) _paNode[i]; } delete [] _paNode; } SetType( RTNone ); // Avoid recursion. } CScopeRestriction::CScopeRestriction( WCHAR const * pwcsPath, BOOL fRecursive, BOOL fVirtual ) : CRestriction( RTScope, MAX_QUERY_RANK ), _fValid( FALSE ), _fRecursive( fRecursive ), _fVirtual( fVirtual ) { SetPath( pwcsPath ); } CScopeRestriction * CScopeRestriction::Clone() const { return( new CScopeRestriction( _lowerFunnyPath.GetActualPath(), _fRecursive, _fVirtual ) ); } CScopeRestriction::~CScopeRestriction() { SetType( RTNone ); // Avoid recursion. } void CScopeRestriction::Marshall( PSerStream & stm ) const { stm.PutWString( _lowerFunnyPath.GetActualPath() ); stm.PutULong( _lowerFunnyPath.GetActualLength() ); stm.PutULong( _fRecursive ); stm.PutULong( _fVirtual ); } CScopeRestriction::CScopeRestriction( ULONG ulWeight, PDeSerStream & stm ) : CRestriction( RTScope, ulWeight ), _fValid( FALSE ) { XCoMem xString( UnMarshallWideString( stm ) ); // // Simple validity checks; not all-inclusive. Just // return with _fValid set to FALSE and the query // will fail with an out of memory error. // // We don't support long paths for scopes. if ( wcslen( xString.GetPointer() ) >= MAX_PATH ) return; // We don't support the NTFS special stream syntax if ( 0 != wcsstr( xString.GetPointer(), L"::$" ) ) return; stm.GetULong(); // length not needed _fRecursive = stm.GetULong(); _fVirtual = stm.GetULong(); _lowerFunnyPath.SetPath( xString.Acquire() ); _fValid = TRUE; // since we have a valid path } CScopeRestriction & CScopeRestriction::operator =( CScopeRestriction const & source ) { _lowerFunnyPath = source._lowerFunnyPath; _fRecursive = source._fRecursive; _fVirtual = source._fVirtual; _fValid = source._fValid; return *this; } //+--------------------------------------------------------------------------- // // Method: CScopeRestriction::SetPath // // Synopsis: Validates and sets a path in a scope restriction // // History: 24-Oct-96 dlee Created. // //---------------------------------------------------------------------------- void CScopeRestriction::SetPath( WCHAR const * pwcsPath ) { _fValid = FALSE; // // Simple validity checks; not all-inclusive. Just // return with _fValid set to FALSE and the query // wil fail with an out of memory error. // // We don't support long paths for scopes. if ( wcslen( pwcsPath ) >= MAX_PATH ) return; // We don't support the NTFS special stream syntax if ( 0 != wcsstr( pwcsPath, L"::$" ) ) return; _lowerFunnyPath.Truncate(0); if ( pwcsPath) { _lowerFunnyPath.SetPath( pwcsPath ); _fValid = TRUE; } } //SetPath //+--------------------------------------------------------------------------- // // Function: ValidateScopeRestriction // // Synopsis: Verifies a scope restriction looks ok. Can't use // CRestriction::IsValid since this needs to make sure there // aren't any odd nodes in the tree (like proximity, etc.) // // Returns: TRUE if it is ok, FALSE otherwise // // History: 24-Oct-96 dlee Created. // //---------------------------------------------------------------------------- BOOL ValidateScopeRestriction( CRestriction * pRst ) { if ( 0 == pRst ) return FALSE; switch ( pRst->Type() ) { #if 0 // someday we might support exclusion scopes case RTNot: { CRestriction *p = ((CNotRestriction *)pRst)->GetChild(); return ValidateScopeRestriction( p ); break; } case RTAnd: #endif // 0 // exclusion scopes case RTOr: { CNodeRestriction * p = pRst->CastToNode(); for ( ULONG x = 0; x < p->Count(); x++ ) { if ( !ValidateScopeRestriction( p->GetChild( x ) ) ) return FALSE; } break; } case RTScope: { CScopeRestriction *p = (CScopeRestriction *) pRst; if ( !p->IsValid() ) return FALSE; break; } default : { return FALSE; } } return TRUE; } //ValidateScopeRestriction #if CIDBG == 1 //+------------------------------------------------------------------------- // // Function: DisplayChar // // Synopsis: Debug print the non-ascii text buffer // // Arguments: [pwString] -- Pointer to string (not null terminated) // [cString] -- len of the string in char // [infolevel] -- // // History: 22-Apr-98 KitmanH Created // //-------------------------------------------------------------------------- void DisplayChar( WCHAR * pwString, DWORD cString, ULONG infolevel ) { BOOL fOk = TRUE; for ( unsigned i = 0; i < cString; i++ ) { if ( pwString[i] > 0xFF ) { fOk = FALSE; break; } } if ( fOk ) { unsigned j = 0; WCHAR awcTemp[71]; for ( unsigned i = 0; i < cString; i++ ) { awcTemp[j] = pwString[i]; j++; if ( j == sizeof(awcTemp)/sizeof(awcTemp[0]) - 1 ) { awcTemp[j] = 0; vqDebugOut(( infolevel | DEB_NOCOMPNAME, "\"%ws\"", awcTemp )); j = 0; } } awcTemp[j] = 0; vqDebugOut(( infolevel | DEB_NOCOMPNAME, "\"%ws\"", awcTemp )); } else { vqDebugOut(( infolevel | DEB_NOCOMPNAME, "0x" )); unsigned j = 0; for ( unsigned i = 0; i < cString; i++ ) { if ( 0 == j ) vqDebugOut(( infolevel | DEB_NOCOMPNAME, "%04X", pwString[i] )); else if ( 14 == j ) { vqDebugOut(( infolevel | DEB_NOCOMPNAME, " %04X\n", pwString[i] )); } else vqDebugOut(( infolevel | DEB_NOCOMPNAME, " %04X", pwString[i] )); j++; if ( j > 14 ) j = 0; } } } void Display( CRestriction * pRst, int indent, ULONG infolevel ) { vqDebugOut(( infolevel, " " )); for ( int i = 0; i < indent; i++ ) { vqDebugOut(( infolevel | DEB_NOCOMPNAME, " " )); } switch ( pRst->Type() ) { case RTContent: vqDebugOut(( infolevel | DEB_NOCOMPNAME, "CONTENT: \"%ws\", LOCALE: %lu\n", ((CContentRestriction *)pRst)->GetPhrase(), ((CContentRestriction *)pRst)->GetLocale() )); break; case RTNatLanguage: vqDebugOut(( infolevel | DEB_NOCOMPNAME, "NATURAL LANGUAGE: \"%ws\", LOCALE: %lu\n", ((CNatLanguageRestriction *)pRst)->GetPhrase(), ((CNatLanguageRestriction *)pRst)->GetLocale() )); break; case RTWord: vqDebugOut(( infolevel | DEB_NOCOMPNAME, "WORD%s: ", ((CWordRestriction *)pRst)->IsRange() ? " PREFIX" : "" )); DisplayChar( ((CWordRestriction *)pRst)->GetKey()->GetStr(), ((CWordRestriction *)pRst)->GetKey()->StrLen(), infolevel ); vqDebugOut(( infolevel | DEB_NOCOMPNAME, " PID %d OCC %d, WEIGHT %d\n", ((CWordRestriction *)pRst)->Pid(), ((CWordRestriction *)pRst)->Occurrence(), ((CWordRestriction *)pRst)->Weight() )); break; case RTSynonym: { vqDebugOut(( infolevel | DEB_NOCOMPNAME, "SYNONYM: OCC %d ", ((CSynRestriction *)pRst)->Occurrence() )); CKeyArray & keys = ((CSynRestriction *)pRst)->GetKeys(); for ( int i = 0; i < keys.Count(); i++ ) { DisplayChar( keys.Get(i).GetStr(), keys.Get(i).StrLen(), infolevel ); vqDebugOut(( infolevel | DEB_NOCOMPNAME, " " )); } vqDebugOut(( infolevel | DEB_NOCOMPNAME, "\n" )); break; } case RTRange: { CRangeRestriction * pr = (CRangeRestriction *)pRst; vqDebugOut(( infolevel | DEB_NOCOMPNAME, "RANGE: " )); char * pc = new char[pr->GetStartKey()->Count() * 2 + 1 + pr->GetEndKey()->Count() * 2 + 2]; for ( unsigned i = 0; i < pr->GetStartKey()->Count(); i++ ) sprintf( pc + i*2, "%02x", pr->GetStartKey()->GetBuf()[i] ); pc[i*2] = '-'; for ( unsigned j = 0; j < pr->GetEndKey()->Count(); j++ ) sprintf( pc + i*2 + 1 + j*2, "%02x", pr->GetEndKey()->GetBuf()[j] ); pc[i*2 + 1 + j*2] = '\n'; pc[i*2 + 1 + j*2 + 1] = 0; vqDebugOut(( infolevel | DEB_NOCOMPNAME, pc )); delete [] pc; break; } case RTProperty: if ( ((CPropertyRestriction *)pRst)->Relation() == PRRE ) vqDebugOut(( infolevel | DEB_NOCOMPNAME, "REGEX " )); else vqDebugOut(( infolevel | DEB_NOCOMPNAME, "PROPERTY " )); ((CPropertyRestriction *) pRst)->Value().DisplayVariant( infolevel | DEB_NOCOMPNAME, 0); vqDebugOut(( infolevel | DEB_NOCOMPNAME, "\n" )); break; case RTInternalProp: { CInternalPropertyRestriction * pir = (CInternalPropertyRestriction *)pRst; if ( pir->Relation() == PRRE ) vqDebugOut(( infolevel | DEB_NOCOMPNAME, "REGEX pid(0x%lx) ", pir->Pid() )); else { vqDebugOut(( infolevel | DEB_NOCOMPNAME, "PROPERTY pid(0x%lx) ", pir->Pid() )); switch ( getBaseRelop( pir->Relation() ) ) { case PRLT: vqDebugOut(( infolevel | DEB_NOCOMPNAME, "< " )); break; case PRLE: vqDebugOut(( infolevel | DEB_NOCOMPNAME, "<= " )); break; case PRGT: vqDebugOut(( infolevel | DEB_NOCOMPNAME, "> " )); break; case PRGE: vqDebugOut(( infolevel | DEB_NOCOMPNAME, ">= " )); break; case PREQ: vqDebugOut(( infolevel | DEB_NOCOMPNAME, "== " )); break; case PRNE: vqDebugOut(( infolevel | DEB_NOCOMPNAME, "!= " )); break; case PRAllBits: vqDebugOut(( infolevel | DEB_NOCOMPNAME, "All bits " )); break; case PRSomeBits: vqDebugOut(( infolevel | DEB_NOCOMPNAME, "Some bits " )); break; default: vqDebugOut(( infolevel | DEB_NOCOMPNAME, "??? " )); break; } if ( pir->Relation() & PRAll ) vqDebugOut(( infolevel | DEB_NOCOMPNAME, "All " )); else if ( pir->Relation() & PRAny ) vqDebugOut(( infolevel | DEB_NOCOMPNAME, "Any " )); } pir->Value().DisplayVariant(infolevel | DEB_NOCOMPNAME, 0); if ( pir->GetContentHelper() ) { vqDebugOut(( infolevel | DEB_NOCOMPNAME, "\n" )); for ( int i = 0; i < indent+5; i++ ) { vqDebugOut(( infolevel | DEB_NOCOMPNAME, " " )); } vqDebugOut(( infolevel | DEB_NOCOMPNAME, "HELPER:\n" )); Display( pir->GetContentHelper(), indent+3, infolevel ); } vqDebugOut(( infolevel | DEB_NOCOMPNAME, "\n" )); break; } case RTNot: vqDebugOut(( infolevel | DEB_NOCOMPNAME, "NOT\n" )); Display( ((CNotRestriction *)pRst)->GetChild(), indent + 1, infolevel ); break; case RTAnd: case RTOr: case RTProximity: case RTVector: case RTPhrase: { switch( pRst->Type() ) { case RTAnd: vqDebugOut(( infolevel | DEB_NOCOMPNAME, "AND\n" )); break; case RTOr: vqDebugOut(( infolevel | DEB_NOCOMPNAME, "OR\n" )); break; case RTNot: vqDebugOut(( infolevel | DEB_NOCOMPNAME, "NOT\n" )); break; case RTProximity: vqDebugOut(( infolevel | DEB_NOCOMPNAME, "PROXIMITY\n" )); break; case RTVector: vqDebugOut(( infolevel | DEB_NOCOMPNAME, "VECTOR " )); switch ( ((CVectorRestriction *)pRst)->RankMethod() ) { case VECTOR_RANK_MIN: vqDebugOut(( infolevel | DEB_NOCOMPNAME, "(Min)\n" )); break; case VECTOR_RANK_MAX: vqDebugOut(( infolevel | DEB_NOCOMPNAME, "(Max)\n" )); break; case VECTOR_RANK_INNER: vqDebugOut(( infolevel | DEB_NOCOMPNAME, "(Inner Product)\n" )); break; case VECTOR_RANK_DICE: vqDebugOut(( infolevel | DEB_NOCOMPNAME, "(Dice Coefficient)\n" )); break; case VECTOR_RANK_JACCARD: vqDebugOut(( infolevel | DEB_NOCOMPNAME, "(Jaccard Coefficient)\n" )); break; default: vqDebugOut(( infolevel | DEB_NOCOMPNAME, "(???)\n" )); break; } break; case RTPhrase: vqDebugOut(( infolevel | DEB_NOCOMPNAME, "PHRASE\n" )); break; } CNodeRestriction * pNodeRst = pRst->CastToNode(); for ( UINT i = 0; i < pNodeRst->Count(); i++ ) { Display( pNodeRst->GetChild( i ), indent + 1, infolevel ); } break; } case RTNone: vqDebugOut(( infolevel | DEB_NOCOMPNAME, "NONE -- empty\n" )); break; default: vqDebugOut(( infolevel | DEB_NOCOMPNAME, "UNKNOWN\n" )); break; } } #endif // CIDBG == 1