1168 lines
30 KiB
C++
1168 lines
30 KiB
C++
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1991 - 2000.
|
||
|
//
|
||
|
// File: Key.hxx
|
||
|
//
|
||
|
// Contents: Normalized key class
|
||
|
//
|
||
|
// Classes: CKey, CKeyBuf
|
||
|
//
|
||
|
// History: 29-Mar-91 BartoszM Created
|
||
|
//
|
||
|
// Notes: Key comparison is tricky. The global Compare function
|
||
|
// is the basis for key sorting. Searching may involve
|
||
|
// wildcard pidAll.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
#include <sstream.hxx>
|
||
|
#include <streams.hxx>
|
||
|
#include <bitoff.hxx>
|
||
|
|
||
|
// size of key prefix in bytes (STRING_KEY and VALUE_KEY)
|
||
|
const unsigned cbKeyPrefix = 1;
|
||
|
|
||
|
// maximum size of key (in bytes)
|
||
|
const unsigned MAXKEYSIZE = 128 + cbKeyPrefix;
|
||
|
const BYTE MAX_BYTE = 0xff;
|
||
|
|
||
|
// maximum size of key (in WCHARs)
|
||
|
const unsigned cwcMaxKey = (MAXKEYSIZE - cbKeyPrefix)/sizeof(WCHAR);
|
||
|
|
||
|
const BYTE STRING_KEY = 0;
|
||
|
const BYTE VALUE_KEY = 1;
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Class: CKey
|
||
|
//
|
||
|
// Purpose: Content index key. Used in data structures holding
|
||
|
// potentially large numbers of keys.
|
||
|
//
|
||
|
// History: 29-Mar-91 BartoszM Created
|
||
|
// 27-Oct-27 DwightKr Added Type() method
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
class CKey
|
||
|
{
|
||
|
friend class CKeyBuf;
|
||
|
public:
|
||
|
CKey () : cb(0), buf(0) {}
|
||
|
|
||
|
inline CKey ( const CKeyBuf& keyBuf );
|
||
|
inline CKey ( const CKey& key );
|
||
|
|
||
|
CKey ( CStream & stream ) { Init( stream ); }
|
||
|
inline ~CKey();
|
||
|
|
||
|
void Init() {
|
||
|
cb = 0;
|
||
|
buf = 0;
|
||
|
}
|
||
|
inline void Init( CStream & stream );
|
||
|
void Free()
|
||
|
{
|
||
|
delete buf;
|
||
|
buf = 0;
|
||
|
}
|
||
|
inline void operator= ( const CKey& key );
|
||
|
inline void operator= ( const CKeyBuf& keybuf );
|
||
|
|
||
|
BOOL IsMinKey() const { return 0 == cb && pidAll == pid; }
|
||
|
|
||
|
inline int Compare ( const CKey& key ) const;
|
||
|
inline int Compare ( const CKeyBuf& key ) const;
|
||
|
inline int CompareStr ( const CKeyBuf & key) const;
|
||
|
inline int CompareStr ( const CKey & key) const;
|
||
|
inline BOOL IsExactMatch ( const CKey& key ) const;
|
||
|
|
||
|
BYTE const* GetBuf() const { return buf; }
|
||
|
unsigned Count() const { return cb; }
|
||
|
|
||
|
PROPID Pid() const { return pid; }
|
||
|
void SetPid( PROPID newpid ) { pid = newpid; }
|
||
|
BOOL MatchPid ( const CKeyBuf& key ) const;
|
||
|
|
||
|
inline void FillMax ();
|
||
|
inline void FillMax ( const CKey& key );
|
||
|
inline void FillMin ();
|
||
|
inline void Serialize( CStream & stream ) const;
|
||
|
inline BOOL IsValue() const { return ( *buf != STRING_KEY ); }
|
||
|
inline BYTE Type() const { return *buf; }
|
||
|
|
||
|
inline void Acquire(CKey & key) {
|
||
|
Win4Assert(0 == buf);
|
||
|
|
||
|
cb = key.cb;
|
||
|
buf = key.buf;
|
||
|
pid = key.pid;
|
||
|
|
||
|
key.buf = 0;
|
||
|
key.cb = 0;
|
||
|
key.pid = 0;
|
||
|
}
|
||
|
//
|
||
|
// Serialization
|
||
|
//
|
||
|
|
||
|
inline void Marshall( PSerStream & stm ) const;
|
||
|
inline CKey( PDeSerStream & stm );
|
||
|
|
||
|
WCHAR* GetStr() const;
|
||
|
unsigned StrLen() const;
|
||
|
|
||
|
#ifdef CIEXTMODE
|
||
|
void CiExtDump(void *ciExtSelf);
|
||
|
#endif
|
||
|
|
||
|
private:
|
||
|
unsigned cb;
|
||
|
BYTE* buf;
|
||
|
PROPID pid;
|
||
|
};
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Class: CKeyBuf
|
||
|
//
|
||
|
// Purpose: Content index key buffer. Used for holding key data.
|
||
|
// It has a large fixed size buffer. Use sparingly.
|
||
|
//
|
||
|
// History: 29-Mar-91 BartoszM Created
|
||
|
// 27-Oct-27 DwightKr Added Type() method
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
class CKeyBuf
|
||
|
{
|
||
|
public:
|
||
|
inline CKeyBuf( PROPID pid, BYTE const * pb, unsigned cb );
|
||
|
|
||
|
inline CKeyBuf() : cb(0)
|
||
|
#if CIDBG == 1
|
||
|
, pid(0)
|
||
|
#endif // CIDBG == 1
|
||
|
{}
|
||
|
|
||
|
#if 0 // STACKSTACK
|
||
|
inline CKeyBuf(const CKey& key);
|
||
|
#endif
|
||
|
|
||
|
inline void operator=(const CKeyBuf & key);
|
||
|
inline void operator=(const CKey & key);
|
||
|
|
||
|
inline void FillMax();
|
||
|
inline void FillMin();
|
||
|
inline BOOL IsMaxKey() const;
|
||
|
inline BOOL IsMinKey() const;
|
||
|
|
||
|
inline int CompareStr ( const CKeyBuf & key) const;
|
||
|
inline int CompareStr ( const CKey & key) const;
|
||
|
inline int Compare ( const CKeyBuf& key ) const;
|
||
|
inline int Compare ( const CKey& key ) const;
|
||
|
|
||
|
inline BOOL IsPossibleRW();
|
||
|
|
||
|
BYTE const* GetBuf() const { return (BYTE *)buf; }
|
||
|
BYTE * GetWritableBuf() { return (BYTE *)buf; }
|
||
|
|
||
|
unsigned Count() const { return cb; }
|
||
|
unsigned * GetWritableCount() { return &cb; }
|
||
|
PROPID Pid() const { return pid; }
|
||
|
|
||
|
void SetCount(unsigned i) {cb = i;}
|
||
|
void SetPid ( PROPID pidNew ) {pid = pidNew;}
|
||
|
unsigned* GetCountAddress() {return(&cb);}
|
||
|
BOOL IsValue() const { return ( *buf != STRING_KEY ); }
|
||
|
BYTE Type() const { return *buf; }
|
||
|
|
||
|
|
||
|
WCHAR* GetStr() const;
|
||
|
unsigned StrLen() const;
|
||
|
|
||
|
#ifdef CIEXTMODE
|
||
|
void CiExtDump(void *ciExtSelf);
|
||
|
#endif
|
||
|
|
||
|
private:
|
||
|
unsigned cb;
|
||
|
BYTE buf[MAXKEYSIZE];
|
||
|
PROPID pid;
|
||
|
};
|
||
|
|
||
|
class SKeyBuf
|
||
|
{
|
||
|
public :
|
||
|
SKeyBuf(CKeyBuf * pKeyBuf) { _pKeyBuf = pKeyBuf;
|
||
|
}
|
||
|
~SKeyBuf() { delete _pKeyBuf; }
|
||
|
|
||
|
CKeyBuf * operator -> () { return _pKeyBuf; }
|
||
|
CKeyBuf & operator * () { return *_pKeyBuf; }
|
||
|
|
||
|
CKeyBuf * Acquire()
|
||
|
{ CKeyBuf * pTemp = _pKeyBuf; _pKeyBuf = 0; return pTemp; }
|
||
|
|
||
|
private:
|
||
|
CKeyBuf * _pKeyBuf;
|
||
|
};
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: Compare
|
||
|
//
|
||
|
// Synopsis: Compare two unsigned longs
|
||
|
//
|
||
|
// Arguments: [ul1] -- first ulong
|
||
|
// [ul2] -- second ulong
|
||
|
//
|
||
|
// Returns: "difference" ul1 - ul2
|
||
|
//
|
||
|
// History: 07-May-91 BartoszM Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
inline int Compare ( ULONG u1, ULONG u2 )
|
||
|
{
|
||
|
return ( u1 > u2 )? 1 : (( u1 < u2 )? -1: 0);
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Class: CDirectoryKey
|
||
|
//
|
||
|
// Purpose: Key class for use in the (downlevel) directory
|
||
|
//
|
||
|
// History: 3-May-95 dlee created
|
||
|
//
|
||
|
// Notes: Directory keys look like this:
|
||
|
//
|
||
|
// cb of the key (2 bytes)
|
||
|
// BitOffset (8 bytes)
|
||
|
// PROPID (4 bytes)
|
||
|
// the key (cb bytes)
|
||
|
//
|
||
|
// There are no alignment constraints on any of the fields.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
#include <pshpack1.h>
|
||
|
|
||
|
const BYTE pidIdMaxSmallPid = 0x40; // 1-byte pids > this are 4096-based
|
||
|
const ULONG pidNewPidBase = INIT_DOWNLEVEL_PID; // base of CI's new pids
|
||
|
|
||
|
class CDirectoryKey
|
||
|
{
|
||
|
public:
|
||
|
void * operator new( size_t size, void *pv ) { return pv; }
|
||
|
void operator delete( void * p ) {}
|
||
|
|
||
|
unsigned Count()
|
||
|
{
|
||
|
return (unsigned) _cbKey;
|
||
|
}
|
||
|
|
||
|
BYTE * Key()
|
||
|
{
|
||
|
Win4Assert( 0 != this );
|
||
|
return (BYTE *) ( this + 1 ) + ExtraPropIdSize();
|
||
|
}
|
||
|
|
||
|
PROPID PropId()
|
||
|
{
|
||
|
Win4Assert( 0 != this );
|
||
|
|
||
|
if ( 0 == _bPropId )
|
||
|
return * (UNALIGNED PROPID *) ( this + 1 );
|
||
|
|
||
|
if ( _bPropId > pidIdMaxSmallPid )
|
||
|
return (PROPID) _bPropId - pidIdMaxSmallPid + pidNewPidBase - 1;
|
||
|
|
||
|
return (PROPID) _bPropId;
|
||
|
}
|
||
|
|
||
|
void PropId( PROPID & pid )
|
||
|
{
|
||
|
pid = PropId();
|
||
|
}
|
||
|
|
||
|
void Offset( BitOffset & offset )
|
||
|
{
|
||
|
Win4Assert( 0 != this );
|
||
|
offset.SetPage( * (UNALIGNED ULONG *) &_oPage );
|
||
|
offset.SetOff( * (UNALIGNED USHORT *) &_oBit );
|
||
|
}
|
||
|
|
||
|
void Write( BYTE cbKey,
|
||
|
BitOffset bitOffset,
|
||
|
PROPID pid,
|
||
|
const BYTE * buf )
|
||
|
{
|
||
|
* (UNALIGNED ULONG *) &_oPage = bitOffset.Page();
|
||
|
Win4Assert( bitOffset.Offset() <= 0xffff );
|
||
|
* (UNALIGNED USHORT *) &_oBit = (USHORT) bitOffset.Offset();
|
||
|
|
||
|
BYTE * pbKey = (BYTE *) (this + 1);
|
||
|
|
||
|
if ( pid <= pidIdMaxSmallPid )
|
||
|
{
|
||
|
_bPropId = (BYTE) pid;
|
||
|
}
|
||
|
else if ( ( pid >= pidNewPidBase ) &&
|
||
|
( pid < ( pidNewPidBase + 0xfd - pidIdMaxSmallPid ) ) )
|
||
|
{
|
||
|
_bPropId = (BYTE) ( pid - pidNewPidBase + pidIdMaxSmallPid + 1 );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
_bPropId = 0;
|
||
|
RtlCopyMemory( pbKey, &pid, sizeof ULONG );
|
||
|
pbKey += sizeof ULONG;
|
||
|
}
|
||
|
|
||
|
_cbKey = cbKey;
|
||
|
|
||
|
RtlCopyMemory( pbKey, buf, cbKey );
|
||
|
}
|
||
|
|
||
|
unsigned Size()
|
||
|
{
|
||
|
return sizeof CDirectoryKey + ExtraPropIdSize() + Count();
|
||
|
}
|
||
|
|
||
|
static unsigned ComputeSize( BYTE cbKey, PROPID pid )
|
||
|
{
|
||
|
unsigned cbPid = 0;
|
||
|
if ( ! ( ( pid <= pidIdMaxSmallPid ) ||
|
||
|
( ( pid >= pidNewPidBase ) &&
|
||
|
( pid < ( pidNewPidBase + 0xfd - pidIdMaxSmallPid ) ) ) ) )
|
||
|
cbPid = sizeof ULONG;
|
||
|
|
||
|
return sizeof CDirectoryKey + cbPid + cbKey;
|
||
|
}
|
||
|
|
||
|
CDirectoryKey * NextKey()
|
||
|
{
|
||
|
Win4Assert( 0 != this );
|
||
|
return (CDirectoryKey *) ( (BYTE *) this + Size() );
|
||
|
}
|
||
|
|
||
|
BOOL IsGreaterThanKeyBuf( const CKeyBuf & key )
|
||
|
{
|
||
|
// return TRUE if "this" is greater than key
|
||
|
|
||
|
Win4Assert( 0 != this );
|
||
|
Win4Assert( 0 != &key );
|
||
|
Win4Assert( pidAll != PropId() );
|
||
|
|
||
|
unsigned count = Count();
|
||
|
unsigned long mincb = __min( count, key.Count() );
|
||
|
int diff = memcmp( Key(), key.GetBuf(), mincb );
|
||
|
|
||
|
if ( 0 == diff )
|
||
|
{
|
||
|
diff = count - key.Count();
|
||
|
if ( 0 == diff )
|
||
|
{
|
||
|
diff = ::Compare( PropId(), key.Pid() );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return diff > 0;
|
||
|
}
|
||
|
|
||
|
void MakeKeyBuf( CKeyBuf & keyBuf )
|
||
|
{
|
||
|
// copy the count and key
|
||
|
|
||
|
unsigned cbKey = Count();
|
||
|
keyBuf.SetCount( cbKey );
|
||
|
|
||
|
RtlCopyMemory( keyBuf.GetWritableBuf(),
|
||
|
Key(),
|
||
|
cbKey );
|
||
|
|
||
|
// copy the pid
|
||
|
|
||
|
keyBuf.SetPid( PropId() );
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
unsigned ExtraPropIdSize()
|
||
|
{
|
||
|
return ( 0 == _bPropId ) ? sizeof ULONG : 0;
|
||
|
}
|
||
|
|
||
|
ULONG _oPage; // page number
|
||
|
USHORT _oBit; // bit offset in the page
|
||
|
BYTE _bPropId; // Byte form of propid, or 0 if it won't fit
|
||
|
BYTE _cbKey; // Byte count of the key following
|
||
|
};
|
||
|
|
||
|
#include <poppack.h>
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CKey::~Ckey
|
||
|
//
|
||
|
// Synopsis: Free memory
|
||
|
//
|
||
|
// History: 07-May-91 BartoszM Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
inline CKey::~CKey()
|
||
|
{
|
||
|
delete buf;
|
||
|
}
|
||
|
|
||
|
inline void CKey::Marshall( PSerStream & stm ) const
|
||
|
{
|
||
|
stm.PutULong( pid );
|
||
|
stm.PutULong( cb );
|
||
|
stm.PutBlob( buf, cb );
|
||
|
}
|
||
|
|
||
|
inline CKey::CKey( PDeSerStream & stm )
|
||
|
: buf(0)
|
||
|
{
|
||
|
pid = stm.GetULong();
|
||
|
cb = stm.GetULong();
|
||
|
|
||
|
// Guard against attack
|
||
|
|
||
|
if ( cb >= 65536 )
|
||
|
THROW( CException( E_INVALIDARG ) );
|
||
|
|
||
|
buf = new BYTE[cb];
|
||
|
stm.GetBlob( buf, cb );
|
||
|
}
|
||
|
|
||
|
inline void CKey::Init( CStream & stream )
|
||
|
{
|
||
|
stream.Read( &cb, sizeof( cb ) );
|
||
|
buf = new BYTE[cb];
|
||
|
stream.Read( buf, sizeof( buf[0] ) * cb );
|
||
|
stream.Read( &pid, sizeof( pid ) );
|
||
|
}
|
||
|
|
||
|
inline void CKey::Serialize( CStream & stream ) const
|
||
|
{
|
||
|
stream.Write( &cb, sizeof( cb ) );
|
||
|
stream.Write( buf, sizeof( buf[0] ) * cb );
|
||
|
stream.Write( &pid, sizeof( pid ) );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CKey::FillMax
|
||
|
//
|
||
|
// Synopsis: Makes a max key, greater or equal to any key.
|
||
|
//
|
||
|
// History: 07-May-91 BartoszM Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
inline void CKey::FillMax ()
|
||
|
{
|
||
|
Win4Assert ( pidInvalid == 0xffffffff );
|
||
|
pid = pidInvalid;
|
||
|
cb = MAXKEYSIZE;
|
||
|
Win4Assert ( buf == 0 );
|
||
|
buf = new BYTE[MAXKEYSIZE];
|
||
|
memset( buf, MAX_BYTE, MAXKEYSIZE);
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CKey::FillMax
|
||
|
//
|
||
|
// Synopsis: Treats [key] as a prefix. Creates a key that is greater
|
||
|
// than any other key with the same prefix.
|
||
|
// Used for end of range
|
||
|
//
|
||
|
// Arguments: [key] -- prefix
|
||
|
//
|
||
|
// History: 07-May-91 BartoszM Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
inline void CKey::FillMax ( const CKey& key )
|
||
|
{
|
||
|
Win4Assert ( &key != 0 );
|
||
|
Win4Assert ( this != 0 );
|
||
|
buf = new BYTE[MAXKEYSIZE];
|
||
|
cb = MAXKEYSIZE;
|
||
|
pid = key.Pid();
|
||
|
memcpy ( buf, key.GetBuf(), key.Count());
|
||
|
memset ( buf + key.Count(), MAX_BYTE, MAXKEYSIZE - key.Count() );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CKey::FillMin
|
||
|
//
|
||
|
// Synopsis: Creates a minimum key
|
||
|
//
|
||
|
// History: 07-May-91 BartoszM Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
inline void CKey::FillMin()
|
||
|
{
|
||
|
cb = 0;
|
||
|
pid = 0;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CKey::CKey
|
||
|
//
|
||
|
// Synopsis: Creates CKey based on CKeyBuf
|
||
|
//
|
||
|
// Arguments: [keybuf] -- original
|
||
|
//
|
||
|
// History: 07-May-91 BartoszM Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
inline CKey::CKey ( const CKeyBuf& keybuf )
|
||
|
: buf(0)
|
||
|
{
|
||
|
Win4Assert ( &keybuf != 0 );
|
||
|
Win4Assert ( this != 0 );
|
||
|
cb = keybuf.Count();
|
||
|
pid = keybuf.Pid();
|
||
|
buf = new BYTE [cb];
|
||
|
memcpy ( buf, keybuf.GetBuf(), cb );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CKey::CKey
|
||
|
//
|
||
|
// Synopsis: Copy constructor
|
||
|
//
|
||
|
// Arguments: [keySrc] -- original
|
||
|
//
|
||
|
// History: 07-May-91 BartoszM Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
inline CKey::CKey ( const CKey& keySrc )
|
||
|
: buf(0)
|
||
|
{
|
||
|
Win4Assert ( &keySrc != 0 );
|
||
|
Win4Assert ( this != 0 );
|
||
|
cb = keySrc.cb;
|
||
|
pid = keySrc.pid;
|
||
|
buf = new BYTE [cb];
|
||
|
memcpy ( buf, keySrc.buf, cb );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CKey::operator=
|
||
|
//
|
||
|
// Synopsis: Creates CKey based on CKeyBuf
|
||
|
//
|
||
|
// Arguments: [keybuf] -- original
|
||
|
//
|
||
|
// History: 07-May-91 BartoszM Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
inline void CKey::operator= ( const CKeyBuf& keybuf )
|
||
|
{
|
||
|
Win4Assert ( &keybuf != 0 );
|
||
|
Win4Assert ( this != 0 );
|
||
|
cb = keybuf.Count();
|
||
|
pid = keybuf.Pid();
|
||
|
Win4Assert ( buf == 0 );
|
||
|
buf = new BYTE [cb];
|
||
|
memcpy ( buf, keybuf.GetBuf(), cb );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CKey::operator=
|
||
|
//
|
||
|
// Synopsis: Creates CKey based on another CKey
|
||
|
//
|
||
|
// Arguments: [key] -- original
|
||
|
//
|
||
|
// History: 07-May-91 BartoszM Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
inline void CKey::operator= ( const CKey& key )
|
||
|
{
|
||
|
Win4Assert ( &key != 0 );
|
||
|
Win4Assert ( this != 0 );
|
||
|
cb = key.cb;
|
||
|
pid = key.pid;
|
||
|
Win4Assert ( buf == 0 );
|
||
|
buf = new BYTE [cb];
|
||
|
memcpy ( buf, key.buf, cb );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CKey::MatchPid
|
||
|
//
|
||
|
// Synopsis: Compares pids, "this" may have wildcard pidAll
|
||
|
//
|
||
|
// Arguments: [key] -- the other key (not pidAll)
|
||
|
//
|
||
|
// History: 29-Nov-94 BartoszM Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
inline BOOL CKey::MatchPid ( const CKeyBuf& key ) const
|
||
|
{
|
||
|
Win4Assert (key.Pid() != pidAll);
|
||
|
return ( Pid() == pidAll && key.Pid() != pidRevName ) || Pid() == key.Pid();
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: Compare
|
||
|
//
|
||
|
// Synopsis: Compare two keys
|
||
|
//
|
||
|
// Arguments: [key1] -- first key
|
||
|
// [key2] -- second key
|
||
|
//
|
||
|
// Returns: "difference" key1 - key2
|
||
|
//
|
||
|
// Requires: key1 != NULL && key2 != NULL
|
||
|
//
|
||
|
// History: 06-May-91 BartoszM Created
|
||
|
//
|
||
|
// Notice: No wildcard pidAll allowed
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
inline int Compare ( const CKeyBuf* key1, const CKeyBuf* key2 )
|
||
|
{
|
||
|
Win4Assert ( key1 != 0 );
|
||
|
Win4Assert ( key2 != 0 );
|
||
|
Win4Assert ( key1->Pid() != pidAll );
|
||
|
Win4Assert ( key2->Pid() != pidAll );
|
||
|
|
||
|
int result;
|
||
|
unsigned long mincb = __min(key1->Count(), key2->Count());
|
||
|
|
||
|
result = memcmp(key1->GetBuf(), key2->GetBuf(), mincb);
|
||
|
|
||
|
if (result == 0)
|
||
|
{
|
||
|
result = key1->Count() - key2->Count();
|
||
|
if ( result == 0 )
|
||
|
result = Compare ( key1->Pid(), key2->Pid() );
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: AreEqual
|
||
|
//
|
||
|
// Synopsis: Compare two keys for equality. Early exit when lengths differ
|
||
|
//
|
||
|
// Arguments: [key1] -- first key
|
||
|
// [key2] -- second key
|
||
|
//
|
||
|
// Returns: TRUE when equal
|
||
|
//
|
||
|
// Requires: key1 != NULL && key2 != NULL
|
||
|
//
|
||
|
// History: 06-May-91 BartoszM Created
|
||
|
//
|
||
|
// Notice: No wildcard pidAll allowed
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
inline BOOL AreEqual ( const CKeyBuf* key1, const CKeyBuf* key2 )
|
||
|
{
|
||
|
Win4Assert ( key1 != 0 );
|
||
|
Win4Assert ( key2 != 0 );
|
||
|
Win4Assert ( key1->Pid() != pidAll );
|
||
|
Win4Assert ( key2->Pid() != pidAll );
|
||
|
|
||
|
unsigned len = key1->Count();
|
||
|
|
||
|
if (key2->Count() != len)
|
||
|
return(FALSE);
|
||
|
|
||
|
if ( memcmp(key1->GetBuf(), key2->GetBuf(), len) != 0 )
|
||
|
return(FALSE);
|
||
|
|
||
|
return ( key1->Pid() == key2->Pid() );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: AreEqualStr
|
||
|
//
|
||
|
// Synopsis: Compare two keys for equality of buffers (disregard PID).
|
||
|
// Early exit when lengths differ
|
||
|
//
|
||
|
// Arguments: [key1] -- first key
|
||
|
// [key2] -- second key
|
||
|
//
|
||
|
// Returns: TRUE when equal
|
||
|
//
|
||
|
// Requires: key1 != NULL && key2 != NULL
|
||
|
//
|
||
|
// History: 06-May-91 BartoszM Created
|
||
|
//
|
||
|
// Notice: No wildcard pidAll allowed
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
inline BOOL AreEqualStr ( const CKeyBuf* key1, const CKeyBuf* key2 )
|
||
|
{
|
||
|
Win4Assert ( key1 != 0 );
|
||
|
Win4Assert ( key2 != 0 );
|
||
|
Win4Assert ( key1->Pid() != pidAll );
|
||
|
Win4Assert ( key2->Pid() != pidAll );
|
||
|
|
||
|
unsigned len = key1->Count();
|
||
|
|
||
|
if (key2->Count() != len)
|
||
|
return(FALSE);
|
||
|
|
||
|
return memcmp(key1->GetBuf(), key2->GetBuf(), len) == 0;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CKey::Compare
|
||
|
//
|
||
|
// Synopsis: Compare this with another key
|
||
|
//
|
||
|
// Arguments: [key] -- key to compare with
|
||
|
//
|
||
|
// Returns: "difference" this - key
|
||
|
// this key can have wildcard pidAll
|
||
|
// but it will be treated like any other pid
|
||
|
//
|
||
|
// Requires: [key]'s pid cannot be pidAll
|
||
|
//
|
||
|
// History: 14-Sep-92 BartoszM Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
inline int CKey::Compare( const CKey & key) const
|
||
|
{
|
||
|
Win4Assert ( this != 0 );
|
||
|
Win4Assert ( &key != 0 );
|
||
|
Win4Assert ( key.Pid() != pidAll );
|
||
|
|
||
|
unsigned long mincb = __min(cb, key.Count());
|
||
|
int diff = memcmp(buf, key.GetBuf(), mincb);
|
||
|
if (diff == 0)
|
||
|
{ // this->buf == key.buf
|
||
|
diff = cb - key.Count();
|
||
|
if (diff == 0)
|
||
|
{
|
||
|
diff = ::Compare ( pid, key.Pid());
|
||
|
}
|
||
|
}
|
||
|
return(diff);
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CKey::Compare
|
||
|
//
|
||
|
// Synopsis: Compare this with another key
|
||
|
//
|
||
|
// Arguments: [key] -- key to compare with
|
||
|
//
|
||
|
// Returns: "difference" this - key
|
||
|
// this key can have wildcard pidAll
|
||
|
// but it will be treated like any other pid
|
||
|
//
|
||
|
// Requires: [key]'s pid cannot be pidAll
|
||
|
//
|
||
|
// History: 14-Sep-92 BartoszM Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
inline int CKey::Compare( const CKeyBuf & key) const
|
||
|
{
|
||
|
Win4Assert ( this != 0 );
|
||
|
Win4Assert ( &key != 0 );
|
||
|
Win4Assert ( key.Pid() != pidAll );
|
||
|
|
||
|
unsigned long mincb = __min(cb, key.Count());
|
||
|
int diff = memcmp(buf, key.GetBuf(), mincb);
|
||
|
if (diff == 0)
|
||
|
{ // this->buf == key.buf
|
||
|
diff = cb - key.Count();
|
||
|
if (diff == 0)
|
||
|
{
|
||
|
diff = ::Compare ( pid, key.Pid());
|
||
|
}
|
||
|
}
|
||
|
return(diff);
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CKey::CompareStr
|
||
|
//
|
||
|
// Synopsis: Compare this with another key ignoring pid
|
||
|
//
|
||
|
// Arguments: [key] -- key to compare with
|
||
|
//
|
||
|
// Returns: "difference" this - key
|
||
|
//
|
||
|
// History: 14-Sep-92 BartoszM Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
inline int CKey::CompareStr( const CKeyBuf & key) const
|
||
|
{
|
||
|
Win4Assert ( this != 0 );
|
||
|
Win4Assert ( &key != 0 );
|
||
|
|
||
|
unsigned long mincb = __min(cb, key.Count());
|
||
|
int diff = memcmp(buf, key.GetBuf(), mincb);
|
||
|
if (diff == 0)
|
||
|
{ // this->buf == key.buf
|
||
|
diff = cb - key.Count();
|
||
|
}
|
||
|
return(diff);
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CKey::CompareStr
|
||
|
//
|
||
|
// Synopsis: Compare this with another key ignoring pid
|
||
|
//
|
||
|
// Arguments: [key] -- key to compare with
|
||
|
//
|
||
|
// Returns: "difference" this - key
|
||
|
//
|
||
|
// History: 14-Sep-92 BartoszM Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
inline int CKeyBuf::CompareStr( const CKey & key) const
|
||
|
{
|
||
|
Win4Assert ( this != 0 );
|
||
|
Win4Assert ( &key != 0 );
|
||
|
|
||
|
unsigned long mincb = __min(cb, key.Count());
|
||
|
int diff = memcmp(buf, key.GetBuf(), mincb);
|
||
|
if (diff == 0)
|
||
|
{ // this->buf == key.buf
|
||
|
diff = cb - key.Count();
|
||
|
}
|
||
|
return(diff);
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CKey::CompareStr
|
||
|
//
|
||
|
// Synopsis: Compare this with another key ignoring pid
|
||
|
//
|
||
|
// Arguments: [key] -- key to compare with
|
||
|
//
|
||
|
// Returns: "difference" this - key
|
||
|
//
|
||
|
// History: 14-Sep-92 BartoszM Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
inline int CKey::CompareStr( const CKey & key) const
|
||
|
{
|
||
|
Win4Assert ( this != 0 );
|
||
|
Win4Assert ( &key != 0 );
|
||
|
|
||
|
unsigned long mincb = __min(cb, key.Count());
|
||
|
int diff = memcmp(buf, key.GetBuf(), mincb);
|
||
|
if (diff == 0)
|
||
|
{ // this->buf == key.buf
|
||
|
diff = cb - key.Count();
|
||
|
}
|
||
|
return(diff);
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Method: IsExactMatch
|
||
|
//
|
||
|
// Synopsis: Compare for exact equality. Early exit when lengths differ
|
||
|
//
|
||
|
// Arguments: [key] -- key to compare with
|
||
|
//
|
||
|
// Returns: TRUE when equal
|
||
|
//
|
||
|
// Requires: key1 != NULL && key2 != NULL
|
||
|
//
|
||
|
// History: 06-Oct-94 BartoszM Created
|
||
|
//
|
||
|
// Notice: pidAll allowed in both. Use to compare keys in query
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
inline BOOL CKey::IsExactMatch ( const CKey& key ) const
|
||
|
{
|
||
|
Win4Assert (this != 0);
|
||
|
Win4Assert (&key != 0);
|
||
|
|
||
|
return cb == key.Count()
|
||
|
&& pid == key.Pid()
|
||
|
&& memcmp(buf, key.GetBuf(), cb) == 0;
|
||
|
}
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CKeyBuf::IsPossibleRW, public
|
||
|
//
|
||
|
// Synopsis: Determine whether a word can be a relevant word or not.
|
||
|
//
|
||
|
// Returns: TRUE if no digits and > 2 characters long
|
||
|
//
|
||
|
// Notes: All of these characters are deemed 'digits' by Win32
|
||
|
//
|
||
|
// History: 6-May-94 v-dlee Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
#define _IsADigit(x) (((x) >= 0x30 && (x) <= 0x39) || \
|
||
|
((x) >= 0xb2 && (x) <= 0xb3) || \
|
||
|
((x) == 0xb9) || \
|
||
|
((x) >= 0x660 && (x) <= 0x669) || \
|
||
|
((x) >= 0x6f0 && (x) <= 0x6f9) || \
|
||
|
((x) >= 0x966 && (x) <= 0x96f) || \
|
||
|
((x) >= 0x9e6 && (x) <= 0x9ef) || \
|
||
|
((x) >= 0xa66 && (x) <= 0xa6f) || \
|
||
|
((x) >= 0xae6 && (x) <= 0xaef) || \
|
||
|
((x) >= 0xb66 && (x) <= 0xb6f) || \
|
||
|
((x) >= 0xbe7 && (x) <= 0xbef) || \
|
||
|
((x) >= 0xbf0 && (x) <= 0xbf2) || \
|
||
|
((x) >= 0xc66 && (x) <= 0xc6f) || \
|
||
|
((x) >= 0xce6 && (x) <= 0xcef) || \
|
||
|
((x) >= 0xd66 && (x) <= 0xd6f) || \
|
||
|
((x) >= 0xe50 && (x) <= 0xe59) || \
|
||
|
((x) >= 0xed0 && (x) <= 0xed9) || \
|
||
|
((x) >= 0x1040 && (x) <= 0x1049) || \
|
||
|
((x) == 0x2070) || \
|
||
|
((x) >= 0x2074 && (x) <= 0x2079) || \
|
||
|
((x) >= 0x2080 && (x) <= 0x2089) || \
|
||
|
((x) >= 0xff10 && (x) <= 0xff19))
|
||
|
|
||
|
|
||
|
inline BOOL CKeyBuf::IsPossibleRW()
|
||
|
{
|
||
|
unsigned uCount = Count();
|
||
|
|
||
|
if (uCount > (1 + 2 * sizeof(WCHAR)))
|
||
|
{
|
||
|
const BYTE * p = (BYTE *) &buf;
|
||
|
p++;
|
||
|
for (unsigned c = 0; c < uCount; c += 2, p += 2)
|
||
|
{
|
||
|
WCHAR wc = MAKEWORD(*(p + 1),*p);
|
||
|
if (_IsADigit(wc))
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else return FALSE;
|
||
|
|
||
|
return TRUE;
|
||
|
} //IsPossibleRW
|
||
|
|
||
|
inline CKeyBuf::CKeyBuf( PROPID p, BYTE const * pb, unsigned count )
|
||
|
: pid( p ),
|
||
|
cb( count )
|
||
|
{
|
||
|
memcpy( buf, pb, count );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CKeyBuf::operator=, public
|
||
|
//
|
||
|
// Synopsis: Assignment operator
|
||
|
//
|
||
|
// Arguments: [key] -- CKeyBuf to assign to this.
|
||
|
//
|
||
|
// History: 26-Jun-91 KyleP Created.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
inline void CKeyBuf::operator=(const CKeyBuf & key)
|
||
|
{
|
||
|
cb = key.Count();
|
||
|
pid = key.Pid();
|
||
|
memcpy(buf, key.GetBuf(), cb);
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CKeyBuf::CKeyBuf, public
|
||
|
//
|
||
|
// Synopsis: Assignment operator
|
||
|
//
|
||
|
// Arguments: [key] -- CKeyBuf to assign to this.
|
||
|
//
|
||
|
// History: 26-Jun-91 KyleP Created.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
#if 0 //STACKSTACK
|
||
|
inline CKeyBuf::CKeyBuf(const CKey& key)
|
||
|
{
|
||
|
*this = key;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
inline void CKeyBuf::operator=( const CKey& key)
|
||
|
{
|
||
|
Win4Assert( key.Count() <= MAXKEYSIZE );
|
||
|
cb = key.Count();
|
||
|
pid = key.Pid();
|
||
|
memcpy(buf, key.GetBuf(), cb);
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CKeyBuf::FillMax
|
||
|
//
|
||
|
// Synopsis: Makes a max key, greater or equal to any key.
|
||
|
//
|
||
|
// History: 07-May-91 BartoszM Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
inline void CKeyBuf::FillMax ()
|
||
|
{
|
||
|
Win4Assert ( pidInvalid == 0xffffffff );
|
||
|
pid = pidInvalid;
|
||
|
cb = MAXKEYSIZE;
|
||
|
memset( buf, MAX_BYTE, MAXKEYSIZE);
|
||
|
}
|
||
|
|
||
|
inline void CKeyBuf::FillMin()
|
||
|
{
|
||
|
cb = 0;
|
||
|
pid = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CKeyBuf::IsMaxKey
|
||
|
//
|
||
|
// Synopsis: Returns TRUE if this is the maximum possible key
|
||
|
//
|
||
|
// History: 07-May-91 BartoszM Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
inline BOOL CKeyBuf::IsMaxKey() const
|
||
|
{
|
||
|
|
||
|
if (cb == MAXKEYSIZE)
|
||
|
{
|
||
|
for(unsigned n = 0; n < MAXKEYSIZE; n++)
|
||
|
{
|
||
|
if (buf[n] != MAX_BYTE)
|
||
|
{
|
||
|
return(FALSE);
|
||
|
}
|
||
|
}
|
||
|
return(TRUE);
|
||
|
}
|
||
|
else
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
inline BOOL CKeyBuf::IsMinKey() const
|
||
|
{
|
||
|
return ( 0 == cb ) && ( 0 == pid );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CKeyBuf::CompareStr
|
||
|
//
|
||
|
// Synopsis: Compare this with another key ignoring pid
|
||
|
//
|
||
|
// Arguments: [key] -- key to compare with
|
||
|
//
|
||
|
// Returns: "difference" this - key
|
||
|
//
|
||
|
// History: 14-Sep-92 BartoszM Created
|
||
|
// 15-Dec-93 w-PatG Stolen from CKey
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
inline int CKeyBuf::CompareStr( const CKeyBuf & key) const
|
||
|
{
|
||
|
Win4Assert ( this != 0 );
|
||
|
Win4Assert ( &key != 0 );
|
||
|
|
||
|
unsigned long mincb = __min(cb, key.Count());
|
||
|
int diff = memcmp(buf, key.GetBuf(), mincb);
|
||
|
if (diff == 0)
|
||
|
{ // this->buf == key.buf
|
||
|
diff = cb - key.Count();
|
||
|
}
|
||
|
return(diff);
|
||
|
}
|
||
|
|
||
|
inline int CKeyBuf::Compare( const CKeyBuf & key) const
|
||
|
{
|
||
|
Win4Assert ( this != 0 );
|
||
|
Win4Assert ( &key != 0 );
|
||
|
Win4Assert ( key.Pid() != pidAll );
|
||
|
|
||
|
unsigned long mincb = __min(cb, key.Count());
|
||
|
int diff = memcmp(buf, key.GetBuf(), mincb);
|
||
|
if (diff == 0)
|
||
|
{ // this->buf == key.buf
|
||
|
diff = cb - key.Count();
|
||
|
if (diff == 0)
|
||
|
{
|
||
|
diff = ::Compare ( pid, key.Pid());
|
||
|
}
|
||
|
}
|
||
|
return(diff);
|
||
|
}
|
||
|
|
||
|
|
||
|
inline int CKeyBuf::Compare( const CKey & key) const
|
||
|
{
|
||
|
Win4Assert ( this != 0 );
|
||
|
Win4Assert ( &key != 0 );
|
||
|
Win4Assert ( key.Pid() != pidAll );
|
||
|
|
||
|
unsigned long mincb = __min(cb, key.Count());
|
||
|
int diff = memcmp(buf, key.GetBuf(), mincb);
|
||
|
if (diff == 0)
|
||
|
{ // this->buf == key.buf
|
||
|
diff = cb - key.Count();
|
||
|
if (diff == 0)
|
||
|
{
|
||
|
diff = ::Compare ( pid, key.Pid());
|
||
|
}
|
||
|
}
|
||
|
return(diff);
|
||
|
}
|
||
|
|