Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

634 lines
14 KiB

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Copyright (c) 1989-1999 Microsoft Corporation
Module Name:
paddict.cxx
Abstract:
Implement a counted dictionary class.
Implements a dictionary for handling padding expressions for unknown
represent as data types.
Implements a dictionary for handling sizing macro for unknown
represent as data types.
Implements Quintuple dictionary for registering all type names for both
transmit_as and represent_as.
Implements Quadruple dictionary for handling usr_marshal.
Notes:
History:
Jan 25, 1994 RyszardK Created
----------------------------------------------------------------------------*/
#include "becls.hxx"
#pragma hdrstop
#include "typecls.hxx"
/////////////////////////////////////////////////////////////////////////////
//
// CountedDictionary class.
//
/////////////////////////////////////////////////////////////////////////////
unsigned short
CountedDictionary::GetListOfItems(
ITERATOR& ListIter )
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Get a list of dict items into the specified iterator.
Arguments:
ListIter - A reference to the iterator class where the list is
accumulated.
Return Value:
A count of the number of dictionary elements.
Notes:
----------------------------------------------------------------------------*/
{
Dict_Status Status;
void * pR;
short Count = 0;
//
// Get to the top of the dictionary.
//
Status = Dict_Next( (pUserType) 0 );
//
// Iterate till the entire dictionary is done.
//
while( SUCCESS == Status )
{
pR = Dict_Curr_Item();
ITERATOR_INSERT( ListIter, pR );
Count++;
Status = Dict_Next( pR );
}
return Count;
}
void *
CountedDictionary::GetFirst()
{
Dict_Status Status;
void * pFirst = 0;
Status = Dict_Next( 0 );
if ( Status == SUCCESS )
pFirst = Dict_Curr_Item();
return( pFirst );
}
void *
CountedDictionary::GetNext()
{
Dict_Status Status;
void *pCurr, *pNext = 0;
pCurr = Dict_Curr_Item();
if ( pCurr )
{
Status = Dict_Next( pCurr );
if ( Status == SUCCESS )
pNext = Dict_Curr_Item();
}
return( pNext );
}
SSIZE_T
CountedDictionary::Compare(
pUserType pE1,
pUserType pE2
)
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Compare two Counted types. Defaults to string comparison.
Arguments:
Return Value:
----------------------------------------------------------------------------*/
{
return( strcmp( (char *)pE1, (char *)pE2) );
}
//===========================================================================
void
RepAsPadExprDict::Register(
unsigned long Offset,
node_skl * pStructType,
char * pFieldName,
node_skl * pPrevFieldType
)
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Adds a padding expression description to the dictionary
Arguments:
Offset - offset of the padding field
pPaddingExpr - text of the expression to be printed out
----------------------------------------------------------------------------*/
{
Dict_Status Status;
REP_AS_PAD_EXPR_DESC * pOldEntry;
REP_AS_PAD_EXPR_DESC * pEntry = new REP_AS_PAD_EXPR_DESC;
pEntry->KeyOffset = Offset;
pEntry->pStructType = pStructType;
pEntry->pFieldName = pFieldName;
pEntry->pPrevFieldType = pPrevFieldType;
Status = Dict_Find( pEntry );
switch( Status )
{
case EMPTY_DICTIONARY:
case ITEM_NOT_FOUND:
Dict_Insert( pEntry );
EntryCount++;
break;
default:
// The only reason for an entry (offset) to be used already
// would be that the otimization has shrunk the format string.
// This means that the old entry should be deleted.
pOldEntry = (REP_AS_PAD_EXPR_DESC *)Dict_Curr_Item();
Dict_Delete( (pUserType *) &pOldEntry );
Dict_Insert( pEntry );
break;
}
return;
}
SSIZE_T
RepAsPadExprDict::Compare(
pUserType pE1,
pUserType pE2
)
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Compare pad expr descriptors.
KeyOffset is the key that orders the entries.
Arguments:
Return Value:
----------------------------------------------------------------------------*/
{
if( ((REP_AS_PAD_EXPR_DESC *)pE1)->KeyOffset <
((REP_AS_PAD_EXPR_DESC *)pE2)->KeyOffset )
return( -1 );
else
if( ((REP_AS_PAD_EXPR_DESC *)pE1)->KeyOffset >
((REP_AS_PAD_EXPR_DESC *)pE2)->KeyOffset )
return( 1 );
else
return( 0 );
}
REP_AS_PAD_EXPR_DESC *
RepAsPadExprDict::GetFirst()
{
Dict_Status Status;
REP_AS_PAD_EXPR_DESC * pFirst = 0;
Status = Dict_Next( 0 );
if ( Status == SUCCESS )
pFirst = (REP_AS_PAD_EXPR_DESC *)Dict_Curr_Item();
return( pFirst );
}
REP_AS_PAD_EXPR_DESC *
RepAsPadExprDict::GetNext()
{
Dict_Status Status;
REP_AS_PAD_EXPR_DESC *pCurr, *pNext = 0;
pCurr = (REP_AS_PAD_EXPR_DESC *)Dict_Curr_Item();
if ( pCurr )
{
Status = Dict_Next( pCurr );
if ( Status == SUCCESS )
pNext = (REP_AS_PAD_EXPR_DESC *)Dict_Curr_Item();
}
return( pNext );
}
void
RepAsPadExprDict::WriteCurrentPadDesc(
ISTREAM * pStream
)
/*++
Routine description:
Writes out the following string:
(unsigned char)(NdrFieldPad(pSN,pFN,pPFN,pPFT))
Arguments:
pStream - stream to write to.
--*/
{
REP_AS_PAD_EXPR_DESC *pCurr = (REP_AS_PAD_EXPR_DESC *)Dict_Curr_Item();
if ( pCurr && pCurr->pPrevFieldType )
{
pStream->Write( "(unsigned char)("FC_FIELD_PAD_MACRO"(" );
pCurr->pStructType->PrintType( PRT_TYPE_SPECIFIER, pStream );
pStream->Write( ',' );
pStream->Write( pCurr->pFieldName );
pStream->Write( ',' );
pStream->Write( pCurr->pPrevFieldType->GetSymName() );
pStream->Write( ',' );
pCurr->pPrevFieldType->GetChild()->
PrintType( PRT_TYPE_SPECIFIER, pStream );
pStream->Write( "))," );
}
else
pStream->Write( "0," );
}
//========================================================================
void
RepAsSizeDict::Register(
unsigned long Offset,
char * pTypeName
)
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Adds a sizing macro description to the dictionary
Arguments:
Offset - offset of the padding field
pPaddingExpr - text of the expression to be printed out
----------------------------------------------------------------------------*/
{
Dict_Status Status;
REP_AS_SIZE_DESC * pOldEntry;
REP_AS_SIZE_DESC * pEntry = new REP_AS_SIZE_DESC;
pEntry->KeyOffset = Offset;
pEntry->pTypeName = pTypeName;
Status = Dict_Find( pEntry );
switch( Status )
{
case EMPTY_DICTIONARY:
case ITEM_NOT_FOUND:
Dict_Insert( pEntry );
EntryCount++;
break;
default:
// The only reason for an entry (offset) to be used already
// would be that the otimization has shrunk the format string.
// This means that the old entry should be deleted.
pOldEntry = (REP_AS_SIZE_DESC *)Dict_Curr_Item();
Dict_Delete( (pUserType *) &pOldEntry );
Dict_Insert( pEntry );
break;
}
return;
}
SSIZE_T
RepAsSizeDict::Compare(
pUserType pE1,
pUserType pE2
)
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Compare size descriptors.
KeyOffset is the key that orders the entries.
Arguments:
Return Value:
----------------------------------------------------------------------------*/
{
if( ((REP_AS_SIZE_DESC *)pE1)->KeyOffset <
((REP_AS_SIZE_DESC *)pE2)->KeyOffset )
return( -1 );
else
if( ((REP_AS_SIZE_DESC *)pE1)->KeyOffset >
((REP_AS_SIZE_DESC *)pE2)->KeyOffset )
return( 1 );
else
return( 0 );
}
REP_AS_SIZE_DESC *
RepAsSizeDict::GetFirst()
{
Dict_Status Status;
REP_AS_SIZE_DESC * pFirst = 0;
Status = Dict_Next( 0 );
if ( Status == SUCCESS )
pFirst = (REP_AS_SIZE_DESC *)Dict_Curr_Item();
return( pFirst );
}
REP_AS_SIZE_DESC *
RepAsSizeDict::GetNext()
{
Dict_Status Status;
REP_AS_SIZE_DESC *pCurr, *pNext = 0;
pCurr = (REP_AS_SIZE_DESC *)Dict_Curr_Item();
if ( pCurr )
{
Status = Dict_Next( pCurr );
if ( Status == SUCCESS )
pNext = (REP_AS_SIZE_DESC *)Dict_Curr_Item();
}
return( pNext );
}
void
RepAsSizeDict::WriteCurrentSizeDesc(
ISTREAM * pStream
)
/*++
Routine description:
Writes out the following string:
NdrFcShort( sizeof(<type>)
Arguments:
pStream - stream to write to.
--*/
{
REP_AS_SIZE_DESC *pCurr = (REP_AS_SIZE_DESC *)Dict_Curr_Item();
if ( pCurr )
{
pStream->Write( "NdrFcShort( sizeof(" );
pStream->Write( pCurr->pTypeName );
pStream->Write( "))," );
}
else
pStream->Write( "0," );
}
//========================================================================
BOOL
QuintupleDict::Add(
void * pContext
)
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Adds a Quintuple description to the dictionary.
Arguments:
Returns:
TRUE - when a new entry has been registered,
FALSE - otherwise
Index field gets set to appropriate index.
----------------------------------------------------------------------------*/
{
Dict_Status Status;
XMIT_AS_CONTEXT * pEntry = (XMIT_AS_CONTEXT *) pContext;
Status = Dict_Find( pEntry );
if( Status == EMPTY_DICTIONARY || Status == ITEM_NOT_FOUND )
{
pEntry->Index = CurrentIndex;
Dict_Insert( pEntry );
CurrentIndex++;
return TRUE;
}
else
{
pEntry->Index = ((XMIT_AS_CONTEXT *)Dict_Curr_Item())->Index;
return FALSE;
}
}
SSIZE_T
QuintupleDict::Compare(
pUserType pE1,
pUserType pE2
)
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Compare two quintuple types.
Both fXmit and the name have to match.
fXmit allows for comparing xmit_as with xmit_as and rep_as with rep_as.
For xmit_as we compare the presented types.
For rep_as we compare the wire types (not the local types).
Arguments:
Return Value:
----------------------------------------------------------------------------*/
{
if( ((XMIT_AS_CONTEXT *)pE1)->fXmit == ((XMIT_AS_CONTEXT *)pE2)->fXmit )
if ( ((XMIT_AS_CONTEXT *)pE1)->fXmit )
return( strcmp( ((XMIT_AS_CONTEXT *)pE1)->pTypeName,
((XMIT_AS_CONTEXT *)pE2)->pTypeName ) );
else
return( strcmp(
((CG_REPRESENT_AS *)((XMIT_AS_CONTEXT *)pE1)->pXmitNode)->
GetTransmittedType()->GetSymName(),
((CG_REPRESENT_AS *)((XMIT_AS_CONTEXT *)pE2)->pXmitNode)->
GetTransmittedType()->GetSymName()
) );
else
if( ((XMIT_AS_CONTEXT *)pE1)->fXmit )
return( -1 );
else
return( 1 );
}
void *
QuintupleDict::GetFirst()
{
Dict_Status Status;
XMIT_AS_CONTEXT * pFirst = 0;
Status = Dict_Next( 0 );
if ( Status == SUCCESS )
pFirst = (XMIT_AS_CONTEXT *)Dict_Curr_Item();
return( pFirst );
}
void *
QuintupleDict::GetNext()
{
Dict_Status Status;
XMIT_AS_CONTEXT *pCurr, *pNext = 0;
pCurr = (XMIT_AS_CONTEXT *)Dict_Curr_Item();
if ( pCurr )
{
Status = Dict_Next( pCurr );
if ( Status == SUCCESS )
pNext = (XMIT_AS_CONTEXT *)Dict_Curr_Item();
}
return( pNext );
}
//========================================================================
BOOL
QuadrupleDict::Add(
void * pContext
)
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Adds a Quadruple description to the dictionary.
Arguments:
Returns:
TRUE - when a new entry has been registered,
FALSE - otherwise entry exist already
Index field gets set to appropriate index.
----------------------------------------------------------------------------*/
{
Dict_Status Status;
USER_MARSHAL_CONTEXT * pEntry = (USER_MARSHAL_CONTEXT *) pContext;
Status = Dict_Find( pEntry );
if( Status == EMPTY_DICTIONARY || Status == ITEM_NOT_FOUND )
{
pEntry->Index = GetCount();
Dict_Insert( pEntry );
IncrementCount();
return TRUE;
}
else
{
pEntry->Index = ((USER_MARSHAL_CONTEXT *)Dict_Curr_Item())->Index;
return FALSE;
}
}
SSIZE_T
QuadrupleDict::Compare(
pUserType pE1,
pUserType pE2
)
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Compare two Quadruple types.
For usr_marshall we compare the types.
Arguments:
Return Value:
----------------------------------------------------------------------------*/
{
return( strcmp( ((USER_MARSHAL_CONTEXT *)pE1)->pTypeName,
((USER_MARSHAL_CONTEXT *)pE2)->pTypeName ) );
}