⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unpack.cpp

📁 7Zip软件实现: 七种编码格式的压缩与解压缩功能。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "rar.hpp"#include "coder.cpp"#include "suballoc.cpp"#include "model.cpp"#ifndef SFX_MODULE#include "unpack15.cpp"// Igor Pavlov
// #include "unpack20.cpp"#endifUnpack::Unpack(ComprDataIO *DataIO){  UnpIO=DataIO;  Window=NULL;  ExternalWindow=false;  Suspended=false;  UnpAllBuf=false;  UnpSomeRead=false;}Unpack::~Unpack(){  if (Window!=NULL && !ExternalWindow)    delete[] Window;  InitFilters();}void Unpack::Init(byte *Window){  if (Window==NULL)  {    Unpack::Window=new byte[MAXWINSIZE];#ifndef ALLOW_EXCEPTIONS    if (Unpack::Window==NULL)      ErrHandler.MemoryError();#endif  }  else  {    Unpack::Window=Window;    ExternalWindow=true;  }  UnpInitData(false);}void Unpack::DoUnpack(int Method,bool Solid){  switch(Method)  {#ifndef SFX_MODULE    case 15:      Unpack15(Solid);      break;    // Igor Pavlov
    /*
    case 20:    case 26:      Unpack20(Solid);      break;    */
#endif    case 29:      Unpack29(Solid);      break;  }}inline void Unpack::InsertOldDist(unsigned int Distance){  OldDist[3]=OldDist[2];  OldDist[2]=OldDist[1];  OldDist[1]=OldDist[0];  OldDist[0]=Distance;}inline void Unpack::InsertLastMatch(unsigned int Length,unsigned int Distance){  LastDist=Distance;  LastLength=Length;}void Unpack::CopyString(unsigned int Length,unsigned int Distance){  unsigned int DestPtr=UnpPtr-Distance;  if (DestPtr<MAXWINSIZE-260 && UnpPtr<MAXWINSIZE-260)  {    Window[UnpPtr++]=Window[DestPtr++];    while (--Length>0)      Window[UnpPtr++]=Window[DestPtr++];  }  else    while (Length--)    {      Window[UnpPtr]=Window[DestPtr++ & MAXWINMASK];      UnpPtr=(UnpPtr+1) & MAXWINMASK;    }}int Unpack::DecodeNumber(struct Decode *Dec){  unsigned int Bits;  unsigned int BitField=getbits() & 0xfffe;  if (BitField<Dec->DecodeLen[8])    if (BitField<Dec->DecodeLen[4])      if (BitField<Dec->DecodeLen[2])        if (BitField<Dec->DecodeLen[1])          Bits=1;        else          Bits=2;      else        if (BitField<Dec->DecodeLen[3])          Bits=3;        else          Bits=4;    else      if (BitField<Dec->DecodeLen[6])        if (BitField<Dec->DecodeLen[5])          Bits=5;        else          Bits=6;      else        if (BitField<Dec->DecodeLen[7])          Bits=7;        else          Bits=8;  else    if (BitField<Dec->DecodeLen[12])      if (BitField<Dec->DecodeLen[10])        if (BitField<Dec->DecodeLen[9])          Bits=9;        else          Bits=10;      else        if (BitField<Dec->DecodeLen[11])          Bits=11;        else          Bits=12;    else      if (BitField<Dec->DecodeLen[14])        if (BitField<Dec->DecodeLen[13])          Bits=13;        else          Bits=14;      else        Bits=15;  addbits(Bits);  unsigned int N=Dec->DecodePos[Bits]+((BitField-Dec->DecodeLen[Bits-1])>>(16-Bits));  if (N>=Dec->MaxNum)    N=0;  return(Dec->DecodeNum[N]);}void Unpack::Unpack29(bool Solid){  static unsigned char LDecode[]={0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224};  static unsigned char LBits[]=  {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,  4,  5,  5,  5,  5};  static int DDecode[DC];  static byte DBits[DC];  static int DBitLengthCounts[]= {4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,14,0,12};  static unsigned char SDDecode[]={0,4,8,16,32,64,128,192};  static unsigned char SDBits[]=  {2,2,3, 4, 5, 6,  6,  6};  unsigned int Bits;  if (DDecode[1]==0)  {    int Dist=0,BitLength=0,Slot=0;    for (int I=0;I<sizeof(DBitLengthCounts)/sizeof(DBitLengthCounts[0]);I++,BitLength++)      for (int J=0;J<DBitLengthCounts[I];J++,Slot++,Dist+=(1<<BitLength))      {        DDecode[Slot]=Dist;        DBits[Slot]=BitLength;      }  }  FileExtracted=true;  if (!Suspended)  {    UnpInitData(Solid);    if (!UnpReadBuf())      return;    if ((!Solid || !TablesRead) && !ReadTables())      return;  }  if (PPMError)    return;  while (true)  {    UnpPtr&=MAXWINMASK;    if (InAddr>ReadBorder)    {      if (!UnpReadBuf())        break;    }    if (((WrPtr-UnpPtr) & MAXWINMASK)<260 && WrPtr!=UnpPtr)    {      UnpWriteBuf();      if (WrittenFileSize>DestUnpSize)        return;      if (Suspended)      {        FileExtracted=false;        return;      }    }    if (UnpBlockType==BLOCK_PPM)    {      int Ch=PPM.DecodeChar();      if (Ch==-1)      {        PPMError=true;        break;      }      if (Ch==PPMEscChar)      {        int NextCh=PPM.DecodeChar();        if (NextCh==0)        {          if (!ReadTables())            break;          continue;        }        if (NextCh==2 || NextCh==-1)          break;        if (NextCh==3)        {          if (!ReadVMCodePPM())            break;          continue;        }        if (NextCh==4)        {          unsigned int Distance=0,Length;          bool Failed=false;          for (int I=0;I<4 && !Failed;I++)          {            int Ch=PPM.DecodeChar();            if (Ch==-1)              Failed=true;            else              if (I==3)                Length=(byte)Ch;              else                Distance=(Distance<<8)+(byte)Ch;          }          if (Failed)            break;          CopyString(Length+32,Distance+2);          continue;        }        if (NextCh==5)        {          int Length=PPM.DecodeChar();          if (Length==-1)            break;          CopyString(Length+4,1);          continue;        }      }      Window[UnpPtr++]=Ch;      continue;    }    int Number=DecodeNumber((struct Decode *)&LD);    if (Number<256)    {      Window[UnpPtr++]=(byte)Number;      continue;    }    if (Number>=271)    {      int Length=LDecode[Number-=271]+3;      if ((Bits=LBits[Number])>0)      {        Length+=getbits()>>(16-Bits);        addbits(Bits);      }      int DistNumber=DecodeNumber((struct Decode *)&DD);      unsigned int Distance=DDecode[DistNumber]+1;      if ((Bits=DBits[DistNumber])>0)      {        if (DistNumber>9)        {          if (Bits>4)          {            Distance+=((getbits()>>(20-Bits))<<4);            addbits(Bits-4);          }          if (LowDistRepCount>0)          {            LowDistRepCount--;            Distance+=PrevLowDist;          }          else          {            int LowDist=DecodeNumber((struct Decode *)&LDD);            if (LowDist==16)            {              LowDistRepCount=LOW_DIST_REP_COUNT-1;              Distance+=PrevLowDist;            }            else            {              Distance+=LowDist;              PrevLowDist=LowDist;            }          }        }        else        {          Distance+=getbits()>>(16-Bits);          addbits(Bits);        }      }      if (Distance>=0x2000)      {        Length++;        if (Distance>=0x40000L)          Length++;      }      InsertOldDist(Distance);      InsertLastMatch(Length,Distance);      CopyString(Length,Distance);      continue;    }    if (Number==256)    {      if (!ReadEndOfBlock())        break;      continue;    }    if (Number==257)    {      if (!ReadVMCode())        break;      continue;    }    if (Number==258)    {      if (LastLength!=0)        CopyString(LastLength,LastDist);      continue;    }    if (Number<263)    {      int DistNum=Number-259;      unsigned int Distance=OldDist[DistNum];      for (int I=DistNum;I>0;I--)        OldDist[I]=OldDist[I-1];      OldDist[0]=Distance;      int LengthNumber=DecodeNumber((struct Decode *)&RD);      int Length=LDecode[LengthNumber]+2;      if ((Bits=LBits[LengthNumber])>0)      {        Length+=getbits()>>(16-Bits);        addbits(Bits);      }      InsertLastMatch(Length,Distance);      CopyString(Length,Distance);      continue;    }    if (Number<272)    {      unsigned int Distance=SDDecode[Number-=263]+1;      if ((Bits=SDBits[Number])>0)      {        Distance+=getbits()>>(16-Bits);        addbits(Bits);      }      InsertOldDist(Distance);      InsertLastMatch(2,Distance);      CopyString(2,Distance);      continue;    }  }  UnpWriteBuf();}bool Unpack::ReadEndOfBlock(){  unsigned int BitField=getbits();  bool NewTable,NewFile=false;  if (BitField & 0x8000)  {    NewTable=true;    addbits(1);  }  else  {    NewFile=true;
  
    // Igor Pavlov
    NewTable = ((BitField & 0x4000) != 0);    
    addbits(2);  }  TablesRead=!NewTable;  return !(NewFile || NewTable && !ReadTables());}bool Unpack::ReadVMCode(){  unsigned int FirstByte=getbits()>>8;  addbits(8);  int Length=(FirstByte & 7)+1;  if (Length==7)  {    Length=(getbits()>>8)+7;    addbits(8);  }  else    if (Length==8)    {      Length=getbits();      addbits(16);    }  Array<byte> VMCode(Length);  for (int I=0;I<Length;I++)  {    if (InAddr>=ReadTop-1 && !UnpReadBuf() && I<Length-1)      return(false);    VMCode[I]=getbits()>>8;    addbits(8);  }  return(AddVMCode(FirstByte,&VMCode[0],Length));}bool Unpack::ReadVMCodePPM(){  unsigned int FirstByte=PPM.DecodeChar();  if ((int)FirstByte==-1)    return(false);  int Length=(FirstByte & 7)+1;  if (Length==7)  {    int B1=PPM.DecodeChar();    if (B1==-1)      return(false);    Length=B1+7;  }  else    if (Length==8)    {      int B1=PPM.DecodeChar();      if (B1==-1)        return(false);      int B2=PPM.DecodeChar();      if (B2==-1)        return(false);      Length=B1*256+B2;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -