windows-nt/Source/XPSP1/NT/com/rpc/runtime/mtrt/pipe.cxx
2020-09-26 16:20:57 +08:00

274 lines
8.9 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1996 - 1999
//
// File: pipe.cxx
//
//--------------------------------------------------------------------------
#include <precomp.hxx>
#include "pipe.h"
void I_RpcReadPipeElementsFromBuffer (
PIPE_STATE PAPI *state,
char PAPI *TargetBuffer,
int TargetBufferSize,
int PAPI *NumCopied
)
{
char PAPI *temp, PAPI *temp1 ;
int size ;
int totalsize ;
ASSERT(state->CurrentState == start ||
(state->PartialCountSize < sizeof(DWORD) &&
state->PartialPipeElementSize < state->PipeElementSize)) ;
if (TargetBufferSize < state->PipeElementSize)
{
return ;
}
while (1)
{
switch(state->CurrentState)
{
case start:
// read in an element count
if (state->BytesRemaining == 0)
{
return ;
}
// transition: end of src
if (state->BytesRemaining <sizeof(DWORD))
{
state->CurrentState = return_partial_count ;
break;
}
// transition: scan chunk count
state->PartialCount = 0 ;
state->PartialCountSize = 0 ;
state->PartialPipeElementSize = 0 ;
state->ElementsRemaining = *((DWORD *) state->CurPointer) ;
#if DBG
PrintToDebugger("PIPES: <start> ElementsRemainaing: %d\n",
state->ElementsRemaining) ;
#endif
state->CurPointer += sizeof(DWORD) ;
state->BytesRemaining -= sizeof(DWORD) ;
if (state->ElementsRemaining == 0)
{
state->EndOfPipe = 1 ;
return ;
}
else
{
state->CurrentState = copy_pipe_elem ;
}
break;
case read_partial_count: // also a start state & final state
size = sizeof(DWORD) ;
totalsize = 0 ;
ASSERT(state->PartialCountSize > 0 && state->PartialCountSize < 4) ;
ASSERT(state->ElementsRemaining == 0) ;
temp = (char *) &(state->PartialCount) ;
temp1 = (char *) &(state->ElementsRemaining) ;
for (;state->PartialCountSize;
state->PartialCountSize--, size--, totalsize++)
{
*temp1++ = *temp++ ;
}
for (;size && state->BytesRemaining;
size--,state->BytesRemaining--, totalsize++)
{
*temp1++ = *state->CurPointer++ ;
}
#if DBG
PrintToDebugger("PIPES: <read_partial_count>ElementsRemainaing: %d\n",
state->ElementsRemaining) ;
#endif
if (size == 0)
{
state->CurrentState = copy_pipe_elem ;
}
else
{
// copy the stuff back into Partial count
// and keep it around for the next call
// the next time around, we'll end up in the same
// state
temp = (char *) &(state->PartialCount) ;
temp1 = (char *) &(state->ElementsRemaining) ;
ASSERT(totalsize < sizeof(DWORD)) ;
for (;totalsize; totalsize--, state->PartialCountSize++)
{
*temp++ = *temp1++ ;
}
return ;
}
break;
case read_partial_pipe_elem: //also a start state
ASSERT(state->PartialPipeElementSize > 0 &&
state->PartialPipeElementSize < state->PipeElementSize) ;
if (TargetBufferSize < state->PipeElementSize)
{
// this is not an error
return ;
}
size = state->PipeElementSize ;
if (state->BytesRemaining >= size-state->PartialPipeElementSize)
{
temp = (char *) state->PartialPipeElement ;
for (;state->PartialPipeElementSize;
state->PartialPipeElementSize--, size--,
TargetBufferSize--)
{
*TargetBuffer++ = *temp++ ;
}
for (;size && state->BytesRemaining;
size--, state->BytesRemaining--,
TargetBufferSize--)
{
*TargetBuffer++ = *state->CurPointer++ ;
}
state->CurrentState = copy_pipe_elem ;
*NumCopied += 1 ;
}
else
{
// copy the stuff back into partial pipe buffer
// and keep it around for the next call
// the next time around, we'll end up in the same
// state
temp = (char *) state->PartialPipeElement+
state->PartialPipeElementSize ;
for (;state->BytesRemaining; state->BytesRemaining--,
state->PartialPipeElementSize++)
{
*temp++ = *state->CurPointer++ ;
}
return ;
}
break;
case copy_pipe_elem: // also a start state
if (state->BytesRemaining >= state->PipeElementSize)
{
if (TargetBufferSize >= state->PipeElementSize)
{
for (size = state->PipeElementSize; size;
size--, TargetBufferSize--, state->BytesRemaining--)
{
*TargetBuffer++ = *state->CurPointer++ ;
}
state->ElementsRemaining-- ;
*NumCopied += 1 ;
if (state->ElementsRemaining == 0)
{
state->CurrentState = start ;
if (TargetBufferSize < state->PipeElementSize)
{
return ;
}
}
}
else
{
// end of target buffer
// return the appropriate count
return ;
}
}
else
{
if (state->BytesRemaining)
{
state->CurrentState = return_partial_pipe_elem ;
}
else
{
return ;
}
}
break;
case return_partial_pipe_elem: // also save pipe elem
ASSERT(state->BytesRemaining < state->PipeElementSize) ;
state->PartialPipeElementSize = 0;
for (temp = (char *) state->PartialPipeElement; state->BytesRemaining;
state->BytesRemaining--, state->PartialPipeElementSize++)
{
*temp++ = *state->CurPointer++ ;
}
state->CurrentState = read_partial_pipe_elem ;
return;
case return_partial_count: // also save count
state->PartialCountSize = 0 ;
ASSERT(state->BytesRemaining < sizeof(DWORD)) ;
for (temp = (char *) &(state->PartialCount); state->BytesRemaining;
state->BytesRemaining--, state->PartialCountSize++)
{
*temp++ = *state->CurPointer++ ;
}
state->CurrentState = read_partial_count ;
return;
default:
ASSERT(0) ;
break;
}
}
}
RPC_STATUS RPC_ENTRY
MyRpcCompleteAsyncCall (
IN PRPC_ASYNC_STATE pAsync,
IN void *Reply
)
/*++
Function Name:MyRpcCompleteAsyncCall
This is function is used by the bvts, the real stuff will call
RpcCompleteAsyncCall.
Parameters:
Description:
Returns:
--*/
{
return STUB(pAsync)->CompletionRoutine (pAsync, Reply) ;
}