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

📄 file.cpp

📁 source code for unrar3.3.4,uppack the .rar files,for multi-os
💻 CPP
字号:
#include "rar.hpp"static File *CreatedFiles[32];static int RemoveCreatedActive=0;File::File(){  hFile=BAD_HANDLE;  *FileName=0;  *FileNameW=0;  NewFile=false;  LastWrite=false;  HandleType=FILE_HANDLENORMAL;  SkipClose=false;  IgnoreReadErrors=false;  ErrorType=FILE_SUCCESS;  OpenShared=false;  AllowDelete=true;  CloseCount=0;  AllowExceptions=true;}File::~File(){  if (hFile!=BAD_HANDLE && !SkipClose)    if (NewFile)      Delete();    else      Close();}void File::operator = (File &SrcFile){  hFile=SrcFile.hFile;  strcpy(FileName,SrcFile.FileName);  NewFile=SrcFile.NewFile;  LastWrite=SrcFile.LastWrite;  HandleType=SrcFile.HandleType;  SrcFile.SkipClose=true;}bool File::Open(const char *Name,const wchar *NameW,bool OpenShared,bool Update){  ErrorType=FILE_SUCCESS;  FileHandle hNewFile;  if (File::OpenShared)    OpenShared=true;#ifdef _WIN_32  uint Access=GENERIC_READ;  if (Update)    Access|=GENERIC_WRITE;  uint ShareMode=FILE_SHARE_READ;  if (OpenShared)    ShareMode|=FILE_SHARE_WRITE;  if (WinNT() && NameW!=NULL && *NameW!=0)    hNewFile=CreateFileW(NameW,Access,ShareMode,NULL,OPEN_EXISTING,                         FILE_FLAG_SEQUENTIAL_SCAN,NULL);  else    hNewFile=CreateFile(Name,Access,ShareMode,NULL,OPEN_EXISTING,                        FILE_FLAG_SEQUENTIAL_SCAN,NULL);  if (hNewFile==BAD_HANDLE && GetLastError()==ERROR_FILE_NOT_FOUND)    ErrorType=FILE_NOTFOUND;#else  int flags=Update ? O_RDWR:O_RDONLY;#ifdef O_BINARY  flags|=O_BINARY;#if defined(_AIX) && defined(_LARGE_FILE_API)  flags|=O_LARGEFILE;#endif#endif#if defined(_EMX) && !defined(_DJGPP)  int sflags=OpenShared ? SH_DENYNO:SH_DENYWR;  int handle=sopen(Name,flags,sflags);#else  int handle=open(Name,flags);#ifdef LOCK_EX  if (!OpenShared && Update && handle>=0 && flock(handle,LOCK_EX|LOCK_NB)==-1)  {    close(handle);    return(false);  }#endif#endif  hNewFile=handle==-1 ? BAD_HANDLE:fdopen(handle,Update ? UPDATEBINARY:READBINARY);  if (hNewFile==BAD_HANDLE && errno==ENOENT)    ErrorType=FILE_NOTFOUND;#endif  NewFile=false;  HandleType=FILE_HANDLENORMAL;  SkipClose=false;  bool Success=hNewFile!=BAD_HANDLE;  if (Success)  {    hFile=hNewFile;    if (NameW!=NULL)      strcpyw(FileNameW,NameW);    else      *FileNameW=0;    if (Name!=NULL)      strcpy(FileName,Name);    else      WideToChar(NameW,FileName);    AddFileToList(hFile);  }  return(Success);}#if !defined(SHELL_EXT) && !defined(SFX_MODULE)void File::TOpen(const char *Name,const wchar *NameW){  if (!WOpen(Name,NameW))    ErrHandler.Exit(OPEN_ERROR);}#endifbool File::WOpen(const char *Name,const wchar *NameW){  if (Open(Name,NameW))    return(true);  ErrHandler.OpenErrorMsg(Name);  return(false);}bool File::Create(const char *Name,const wchar *NameW){#ifdef _WIN_32  if (WinNT() && NameW!=NULL && *NameW!=0)    hFile=CreateFileW(NameW,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,                      CREATE_ALWAYS,0,NULL);  else    hFile=CreateFile(Name,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,                     CREATE_ALWAYS,0,NULL);#else  hFile=fopen(Name,CREATEBINARY);#endif  NewFile=true;  HandleType=FILE_HANDLENORMAL;  SkipClose=false;  if (NameW!=NULL)    strcpyw(FileNameW,NameW);  else    *FileNameW=0;  if (Name!=NULL)    strcpy(FileName,Name);  else    WideToChar(NameW,FileName);  AddFileToList(hFile);  return(hFile!=BAD_HANDLE);}void File::AddFileToList(FileHandle hFile){  if (hFile!=BAD_HANDLE)    for (int I=0;I<sizeof(CreatedFiles)/sizeof(CreatedFiles[0]);I++)      if (CreatedFiles[I]==NULL)      {        CreatedFiles[I]=this;        break;      }}#if !defined(SHELL_EXT) && !defined(SFX_MODULE)void File::TCreate(const char *Name,const wchar *NameW){  if (!WCreate(Name,NameW))    ErrHandler.Exit(FATAL_ERROR);}#endifbool File::WCreate(const char *Name,const wchar *NameW){  if (Create(Name,NameW))    return(true);  ErrHandler.SetErrorCode(CREATE_ERROR);  ErrHandler.CreateErrorMsg(Name);  return(false);}bool File::Close(){  bool Success=true;  if (HandleType!=FILE_HANDLENORMAL)    HandleType=FILE_HANDLENORMAL;  else    if (hFile!=BAD_HANDLE)    {      if (!SkipClose)      {#ifdef _WIN_32        Success=CloseHandle(hFile);#else        Success=fclose(hFile)!=EOF;#endif        if (Success || !RemoveCreatedActive)          for (int I=0;I<sizeof(CreatedFiles)/sizeof(CreatedFiles[0]);I++)            if (CreatedFiles[I]==this)            {              CreatedFiles[I]=NULL;              break;            }      }      hFile=BAD_HANDLE;      if (!Success && AllowExceptions)        ErrHandler.CloseError(FileName);    }  CloseCount++;  return(Success);}void File::Flush(){#ifdef _WIN_32  FlushFileBuffers(hFile);#else  fflush(hFile);#endif}bool File::Delete(){  if (HandleType!=FILE_HANDLENORMAL || !AllowDelete)    return(false);  if (hFile!=BAD_HANDLE)    Close();  return(DelFile(FileName,FileNameW));}bool File::Rename(const char *NewName){  bool Success=strcmp(FileName,NewName)==0;  if (!Success)    Success=rename(FileName,NewName)==0;  if (Success)  {    strcpy(FileName,NewName);    *FileNameW=0;  }  return(Success);}void File::Write(const void *Data,int Size){  if (Size==0)    return;#ifndef _WIN_CE  if (HandleType!=FILE_HANDLENORMAL)    switch(HandleType)    {      case FILE_HANDLESTD:#ifdef _WIN_32        hFile=GetStdHandle(STD_OUTPUT_HANDLE);#else        hFile=stdout;#endif        break;      case FILE_HANDLEERR:#ifdef _WIN_32        hFile=GetStdHandle(STD_ERROR_HANDLE);#else        hFile=stderr;#endif        break;    }#endif  while (1)  {    bool Success;#ifdef _WIN_32    DWORD Written;    if (HandleType!=FILE_HANDLENORMAL)    {      const int MaxSize=0x4000;      for (int I=0;I<Size;I+=MaxSize)        if (!(Success=WriteFile(hFile,(byte *)Data+I,Min(Size-I,MaxSize),&Written,NULL)))          break;    }    else      Success=WriteFile(hFile,Data,Size,&Written,NULL);#else    Success=fwrite(Data,1,Size,hFile)==Size && !ferror(hFile);#endif    if (!Success && AllowExceptions && HandleType==FILE_HANDLENORMAL)    {#if defined(_WIN_32) && !defined(SFX_MODULE) && !defined(RARDLL)      int ErrCode=GetLastError();      Int64 FilePos=Tell();      Int64 FreeSize=GetFreeDisk(FileName);      SetLastError(ErrCode);      if (FreeSize>Size && FilePos-Size<=0xffffffff && FilePos+Size>0xffffffff)        ErrHandler.WriteErrorFAT(FileName);#endif      if (ErrHandler.AskRepeatWrite(FileName))        continue;      ErrHandler.WriteError(NULL,FileName);    }    break;  }  LastWrite=true;}int File::Read(void *Data,int Size){  Int64 FilePos;  if (IgnoreReadErrors)    FilePos=Tell();  int ReadSize;  while (true)  {    ReadSize=DirectRead(Data,Size);    if (ReadSize==-1)    {      ErrorType=FILE_READERROR;      if (AllowExceptions)        if (IgnoreReadErrors)        {          ReadSize=0;          for (int I=0;I<Size;I+=512)          {            Seek(FilePos+I,SEEK_SET);            int SizeToRead=Min(Size-I,512);            int ReadCode=DirectRead(Data,SizeToRead);            ReadSize+=(ReadCode==-1) ? 512:ReadCode;          }        }        else        {          if (HandleType==FILE_HANDLENORMAL && ErrHandler.AskRepeatRead(FileName))            continue;          ErrHandler.ReadError(FileName);        }    }    break;  }  return(ReadSize);}int File::DirectRead(void *Data,int Size){#ifdef _WIN_32  const int MaxDeviceRead=20000;#endif#ifndef _WIN_CE  if (HandleType==FILE_HANDLESTD)  {#ifdef _WIN_32    if (Size>MaxDeviceRead)      Size=MaxDeviceRead;    hFile=GetStdHandle(STD_INPUT_HANDLE);#else    hFile=stdin;#endif  }#endif#ifdef _WIN_32  DWORD Read;  if (!ReadFile(hFile,Data,Size,&Read,NULL))  {    if (IsDevice() && Size>MaxDeviceRead)      return(DirectRead(Data,MaxDeviceRead));    if (HandleType==FILE_HANDLESTD && GetLastError()==ERROR_BROKEN_PIPE)      return(0);    return(-1);  }  return(Read);#else  if (LastWrite)  {    fflush(hFile);    LastWrite=false;  }  clearerr(hFile);  int ReadSize=fread(Data,1,Size,hFile);  if (ferror(hFile))    return(-1);  return(ReadSize);#endif}void File::Seek(Int64 Offset,int Method){  if (!RawSeek(Offset,Method) && AllowExceptions)    ErrHandler.SeekError(FileName);}bool File::RawSeek(Int64 Offset,int Method){  if (hFile==BAD_HANDLE)    return(true);  if (!is64plus(Offset) && Method!=SEEK_SET)  {    Offset=(Method==SEEK_CUR ? Tell():FileLength())+Offset;    Method=SEEK_SET;  }#ifdef _WIN_32  LONG HighDist=int64to32(Offset>>32);  if (SetFilePointer(hFile,int64to32(Offset),&HighDist,Method)==0xffffffff &&      GetLastError()!=NO_ERROR)    return(false);#else  LastWrite=false;#ifdef _LARGEFILE_SOURCE  if (fseeko(hFile,Offset,Method)!=0)#else  if (fseek(hFile,int64to32(Offset),Method)!=0)#endif    return(false);#endif  return(true);}Int64 File::Tell(){#ifdef _WIN_32  LONG HighDist=0;  uint LowDist=SetFilePointer(hFile,0,&HighDist,FILE_CURRENT);  if (LowDist==0xffffffff && GetLastError()!=NO_ERROR)    if (AllowExceptions)      ErrHandler.SeekError(FileName);    else      return(-1);  return(int32to64(HighDist,LowDist));#else#ifdef _LARGEFILE_SOURCE  return(ftello(hFile));#else  return(ftell(hFile));#endif#endif}void File::Prealloc(Int64 Size){#ifdef _WIN_32  if (RawSeek(Size,SEEK_SET))  {    Truncate();    Seek(0,SEEK_SET);  }#endif}byte File::GetByte(){  byte Byte=0;  Read(&Byte,1);  return(Byte);}void File::PutByte(byte Byte){  Write(&Byte,1);}bool File::Truncate(){#ifdef _WIN_32  return(SetEndOfFile(hFile));#else  return(false);#endif}void File::SetOpenFileTime(RarTime *ftm,RarTime *ftc,RarTime *fta){#ifdef _WIN_32  bool sm=ftm!=NULL && ftm->IsSet();  bool sc=ftc!=NULL && ftc->IsSet();  bool sa=fta!=NULL && fta->IsSet();  FILETIME fm,fc,fa;  if (sm)    ftm->GetWin32(&fm);  if (sc)    ftc->GetWin32(&fc);  if (sa)    fta->GetWin32(&fa);  SetFileTime(hFile,sc ? &fc:NULL,sa ? &fa:NULL,sm ? &fm:NULL);#endif}void File::SetCloseFileTime(RarTime *ftm,RarTime *fta){#if defined(_UNIX) || defined(_EMX)  SetCloseFileTimeByName(FileName,ftm,fta);#endif}void File::SetCloseFileTimeByName(const char *Name,RarTime *ftm,RarTime *fta){#if defined(_UNIX) || defined(_EMX)  bool setm=ftm!=NULL && ftm->IsSet();  bool seta=fta!=NULL && fta->IsSet();  if (setm || seta)  {    struct utimbuf ut;    if (setm)      ut.modtime=ftm->GetUnix();    else      ut.modtime=fta->GetUnix();    if (seta)      ut.actime=fta->GetUnix();    else      ut.actime=ut.modtime;    utime(Name,&ut);  }#endif}void File::GetOpenFileTime(RarTime *ft){#ifdef _WIN_32  FILETIME FileTime;  GetFileTime(hFile,NULL,NULL,&FileTime);  *ft=FileTime;#endif#if defined(_UNIX) || defined(_EMX)  struct stat st;  fstat(fileno(hFile),&st);  *ft=st.st_mtime;#endif}void File::SetOpenFileStat(RarTime *ftm,RarTime *ftc,RarTime *fta){#ifdef _WIN_32  SetOpenFileTime(ftm,ftc,fta);#endif}void File::SetCloseFileStat(RarTime *ftm,RarTime *fta,uint FileAttr){#ifdef _WIN_32  SetFileAttr(FileName,FileNameW,FileAttr);#endif#ifdef _EMX  SetCloseFileTime(ftm,fta);  SetFileAttr(FileName,FileNameW,FileAttr);#endif#ifdef _UNIX  SetCloseFileTime(ftm,fta);  chmod(FileName,(mode_t)FileAttr);#endif}Int64 File::FileLength(){  SaveFilePos SavePos(*this);  Seek(0,SEEK_END);  return(Tell());}void File::SetHandleType(FILE_HANDLETYPE Type){  HandleType=Type;}bool File::IsDevice(){  if (hFile==BAD_HANDLE)    return(false);#ifdef _WIN_32  uint Type=GetFileType(hFile);  return(Type==FILE_TYPE_CHAR || Type==FILE_TYPE_PIPE);#else  return(isatty(fileno(hFile)));#endif}#ifndef SFX_MODULEvoid File::fprintf(const char *fmt,...){  va_list argptr;  va_start(argptr,fmt);  safebuf char Msg[2*NM+1024],OutMsg[2*NM+1024];  vsprintf(Msg,fmt,argptr);#ifdef _WIN_32  for (int Src=0,Dest=0;;Src++)  {    char CurChar=Msg[Src];    if (CurChar=='\n')      OutMsg[Dest++]='\r';    OutMsg[Dest++]=CurChar;    if (CurChar==0)      break;  }#else  strcpy(OutMsg,Msg);#endif  Write(OutMsg,strlen(OutMsg));  va_end(argptr);}#endifbool File::RemoveCreated(){  RemoveCreatedActive++;  bool RetCode=true;  for (int I=0;I<sizeof(CreatedFiles)/sizeof(CreatedFiles[0]);I++)    if (CreatedFiles[I]!=NULL)    {      CreatedFiles[I]->SetExceptions(false);      bool Success;      if (CreatedFiles[I]->NewFile)        Success=CreatedFiles[I]->Delete();      else        Success=CreatedFiles[I]->Close();      if (Success)        CreatedFiles[I]=NULL;      else        RetCode=false;    }  RemoveCreatedActive--;  return(RetCode);}#ifndef SFX_MODULElong File::Copy(File &Dest,Int64 Length){  Array<char> Buffer(0x10000);  long CopySize=0;  bool CopyAll=(Length==INT64ERR);  while (CopyAll || Length>0)  {    Wait();    int SizeToRead=(!CopyAll && Length<Buffer.Size()) ? int64to32(Length):Buffer.Size();    int ReadSize=Read(&Buffer[0],SizeToRead);    if (ReadSize==0)      break;    Dest.Write(&Buffer[0],ReadSize);    CopySize+=ReadSize;    if (!CopyAll)      Length-=ReadSize;  }  return(CopySize);}#endif

⌨️ 快捷键说明

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