Bool LArray_FetchItemAt(LArray* This, ui4 inIndex, void* outItem){ /* Range check */ if (inIndex>=This->mItemsCount) return FALSE; /* Pass back item */ LMemory_Copy(This->mData+(inIndex)*This->mItemSize,(i1 *) outItem,This->mItemSize); return TRUE; }
/* --------------------------------------------------------------------------------- * Write * --------------------------------------------------------------------------------- */ void LSystem_Write(const i1* inMsg, ui4 inSize){ if (sPrintH==NULL) fwrite(inMsg,1,inSize,stderr); else { i1* theBuf = (i1*)LMemory_Malloc(inSize+1); LMemory_Copy(inMsg,theBuf,inSize); theBuf[inSize]='\0'; sPrintH(theBuf); LMemory_Free(&theBuf); } }
static void _PrintH(const i1* inMsg){ ui4 theCount, theMsgLen, thePrevBlockLen; _TStackEntry theEntry; if (sStack==NULL) Throw(LSystem_INTERNAL_ERROR); theCount = LArray_GetItemsCount(sStack); if (theCount==0) Throw(LSystem_INTERNAL_ERROR); LArray_FetchItemAt(sStack,theCount-1,&theEntry); theMsgLen = LString_Len(inMsg); thePrevBlockLen = LArray_GetItemsCount(theEntry.mBlock); LArray_ResizeBy(theEntry.mBlock,(i4)theMsgLen); LMemory_Copy(inMsg, (i1*)LArray_GetData(theEntry.mBlock)+thePrevBlockLen, theMsgLen); }
/* --------------------------------------------------------------------------------- * CloseBlock * --------------------------------------------------------------------------------- */ void LSystem_CloseBlock(i1** outBlock,ui4* outSize){ ui4 theItemsCount; _TStackEntry theEntry; if (sStack==NULL) Throw(LSystem_INTERNAL_ERROR); theItemsCount = LArray_GetItemsCount(sStack); if (theItemsCount==0) Throw(LSystem_INTERNAL_ERROR); LArray_FetchItemAt(sStack,theItemsCount-1,&theEntry); LArray_RemoveLastItem(sStack); *outSize = LArray_GetItemsCount(theEntry.mBlock); *outBlock = (i1*)LMemory_Malloc(*outSize); LMemory_Copy(LArray_GetData(theEntry.mBlock),(void*)*outBlock,*outSize); LArray_Delete(&theEntry.mBlock); sPrintH = theEntry.mPrintH; if (theItemsCount==1) LArray_Delete(&sStack); }
void LArray_InsertItemAt(LArray* This, const void* inItem, ui4 inIndex){ /* Range adjustment */ if (inIndex > This->mItemsCount) inIndex = This->mItemsCount; /* Make room for the new entry */ LArray_ResizeBy(This,+1); /* Scroll items with indices > inIndex */ if (This->mItemsCount -1 -inIndex > 0) LMemory_Move(This->mData + (inIndex) * This->mItemSize, This->mData + (inIndex+1) * This->mItemSize, This->mItemSize * (This->mItemsCount -1 -inIndex)); /* Assign the new entry */ LMemory_Copy(inItem, This->mData+(inIndex)*This->mItemSize, This->mItemSize); }
LArray* LArray_Clone(LArray* This){ LArray* theArray; ui4 theDataSize; void* theData; theDataSize = LArray_GetDataSize(This); if (theDataSize) { theData = LMemory_Malloc(theDataSize); LMemory_Copy(LArray_GetData(This), theData, theDataSize); theArray = LArray_NewFromData(LArray_GetItemSize(This), &theData, theDataSize); } else theArray = LArray_New(LArray_GetItemSize(This)); return theArray; }
ui4 LArray_AppendItem(LArray* This, const void* inItem){ /* Make room for the new entry */ LArray_ResizeBy(This,+1); /* Copy the input item at the end of the array */ if (This->mItemSize == 4) _ui4_(This->mData+(This->mItemsCount-1)*This->mItemSize) = _ui4_(inItem); else LMemory_Copy(inItem, This->mData+(This->mItemsCount-1)*This->mItemSize, This->mItemSize); #ifdef TRACE_OPERATIONS_ LSystem_Print("LArray_AppendItem [This->mData size=%u, This->mItemsCount=%u]\n", This->mDataSize,This->mItemsCount); #endif /* Return the index of added item */ return This->mItemsCount-1; }
/* --------------------------------------------------------------------------------- * _LEdgeInfo_DeleteItemAt * --------------------------------------------------------------------------------- * Delete the info of a specified Edge*/ void _LEdgeInfo_DeleteItemAt(LEdgeInfo* This, LGraph_TEdge* inEdge) { LException* theException; ui4 theIndex; if (This == NULL) Throw(LEdgeInfo_OBJECT_NULL_POINTER); /* if installed, calls the destructor handler */ if (This->mDealloc) (*(This->mDealloc))(This, inEdge); theIndex = inEdge->mIndex; LMemory_Copy(LArray_LastItem(This->mData), LArray_ItemAt(This->mData, theIndex), LArray_GetItemSize(This->mData)); Try LArray_ResizeBy(This->mData, -1); Catch(theException) LException_Dump(theException); }
/* --------------------------------------------------------------------------------- * LEdgeInfo_AssignItemAt * --------------------------------------------------------------------------------- * Assigns the data pointed by inItem to the Edge inEdge */ void LEdgeInfo_AssignItemAt(LEdgeInfo* This, LGraph_TEdge* inEdge, const void* inItem) { /*at this point there MUST be the allocated space for the item */ LException* theException; void* thePtr; ui4 theItemSize; if (This == NULL) Throw(LEdgeInfo_OBJECT_NULL_POINTER); if (inEdge == NULL) Throw(LEdgeInfo_EDGE_NULL_POINTER); if (inItem == NULL) Throw(LEdgeInfo_ITEM_NULL_POINTER); Try { thePtr = LArray_ItemAt(This->mData, inEdge->mIndex); theItemSize = LArray_GetItemSize(This->mData); } Catch(theException) LException_Dump(theException); LMemory_Copy(inItem, thePtr, theItemSize); }
/* --------------------------------------------------------------------------------- * LQuickFind_Union * --------------------------------------------------------------------------------- * Union */ ui4 LQuickFind_Union (LQuickFind* This, ui4 inItem1, ui4 inItem2) { ui4 thelength1, thelength2; LArray *thelarray1, *thelarray2; ui4 i; ui4 *thecur_item; ui4 theset1, theset2; void *theSource, *theDest; #if LQuickFind_STATS /*updates stats...*/ This->mNumUnions++; #endif /*parameter checking...*/ if ((inItem1==LQuickFind_BAD_ITEM) || (inItem2==LQuickFind_BAD_ITEM)) return LQuickFind_BAD_ITEM; theset1=LQuickFind_Find (This, inItem1); theset2=LQuickFind_Find (This, inItem2); /*if either set doesn't exist...*/ if ((theset1==LQuickFind_BAD_ITEM) || (theset2==LQuickFind_BAD_ITEM)) return LQuickFind_BAD_ITEM; /*returns an invalid id...*/ /*if already in same set...*/ if (theset1==theset2) return theset1; //nothing to do... /*retrieves 1st tree (LArray)...*/ thelarray1=(LArray *)LHash_GetItemByKey (This->mHashTable, inItem1); /*retrieves 2nd tree (LArray)...*/ thelarray2=(LArray *)LHash_GetItemByKey (This->mHashTable, inItem2); /*gets lengths...*/ thelength1=LArray_GetItemsCount (thelarray1); thelength2=LArray_GetItemsCount (thelarray2); /*performs (balanced) union...*/ if (thelength1 >= thelength2) { /*resizes larray1...*/ LArray_ResizeBy (thelarray1, thelength2); /*gets address of first item of larray2...*/ theSource=LArray_ItemAt (thelarray2, 0); /*gets first empty slot in larray1...*/ theDest=LArray_ItemAt (thelarray1, thelength1); /*copies larray2 onto larray1...*/ LMemory_Copy (theSource, theDest, thelength2*4); #if LQuickFind_STATS /*updates stats...*/ This->mItemsMovedByUnions=This->mItemsMovedByUnions+thelength2; #endif for (i=0; i<thelength2; i++) { thecur_item=(ui4 *)LArray_ItemAt (thelarray2, i); //LArray_AppendItem (thelarray1, thecur_item); /*replaces item in hash table...*/ //LHash_InsertItem (This->mHashTable, (void *)thelarray1, *thecur_item); LHash_ReplaceItemByKey (This->mHashTable, *thecur_item, (void *)thelarray1); } LArray_Delete (&thelarray2); } else { /*renames tree as well...*/ thecur_item=(ui4 *)LArray_ItemAt (thelarray1, 0); LArray_InsertItemAt (thelarray2, thecur_item, 0); /*replaces item in hash table...*/ LHash_InsertItem (This->mHashTable, (void *)thelarray2, *thecur_item); if (thelength1>1) { /*resizes larray2...*/ LArray_ResizeBy (thelarray2, thelength1-1); /*gets address of second item of larray1...*/ theSource=LArray_ItemAt (thelarray1, 1); /*gets first empty slot in larray1...*/ theDest=LArray_ItemAt (thelarray2, thelength2+1); /*copies larray1 onto larray2...*/ LMemory_Copy (theSource, theDest, (thelength1-1)*4); } #if LQuickFind_STATS /*updates stats...*/ This->mItemsMovedByUnions=This->mItemsMovedByUnions+thelength1; #endif for (i=1; i<thelength1; i++) { thecur_item=(ui4 *)LArray_ItemAt (thelarray1, i); //LArray_AppendItem (thelarray2, thecur_item); /*replaces item in hash table...*/ //LHash_InsertItem (This->mHashTable, (void *)thelarray2, *thecur_item); LHash_ReplaceItemByKey (This->mHashTable, *thecur_item, (void *)thelarray2); } LArray_Delete (&thelarray1); } /*returns appropriate set name...*/ if (thelength1 >= thelength2) return theset1; else return theset2; }