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 / client.c next >
Encoding:
C/C++ Source or Header  |  1996-06-12  |  12.8 KB  |  415 lines

  1. /*************************************************************/
  2. /**                                                         **/
  3. /**                 Microsoft RPC Examples                  **/
  4. /**                 Dictionary Application                  **/
  5. /**          Copyright(c) Microsoft Corp. 1992-1996         **/
  6. /**                                                         **/
  7. /*************************************************************/
  8.  
  9. /*************************************************************************
  10.  *                                                                       *
  11.  * Remote dictionary example: client side                                *
  12.  *                                                                       *
  13.  * Description:                                                          *
  14.  * This is the driver for the client side remote dictionary              *
  15.  * (splay trees based) demo.  This works as follows:                     *
  16.  *                                                                       *
  17.  *  o in main we bind to the dict interface, and call main_dict;         *
  18.  *                                                                       *
  19.  *  o in dict_main we call VDict_New to initialize the dictionary        *
  20.  *    on the server side, and then call TestLoop.                        *
  21.  *                                                                       *
  22.  *  o in TestLoop we loop responding to user input of the form:          *
  23.  *    <one_letter_opcode> [<optional_arg>],                              *
  24.  *    where <optional_arg> is a an integer constant followed by a        *
  25.  *    string.  Type "?" for a detailed usage message.                    *
  26.  *                                                                       *
  27.  *************************************************************************
  28. */
  29.  
  30. #include <stdlib.h>
  31. #include <stdio.h>
  32. #include <string.h>
  33. #include <ctype.h>
  34.  
  35. #include "replay.h"  // header file generated by MIDL compiler
  36. #include "dict0.h"
  37. #include "util0.h"
  38.  
  39. #define TAB_STOPS 4
  40.  
  41. #define RDICT_CURR_RECORD(dict) (((DictState*)dict->state)->curr_record)
  42.  
  43.  
  44. char * view = "normal";
  45.  
  46.  
  47. void Usage()
  48. {
  49.   printf("Usage : client -s\n");
  50.   printf("               -n <server_name>\n");
  51.   printf("               -v <view_option>\n");
  52.   exit(1);
  53. }
  54.  
  55. /*************************************************************************/
  56. /***                     Remote Dictionary Print                       ***/
  57. /*************************************************************************/
  58.  
  59. void
  60. RevPrinTree(
  61.     int lmargin,             /* indentation of the root of the tree     */
  62.     int indent,              /* indentation of subsequent levels        */
  63.     TreeNode *np,            /* pointer to the root node                */
  64.     PrintFun print)          /* short, one line, record print routine   */
  65. {
  66.     static char lspaces[] =
  67. "                                                                                                                                                                                                                                                       ";
  68.  
  69.  
  70.  
  71.     if (np == NULL)
  72.         return;
  73.  
  74.     RevPrinTree(lmargin+indent, indent, np->left, print);
  75.  
  76.     if (lmargin > sizeof(lspaces))
  77.         lmargin = sizeof(lspaces);
  78.  
  79.     lspaces[lmargin] = 0;
  80.     printf(lspaces);
  81.     lspaces[lmargin] = ' ';
  82.  
  83.     (*print)(np->item);
  84.  
  85.     RevPrinTree(lmargin+indent, indent, np->right, print);
  86. }
  87.  
  88. void
  89. LinPrinTree(
  90.     TreeNode *np,           /* pointer to the root node                */
  91.     PrintFun print,         /* short, one line, record print routine   */
  92.     Record * local,         /* local iterator point                    */
  93.     Record * global         /* global iterator point                   */
  94.     )
  95. {
  96.     if (np == NULL)
  97.         return;
  98.  
  99.     LinPrinTree(np->left, print, local, global);
  100.  
  101.     if (comp(np->item, local) == 0) {
  102.         if (comp(np->item, global) == 0)
  103.             printf(" ==>> ");
  104.         else
  105.             printf("   >> ");
  106.     }
  107.     else if (comp(np->item, global) == 0)
  108.         printf(" ==   ");
  109.     else
  110.         printf("      ");
  111.  
  112.     (*print)(np->item);
  113.  
  114.     LinPrinTree(np->right, print, local, global);
  115. }
  116.  
  117. void
  118. Clnt_Dict_Print(
  119.     VDict * pvd,
  120.     int indent,
  121.     Record * local,
  122.     Record * global
  123.     )
  124. {
  125.     RDict DictT = {0, 0};
  126.     RDict *prd = &DictT;
  127.  
  128.     // first: get a new copy a from the server
  129.     VDict_Get_Dict(*pvd, &prd);
  130.  
  131.     if ( !strcmp(view, "normal") )
  132.         prinTree(0,
  133.                  TAB_STOPS,
  134.                  (TreeNode *) prd->root,
  135.                  printRecord);
  136.     else if ( !strcmp(view, "reverse") || !strcmp(view, "rev") )
  137.         RevPrinTree(0,
  138.                     TAB_STOPS,
  139.                     (TreeNode *) prd->root,
  140.                     printRecord);
  141.     else if ( !strcmp(view, "flat") )
  142.         LinPrinTree((TreeNode *) prd->root,
  143.                     printRecord,
  144.                     local,
  145.                     RDICT_CURR_RECORD(prd));
  146.  
  147.     RDict_Free_Dict(prd);
  148. }
  149.  
  150. /*************************************************************************/
  151. /***                     Remote Dictionary Test Loop                   ***/
  152. /*************************************************************************/
  153.  
  154. void
  155. Usage_Msg()
  156. {
  157.     printf("\nUsage: \nType a single character, followed by an optional key as follows:\n\n");
  158.     printf("    i <key> :: Insert <key> into dictionary\n");
  159.     printf("    d <key> :: Delete <key> from dictionary\n");
  160.     printf("    f <key> :: Find <key> in dictionary\n");
  161.     printf("    N       :: next of current item in dictionary\n");
  162.     printf("    P       :: previous of current item in dictionary\n");
  163.     printf("    n       :: Next of local current item in dictionary\n");
  164.     printf("    p       :: Previous of local current item in dictionary\n");
  165.     printf("    h       :: Head (first item) of dictionary\n");
  166.     printf("    t       :: Tail (last item) of dictionary\n");
  167.     printf("    ?       :: Print this message\n");
  168.     printf("    q       :: Quit\n\n");
  169.     printf("where <key> is <integer> <string>\n");
  170. }
  171.  
  172. void
  173. TestLoop( VDict * pvd )
  174. {
  175.     char currName[80];
  176.     char name[80];
  177.     char op = 0;
  178.     char buffer[80];
  179.  
  180.     Record r, currRecord;
  181.     Record *pcurrRecord = &currRecord;
  182.     Record *pr = &r;
  183.     Record * pNullRecord = NULL;
  184.  
  185.     Dict_Status status;
  186.  
  187.     pcurrRecord->name = currName;
  188.     pr->name = name;
  189.  
  190.     VDict_Curr_Item(*pvd, &pcurrRecord);
  191.     ItemCopy(pcurrRecord, pr);
  192.  
  193.     Clnt_Dict_Print(pvd, TAB_STOPS, pcurrRecord, pr);
  194.     Usage_Msg();
  195.  
  196.     while ( op != 'q' ) {
  197.  
  198.         printf("\nnext op (i d x f n N p P h t ? q): ");
  199.         gets(buffer);
  200.         op = buffer[0];
  201.  
  202.         if (op == 'i' || op == 'd' || op == 'f' || op == 'I')
  203.             sscanf(buffer+1, "%d %s", &pr->key, pr->name);
  204.  
  205.         switch (op) {
  206.             case 'h':
  207.                 // get Head of list (first record);
  208.  
  209.                 status = VDict_Next(*pvd, &pNullRecord);
  210.                 if (pNullRecord != NULL) {
  211.                     ItemCopy(pNullRecord, pcurrRecord);
  212.                     freeRecord(pNullRecord);
  213.                     pNullRecord = NULL;
  214.                 }
  215.                 break;
  216.  
  217.             case 't':
  218.                 // get Tail of list (last record)
  219.  
  220.                 status = VDict_Prev(*pvd, &pNullRecord);
  221.                 if (pNullRecord != NULL) {
  222.                     ItemCopy(pNullRecord, pcurrRecord);
  223.                     freeRecord(pNullRecord);
  224.                     pNullRecord = NULL;
  225.                 }
  226.                 break;
  227.  
  228.             case 'n':
  229.                 // get next record (advance private (local) iterator)
  230.  
  231.                 status = VDict_Next(*pvd, &pcurrRecord);
  232.                 break;
  233.  
  234.             case 'p':
  235.                 // get previous record (retreat private (local) iterator)
  236.  
  237.                 status = VDict_Prev(*pvd, &pcurrRecord);
  238.                 break;
  239.  
  240.             case 'r':
  241.                 // Reset local iterator to global "current item"
  242.  
  243.                 status = VDict_Curr_Item(*pvd, &pcurrRecord);
  244.                 break;
  245.  
  246.             case 'N':
  247.                 // get Next record (advance global iterator)
  248.  
  249.                 status = VDict_Curr_Next(*pvd, &pr);
  250.                 pr = &r;
  251.                 break;
  252.  
  253.             case 'P':
  254.                 // get Previous record (retreat global iterator)
  255.  
  256.                 status = VDict_Curr_Prev(*pvd, &pr);
  257.                 pr = &r;
  258.                 break;
  259.  
  260.             case 'f':
  261.                 // Find <key>
  262.  
  263.                 status = VDict_Find(*pvd, &pr);
  264.                 pr = &r;
  265.                 break;
  266.  
  267.             case 'i':
  268.                 // Insert <key>
  269.  
  270.                 status = VDict_Insert(*pvd, pr);
  271.                 break;
  272.  
  273.             case 'I':
  274.                 // Insert (<num'>,"") for all num' s.t. 3 < num' < num
  275.  
  276.                 status = VDict_I_Dict(*pvd, pr->key);
  277.                 break;
  278.  
  279.             case 'd':
  280.                 // Delete <key>
  281.  
  282.                 status = VDict_Delete(*pvd, &pr);
  283.                 if (status != ITEM_NOT_FOUND && status != EMPTY_DICTIONARY) {
  284.                     pr = &r;
  285.                 }
  286.                 break;
  287.  
  288.             case 'x':
  289.                 // Delete DICT_CURR_ITEM
  290.  
  291.                 status = VDict_Curr_Delete(*pvd, &pr);
  292.                 if (pr == NULL) {
  293.                     pr = &r;
  294.                 }
  295.                 break;
  296.  
  297.             case 'X':
  298.                 // Empty the dictionary
  299.  
  300.                 status = VDict_X_Dict(*pvd);
  301.                 break;
  302.  
  303.             case '?':
  304.                 Usage_Msg();
  305.                 break;
  306.         }
  307.  
  308.         if (op != '?' && op != 'q')
  309.             Clnt_Dict_Print(pvd, TAB_STOPS, pcurrRecord, pr);
  310.     }
  311. }
  312.  
  313.  
  314. /*************************************************************************/
  315. /***                             Main Loop                             ***/
  316. /*************************************************************************/
  317.  
  318. void main_dict (short SharedDict)
  319. {
  320.     VDict v_dict = (VDict)0;
  321.     VDict * pvdict;
  322.  
  323.     pvdict = &v_dict;
  324.  
  325.     printf ("Getting a new dict...");
  326.     VDict_New( SharedDict, pvdict );
  327.  
  328.     printf ("Done.\n");
  329.     TestLoop(pvdict);
  330. }
  331.  
  332. int _CRTAPI1
  333. main(int argc, char *argv[])
  334. {
  335.     RPC_STATUS status;
  336.     unsigned char * pszUuid             = NULL;
  337.     unsigned char * pszProtocolSequence = "ncacn_np";
  338.     unsigned char * pszNetworkAddress   = NULL;
  339.     unsigned char * pszEndpoint         = "\\pipe\\dict";
  340.     unsigned char * pszOptions          = NULL;
  341.     unsigned char * pszStringBinding    = NULL;
  342.     short Shared_Dictionary = 0;  // Share an existing dictionary?
  343.     int i;
  344.  
  345.     printf ("Microsoft RPC demo Client - Splay (Binary) Tree DataBase\n");
  346.  
  347.     for (i = 1; i < argc; i++) {
  348.         if ((*argv[i] == '-') || (*argv[i] == '/')) {
  349.             switch (tolower(*(argv[i]+1))) {
  350.             case 'n':  // network address
  351.                 pszNetworkAddress = argv[++i];
  352.                 break;
  353.             case 's':
  354.                 Shared_Dictionary = 1;
  355.                 break;
  356.             case 'v':
  357.                 view = argv[++i];
  358.                 break;
  359.             case 'h':
  360.             case '?':
  361.             default:
  362.                 Usage();
  363.             }
  364.         }
  365.         else
  366.             Usage();
  367.     }
  368.  
  369.     /* The dict_ProtocolStack contains a partially initialized
  370.      * protocol stack for the dict interface.  Fill in the
  371.      * remaining fields:
  372.      */
  373.  
  374.     status = RpcStringBindingCompose(pszUuid,
  375.                                      pszProtocolSequence,
  376.                                      pszNetworkAddress,
  377.                                      pszEndpoint,
  378.                                      pszOptions,
  379.                                      &pszStringBinding);
  380.     if (status) {
  381.         printf("RpcStringBindingCompose returned 0x%x\n", status);
  382.         return(status);
  383.     }
  384.  
  385.     status = RpcBindingFromStringBinding(pszStringBinding,
  386.                                          &dict_IfHandle);
  387.     if (status) {
  388.         printf("RpcBindingFromStringBinding returned 0x%x\n", status);
  389.         return(status);
  390.     }
  391.  
  392.     status = RpcStringFree(&pszStringBinding);  // remote calls done; unbind
  393.     if (status) {
  394.         printf("RpcStringFree returned 0x%x\n", status);
  395.         return(status);
  396.     }
  397.  
  398.     RpcTryExcept {
  399.        main_dict(Shared_Dictionary);
  400.     }
  401.     RpcExcept(1) {
  402.        printf("RPC runtime raised exception 0x%x\n", RpcExceptionCode());
  403.     }
  404.     RpcEndExcept
  405.  
  406.     status = RpcBindingFree(&dict_IfHandle);  // remote calls done; unbind
  407.     if (status) {
  408.         printf("RpcBindingFree returned 0x%x\n", status);
  409.         return(status);
  410.     }
  411.  
  412.     return(0);
  413.  
  414. }
  415.