|
|
@@ -24,7 +24,8 @@ interface
|
|
|
uses
|
|
|
Classes,
|
|
|
SysUtils,
|
|
|
- ClpCryptoLibTypes;
|
|
|
+ ClpCryptoLibTypes,
|
|
|
+ ClpStreamUtilities;
|
|
|
|
|
|
type
|
|
|
/// <summary>
|
|
|
@@ -244,54 +245,6 @@ type
|
|
|
|
|
|
end;
|
|
|
|
|
|
-type
|
|
|
- /// <summary>
|
|
|
- /// Utility class with static methods for stream operations.
|
|
|
- /// </summary>
|
|
|
- TStreamUtils = class sealed(TObject)
|
|
|
-
|
|
|
- strict private
|
|
|
- const
|
|
|
- MaxStackAlloc = Int32(4096);
|
|
|
-
|
|
|
- public
|
|
|
- class function DefaultBufferSize: Int32; static; inline;
|
|
|
-
|
|
|
- class procedure CopyTo(const ASource: TStream; const ADestination: TStream;
|
|
|
- ABufferSize: Int32); overload; static;
|
|
|
- class procedure CopyTo(const ASource: TStream;
|
|
|
- const ADestination: TStream); overload; static;
|
|
|
-
|
|
|
- class procedure Drain(const AInStr: TStream); static;
|
|
|
-
|
|
|
- class procedure PipeAll(const AInStr: TStream; const AOutStr: TStream;
|
|
|
- ABufferSize: Int32); overload; static;
|
|
|
- class procedure PipeAll(const AInStr: TStream;
|
|
|
- AOutStr: TStream); overload; static;
|
|
|
-
|
|
|
- class function PipeAllLimited(const AInStr: TStream; ALimit: Int64;
|
|
|
- const AOutStr: TStream; ABufferSize: Int32): Int64; overload; static;
|
|
|
- class function PipeAllLimited(const AInStr: TStream; ALimit: Int64;
|
|
|
- const AOutStr: TStream): Int64; overload; static;
|
|
|
-
|
|
|
- class function ReadAll(const AInStr: TStream): TCryptoLibByteArray; static;
|
|
|
-
|
|
|
- class function ReadAllLimited(const AInStr: TStream;
|
|
|
- ALimit: Int32): TCryptoLibByteArray; static;
|
|
|
-
|
|
|
- class function ReadFully(const AInStr: TStream;
|
|
|
- const ABuf: TCryptoLibByteArray; AOff, ALen: Int32): Int32; overload; static;
|
|
|
- class function ReadFully(const AInStr: TStream;
|
|
|
- const ABuf: TCryptoLibByteArray): Int32; overload; static;
|
|
|
-
|
|
|
- class procedure ValidateBufferArguments(const ABuffer: TCryptoLibByteArray;
|
|
|
- AOffset, ACount: Int32); static;
|
|
|
-
|
|
|
- class function WriteBufTo(const ABuf: TMemoryStream;
|
|
|
- const AOutput: TCryptoLibByteArray; AOffset: Int32): Int32; static;
|
|
|
-
|
|
|
- end;
|
|
|
-
|
|
|
implementation
|
|
|
|
|
|
{ TStreamHelper }
|
|
|
@@ -601,7 +554,7 @@ end;
|
|
|
|
|
|
function TBaseInputStream.Read(ABuffer: TCryptoLibByteArray; AOffset, ACount: LongInt): LongInt;
|
|
|
begin
|
|
|
- TStreamUtils.ValidateBufferArguments(ABuffer, AOffset, ACount);
|
|
|
+ TStreamUtilities.ValidateBufferArguments(ABuffer, AOffset, ACount);
|
|
|
Result := Read(ABuffer[AOffset], ACount);
|
|
|
end;
|
|
|
|
|
|
@@ -663,7 +616,7 @@ end;
|
|
|
|
|
|
function TBaseOutputStream.Write(const ABuffer: TCryptoLibByteArray; AOffset, ACount: LongInt): LongInt;
|
|
|
begin
|
|
|
- TStreamUtils.ValidateBufferArguments(ABuffer, AOffset, ACount);
|
|
|
+ TStreamUtilities.ValidateBufferArguments(ABuffer, AOffset, ACount);
|
|
|
Result := Write(ABuffer[AOffset], ACount);
|
|
|
end;
|
|
|
|
|
|
@@ -753,7 +706,7 @@ end;
|
|
|
|
|
|
constructor TBufferedFilterStream.Create(const AStream: TStream);
|
|
|
begin
|
|
|
- Create(AStream, TStreamUtils.DefaultBufferSize);
|
|
|
+ Create(AStream, TStreamUtilities.DefaultBufferSize);
|
|
|
end;
|
|
|
|
|
|
constructor TBufferedFilterStream.Create(const AStream: TStream;
|
|
|
@@ -855,158 +808,4 @@ begin
|
|
|
FBuffer := AByte and $FF;
|
|
|
end;
|
|
|
|
|
|
-{ TStreamUtils }
|
|
|
-
|
|
|
-class function TStreamUtils.DefaultBufferSize: Int32;
|
|
|
-begin
|
|
|
- Result := MaxStackAlloc;
|
|
|
-end;
|
|
|
-
|
|
|
-class procedure TStreamUtils.CopyTo(const ASource: TStream;
|
|
|
- const ADestination: TStream; ABufferSize: Int32);
|
|
|
-var
|
|
|
- LBytesRead: Int32;
|
|
|
- LBuffer: TCryptoLibByteArray;
|
|
|
-begin
|
|
|
- System.SetLength(LBuffer, ABufferSize);
|
|
|
- LBytesRead := ASource.Read(LBuffer, 0, ABufferSize);
|
|
|
- while LBytesRead <> 0 do
|
|
|
- begin
|
|
|
- ADestination.Write(LBuffer, 0, LBytesRead);
|
|
|
- LBytesRead := ASource.Read(LBuffer, 0, ABufferSize);
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-class procedure TStreamUtils.CopyTo(const ASource: TStream;
|
|
|
- const ADestination: TStream);
|
|
|
-begin
|
|
|
- CopyTo(ASource, ADestination, DefaultBufferSize);
|
|
|
-end;
|
|
|
-
|
|
|
-class procedure TStreamUtils.Drain(const AInStr: TStream);
|
|
|
-var
|
|
|
- LBuffer: TCryptoLibByteArray;
|
|
|
- LBytesRead: Int32;
|
|
|
-begin
|
|
|
- System.SetLength(LBuffer, DefaultBufferSize);
|
|
|
- LBytesRead := AInStr.Read(LBuffer, 0, DefaultBufferSize);
|
|
|
- while LBytesRead > 0 do
|
|
|
- begin
|
|
|
- // Discard the data
|
|
|
- LBytesRead := AInStr.Read(LBuffer, 0, DefaultBufferSize);
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-class procedure TStreamUtils.PipeAll(const AInStr: TStream; const AOutStr: TStream;
|
|
|
- ABufferSize: Int32);
|
|
|
-begin
|
|
|
- CopyTo(AInStr, AOutStr, ABufferSize);
|
|
|
-end;
|
|
|
-
|
|
|
-class procedure TStreamUtils.PipeAll(const AInStr: TStream;
|
|
|
- AOutStr: TStream);
|
|
|
-begin
|
|
|
- PipeAll(AInStr, AOutStr, DefaultBufferSize);
|
|
|
-end;
|
|
|
-
|
|
|
-class function TStreamUtils.PipeAllLimited(const AInStr: TStream;
|
|
|
- ALimit: Int64; const AOutStr: TStream; ABufferSize: Int32): Int64;
|
|
|
-var
|
|
|
- LLimited: TLimitedInputStream;
|
|
|
-begin
|
|
|
- LLimited := TLimitedInputStream.Create(AInStr, ALimit);
|
|
|
- try
|
|
|
- CopyTo(LLimited, AOutStr, ABufferSize);
|
|
|
- Result := ALimit - LLimited.CurrentLimit;
|
|
|
- finally
|
|
|
- LLimited.Free;
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-class function TStreamUtils.PipeAllLimited(const AInStr: TStream;
|
|
|
- ALimit: Int64; const AOutStr: TStream): Int64;
|
|
|
-begin
|
|
|
- Result := PipeAllLimited(AInStr, ALimit, AOutStr, DefaultBufferSize);
|
|
|
-end;
|
|
|
-
|
|
|
-class function TStreamUtils.ReadAll(const AInStr: TStream): TCryptoLibByteArray;
|
|
|
-var
|
|
|
- LBuf: TMemoryStream;
|
|
|
-begin
|
|
|
- LBuf := TMemoryStream.Create();
|
|
|
- try
|
|
|
- PipeAll(AInStr, LBuf);
|
|
|
- System.SetLength(Result, LBuf.Size);
|
|
|
- LBuf.Position := 0;
|
|
|
- LBuf.Read(Result, 0, LBuf.Size);
|
|
|
- finally
|
|
|
- LBuf.Free;
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-class function TStreamUtils.ReadAllLimited(const AInStr: TStream;
|
|
|
- ALimit: Int32): TCryptoLibByteArray;
|
|
|
-var
|
|
|
- LBuf: TMemoryStream;
|
|
|
-begin
|
|
|
- LBuf := TMemoryStream.Create();
|
|
|
- try
|
|
|
- PipeAllLimited(AInStr, ALimit, LBuf);
|
|
|
- System.SetLength(Result, LBuf.Size);
|
|
|
- LBuf.Position := 0;
|
|
|
- LBuf.Read(Result, 0, LBuf.Size);
|
|
|
- finally
|
|
|
- LBuf.Free;
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-class function TStreamUtils.ReadFully(const AInStr: TStream;
|
|
|
- const ABuf: TCryptoLibByteArray; AOff, ALen: Int32): Int32;
|
|
|
-var
|
|
|
- LTotalRead, LNumRead: Int32;
|
|
|
-begin
|
|
|
- LTotalRead := 0;
|
|
|
- while LTotalRead < ALen do
|
|
|
- begin
|
|
|
- LNumRead := AInStr.Read(ABuf, AOff + LTotalRead, ALen - LTotalRead);
|
|
|
- if LNumRead < 1 then
|
|
|
- break;
|
|
|
- LTotalRead := LTotalRead + LNumRead;
|
|
|
- end;
|
|
|
- Result := LTotalRead;
|
|
|
-end;
|
|
|
-
|
|
|
-class function TStreamUtils.ReadFully(const AInStr: TStream;
|
|
|
- const ABuf: TCryptoLibByteArray): Int32;
|
|
|
-begin
|
|
|
- Result := ReadFully(AInStr, ABuf, 0, System.Length(ABuf));
|
|
|
-end;
|
|
|
-
|
|
|
-class procedure TStreamUtils.ValidateBufferArguments(const ABuffer
|
|
|
- : TCryptoLibByteArray; AOffset, ACount: Int32);
|
|
|
-var
|
|
|
- LAvailable, LRemaining: Int32;
|
|
|
-begin
|
|
|
- if ABuffer = nil then
|
|
|
- raise EArgumentNilCryptoLibException.Create('Buffer cannot be nil');
|
|
|
- LAvailable := System.Length(ABuffer) - AOffset;
|
|
|
- if ((AOffset or LAvailable) < 0) then
|
|
|
- raise EArgumentOutOfRangeCryptoLibException.Create('Offset out of range');
|
|
|
- LRemaining := LAvailable - ACount;
|
|
|
- if ((ACount or LRemaining) < 0) then
|
|
|
- raise EArgumentOutOfRangeCryptoLibException.Create('Count out of range');
|
|
|
-end;
|
|
|
-
|
|
|
-class function TStreamUtils.WriteBufTo(const ABuf: TMemoryStream;
|
|
|
- const AOutput: TBytes; AOffset: Integer): Integer;
|
|
|
-begin
|
|
|
- Result := ABuf.Size;
|
|
|
-
|
|
|
- if (AOffset < 0) or (AOffset + Result > Length(AOutput)) then
|
|
|
- raise ERangeError.Create('Output buffer too small');
|
|
|
-
|
|
|
- // Copy directly from stream buffer into the byte array
|
|
|
- Move(PByte(ABuf.Memory)^, AOutput[AOffset], Result);
|
|
|
-end;
|
|
|
-
|
|
|
end.
|