/* * Registration of free area on FreeQue * FreeQue is composed of 2 types: Queue that links the * different size of areas by size and queue that links the * same size of areas. * * freeque * | * | +-----------------------+ +-----------------------+ * | | AreaQue | | AreaQue | * | +-----------------------+ +-----------------------+ * *---> FreeQue Size order | | EmptyQue | * | | FreeQue Same size --------->| FreeQue Same size -----> * | | | | | * | | | | | * | +-----------------------+ +-----------------------+ * | | AreaQue | | AreaQue | * v +-----------------------+ +-----------------------+ */ EXPORT void knl_appendFreeArea( IMACB *imacb, QUEUE *aq ) { QUEUE *fq; W size = AreaSize(aq); /* Registration position search */ /* Search the free area whose size is equal to 'blksz', * or larger than 'blksz' but closest. * If it does not exist, return '&imacb->freeque'. */ fq = knl_searchFreeArea(imacb, size); /* Register */ clrAreaFlag(aq, AREA_USE); if ( fq != &imacb->freeque && FreeSize(fq) == size ) { /* FreeQue Same size */ (aq + 2)->next = (fq + 1)->next; (fq + 1)->next = aq + 2; (aq + 2)->prev = fq + 1; if( (aq + 2)->next != NULL ) { (aq + 2)->next->prev = aq + 2; } (aq + 1)->next = NULL; } else { /* FreeQue Size order */ QueInsert(aq + 1, fq); (aq + 2)->next = NULL; (aq + 2)->prev = (QUEUE*)size; } }
/* * Get memory block * 'blksz' must be larger than minimum fragment size * and adjusted by ROUNDSZ unit. */ LOCAL void* get_blk( MPLCB *mplcb, INT blksz ) { QUEUE *q, *aq; /* Search FreeQue */ q = searchFreeArea(mplcb, blksz); if ( q == &mplcb->freeque ) { return NULL; } /* remove free area from FreeQue */ removeFreeQue(q); aq = q - 1; /* If there is a fragment smaller than the minimum fragment size, allocate them together */ if ( AreaSize(aq) - (UINT)blksz >= MIN_FRAGMENT + sizeof(QUEUE) ) { /* Divide the area into 2. */ q = (QUEUE*)((VB*)(aq + 1) + blksz); insertAreaQue(aq, q); /* Register the remaining area onto FreeQue */ appendFreeArea(mplcb, q); } setAreaFlag(aq, AREA_USE); return (void*)(aq + 1); }
/* * Fragment and allocate */ static void *allocate( LIST *aq, RAW_U32 size, MACB *_macb ) { LIST *q; /* Any fragments smaller than the minimum fragment size will also be allocated together */ if ( (RAW_U32)AreaSize(aq) - size >= MIN_FRAGMENT + sizeof(LIST ) ) { /* Divide area in half */ q = (LIST *)((RAW_S8 *)(aq + 1) + size); insertAreaQue(aq, q); /* Register surplus area in free queue */ appendFreeArea(q, _macb); } setAreaFlag(aq, AREA_USE); return (void*)(aq + 1); }
/* * Subdivide and allocate */ Inline VP mem_alloc( QUEUE *aq, size_t blksz, IMACB *imacb ) { QUEUE *q; /* If there are fragments smaller than the minimum fragment size, allocate them also */ if ( (AreaSize(aq) - blksz) >= (MIN_FRAGMENT + sizeof(QUEUE)) ) { /* Divide area into 2 */ q = (QUEUE*)((VB*)(aq + 1) + blksz); insertAreaQue(aq, q); /* Register remaining area to FreeQue */ appendFreeArea(q, imacb); } setAreaFlag(aq, AREA_USE); return (VP)(aq + 1); }
/* * Registration in free space free queue * Free queue comprises a two-tier structure: a queue linking * areas of differing size in order of size, and a queue * linking areas that are the same size. * * macb->freeque * | * | +-----------------------+ +-----------------------+ * | | AreaQue | | AreaQue | * | +-----------------------+ +-----------------------+ * +----> FreeQue size order | +--------> FreeQue same size -----> * | | FreeQue same size --------+ | EmptyQue | * | | | | | * | | | | | * | +-----------------------+ +-----------------------+ * | | AreaQue | | AreaQue | * | +-----------------------+ +-----------------------+ */ void appendFreeArea( LIST *aq, MACB *macb ) { LIST *fq; RAW_U32 size = (RAW_U32)AreaSize(aq); /* Search registration position */ /* Searches for a free space with the same size as 'size' or * the next largest. * If none is found, returns &freeque. */ fq = searchFreeArea(size, macb); /* Registration */ clrAreaFlag(aq, AREA_USE); if ( fq != &macb->freeque && (RAW_U32)FreeSize(fq) == size ) { list_insert(fq + 1, aq + 1); } else { list_insert(fq, aq + 1); } list_init(aq + 2); }
/* * Registration of free area on FreeQue * FreeQue is composed of 2 types: Queue that links the * different size of areas by size and queue that links the * same size of areas. * * freeque * | * | +-----------------------+ +-----------------------+ * | | AreaQue | | AreaQue | * | +-----------------------+ +-----------------------+ * *---> FreeQue Size order | *----> FreeQue Same size -----> * | | FreeQue Same size -----* | EmptyQue | * | | | | | * | | | | | * | +-----------------------+ +-----------------------+ * | | AreaQue | | AreaQue | * v +-----------------------+ +-----------------------+ */ LOCAL void appendFreeArea( MPLCB *mplcb, QUEUE *aq ) { QUEUE *fq; INT size = AreaSize(aq); /* Registration position search */ /* Search the free area whose size is equal to 'blksz', * or larger than 'blksz' but closest. * If it does not exist, return '&mplcb->freeque'. */ fq = searchFreeArea(mplcb, size); /* Register */ clrAreaFlag(aq, AREA_USE); if ( fq != &mplcb->freeque && FreeSize(fq) == size ) { QueInsert(aq + 1, fq + 1); } else { QueInsert(aq + 1, fq); } QueInit(aq + 2); }
/* * Registration of free area on FreeQue * FreeQue is composed of 2 types: Queue that links the different * size of areas by size * and queue that links the same size areas. * * imacb->freeque * | * | +-----------------------+ +-----------------------+ * | | AreaQue | | AreaQue | * | +-----------------------+ +-----------------------+ * *---> FreeQue by size | *----> FreeQue same size ----> * | | FreeQue same size ----* | EmptyQue | * | | | | | * | | | | | * | +-----------------------+ +-----------------------+ * | | AreaQue | | AreaQue | * v +-----------------------+ +-----------------------+ */ LOCAL void appendFreeArea( QUEUE *aq, IMACB *imacb ) { QUEUE *fq; size_t size = AreaSize(aq); /* Registration position search */ /* Search free area whose size is equal to 'blksz', * or closest and larger than 'blksz'. * If it can not be found, return '&imacb->freeque'. */ fq = searchFreeArea(size, imacb); /* Registration */ clrAreaFlag(aq, AREA_USE); if ( (fq != &imacb->freeque) && (FreeSize(fq) == size) ) { QueInsert(aq + 1, fq + 1); } else { QueInsert(aq + 1, fq); } QueInit(aq + 2); }
/* * Checks for errors in memory allocation information. When mode < 0, * dumps the usage status. When ptr != NULL, checks to see that * memory allocation corresponds properly with ptr allocated blocks. * If so, returns True. */ LOCAL BOOL chkalloc( void *ptr, int mode, MACB *macb ) { QUEUE *aq, *nq; size_t usesz = 0, fresz = 0, sz; int usebk = 0, frebk = 0, npage = 0; BOOL newpg, ptr_ok; /* Checks each area in turn */ newpg = TRUE; ptr_ok = ( ptr == NULL )? TRUE: FALSE; for ( aq = macb->areaque.next; aq != &macb->areaque; aq = aq->next ) { if ( newpg && !chkAreaFlag(aq, AREA_TOP) ) { goto err_found; } if ( chkAreaFlag(aq, AREA_END) ) { if ( newpg ) { goto err_found; } newpg = TRUE; fresz += sizeof(QUEUE); npage++; continue; } newpg = FALSE; nq = aq->next; if ( Mask(aq->next) != nq || nq <= aq || Mask(nq->prev) != aq ) { goto err_found; } sz = (size_t)((VB*)nq - (VB*)aq); if ( sz < sizeof(QUEUE)*3 ) { goto err_found; } if ( chkAreaFlag(aq, AREA_USE) ) { usesz += sz; ++usebk; if ( ptr == (void*)(aq+1) ) { ptr_ok = TRUE; } if ( mode < -1 ) { syslog(LOG_NOTICE, "malloc ptr: 0x%08x [%d B]", aq+1, AreaSize(aq)); } } else { fresz += sz; ++frebk; } } if ( !newpg ) { goto err_found; } if ( !ptr_ok ) { syslog(LOG_ERR, "MALLOC: illegal ptr: 0x%08x", ptr); return FALSE; } if ( mode < 0 ) { syslog(LOG_NOTICE, "MALLOC: %d pages, used: %d [%d blks] free: %d [%d blks]", npage, usesz, usebk, fresz, frebk); } return TRUE; err_found: syslog(LOG_ERR, "MALLOC: block corrupted at 0x%08x", aq); return FALSE; }
/* * Checks for errors in memory allocation information. When mode < 0, * dumps the usage status. When ptr != NULL, checks to see that * memory allocation corresponds properly with ptr allocated blocks. * If so, returns True. */ static RAW_U16 chkalloc_test( void *ptr, int mode, MACB *macb ) { LIST *aq, *nq; RAW_U32 usesz = 0, fresz = 0, sz; int usebk = 0, frebk = 0, npage = 0; RAW_U8 newpg, ptr_ok; /* Checks each area in turn */ newpg = 1; ptr_ok = ( ptr == 0 )? 1: 0; for ( aq = macb->areaque.next; aq != &macb->areaque; aq = aq->next ) { if ( newpg && !chkAreaFlag(aq, AREA_TOP) ) { goto err_found; } if ( chkAreaFlag(aq, AREA_END) ) { if ( newpg ) { goto err_found; } newpg = 1; fresz += sizeof(LIST); npage++; continue; } newpg = 0; nq = aq->next; if ( Mask(aq->next) != nq || nq <= aq || Mask(nq->previous) != aq ) { goto err_found; } sz = (RAW_U32)((RAW_S8 *)nq - (RAW_S8 *)aq); if ( sz < sizeof(LIST)*3 ) { goto err_found; } if ( chkAreaFlag(aq, AREA_USE) ) { usesz += sz; ++usebk; if ( ptr == (void*)(aq+1) ) { ptr_ok = 1; } if ( mode < -1 ) { extension_printf("malloc ptr: 0x%08x [%d B]", aq+1, AreaSize(aq)); } } else { fresz += sz; ++frebk; } } if ( !newpg ) { goto err_found; } if ( !ptr_ok ) { extension_printf("MALLOC: illegal ptr: 0x%08x", ptr); return 0; } if ( mode < 0 ) { extension_printf("MALLOC: %d pages, used: %d [%d blks] free: %d [%d blks]", npage, usesz, usebk, fresz, frebk); } return 1; err_found: extension_printf("MALLOC: block corrupted at 0x%08x", aq); return 0; }
/* * Memory allocation size change */ static void *_mem_realloc( void *ptr, RAW_U32 size, MACB *macb ) { LIST *aq; RAW_U32 oldsz, sz; if ( macb->testmode > 0 ) { if ( !chkalloc(ptr, 0, macb) ) { return 0; } } /* If smaller than minimum fragment size, allocate minimum fragment size */ if ( size > 0 && size < MIN_FRAGMENT ) { size = MIN_FRAGMENT; } size = ROUND(size); aq = (LIST *)ptr - 1; if ( ptr != 0 ) { /* Current allocation size */ oldsz = (RAW_U32)AreaSize(aq); /* Merge if next space is free space */ if ( !chkAreaFlag(aq->next, AREA_END|AREA_USE) ) { removeFreeQue(aq->next + 1); removeAreaQue(aq->next); } sz = (RAW_U32)AreaSize(aq); } else { sz = oldsz = 0; } if ( size <= sz ) { if ( size > 0 ) { /* Fragment current area and allocate */ allocate(aq, size, macb); } else { /* Release area */ _mem_free(ptr, macb); ptr = 0; } } else { /* Allocate new area */ void *newptr = _mem_malloc(size, macb); if ( newptr == 0 ) { /* Reallocate original area at original size */ if ( ptr != 0 ) { allocate(aq, oldsz, macb); } return 0; } if ( ptr != 0 ) { /* Copy contents */ raw_memcpy(newptr, ptr, oldsz); /* Release old area */ _mem_free(ptr, macb); } ptr = newptr; } return ptr; }
// -------------------------------------------------------------------------------------------- // ContinueButton in der PropertySheet gedrückt HRESULT CNewArea::ContinueButtonAction (void) { // Das Drücken eines Buttons bzw. die Korrektur des letzten Koordinatenpaars durch den Anwender // kann den Punkt, an dem fortgesetzt werden soll, verändern. Deshalb ist dieser Punkt neu zu // ermitteln. Außerdem ist der Gesamtflächeninhalt neu zu berechnen. long lCnt; KoOrd* plXK; KoOrd* plYK; m_wObj->GetCnt (&lCnt); m_wObj->GetX ((void**)&plXK); m_wObj->GetY ((void**)&plYK); // Gesamtflächeninhalt als vorzeichenbehafteten Wert neu berechnen AreaSize (plXK, plYK, 0, lCnt-1, m_pCT, &m_dAktGesFlaeche); m_dAktInsel = 0.; m_dAktDreieck = 0.; m_LastPt = BSKoordinaten (plXK[lCnt-1], plYK[lCnt-1]); m_LastPkt.X() = plXK[lCnt-1]; m_LastPkt.Y() = plYK[lCnt-1]; // falls durch den DeleteButton eine Insel komplett gelöscht wurde, muß auch der erster Punkt // der jetzt aktuell editierten Kontur korrigiert werden long* plCnt; m_wObj->GetKCnt (&m_iKCnt); m_wObj->GetLPCnt (&plCnt); m_lKSize = plCnt[m_iKCnt-1]; long lAInd = lCnt - m_lKSize; m_FirstPt = BSKoordinaten (plXK[lAInd], plYK[lAInd]); m_FirstPkt.X() = plXK[lAInd]; m_FirstPkt.Y() = plYK[lAInd]; try { WDragObject wDragObj (CLSID_DragMultiLine); // throws_com_error (ab zum Konstruktor) m_wDragObj.Assign (NULL); m_wDragObj = wDragObj; m_iSPCnt = 0; if (S_OK == m_wDragObj->AddStartPoint ((POINT&)m_FirstPt)) { m_pStartPkt[m_iSPCnt] = DBKoordinaten (m_FirstPt); m_iSPCnt++; } if (S_OK == m_wDragObj->AddStartPoint ((POINT&)m_LastPt)) { m_pStartPkt[m_iSPCnt] = DBKoordinaten (m_LastPt); m_iSPCnt++; } m_wDragObj->ConstructDragLines(); } catch (_com_error& e) { return _COM_ERROR (e); } return S_OK; } // ContinueButtonAction