home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / netds / rpc / data / xmit / xmitu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-06-11  |  5.6 KB  |  184 lines

  1. /****************************************************************************
  2.                    Microsoft RPC Version 2.0
  3.            Copyright Microsoft Corp. 1992, 1993, 1994- 1996
  4.                         xmit Example
  5.  
  6.     FILE:       xmitu.c
  7.  
  8.     PURPOSE:    Utility functions used by both client and server
  9.                 sides of the RPC distributed application.
  10.                 This sample demonstrates the transmit_as example.
  11.                 A doubly-linked list is transmitted over the network
  12.                 as a sized array.
  13.  
  14.     RELATED:    xmits.c - server main
  15.                 xmitp.c - remote procedures
  16.                 xmitc.c - client main
  17.  
  18.     FUNCTIONS:  DOUBLE_LINK_TYPE_to_xmit - convert list to array
  19.                 DOUBLE_LINK_TYPE_from_xmit - convert array to list
  20.                 DOUBLE_LINK_TYPE_free_inst - free linked list memory
  21.                 DOUBLE_LINK_TYPE_free_xmit - free array memory
  22.                 midl_user_allocate - user-supplied memory allocator
  23.                 midl_user_free - user-supplied routine to free memory
  24.  
  25.                 ArrayWalkProc - utility to display the array
  26.                 ListWalkProc - utility to display the linked list
  27.                 InsertNewNode - utility to add a node to the list
  28.  
  29.     COMMENTS:   This sample program generates a linked list to
  30.                 demonstrate how a list with aliasing can be transmitted
  31.                 using the transmit_as attribute as a sized array.
  32.                 The pointers are rebuilt on the server side.
  33.  
  34. ****************************************************************************/
  35.  
  36. #include <stdlib.h>
  37. #include <stdio.h>
  38. #include "xmit.h"    // header file generated by MIDL compiler
  39. #include "xmitu.h"
  40.  
  41.  
  42. /***************************************************************************/
  43.  
  44. void ArrayWalkProc(DOUBLE_XMIT_TYPE * pArray)
  45. {
  46.     int i;
  47.  
  48.     printf("Display contents of transmitted array:\n");
  49.     for (i = 0; i < pArray->sSize; i++)
  50.         printf("pArray->asNumber[%d] = %d\n", i, pArray->asNumber[i]);
  51. }
  52.  
  53. void ListWalkProc(DOUBLE_LINK_TYPE * pList)
  54. {
  55.     printf("Display contents of doubly linked list:\n");
  56.     while (pList != NULL) {
  57.         printf("pList @0x%lx = %d, Next = 0x%lx\n",
  58.                pList, pList->sNumber, pList->pNext);
  59.         pList = pList->pNext;
  60.     }
  61. }
  62.  
  63. DOUBLE_LINK_TYPE * InsertNewNode(short sValue, DOUBLE_LINK_TYPE * pPrevious)
  64. {
  65.     DOUBLE_LINK_TYPE * pNew;
  66.  
  67.     do {
  68.         pNew = (DOUBLE_LINK_TYPE *)midl_user_allocate(sizeof(DOUBLE_LINK_TYPE));
  69.     } while (pNew == pPrevious);
  70.  
  71.     pNew->pNext = NULL;      // initialize
  72.     pNew->pPrevious = NULL;  // initialize
  73.     pNew->sNumber = sValue;  // insert b between a and c
  74.  
  75.     pNew->pPrevious = pPrevious;             // prev(b) = a
  76.     if (pPrevious == NULL)
  77.         pNew->pNext = NULL;
  78.     else {
  79.         pNew->pNext = pPrevious->pNext;      // next(b) = c
  80.         pPrevious->pNext = pNew;             // next(a) = b
  81.         if (pNew->pNext != NULL)
  82.             (pNew->pNext)->pPrevious = pNew; // prev(c) = b
  83.     }
  84.  
  85.     return(pNew);
  86. }
  87.  
  88.  
  89. /***************************************************************************/
  90.  
  91. void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
  92. {
  93.     return(malloc(len));
  94. }
  95.  
  96. void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
  97. {
  98.     free(ptr);
  99. }
  100.  
  101.  
  102. /***************************************************************************/
  103.  
  104. /* convert from linked list to array */
  105. void __RPC_USER
  106. DOUBLE_LINK_TYPE_to_xmit(
  107.     DOUBLE_LINK_TYPE __RPC_FAR * pList,
  108.     DOUBLE_XMIT_TYPE __RPC_FAR * __RPC_FAR * ppArray)
  109. {
  110.     short cCount = 0;
  111.     DOUBLE_LINK_TYPE * pHead = pList;  // save pointer to start
  112.     DOUBLE_XMIT_TYPE * pArray;
  113.  
  114.     /* count the number of elements to allocate memory */
  115.     for (; pList != NULL; pList = pList->pNext)
  116.         cCount++;
  117.  
  118.     /* allocate the memory for the array */
  119.     pArray = (DOUBLE_XMIT_TYPE *) midl_user_allocate
  120.              (sizeof(DOUBLE_XMIT_TYPE) + (cCount * sizeof(short)));
  121.     pArray->sSize = cCount;
  122.  
  123.     /* copy the linked list contents into the array */
  124.     for (cCount = 0, pList = pHead; pList != NULL; pList = pList->pNext)
  125.         pArray->asNumber[cCount++] = pList->sNumber;
  126.  
  127.     /* return the address of the pointer to the array */
  128.     *ppArray = pArray;
  129. }
  130.  
  131. /* convert from array to linked list */
  132. void __RPC_USER
  133. DOUBLE_LINK_TYPE_from_xmit(
  134.     DOUBLE_XMIT_TYPE __RPC_FAR * pArray,
  135.     DOUBLE_LINK_TYPE __RPC_FAR * pList)
  136. {
  137.     DOUBLE_LINK_TYPE *pCurrent;
  138.     int i;
  139.  
  140.     if (pArray->sSize <= 0) {  // error checking
  141.         pList = NULL;
  142.         return;
  143.     }
  144.  
  145.     if (pList == NULL)
  146.         pList = InsertNewNode(pArray->asNumber[0], NULL);
  147.     else {
  148.         DOUBLE_LINK_TYPE_free_inst(pList);  // free all other nodes
  149.         pList->sNumber = pArray->asNumber[0];
  150.         pList->pNext = NULL;
  151.     }
  152.  
  153.     pCurrent = pList;
  154.     for (i = 1; i < pArray->sSize; i++)  // write new values
  155.         pCurrent = InsertNewNode(pArray->asNumber[i], pCurrent);
  156. }
  157.  
  158.  
  159. /* free the doubly linked list */
  160. /* move forward through list, freeing the previous entry */
  161. void __RPC_USER
  162. DOUBLE_LINK_TYPE_free_inst(
  163.     DOUBLE_LINK_TYPE __RPC_FAR * pList)
  164. {
  165.     while (pList->pNext != NULL)  // go to end of list
  166.         pList = pList->pNext;
  167.  
  168.     pList = pList->pPrevious;
  169.     while (pList != NULL) {  // back through list
  170.         midl_user_free(pList->pNext);
  171.         pList = pList->pPrevious;
  172.     }
  173. }
  174.  
  175. /* free the array structure */
  176. void __RPC_USER
  177. DOUBLE_LINK_TYPE_free_xmit(
  178.     DOUBLE_XMIT_TYPE __RPC_FAR * pArray)
  179. {
  180.     midl_user_free(pArray);
  181. }
  182.  
  183. /* end file xmitu.c */
  184.