/****************************************************************************
Microsoft RPC Version 2.0
Copyright Microsoft Corp. 1992, 1993, 1994- 1996
xmit Example
FILE: xmitu.c
PURPOSE: Utility functions used by both client and server
sides of the RPC distributed application.
This sample demonstrates the transmit_as example.
A doubly-linked list is transmitted over the network
as a sized array.
RELATED: xmits.c - server main
xmitp.c - remote procedures
xmitc.c - client main
FUNCTIONS: DOUBLE_LINK_TYPE_to_xmit - convert list to array
DOUBLE_LINK_TYPE_from_xmit - convert array to list
DOUBLE_LINK_TYPE_free_inst - free linked list memory
DOUBLE_LINK_TYPE_free_xmit - free array memory
midl_user_allocate - user-supplied memory allocator
midl_user_free - user-supplied routine to free memory
ArrayWalkProc - utility to display the array
ListWalkProc - utility to display the linked list
InsertNewNode - utility to add a node to the list
COMMENTS: This sample program generates a linked list to
demonstrate how a list with aliasing can be transmitted
using the transmit_as attribute as a sized array.
The pointers are rebuilt on the server side.
****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include "xmit.h" // header file generated by MIDL compiler
#include "xmitu.h"
/***************************************************************************/
void ArrayWalkProc(DOUBLE_XMIT_TYPE * pArray)
{
int i;
printf("Display contents of transmitted array:\n");
for (i = 0; i < pArray->sSize; i++)
printf("pArray->asNumber[%d] = %d\n", i, pArray->asNumber[i]);
}
void ListWalkProc(DOUBLE_LINK_TYPE * pList)
{
printf("Display contents of doubly linked list:\n");
while (pList != NULL) {
printf("pList @0x%lx = %d, Next = 0x%lx\n",
pList, pList->sNumber, pList->pNext);
pList = pList->pNext;
}
}
DOUBLE_LINK_TYPE * InsertNewNode(short sValue, DOUBLE_LINK_TYPE * pPrevious)
{
DOUBLE_LINK_TYPE * pNew;
do {
pNew = (DOUBLE_LINK_TYPE *)midl_user_allocate(sizeof(DOUBLE_LINK_TYPE));
} while (pNew == pPrevious);
pNew->pNext = NULL; // initialize
pNew->pPrevious = NULL; // initialize
pNew->sNumber = sValue; // insert b between a and c
pNew->pPrevious = pPrevious; // prev(b) = a
if (pPrevious == NULL)
pNew->pNext = NULL;
else {
pNew->pNext = pPrevious->pNext; // next(b) = c
pPrevious->pNext = pNew; // next(a) = b
if (pNew->pNext != NULL)
(pNew->pNext)->pPrevious = pNew; // prev(c) = b
}
return(pNew);
}
/***************************************************************************/
void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
{
return(malloc(len));
}
void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
{
free(ptr);
}
/***************************************************************************/
/* convert from linked list to array */
void __RPC_USER
DOUBLE_LINK_TYPE_to_xmit(
DOUBLE_LINK_TYPE __RPC_FAR * pList,
DOUBLE_XMIT_TYPE __RPC_FAR * __RPC_FAR * ppArray)
{
short cCount = 0;
DOUBLE_LINK_TYPE * pHead = pList; // save pointer to start
DOUBLE_XMIT_TYPE * pArray;
/* count the number of elements to allocate memory */
for (; pList != NULL; pList = pList->pNext)
cCount++;
/* allocate the memory for the array */
pArray = (DOUBLE_XMIT_TYPE *) midl_user_allocate
(sizeof(DOUBLE_XMIT_TYPE) + (cCount * sizeof(short)));
pArray->sSize = cCount;
/* copy the linked list contents into the array */
for (cCount = 0, pList = pHead; pList != NULL; pList = pList->pNext)
pArray->asNumber[cCount++] = pList->sNumber;
/* return the address of the pointer to the array */
*ppArray = pArray;
}
/* convert from array to linked list */
void __RPC_USER
DOUBLE_LINK_TYPE_from_xmit(
DOUBLE_XMIT_TYPE __RPC_FAR * pArray,
DOUBLE_LINK_TYPE __RPC_FAR * pList)
{
DOUBLE_LINK_TYPE *pCurrent;
int i;
if (pArray->sSize <= 0) { // error checking
pList = NULL;
return;
}
if (pList == NULL)
pList = InsertNewNode(pArray->asNumber[0], NULL);
else {
DOUBLE_LINK_TYPE_free_inst(pList); // free all other nodes
pList->sNumber = pArray->asNumber[0];
pList->pNext = NULL;
}
pCurrent = pList;
for (i = 1; i < pArray->sSize; i++) // write new values
pCurrent = InsertNewNode(pArray->asNumber[i], pCurrent);
}
/* free the doubly linked list */
/* move forward through list, freeing the previous entry */
void __RPC_USER
DOUBLE_LINK_TYPE_free_inst(
DOUBLE_LINK_TYPE __RPC_FAR * pList)
{
while (pList->pNext != NULL) // go to end of list
pList = pList->pNext;
pList = pList->pPrevious;
while (pList != NULL) { // back through list
midl_user_free(pList->pNext);
pList = pList->pPrevious;
}
}
/* free the array structure */
void __RPC_USER
DOUBLE_LINK_TYPE_free_xmit(
DOUBLE_XMIT_TYPE __RPC_FAR * pArray)
{
midl_user_free(pArray);
}
/* end file xmitu.c */