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 / dict / util0.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-06-12  |  7.6 KB  |  312 lines

  1. /*************************************************************/
  2. /**                                                         **/
  3. /**                 Microsoft RPC Examples                  **/
  4. /**                 Dictionary Application                  **/
  5. /**          Copyright(c) Microsoft Corp. 1992-1996         **/
  6. /**                                                         **/
  7. /*************************************************************/
  8.  
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <ctype.h>
  13.  
  14. #ifndef _LOCAL
  15. #include "replay.h"
  16. #else
  17. #include "play.h"
  18. #endif // _LOCAL
  19.  
  20. #include "dict0.h"
  21. #include "util0.h"
  22.  
  23.  
  24. /*************************************************************************/
  25. /***                RecordNode / RecordTree free routines              ***/
  26. /*************************************************************************/
  27.  
  28. void
  29. RecordTreeNodeFree(
  30.     IN RecordTreeNode * node
  31.     )
  32. {
  33.     if (node == NULL)
  34.         return;
  35.  
  36.     MIDL_user_free( node->item->name );
  37.     MIDL_user_free( node->item );
  38.     node->left = NULL;
  39.     node->right = NULL;
  40.     MIDL_user_free( node );
  41. }
  42.  
  43. void
  44. RecordTreeFree(
  45.     IN RecordTreeNode * node
  46.     )
  47. {
  48.     if (node == NULL)
  49.         return;
  50.  
  51.     if (node->left != NULL) {
  52.         RecordTreeFree(node->left);
  53.     }
  54.     if (node->right != NULL) {
  55.         RecordTreeFree(node->right);
  56.     }
  57.     RecordTreeNodeFree( node );
  58. }
  59.  
  60. VDict_Status
  61. RDict_Free_Dict(
  62.     IN OUT RDict * r_dict
  63.     )
  64. {
  65.     RecordTreeFree( r_dict->root );
  66.  
  67.     return(DICT_SUCCESS);
  68. }
  69.  
  70. /*************************************************************************/
  71. /***                  State Allocate / Free routines                   ***/
  72. /*************************************************************************/
  73.  
  74. DictState * allocate_state(void)
  75. {
  76.     DictState * pstate = (DictState*) MIDL_user_allocate(sizeof(DictState));
  77.  
  78.     pstate->curr_record = (Record*) MIDL_user_allocate(sizeof(Record));
  79.     pstate->curr_record->name = (char*) MIDL_user_allocate(81 * sizeof(char));
  80.  
  81.     // initialize curr_record to "minus infinity" in the order
  82.     pstate->curr_record->key = -1;
  83.     strcpy(pstate->curr_record->name, "");
  84.     pstate->ref_count = 0;
  85.  
  86.     return(pstate);
  87. }
  88.  
  89. void free_state(DictState * state)
  90. {
  91.     if (state != NULL) {
  92.         if (state->curr_record != NULL) {
  93.             if (state->curr_record->name != NULL)
  94.                 MIDL_user_free(state->curr_record->name);
  95.             MIDL_user_free(state->curr_record);
  96.         }
  97.         MIDL_user_free(state);
  98.     }
  99. }
  100.  
  101. /*************************************************************************/
  102. /***                     Rdict Duplicate utilities                     ***/
  103. /*************************************************************************/
  104.  
  105. RDict *
  106. RDict_Duplicate(
  107.     IN RDict * src
  108.     )
  109. {
  110.     RDict * dst = (RDict*) MIDL_user_allocate(sizeof(RDict));
  111.  
  112.     dst->root = (RecordTreeNode*) Tree_Duplicate((TreeNode*)src->root);
  113.     dst->size = src->size;
  114.     dst->state = DictState_Duplicate(src->state);
  115.  
  116.     return(dst);
  117. }
  118.  
  119. DictState *
  120. DictState_Duplicate(
  121.     IN DictState * src
  122.     )
  123. {
  124.     DictState * dst = (DictState*) MIDL_user_allocate(sizeof(DictState));
  125.  
  126.     dst->curr_record = ItemDuplicate(src->curr_record);
  127.     dst->ref_count = src->ref_count;
  128.  
  129.     return(dst);
  130. }
  131.  
  132. TreeNode *
  133. TreeNode_Duplicate(
  134.     IN TreeNode * src
  135.     )
  136. {
  137.     TreeNode * pnode = (TreeNode*) MIDL_user_allocate(sizeof(TreeNode));
  138.  
  139.     pnode->left = pnode->right = NULL;
  140.     pnode->item = ItemDuplicate(src->item);
  141.  
  142.     return(pnode);
  143. }
  144.  
  145. TreeNode *
  146. Tree_Duplicate(
  147.     IN TreeNode * src
  148.     )
  149. {
  150.     TreeNode * dst;
  151.  
  152.     if (src == NULL)
  153.         return((TreeNode*)NULL);
  154.  
  155.     dst = TreeNode_Duplicate(src);
  156.     dst->left = Tree_Duplicate(src->left);
  157.     dst->right = Tree_Duplicate(src->right);
  158.     return(dst);
  159. }
  160.  
  161. /*************************************************************************/
  162. /***                MIDL_user_allocate / MIDL_user_free                ***/
  163. /*************************************************************************/
  164.  
  165. void __RPC_FAR * __RPC_USER MIDL_user_allocate(size_t count)
  166. {
  167.     return(malloc(count));
  168. }
  169.  
  170. void __RPC_USER MIDL_user_free(void __RPC_FAR * p)
  171. {
  172.     free(p);
  173. }
  174.  
  175. /*************************************************************************/
  176. /***                          Utility functions                        ***/
  177. /*************************************************************************/
  178.  
  179. /*  In the most general case *cmp is a two argument function:
  180.     (*cmp)(void *item0, void *item1) which compares two items,
  181.     and returns:    -1 if item0 < item1;
  182.                      0 if item0 == item1;
  183.                     +1 if item0 > item1.
  184.     The common case is: each item has a field named "key";
  185.     item.key is of type long, or string.
  186. */
  187.  
  188. int
  189. comp(void* x, void* y)
  190. {
  191.     int res = ((Record*)x)->key - ((Record*)y)->key;
  192.  
  193.     if (res == 0)
  194.         return( strcmp( ((Record*)x)->name, ((Record*)y)->name ) );
  195.     else
  196.         return( res ) ;
  197. }
  198.  
  199. Record *
  200. ItemDuplicate(
  201.     Record * item
  202.     )
  203. {
  204.     if (item == NULL)
  205.         return(NULL);
  206.  
  207.     return( makeRecord( item->key, item->name ) );
  208. }
  209.  
  210. Record *
  211. makeRecord(
  212.     short key,
  213.     char * name
  214.     )
  215. {
  216.     Record * pr = (Record*) MIDL_user_allocate(sizeof(Record));
  217.  
  218.     if (!name)
  219.         printf("makeRecord: NULL name\n");
  220.  
  221.     pr->name = (char*) MIDL_user_allocate(strlen(name)+1);
  222.     strcpy(pr->name, name);
  223.     pr->key = key;
  224.  
  225.     return(pr);
  226. }
  227.  
  228. void
  229. freeRecord(
  230.     Record * pr
  231.     )
  232. {
  233.     if (pr != NULL) {
  234.         if (pr->name != NULL)
  235.             MIDL_user_free(pr->name);
  236.         MIDL_user_free(pr);
  237.     }
  238. }
  239.  
  240. void
  241. ItemCopy(
  242.     IN Record * src,
  243.     OUT Record * dest
  244.     )
  245. {
  246.     int i;
  247.  
  248.     dest->key = src->key;
  249.  
  250.     // copy name, trubcated to 80 characters
  251.     for(i=0 ; (src->name[i] != '\0') && (i<80) ; i++)
  252.         dest->name[i]=src->name[i];
  253.  
  254.     dest->name[i]='\0';
  255. }
  256.  
  257. void
  258. printRecord(void* rp)
  259. {
  260.     printf("%d : %s\n", ((Record*)rp)->key, ((Record*)rp)->name);
  261. }
  262.  
  263. void
  264. Dict_Print(             /* prints the binary tree (indented right subtree,
  265.                            followed by the root, followed by the indented
  266.                            right dubtree) */
  267.     Dictionary * dp,
  268.     int indent)         /* number of spaces to indent subsequent levels */
  269. {
  270.     prinTree(0, indent, dp->root, dp->print_rec);
  271. }
  272.  
  273. char spaces[] =
  274. "                                                                                                                                                                                                                                                       ";
  275.  
  276. void
  277. prinTree(
  278.     int lmargin,             /* indentation of the root of the tree     */
  279.     int indent,              /* indentation of subsequent levels        */
  280.     TreeNode *np,            /* pointer to the root node                */
  281.     PrintFun print)          /* short, one line, record print routine   */
  282. {
  283.     if (np == NULL)
  284.         return;
  285.  
  286.     prinTree(lmargin+indent, indent, np->right, print);
  287.  
  288.     if (lmargin > sizeof(spaces))
  289.         lmargin = sizeof(spaces);;
  290.  
  291.     spaces[lmargin] = 0;
  292.     printf(spaces);
  293.     spaces[lmargin] = ' ';
  294.  
  295.     (*print)(np->item);
  296.  
  297.     prinTree(lmargin+indent, indent, np->left, print);
  298.  
  299. }
  300.  
  301. TreeNode*
  302. makeNode(void * item)
  303. {
  304.     TreeNode* tp;
  305.  
  306.     tp = (TreeNode*)MIDL_user_allocate(sizeof(TreeNode));
  307.     tp->item = item;
  308.     tp->left = tp->right = NULL;
  309.  
  310.     return(tp);
  311. }
  312.