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

📄 gphugef.pas

📁 Advanced Data Import Component Suite for Borland Delphi and C++ Builder allows you to import your da
💻 PAS
📖 第 1 页 / 共 5 页
字号:
      Dec(count,send);
      bufp := OffsetPtr(bufp,send);
    end;                           
  end
  else
    bufp := @buf;
  if count > 0 then begin // store leftovers
    Move(bufp^,OffsetPtr(hfBuffer,hfBufOffs)^,count);
    Inc(hfBufOffs,count);
    Inc(transferred,count);
    hfBufFilePos := hfBufFileOffs+hfBufOffs;
  end;
end; { TGpHugeFile.Transmit }

{:Reads 'count' number of bytes large units from a file (or buffer if access is
  buffered).
  @param   buf         Buffer for read data.
  @param   count       Number of bytes to be read..
  @param   transferred (out) Number of bytes actually read..
  @raises  EGpHugeFile when trying to read while in buffered write mode.
  @raises  Various system exceptions.
  @seeAlso Reset, Rewrite
}
procedure TGpHugeFile.Fetch(var buf; count: DWORD; var transferred: DWORD);
var
  got  : DWORD;
  bufp : pointer;
  read : DWORD;
  trans: DWORD;
begin
  if hfBufWrite then
    raise EGpHugeFile.CreateFmtHelp(sReadWhileInBufferedWriteMode,[FileName],hcHFReadInBufferedWriteMode);
  transferred := 0;
  got := hfBufSize-hfBufOffs;
  if got <= count then begin
    if got > 0 then begin // read from buffer
      Move(OffsetPtr(hfBuffer,hfBufOffs)^,buf,got);
      transferred := got;
      Dec(count,got);
      hfBufFilePos := hfBufFileOffs-hfBufSize+hfBufOffs+got;
    end;
    bufp := OffsetPtr(@buf,got);
    hfBufOffs := 0;
    if count >= hfBufferSize then begin // read directly
      read := (count div hfBufferSize)*hfBufferSize;
      if hfHalfClosed then
        trans := 0 //2.26
      else if not ReadFile(hfHandle,bufp^,read,trans,nil) then
        Exit;
      hfBufFileOffs := hfBufFileOffs+trans;
      hfBufFilePos := hfBufFileOffs;
      Inc(transferred,trans);
      Dec(count,read);
      bufp := OffsetPtr(bufp,read);
      if trans < read then
        Exit; // Eof
    end;
    // fill the buffer
    if not hfHalfClosed then begin 
      if LoadedToTheEOF then
        hfBufSize := 0
      else begin
        SetLastError(0);
        Win32Check(ReadFile(hfHandle,hfBuffer^,hfBufferSize,hfBufSize,nil),'Fetch');
        hfBufFileOffs := hfBufFileOffs+hfBufSize;
      end;
    end
    else begin
      //3.03: when reacing end of buffer in hfHalfClosed mode, buffer must not
      //      be invalidated
      hfBufOffs := hfBufSize;
      Exit;
    end;
  end
  else
    bufp := @buf;
  if count > 0 then begin // read from buffer
    got := hfBufSize-hfBufOffs;
    if got < count then
      count := got;
    if count > 0 then
      Move(OffsetPtr(hfBuffer,hfBufOffs)^,bufp^,count);
    Inc(hfBufOffs,count);
    Inc(transferred,count);
    hfBufFilePos := hfBufFileOffs-hfBufSize+hfBufOffs;
  end;
end; { TGpHugeFile.Fetch }

{:Flushed file buffers (internal implementation).
  @returns False if data could not be written.
}
function TGpHugeFile.FlushBuffer: boolean;
var
  written: DWORD;
begin
  if (hfBufOffs > 0) and hfBufWrite then begin
    if hfFlagNoBuf then
      hfBufOffs := RoundToPageSize(hfBufOffs);
    Result := WriteFile(hfHandle,hfBuffer^,hfBufOffs,written,nil);
    hfBufFileOffs := hfBufFileOffs+written;
    hfBufOffs     := 0;
    hfBufFilePos  := hfBufFileOffs;
    if hfFlagNoBuf then
      FillChar(hfBuffer^,hfBufferSize,0);
  end
  else
    Result := true;
end; { TGpHugeFile.FlushBuffer }

{:Reads 'count' number of 'block size' large units (see 'blockSize' parameter
  to Reset and Rewrite methods) from a file (or buffer if access is buffered).
  @param   buf         Buffer for read data.
  @param   count       Number of 'block size' large units to be read.
  @raises  EGpHugeFile on Windows errors or if not enough data could be read
           from file.
  @seeAlso Reset, Rewrite
}
procedure TGpHugeFile.BlockReadUnsafe(var buf; count: DWORD);
var
  transferred: DWORD;
begin
  BlockRead(buf,count,transferred);
  if count <> transferred then begin
    if hfBuffered then
      raise EGpHugeFile.CreateHelp(sEndOfFile,hcHFUnexpectedEOF)
    else
      Win32Check(false,'BlockReadUnsafe');
  end;
end; { TGpHugeFile.BlockReadUnsafe }

{:Writes 'count' number of 'block size' large units (see 'blockSize' parameter
  to Reset and Rewrite methods) to a file (or buffer if access is buffered).
  @param   buf         Data to be written.
  @param   count       Number of 'block size' large units to be written.
  @raises  EGpHugeFile on Windows errors or if data could not be written
                       completely.
  @seeAlso Reset, Rewrite
}
procedure TGpHugeFile.BlockWriteUnsafe(const buf; count: DWORD);
var
  transferred: DWORD;
begin
  BlockWrite(buf,count,transferred);
  if count <> transferred then begin
    if hfBuffered then
      raise EGpHugeFile.CreateFmtHelp(sWriteFailed,[FileName],hcHFWriteFailed)
    else
      Win32Check(false,'BlockWriteUnsafe');
  end;
end; { BlockWriteUnsafe }

function TGpHugeFile.Compress: boolean;
begin
  Result := true;
  if (IsUnicodeMode and DSiIsFileCompressedW(hfName)) or
     ((not IsUnicodeMode) and DSiIsFileCompressed(hfNameA))
  then
    Result := DSiCompressFile(hfHandle);
end; { Compress }

{:Returns true if file is open.
  @returns True if file is open.
}
function TGpHugeFile.IsOpen: boolean;
begin
  Result := hfIsOpen;
end; { TGpHugeFile.IsOpen }

{:Checks condition and creates appropriately formatted EGpHugeFile exception.
  @param   condition If false, Win32Check will generate an exception.
  @param   method    Name of TGpHugeFile method that called Win32Check.
  @raises  EGpHugeFile if (not condition).
}
procedure TGpHugeFile.Win32Check(condition: boolean; method: string);
var
  Error: EGpHugeFile;
begin
  if not condition then begin
    hfWindowsError := GetLastError;
    if hfWindowsError <> ERROR_SUCCESS then
      Error := EGpHugeFile.CreateFmtHelp(sFileFailed+
        {$IFNDEF D6PLUS}SWin32Error{$ELSE}SOSError{$ENDIF},
        [method, FileName, hfWindowsError, SysErrorMessage(hfWindowsError)],
        hcHFWindowsError)
    else
      Error := EGpHugeFile.CreateFmtHelp(sFileFailed+
        {$IFNDEF D6PLUS}SUnkWin32Error{$ELSE}SUnkOSError{$ENDIF},
        [method, FileName],hcHFUnknownWindowsError);
    raise Error;
  end;
end; { TGpHugeFile.Win32Check }

{:Returns file date in Delphi format.
  @returns Returns file date in Delphi format.
  @raises  EGpHugeFile on Windows errors.
}
function TGpHugeFile.GetDate: TDateTime;
begin
  try
    CheckHandle;
    {$IFDEF D10PLUS}
    FileAge(FileName, Result);
    {$ELSE}
    Result := FileDateToDateTime(FileAge(FileName));
    {$ENDIF}
  except
    on EGpHugeFile do
      raise;
    on E:Exception do
      raise EGpHugeFile.CreateHelp(E.Message,hcHFUnexpected);
  end;
end; { TGpHugeFile.GetDate }

function TGpHugeFile.GetFileName: WideString;
begin
  if IsUnicodeMode then
    Result := hfName
  else
    Result := hfNameA;
end; { TGpHugeFile.GetFileName }

{$IFDEF VCL6}
  {$WARN SYMBOL_PLATFORM OFF}
{$ENDIF}

{:Sets file date.
  @param   Value new file date.
}
procedure TGpHugeFile.SetDate(const Value: TDateTime);
var
  err: integer;
begin
  try
    CheckHandle;
    err := FileSetDate(hfHandle,DateTimeToFileDate(Value));
    if err <> 0 then
      raise EGpHugeFile.CreateFmtHelp(sFileFailed+SysErrorMessage(err),
        ['SetDate', FileName],hcHFWindowsError);
  except
    on EGpHugeFile do
      raise;
    on E:Exception do
      raise EGpHugeFile.CreateHelp(E.Message,hcHFUnexpected);
  end;
end; { TGpHugeFile.SetDate }

{$IFDEF VCL6}
  {$WARN SYMBOL_PLATFORM ON}
{$ENDIF}


{:Returns true if file is loaded into the buffer up to the last byte.
  @returns Returns true if file is loaded into the buffer up to the last byte.
}
function TGpHugeFile.LoadedToTheEOF: boolean;
begin
  Result := (hfBufFileOffs >= (_FileSize*hfBlockSize));
end; { TGpHugeFile.LoadedToTheEOF }

{:Returns file size. If available, returns cached size.
  @returns File size in bytes.
  @raises  EGpHugeFile on Windows errors.
}
function TGpHugeFile._FileSize: HugeInt;
begin
  if hfCachedSize < 0 then
    hfCachedSize := FileSize;
  Result := hfCachedSize;
end; { TGpHugeFile._FileSize }

{:Initializes buffer for writing.
}
procedure TGpHugeFile.InitWriteBuffer;
begin
  hfBufSize     := 0;
  hfBufOffs     := 0;
  hfBufFileOffs := 0;
  hfBufWrite    := true;
end; { TGpHugeFile.InitWriteBuffer }

{:Initializes buffer for reading.
}
procedure TGpHugeFile.InitReadBuffer;
begin
  hfBufOffs     := 0;
  hfBufSize     := 0;
  hfBufFileOffs := 0;
  hfBufWrite    := false;
end; { TGpHugeFile.InitReadBuffer }

procedure TGpHugeFile.InternalCreateEx(FlagsAndAttributes: DWORD; DesiredAccess: DWORD;
  DesiredShareMode: DWORD);
begin
  hfBlockSize        := 1;
  hfBuffer           := nil;
  hfBuffered         := false;
  hfCachedSize       := -1;
  hfDesiredAcc       := DesiredAccess;
  hfDesiredShareMode := DesiredShareMode;
  hfShareModeSet     := true;
  hfFlagNoBuf        := ((FILE_FLAG_NO_BUFFERING AND FlagsAndAttributes) <> 0);
  hfFlags            := FlagsAndAttributes;
  hfHandle           := INVALID_HANDLE_VALUE;
end; { TGpHugeFile.InternalCreateEx }

function TGpHugeFile.IsUnicodeMode: boolean;
begin
  Result := (hfNameA = '');
end; { TGpHugeFile.IsUnicodeMode }

{ TGpHugeFileStream }

{:Initializes stream and opens file in required access mode.
  @param   fileName    Name of file to be accessed.
  @param   access      Required access mode.
  @param   openOptions Set of possible open options.
}
constructor TGpHugeFileStream.Create(const fileName: string;
  access: TGpHugeFileStreamAccess; openOptions: THFOpenOptions;
  desiredShareMode: DWORD; diskLockTimeout, diskRetryDelay: integer);
begin
  inherited Create;
  hfsExternalHF := false;
  case access of
    accRead:
      begin
        hfsFile := TGpHugeFile.CreateEx(fileName, FILE_ATTRIBUTE_NORMAL, GENERIC_READ, desiredShareMode);
        hfsFile.Win32Check(hfsFile.ResetEx(1,0,diskLockTimeout,diskRetryDelay,openOptions) = hfOK, 'Reset');
      end; //accRead
    accWrite:
      begin
        hfsFile := TGpHugeFile.CreateEx(fileName, FILE_ATTRIBUTE_NORMAL, GENERIC_WRITE, desiredShareMode);
        hfsFile.Win32Check(hfsFile.RewriteEx(1,0,diskLockTimeout,diskRetryDelay,openOptions) = hfOK, 'Rewrite');
      end; //accWrite
    accReadWrite:
      begin
        hfsFile := TGpHugeFile.CreateEx(fileName, FILE_ATTRIBUTE_NORMAL, GENERIC_READ+GENERIC_WRITE, desiredShareMode);
        hfsFile.Win32Check(hfsFile.ResetEx(1,0,diskLockTimeout,diskRetryDelay,openOptions) = hfOK, 'Reset');
      end; // accReadWrite
    accAppend:
      begin
        hfsFile := T

⌨️ 快捷键说明

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