|
|
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 <stdio.h>
10: #include <malloc.h>
11: #include <stdlib.h>
12: #include <string.h>
13: #include <ctype.h>
1.1.1.2 ! root 14:
! 15: #ifdef NTENV
1.1 root 16: #include <windows.h>
1.1.1.2 ! root 17: // #define printf DbgPrint
! 18: #endif // NTENV
1.1 root 19:
20: #include <rpc.h>
1.1.1.2 ! root 21: // #include <rpcbse.h>
! 22: // #include <rpcndr.h>
! 23: // #include <rpcnterr.h>
! 24:
1.1 root 25: #include "dict0.h"
26:
27: #ifndef _LOCAL
28: #include "replay.h"
29: #else
30: #include "play.h"
31: #endif // _LOCAL
32:
33: #include "util0.h"
34:
35: #define SIZE 2000
36: #define TAB_STOPS 3
37:
38: /*************************************************************************/
39: /*** RecordNode / RecordTree free routines ***/
40: /*************************************************************************/
41:
42: void
43: RecordTreeNodeFree(
44: IN RecordTreeNode * node
45: )
46: {
47: if(node == NULL) return;
48:
49: MIDL_user_free( node->item->name );
50: MIDL_user_free( node->item );
51: node->left = NULL;
52: node->right = NULL;
53: MIDL_user_free( node );
54: }
55:
56: void
57: RecordTreeFree(
58: IN RecordTreeNode * node
59: )
60: {
61: if(node == NULL) return;
62:
63: if (node->left != NULL) {
64: RecordTreeFree(node->left); }
65: if (node->right != NULL) {
66: RecordTreeFree(node->right); }
67: RecordTreeNodeFree( node );
68: }
69:
70: VDict_Status
71: RDict_Free_Dict(
72: IN OUT RDict * r_dict
73: )
74: {
75: RecordTreeFree( r_dict->root );
76: return(DICT_SUCCESS);
77: }
78:
79: /*************************************************************************/
80: /*** State Allocate / Free routines ***/
81: /*************************************************************************/
82:
83: DictState * allocate_state(void)
84: {
85: DictState * pstate = (DictState*) MIDL_user_allocate(sizeof(DictState));
86:
87: pstate->curr_record = (Record*) MIDL_user_allocate(sizeof(Record));
88: pstate->curr_record->name = (char*) MIDL_user_allocate(81 * sizeof(char));
89:
90: // initialize curr_record to "minus infinity" in the order
91: pstate->curr_record->key = -1;
92: strcpy(pstate->curr_record->name, "");
93: pstate->ref_count = 0;
94:
95: return(pstate);
96: }
97:
98: void free_state(DictState * state)
99: {
100: if (state != NULL) {
101: if (state->curr_record != NULL) {
102: if (state->curr_record->name != NULL)
103: MIDL_user_free(state->curr_record->name);
104: MIDL_user_free(state->curr_record);
105: }
106: MIDL_user_free(state);
107: }
108: }
109:
110: /*************************************************************************/
111: /*** Rdict Duplicate utilities ***/
112: /*************************************************************************/
113:
114:
115: RDict *
116: RDict_Duplicate(
117: IN RDict * src
118: )
119: {
120: RDict * dst = (RDict*)MIDL_user_allocate(sizeof(RDict));
121:
122: dst->root = (RecordTreeNode*)Tree_Duplicate((TreeNode*)src->root);
123: dst->size = src->size;
124: dst->state = DictState_Duplicate(src->state);
125: return( dst );
126: }
127:
128: DictState *
129: DictState_Duplicate(
130: IN DictState * src
131: )
132: {
133: DictState * dst = (DictState*) MIDL_user_allocate(sizeof(DictState));
134: dst->curr_record = ItemDuplicate(src->curr_record);
135: dst->ref_count = src->ref_count;
136:
137: return(dst);
138: }
139:
140: TreeNode *
141: TreeNode_Duplicate(
142: IN TreeNode * src
143: )
144: {
145: TreeNode * pnode = (TreeNode*) MIDL_user_allocate(sizeof(TreeNode));
146:
147: pnode->left = pnode->right = NULL;
148: pnode->item = ItemDuplicate(src->item);
149: return ( pnode );
150: }
151:
152: TreeNode *
153: Tree_Duplicate(
154: IN TreeNode * src
155: )
156: {
157: TreeNode * dst;
158:
159: if (src == NULL) return((TreeNode*)NULL);
160:
161: dst = TreeNode_Duplicate(src);
162: dst->left = Tree_Duplicate(src->left);
163: dst->right = Tree_Duplicate(src->right);
164: return ( dst );
165: }
166:
167: /*************************************************************************/
168: /*** MIDL_user_allocate / MIDL_user_free ***/
169: /*************************************************************************/
170:
171: void *
1.1.1.2 ! root 172: MIDL_user_allocate(size_t count)
1.1 root 173: {
174:
175: unsigned char * ptr;
176: ptr = malloc( count );
177: return ( ptr );
178:
179: }
1.1.1.2 ! root 180:
! 181: void
! 182: MIDL_user_free(void * p)
! 183: {
! 184: free (p);
! 185: }
! 186:
! 187: /*
1.1 root 188:
189: void *
1.1.1.2 ! root 190: MIDL_user_allocate(size_t count)
1.1 root 191: {
192:
193: unsigned char *ptr, *old;
194: unsigned long delta = 0;
195:
196: ptr = old = malloc( (size_t)(count+7) );
197:
198: // Normalize: modify ptr to the next (0 mod 4) address
199: ptr += 3;
200: *(unsigned long *)&ptr &= 0xfffffffc;
201:
202: // ptr is now aligned on a (0 mod 4) boundary, and we have at least
203: // 4 extra bytes, for the decrement (delta) and count values
204:
205: // delta = 4 - the remainder of ptr mod 4
206: // decrement to restore the original pointer value
207: // delta = 4LU - ((unsigned long)ptr - (unsigned long)old);
208: delta = 4 - ((unsigned long) ptr) & 0x00000003;
209:
210: // correct for the exception case:
211: if (delta == 4) delta = 0;
212:
213: // store the count in the first two bytes:
214: *(short*)ptr = (short)count;
215: ptr += 2;
216:
217: // store the difference between the count point and the original
218: // pointer in the next two bytes:
219: *(short*)ptr = (short)delta;
220: ptr += 2;
221: return( ptr );
222:
223: // return(malloc(count));
224: }
225:
226: void
227: MIDL_user_free(void * p)
228: {
229:
230: short * pdelta = ((short*)p-1);
231: short * pcount = ((short*)p-2);
232: char * ptr = (char*)pcount - (*pdelta);
233: int i;
234:
235: for(i = *pcount; i; ptr[--i] = '\0')
236: ;
237: free (ptr);
238: }
239:
1.1.1.2 ! root 240: */
! 241:
1.1 root 242: /*************************************************************************/
243: /*** Utility functions ***/
244: /*************************************************************************/
245:
246: /* In the most general case *cmp is a two argument function:
247: (*cmp)(void *item0, void *item1) which compares two items,
248: and returns: -1 if item0 < item1;
249: 0 if item0 == item1;
250: +1 if item0 > item1.
251: The common case is: each item has a field named "key";
252: item.key is of type long, or string.
253: */
254:
255: int
256: comp(void* x, void* y)
257: {
258: int res = ((Record*)x)->key - ((Record*)y)->key;
259:
260: if (res == 0)
261: return( strcmp( ((Record*)x)->name, ((Record*)y)->name ) );
262: else
263: return( res ) ;
264: }
265:
266: Record *
267: ItemDuplicate(
268: Record * item
269: )
270: {
271: // Record * pR;
272: // pR = makeRecord( item->key, item->name );
273: // return(pR);
274:
275: if (item == NULL) return(NULL);
276: return ( makeRecord( item->key, item->name ) );
277: }
278:
279: Record *
280: makeRecord(
281: short key,
282: char * name
283: )
284: {
285: Record * pr = (Record*) MIDL_user_allocate(sizeof(Record));
1.1.1.2 ! root 286:
! 287: if (!name)
! 288: printf("makeRecord: NULL name\n");
! 289:
1.1 root 290: pr->name = (char*) MIDL_user_allocate(strlen(name)+1);
291: strcpy(pr->name, name);
292: pr->key = key;
293: return(pr);
294: }
295:
296: void
297: freeRecord(
298: Record * pr
299: )
300: {
301: if (pr != NULL) {
302: if (pr->name != NULL)
303: MIDL_user_free(pr->name);
304: MIDL_user_free(pr);
305: }
306: }
307: void
308: ItemCopy(
309: IN Record * src,
310: OUT Record * dest
311: )
312: { int i;
313:
314: dest->key = src->key;
315: // copy name, trubcated to 80 characters
316: for(i=0 ; (src->name[i] != '\0') && (i<80) ; i++)
317: dest->name[i]=src->name[i];
318:
319: dest->name[i]='\0';
320: }
321:
322: void
323: printRecord(void* rp)
324: {
325: printf("%d : %s\n", ((Record*)rp)->key, ((Record*)rp)->name);
326: }
327:
328: void
329: Dict_Print( /* prints the binary tree (indented right subtree,
330: followed by the root, followed by the indented
331: right dubtree) */
332: Dictionary * dp,
333: int indent) /* number of spaces to indent subsequent levels */
334: {
335: prinTree(0, indent, dp->root, dp->print_rec);
336: }
337:
338: char spaces[] =
339: " ";
340:
341:
342:
343:
344:
345:
346: void
347: prinTree(int lmargin, /* indentation of the root of the tree */
348: int indent, /* indentation of subsequent levels */
349: TreeNode *np, /* pointer to the root node */
350: PrintFun print) /* short, one line, record print routine */
351: {
1.1.1.2 ! root 352: int i;
1.1 root 353: if (np == NULL) return;
354:
355: prinTree(lmargin+indent, indent, np->right, print);
356:
357: if (lmargin > sizeof(spaces))
358: lmargin = sizeof(spaces);;
359:
360: spaces[lmargin] = 0;
361: printf(spaces);
362: spaces[lmargin] = ' ';
363:
364: (*print)(np->item);
365:
366: prinTree(lmargin+indent, indent, np->left, print);
367:
368: }
369:
370: TreeNode*
371: makeNode(void * item)
372: {
373: TreeNode* tp;
374: tp = (TreeNode*)MIDL_user_allocate(sizeof(TreeNode));
375: tp->item = item;
376: tp->left = tp->right = NULL;
377: return(tp);
378: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.