BoxedApp Blog

BoxedApp: Tips'n'Tricks, Examples, Use Cases etc.

Delphi: why TStreamAdapter is not suitable for IStream-based virtual files?


Hello,

One delphi programmer wrote me that he tried to create a IStream-based virtual file using a TStreamAdapter. But it doesn’t work. Why?

The reason is quite simple: TStreamAdapter doesn’t provide a correct implementation of IStream.Clone. Check Classes.pas:

function TStreamAdapter.Clone(out stm: IStream): HResult;
begin
  Result := E_NOTIMPL;
end;

IStream.Clone is important method, BoxedApp SDK uses it. But TStreamAdapter just returns E_NOTIMPL. OK, but what’s the solution?

The solution is to create a new class derived from TStreamAdapter and implement IStream.Clone.

For example, if you need a TStreamAdapter based on TFileStream, the implementation would be the following:

type
  TCloneSA = class(TStreamAdapter)
  public
    Path: String;
  public
    function Clone(out stm: IStream): HResult; override; stdcall;
    destructor Destroy; override;
  end;

  { TCloneSA }

function TCloneSA.Clone(out stm: IStream): HResult;
var
  FS: TFileStream;
  S: TCloneSA;
begin
  FS := TFileStream.Create(Path, fmOpenReadWrite or fmShareDenyNone);
  S := TCloneSA.Create(FS, soOwned);
  S.Path := Path;

  result := S.QueryInterface(IStream, stm);
end;