Annotation of mstools/samples/rpc/dict/replay.c, revision 1.1.1.3

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: /***                                                                   ***/
1.1.1.3 ! root       11: /***  Example dictionary using splay trees:                            ***/
1.1       root       12: /***                                                                   ***/
                     13: /*************************************************************************/
                     14: 
                     15: #include <stdlib.h>
1.1.1.3 ! root       16: #include <stdio.h>
1.1       root       17: #include <string.h>
                     18: 
1.1.1.3 ! root       19: #include "replay.h"    // header file generated by MIDL compiler
1.1       root       20: #include "dict0.h"
                     21: #include "util0.h"
                     22: 
                     23: #define TAB_STOPS 3
                     24: 
                     25: /*************************************************************************/
                     26: /***                   Declarations (from replay.h)                    ***/
                     27: /*************************************************************************/
                     28: 
                     29: /*
                     30: typedef struct _Record {
                     31:     short key;                      // RPC "generation"
                     32:     [string] char* name;            // contributor
                     33: } Record;
                     34: 
                     35: typedef struct _RecordTreeNode RecordTreeNode;
                     36: 
                     37: typedef struct _RecordTreeNode {
                     38:     RecordTreeNode *left;           // left child pointer
                     39:     RecordTreeNode *right;          // right child pointer
                     40:     Record *item;                   // pointer to a Record structure
                     41: } RecordTreeNode;
                     42: 
                     43: typedef struct _RDict {
                     44:     RecordTreeNode *root;           // pointer to the root of a SAT
                     45:     long size;                      // number of records in dictionary
                     46: } RDict;
                     47: 
                     48: // RDict is used for marshalling a complete dictionary.
                     49: 
                     50: typedef enum {
                     51:     DICT_SUCCESS,
                     52:     DICT_ITEM_ALREADY_PRESENT,
                     53:     DICT_ITEM_NOT_FOUND,
                     54:     DICT_FIRST_ITEM,
                     55:     DICT_LAST_ITEM,
                     56:     DICT_EMPTY_DICTIONARY,
                     57:     DICT_NULL_ITEM
1.1.1.3 ! root       58: } VDict_Status;
1.1       root       59: 
                     60: typedef struct _DictState {
                     61:     short ref_count;               // for shared dictionaries
                     62:     Record * curr_record;          // for global iterators
                     63: } DictState;
                     64: */
                     65: 
                     66: /*************************************************************************/
                     67: /***                   Internal state access methods                   ***/
                     68: /*************************************************************************/
                     69: 
                     70: #define RDICT_CURR_RECORD(dict) (((DictState*)dict->state)->curr_record)
                     71: 
1.1.1.3 ! root       72: #define RDICT_REF_COUNT(dict)   (((DictState*)dict->state)->ref_count)
1.1       root       73: 
1.1.1.3 ! root       74: #define RDICT_STATE(dict)       (((RDict*)dict)->state)
1.1       root       75: 
                     76: static int active_dictionary = 0;
                     77: 
                     78: /*************************************************************************/
                     79: /***    Generic Dictionary Operations: (From dict0.h)                  ***/
                     80: /***                                                                   ***/
                     81: /***    Dictionary *Dict_New(Cmp_rec*, Splay*, print_rec*)             ***/
                     82: /***                                                                   ***/
                     83: /***    Dict_Status Dict_Find(Dictionary*, Item*)                      ***/
                     84: /***    Dict_Status Dict_Next(Dictionary*, Item*)                      ***/
                     85: /***    Dict_Status Dict_Prev(Dictionary*, Item*)                      ***/
                     86: /***    Dict_Status Dict_Insert(Dictionary*, Item*)                    ***/
                     87: /***    Dict_Status Dict_Delete(Dictionary*, Item**)                   ***/
                     88: /***                                                                   ***/
                     89: /***    Item* DICT_CURR_ITEM(Dict*)                                    ***/
                     90: /*************************************************************************/
                     91: 
                     92: /*************************************************************************/
                     93: /***    Virtual Dictionary Operations: (From replay.h)                 ***/
                     94: /***                                                                   ***/
                     95: /***    VDict_Status VDict_New(OUT VDict **)                           ***/
                     96: /***                                                                   ***/
                     97: /***    VDict_Status VDict_Find(IN VDict*, IN OUT Record**)            ***/
                     98: /***    VDict_Status VDict_Next(IN VDict*, IN OUT Record**)            ***/
                     99: /***    VDict_Status VDict_Prev(IN VDict*, IN OUT Record**)            ***/
                    100: /***    VDict_Status VDict_Insert(IN VDict*, IN Record*)               ***/
                    101: /***    VDict_Status VDict_Delete(IN VDict*, IN OUT Record**)          ***/
                    102: /***                                                                   ***/
                    103: /***    VDict_Status VDict_Curr_Item(IN VDict*, OUT Record**);         ***/
                    104: /***    VDict_Status VDict_Curr_Delete(IN VDict*, OUT Record**);       ***/
                    105: /***    VDict_Status VDict_Curr_Next(IN VDict*, OUT Record**);         ***/
                    106: /***    VDict_Status VDict_Curr_Prev(IN VDict*, OUT Record**);         ***/
                    107: /***                                                                   ***/
                    108: /***    VDict_Status VDict_Get_Dict(IN VDict*, OUT RDict**)            ***/
                    109: /*************************************************************************/
                    110: 
                    111: /*************************************************************************/
                    112: /***                   context rundown routine                         ***/
                    113: /*************************************************************************/
                    114: 
1.1.1.3 ! root      115: void __RPC_USER VDict_rundown (VDict v_dict)
1.1       root      116: {
                    117:     Dictionary * pdict = (Dictionary*) v_dict;
                    118:     short count = --RDICT_REF_COUNT(pdict);
                    119: 
                    120:     printf("# of remaining users of context: %d\n\n",
1.1.1.3 ! root      121:            RDICT_REF_COUNT(pdict) );
1.1       root      122: 
1.1.1.3 ! root      123:     if (RDICT_REF_COUNT(pdict) <= 0) {
1.1       root      124:         printf("CLOSING CONTEXT\n\n");
                    125: 
                    126:         // free the splay tree
                    127:         RDict_Free_Dict(v_dict);
                    128: 
                    129:         // free the dictionary object
1.1.1.3 ! root      130:         free_state((DictState*) pdict->state);
        !           131:         MIDL_user_free(v_dict);
        !           132:         if (count == 0)
1.1       root      133:             active_dictionary = 0;
                    134:     }
                    135: }
                    136: 
                    137: //  For now: need to allocate a new item record prior to operation,
                    138: //  for all OUT and IN OUT arguments, as the callee stub will free
                    139: //  storage allocated for such pointer parameters.
                    140: //
                    141: //  Will be fixed by the introduction of [allocate(dont_free)]
                    142: //  ACF pointer type and parameter attribute.
                    143: 
                    144: /**************************************************************************
                    145:  * VDict_New initializes a new dictionary if (1) a non shared dictionary
                    146:  * was requested, or (2) a shared dictionary was requested, but no shared
                    147:  * dictionary is currently active.  There is at most one shared dictionary
                    148:  * at any point in time.
                    149:  *
                    150:  * BUGBUG: shared dictionaries are *NOT* locked (by semaphore, to
                    151:  * serialize access to them.  They *should be, though...
                    152:  **************************************************************************
                    153: */
                    154: 
                    155: VDict_Status
                    156: VDict_New(
                    157:   IN short shared_dict,
                    158:   OUT VDict * v_dict
                    159:   )
                    160: {
                    161:     Dictionary * pdict0;
                    162:     static Dictionary * pdict;
                    163: 
                    164:     if (!active_dictionary  || !shared_dict) {
1.1.1.3 ! root      165:         // server side dictionary initialization 
1.1       root      166:         pdict0 = Dict_New(comp, tdSplay, printRecord);
                    167: 
1.1.1.3 ! root      168:         // Initializes RDICT_CURR_RECORD(pdict0) to 
        !           169:         // "minus infinity" in the order
1.1       root      170:         ((RDict*)pdict0)->state = allocate_state();
                    171: 
                    172:         Init_dict(pdict0);
                    173:         *v_dict = (VDict)pdict0;
                    174: 
                    175:         if (shared_dict) {
                    176:             printf("OPENING SHARED DICTIONARY CONTEXT!\n\n");
                    177:             active_dictionary = 1;
                    178:             pdict = pdict0;
                    179:             RDICT_REF_COUNT(pdict)++;
                    180:         } // else RDICT_REF_COUNT(pdict0) = 0;
                    181:     }
                    182:     else {
                    183:         RDICT_REF_COUNT(pdict)++;
                    184:         printf("# of users of shared context: %d\n\n", RDICT_REF_COUNT(pdict));
                    185:         *v_dict = (VDict)pdict;
                    186:     }
                    187: 
                    188:     return(DICT_SUCCESS);
                    189: }
                    190: 
                    191: VDict_Status
                    192: VDict_Find(
                    193:     IN VDict  v_dict,
                    194:     IN OUT Record ** item
                    195:     )
                    196: {
                    197:     Dictionary * pdict = (Dictionary*) (v_dict);
                    198:     Dict_Status status;
                    199: 
                    200:     status = Dict_Find(pdict, *item);
                    201:     if ( (pdict == NULL) || DICT_EMPTY(pdict) ) {
1.1.1.3 ! root      202:         *item = NULL; 
        !           203:     }
1.1       root      204:     else {
                    205:         *item = DICT_CURR_ITEM(pdict);
                    206:         *item = ItemDuplicate(*item);
                    207:     }
                    208:     return( (VDict_Status)status );
                    209: }
                    210: 
                    211: VDict_Status
                    212: VDict_Next(
                    213:     IN VDict  v_dict,
                    214:     IN OUT Record ** item
                    215:     )
                    216: // get successor of *item, and update *item to point to it
                    217: {
                    218:     Dictionary * pdict = (Dictionary*) (v_dict);
                    219:     Dict_Status status;
                    220: 
                    221:     status = Dict_Next(pdict, *item);
                    222:     if ( (pdict == NULL) || DICT_EMPTY(pdict) ) {
1.1.1.3 ! root      223:         *item = NULL; 
        !           224:     }
1.1       root      225:     else {
                    226:         if (*item == NULL)
                    227:             ItemCopy(DICT_CURR_ITEM(pdict), RDICT_CURR_RECORD(pdict));
                    228:         *item = DICT_CURR_ITEM(pdict);
                    229:     }
                    230:     *item = ItemDuplicate(*item);
                    231:     return( (VDict_Status)status );
                    232: }
                    233: 
                    234: VDict_Status
                    235: VDict_Prev(
                    236:     IN VDict  v_dict,
                    237:     IN OUT Record ** item
                    238:     )
                    239: // get predecessor of *item, and update *item to point to it
                    240: {
                    241:     Dictionary * pdict = (Dictionary*) (v_dict);
                    242:     Dict_Status status;
                    243: 
                    244:     status = Dict_Prev(pdict, *item);
                    245:     if ( (pdict == NULL) || DICT_EMPTY(pdict) ) {
1.1.1.3 ! root      246:         *item = NULL;
        !           247:     }
1.1       root      248:     else {
                    249:         if (*item == NULL)
                    250:             ItemCopy(DICT_CURR_ITEM(pdict), RDICT_CURR_RECORD(pdict));
                    251:         *item = DICT_CURR_ITEM(pdict);
                    252:     }
                    253:     *item = ItemDuplicate(*item);
                    254:     return( (VDict_Status)status );
                    255: }
                    256: 
                    257: VDict_Status
                    258: VDict_Curr_Next(
                    259:     IN VDict  v_dict,
                    260:     OUT Record ** item
                    261:     )
                    262: // get successor of RDICT_CURR_RECORD(v_dict),
                    263: // and update *item to point to it (global iterator prev)
                    264: {
                    265:     Dictionary * pdict = (Dictionary*) (v_dict);
                    266:     Dict_Status status;
                    267: 
                    268:     if ( (pdict == NULL) || DICT_EMPTY(pdict) ) {
                    269:         status = EMPTY_DICTIONARY;
1.1.1.3 ! root      270:         *item = NULL; 
        !           271:     }
1.1       root      272:     else {
                    273:         status = Dict_Next(pdict, RDICT_CURR_RECORD(pdict));
                    274:         ItemCopy(DICT_CURR_ITEM(pdict), RDICT_CURR_RECORD(pdict));
                    275:         *item = DICT_CURR_ITEM(pdict);
                    276:     }
                    277:     *item = ItemDuplicate(*item);
                    278:     return( (VDict_Status)status );
                    279: }
                    280: 
                    281: VDict_Status
                    282: VDict_Curr_Prev(
                    283:     IN VDict  v_dict,
                    284:     OUT Record ** item
                    285:     )
                    286: // get predecessor of RDICT_CURR_RECORD(v_dict),
                    287: // and update *item to point to it (global iterator prev)
                    288: {
                    289:     Dictionary * pdict = (Dictionary*) (v_dict);
                    290:     Dict_Status status;
                    291: 
                    292:     if ( (pdict == NULL) || DICT_EMPTY(pdict) ) {
                    293:         status = EMPTY_DICTIONARY;
1.1.1.3 ! root      294:         *item = NULL;
        !           295:     }
1.1       root      296:     else {
                    297:         // update RDICT_CURR_RECORD(pdict)
                    298:         status = Dict_Prev(pdict, RDICT_CURR_RECORD(pdict));
                    299:         ItemCopy(DICT_CURR_ITEM(pdict), RDICT_CURR_RECORD(pdict));
                    300:         *item = DICT_CURR_ITEM(pdict);
                    301:     }
                    302:     *item = ItemDuplicate(*item);
                    303:     return( (VDict_Status)status );
                    304: }
                    305: 
                    306: VDict_Status
                    307: VDict_Insert(
                    308:     IN VDict  v_dict,
                    309:     IN Record * item
                    310:     )
                    311: {
                    312:     Dictionary * pdict = (Dictionary*) (v_dict);
                    313:     Dict_Status status;
                    314:     Record * rp = makeRecord(item->key, item->name);
                    315: 
                    316:     status = Dict_Insert(pdict, rp); // No return value required.
                    317:     return( (VDict_Status)status );
                    318: }
                    319: 
                    320: VDict_Status
                    321: VDict_Delete(
                    322:     IN VDict  v_dict,
                    323:     IN OUT Record ** item
                    324:     )
                    325: {
                    326:     Dictionary * pdict = (Dictionary*) (v_dict);
                    327:     Dict_Status status;
                    328: 
1.1.1.3 ! root      329:     status = Dict_Delete(pdict, (void **)item);
        !           330:                                     // (*item) is returned by Dict_Delete!
1.1       root      331:     return( (VDict_Status)status );
                    332: }
                    333: 
                    334: VDict_Status
                    335: VDict_Curr_Item(
                    336:     IN VDict  v_dict,
                    337:     OUT Record ** item
                    338:     )
                    339: {
                    340:     Dictionary * pdict = (Dictionary*) (v_dict);
                    341:     Dict_Status status;
                    342: 
                    343:     if ( (pdict == NULL) || DICT_EMPTY(pdict) ) {
                    344:         status = EMPTY_DICTIONARY;
1.1.1.3 ! root      345:         *item = NULL;
        !           346:     }
1.1       root      347:     else {
                    348:         status = SUCCESS;
                    349:         *item = DICT_CURR_ITEM(pdict);
                    350:     }
                    351:     *item = ItemDuplicate(*item);
                    352:     return( (VDict_Status)status );
                    353: }
                    354: 
                    355: VDict_Status
                    356: VDict_Curr_Delete(
                    357:     IN VDict  v_dict,
                    358:     OUT Record ** item
                    359:     )
                    360: {
                    361:     Dictionary * pdict = (Dictionary*) (v_dict);
                    362:     Dict_Status status;
                    363: 
                    364:     if ( (pdict == NULL) || DICT_EMPTY(pdict) ) {
                    365:         status = EMPTY_DICTIONARY;
1.1.1.3 ! root      366:         *item = NULL; 
        !           367:     }
1.1       root      368:     else {
                    369:         *item = DICT_CURR_ITEM(pdict);
1.1.1.3 ! root      370:         status = Dict_Delete( pdict, (void **)item );
1.1       root      371:     }
                    372:     return( (VDict_Status)status );
                    373: }
                    374: 
                    375: VDict_Status
                    376: VDict_Get_Dict(
                    377:     IN VDict  v_dict,
                    378:     OUT RDict ** r_dict
                    379:     )
                    380: //  used to transmit the dictionary back to the callee
                    381: //  (In this demo program - for printing on the client side)
                    382: {
                    383:     Dictionary * pdict = (Dictionary*) (v_dict);
                    384: 
1.1.1.3 ! root      385:     if (pdict == NULL) {
        !           386:         return(DICT_EMPTY_DICTIONARY);
        !           387:     }
1.1       root      388:     else {
1.1.1.3 ! root      389:         prinTree(0, 3, pdict->root, printRecord);
1.1       root      390: 
                    391:         *r_dict = RDict_Duplicate((RDict*)pdict);
                    392:             // Duplication is done to avoid freeing the tree by
                    393:             // the callee stub.  This is a temporary fix, until we
                    394:             // implement [allocate(dont_free)]!
                    395: 
                    396:         return(DICT_SUCCESS);
                    397:     }
                    398: }
                    399: 
                    400: /*************************************************************************/
                    401: /***                        Server Utility Functions                   ***/
                    402: /*************************************************************************/
                    403: 
                    404: void
                    405: Init_dict(Dictionary * dp)
                    406: {
                    407:     Record* rp;
                    408: 
1.1.1.2   root      409:     rp = makeRecord((short)0, "jack_smith"); Dict_Insert(dp, rp);
                    410:     rp = makeRecord((short)0, "john_doe"); Dict_Insert(dp, rp);
                    411:     rp = makeRecord((short)1, "steve_johnson"); Dict_Insert(dp, rp);
                    412:     rp = makeRecord((short)2, "debbie_jones"); Dict_Insert(dp, rp);
                    413:     rp = makeRecord((short)0, "mike_jacobs"); Dict_Insert(dp, rp);
                    414:     rp = makeRecord((short)2, "bill_jackson"); Dict_Insert(dp, rp);
                    415:     rp = makeRecord((short)0, "jane_doe"); Dict_Insert(dp, rp);
                    416:     rp = makeRecord((short)1, "james_doe"); Dict_Insert(dp, rp);
                    417:     rp = makeRecord((short)1, "jean_doe"); Dict_Insert(dp, rp);
                    418:     rp = makeRecord((short)0, "joana_smith"); Dict_Insert(dp, rp);
                    419:     rp = makeRecord((short)1, "michael_jones"); Dict_Insert(dp, rp);
                    420:     rp = makeRecord((short)0, "dianne_jackson"); Dict_Insert(dp, rp);
                    421:     rp = makeRecord((short)0, "jacob_jacobson"); Dict_Insert(dp, rp);
1.1       root      422: 
                    423:     Dict_Print(dp, TAB_STOPS);
                    424: }
                    425: 
                    426: /*************************************************************************/
                    427: /***                        Play oriented Functions ...                ***/
                    428: /*** (used to empty the tree and replace it by a tree of integers      ***/
                    429: /*************************************************************************/
                    430: 
                    431: VDict_Status
                    432: VDict_X_Dict(
                    433:     IN VDict  v_dict
                    434:     )
                    435: // Empty the dictionary
                    436: {
                    437:     RDict * prdict = (RDict*)v_dict;
                    438: 
                    439:     if (DICT_EMPTY(prdict))
                    440:         return(DICT_EMPTY_DICTIONARY);
                    441: 
                    442:     RecordTreeNodeFree(prdict->root);
                    443:     prdict->root = NULL;
1.1.1.3 ! root      444:     return(DICT_SUCCESS);
1.1       root      445: }
                    446: 
                    447: VDict_Status
                    448: VDict_I_Dict(
                    449:     IN VDict  v_dict,
                    450:     IN short  size
                    451:     )
                    452: // Insert integers from 3 to a specified upper bound into the tree
                    453: {
                    454:     RDict * prdict = (RDict*)v_dict;
                    455:     Dict_Status status;
                    456:     short i;
                    457: 
                    458:     // Insert (<num'>, "") for all num' s.t. 3 < num' < num
                    459:     for (i=3; i < size; i++) {
1.1.1.3 ! root      460:         status = VDict_Insert(prdict,
        !           461:                               makeRecord(i, "<"));
        !           462:     }
1.1       root      463:     return( (VDict_Status)status );
                    464: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.