// Archive/CabIn.cpp

#include "StdAfx.h"

#include "../Common/FindSignature.h"

#include "CabIn.h"

namespace NArchive {
namespace NCab {

Byte CInArchive::Read8()
{
  Byte b;
  if (!inBuffer.ReadByte(b))
    throw CInArchiveException(CInArchiveException::kUnsupported);
  return b;
}

UInt16 CInArchive::Read16()
{
  UInt16 value = 0;
  for (int i = 0; i < 2; i++)
  {
    Byte b = Read8();
    value |= (UInt16(b) << (8 * i));
  }
  return value;
}

UInt32 CInArchive::Read32()
{
  UInt32 value = 0;
  for (int i = 0; i < 4; i++)
  {
    Byte b = Read8();
    value |= (UInt32(b) << (8 * i));
  }
  return value;
}

AString CInArchive::SafeReadName()
{
  AString name;
  for (;;)
  {
    Byte b = Read8();
    if (b == 0)
      return name;
    name += (char)b;
  }
}

void CInArchive::ReadOtherArchive(COtherArchive &oa)
{
  oa.FileName = SafeReadName();
  oa.DiskName = SafeReadName();
}

void CInArchive::Skip(UInt32 size)
{
  while (size-- != 0)
    Read8();
}

HRESULT CInArchive::Open(const UInt64 *searchHeaderSizeLimit, CDatabaseEx &db)
{
  IInStream *stream = db.Stream;
  db.Clear();
  RINOK(stream->Seek(0, STREAM_SEEK_SET, &db.StartPosition));

  RINOK(FindSignatureInStream(stream, NHeader::kMarker, NHeader::kMarkerSize,
      searchHeaderSizeLimit, db.StartPosition));

  RINOK(stream->Seek(db.StartPosition + NHeader::kMarkerSize, STREAM_SEEK_SET, NULL));
  if (!inBuffer.Create(1 << 17))
    return E_OUTOFMEMORY;
  inBuffer.SetStream(stream);
  inBuffer.Init();

  CInArchiveInfo &ai = db.ArchiveInfo;

  ai.Size = Read32();
  if (Read32() != 0)
    return S_FALSE;
  ai.FileHeadersOffset = Read32();
  if (Read32() != 0)
    return S_FALSE;

  ai.VersionMinor = Read8();
  ai.VersionMajor = Read8();
  ai.NumFolders = Read16();
  ai.NumFiles = Read16();
  ai.Flags = Read16();
  if (ai.Flags > 7)
    return S_FALSE;
  ai.SetID = Read16();
  ai.CabinetNumber = Read16();

  if (ai.ReserveBlockPresent())
  {
    ai.PerCabinetAreaSize = Read16();
    ai.PerFolderAreaSize = Read8();
    ai.PerDataBlockAreaSize = Read8();

    Skip(ai.PerCabinetAreaSize);
  }

  {
    if (ai.IsTherePrev())
      ReadOtherArchive(ai.PrevArc);
    if (ai.IsThereNext())
      ReadOtherArchive(ai.NextArc);
  }
  
  int i;
  for (i = 0; i < ai.NumFolders; i++)
  {
    CFolder folder;

    folder.DataStart = Read32();
    folder.NumDataBlocks = Read16();
    folder.CompressionTypeMajor = Read8();
    folder.CompressionTypeMinor = Read8();

    Skip(ai.PerFolderAreaSize);
    db.Folders.Add(folder);
  }
  
  RINOK(stream->Seek(db.StartPosition + ai.FileHeadersOffset, STREAM_SEEK_SET, NULL));

  inBuffer.SetStream(stream);
  inBuffer.Init();
  for (i = 0; i < ai.NumFiles; i++)
  {
    CItem item;
    item.Size = Read32();
    item.Offset = Read32();
    item.FolderIndex = Read16();
    UInt16 pureDate = Read16();
    UInt16 pureTime = Read16();
    item.Time = ((UInt32(pureDate) << 16)) | pureTime;
    item.Attributes = Read16();
    item.Name = SafeReadName();
    int folderIndex = item.GetFolderIndex(db.Folders.Size());
    if (folderIndex >= db.Folders.Size())
      return S_FALSE;
    db.Items.Add(item);
  }
  return S_OK;
}

#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }

static int CompareMvItems(const CMvItem *p1, const CMvItem *p2, void *param)
{
  const CMvDatabaseEx &mvDb = *(const CMvDatabaseEx *)param;
  const CDatabaseEx &db1 = mvDb.Volumes[p1->VolumeIndex];
  const CDatabaseEx &db2 = mvDb.Volumes[p2->VolumeIndex];
  const CItem &item1 = db1.Items[p1->ItemIndex];
  const CItem &item2 = db2.Items[p2->ItemIndex];;
  bool isDir1 = item1.IsDir();
  bool isDir2 = item2.IsDir();
  if (isDir1 && !isDir2)
    return -1;
  if (isDir2 && !isDir1)
    return 1;
  int f1 = mvDb.GetFolderIndex(p1);
  int f2 = mvDb.GetFolderIndex(p2);
  RINOZ(MyCompare(f1, f2));
  RINOZ(MyCompare(item1.Offset, item2.Offset));
  RINOZ(MyCompare(item1.Size, item2.Size));
  RINOZ(MyCompare(p1->VolumeIndex, p2->VolumeIndex));
  return MyCompare(p1->ItemIndex, p2->ItemIndex);
}

bool CMvDatabaseEx::AreItemsEqual(int i1, int i2)
{
  const CMvItem *p1 = &Items[i1];
  const CMvItem *p2 = &Items[i2];
  const CDatabaseEx &db1 = Volumes[p1->VolumeIndex];
  const CDatabaseEx &db2 = Volumes[p2->VolumeIndex];
  const CItem &item1 = db1.Items[p1->ItemIndex];
  const CItem &item2 = db2.Items[p2->ItemIndex];;
  return GetFolderIndex(p1) == GetFolderIndex(p2) &&
    item1.Offset == item2.Offset &&
    item1.Size == item2.Size &&
    item1.Name == item2.Name;
}

void CMvDatabaseEx::FillSortAndShrink()
{
  Items.Clear();
  StartFolderOfVol.Clear();
  FolderStartFileIndex.Clear();
  int offset = 0;
  for (int v = 0; v < Volumes.Size(); v++)
  {
    const CDatabaseEx &db = Volumes[v];
    int curOffset = offset;
    if (db.IsTherePrevFolder())
      curOffset--;
    StartFolderOfVol.Add(curOffset);
    offset += db.GetNumberOfNewFolders();

    CMvItem mvItem;
    mvItem.VolumeIndex = v;
    for (int i = 0 ; i < db.Items.Size(); i++)
    {
      mvItem.ItemIndex = i;
      Items.Add(mvItem);
    }
  }

  Items.Sort(CompareMvItems, (void *)this);
  int j = 1;
  int i;
  for (i = 1; i < Items.Size(); i++)
    if (!AreItemsEqual(i, i -1))
      Items[j++] = Items[i];
  Items.DeleteFrom(j);

  for (i = 0; i < Items.Size(); i++)
  {
    int folderIndex = GetFolderIndex(&Items[i]);
    if (folderIndex >= FolderStartFileIndex.Size())
      FolderStartFileIndex.Add(i);
  }
}

bool CMvDatabaseEx::Check()
{
  for (int v = 1; v < Volumes.Size(); v++)
  {
    const CDatabaseEx &db1 = Volumes[v];
    if (db1.IsTherePrevFolder())
    {
      const CDatabaseEx &db0 = Volumes[v - 1];
      if (db0.Folders.IsEmpty() || db1.Folders.IsEmpty())
        return false;
      const CFolder &f0 = db0.Folders.Back();
      const CFolder &f1 = db1.Folders.Front();
      if (f0.CompressionTypeMajor != f1.CompressionTypeMajor ||
          f0.CompressionTypeMinor != f1.CompressionTypeMinor)
        return false;
    }
  }
  UInt32 beginPos = 0;
  UInt64 endPos = 0;
  int prevFolder = -2;
  for (int i = 0; i < Items.Size(); i++)
  {
    const CMvItem &mvItem = Items[i];
    int fIndex = GetFolderIndex(&mvItem);
    if (fIndex >= FolderStartFileIndex.Size())
      return false;
    const CItem &item = Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
    if (item.IsDir())
      continue;
    int folderIndex = GetFolderIndex(&mvItem);
    if (folderIndex != prevFolder)
      prevFolder = folderIndex;
    else if (item.Offset < endPos &&
        (item.Offset != beginPos || item.GetEndOffset() != endPos))
      return false;
    beginPos = item.Offset;
    endPos = item.GetEndOffset();
  }
  return true;
}

}}
