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

📄 ziplibs.cpp

📁 zip算法的源码
💻 CPP
字号:
//---------------------------------------------------------------------------


#include <vcl.h>
#pragma hdrstop
#include <lzexpand.h>
#include "ZipLibs.h"

#include "ZipBuilder.h"
#include "ZipMsg.h"
#include "ZipBuildDefs.h"
//---------------------------------------------------------------------------

#pragma package(smart_init)
char*	RType = "BinFile";
const int zldTemp = 1;
const int	zldAuto = 2;
const int	zldFixed = 4;
const int DllRes[2]	= {RDLL_Unz, RDLL_Zip};
// new resource numbers  RDLL_ZVer= 11607, RDLL_UVer = 11608
const int VersRes[2] = {RDLL_UVer, RDLL_ZVer};
const char* DllNames[2] = {"UNZDLL.DLL","ZIPDLL.DLL"};
const char* ExecNames[2] = {"UnzDllExec","ZipDllExec"};
const char* VersNames[2] = {"GetUnzDllVersion","GetZipDllVersion"};
const char* PrivNames[2] = {"GetUnzDllPrivVersion", "GetZipDllPrivVersion"};


TZipLib::TZipLib(TObject *owner, bool type)
{
  Clear();
	fOwner = dynamic_cast<TZipBuilder*>(owner) ;
	IsZip = type ? 1 : 0;
	loadLevel = 0;
/*	fVer = 0;
	hndl = 0;
	fExecFunc = NULL;
	fVersFunc = NULL;
  fPrivFunc = NULL; */
	fPath = DllNames[IsZip];
  TmpFileName = "";
}

TZipLib::~TZipLib(void)
{
	if(hndl)  ::FreeLibrary(hndl);
	hndl = NULL;
  if((TmpFileName != "") && FileExists(TmpFileName)) DeleteFile(TmpFileName);
	loadLevel = 0;
}

void TZipLib::Clear(void)
{
  hndl = 0;
	fExecFunc = NULL;
	fVersFunc = NULL;
	fPrivFunc = NULL;
	fVer = 0;
	fPriv = 0;
}

// 1.73 27 July 2003 RA / RP unload wrong version
int TZipLib::LoadDll(int minver, bool level)
{
	DoLoad(level ? zldFixed : zldAuto);
	if(fVer < minver)
	{
		DoUnload(zldFixed | zldAuto | zldTemp);
		throw EZipBuilder(LD_BadDll,fPath);
	}
	return hndl ? fVer : 0;
}

// TZipLib::LoadLib
// 1.73 15 September 2003 RA added parameter MustExist
//1.73.2.4 10 September 2003 RP new function
int TZipLib::LoadLib(AnsiString Fullpath, bool MustExist)
{
  if(hndl) FreeLibrary(hndl);
  Clear();
  unsigned oldMode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
  try
  {
    hndl = ::LoadLibrary(Fullpath.c_str());
    if(hndl)
    {
      fExecFunc = (ZDllExecAddress)::GetProcAddress(hndl, ExecNames[IsZip]);
      fVersFunc = (ZDllVersionAddress)::GetProcAddress(hndl, VersNames[IsZip]);
      fPrivFunc = (ZDllPrivFuncAddress)::GetProcAddress(hndl, PrivNames[IsZip]);
      fPath = GetLoadedPath();
    }
  }
  __finally
  {
    SetErrorMode(oldMode);
  }
  if(!hndl)
  {
    Clear();
    loadLevel = 0;
    if(MustExist) throw EZipBuilder(LD_NoDll, Fullpath);
    return 0;
  }
  if(fExecFunc && fVersFunc)
  {
    fVer = fVersFunc();
    if(fPrivFunc) fPriv = fPrivFunc();
  }
  if((fVer < 153) || (fVer > 300))
  {
    Fullpath = fPath;
    FreeLibrary(hndl);
    Clear();
    loadLevel = 0;
    if(MustExist) throw EZipBuilder(LD_BadDll, Fullpath);
  }
  return fPriv;
}
// TZipLib::LoadLib

void TZipLib::Unload(bool level)
{
	DoUnload(level ? zldFixed : zldAuto);
}

int __fastcall TZipLib::GetLoaded(void)
{
  return hndl ? fVer : 0;
}

// TZipLib::Expand
//1.73.2.4 10 September 2003 RP new function
int TZipLib::Expand(AnsiString src, AnsiString dest)
{
  OFSTRUCT sTOF;
  OFSTRUCT dTOF;
  int sH = -1, dH = -1;
  int Result = 0;
  try
  {
    sH = LZOpenFile(src.c_str(), &sTOF, OF_READ);
    dH = LZOpenFile(dest.c_str(), &dTOF, OF_CREATE);
    if((sH > 0) && (dH >= 0)) Result = LZCopy(sH, dH);
  }
  __finally
  {
    if(sH >= 0) LZClose(sH);
    if(dH >= 0) LZClose(dH);
  }
  return Result;
}

// 1.80 7 September 2003 RA trace message adapted
int TZipLib::DoUnload(int level)
{
	loadLevel = (loadLevel & ~level) & 7;	// reset bit
	if (!loadLevel && hndl)
	{
		TZipBuilder *z = dynamic_cast<TZipBuilder *>(fOwner);
    if (z->Verbose)
      z->CallBack(zacMessage,0,z->LoadZipStr(LD_DllUnloaded,"unloaded ")+ Path,0);
		::FreeLibrary(hndl);
		hndl = NULL;
	}
	if (!hndl)
  {
    Clear();
    loadLevel = 0;
  }
  return fVer;
}
// 1.73 (2 August 2003 RA) added minver parameter, loading by call to LoadDll
int TZipLib::DoExec(void *info, int minver)
{
  LoadDll(minver, false);
	int r = fExecFunc(info);
	DoUnload(zldTemp);
	return r;
}

AnsiString __fastcall TZipLib::GetLoadedPath(void)
{
	String p = "";
	String buf;
	buf.SetLength(MAX_PATH);
	if(hndl && GetModuleFileName(hndl, buf.c_str(), MAX_PATH))
		p = buf.c_str();
	return p;
}
/* TZipLIb::DoLoad
1.73 15 September RA extra parameter in LoadLib
1.73.2.6 10 September 2003 RP only load resource if later or no other found
1.73 24 July 2003 RA fix
*/
int TZipLib::DoLoad(int level)
{
  loadLevel = (loadLevel | level) & 7;
  if(!hndl)
	{
		fVer = 0;
		loadLevel = level;
		String FullPath = "";
		TZipBuilder* zip= dynamic_cast<TZipBuilder*>(fOwner);
		String dir = zip->DLLDirectory;
    if(TmpFileName != "") FullPath = TmpFileName;
    if(FullPath == "")
    {
      if(dir != "")
      {
        FullPath = TZipBuilder::PathConcat(dir, DllNames[IsZip]);
        if(dir[1] == '.')
          FullPath = TZipBuilder::PathConcat(ExtractFilePath(ParamStr(0)),FullPath);
        if(!FileExists(FullPath)) FullPath = "";
      }
    }
    if(FullPath == "")
			    FullPath = DllNames[IsZip];  // let Windows search the std dirs
    AnsiString RVrs = LoadStr(VersRes[IsZip]);
    int RVer = StrToIntDef(RVrs.SubString(1,5),0);
    if(RVer > LoadLib(FullPath, RVer))
    {
      if(LoadLib(GetResDllPath(), true) < 17300)  // res dll older than 1.73
         LoadLib(FullPath, false); //could not load resource
    }
    if(zip->Verbose)
      zip->CallBack(zacMessage,0,zip->LoadZipStr(LD_DllLoaded,"loaded ") + fPath,0);
	}
	return fVer;
}
// TZipLib::DoLoad

/*? TZipLib::GetResDllPath
1.73.2.6 7 September 2006 extract 'compressed' resource files
*/
AnsiString __fastcall TZipLib::GetResDllPath(void)
{
  Word m;
	AnsiString Result = "";
	bool done = false;
  AnsiString tmp = LoadStr(VersRes[IsZip]);
  int ver = StrToIntDef(tmp.SubString(1,5),0);
  if( ver > 17300) // works from version 1.73.0.0 onwards
  {
    TZipBuilder *z = dynamic_cast<TZipBuilder *>(fOwner);
    if(IsZip)
      TmpFileName = z->MakeTempFileName("ZMZ",".dll");
    else
      TmpFileName = z->MakeTempFileName("ZMU",".dll");
    TResourceStream* rs = new TResourceStream((int)HInstance, DllRes[IsZip], RType);
    try
    {
      if(rs)
      {
        TFileStream* fs;
        try
        {
					rs->Read(&m, 2);
					if(m == 0)
					{
            fs = new TFileStream(TmpFileName, fmCreate);
						rs->Position = 6;
						done = (fs->CopyFrom(rs,rs->Size - 6) == (rs->Size - 6));
					}
					else if(m == 2)
          {
            tmp = z->MakeTempFileName("ZMt",".tmp");
            rs->Position = 6;
            fs = new TFileStream(tmp, fmCreate);
            done = (fs->CopyFrom(rs,rs->Size - 6) == (rs->Size - 6));
            delete fs;
            fs = NULL; // to avoid second delete in __finally
            if(done)
            {
              done = Expand(tmp, TmpFileName) > 100000; // expand returns size of expanded dll
              DeleteFile(tmp);
            }
          }
        }
				__finally
        {
					delete fs;
				}
      }
    }
    __finally
    {
      delete rs;
      if(!done && FileExists(TmpFileName))
         DeleteFile(TmpFileName);
      if(!FileExists(TmpFileName)) TmpFileName = "";
      else Result = TmpFileName;
    }
  }
  return Result;
}

/*? TZipLib::GetVer
1.73.2.8 2 Oct 2003 new getter
*/
int __fastcall TZipLib::GetVer(void)
{
	DoLoad(zldTemp);
	int Result = fVer;
	DoUnload(zldTemp);
  return Result;
}
//? TZipLib::GetVer

/*? TZipLib::GetPath
1.73.2.8 2 Oct 2003 new getter
*/
AnsiString __fastcall TZipLib::GetPath(void)
{
	DoLoad(zldTemp);
	AnsiString Result = fPath;
	DoUnload(zldTemp);
  return Result;
}
//? TZipLib::GetPath

/*? TZipLib::GetPriv
1.73.2.8 2 Oct 2003 new getter
*/
int __fastcall TZipLib::GetPriv(void)
{
	DoLoad(zldTemp);
	int Result = fPriv;
	DoUnload(zldTemp);
  return Result;
}
//? TZipLib::GetPriv

⌨️ 快捷键说明

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