|
|
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.