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