184 lines
5.4 KiB
C
184 lines
5.4 KiB
C
/****************************************************************************
|
|
Microsoft RPC Version 2.0
|
|
Copyright Microsoft Corp. 1992 - 2000
|
|
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 %p = %d, Next = %p\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 */
|