/*++ Copyright (c) 1994 Microsoft Corporation Module Name: union.cxx Abstract: Author: David Kays (dkays) August 1 1994 Revision History: RyszardK Sep 16, 94 Encapsulated unions, union arms Ryszardk Nov 12, 94 Array of unions, pointer issues --*/ #include #include #include #include #include extern "C" { #include #include } #include "misc.hxx" #include "bufout.hxx" void UNION::OutputArms( long ArmFO, long SwitchIs ) { uchar Format[1024]; long CurrentOffset, Arms, Alignment; NDR * Ndr; uchar * pFormat; if ( fOutputLimitReached ) return; // // Get the union's arm descriptions. // FormatString->Read( ArmFO + 2, Format, 2 ); Arms = GET_SHORT(Format) & 0x0fff; Alignment = GET_SHORT(Format) >> 12; CurrentOffset = ArmFO + 4; FormatString->Read( CurrentOffset, Format, (Arms * 6) + 2 ); pFormat = (uchar *) &Format[0]; Buffer->Align( Alignment ); for ( ; Arms--; pFormat += 6, CurrentOffset += 6 ) { if ( SwitchIs == GET_LONG(pFormat) ) { CurrentOffset += 4; pFormat += 4; break; } } IndentInc(); // // Check for default arm cases. // if ( Arms < 0 ) { if ( *((short *)pFormat) == 0xffff ) ABORT( "Undefined union default arm taken\n" ); if ( *((short *)pFormat) == 0 ) { PrintIndent(); Print( "Empty default arm\n" ); IndentDec(); return; } } if ( IS_MAGIC_UNION_BYTE(pFormat) ) { BASETYPE * Basetype; Basetype = new BASETYPE( this, pFormat[0] ); Basetype->Output(); delete Basetype; } else { long ArmOffset = GET_SHORT( pFormat ); if ( ArmOffset == 0 ) { PrintIndent(); Print("Empty arm\n"); } else { CurrentOffset += ArmOffset; FormatString->Read( CurrentOffset, Format, 4 ); if ( IS_POINTER_TYPE( Format[0] ) ) { char PtrValue[4]; long PtrBO; POINTER * pMember; // Read thru the pointer field. Buffer->Align( 0x3 ); PtrBO = Buffer->GetCurrentOffset(); Buffer->Read( PtrValue, 4); pMember = new POINTER( this, CurrentOffset, PtrBO ); PrintIndent(); Print( "%s %08x\t\n", FcTypeName[ Format[0] ], *(unsigned long *)PtrValue, pMember->GetPointerId() ); PointerDict.Register( PtrBO, pMember ); } else { Ndr = Create( CurrentOffset, this ); Ndr->Output(); delete Ndr; } PointerDict.OutputPointees( this ); } } IndentDec(); } void UNION::Output() { uchar Format[8]; long CurrentOffset; long SwitchIs; if ( fOutputLimitReached ) return; CurrentOffset = FormatOffset; // Read the fixed part of the union's description. FormatString->Read( CurrentOffset, &Format[0], 8 ); Buffer->Align( SIMPLE_TYPE_ALIGNMENT(Format[1]) ); SwitchIs = 0; Buffer->Read( (char *) &SwitchIs, SIMPLE_TYPE_BUFSIZE(Format[1]) ); PrintIndent(); Print( "Non-encapsulated union (switch is == 0x%x (%s)) : \n", SwitchIs, (unsigned long) FormatCharNames[Format[1]] ); // // Get the union's arm descriptions. // CurrentOffset += 6; CurrentOffset += GET_SHORT( Format + 6 ); OutputArms( CurrentOffset, SwitchIs ); } void ENCAPSULATED_UNION::Output() { uchar Format[2]; long SwitchIs; char SwitchType; if ( fOutputLimitReached ) return; // Read the fixed part of the union's description. FormatString->Read( FormatOffset, Format, 2 ); SwitchType = (char)(0xf & Format[1]); Buffer->Align( SIMPLE_TYPE_ALIGNMENT( SwitchType )); SwitchIs = 0; Buffer->Read( (char *) &SwitchIs, SIMPLE_TYPE_BUFSIZE( SwitchType ) ); PrintIndent(); Print( "Encapsulated union (switch is == 0x%x (%s)) : \n", SwitchIs, (unsigned long) FormatCharNames[ SwitchType ] ); OutputArms( FormatOffset + 2, SwitchIs ); }