⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 udldcfg.c

📁 工业组态软件modbus驱动源代码, 包括帮助文件.共享.
💻 C
📖 第 1 页 / 共 5 页
字号:
        return -1;
    if (a->msBitPos > b->msBitPos)
        return 1;

    /* bit positions same, compare subtypes */
    if (a->msSubType < b->msSubType)
        return -1;
    if (a->msSubType > b->msSubType)
        return 1;

    /*********************************************************\
        If additional fields have been defined which should
        be used in symbol table sorting, add the required
        code here.
    \*********************************************************/

    /* everything else same, compare data base handles */
    if (a->msDbHnd < b->msDbHnd)
        return -1;
    if (a->msDbHnd > b->msDbHnd)
        return 1;

    /* everything is the same, indicate equal */
    return 0;
} /* LogicalAddrCmp */

/***********************************************************************/
/** perform logical address comparison in a chain search
    returns -1, 0, +1 for <, =, >        **/

int FAR CompareSymbols (LPCHAINLINK item, LPCHAINLINK new_item)
{
    return (LogicalAddrCmp ((SYMPTR) item, (SYMPTR) new_item));
} /* CompareSymbols */

/***********************************************************************/
/** allocate an extensible array on the heap
    attempt to allocate memory
    returns pointer to first member if successful **/

LPHVOID FAR AllocateHeapArray (LPEXTARRAY array)
{
    unsigned long newSize;
    LPHVOID firstPtr;

    /* initialize return value */
    firstPtr = NULL;

    if (array != NULL) {
        /* attempt to allocate initial array */
        if ((array->member_size > 0) &&
            (array->init_count > 0)) {
            newSize = array->init_count * array->member_size;
            firstPtr = wwHeap_AllocPtr (hHeap,
                                        GMEM_MOVEABLE | GMEM_ZEROINIT,
                                        newSize);
        }
    }

    /* return pointer, if successful */
    return (firstPtr);
} /* AllocateHeapArray */

/***********************************************************************/
/** extend an extensible array on the heap
    attempt to allocate memory
    returns new pointer to first member if successful **/

LPHVOID FAR ExtendHeapArray (LPEXTARRAY array)
{
    unsigned long newCount;
    unsigned long newSize;
    LPHVOID newFirst;

    /* initialize return value */
    newFirst = NULL;

    if (array != NULL) {
        /* if array is extensible, attempt to reallocate memory */
        if ((array->first_member != NULL) &&
            (array->member_size > 0) &&
            (array->extension_count > 0)) {
            newCount = array->member_count + array->extension_count;
            newSize = newCount * array->member_size;
            newFirst = wwHeap_ReAllocPtr (hHeap,
                                        array->first_member,
                                        GMEM_MOVEABLE | GMEM_ZEROINIT,
                                        newSize);
        }
    }

    /* return pointer, if successful */
    return (newFirst);
} /* ExtendHeapArray */

/***********************************************************************/
/** delete an extensible array on the heap
    returns TRUE if successful **/

BOOL FAR DeleteHeapArray (LPEXTARRAY array)
{
    BOOL status;

    /* initialize return value */
    status = FALSE;

    if (array != NULL) {
        if (array->first_member != NULL) {
            /* free the memory used for the array */
            wwHeap_FreePtr (hHeap, array->first_member);
            status = TRUE;
        }
    }

    /* indicate success or failure */
    return (status);
} /* DeleteHeapArray */

/***********************************************************************/
/** add a new symbol to symbol table for indicated topic
    returns index+SYM_OFFSET of symbol if successful, 0 otherwise **/

unsigned long
WINAPI
UdprotAddSymbol(LPSTAT lpTopic, /* pointer to topic data struct */
                LPPPS lpPps,    /* pointer to point parameters  */
                HDB hDb)        /* data base handle to keep with point */
{
    /******************************************************************
     * Symbol Table (in lpTopic):
     *
     *   lpTopic->statSymTab is an extensible array of symbol entries
     *       SYM[0], SYM[1], ..., SYM[member_count-1]
     *
     *   lpTopic->statSymUnused is a chain of free entries, i.e. NOT in use
     *       SYM[X] <--> SYM[Y] <--> ... <--> SYM[Z]
     *
     *   lpTopic->statSymUsed is a SORTED chain of symbols being used
     *       SYM[A] <--> SYM[B] <--> ... <--> SYM[lEntries]
     *
     * When a new symbol is needed, an entry is taken off the free chain
     * and inserted at the proper place in the chain of symbols being used.
     * If the free chain is empty, the array is extended (if possible)
     * to put new items in the free chain.
     ******************************************************************/

    int            order;    
    unsigned long  i, old_count, new_count, newEnt;
    unsigned long  uFloor, uCeiling, uCompare;
    SYMPTR         lpSymTab, lpSymEnt, lpCompareEnt;
    LPCHAIN        lpUsed_symbols, lpUnused_symbols;
    LPEXTARRAY     lpSymbol_table, lpSymbol_index;
    CHAINSCANNER   symbol_scanner;
    unsigned long huge *lpSymIndex;

    /* get pointers to symbol table, chains */
    lpSymbol_table   = &lpTopic->statSymTab;
    lpSymbol_index   = &lpTopic->statSymInd;
    lpUsed_symbols   = &lpTopic->statSymUsed;
    lpUnused_symbols = &lpTopic->statSymUnused;

    /* check number of unused symbol table entries */
    if (lpUnused_symbols->item_count == 0) {
        /* Symbol table is full or hasn't yet been allocated */

        /* check number of entries in symbol table array */
        old_count = lpSymbol_table->member_count;
        if (old_count + SYMTABQUANTUM >= SYMTABMAXCOUNT) {
            /* extending the table would overflow the allowable size */
            return (0);
        }

        /* attempt to allocate or extend the symbol table array */
        lpSymTab = (SYMPTR) ExtendExtArray (lpSymbol_table);
        if ( lpSymTab == NULL ) {
            /* could not allocate the necessary memory */
            WWDisplayOutofMemory( (LPSTR)"Symbol table", GetAppName());
            return (0);
        }
        new_count = lpSymbol_table->member_count;

        /* attempt to allocate or extend the used symbol index array */
        while (lpSymbol_index->member_count < new_count) {
            lpSymIndex = (unsigned long huge *) ExtendExtArray (lpSymbol_index);
            if (lpSymIndex == NULL) {
                /* could not allocate the necessary memory */
                WWDisplayOutofMemory( (LPSTR)"Symbol indexes", GetAppName());
                return (0);
            }
        }

        /* update base address for the lists of used and unused entries */
        SetChainBase (lpUsed_symbols,   lpSymTab);
        SetChainBase (lpUnused_symbols, lpSymTab);

        /* set up newly allocated entries in the list of unused entries */
        for (i = old_count; i < new_count; i++) {
            /* store index of array member in symbol entry */
            lpSymEnt = &lpSymTab[i];
            lpSymEnt->msIndex = i;
            /* append symbol entry to list of unused symbols */
            AppendItemAtTail (lpUnused_symbols, (LPCHAINLINK) lpSymEnt);
        }
    }

    /* Allocate a new entry from the free list */
    lpSymEnt = (SYMPTR) FindFirstItem (lpUnused_symbols, SCAN_FROM_HEAD,
                                       NULL, NULL, &symbol_scanner);
    if (lpSymEnt == NULL) {
        /* unable to get a symbol entry -- this is a problem! */
        return (0);
    }

    /* found a free entry, take it off the free list */
    if (!UnchainItem (lpUnused_symbols, (LPCHAINLINK) lpSymEnt)) {
        /* couldn't remove item from free list -- this is a problem! */
        return (0);
    }

    /* get index of newly allocated entry */
    newEnt = lpSymEnt->msIndex;

    /* store data base handle, point description in symbol entry */
    lpSymEnt->msDbHnd       = hDb;
    lpSymEnt->msLockCt      = 0;
    lpSymEnt->msActive      = FALSE;
    lpSymEnt->msBadBCDRead  = FALSE;
    lpSymEnt->msPollMsg     = (LPUDMSG) NULL;
    /******************************************************************\
       Fill in the driver dependent fields of the symbol table entry
       as required by your driver.
    \******************************************************************/
    lpSymEnt->msPlcDataType = lpPps->ppsPlcDataType;
    lpSymEnt->msAddr1       = lpPps->ppsAlias;
    lpSymEnt->msCount       = lpPps->ppsCount;
    lpSymEnt->msBitPos      = lpPps->ppsBitPos;
    lpSymEnt->msSubType     = lpPps->ppsSubType;
    lpSymEnt->msNumBytes    = lpPps->ppsNumBytes;
    lpSymEnt->msDdeType     = lpPps->ppsDdeType;

#ifdef nocode
    /* insert entry into sorted chain */
    if (!InsertItemInMiddle (lpUsed_symbols,
                             (LPCHAINLINK) lpSymEnt, /* new entry */
                             CompareSymbols,         /* address comparison */
                             TRUE)) {                /* forward direction */
        /* unable to insert new item -- this is a problem ! */
        return (0);
    }
    return (newEnt+SYM_OFFSET);        /* return array index+SYM_OFFSET */
#endif

    /**********************************************************************
     * Link the new entry into the sorted list.
     * The list is kept in ascending order according to the sort criteria
     * setup in the function LogicalAddrCmp.
     * As of version 5.0 of the toolkit, this sample server includes
     * a binary search for the symbol below.
     *********************************************************************/

    lpSymTab   = (SYMPTR) lpSymbol_table->first_member;
    lpSymIndex = (unsigned long huge *) lpSymbol_index->first_member;
    old_count  = lpUsed_symbols->item_count;

    if (old_count == 0) {
        /* this is the first (only) entry in the symbol table */
        /* put item in chain of used symbols, store index in ordered array */
        AppendItemAtTail (lpUsed_symbols, (LPCHAINLINK) lpSymEnt);
        lpSymIndex[0] = newEnt;
        return (newEnt+SYM_OFFSET);    /* return array index+SYM_OFFSET */
    } else {
        /** there are other symbols already used,
            perform binary search for proper insertion point */
        uFloor = 0;                              /* binary search floor */
        uCeiling = old_count - 1;                /* binary search ceiling */
        uCompare = (uFloor + uCeiling) >> 1;     /* divide by 2 */

        for(;;) {
            /* get pointer to symbol in used list */
            lpCompareEnt = &lpSymTab[lpSymIndex[uCompare]];
            /* compare used symbol's address to new symbol's address */
            order = LogicalAddrCmp(lpSymEnt, lpCompareEnt);
            if (order < 0) {
                /* new entry goes somewhere before lpCompareEnt */
                if( uCompare == uFloor ) {
                    /* add new point before lpCompareEnt */
                    InsertItemBefore (lpUsed_symbols,
                                      (LPCHAINLINK) lpSymEnt,
                                      (LPCHAINLINK) lpCompareEnt);
                    /** move index from uCompare back one notch
                        to make room for index of new entry **/
                    _fmemmove( &lpSymIndex[uCompare+1],
                               &lpSymIndex[uCompare],
                               (size_t) ((old_count - uCompare) * sizeof(unsigned long)) );
                    lpSymIndex[uCompare] = newEnt;       /* new index entry */
                    return (newEnt+SYM_OFFSET);    /* return array index+SYM_OFFSET */
                } else {
                    /* keep looking before lpCompareEnt */
                    uCeiling = uCompare;                 /* new ceiling */
                    uCompare = (uFloor + uCeiling) >> 1; /* new comparison entry */
                }
            } else {
                /* new entry goes somewhere after lpCompareEnt */
                if( uCompare == uCeiling ) {
                    /* add new point after uCompare */
                    InsertItemAfter (lpUsed_symbols,
                                     (LPCHAINLINK) lpSymEnt,
                                     (LPCHAINLINK) lpCompareEnt);
                    if (uCompare < old_count - 1) {
                        /** move index from uCompare+1 back one notch
                            to make room for index of new entry **/
                        _fmemmove( &lpSymIndex[uCompare+2],
                                   &lpSymIndex[uCompare+1],
                                   (size_t) ((old_count-1 - uCompare) * sizeof(unsigned long)) );
                    }
                    lpSymIndex[uCompare+1] = newEnt;     /* new index entry */
                    return (newEnt+SYM_OFFSET);   /* return array index+SYM_OFFSET */
                } else {
                    /* check whether already at uFloor */
                    if (uCompare == uFloor) {
                        /* force end of loop */
                        uCompare = uFloor = uCeiling;
                    } else {
                        /* keep looking after lpCompareEnt */
                        uFloor = uCompare;                   /* new floor */
                        uCompare = (uFloor + uCeiling) >> 1; /* new comparison entry */
                    }
                }
            }       /* end - else (order >= 0) */
        }           /* end - for (;;) */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -