diff options
author | Caolán McNamara <caolanm@redhat.com> | 2011-11-15 23:05:29 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2011-11-15 23:05:29 +0000 |
commit | 861a197b7ff1dab44c7fe31a8b491a3c591a8ed5 (patch) | |
tree | 6f53e4739425d61fda5653bf8f63854b6a4521cb | |
parent | Application::CreateUniqueId only need by binfilter, move content here (diff) | |
download | binfilter-861a197b7ff1dab44c7fe31a8b491a3c591a8ed5.tar.gz binfilter-861a197b7ff1dab44c7fe31a8b491a3c591a8ed5.zip |
move UniqueIndex into binfilter
-rw-r--r-- | binfilter/bf_sfx2/source/appl/appimp.hxx | 2 | ||||
-rw-r--r-- | binfilter/bf_so3/source/data/pseudo.cxx | 2 | ||||
-rw-r--r-- | binfilter/bf_svtools/source/memtools/makefile.mk | 4 | ||||
-rw-r--r-- | binfilter/bf_svtools/source/memtools/tl_contnr.cxx | 1425 | ||||
-rw-r--r-- | binfilter/bf_svtools/source/memtools/tl_unqidx.cxx | 452 | ||||
-rw-r--r-- | binfilter/inc/bf_so3/pseudo.hxx | 2 | ||||
-rw-r--r-- | binfilter/inc/bf_tools/contnr.hxx | 124 | ||||
-rw-r--r-- | binfilter/inc/bf_tools/impcont.hxx | 147 | ||||
-rw-r--r-- | binfilter/inc/bf_tools/unqid.hxx | 113 | ||||
-rw-r--r-- | binfilter/inc/bf_tools/unqidx.hxx | 152 |
10 files changed, 2419 insertions, 4 deletions
diff --git a/binfilter/bf_sfx2/source/appl/appimp.hxx b/binfilter/bf_sfx2/source/appl/appimp.hxx index 8de38bfdd..801fa88fa 100644 --- a/binfilter/bf_sfx2/source/appl/appimp.hxx +++ b/binfilter/bf_sfx2/source/appl/appimp.hxx @@ -31,7 +31,6 @@ #include <tools/time.hxx> #include <tools/string.hxx> class MenuBar; -class UniqueIndex; class BasicManager; class Timer; namespace binfilter { @@ -47,6 +46,7 @@ class SfxTemplateDialog; class SfxDialogLibraryContainer; class SfxScriptLibraryContainer; class SfxBasicTestWin; +class UniqueIndex; struct SfxApplication_Impl { diff --git a/binfilter/bf_so3/source/data/pseudo.cxx b/binfilter/bf_so3/source/data/pseudo.cxx index 9127dc063..625fc41d3 100644 --- a/binfilter/bf_so3/source/data/pseudo.cxx +++ b/binfilter/bf_so3/source/data/pseudo.cxx @@ -30,7 +30,7 @@ #include <bf_so3/pseudo.hxx> #include <tools/date.hxx> #include <tools/debug.hxx> -#include <tools/unqid.hxx> +#include <bf_tools/unqid.hxx> #include <vcl/svapp.hxx> #include <vcl/wrkwin.hxx> #include <vcl/menu.hxx> diff --git a/binfilter/bf_svtools/source/memtools/makefile.mk b/binfilter/bf_svtools/source/memtools/makefile.mk index 08ba1d762..24aaa1070 100644 --- a/binfilter/bf_svtools/source/memtools/makefile.mk +++ b/binfilter/bf_svtools/source/memtools/makefile.mk @@ -38,7 +38,9 @@ INC+= -I$(PRJ)$/inc$/bf_svtools # --- Files -------------------------------------------------------- SLOFILES=\ - $(SLO)$/svt_svarray.obj + $(SLO)$/svt_svarray.obj \ + $(SLO)$/tl_contnr.obj \ + $(SLO)$/tl_unqidx.obj # --- Targets ------------------------------------------------------- diff --git a/binfilter/bf_svtools/source/memtools/tl_contnr.cxx b/binfilter/bf_svtools/source/memtools/tl_contnr.cxx new file mode 100644 index 000000000..e548d00e2 --- /dev/null +++ b/binfilter/bf_svtools/source/memtools/tl_contnr.cxx @@ -0,0 +1,1425 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <limits.h> +#include <string.h> +#include <stdio.h> + +#include <tools/solar.h> +#include <tools/debug.hxx> + +#include <bf_tools/impcont.hxx> +#include <bf_tools/contnr.hxx> + +namespace binfilter +{ + +// ----------------------------------------------------------------------- + +DBG_NAME( CBlock ) +DBG_NAME( Container ) + +/************************************************************************* +|* +|* DbgCheckCBlock() +|* +|* Beschreibung Pruefung eines CBlock fuer Debug-Utilities +|* +*************************************************************************/ + +#ifdef DBG_UTIL +const char* CBlock::DbgCheckCBlock( const void* pBlock ) +{ + CBlock* p = (CBlock*)pBlock; + + if ( p->nCount > p->nSize ) + return "nCount > nSize"; + + if ( p->nSize && !p->pNodes ) + return "nSize > 0 && pNodes == NULL"; + + return NULL; +} +#endif + +/************************************************************************* +|* +|* CBlock::CBlock() +|* +|* Beschreibung Construktor des Verwaltungsblocks +|* +*************************************************************************/ + +CBlock::CBlock( sal_uInt16 nInitSize, CBlock* _pPrev, CBlock* _pNext ) +{ + DBG_CTOR( CBlock, DbgCheckCBlock ); + + pPrev = _pPrev; + pNext = _pNext; + nSize = nInitSize; + nCount = 0; + + // Datenpuffer anlegen + pNodes = new PVOID[nSize]; +} + +/************************************************************************* +|* +|* CBlock::CBlock() +|* +|* Beschreibung Construktor des Verwaltungsblocks +|* +*************************************************************************/ + +CBlock::CBlock( sal_uInt16 _nSize, CBlock* _pPrev ) +{ + DBG_CTOR( CBlock, DbgCheckCBlock ); + DBG_ASSERT( _nSize, "CBlock::CBlock(): nSize == 0" ); + + pPrev = _pPrev; + pNext = NULL; + nSize = _nSize; + nCount = _nSize; + + // Datenpuffer anlegen und initialisieren + pNodes = new PVOID[nSize]; + memset( pNodes, 0, nSize*sizeof(PVOID) ); +} + +/************************************************************************* +|* +|* CBlock::CBlock() +|* +|* Beschreibung Copy-Construktor des Verwaltungsblocks +|* +*************************************************************************/ + +CBlock::CBlock( const CBlock& r, CBlock* _pPrev ) +{ + DBG_CTOR( CBlock, DbgCheckCBlock ); + DBG_CHKOBJ( &r, CBlock, DbgCheckCBlock ); + + pPrev = _pPrev; + pNext = NULL; + nSize = r.nSize; + nCount = r.nCount; + + // Datenpuffer anlegen und Daten kopieren + pNodes = new PVOID[nSize]; + memcpy( pNodes, r.pNodes, nCount*sizeof(PVOID) ); +} + +/************************************************************************* +|* +|* CBlock::~CBlock() +|* +|* Beschreibung Destruktor des Verwaltungsblocks +|* +*************************************************************************/ + +inline CBlock::~CBlock() +{ + DBG_DTOR( CBlock, DbgCheckCBlock ); + + // Daten loeschen + delete[] pNodes; +} + +/************************************************************************* +|* +|* CBlock::Insert() +|* +|* Beschreibung Fuegt einen Pointer ein +|* +*************************************************************************/ + +void CBlock::Insert( void* p, sal_uInt16 nIndex, sal_uInt16 nReSize ) +{ + DBG_CHKTHIS( CBlock, DbgCheckCBlock ); + DBG_ASSERT( nIndex <= nCount, "CBlock::Insert(): Index > nCount" ); + + // Muss Block realokiert werden + if ( nCount == nSize ) + { + // Neue Daten anlegen + nSize = nSize + nReSize; // MSVC warns here if += is used + void** pNewNodes = new PVOID[nSize]; + + // Wird angehaengt + if ( nCount == nIndex ) + { + // Daten kopieren + memcpy( pNewNodes, pNodes, nCount*sizeof(PVOID) ); + } + else + { + // Daten kopieren + memcpy( pNewNodes, pNodes, nIndex*sizeof(PVOID) ); + memcpy( pNewNodes + nIndex + 1, + pNodes + nIndex, + (nCount-nIndex)*sizeof(PVOID) ); + } + + // Alte Daten loeschen und neue setzen + delete[] pNodes; + pNodes = pNewNodes; + } + else + { + if ( nIndex < nCount ) + { + memmove( pNodes + nIndex + 1, + pNodes + nIndex, + (nCount-nIndex)*sizeof(PVOID) ); + } + } + + // Neuen Pointer setzen und Elementgroesse erhoehen + pNodes[nIndex] = p; + nCount++; +} + +/************************************************************************* +|* +|* CBlock::Split() +|* +|* Beschreibung Fuegt einen Pointer ein und splittet den Block +|* +*************************************************************************/ + +CBlock* CBlock::Split( void* p, sal_uInt16 nIndex, sal_uInt16 nReSize ) +{ + DBG_CHKTHIS( CBlock, DbgCheckCBlock ); + + sal_uInt16 nNewSize; + sal_uInt16 nMiddle; + CBlock* pNewBlock; + + nMiddle = nCount/2; + + if ( ( nIndex == nCount ) || ( nIndex == 0 ) ) + nNewSize = nReSize; + else + { + // Der aktuelle Block wird in der Mitte geteilt + nNewSize = (nCount+1) / 2; + + if ( nNewSize < nReSize ) + nNewSize = nReSize; + else + { + // Neue Groesse muss ein vielfaches von Resize sein + if ( nNewSize % nReSize ) + nNewSize += nReSize - (nNewSize % nReSize); + else + nNewSize = nNewSize + nReSize; // MSVC warns here if += is used + } + } + + // Vor oder hinter dem aktuellem Block einfuegen? + if ( nIndex > nMiddle ) + { + // Neuen Split-Block anlegen und hinter dem aktuellem Block einfuegen + pNewBlock = new CBlock( nNewSize, this, pNext ); + + if ( pNext ) + pNext->pPrev = pNewBlock; + pNext = pNewBlock; + + if ( nIndex == nCount ) + { + // Neuen Pointer einfuegen + pNewBlock->pNodes[0] = p; + pNewBlock->nCount = 1; + } + else + { + nIndex = nIndex - nMiddle; // MSVC warns here if += is used + // Alles von Mitte bis Index kopieren + if ( nIndex ) + memcpy( pNewBlock->pNodes, pNodes+nMiddle, nIndex*sizeof(PVOID) ); + + // Neuen Pointer einfuegen + pNewBlock->pNodes[nIndex] = p; + + // Alles von Mitte bis Ende hinter Index kopieren + memcpy( pNewBlock->pNodes+nIndex+1, + pNodes+nMiddle+nIndex, + (nCount-nMiddle-nIndex) * sizeof(PVOID) ); + + pNewBlock->nCount = (nCount-nMiddle+1); + nCount = nMiddle; + + // Den aktuellen Datenbereich auch halbieren + if ( nSize != nNewSize ) + { + void** pNewNodes = new PVOID[nNewSize]; + memcpy( pNewNodes, pNodes, nCount*sizeof(PVOID) ); + delete[] pNodes; + pNodes = pNewNodes; + nSize = nNewSize; + } + } + } + else + { + // Neuen Split-Block anlegen und vor dem aktuellem Block einfuegen + pNewBlock = new CBlock( nNewSize, pPrev, this ); + + if ( pPrev ) + pPrev->pNext = pNewBlock; + pPrev = pNewBlock; + + if ( nIndex == 0 ) + { + // Neuen Pointer einfuegen + pNewBlock->pNodes[0] = p; + pNewBlock->nCount = 1; + } + else + { + // Alles von Anfang bis Index kopieren + memcpy( pNewBlock->pNodes, pNodes, nIndex*sizeof(PVOID) ); + + // Neuen Pointer einfuegen + pNewBlock->pNodes[nIndex] = p; + + // Alles von Index bis Mitte hinter Index kopieren + if ( nIndex != nMiddle ) + { + memcpy( pNewBlock->pNodes+nIndex+1, + pNodes+nIndex, + (nMiddle-nIndex) * sizeof(PVOID) ); + } + + pNewBlock->nCount = nMiddle+1; + nCount = nCount - nMiddle; // MSVC warns here if += is used + + // Die zweite Haelfte in einen neuen Block kopieren + if ( nSize != nNewSize ) + { + void** pNewNodes = new PVOID[nNewSize]; + memcpy( pNewNodes, pNodes+nMiddle, nCount*sizeof(PVOID) ); + delete[] pNodes; + pNodes = pNewNodes; + nSize = nNewSize; + } + else + memmove( pNodes, pNodes+nMiddle, nCount*sizeof(PVOID) ); + } + } + + // Neu angelegten Block zurueckgeben, da gegebenfalls die Blockpointer + // im Container angepast werden koennen + return pNewBlock; +} + +/************************************************************************* +|* +|* CBlock::Remove() +|* +|* Beschreibung Entfernt einen Pointer +|* +*************************************************************************/ + +void* CBlock::Remove( sal_uInt16 nIndex, sal_uInt16 nReSize ) +{ + DBG_CHKTHIS( CBlock, DbgCheckCBlock ); + + // Alten Pointer sichern + void* pOld = pNodes[nIndex]; + + // 1 Element weniger + nCount--; + + // Block verkleinern (wenn Reallokationsgroesse um 4 unterschritten wird) + if ( nCount == (nSize-nReSize-4) ) + { + // Neue Daten anlegen + nSize = nSize - nReSize; // MSVC warns here if += is used + void** pNewNodes = new PVOID[nSize]; + + // Wird letzter Eintrag geloescht + if ( nIndex == nCount ) + { + // Daten kopieren + memcpy( pNewNodes, pNodes, nCount*sizeof(PVOID) ); + } + else + { + // Daten kopieren + memcpy( pNewNodes, pNodes, nIndex*sizeof(PVOID) ); + memcpy( pNewNodes + nIndex, pNodes + nIndex+1, + (nCount-nIndex)*sizeof(PVOID) ); + } + + // Alte Daten loeschen und neue setzen + delete[] pNodes; + pNodes = pNewNodes; + } + else + { + // Wenn nicht das letzte Element, dann zusammenschieben + if ( nIndex < nCount ) + { + memmove( pNodes + nIndex, pNodes + nIndex + 1, + (nCount-nIndex)*sizeof(PVOID) ); + } + } + + // Alten Pointer zurueckgeben + return pOld; +} + +/************************************************************************* +|* +|* CBlock::Replace() +|* +|* Beschreibung Ersetzt einen Pointer +|* +*************************************************************************/ + +inline void* CBlock::Replace( void* p, sal_uInt16 nIndex ) +{ + DBG_CHKTHIS( CBlock, DbgCheckCBlock ); + + // Alten Pointer sichern, neuen setzen und alten zurueckgeben + void* pOld = pNodes[nIndex]; + pNodes[nIndex] = p; + return pOld; +} + +/************************************************************************* +|* +|* CBlock::GetObjectPtr() +|* +|* Beschreibung Gibt einen Pointer auf den Pointer aus dem Block +|* zurueck +|* +*************************************************************************/ + +inline void** CBlock::GetObjectPtr( sal_uInt16 nIndex ) +{ + DBG_CHKTHIS( CBlock, DbgCheckCBlock ); + + return &(pNodes[nIndex]); +} + +/************************************************************************* +|* +|* CBlock::SetSize() +|* +|* Beschreibung Aendert die Groesse des Blocks +|* +*************************************************************************/ + +void CBlock::SetSize( sal_uInt16 nNewSize ) +{ + DBG_CHKTHIS( CBlock, DbgCheckCBlock ); + DBG_ASSERT( nNewSize, "CBlock::SetSize(): nNewSize == 0" ); + + // Unterscheidet sich die Groesse + if ( nNewSize != nCount ) + { + // Array erweitern + void** pNewNodes = new PVOID[nNewSize]; + + // Alte Tabelle in die Neue kopieren + if ( nNewSize < nCount ) + memcpy( pNewNodes, pNodes, nNewSize*sizeof(PVOID) ); + else + { + memcpy( pNewNodes, pNodes, nCount*sizeof(PVOID) ); + + // Array mit 0 initialisieren + memset( pNewNodes+nCount, 0, (nNewSize-nCount)*sizeof(PVOID) ); + } + + // Altes Array loeschen und neue Werte setzen + nSize = nNewSize; + nCount = nSize; + delete[] pNodes; + pNodes = pNewNodes; + } +} + +//------------------------------------------------------------------------ + +/************************************************************************* +|* +|* DbgCheckContainer() +|* +|* Beschreibung Pruefung eines Container fuer Debug-Utilities +|* +*************************************************************************/ + +#ifdef DBG_UTIL +const char* Container::DbgCheckContainer( const void* pCont ) +{ + Container* p = (Container*)pCont; + + if ( p->nCount && (!p->pFirstBlock || !p->pLastBlock || !p->pCurBlock) ) + return "nCount > 0 but no CBlocks"; + + return NULL; +} +#endif + +/************************************************************************* +|* +|* ImpCopyContainer() +|* +|* Beschreibung Kopiert alle Daten des Containers +|* +*************************************************************************/ + +void Container::ImpCopyContainer( const Container* pCont2 ) +{ + // Werte vom uebergebenen Container uebernehmen + nCount = pCont2->nCount; + nCurIndex = pCont2->nCurIndex; + nInitSize = pCont2->nInitSize; + nReSize = pCont2->nReSize; + nBlockSize = pCont2->nBlockSize; + + // Alle Bloecke kopieren + if ( pCont2->nCount ) + { + CBlock* pBlock1; + CBlock* pBlock2; + CBlock* pTempBlock; + + // Erstmal ersten Block kopieren + pBlock2 = pCont2->pFirstBlock; + pFirstBlock = new CBlock( *pBlock2, NULL ); + // Ist erster Block der Current-Block, dann Current-Block setzen + if ( pBlock2 == pCont2->pCurBlock ) + pCurBlock = pFirstBlock; + pBlock1 = pFirstBlock; + pBlock2 = pBlock2->GetNextBlock(); + while ( pBlock2 ) + { + // Neuen Block anlegen und aus der uebergebenen Liste kopieren + pTempBlock = new CBlock( *pBlock2, pBlock1 ); + pBlock1->SetNextBlock( pTempBlock ); + pBlock1 = pTempBlock; + + // Current-Block beruecksichtigen + if ( pBlock2 == pCont2->pCurBlock ) + pCurBlock = pBlock1; + + // Auf naechsten Block weitersetzen + pBlock2 = pBlock2->GetNextBlock(); + } + + // Letzten Block setzen + pLastBlock = pBlock1; + } + else + { + pFirstBlock = NULL; + pLastBlock = NULL; + pCurBlock = NULL; + } +} + +/************************************************************************* +|* +|* Container::Container() +|* +*************************************************************************/ + +Container::Container( sal_uInt16 _nBlockSize, sal_uInt16 _nInitSize, sal_uInt16 _nReSize ) +{ + DBG_CTOR( Container, DbgCheckContainer ); + + // BlockSize muss mindestens 4 sein und kleiner als 64 KB + if ( _nBlockSize < 4 ) + nBlockSize = 4; + else + { + if ( _nBlockSize < CONTAINER_MAXBLOCKSIZE ) + nBlockSize = _nBlockSize; + else + nBlockSize = CONTAINER_MAXBLOCKSIZE; + } + + // ReSize muss mindestens 2 sein und kleiner als BlockSize + if ( _nReSize >= nBlockSize ) + nReSize = nBlockSize; + else + { + if ( _nReSize < 2 ) + nReSize = 2; + else + nReSize = _nReSize; + + // BlockSize muss ein vielfaches der Resizegroesse sein + if ( nBlockSize % nReSize ) + nBlockSize -= nReSize - (nBlockSize % nReSize); + } + + // InitSize muss groesser gleich ReSize sein und kleiner als BlockSize + if ( _nInitSize <= nReSize ) + nInitSize = nReSize; + else + { + if ( _nInitSize >= nBlockSize ) + nInitSize = nBlockSize; + else + { + nInitSize = _nInitSize; + + // InitSize muss ein vielfaches der Resizegroesse sein + if ( nInitSize % nReSize ) + nInitSize -= nReSize - (nInitSize % nReSize); + } + } + + // Werte initialisieren + pFirstBlock = NULL; + pLastBlock = NULL; + pCurBlock = NULL; + nCount = 0; + nCurIndex = 0; +} + +/************************************************************************* +|* +|* Container::Container() +|* +*************************************************************************/ + +Container::Container( sal_uIntPtr nSize ) +{ + DBG_CTOR( Container, DbgCheckContainer ); + + nCount = nSize; + nCurIndex = 0; + nBlockSize = CONTAINER_MAXBLOCKSIZE; + nInitSize = 1; + nReSize = 1; + + if ( !nSize ) + { + pFirstBlock = NULL; + pLastBlock = NULL; + pCurBlock = NULL; + } + else + { + // Muss mehr als ein Block angelegt werden + if ( nSize <= nBlockSize ) + { + pFirstBlock = new CBlock( (sal_uInt16)nSize, NULL ); + pLastBlock = pFirstBlock; + } + else + { + CBlock* pBlock1; + CBlock* pBlock2; + + pFirstBlock = new CBlock( nBlockSize, NULL ); + pBlock1 = pFirstBlock; + nSize -= nBlockSize; + + // Solange die Blockgroesse ueberschritten wird, neue Bloecke anlegen + while ( nSize > nBlockSize ) + { + pBlock2 = new CBlock( nBlockSize, pBlock1 ); + pBlock1->SetNextBlock( pBlock2 ); + pBlock1 = pBlock2; + nSize -= nBlockSize; + } + + pLastBlock = new CBlock( (sal_uInt16)nSize, pBlock1 ); + pBlock1->SetNextBlock( pLastBlock ); + } + + pCurBlock = pFirstBlock; + } +} + +/************************************************************************* +|* +|* Container::Container() +|* +*************************************************************************/ + +Container::Container( const Container& r ) +{ + DBG_CTOR( Container, DbgCheckContainer ); + + // Daten kopieren + ImpCopyContainer( &r ); +} + +/************************************************************************* +|* +|* Container::~Container() +|* +*************************************************************************/ + +Container::~Container() +{ + DBG_DTOR( Container, DbgCheckContainer ); + + // Alle Bloecke loeschen + CBlock* pBlock = pFirstBlock; + while ( pBlock ) + { + CBlock* pTemp = pBlock->GetNextBlock(); + delete pBlock; + pBlock = pTemp; + } +} + +/************************************************************************* +|* +|* Container::ImpInsert() +|* +|* Beschreibung Interne Methode zum Einfuegen eines Pointers +|* +*************************************************************************/ + +void Container::ImpInsert( void* p, CBlock* pBlock, sal_uInt16 nIndex ) +{ + DBG_CHKTHIS( Container, DbgCheckContainer ); + + if ( !nCount ) + { + if ( !pBlock ) + { + pFirstBlock = new CBlock( nInitSize, NULL, NULL ); + pLastBlock = pFirstBlock; + pCurBlock = pFirstBlock; + } + pFirstBlock->Insert( p, nIndex, nReSize ); + } + else + { + // Ist im Block die maximale Blockgroesse erreicht, + // dann neuen Block anlegen + if ( pBlock->Count() == nBlockSize ) + { + // Block auftrennen + CBlock* pNewBlock = pBlock->Split( p, nIndex, nReSize ); + + // Wurde Block dahinter angehaegnt + if ( pBlock->pNext == pNewBlock ) + { + // Gegebenenfalls LastBlock anpassen + if ( pBlock == pLastBlock ) + pLastBlock = pNewBlock; + + // Current-Position nachfuehren + if ( pBlock == pCurBlock ) + { + if ( pBlock->nCount <= nCurIndex ) + { + if ( nIndex <= nCurIndex ) + nCurIndex++; + pCurBlock = pNewBlock; + nCurIndex = nCurIndex - pBlock->nCount; // MSVC warns here if += is used + } + } + } + else + { + // Gegebenenfalls FirstBlock anpassen + if ( pBlock == pFirstBlock ) + pFirstBlock = pNewBlock; + + // Current-Position nachfuehren + if ( pBlock == pCurBlock ) + { + if ( nIndex <= nCurIndex ) + nCurIndex++; + if ( pNewBlock->nCount <= nCurIndex ) + nCurIndex = nCurIndex - pNewBlock->nCount; // MSVC warns here if += is used + else + pCurBlock = pNewBlock; + } + } + } + else + { + // Sonst reicht normales einfuegen in den Block + pBlock->Insert( p, nIndex, nReSize ); + + // Current-Position nachfuehren + if ( (pBlock == pCurBlock) && (nIndex <= nCurIndex) ) + nCurIndex++; + } + } + + // Ein neues Item im Container + nCount++; +} + +/************************************************************************* +|* +|* Container::Insert() +|* +*************************************************************************/ + +void Container::Insert( void* p ) +{ + ImpInsert( p, pCurBlock, nCurIndex ); +} + +/************************************************************************* +|* +|* Container::Insert() +|* +*************************************************************************/ + +void Container::Insert( void* p, sal_uIntPtr nIndex ) +{ + if ( nCount <= nIndex ) + { + if ( pLastBlock ) + ImpInsert( p, pLastBlock, pLastBlock->Count() ); + else + ImpInsert( p, NULL, 0 ); + } + else + { + // Block suchen + CBlock* pTemp = pFirstBlock; + while ( pTemp->Count() < nIndex ) + { + nIndex -= pTemp->Count(); + pTemp = pTemp->GetNextBlock(); + } + + ImpInsert( p, pTemp, (sal_uInt16)nIndex ); + } +} + +/************************************************************************* +|* +|* Container::ImpRemove() +|* +|* Beschreibung Interne Methode zum Entfernen eines Pointers +|* +*************************************************************************/ + +void* Container::ImpRemove( CBlock* pBlock, sal_uInt16 nIndex ) +{ + DBG_CHKTHIS( Container, DbgCheckContainer ); + + void* pOld; + + // Ist Liste danach leer + if ( nCount == 1 ) + { + // Block und CurIndex zuruecksetzen + pOld = pBlock->GetObject( nIndex ); + pBlock->Reset(); + nCurIndex = 0; + } + else + { + // Ist Block nach Remove leer + if ( pBlock->Count() == 1 ) + { + // dann Block entfernen und Block-Pointer umsetzen + if ( pBlock->GetPrevBlock() ) + (pBlock->GetPrevBlock())->SetNextBlock( pBlock->GetNextBlock() ); + else + pFirstBlock = pBlock->GetNextBlock(); + + if ( pBlock->GetNextBlock() ) + (pBlock->GetNextBlock())->SetPrevBlock( pBlock->GetPrevBlock() ); + else + pLastBlock = pBlock->GetPrevBlock(); + + // Current-Position nachfuehren + if ( pBlock == pCurBlock ) + { + if ( pBlock->GetNextBlock() ) + { + pCurBlock = pBlock->GetNextBlock(); + nCurIndex = 0; + } + else + { + pCurBlock = pBlock->GetPrevBlock(); + nCurIndex = pCurBlock->Count()-1; + } + } + + pOld = pBlock->GetObject( nIndex ); + delete pBlock; + } + else + { + // Sonst Item aus dem Block entfernen + pOld = pBlock->Remove( nIndex, nReSize ); + + // Current-Position nachfuehren + if ( (pBlock == pCurBlock) && + ((nIndex < nCurIndex) || ((nCurIndex == pBlock->Count()) && nCurIndex)) ) + nCurIndex--; + } + } + + // Jetzt gibt es ein Item weniger + nCount--; + + // Und den Pointer zurueckgeben, der entfernt wurde + return pOld; +} + +/************************************************************************* +|* +|* Container::Remove() +|* +*************************************************************************/ + +void* Container::Remove() +{ + // Wenn kein Item vorhanden ist, NULL zurueckgeben + if ( !nCount ) + return NULL; + else + return ImpRemove( pCurBlock, nCurIndex ); +} + +/************************************************************************* +|* +|* Container::Remove() +|* +*************************************************************************/ + +void* Container::Remove( sal_uIntPtr nIndex ) +{ + // Ist Index nicht innerhalb des Containers, dann NULL zurueckgeben + if ( nCount <= nIndex ) + return NULL; + else + { + // Block suchen + CBlock* pTemp = pFirstBlock; + while ( pTemp->Count() <= nIndex ) + { + nIndex -= pTemp->Count(); + pTemp = pTemp->GetNextBlock(); + } + + return ImpRemove( pTemp, (sal_uInt16)nIndex ); + } +} + +/************************************************************************* +|* +|* Container::Replace() +|* +*************************************************************************/ + +void* Container::Replace( void* p, sal_uIntPtr nIndex ) +{ + DBG_CHKTHIS( Container, DbgCheckContainer ); + + // Ist Index nicht innerhalb des Containers, dann NULL zurueckgeben + if ( nCount <= nIndex ) + return NULL; + else + { + // Block suchen + CBlock* pTemp = pFirstBlock; + while ( pTemp->Count() <= nIndex ) + { + nIndex -= pTemp->Count(); + pTemp = pTemp->GetNextBlock(); + } + + return pTemp->Replace( p, (sal_uInt16)nIndex ); + } +} + +/************************************************************************* +|* +|* Container::SetSize() +|* +*************************************************************************/ + +void Container::SetSize( sal_uIntPtr nNewSize ) +{ + DBG_CHKTHIS( Container, DbgCheckContainer ); + + if ( nNewSize ) + { + // Unterscheiden sich die Groessen + if ( nNewSize != nCount ) + { + CBlock* pTemp; + sal_uIntPtr nTemp; + + // Wird verkleinert + if ( nNewSize < nCount ) + { + pTemp = pFirstBlock; + nTemp = 0; + while ( (nTemp+pTemp->Count()) < nNewSize ) + { + nTemp += pTemp->Count(); + pTemp = pTemp->GetNextBlock(); + } + + // Alle folgenden Bloecke loeschen + sal_Bool bLast = sal_False; + CBlock* pDelNext; + CBlock* pDelBlock = pTemp->GetNextBlock(); + while ( pDelBlock ) + { + // Muss CurrentBlock umgesetzt werden + if ( pDelBlock == pCurBlock ) + bLast = sal_True; + pDelNext = pDelBlock->GetNextBlock(); + delete pDelBlock; + pDelBlock = pDelNext; + } + + // Block in der Groesse anpassen, oder bei Groesse 0 loeschen + if ( nNewSize > nTemp ) + { + pLastBlock = pTemp; + pTemp->SetNextBlock( NULL ); + pTemp->SetSize( (sal_uInt16)(nNewSize-nTemp) ); + } + else + { + pLastBlock = pTemp->GetPrevBlock(); + pLastBlock->SetNextBlock( NULL ); + delete pTemp; + } + + nCount = nNewSize; + if ( bLast ) + { + pCurBlock = pLastBlock; + nCurIndex = pCurBlock->Count()-1; + } + } + else + { + // Auf den letzen Puffer setzen + pTemp = pLastBlock; + nTemp = nNewSize - nCount; + + if ( !pTemp ) + { + // Muss mehr als ein Block angelegt werden + if ( nNewSize <= nBlockSize ) + { + pFirstBlock = new CBlock( (sal_uInt16)nNewSize, NULL ); + pLastBlock = pFirstBlock; + } + else + { + CBlock* pBlock1; + CBlock* pBlock2; + + pFirstBlock = new CBlock( nBlockSize, NULL ); + pBlock1 = pFirstBlock; + nNewSize -= nBlockSize; + + // Solange die Blockgroesse ueberschritten wird, neue Bloecke anlegen + while ( nNewSize > nBlockSize ) + { + pBlock2 = new CBlock( nBlockSize, pBlock1 ); + pBlock1->SetNextBlock( pBlock2 ); + pBlock1 = pBlock2; + nNewSize -= nBlockSize; + } + + pLastBlock = new CBlock( (sal_uInt16)nNewSize, pBlock1 ); + pBlock1->SetNextBlock( pLastBlock ); + } + + pCurBlock = pFirstBlock; + } + // Reicht es, den letzen Puffer in der Groesse anzupassen + else if ( (nTemp+pTemp->Count()) <= nBlockSize ) + pTemp->SetSize( (sal_uInt16)(nTemp+pTemp->Count()) ); + else + { + // Puffer auf max. Blockgroesse setzen + nTemp -= nBlockSize - pTemp->GetSize(); + pTemp->SetSize( nBlockSize ); + + CBlock* pTemp2; + // Solange die Blockgroesse ueberschritten wird, + // neue Bloecke anlegen + while ( nTemp > nBlockSize ) + { + pTemp2 = new CBlock( nBlockSize, pTemp ); + pTemp->SetNextBlock( pTemp2 ); + pTemp = pTemp2; + nTemp -= nBlockSize; + } + + // Den letzten Block anlegen + if ( nTemp ) + { + pLastBlock = new CBlock( (sal_uInt16)nTemp, pTemp ); + pTemp->SetNextBlock( pLastBlock ); + } + else + pLastBlock = pTemp; + } + + nCount = nNewSize; + } + } + } + else + Clear(); +} + +/************************************************************************* +|* +|* Container::Clear() +|* +*************************************************************************/ + +void Container::Clear() +{ + DBG_CHKTHIS( Container, DbgCheckContainer ); + + // Erst alle Bloecke loeschen + CBlock* pBlock = pFirstBlock; + while ( pBlock ) + { + CBlock* pTemp = pBlock->GetNextBlock(); + delete pBlock; + pBlock = pTemp; + } + + // Werte zuruecksetzen + pFirstBlock = NULL; + pLastBlock = NULL; + pCurBlock = NULL; + nCount = 0; + nCurIndex = 0; +} + +/************************************************************************* +|* +|* Container::GetCurObject() +|* +*************************************************************************/ + +void* Container::GetCurObject() const +{ + DBG_CHKTHIS( Container, DbgCheckContainer ); + + // NULL, wenn Container leer + if ( !nCount ) + return NULL; + else + return pCurBlock->GetObject( nCurIndex ); +} + +/************************************************************************* +|* +|* Container::GetCurPos() +|* +*************************************************************************/ + +sal_uIntPtr Container::GetCurPos() const +{ + DBG_CHKTHIS( Container, DbgCheckContainer ); + + // CONTAINER_ENTRY_NOTFOUND, wenn Container leer + if ( !nCount ) + return CONTAINER_ENTRY_NOTFOUND; + else + { + // Block suchen + CBlock* pTemp = pFirstBlock; + sal_uIntPtr nTemp = 0; + while ( pTemp != pCurBlock ) + { + nTemp += pTemp->Count(); + pTemp = pTemp->GetNextBlock(); + } + + return nTemp+nCurIndex; + } +} + +/************************************************************************* +|* +|* Container::GetObject() +|* +*************************************************************************/ + +void* Container::GetObject( sal_uIntPtr nIndex ) const +{ + DBG_CHKTHIS( Container, DbgCheckContainer ); + + // Ist Index nicht innerhalb des Containers, dann NULL zurueckgeben + if ( nCount <= nIndex ) + return NULL; + else + { + // Block suchen + CBlock* pTemp = pFirstBlock; + while ( pTemp->Count() <= nIndex ) + { + nIndex -= pTemp->Count(); + pTemp = pTemp->GetNextBlock(); + } + + // Item innerhalb des gefundenen Blocks zurueckgeben + return pTemp->GetObject( (sal_uInt16)nIndex ); + } +} + +/************************************************************************* +|* +|* Container::GetPos() +|* +*************************************************************************/ + +sal_uIntPtr Container::GetPos( const void* p ) const +{ + DBG_CHKTHIS( Container, DbgCheckContainer ); + + void** pNodes; + CBlock* pTemp; + sal_uIntPtr nTemp; + sal_uInt16 nBlockCount; + sal_uInt16 i; + + // Block suchen + pTemp = pFirstBlock; + nTemp = 0; + while ( pTemp ) + { + pNodes = pTemp->GetNodes(); + i = 0; + nBlockCount = pTemp->Count(); + while ( i < nBlockCount ) + { + if ( p == *pNodes ) + return nTemp+i; + pNodes++; + i++; + } + nTemp += nBlockCount; + pTemp = pTemp->GetNextBlock(); + } + + return CONTAINER_ENTRY_NOTFOUND; +} + +/************************************************************************* +|* +|* Container::Seek() +|* +*************************************************************************/ + +void* Container::Seek( sal_uIntPtr nIndex ) +{ + DBG_CHKTHIS( Container, DbgCheckContainer ); + + // Ist der Container leer, dann NULL zurueckgeben + if ( nCount <= nIndex ) + return NULL; + else + { + // Block suchen + CBlock* pTemp = pFirstBlock; + while ( pTemp->Count() <= nIndex ) + { + nIndex -= pTemp->Count(); + pTemp = pTemp->GetNextBlock(); + } + + // Item innerhalb des gefundenen Blocks zurueckgeben + pCurBlock = pTemp; + nCurIndex = (sal_uInt16)nIndex; + return pCurBlock->GetObject( nCurIndex ); + } +} + +/************************************************************************* +|* +|* Container::First() +|* +*************************************************************************/ + +void* Container::First() +{ + DBG_CHKTHIS( Container, DbgCheckContainer ); + + // Ist Container leer, dann NULL zurueckgeben + if ( !nCount ) + return NULL; + else + { + // Block und Index setzen und ersten Pointer zurueckgeben + pCurBlock = pFirstBlock; + nCurIndex = 0; + return pCurBlock->GetObject( nCurIndex ); + } +} + +/************************************************************************* +|* +|* Container::Last() +|* +*************************************************************************/ + +void* Container::Last() +{ + DBG_CHKTHIS( Container, DbgCheckContainer ); + + // Ist Container leer, dann NULL zurueckgeben + if ( !nCount ) + return NULL; + else + { + // Block und Index setzen und ersten Pointer zurueckgeben + pCurBlock = pLastBlock; + nCurIndex = pCurBlock->Count()-1; + return pCurBlock->GetObject( nCurIndex ); + } +} + +/************************************************************************* +|* +|* Container::Next() +|* +*************************************************************************/ + +void* Container::Next() +{ + DBG_CHKTHIS( Container, DbgCheckContainer ); + + // Ist Container leer, dann NULL zurueckgeben, ansonsten preufen ob + // naechste Position noch im aktuellen Block ist. Falls nicht, dann + // einen Block weiterschalten (geht ohne Gefahr, da leere Bloecke + // nicht vorkommen duerfen, es sein denn, es ist der einzige). + if ( !nCount ) + return NULL; + else if ( (nCurIndex+1) < pCurBlock->Count() ) + return pCurBlock->GetObject( ++nCurIndex ); + else if ( pCurBlock->GetNextBlock() ) + { + pCurBlock = pCurBlock->GetNextBlock(); + nCurIndex = 0; + return pCurBlock->GetObject( nCurIndex ); + } + else + return NULL; +} + +/************************************************************************* +|* +|* Container::Prev() +|* +*************************************************************************/ + +void* Container::Prev() +{ + DBG_CHKTHIS( Container, DbgCheckContainer ); + + // Ist Container leer, dann NULL zurueckgeben, ansonsten preufen ob + // vorherige Position noch im aktuellen Block ist. Falls nicht, dann + // einen Block zurueckschalten (geht ohne Gefahr, da leere Bloecke + // nicht vorkommen duerfen, es sein denn, es ist der einzige). + if ( !nCount ) + return NULL; + else if ( nCurIndex ) + return pCurBlock->GetObject( --nCurIndex ); + else if ( pCurBlock->GetPrevBlock() ) + { + pCurBlock = pCurBlock->GetPrevBlock(); + nCurIndex = pCurBlock->Count() - 1; + return pCurBlock->GetObject( nCurIndex ); + } + else + return NULL; +} + +/************************************************************************* +|* +|* Container::operator =() +|* +*************************************************************************/ + +Container& Container::operator =( const Container& r ) +{ + DBG_CHKTHIS( Container, DbgCheckContainer ); + + // Erst alle Bloecke loeschen + CBlock* pBlock = pFirstBlock; + while ( pBlock ) + { + CBlock* pTemp = pBlock->GetNextBlock(); + delete pBlock; + pBlock = pTemp; + } + + // Daten kopieren + ImpCopyContainer( &r ); + return *this; +} + +/************************************************************************* +|* +|* Container::operator ==() +|* +*************************************************************************/ + +sal_Bool Container::operator ==( const Container& r ) const +{ + DBG_CHKTHIS( Container, DbgCheckContainer ); + + if ( nCount != r.nCount ) + return sal_False; + + sal_uIntPtr i = 0; + while ( i < nCount ) + { + if ( GetObject( i ) != r.GetObject( i ) ) + return sal_False; + i++; + } + + return sal_True; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_svtools/source/memtools/tl_unqidx.cxx b/binfilter/bf_svtools/source/memtools/tl_unqidx.cxx new file mode 100644 index 000000000..3356ccd2b --- /dev/null +++ b/binfilter/bf_svtools/source/memtools/tl_unqidx.cxx @@ -0,0 +1,452 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <bf_tools/impcont.hxx> +#include <bf_tools/unqidx.hxx> +#include <bf_tools/unqid.hxx> + +namespace binfilter +{ + +/************************************************************************* +|* +|* UniqueIndex::UniqueIndex() +|* +*************************************************************************/ + +UniqueIndex::UniqueIndex( sal_uIntPtr _nStartIndex, + sal_uIntPtr _nInitSize, sal_uIntPtr _nReSize ) : + Container( _nInitSize ) +{ + nReSize = _nReSize; + nStartIndex = _nStartIndex; + nUniqIndex = 0; + nCount = 0; +} + +/************************************************************************* +|* +|* UniqueIndex::UniqueIndex() +|* +*************************************************************************/ + +UniqueIndex::UniqueIndex( const UniqueIndex& rIdx ) : + Container( rIdx ) +{ + nReSize = rIdx.nReSize; + nStartIndex = rIdx.nStartIndex; + nUniqIndex = rIdx.nUniqIndex; + nCount = rIdx.nCount; +} + +/************************************************************************* +|* +|* UniqueIndex::Insert() +|* +*************************************************************************/ + +sal_uIntPtr UniqueIndex::Insert( void* p ) +{ + // NULL-Pointer ist nicht erlaubt + if ( !p ) + return UNIQUEINDEX_ENTRY_NOTFOUND; + + // Ist Array voll, dann expandieren + if ( nCount == Container::GetSize() ) + SetSize( nCount + nReSize ); + + // Damit UniqIndex nicht ueberlaeuft, wenn Items geloescht wurden + nUniqIndex = nUniqIndex % Container::GetSize(); + + // Leeren Eintrag suchen + while ( Container::ImpGetObject( nUniqIndex ) != NULL ) + nUniqIndex = (nUniqIndex+1) % Container::GetSize(); + + // Object im Array speichern + Container::Replace( p, nUniqIndex ); + + // Anzahl der Eintraege erhoehen und Index zurueckgeben + nCount++; + nUniqIndex++; + return ( nUniqIndex + nStartIndex - 1 ); +} + +/************************************************************************* +|* +|* UniqueIndex::Insert() +|* +*************************************************************************/ + +sal_uIntPtr UniqueIndex::Insert( sal_uIntPtr nIndex, void* p ) +{ + // NULL-Pointer ist nicht erlaubt + if ( !p ) + return UNIQUEINDEX_ENTRY_NOTFOUND; + + sal_uIntPtr nContIndex = nIndex - nStartIndex; + // Ist Array voll, dann expandieren + if ( nContIndex >= Container::GetSize() ) + SetSize( nContIndex + nReSize ); + + // Object im Array speichern + Container::Replace( p, nContIndex ); + + // Anzahl der Eintraege erhoehen und Index zurueckgeben + nCount++; + return nIndex; +} + +/************************************************************************* +|* +|* UniqueIndex::Remove() +|* +*************************************************************************/ + +void* UniqueIndex::Remove( sal_uIntPtr nIndex ) +{ + // Ist Index zulaessig + if ( (nIndex >= nStartIndex) && + (nIndex < (Container::GetSize()+nStartIndex)) ) + { + // Index-Eintrag als leeren Eintrag setzen und Anzahl der + // gespeicherten Indexe erniedriegen, wenn Eintrag belegt war + void* p = Container::Replace( NULL, nIndex-nStartIndex ); + if ( p ) + nCount--; + return p; + } + else + return NULL; +} + +/************************************************************************* +|* +|* UniqueIndex::Get() +|* +*************************************************************************/ + +void* UniqueIndex::Get( sal_uIntPtr nIndex ) const +{ + // Ist Index zulaessig + if ( (nIndex >= nStartIndex) && + (nIndex < (Container::GetSize()+nStartIndex)) ) + return Container::ImpGetObject( nIndex-nStartIndex ); + else + return NULL; +} + +/************************************************************************* +|* +|* UniqueIndex::GetCurIndex() +|* +*************************************************************************/ + +sal_uIntPtr UniqueIndex::GetCurIndex() const +{ + sal_uIntPtr nPos = Container::GetCurPos(); + + // Ist der Current-Index nicht belegt, dann gibt es keinen Current-Index + if ( !Container::ImpGetObject( nPos ) ) + return UNIQUEINDEX_ENTRY_NOTFOUND; + else + return nPos+nStartIndex; +} + +/************************************************************************* +|* +|* UniqueIndex::GetIndex() +|* +*************************************************************************/ + +sal_uIntPtr UniqueIndex::GetIndex( const void* p ) const +{ + // Wird ein NULL-Pointer uebergeben, dann wurde Pointer nicht gefunden + if ( !p ) + return UNIQUEINDEX_ENTRY_NOTFOUND; + + sal_uIntPtr nIndex = Container::GetPos( p ); + + if ( nIndex != CONTAINER_ENTRY_NOTFOUND ) + return nIndex+nStartIndex; + else + return UNIQUEINDEX_ENTRY_NOTFOUND; +} + +/************************************************************************* +|* +|* UniqueIndex::IsIndexValid() +|* +*************************************************************************/ + +sal_Bool UniqueIndex::IsIndexValid( sal_uIntPtr nIndex ) const +{ + // Ist Index zulaessig + if ( (nIndex >= nStartIndex) && + (nIndex < (Container::GetSize()+nStartIndex)) ) + { + // Index ist nur zulaessig, wenn Eintrag auch belegt ist + if ( Container::ImpGetObject( nIndex-nStartIndex ) ) + return sal_True; + else + return sal_False; + } + else + return sal_False; +} + +/************************************************************************* +|* +|* UniqueIndex::Seek() +|* +*************************************************************************/ + +void* UniqueIndex::Seek( sal_uIntPtr nIndex ) +{ + // Index-Eintrag als aktuellen setzten, wenn er gueltig ist + if ( IsIndexValid( nIndex ) ) + return Container::Seek( nIndex-nStartIndex ); + else + return NULL; +} + +/************************************************************************* +|* +|* UniqueIndex::Seek() +|* +*************************************************************************/ + +void* UniqueIndex::Seek( void* p ) +{ + // Wird ein NULL-Pointer uebergeben, dann wurde Pointer nicht gefunden + if ( !p ) + return NULL; + + sal_uIntPtr nIndex = GetIndex( p ); + + // Ist Index vorhanden, dann als aktuellen Eintrag setzen + if ( nIndex != UNIQUEINDEX_ENTRY_NOTFOUND ) + return Container::Seek( nIndex-nStartIndex ); + else + return NULL; +} + +/************************************************************************* +|* +|* UniqueIndex::First() +|* +*************************************************************************/ + +void* UniqueIndex::First() +{ + void* p = Container::First(); + + while ( !p && (Container::GetCurPos() < (Container::GetSize()-1)) ) + p = Container::Next(); + + return p; +} + +/************************************************************************* +|* +|* UniqueIndex::Last() +|* +*************************************************************************/ + +void* UniqueIndex::Last() +{ + void* p = Container::Last(); + + while ( !p && Container::GetCurPos() ) + p = Container::Prev(); + + return p; +} + +/************************************************************************* +|* +|* UniqueIndex::Next() +|* +*************************************************************************/ + +void* UniqueIndex::Next() +{ + void* p = NULL; + + while ( !p && (Container::GetCurPos() < (Container::GetSize()-1)) ) + p = Container::Next(); + + return p; +} + +/************************************************************************* +|* +|* UniqueIndex::Prev() +|* +*************************************************************************/ + +void* UniqueIndex::Prev() +{ + void* p = NULL; + + while ( !p && Container::GetCurPos() ) + p = Container::Prev(); + + return p; +} + +/************************************************************************* +|* +|* UniqueIndex::operator =() +|* +*************************************************************************/ + +UniqueIndex& UniqueIndex::operator =( const UniqueIndex& rIdx ) +{ + // Neue Werte zuweisen + Container::operator =( rIdx ); + nReSize = rIdx.nReSize; + nStartIndex = rIdx.nStartIndex; + nUniqIndex = rIdx.nUniqIndex; + nCount = rIdx.nCount; + return *this; +} + +/************************************************************************* +|* +|* UniqueIndex::operator ==() +|* +*************************************************************************/ + +sal_Bool UniqueIndex::operator ==( const UniqueIndex& rIdx ) const +{ + // Neue Werte zuweisen + if ( (nStartIndex == rIdx.nStartIndex) && + (nCount == rIdx.nCount) && + (Container::operator ==( rIdx )) ) + return sal_True; + else + return sal_False; +} +/************************************************************************* +|* +|* UniqueIdContainer::UniqueIdContainer () +|* +*************************************************************************/ + +UniqueIdContainer::UniqueIdContainer( const UniqueIdContainer& rObj ) + : UniqueIndex( rObj ) + , nCollectCount( rObj.nCollectCount ) +{ + sal_uIntPtr nCur = GetCurIndex(); + + ImpUniqueId * pEle = (ImpUniqueId *)First(); + while( pEle ) + { + pEle->nRefCount++; + pEle = (ImpUniqueId *)Next(); + } + Seek( nCur ); +} + +/************************************************************************* +|* +|* UniqueIdContainer::operator = () +|* +*************************************************************************/ + +UniqueIdContainer& UniqueIdContainer::operator = ( const UniqueIdContainer & rObj ) +{ + UniqueIndex::operator = ( rObj ); + nCollectCount = rObj.nCollectCount; + + sal_uIntPtr nCur = GetCurIndex(); + + ImpUniqueId * pEle = (ImpUniqueId *)First(); + while( pEle ) + { + pEle->nRefCount++; + pEle = (ImpUniqueId *)Next(); + } + Seek( nCur ); + return *this; +} + +/************************************************************************* +|* +|* UniqueIdContainer::Clear() +|* +*************************************************************************/ + +void UniqueIdContainer::Clear( sal_Bool bAll ) +{ + sal_uInt16 nFree = bAll ? 0xFFFF : 1; + + ImpUniqueId* pId = (ImpUniqueId*)Last(); + sal_Bool bLast = sal_True; + while ( pId ) + { + if ( pId->nRefCount <= nFree ) + { + ((ImpUniqueId *)Remove( pId->nId ))->Release(); + if( bLast ) + pId = (ImpUniqueId *)Last(); + else + pId = (ImpUniqueId *)Prev(); + } + else + { + pId = (ImpUniqueId *)Prev(); + bLast = sal_False; + } + } +} + +/************************************************************************* +|* +|* UniqueIdContainer::CreateId() +|* +*************************************************************************/ + +UniqueItemId UniqueIdContainer::CreateId() +{ + if( nCollectCount > 50 ) + { // aufraeumen + Clear( sal_False ); + nCollectCount = 0; + } + nCollectCount++; + + ImpUniqueId * pId = new ImpUniqueId; + pId->nRefCount = 1; + pId->nId = Insert( pId ); + return UniqueItemId( pId ); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/inc/bf_so3/pseudo.hxx b/binfilter/inc/bf_so3/pseudo.hxx index 395e1c71e..9236cbc3c 100644 --- a/binfilter/inc/bf_so3/pseudo.hxx +++ b/binfilter/inc/bf_so3/pseudo.hxx @@ -30,7 +30,7 @@ #include <bf_svtools/bf_solar.h> -#include <tools/unqid.hxx> +#include <bf_tools/unqid.hxx> #include <bf_so3/iface.hxx> #include <bf_svtools/ownlist.hxx> diff --git a/binfilter/inc/bf_tools/contnr.hxx b/binfilter/inc/bf_tools/contnr.hxx new file mode 100644 index 000000000..6d7e70fc5 --- /dev/null +++ b/binfilter/inc/bf_tools/contnr.hxx @@ -0,0 +1,124 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _BF_CONTNR_HXX +#define _BF_CONTNR_HXX + +#include <tools/solar.h> + +#include <limits.h> + +namespace binfilter { + +class CBlock; + +// ------------- +// - Container - +// ------------- + +// Maximale Blockgroesse +#define CONTAINER_MAXBLOCKSIZE ((sal_uInt16)0x3FF0) + +#define CONTAINER_APPEND ULONG_MAX +#define CONTAINER_ENTRY_NOTFOUND ULONG_MAX + +class Container +{ +private: + CBlock* pFirstBlock; + CBlock* pCurBlock; + CBlock* pLastBlock; + sal_uInt16 nCurIndex; + sal_uInt16 nBlockSize; + sal_uInt16 nInitSize; + sal_uInt16 nReSize; + sal_uIntPtr nCount; + + void ImpCopyContainer(Container const *); +#if defined DBG_UTIL + static char const * DbgCheckContainer(void const *); +#endif + +protected: +#ifdef _BF_IMPCONT_HXX + void ImpInsert( void* p, CBlock* pBlock, sal_uInt16 nIndex ); + void* ImpRemove( CBlock* pBlock, sal_uInt16 nIndex ); + void* ImpGetObject( sal_uIntPtr nIndex ) const; + void** ImpGetOnlyNodes() const; +#endif + +public: + Container( sal_uInt16 nBlockSize, + sal_uInt16 nInitSize, + sal_uInt16 nReSize ); + Container( sal_uIntPtr nSize ); + Container( const Container& rContainer ); + ~Container(); + + void Insert( void* p ); + void Insert( void* p, sal_uIntPtr nIndex ); + + void* Remove(); + void* Remove( sal_uIntPtr nIndex ); + void* Remove( void* p ) + { return Remove( GetPos( p ) ); } + + void* Replace( void* p, sal_uIntPtr nIndex ); + void* Replace( void* pNew, void* pOld ) + { return Replace( pNew, GetPos( pOld ) ); } + + void SetSize( sal_uIntPtr nNewSize ); + sal_uIntPtr GetSize() const { return nCount; } + + sal_uIntPtr Count() const { return nCount; } + void Clear(); + + void* GetCurObject() const; + sal_uIntPtr GetCurPos() const; + void* GetObject( sal_uIntPtr nIndex ) const; + sal_uIntPtr GetPos( const void* p ) const; + + void* Seek( sal_uIntPtr nIndex ); + void* Seek( void* p ) { return Seek( GetPos( p ) ); } + + void* First(); + void* Last(); + void* Next(); + void* Prev(); + + Container& operator =( const Container& rContainer ); + + sal_Bool operator ==( const Container& rContainer ) const; + sal_Bool operator !=( const Container& rContainer ) const + { return !(Container::operator==( rContainer )); } +}; + +} + +#endif // _BF_CONTNR_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/inc/bf_tools/impcont.hxx b/binfilter/inc/bf_tools/impcont.hxx new file mode 100644 index 000000000..09cdcb2b1 --- /dev/null +++ b/binfilter/inc/bf_tools/impcont.hxx @@ -0,0 +1,147 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _BF_IMPCONT_HXX +#define _BF_IMPCONT_HXX + +#include <bf_tools/contnr.hxx> + +namespace binfilter { + +typedef void* PVOID; + +// ---------- +// - CBlock - +// ---------- + +class CBlock +{ +private: + CBlock* pPrev; // Vorheriger Block + CBlock* pNext; // Naechster Block + sal_uInt16 nSize; // Groesse des Blocks + sal_uInt16 nCount; // Anzahl Pointer + void** pNodes; // Pointer auf die Daten + +#if defined DBG_UTIL + static char const * DbgCheckCBlock(void const *); +#endif + +public: + // Fuer List-Container + CBlock( sal_uInt16 nSize, CBlock* pPrev, CBlock* pNext ); + // Fuer Array-Container + CBlock( sal_uInt16 nSize, CBlock* pPrev ); + // Copy-Ctor + CBlock( const CBlock& r, CBlock* pPrev ); + ~CBlock(); + + void Insert( void* p, sal_uInt16 nIndex, sal_uInt16 nReSize ); + CBlock* Split( void* p, sal_uInt16 nIndex, sal_uInt16 nReSize ); + void* Remove( sal_uInt16 nIndex, sal_uInt16 nReSize ); + void* Replace( void* pNew, sal_uInt16 nIndex ); + + void** GetNodes() const { return pNodes; } + void** GetObjectPtr( sal_uInt16 nIndex ); + void* GetObject( sal_uInt16 nIndex ) const; + + void SetSize( sal_uInt16 nNewSize ); + + sal_uInt16 GetSize() const { return nCount; } + sal_uInt16 Count() const { return nCount; } + void SetPrevBlock( CBlock* p ) { pPrev = p; } + void SetNextBlock( CBlock* p ) { pNext = p; } + CBlock* GetPrevBlock() const { return pPrev; } + CBlock* GetNextBlock() const { return pNext; } + void Reset() { nCount = 0; } + +private: + CBlock( const CBlock& r ); + + friend class Container; +}; + +/************************************************************************* +|* +|* CBlock::GetObject() +|* +|* Beschreibung Gibt einen Pointer aus dem Block zurueck +|* +*************************************************************************/ + +inline void* CBlock::GetObject( sal_uInt16 nIndex ) const +{ + return pNodes[nIndex]; +} + +/************************************************************************* +|* +|* Container::ImpGetObject() +|* +|* Beschreibung Wir gehen davon aus, das Pointer in der Regel +|* sich im ersten Block befindet und schalten +|* deshalb eine Inline-Methode davor +|* +*************************************************************************/ + +inline void* Container::ImpGetObject( sal_uIntPtr nIndex ) const +{ + if ( pFirstBlock && (nIndex < pFirstBlock->Count()) ) + // Item innerhalb des gefundenen Blocks zurueckgeben + return pFirstBlock->GetObject( (sal_uInt16)nIndex ); + else + return GetObject( nIndex ); +} + +/************************************************************************* +|* +|* Container::ImpGetOnlyNodes() +|* +|* Beschreibung Wenn es nur einen Block gibt, wird davon +|* das Daten-Array zurueckgegeben +|* +*************************************************************************/ + +// #i70651#: Prevent warnings on Mac OS X +#ifdef MACOSX +#pragma GCC system_header +#endif + +inline void** Container::ImpGetOnlyNodes() const +{ + if ( (pFirstBlock == pLastBlock) && pFirstBlock ) + return pFirstBlock->GetNodes(); + else + return NULL; +} + +} + +#endif // _BF_IMPCONT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/inc/bf_tools/unqid.hxx b/binfilter/inc/bf_tools/unqid.hxx new file mode 100644 index 000000000..853e9fb22 --- /dev/null +++ b/binfilter/inc/bf_tools/unqid.hxx @@ -0,0 +1,113 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _BF_UNQID_HXX +#define _BF_UNQID_HXX + +#include <bf_tools/unqidx.hxx> + +namespace binfilter { + +// --------------- +// - ImpUniqueId - +// --------------- + +struct ImpUniqueId +{ + sal_uIntPtr nId; + sal_uInt16 nRefCount; + void Release() + { + nRefCount--; + if( 0 == nRefCount ) + delete this; + } +}; + +// ------------ +// - UniqueId - +// ------------ + +class UniqueIdContainer; +class UniqueItemId +{ + friend class UniqueIdContainer; + ImpUniqueId* pId; + + UniqueItemId( ImpUniqueId * pIdP ) + { pId = pIdP; pId->nRefCount++; } +public: + UniqueItemId() { pId = NULL; } + UniqueItemId( const UniqueItemId & rId ) + { pId = rId.pId; if( pId ) pId->nRefCount++; } + ~UniqueItemId() + { if( pId ) pId->Release(); } + UniqueItemId& operator = ( const UniqueItemId & rId ) + { + if( rId.pId ) rId.pId->nRefCount++; + if( pId ) pId->Release(); + pId = rId.pId; + return *this; + } + sal_uIntPtr GetId() const { return pId ? pId->nId : 0; } +}; + +// --------------------- +// - UniqueIdContainer - +// --------------------- + +class UniqueIdContainer : private UniqueIndex +{ + sal_uInt16 nCollectCount; + +public: // Irgend etwas mit protected falsch + void Clear( sal_Bool bAll ); + +public: + UniqueIdContainer( sal_uIntPtr _nStartIndex, + sal_uIntPtr _nInitSize = 16, + sal_uIntPtr _nReSize = 16 ) + : UniqueIndex( _nStartIndex, _nInitSize, _nReSize ) + , nCollectCount( 0 ) + {} + UniqueIdContainer( const UniqueIdContainer& ); + + ~UniqueIdContainer() + { Clear( sal_True ); } + UniqueIdContainer& operator = ( const UniqueIdContainer & ); + + sal_Bool IsIndexValid( sal_uIntPtr nIndex ) const + { return UniqueIndex::IsIndexValid( nIndex ); } + + UniqueItemId CreateId(); +}; + +} + +#endif // _BF_UNQID_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/inc/bf_tools/unqidx.hxx b/binfilter/inc/bf_tools/unqidx.hxx new file mode 100644 index 000000000..3bcd88af4 --- /dev/null +++ b/binfilter/inc/bf_tools/unqidx.hxx @@ -0,0 +1,152 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _BF_UNQIDX_HXX +#define _BF_UNQIDX_HXX + +#include <bf_tools/contnr.hxx> + +namespace binfilter { + +// --------------- +// - UniqueIndex - +// --------------- + +#define UNIQUEINDEX_ENTRY_NOTFOUND CONTAINER_ENTRY_NOTFOUND + +class UniqueIndex : private Container +{ +private: + sal_uIntPtr nReSize; + sal_uIntPtr nStartIndex; + sal_uIntPtr nUniqIndex; + sal_uIntPtr nCount; + +public: + using Container::GetCurObject; + + UniqueIndex( sal_uIntPtr nStartIndex = 0, + sal_uIntPtr nInitSize = 16, + sal_uIntPtr nReSize = 16 ); + UniqueIndex( const UniqueIndex& rIdx ); + + sal_uIntPtr Insert( sal_uIntPtr nIndex, void* p ); + sal_uIntPtr Insert( void* p ); + void* Remove( sal_uIntPtr nIndex ); + void* Get( sal_uIntPtr nIndex ) const; + + void Clear(); + sal_uIntPtr Count() const { return nCount; } + + sal_uIntPtr GetCurIndex() const; + sal_uIntPtr GetIndex( const void* p ) const; + sal_Bool IsIndexValid( sal_uIntPtr nIndex ) const; + + void* Seek( sal_uIntPtr nIndex ); + void* Seek( void* p ); + void* First(); + void* Last(); + void* Next(); + void* Prev(); + + sal_uIntPtr GetStartIndex() const { return nStartIndex; } + sal_uIntPtr GetCurMaxIndex() const + { return (nStartIndex + Container::GetSize()); } + + UniqueIndex& operator =( const UniqueIndex& rIdx ); + + sal_Bool operator ==( const UniqueIndex& rIdx ) const; + sal_Bool operator !=( const UniqueIndex& rIdx ) const + { return !(UniqueIndex::operator==( rIdx )); } +}; + +inline void UniqueIndex::Clear() +{ + Container::Clear(); + nCount = 0; + nUniqIndex = 0; +} + +// ----------------------- +// - DECLARE_UNIQUEINDEX - +// ----------------------- + +#define DECLARE_UNIQUEINDEX( ClassName, Type ) \ +class ClassName : private UniqueIndex \ +{ \ +public: \ + using UniqueIndex::Clear; \ + using UniqueIndex::Count; \ + using UniqueIndex::GetCurIndex; \ + using UniqueIndex::IsIndexValid; \ + using UniqueIndex::GetStartIndex; \ + using UniqueIndex::GetCurMaxIndex; \ + \ + ClassName( sal_uIntPtr _nStartIndex = 0, \ + sal_uIntPtr _nInitSize = 16, sal_uIntPtr _nReSize = 16 ):\ + UniqueIndex( _nStartIndex, _nInitSize, _nReSize ) {}\ + ClassName( const ClassName& rClassName ) : \ + UniqueIndex( rClassName ) {} \ + \ + sal_uIntPtr Insert( sal_uIntPtr nIndex, Type p ) \ + { return UniqueIndex::Insert( nIndex, (void*)p ); } \ + sal_uIntPtr Insert( Type p ) \ + { return UniqueIndex::Insert( (void*)p ); } \ + Type Remove( sal_uIntPtr nIndex ) \ + { return (Type)UniqueIndex::Remove( nIndex ); } \ + Type Get( sal_uIntPtr nIndex ) const \ + { return (Type)UniqueIndex::Get( nIndex ); } \ + \ + Type GetCurObject() const \ + { return (Type)UniqueIndex::GetCurObject(); } \ + sal_uIntPtr GetIndex( const Type p ) const \ + { return UniqueIndex::GetIndex( (const void*)p ); } \ + \ + Type Seek( sal_uIntPtr nKey ) \ + { return (Type)UniqueIndex::Seek( nKey ); } \ + Type Seek( Type p ) \ + { return (Type)UniqueIndex::Seek( (void*)p ); } \ + Type First() { return (Type)UniqueIndex::First(); } \ + Type Last() { return (Type)UniqueIndex::Last(); } \ + Type Next() { return (Type)UniqueIndex::Next(); } \ + Type Prev() { return (Type)UniqueIndex::Prev(); } \ + \ + ClassName& operator =( const ClassName& rClassName ) \ + { UniqueIndex::operator =( rClassName ); \ + return *this; } \ + \ + sal_Bool operator ==( const ClassName& rIdx ) const \ + { return UniqueIndex::operator ==( rIdx ); } \ + sal_Bool operator !=( const ClassName& rIdx ) const \ + { return UniqueIndex::operator !=( rIdx ); } \ +}; + +} + +#endif // _BF_UNQIDX_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |