windows-nt/Source/XPSP1/NT/net/ias/providers/nap/regex/xlatstat.cxx
2020-09-26 16:20:57 +08:00

242 lines
6.1 KiB
C++

//+-------------------------------------------------------------------------
//
// Copyright (C) 1991, Microsoft Corporation.
//
// File: XlatStat.cxx
//
// Contents: State translation class.
//
// Classes: CXlatState
//
// History: 01-20-92 KyleP Created
// 03-11-97 arunk Modified for regex lib
//
//--------------------------------------------------------------------------
// Local includes:
#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 )
{
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;
}