mirror of https://github.com/lianthony/NT4.0
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.
983 lines
19 KiB
983 lines
19 KiB
/*++
|
|
|
|
Copyright (c) 1991 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
recvgen.cxx
|
|
|
|
Abstract:
|
|
|
|
This module collects implementations of RecvNode virtual method
|
|
for various classes derived from node_skl.
|
|
|
|
Author:
|
|
|
|
Donna Liu (donnali) 09-Nov-1990
|
|
|
|
Revision History:
|
|
|
|
22-Mar-1992 donnali
|
|
|
|
Moved toward NT coding style.
|
|
|
|
--*/
|
|
|
|
|
|
#include "nulldefs.h"
|
|
extern "C" {
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <malloc.h>
|
|
#include <assert.h>
|
|
}
|
|
#include "nodeskl.hxx"
|
|
#include "buffer.hxx"
|
|
#include "output.hxx"
|
|
#include "listhndl.hxx"
|
|
#include "basetype.hxx"
|
|
#include "ptrarray.hxx"
|
|
#include "compnode.hxx"
|
|
#include "procnode.hxx"
|
|
#include "miscnode.hxx"
|
|
#include "typedef.hxx"
|
|
#include "stubgen.hxx"
|
|
#include "newexpr.hxx"
|
|
|
|
#define PRPCMSG "_prpcmsg"
|
|
#define PRPCBUF "_prpcmsg->Buffer"
|
|
#define RECVBUF "_recvbuf"
|
|
#define TEMPBUF "_tempbuf"
|
|
#define SAVEBUF "_savebuf"
|
|
|
|
extern OutputManager * pOutput;
|
|
extern char * STRING_TABLE[LAST_COMPONENT];
|
|
extern void midl_debug (char *);
|
|
|
|
STATUS_T
|
|
node_base_type::RecvNode(
|
|
SIDE_T Side,
|
|
NODE_T Parent,
|
|
BufferManager * pBuffer)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine receives a node of base type.
|
|
|
|
Arguments:
|
|
|
|
Side - Supplies which side to generate code for.
|
|
|
|
Parent - Supplies type of the parent node.
|
|
|
|
pBuffer - Supplies a buffer to accumulate output.
|
|
|
|
--*/
|
|
{
|
|
char * pName;
|
|
NODE_T Type;
|
|
|
|
midl_debug ("node_base_type::RecvNode()\n");
|
|
|
|
pName = GetSymName();
|
|
assert (pName != (char *)0);
|
|
|
|
Type = GetNodeType();
|
|
|
|
if (Parent != NODE_POINTER)
|
|
{
|
|
pBuffer->ConcatHead (OP_ADDRESS);
|
|
}
|
|
switch (Type)
|
|
{
|
|
case NODE_DOUBLE :
|
|
case NODE_FLOAT :
|
|
case NODE_HYPER :
|
|
case NODE_LONGLONG :
|
|
case NODE_LONG :
|
|
case NODE_SHORT :
|
|
case NODE_SMALL :
|
|
case NODE_CHAR :
|
|
case NODE_BYTE :
|
|
case NODE_BOOLEAN :
|
|
pOutput->RecvAssign
|
|
(Side, GetNdrAlign(), GetSize(0), pName, pBuffer);
|
|
break;
|
|
default :
|
|
return I_ERR_INVALID_NODE_TYPE;
|
|
}
|
|
if (Parent != NODE_POINTER)
|
|
{
|
|
pBuffer->RemoveHead (&pName);
|
|
}
|
|
|
|
return STATUS_OK;
|
|
}
|
|
|
|
STATUS_T
|
|
node_e_status_t::RecvNode(
|
|
SIDE_T Side,
|
|
NODE_T Parent,
|
|
BufferManager * pBuffer)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine receives a node of error_status_t type.
|
|
|
|
Arguments:
|
|
|
|
Side - Supplies which side to generate code for.
|
|
|
|
Parent - Supplies type of the parent node to pass to the child node.
|
|
|
|
pBuffer - Supplies a buffer to pass to the child node.
|
|
|
|
--*/
|
|
{
|
|
node_skl * pNode;
|
|
|
|
pNode = GetMembers ();
|
|
|
|
return pNode->RecvNode (Side, Parent, pBuffer);
|
|
}
|
|
|
|
STATUS_T
|
|
node_wchar_t::RecvNode(
|
|
SIDE_T Side,
|
|
NODE_T Parent,
|
|
BufferManager * pBuffer)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine receives a node of wchar_t type.
|
|
|
|
Arguments:
|
|
|
|
Side - Supplies which side to generate code for.
|
|
|
|
Parent - Supplies type of the parent node to pass to the child node.
|
|
|
|
pBuffer - Supplies a buffer to pass to the child node.
|
|
|
|
--*/
|
|
{
|
|
node_skl * pNode;
|
|
|
|
pNode = GetMembers ();
|
|
|
|
return pNode->RecvNode (Side, Parent, pBuffer);
|
|
}
|
|
|
|
STATUS_T
|
|
node_def::RecvNode(
|
|
SIDE_T Side,
|
|
NODE_T Parent,
|
|
BufferManager * pBuffer)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine receives a node of typedef.
|
|
|
|
Arguments:
|
|
|
|
Side - Supplies which side to generate code for.
|
|
|
|
Parent - Supplies type of the parent node to pass to the child node.
|
|
|
|
pBuffer - Supplies a buffer to pass to the child node.
|
|
|
|
--*/
|
|
{
|
|
node_skl * pNode;
|
|
|
|
pNode = GetMembers ();
|
|
|
|
return pNode->RecvNode (Side, Parent, pBuffer);
|
|
}
|
|
|
|
STATUS_T
|
|
npa::RecvNode(
|
|
SIDE_T Side,
|
|
NODE_T Parent,
|
|
BufferManager * pBuffer)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine receives an aggregate of homogeneous nodes.
|
|
|
|
Arguments:
|
|
|
|
Side - Supplies which side to generate code for.
|
|
|
|
Parent - Supplies type of the parent node.
|
|
|
|
pBuffer - Supplies a buffer to accumulate output.
|
|
|
|
--*/
|
|
{
|
|
node_skl * pNode;
|
|
node_skl * pBase;
|
|
node_skl * pType = (node_skl *)0;
|
|
char * pName;
|
|
node_state State;
|
|
STATUS_T Status = STATUS_OK;
|
|
unsigned short HasAllocBound = 0;
|
|
unsigned short HasValidBound = 0;
|
|
unsigned short usTotal = 0;
|
|
unsigned long MscTemp = 0;
|
|
unsigned long NdrTemp = 0;
|
|
BufferManager TempBuffer(8, LAST_COMPONENT, STRING_TABLE);
|
|
BufferManager TailBuffer(8, LAST_COMPONENT, STRING_TABLE);
|
|
|
|
midl_debug ("npa::RecvNode()\n");
|
|
|
|
pNode = GetMembers ();
|
|
|
|
|
|
#if 0
|
|
// if the basic type of the array derives from a transmit_as, then dont
|
|
// do anything. npa::WalkTree will do the right thing, I hope
|
|
|
|
if( HasAnyNETransmitAsType() )
|
|
return STATUS_OK;
|
|
|
|
#endif // 1
|
|
|
|
State = GetNodeState ();
|
|
|
|
pBase = GetBasicType ();
|
|
|
|
HasAllocBound =
|
|
FInSummary (ATTR_MAX) ||
|
|
FInSummary (ATTR_SIZE);
|
|
|
|
HasValidBound =
|
|
FInSummary (ATTR_FIRST) ||
|
|
FInSummary (ATTR_LAST) ||
|
|
FInSummary (ATTR_LENGTH);
|
|
|
|
GetAttrPath (pBuffer, &TempBuffer, &TailBuffer);
|
|
|
|
AllocBounds.pLower->Clear ();
|
|
AllocBounds.pUpper->Clear ();
|
|
AllocBounds.pTotal->Clear ();
|
|
GetAllocBoundInfo (&TempBuffer, &TailBuffer, &AllocBounds, this);
|
|
|
|
ValidBounds.pLower->Clear ();
|
|
ValidBounds.pUpper->Clear ();
|
|
ValidBounds.pTotal->Clear ();
|
|
GetValidBoundInfo (&TempBuffer, &TailBuffer, &ValidBounds, this);
|
|
|
|
if (FInSummary(ATTR_STRING))
|
|
{
|
|
// strings with or without upper bound
|
|
if (Parent == NODE_POINTER)
|
|
{
|
|
pBuffer->ConcatHead (OP_DEREF);
|
|
pBuffer->ConcatHead (CHAR_LPAREN);
|
|
pBuffer->ConcatTail (CHAR_RPAREN);
|
|
}
|
|
if (pBase->GetNodeType() == NODE_BYTE)
|
|
{
|
|
pOutput->RecvByteString (Side, pBuffer);
|
|
}
|
|
else
|
|
{
|
|
pOutput->RecvCharString (Side, pBuffer, (unsigned short )pNode->GetSize(0));
|
|
}
|
|
if (Parent == NODE_POINTER)
|
|
{
|
|
pBuffer->RemoveHead (&pName);
|
|
pBuffer->RemoveHead (&pName);
|
|
pBuffer->RemoveTail (&pName);
|
|
}
|
|
return STATUS_OK;
|
|
}
|
|
else if( FInSummary( ATTR_BSTRING ) )
|
|
{
|
|
// strings with or without upper bound
|
|
if (Parent == NODE_POINTER)
|
|
{
|
|
pBuffer->ConcatHead (OP_DEREF);
|
|
pBuffer->ConcatHead (CHAR_LPAREN);
|
|
pBuffer->ConcatTail (CHAR_RPAREN);
|
|
}
|
|
if (pBase->GetNodeType() == NODE_BYTE)
|
|
{
|
|
pOutput->RecvByteBString (Side, pBuffer);
|
|
}
|
|
else
|
|
{
|
|
pOutput->RecvCharBString (Side, pBuffer, (unsigned short )pNode->GetSize(0));
|
|
}
|
|
if (Parent == NODE_POINTER)
|
|
{
|
|
pBuffer->RemoveHead (&pName);
|
|
pBuffer->RemoveHead (&pName);
|
|
pBuffer->RemoveTail (&pName);
|
|
}
|
|
return STATUS_OK;
|
|
}
|
|
|
|
if (Parent == NODE_POINTER || Parent == NODE_DYNAMIC_ARRAY)
|
|
{
|
|
if (pNode->HasPointer() || !pOutput->InsideProcedure())
|
|
{
|
|
pOutput->EmitAssign (Side, SAVEBUF, TEMPBUF);
|
|
pOutput->EmitAssign (Side, TEMPBUF, PRPCBUF);
|
|
}
|
|
}
|
|
|
|
/// if (Parent != NODE_ARRAY)
|
|
/// {
|
|
BOOL IsVaryingArray = FALSE;
|
|
BOOL fIsAFixedArrayOfStrings = FALSE;
|
|
|
|
if (State & NODE_STATE_VARYING_ARRAY)
|
|
{
|
|
pOutput->RecvValidBounds (Side, PRPCMSG);
|
|
if (Parent != NODE_ARRAY && GetNodeType() == NODE_ARRAY)
|
|
{
|
|
IsVaryingArray = TRUE;
|
|
}
|
|
}
|
|
else if (Parent != NODE_ARRAY && GetNodeType() == NODE_ARRAY)
|
|
{
|
|
#if 1
|
|
BOOL fDontSendBounds = FInSummary( ATTR_INT_SIZE );
|
|
#endif // 1
|
|
for (pType = GetBasicType();
|
|
pType->GetNodeType() == NODE_ARRAY;
|
|
pType = pType->GetBasicType())
|
|
{
|
|
if (pType->FInSummary(ATTR_STRING))
|
|
{
|
|
if( !fDontSendBounds )
|
|
{
|
|
usTotal += 8;
|
|
}
|
|
else
|
|
fIsAFixedArrayOfStrings = TRUE;
|
|
IsVaryingArray = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (IsVaryingArray)
|
|
{
|
|
for (pType = GetBasicType();
|
|
pType->GetNodeType() == NODE_ARRAY;
|
|
pType = pType->GetBasicType())
|
|
{
|
|
if (!pType->FInSummary(ATTR_STRING) && !fIsAFixedArrayOfStrings )
|
|
{
|
|
usTotal += 8;
|
|
}
|
|
}
|
|
if (usTotal)
|
|
{
|
|
pOutput->Alignment (Side, PRPCBUF, 4);
|
|
pOutput->Increment (Side, PRPCBUF, usTotal);
|
|
}
|
|
}
|
|
/// }
|
|
|
|
|
|
if (pNode->HasRef()
|
|
#if 1
|
|
|| ((HasAnyNETransmitAsType() || DerivesFromTransmitAs()) &&
|
|
(GetBasicTransmissionType()->NodeKind() != NODE_POINTER ))
|
|
#endif // 1
|
|
)
|
|
{
|
|
return Status;
|
|
}
|
|
|
|
if (Parent == NODE_POINTER)
|
|
{
|
|
pBuffer->ConcatHead (OP_DEREF);
|
|
pBuffer->ConcatHead (CHAR_LPAREN);
|
|
pBuffer->ConcatTail (CHAR_RPAREN);
|
|
}
|
|
|
|
switch (pBase->GetNodeType())
|
|
{
|
|
// case NODE_DOUBLE:
|
|
case NODE_FLOAT:
|
|
case NODE_HYPER:
|
|
case NODE_LONGLONG:
|
|
case NODE_LONG:
|
|
case NODE_SHORT:
|
|
case NODE_SMALL:
|
|
case NODE_CHAR:
|
|
case NODE_BYTE:
|
|
case NODE_BOOLEAN:
|
|
case NODE_VOID:
|
|
if(pBase->GetNodeType() == NODE_VOID)
|
|
pName = "byte";
|
|
else
|
|
pName = pBase->GetSymName ();
|
|
|
|
if (State & NODE_STATE_VARYING_ARRAY)
|
|
{
|
|
pOutput->RecvArray (Side, pBuffer, pName, VALID_BOUND);
|
|
}
|
|
else if (FInSummary(ATTR_MAX) || FInSummary(ATTR_SIZE))
|
|
{
|
|
if (Parent == NODE_STRUCT)
|
|
{
|
|
pOutput->RecvArray (Side, pBuffer, pName);
|
|
}
|
|
else
|
|
{
|
|
pOutput->RecvArray (Side, pBuffer, pName, ALLOC_BOUND);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pOutput->RecvArray (Side, pBuffer, pName, &ValidBounds);
|
|
}
|
|
break;
|
|
default:
|
|
pOutput->InitBlock (Side);
|
|
|
|
if (State & NODE_STATE_VARYING_ARRAY)
|
|
{
|
|
pName = pOutput->EmitTemp (Side, VALID_BOUND);
|
|
pBuffer->ConcatTail (CHAR_LBRACK);
|
|
pBuffer->ConcatTail (pName);
|
|
pBuffer->ConcatTail (CHAR_RBRACK);
|
|
pOutput->InitLoop (Side, pName, VALID_BOUND);
|
|
Status = pNode->RecvNode (Side, NODE_ARRAY, pBuffer);
|
|
pOutput->ExitLoop (Side, VALID_BOUND);
|
|
}
|
|
else if (FInSummary(ATTR_MAX) || FInSummary(ATTR_SIZE))
|
|
{
|
|
pName = pOutput->EmitTemp (Side, ALLOC_BOUND);
|
|
pBuffer->ConcatTail (CHAR_LBRACK);
|
|
pBuffer->ConcatTail (pName);
|
|
pBuffer->ConcatTail (CHAR_RBRACK);
|
|
if (Parent == NODE_STRUCT)
|
|
{
|
|
pOutput->InitLoop (Side, pName);
|
|
Status = pNode->RecvNode (Side, NODE_ARRAY, pBuffer);
|
|
pOutput->ExitLoop (Side);
|
|
}
|
|
else
|
|
{
|
|
pOutput->InitLoop (Side, pName, ALLOC_BOUND);
|
|
Status = pNode->RecvNode (Side, NODE_ARRAY, pBuffer);
|
|
pOutput->ExitLoop (Side, ALLOC_BOUND);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pName = pOutput->EmitTemp (Side, (BufferManager *)0);
|
|
pBuffer->ConcatTail (CHAR_LBRACK);
|
|
pBuffer->ConcatTail (pName);
|
|
pBuffer->ConcatTail (CHAR_RBRACK);
|
|
pOutput->InitLoop (Side, pName, &ValidBounds, (BufferManager *)0);
|
|
Status = pNode->RecvNode (Side, NODE_ARRAY, pBuffer);
|
|
pOutput->ExitLoop (Side);
|
|
}
|
|
|
|
pBuffer->RemoveTail (&pName);
|
|
pBuffer->RemoveTail (&pName);
|
|
pBuffer->RemoveTail (&pName);
|
|
|
|
pOutput->ExitBlock (Side);
|
|
break;
|
|
}
|
|
|
|
|
|
if (Parent == NODE_POINTER)
|
|
{
|
|
pBuffer->RemoveHead (&pName);
|
|
pBuffer->RemoveHead (&pName);
|
|
pBuffer->RemoveTail (&pName);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
STATUS_T
|
|
node_array::RecvNode(
|
|
SIDE_T Side,
|
|
NODE_T Parent,
|
|
BufferManager * pBuffer)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine receives a node of array type.
|
|
|
|
Arguments:
|
|
|
|
Side - Supplies which side to generate code for.
|
|
|
|
Parent - Supplies type of the parent node.
|
|
|
|
pBuffer - Supplies a buffer to accumulate output.
|
|
|
|
--*/
|
|
{
|
|
node_skl * pType = (node_skl *)0;
|
|
node_state State;
|
|
STATUS_T Status;
|
|
unsigned short usTotal = 0;
|
|
|
|
midl_debug ("node_array::RecvNode()\n");
|
|
|
|
State = GetNodeState();
|
|
|
|
if (Parent == NODE_PROC &&
|
|
(FInSummary(ATTR_UNIQUE) || FInSummary(ATTR_PTR)))
|
|
{
|
|
pOutput->Alignment (Side, PRPCBUF, 4);
|
|
pOutput->Increment (Side, PRPCBUF, 4);
|
|
|
|
if (HasRef()) return STATUS_OK;
|
|
|
|
pOutput->Alignment (Side, TEMPBUF, 4);
|
|
pOutput->EmitIf (Side, TEMPBUF);
|
|
// pOutput->EmitIf (Side, "*(*(unsigned long **)&" TEMPBUF ")++");
|
|
pOutput->InitBlock (Side);
|
|
}
|
|
|
|
if (Parent == NODE_PROC)
|
|
{
|
|
if (State & NODE_STATE_CONF_ARRAY)
|
|
{
|
|
pOutput->RecvAllocBounds (Side, PRPCMSG);
|
|
for (pType = GetBasicType();
|
|
pType->GetNodeType() == NODE_ARRAY;
|
|
pType = pType->GetBasicType())
|
|
{
|
|
usTotal += 4;
|
|
}
|
|
if (usTotal)
|
|
{
|
|
pOutput->Alignment (Side, PRPCBUF, 4);
|
|
pOutput->Increment (Side, PRPCBUF, usTotal);
|
|
}
|
|
}
|
|
if (Side == SERVER_STUB)
|
|
{
|
|
if (FInSummary(ATTR_UNIQUE) ||
|
|
FInSummary(ATTR_PTR) ||
|
|
(State & NODE_STATE_CONF_ARRAY))
|
|
{
|
|
pOutput->EmitIf (Side, pBuffer, "==");
|
|
pOutput->InitBlock (Side);
|
|
npa::InitNode (Side, Parent, pBuffer);
|
|
pOutput->ExitBlock (Side);
|
|
}
|
|
}
|
|
else if (Side == CLIENT_STUB)
|
|
{
|
|
if (!FInSummary(ATTR_UNIQUE) && !FInSummary(ATTR_PTR))
|
|
{
|
|
pOutput->EmitIf (Side, pBuffer, "==");
|
|
pOutput->Print (Side, "\t");
|
|
pOutput->RaiseException (Side, 0, "RPC_X_NULL_REF_POINTER");
|
|
}
|
|
}
|
|
}
|
|
|
|
Status = npa::RecvNode (Side, Parent, pBuffer);
|
|
|
|
if (Parent == NODE_PROC &&
|
|
(FInSummary(ATTR_UNIQUE) || FInSummary(ATTR_PTR)))
|
|
{
|
|
pOutput->ExitBlock (Side);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
STATUS_T
|
|
node_pointer::RecvNode(
|
|
SIDE_T Side,
|
|
NODE_T Parent,
|
|
BufferManager * pBuffer)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine receives a node of pointer type.
|
|
|
|
Arguments:
|
|
|
|
Side - Supplies which side to generate code for.
|
|
|
|
Parent - Supplies type of the parent node.
|
|
|
|
pBuffer - Supplies a buffer to accumulate output.
|
|
|
|
--*/
|
|
{
|
|
char * pName;
|
|
|
|
midl_debug ("node_pointer::RecvNode()\n");
|
|
|
|
// if statement used no matter client or server
|
|
if (Parent != NODE_POINTER && Parent != NODE_DYNAMIC_ARRAY)
|
|
{
|
|
if (Parent == NODE_PROC)
|
|
{
|
|
if (!FInSummary(ATTR_UNIQUE) && !FInSummary(ATTR_PTR))
|
|
{
|
|
return STATUS_OK;
|
|
}
|
|
}
|
|
else if (Parent != NODE_STRUCT)
|
|
{
|
|
if (FInSummary(ATTR_REF) ||
|
|
(!FInSummary(ATTR_UNIQUE) && !FInSummary(ATTR_PTR) &&
|
|
pOutput->PointerDefault() == POINTER_REF))
|
|
{
|
|
return STATUS_OK;
|
|
}
|
|
}
|
|
if (Parent != NODE_POINTER)
|
|
{
|
|
pBuffer->ConcatHead (OP_ADDRESS);
|
|
}
|
|
pOutput->Alignment (Side, PRPCBUF, GetNdrAlign());
|
|
pOutput->Increment (Side, PRPCBUF, GetSize(0));
|
|
if (Parent != NODE_POINTER)
|
|
{
|
|
pBuffer->RemoveHead (&pName);
|
|
}
|
|
}
|
|
|
|
return STATUS_OK;
|
|
}
|
|
|
|
STATUS_T
|
|
node_enum::RecvNode(
|
|
SIDE_T Side,
|
|
NODE_T Parent,
|
|
BufferManager * pBuffer)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine receives a node of enum type.
|
|
|
|
Arguments:
|
|
|
|
Side - Supplies which side to generate code for.
|
|
|
|
Parent - Supplies type of the parent node.
|
|
|
|
pBuffer - Supplies a buffer to accumulate output.
|
|
|
|
--*/
|
|
{
|
|
char * pName;
|
|
|
|
midl_debug ("node_enum::RecvNode()\n");
|
|
|
|
if (Parent != NODE_POINTER)
|
|
{
|
|
pBuffer->ConcatHead (OP_ADDRESS);
|
|
}
|
|
|
|
pOutput->RecvAssign (Side, GetNdrAlign(), 2, "short", pBuffer);
|
|
|
|
if (Parent != NODE_POINTER)
|
|
{
|
|
pBuffer->RemoveHead (&pName);
|
|
}
|
|
else
|
|
{
|
|
pBuffer->ConcatHead (OP_DEREF);
|
|
}
|
|
|
|
pOutput->EnumCoersion (Side, pBuffer);
|
|
|
|
if (Parent == NODE_POINTER)
|
|
{
|
|
pBuffer->RemoveHead (&pName);
|
|
}
|
|
|
|
return STATUS_OK;
|
|
}
|
|
|
|
|
|
STATUS_T
|
|
node_field::RecvNode(
|
|
SIDE_T Side,
|
|
NODE_T Parent,
|
|
BufferManager * pBuffer)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine receives a node of field type.
|
|
|
|
Arguments:
|
|
|
|
Side - Supplies which side to generate code for.
|
|
|
|
Parent - Supplies type of the parent node.
|
|
The parent has to be either node_struct or node_union.
|
|
|
|
pBuffer - Supplies a buffer to accumulate output.
|
|
|
|
--*/
|
|
{
|
|
expr_node * pExpr;
|
|
node_skl * pNode;
|
|
char * pName;
|
|
node_state State;
|
|
STATUS_T Status;
|
|
|
|
midl_debug ("node_field::RecvNode()\n");
|
|
|
|
if (IsEmptyArm()) return STATUS_OK;
|
|
|
|
pNode = GetMembers ();
|
|
|
|
pName = GetSymName();
|
|
assert (pName != (char *)0);
|
|
|
|
State = GetNodeState();
|
|
|
|
if (State & NODE_STATE_UNION)
|
|
{
|
|
SwitchBuffer->Clear();
|
|
pExpr = GetSwitchIsExpr();
|
|
pExpr->PrintExpr (pBuffer, 0, SwitchBuffer);
|
|
SetUpUnionSwitch (SwitchBuffer);
|
|
}
|
|
|
|
char * pTemp = SpecialActionUnnamedFields( pBuffer, &pName );
|
|
|
|
pBuffer->ConcatTail (pName);
|
|
Status = pNode->RecvNode (Side, Parent, pBuffer);
|
|
pBuffer->RemoveTail (&pName);
|
|
|
|
return Status;
|
|
}
|
|
|
|
STATUS_T
|
|
node_union::RecvNode(
|
|
SIDE_T Side,
|
|
NODE_T Parent,
|
|
BufferManager * pBuffer)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine receives a node of union type.
|
|
|
|
Arguments:
|
|
|
|
Side - Supplies which side to generate code for.
|
|
|
|
Parent - Supplies type of the parent node.
|
|
|
|
pBuffer - Supplies a buffer to accumulate output.
|
|
|
|
--*/
|
|
{
|
|
node_skl * pNode;
|
|
char * pName;
|
|
|
|
pNode = GetSwitchType ();
|
|
assert (pNode != (node_skl *)0);
|
|
|
|
if (!IsEncapsulatedUnion())
|
|
{
|
|
pOutput->RecvBranch (Side, pNode->GetSize(0), PRPCMSG);
|
|
}
|
|
|
|
pName = GetSymName();
|
|
assert (pName != (char *)0);
|
|
|
|
if (Parent == NODE_POINTER)
|
|
{
|
|
if (HasPointer())
|
|
{
|
|
pOutput->EmitAssign (Side, SAVEBUF, PRPCBUF);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pBuffer->ConcatHead (OP_ADDRESS);
|
|
}
|
|
|
|
pOutput->InvokeRecvNodeUnion (
|
|
Side, pName, pBuffer,
|
|
(IsEncapsulatedUnion() ? Info.pSwStringBuffer : (BufferManager *)0),
|
|
pNode->GetSize(0),
|
|
GetOriginalTypedefName());
|
|
|
|
if (Parent != NODE_POINTER)
|
|
{
|
|
pBuffer->RemoveHead (&pName);
|
|
}
|
|
|
|
return STATUS_OK;
|
|
}
|
|
|
|
STATUS_T
|
|
node_struct::RecvNode(
|
|
SIDE_T Side,
|
|
NODE_T Parent,
|
|
BufferManager * pBuffer)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine receives a node of struct type.
|
|
|
|
Arguments:
|
|
|
|
Side - Supplies which side to generate code for.
|
|
|
|
Parent - Supplies type of the parent node.
|
|
|
|
pBuffer - Supplies a buffer to accumulate output.
|
|
|
|
--*/
|
|
{
|
|
type_node_list tnList;
|
|
node_skl * pNode;
|
|
char * pName;
|
|
node_array * pArray;
|
|
node_state State;
|
|
STATUS_T Status;
|
|
BufferManager TempBuffer(8, LAST_COMPONENT, STRING_TABLE);
|
|
BOOL fAbortAlignForEncapUnion;
|
|
|
|
fAbortAlignForEncapUnion = IsEncapsulatedStruct() || IsLastMemberEncapUnion();
|
|
|
|
midl_debug ("node_struct::RecvNode()\n");
|
|
|
|
if ((Status = GetMembers(&tnList)) != STATUS_OK) return Status;
|
|
|
|
pName = GetSymName();
|
|
assert (pName != (char *)0);
|
|
|
|
State = GetNodeState();
|
|
|
|
/* commented out to test out_of_line node unmarshalling
|
|
|
|
pOutput->Alignment (Side, RECVBUF, GetNdrAlign());
|
|
|
|
if (((Side == SERVER_STUB) &&
|
|
(Parent == NODE_PROC) && (State & NODE_STATE_CONF_ARRAY)) ||
|
|
(Parent == NODE_POINTER))
|
|
{
|
|
pBuffer->ConcatTail (OP_POINTER);
|
|
}
|
|
else
|
|
{
|
|
pBuffer->ConcatTail (OP_MEMBER);
|
|
}
|
|
tnList.Init();
|
|
while (tnList.GetPeer(&pNode) == STATUS_OK)
|
|
{
|
|
pNode->RecvNode (Side, NODE_STRUCT, pBuffer);
|
|
}
|
|
pBuffer->RemoveTail (&pName);
|
|
*/
|
|
if (Parent == NODE_POINTER && HasPointer())
|
|
{
|
|
pOutput->EmitAssign (Side, SAVEBUF, PRPCBUF);
|
|
}
|
|
|
|
if (!(State & NODE_STATE_CONF_ARRAY) &&
|
|
!(State & NODE_STATE_VARYING_ARRAY) &&
|
|
!(State & NODE_STATE_UNION))
|
|
{
|
|
TempBuffer.Clear ();
|
|
tnList.Init();
|
|
while (tnList.GetPeer(&pNode) == STATUS_OK)
|
|
{
|
|
if ((Status = pNode->ConvNode (&TempBuffer)) != STATUS_OK) break;
|
|
}
|
|
|
|
if (Status == STATUS_OK)
|
|
{
|
|
unsigned short NdrAln;
|
|
|
|
NdrAln = GetNdrAlign ();
|
|
if (NdrAln == 4)
|
|
{
|
|
TempBuffer.ConcatHead ("4");
|
|
}
|
|
else if (NdrAln == 2)
|
|
{
|
|
TempBuffer.ConcatHead ("2");
|
|
}
|
|
else if (NdrAln == 1)
|
|
{
|
|
TempBuffer.ConcatHead ("1");
|
|
}
|
|
else if (NdrAln == 8)
|
|
{
|
|
TempBuffer.ConcatHead ("8");
|
|
}
|
|
if (Parent != NODE_POINTER)
|
|
{
|
|
pBuffer->ConcatHead (OP_ADDRESS);
|
|
}
|
|
pOutput->RecvStream (Side, pBuffer, &TempBuffer);
|
|
if (Parent != NODE_POINTER)
|
|
{
|
|
pBuffer->RemoveHead (&pName);
|
|
}
|
|
return STATUS_OK;
|
|
}
|
|
}
|
|
|
|
if (Parent != NODE_POINTER)
|
|
{
|
|
pBuffer->ConcatHead (OP_ADDRESS);
|
|
}
|
|
|
|
if (State & NODE_STATE_CONF_ARRAY)
|
|
{
|
|
pArray = GetConfArrayNode ();
|
|
if ((Status = pArray->GetNodeState(&State)) != STATUS_OK) return Status;
|
|
|
|
if (!(State & NODE_STATE_VARYING_ARRAY) &&
|
|
!pArray->FInSummary (ATTR_STRING) &&
|
|
!pArray->FInSummary (ATTR_BSTRING)
|
|
)
|
|
{
|
|
if (Parent != NODE_STRUCT)
|
|
pOutput->InvokeRecvNodeStruct (
|
|
Side, pName, pBuffer, TRUE, FALSE, FALSE, GetOriginalTypedefName());
|
|
else
|
|
pOutput->InvokeRecvNodeStruct (
|
|
Side, pName, pBuffer, TRUE, TRUE, FALSE, GetOriginalTypedefName());
|
|
}
|
|
else
|
|
{
|
|
pOutput->InvokeRecvNodeStruct (Side, pName, pBuffer, FALSE, FALSE, FALSE, GetOriginalTypedefName());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pOutput->InvokeRecvNodeStruct (Side, pName, pBuffer, FALSE, FALSE, fAbortAlignForEncapUnion, GetOriginalTypedefName());
|
|
}
|
|
|
|
if (Parent != NODE_POINTER)
|
|
{
|
|
pBuffer->RemoveHead (&pName);
|
|
}
|
|
|
|
return STATUS_OK;
|
|
}
|
|
|