/**************************************************************************** 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 #include #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 */