|
|
1.1 root 1: /*************************************************************/
2: /** **/
3: /** Microsoft RPC Examples **/
4: /** Dictionary Application **/
1.1.1.2 root 5: /** Copyright(c) Microsoft Corp. 1992 **/
1.1 root 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>
1.1.1.4 ! root 31: #include <stdio.h>
1.1 root 32: #include <string.h>
33: #include <ctype.h>
34:
1.1.1.4 ! root 35: #include "replay.h" // header file generated by MIDL compiler
1.1 root 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:
1.1.1.4 ! root 46:
1.1 root 47: void Usage()
48: {
1.1.1.4 ! root 49: printf("Usage : client -s\n");
! 50: printf(" -n <server_name>\n");
! 51: printf(" -v <view_option>\n");
1.1 root 52: exit(1);
53: }
54:
55: /*************************************************************************/
56: /*** Remote Dictionary Print ***/
57: /*************************************************************************/
58:
59: void
1.1.1.4 ! root 60: RevPrinTree(
! 61: int lmargin, /* indentation of the root of the tree */
1.1 root 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: {
1.1.1.4 ! root 66: static char lspaces[] =
1.1 root 67: " ";
1.1.1.3 root 68:
69:
1.1 root 70:
1.1.1.4 ! root 71: if (np == NULL)
! 72: return;
! 73:
! 74: RevPrinTree(lmargin+indent, indent, np->left, print);
1.1 root 75:
76: if (lmargin > sizeof(lspaces))
1.1.1.4 ! root 77: lmargin = sizeof(lspaces);
1.1 root 78:
79: lspaces[lmargin] = 0;
80: printf(lspaces);
81: lspaces[lmargin] = ' ';
82:
83: (*print)(np->item);
84:
1.1.1.4 ! root 85: RevPrinTree(lmargin+indent, indent, np->right, print);
1.1 root 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: {
1.1.1.4 ! root 96: if (np == NULL)
! 97: return;
1.1 root 98:
99: LinPrinTree(np->left, print, local, global);
100:
1.1.1.4 ! root 101: if (comp(np->item, local) == 0) {
! 102: if (comp(np->item, global) == 0)
1.1 root 103: printf(" ==>> ");
104: else
105: printf(" >> ");
1.1.1.4 ! root 106: }
! 107: else if (comp(np->item, global) == 0)
! 108: printf(" == ");
! 109: else
! 110: printf(" ");
1.1 root 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") )
1.1.1.4 ! root 132: prinTree(0,
! 133: TAB_STOPS,
! 134: (TreeNode *) prd->root,
! 135: printRecord);
1.1 root 136: else if ( !strcmp(view, "reverse") || !strcmp(view, "rev") )
1.1.1.4 ! root 137: RevPrinTree(0,
! 138: TAB_STOPS,
! 139: (TreeNode *) prd->root,
! 140: printRecord);
1.1 root 141: else if ( !strcmp(view, "flat") )
1.1.1.4 ! root 142: LinPrinTree((TreeNode *) prd->root,
! 143: printRecord,
! 144: local,
! 145: RDICT_CURR_RECORD(prd));
1.1 root 146:
147: RDict_Free_Dict(prd);
148: }
149:
150: /*************************************************************************/
151: /*** Remote Dictionary Test Loop ***/
152: /*************************************************************************/
153:
154: void
155: Usage_Msg()
156: {
1.1.1.2 root 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");
1.1 root 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;
1.1.1.4 ! root 186:
1.1 root 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)
1.1.1.4 ! root 230:
1.1 root 231: status = VDict_Next(*pvd, &pcurrRecord);
232: break;
233:
234: case 'p':
235: // get previous record (retreat private (local) iterator)
1.1.1.4 ! root 236:
1.1 root 237: status = VDict_Prev(*pvd, &pcurrRecord);
238: break;
239:
240: case 'r':
241: // Reset local iterator to global "current item"
1.1.1.4 ! root 242:
1.1 root 243: status = VDict_Curr_Item(*pvd, &pcurrRecord);
244: break;
245:
246: case 'N':
247: // get Next record (advance global iterator)
1.1.1.4 ! root 248:
1.1 root 249: status = VDict_Curr_Next(*pvd, &pr);
250: pr = &r;
251: break;
252:
253: case 'P':
254: // get Previous record (retreat global iterator)
1.1.1.4 ! root 255:
1.1 root 256: status = VDict_Curr_Prev(*pvd, &pr);
257: pr = &r;
258: break;
259:
1.1.1.4 ! root 260: case 'f':
! 261: // Find <key>
! 262:
! 263: status = VDict_Find(*pvd, &pr);
! 264: pr = &r;
! 265: break;
! 266:
1.1 root 267: case 'i':
268: // Insert <key>
1.1.1.4 ! root 269:
1.1 root 270: status = VDict_Insert(*pvd, pr);
271: break;
272:
273: case 'I':
274: // Insert (<num'>,"") for all num' s.t. 3 < num' < num
1.1.1.4 ! root 275:
1.1 root 276: status = VDict_I_Dict(*pvd, pr->key);
277: break;
278:
279: case 'd':
280: // Delete <key>
1.1.1.4 ! root 281:
1.1 root 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
1.1.1.4 ! root 290:
1.1 root 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
1.1.1.4 ! root 299:
1.1 root 300: status = VDict_X_Dict(*pvd);
301: break;
302:
303: case '?':
304: Usage_Msg();
305: break;
306: }
1.1.1.4 ! root 307:
1.1 root 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:
1.1.1.2 root 325: printf ("Getting a new dict...");
1.1 root 326: VDict_New( SharedDict, pvdict );
1.1.1.2 root 327:
328: printf ("Done.\n");
1.1 root 329: TestLoop(pvdict);
330: }
331:
1.1.1.4 ! root 332: int _CRTAPI1
! 333: main(int argc, char *argv[])
1.1 root 334: {
335: RPC_STATUS status;
1.1.1.4 ! root 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;
1.1.1.2 root 344:
345: printf ("Microsoft RPC demo Client - Splay (Binary) Tree DataBase\n");
1.1 root 346:
1.1.1.4 ! root 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: }
1.1 root 368:
369: /* The dict_ProtocolStack contains a partially initialized
1.1.1.4 ! root 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 {
1.1.1.2 root 399: main_dict(Shared_Dictionary);
1.1.1.4 ! root 400: }
! 401: RpcExcept(1) {
! 402: printf("RPC runtime raised exception 0x%x\n", RpcExceptionCode());
! 403: }
1.1.1.2 root 404: RpcEndExcept
1.1.1.4 ! root 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: }
1.1 root 411:
1.1.1.4 ! root 412: return(0);
1.1 root 413:
414: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.