229 lines
6.5 KiB
C
229 lines
6.5 KiB
C
/* chunks.c */
|
|
/*****************************************************************************/
|
|
/* AS-Portierung */
|
|
/* */
|
|
/* Verwaltung von Adressbereichslisten */
|
|
/* */
|
|
/* Historie: 16. 5.1996 Grundsteinlegung */
|
|
/* 16. 8.1998 Min/Max-Ausgabe */
|
|
/* */
|
|
/*****************************************************************************/
|
|
|
|
#include "stdinc.h"
|
|
|
|
#include "strutil.h"
|
|
|
|
#include "chunks.h"
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* eine Chunkliste initialisieren */
|
|
|
|
void InitChunk(ChunkList *NChunk)
|
|
BEGIN
|
|
NChunk->RealLen=0;
|
|
NChunk->AllocLen=0;
|
|
NChunk->Chunks=Nil;
|
|
END
|
|
|
|
void ClearChunk(ChunkList *NChunk)
|
|
BEGIN
|
|
if (NChunk->AllocLen>0) free(NChunk->Chunks);
|
|
InitChunk(NChunk);
|
|
END
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* eine Chunkliste um einen Eintrag erweitern */
|
|
|
|
static Boolean Overlap(LargeWord Start1, LargeWord Len1, LargeWord Start2, LargeWord Len2)
|
|
BEGIN
|
|
return ((Start1==Start2)
|
|
OR ((Start2>Start1) AND (Start1+Len1>=Start2))
|
|
OR ((Start1>Start2) AND (Start2+Len2>=Start1)));
|
|
END
|
|
|
|
static void SetChunk(OneChunk *NChunk, LargeWord Start1, LargeWord Len1,
|
|
LargeWord Start2, LargeWord Len2)
|
|
BEGIN
|
|
NChunk->Start =min(Start1,Start2);
|
|
NChunk->Length=max(Start1+Len1-1,Start2+Len2-1)-NChunk->Start+1;
|
|
END
|
|
|
|
static void IncChunk(ChunkList *NChunk)
|
|
BEGIN
|
|
if (NChunk->RealLen+1>NChunk->AllocLen)
|
|
BEGIN
|
|
if (NChunk->RealLen==0)
|
|
NChunk->Chunks=(OneChunk *) malloc(sizeof(OneChunk));
|
|
else
|
|
NChunk->Chunks=(OneChunk *) realloc(NChunk->Chunks,sizeof(OneChunk)*(NChunk->RealLen+1));
|
|
NChunk->AllocLen=NChunk->RealLen+1;
|
|
END
|
|
END
|
|
|
|
Boolean AddChunk(ChunkList *NChunk, LargeWord NewStart, LargeWord NewLen, Boolean Warn)
|
|
BEGIN
|
|
Word z,f1=0,f2=0;
|
|
Boolean Found;
|
|
LongInt PartSum;
|
|
Boolean Result;
|
|
|
|
Result=False;
|
|
|
|
if (NewLen==0) return Result;
|
|
|
|
/* herausfinden, ob sich das neue Teil irgendwo mitanhaengen laesst */
|
|
|
|
Found=False;
|
|
for (z=0; z<NChunk->RealLen; z++)
|
|
if (Overlap(NewStart,NewLen,NChunk->Chunks[z].Start,NChunk->Chunks[z].Length))
|
|
BEGIN
|
|
Found=True; f1=z; break;
|
|
END
|
|
|
|
/* Fall 1: etwas gefunden : */
|
|
|
|
if (Found)
|
|
BEGIN
|
|
/* gefundene Chunk erweitern */
|
|
|
|
PartSum=NChunk->Chunks[f1].Length+NewLen;
|
|
SetChunk(NChunk->Chunks+f1,NewStart,NewLen,NChunk->Chunks[f1].Start,NChunk->Chunks[f1].Length);
|
|
if (Warn)
|
|
if (PartSum!=NChunk->Chunks[f1].Length) Result=True;
|
|
|
|
/* schauen, ob sukzessiv neue Chunks angebunden werden koennen */
|
|
|
|
do
|
|
BEGIN
|
|
Found=False;
|
|
for (z=1; z<NChunk->RealLen; z++)
|
|
if (z!=f1)
|
|
if (Overlap(NChunk->Chunks[z].Start,NChunk->Chunks[z].Length,NChunk->Chunks[f1].Start,NChunk->Chunks[f1].Length))
|
|
BEGIN
|
|
Found=True; f2=z; break;
|
|
END
|
|
if (Found)
|
|
BEGIN
|
|
SetChunk(NChunk->Chunks+f1,NChunk->Chunks[f1].Start,NChunk->Chunks[f1].Length,NChunk->Chunks[f2].Start,NChunk->Chunks[f2].Length);
|
|
NChunk->Chunks[f2]=NChunk->Chunks[--NChunk->RealLen];
|
|
END
|
|
END
|
|
while (Found);
|
|
END
|
|
|
|
/* ansonsten Feld erweitern und einschreiben */
|
|
|
|
else
|
|
BEGIN
|
|
IncChunk(NChunk);
|
|
|
|
NChunk->Chunks[NChunk->RealLen].Length=NewLen;
|
|
NChunk->Chunks[NChunk->RealLen].Start=NewStart;
|
|
NChunk->RealLen++;
|
|
END
|
|
|
|
return Result;
|
|
END
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* Ein Stueck wieder austragen */
|
|
|
|
void DeleteChunk(ChunkList *NChunk, LargeWord DelStart, LargeWord DelLen)
|
|
BEGIN
|
|
Word z;
|
|
LargeWord OStart;
|
|
|
|
if (DelLen==0) return;
|
|
|
|
z=0;
|
|
while (z<=NChunk->RealLen)
|
|
BEGIN
|
|
if (Overlap(DelStart,DelLen,NChunk->Chunks[z].Start,NChunk->Chunks[z].Length))
|
|
BEGIN
|
|
if (NChunk->Chunks[z].Start>=DelStart)
|
|
if (DelStart+DelLen>=NChunk->Chunks[z].Start+NChunk->Chunks[z].Length)
|
|
BEGIN
|
|
/* ganz loeschen */
|
|
NChunk->Chunks[z]=NChunk->Chunks[--NChunk->RealLen];
|
|
END
|
|
else
|
|
BEGIN
|
|
/* unten abschneiden */
|
|
OStart=NChunk->Chunks[z].Start; NChunk->Chunks[z].Start=DelStart+DelLen;
|
|
NChunk->Chunks[z].Start-=NChunk->Chunks[z].Start-OStart;
|
|
END
|
|
else
|
|
if (DelStart+DelLen>=NChunk->Chunks[z].Start+NChunk->Chunks[z].Length)
|
|
BEGIN
|
|
/* oben abschneiden */
|
|
NChunk->Chunks[z].Length=DelStart-NChunk->Chunks[z].Start;
|
|
/* wenn Laenge 0, ganz loeschen */
|
|
if (NChunk->Chunks[z].Length==0)
|
|
BEGIN
|
|
NChunk->Chunks[z]=NChunk->Chunks[--NChunk->RealLen];
|
|
END
|
|
END
|
|
else
|
|
BEGIN
|
|
/* teilen */
|
|
IncChunk(NChunk);
|
|
NChunk->Chunks[NChunk->RealLen].Start=DelStart+DelLen;
|
|
NChunk->Chunks[NChunk->RealLen].Length=NChunk->Chunks[z].Start+NChunk->Chunks[z].Length-NChunk->Chunks[NChunk->RealLen].Start;
|
|
NChunk->Chunks[z].Length=DelStart-NChunk->Chunks[z].Start;
|
|
END
|
|
END
|
|
z++;
|
|
END
|
|
END
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* Minimaladresse holen */
|
|
|
|
LargeWord ChunkMin(ChunkList *NChunk)
|
|
BEGIN
|
|
LongInt z;
|
|
LargeWord t=(LargeWord) -1;
|
|
|
|
if (NChunk->RealLen==0) return 0;
|
|
|
|
for (z=0; z<NChunk->RealLen; z++)
|
|
if (NChunk->Chunks[z].Start<t) t=NChunk->Chunks[z].Start;
|
|
|
|
return t;
|
|
END
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* Maximaladresse holen */
|
|
|
|
LargeWord ChunkMax(ChunkList *NChunk)
|
|
BEGIN
|
|
LongInt z;
|
|
LargeWord t=(LargeWord) 0;
|
|
|
|
if (NChunk->RealLen==0) return 0;
|
|
|
|
for (z=0; z<NChunk->RealLen; z++)
|
|
if (NChunk->Chunks[z].Start+NChunk->Chunks[z].Length-1>t)
|
|
t=NChunk->Chunks[z].Start+NChunk->Chunks[z].Length-1;
|
|
|
|
return t;
|
|
END
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* Menge holen */
|
|
|
|
LargeWord ChunkSum(ChunkList *NChunk)
|
|
BEGIN
|
|
LongInt z;
|
|
LargeWord Sum=0;
|
|
|
|
for (z=0; z<NChunk->RealLen; z++)
|
|
Sum+=NChunk->Chunks[z].Length;
|
|
|
|
return Sum;
|
|
END
|
|
|
|
void chunks_init(void)
|
|
BEGIN
|
|
END
|