|
|
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: #include <stdlib.h>
1.1.1.3 ! root 10: #include <stdio.h>
1.1 root 11: #include <string.h>
12: #include <ctype.h>
1.1.1.2 root 13:
1.1 root 14: #ifndef _LOCAL
15: #include "replay.h"
16: #else
17: #include "play.h"
18: #endif // _LOCAL
19:
1.1.1.3 ! root 20: #include "dict0.h"
1.1 root 21: #include "util0.h"
22:
23:
24: /*************************************************************************/
25: /*** RecordNode / RecordTree free routines ***/
26: /*************************************************************************/
27:
28: void
29: RecordTreeNodeFree(
30: IN RecordTreeNode * node
31: )
32: {
1.1.1.3 ! root 33: if (node == NULL)
! 34: return;
1.1 root 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: {
1.1.1.3 ! root 48: if (node == NULL)
! 49: return;
1.1 root 50:
51: if (node->left != NULL) {
1.1.1.3 ! root 52: RecordTreeFree(node->left);
! 53: }
1.1 root 54: if (node->right != NULL) {
1.1.1.3 ! root 55: RecordTreeFree(node->right);
! 56: }
1.1 root 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 );
1.1.1.3 ! root 66:
1.1 root 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: {
1.1.1.3 ! root 110: RDict * dst = (RDict*) MIDL_user_allocate(sizeof(RDict));
1.1 root 111:
1.1.1.3 ! root 112: dst->root = (RecordTreeNode*) Tree_Duplicate((TreeNode*)src->root);
1.1 root 113: dst->size = src->size;
114: dst->state = DictState_Duplicate(src->state);
1.1.1.3 ! root 115:
! 116: return(dst);
1.1 root 117: }
118:
119: DictState *
120: DictState_Duplicate(
121: IN DictState * src
122: )
123: {
124: DictState * dst = (DictState*) MIDL_user_allocate(sizeof(DictState));
1.1.1.3 ! root 125:
1.1 root 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);
1.1.1.3 ! root 141:
! 142: return(pnode);
1.1 root 143: }
144:
145: TreeNode *
146: Tree_Duplicate(
147: IN TreeNode * src
148: )
149: {
150: TreeNode * dst;
151:
1.1.1.3 ! root 152: if (src == NULL)
! 153: return((TreeNode*)NULL);
1.1 root 154:
155: dst = TreeNode_Duplicate(src);
156: dst->left = Tree_Duplicate(src->left);
157: dst->right = Tree_Duplicate(src->right);
1.1.1.3 ! root 158: return(dst);
1.1 root 159: }
160:
161: /*************************************************************************/
162: /*** MIDL_user_allocate / MIDL_user_free ***/
163: /*************************************************************************/
164:
1.1.1.3 ! root 165: void __RPC_FAR * __RPC_API MIDL_user_allocate(size_t count)
1.1 root 166: {
1.1.1.3 ! root 167: return(malloc(count));
1.1 root 168: }
1.1.1.2 root 169:
1.1.1.3 ! root 170: void __RPC_API MIDL_user_free(void __RPC_FAR * p)
1.1.1.2 root 171: {
1.1.1.3 ! root 172: free(p);
1.1.1.2 root 173: }
174:
1.1 root 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: {
1.1.1.3 ! root 204: if (item == NULL)
! 205: return(NULL);
1.1 root 206:
1.1.1.3 ! root 207: return( makeRecord( item->key, item->name ) );
1.1 root 208: }
209:
210: Record *
211: makeRecord(
212: short key,
213: char * name
214: )
215: {
216: Record * pr = (Record*) MIDL_user_allocate(sizeof(Record));
1.1.1.2 root 217:
218: if (!name)
219: printf("makeRecord: NULL name\n");
220:
1.1 root 221: pr->name = (char*) MIDL_user_allocate(strlen(name)+1);
222: strcpy(pr->name, name);
223: pr->key = key;
1.1.1.3 ! root 224:
1.1 root 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: }
1.1.1.3 ! root 239:
1.1 root 240: void
241: ItemCopy(
242: IN Record * src,
243: OUT Record * dest
244: )
1.1.1.3 ! root 245: {
! 246: int i;
1.1 root 247:
248: dest->key = src->key;
1.1.1.3 ! root 249:
1.1 root 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
1.1.1.3 ! root 277: prinTree(
! 278: int lmargin, /* indentation of the root of the tree */
1.1 root 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: {
1.1.1.3 ! root 283: if (np == NULL)
! 284: return;
1.1 root 285:
1.1.1.3 ! root 286: prinTree(lmargin+indent, indent, np->right, print);
1.1 root 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:
1.1.1.3 ! root 297: prinTree(lmargin+indent, indent, np->left, print);
1.1 root 298:
299: }
300:
301: TreeNode*
302: makeNode(void * item)
303: {
304: TreeNode* tp;
1.1.1.3 ! root 305:
1.1 root 306: tp = (TreeNode*)MIDL_user_allocate(sizeof(TreeNode));
307: tp->item = item;
308: tp->left = tp->right = NULL;
1.1.1.3 ! root 309:
1.1 root 310: return(tp);
311: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.