📄 udldcfg.c
字号:
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 + -