/****************************************************************************
 *  This file is part of PPMd project                                       *
 *  Written and distributed to public domain by Dmitry Shkarin 1997,        *
 *  1999-2000                                                               *
 *  Contents: memory allocation routines                                    *
 ****************************************************************************/

namespace third_party_unrar {

static const uint UNIT_SIZE=Max(sizeof(RARPPM_CONTEXT),sizeof(RARPPM_MEM_BLK));
static const uint FIXED_UNIT_SIZE=12;

SubAllocator::SubAllocator()
{
  Clean();
}


void SubAllocator::Clean()
{
  SubAllocatorSize=0;
}


inline void SubAllocator::InsertNode(void* p,int indx) 
{
  ((RAR_NODE*) p)->next=FreeList[indx].next;
  FreeList[indx].next=(RAR_NODE*) p;
}


inline void* SubAllocator::RemoveNode(int indx) 
{
  RAR_NODE* RetVal=FreeList[indx].next;
  FreeList[indx].next=RetVal->next;
  return RetVal;
}


inline uint SubAllocator::U2B(int NU) 
{ 
  // We calculate the size of units in bytes based on real UNIT_SIZE.
  // In original implementation it was 8*NU+4*NU.
  return UNIT_SIZE*NU;
}



// Calculate RARPPM_MEM_BLK+Items address. Real RARPPM_MEM_BLK size must be
// equal to UNIT_SIZE, so we cannot just add Items to RARPPM_MEM_BLK address.
inline RARPPM_MEM_BLK* SubAllocator::MBPtr(RARPPM_MEM_BLK *BasePtr,int Items)
{
  return((RARPPM_MEM_BLK*)( ((byte *)(BasePtr))+U2B(Items) ));
}


inline void SubAllocator::SplitBlock(void* pv,int OldIndx,int NewIndx)
{
  int i, UDiff=Indx2Units[OldIndx]-Indx2Units[NewIndx];
  byte* p=((byte*) pv)+U2B(Indx2Units[NewIndx]);
  if (Indx2Units[i=Units2Indx[UDiff-1]] != UDiff) 
  {
    InsertNode(p,--i);
    p += U2B(i=Indx2Units[i]);
    UDiff -= i;
  }
  InsertNode(p,Units2Indx[UDiff-1]);
}


void SubAllocator::StopSubAllocator()
{
  if ( SubAllocatorSize ) 
  {
    SubAllocatorSize=0;
    free(HeapStart);
  }
}


bool SubAllocator::StartSubAllocator(int SASize)
{
  uint t=SASize << 20;
  if (SubAllocatorSize == t)
    return true;
  StopSubAllocator();

  // Original algorithm expects FIXED_UNIT_SIZE, but actual structure size
  // can be larger. So let's recalculate the allocated size and add two more
  // units: one as reserve for HeapEnd overflow checks and another
  // to provide the space to correctly align UnitsStart.
  uint AllocSize=t/FIXED_UNIT_SIZE*UNIT_SIZE+2*UNIT_SIZE;
  if ((HeapStart=(byte *)malloc(AllocSize)) == NULL)
  {
    ErrHandler.MemoryError();
    return false;
  }

  // HeapEnd did not present in original algorithm. We added it to control
  // invalid memory access attempts when processing corrupt archived data.
  HeapEnd=HeapStart+AllocSize-UNIT_SIZE;

  SubAllocatorSize=t;
  return true;
}


void SubAllocator::InitSubAllocator()
{
  int i, k;
  memset(FreeList,0,sizeof(FreeList));
  pText=HeapStart;

  // Original algorithm operates with 12 byte FIXED_UNIT_SIZE, but actual
  // size of RARPPM_MEM_BLK and RARPPM_CONTEXT structures can exceed this value
  // because of alignment and larger pointer fields size.
  // So we define UNIT_SIZE for this larger size and adjust memory
  // pointers accordingly.

  // Size2 is (HiUnit-LoUnit) memory area size to allocate as originally
  // supposed by compression algorithm. It is 7/8 of total allocated size.
  uint Size2=FIXED_UNIT_SIZE*(SubAllocatorSize/8/FIXED_UNIT_SIZE*7);

  // RealSize2 is the real adjusted size of (HiUnit-LoUnit) memory taking
  // into account that our UNIT_SIZE can be larger than FIXED_UNIT_SIZE.
  uint RealSize2=Size2/FIXED_UNIT_SIZE*UNIT_SIZE;

  // Size1 is the size of memory area from HeapStart to FakeUnitsStart
  // as originally supposed by compression algorithm. This area can contain
  // different data types, both single symbols and structures.
  uint Size1=SubAllocatorSize-Size2;

  // Real size of this area. We correct it according to UNIT_SIZE vs
  // FIXED_UNIT_SIZE difference. Also we add one more UNIT_SIZE
  // to compensate a possible reminder from Size1/FIXED_UNIT_SIZE,
  // which would be lost otherwise. We add UNIT_SIZE instead of 
  // this Size1%FIXED_UNIT_SIZE reminder, because it allows to align
  // UnitsStart easily and adding more than reminder is ok for algorithm.
  uint RealSize1=Size1/FIXED_UNIT_SIZE*UNIT_SIZE+UNIT_SIZE;

  // RealSize1 must be divided by UNIT_SIZE without a reminder, so UnitsStart
  // is aligned to UNIT_SIZE. It is important for those architectures,
  // where a proper memory alignment is mandatory. Since we produce RealSize1
  // multiplying by UNIT_SIZE, this condition is always true. So LoUnit,
  // UnitsStart, HeapStart are properly aligned,
  LoUnit=UnitsStart=HeapStart+RealSize1;

  // When we reach FakeUnitsStart, we restart the model. It is where
  // the original algorithm expected to see UnitsStart. Real UnitsStart
  // can have a larger value.
  FakeUnitsStart=HeapStart+Size1;

  HiUnit=LoUnit+RealSize2;
  for (i=0,k=1;i < N1     ;i++,k += 1)
    Indx2Units[i]=k;
  for (k++;i < N1+N2      ;i++,k += 2)
    Indx2Units[i]=k;
  for (k++;i < N1+N2+N3   ;i++,k += 3)
    Indx2Units[i]=k;
  for (k++;i < N1+N2+N3+N4;i++,k += 4)
    Indx2Units[i]=k;
  for (GlueCount=k=i=0;k < 128;k++)
  {
    i += (Indx2Units[i] < k+1);
    Units2Indx[k]=i;
  }
}


inline void SubAllocator::GlueFreeBlocks()
{
  RARPPM_MEM_BLK s0, * p, * p1;
  int i, k, sz;
  if (LoUnit != HiUnit)
    *LoUnit=0;
  for (i=0, s0.next=s0.prev=&s0;i < N_INDEXES;i++)
    while ( FreeList[i].next )
    {
      p=(RARPPM_MEM_BLK*)RemoveNode(i);
      p->insertAt(&s0);
      p->Stamp=0xFFFF;
      p->NU=Indx2Units[i];
    }
  for (p=s0.next;p != &s0;p=p->next)
    while ((p1=MBPtr(p,p->NU))->Stamp == 0xFFFF && int(p->NU)+p1->NU < 0x10000)
    {
      p1->remove();
      p->NU += p1->NU;
    }
  while ((p=s0.next) != &s0)
  {
    for (p->remove(), sz=p->NU;sz > 128;sz -= 128, p=MBPtr(p,128))
      InsertNode(p,N_INDEXES-1);
    if (Indx2Units[i=Units2Indx[sz-1]] != sz)
    {
      k=sz-Indx2Units[--i];
      InsertNode(MBPtr(p,sz-k),k-1);
    }
    InsertNode(p,i);
  }
}

void* SubAllocator::AllocUnitsRare(int indx)
{
  if ( !GlueCount )
  {
    GlueCount = 255;
    GlueFreeBlocks();
    if ( FreeList[indx].next )
      return RemoveNode(indx);
  }
  int i=indx;
  do
  {
    if (++i == N_INDEXES)
    {
      GlueCount--;
      i=U2B(Indx2Units[indx]);
      int j=FIXED_UNIT_SIZE*Indx2Units[indx];
      if (FakeUnitsStart - pText > j)
      {
        FakeUnitsStart -= j;
        UnitsStart -= i;
        return UnitsStart;
      }
      return NULL;
    }
  } while ( !FreeList[i].next );
  void* RetVal=RemoveNode(i);
  SplitBlock(RetVal,i,indx);
  return RetVal;
}


inline void* SubAllocator::AllocUnits(int NU)
{
  int indx=Units2Indx[NU-1];
  if ( FreeList[indx].next )
    return RemoveNode(indx);
  void* RetVal=LoUnit;
  LoUnit += U2B(Indx2Units[indx]);
  if (LoUnit <= HiUnit)
    return RetVal;
  LoUnit -= U2B(Indx2Units[indx]);
  return AllocUnitsRare(indx);
}


void* SubAllocator::AllocContext()
{
  if (HiUnit != LoUnit)
    return (HiUnit -= UNIT_SIZE);
  if ( FreeList->next )
    return RemoveNode(0);
  return AllocUnitsRare(0);
}


void* SubAllocator::ExpandUnits(void* OldPtr,int OldNU)
{
  int i0=Units2Indx[OldNU-1], i1=Units2Indx[OldNU-1+1];
  if (i0 == i1)
    return OldPtr;
  void* ptr=AllocUnits(OldNU+1);
  if ( ptr ) 
  {
    memcpy(ptr,OldPtr,U2B(OldNU));
    InsertNode(OldPtr,i0);
  }
  return ptr;
}


void* SubAllocator::ShrinkUnits(void* OldPtr,int OldNU,int NewNU)
{
  int i0=Units2Indx[OldNU-1], i1=Units2Indx[NewNU-1];
  if (i0 == i1)
    return OldPtr;
  if ( FreeList[i1].next )
  {
    void* ptr=RemoveNode(i1);
    memcpy(ptr,OldPtr,U2B(NewNU));
    InsertNode(OldPtr,i0);
    return ptr;
  } 
  else 
  {
    SplitBlock(OldPtr,i0,i1);
    return OldPtr;
  }
}


void SubAllocator::FreeUnits(void* ptr,int OldNU)
{
  InsertNode(ptr,Units2Indx[OldNU-1]);
}

}  // namespace third_party_unrar
