|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1991 - 2000.
//
// File: XlatStat.cxx
//
// Contents: State translation class.
//
// Classes: CXlatState
//
// History: 01-20-92 KyleP Created
//
//--------------------------------------------------------------------------
#include <pch.cxx>
#pragma hdrstop
#include <xlatstat.hxx>
#include "stateset.hxx"
//+-------------------------------------------------------------------------
//
// Member: CXlatState::CXlatState, public
//
// Synopsis: Initialize state translator (no states)
//
// Arguments: [MaxState] -- Largest ordinal of any state that may
// appear in an equivalence class.
//
// History: 20-Jan-92 KyleP Created
//
//--------------------------------------------------------------------------
CXlatState::CXlatState( UINT MaxState ) : _cUsed( 0 ), _pulStates( 0 ), _cStates( 0 ) { //
// Compute the number of DWords / state, assuring at least 1 dword is
// always allocated.
//
_StateSize = (MaxState + sizeof(ULONG) * 8 ) / (sizeof( ULONG ) * 8); _Realloc(); };
//+-------------------------------------------------------------------------
//
// Member: CXlatState::~CXlatState, public
//
// Synopsis: Destroys class.
//
// History: 20-Jan-92 KyleP Created
//
//--------------------------------------------------------------------------
CXlatState::~CXlatState() { delete _pulStates; }
//+-------------------------------------------------------------------------
//
// Member: CXlatState::XlatToOne, public
//
// Synopsis: Maps a state set to its single state equivalent. If
// there is no mapping, then one is created.
//
// Arguments: [ss] -- State set to search for.
//
// Returns: The single state equivalent.
//
// History: 20-Jun-92 KyleP Created
//
//--------------------------------------------------------------------------
UINT CXlatState::XlatToOne( CStateSet const & ss ) { UINT state = _Search( ss );
if ( state == 0 ) { state = _Create( ss ); }
return( state ); }
//+-------------------------------------------------------------------------
//
// Member: CXlatState::XlatToMany, public
//
// Synopsis: Maps a state to its matching state set.
//
// Arguments: [iState] -- State to map.
// [ss] -- On return contains the mapped state set.
//
// History: 20-Jan-92 KyleP Created
//
//--------------------------------------------------------------------------
void CXlatState::XlatToMany( UINT iState, CStateSet & ss ) { if ( iState > _cUsed ) { vqAssert( FALSE ); return; // Don't know about this state.
}
ULONG * pState = _pulStates + iState * _StateSize;
for ( int i = _StateSize * sizeof(ULONG) * 8 - 1; i >= 0; i-- ) { if ( pState[i / (sizeof(ULONG) * 8) ] & ( 1L << i % (sizeof(ULONG) * 8 ) ) ) { ss.Add( i+1 ); } } }
//+-------------------------------------------------------------------------
//
// Member: CXlatState::_Search, private
//
// Arguments: [ss] -- State set to search for.
//
// Returns: Single state mapping for [ss] or 0 if none.
//
// History: 20-Jan-92 KyleP Created
//
// Notes: The first state set is used as temp space.
//
//--------------------------------------------------------------------------
UINT CXlatState::_Search( CStateSet const & ss ) { memset( _pulStates, 0, _StateSize * sizeof(ULONG) ); _BuildState( _pulStates, ss );
UINT cState = 1;
while ( cState <= _cUsed ) { if ( memcmp( _pulStates + cState * _StateSize, _pulStates, _StateSize * sizeof(ULONG) ) == 0 ) { return( cState ); } else { ++cState; } }
return( 0 ); }
//+-------------------------------------------------------------------------
//
// Member: CXlatState::_Create, private
//
// Synopsis: Adds new state set to array.
//
// Arguments: [ss] -- State set to add.
//
// Returns: Single state mapping for [ss]
//
// History: 20-Jan-92 KyleP Created
//
//--------------------------------------------------------------------------
UINT CXlatState::_Create( CStateSet const & ss ) { //
// _cStates-1 because the first state is temp space.
//
if ( _cStates-1 == _cUsed ) _Realloc();
++_cUsed; _BuildState( _pulStates + _cUsed * _StateSize, ss );
return( _cUsed ); }
//+-------------------------------------------------------------------------
//
// Member: CXlatState::_BuildState, private
//
// Synopsis: Formats state set.
//
// Arguments: [ss] -- Format state set...
// [pState] -- into this memory.
//
// History: 20-Jan-92 KyleP Created
//
//--------------------------------------------------------------------------
void CXlatState::_BuildState( ULONG * pState, CStateSet const & ss ) { for ( UINT i = ss.Count(); i > 0; i-- ) { UINT StateNum = ss.State( i ) - 1; pState[ StateNum / (sizeof(ULONG) * 8) ] |= 1L << StateNum % (sizeof(ULONG) * 8); }
}
//+-------------------------------------------------------------------------
//
// Member: CXlatState::_Realloc, private
//
// Synopsis: Grows state set array.
//
// History: 20-Jan-92 KyleP Created
//
// Notes: Grows linearly, since the number of state sets is likely
// to be small and we don't want to waste space.
//
//--------------------------------------------------------------------------
void CXlatState::_Realloc() { UINT oldcStates = _cStates; ULONG * oldpulStates = _pulStates;
_cStates += 10; _pulStates = new ULONG [ _cStates * _StateSize ];
memcpy( _pulStates, oldpulStates, oldcStates * _StateSize * sizeof( ULONG ) );
memset( _pulStates + oldcStates * _StateSize, 0, (_cStates - oldcStates) * _StateSize * sizeof(ULONG) );
delete [] oldpulStates; }
|