[fpc-pascal] Get empty memory quickly or... an empty file

Michael Van Canneyt michael at freepascal.org
Fri Sep 13 16:17:23 CEST 2013



On Fri, 13 Sep 2013, Reinier Olislagers wrote:

> On 13/09/2013 15:38, Marco van de Voort wrote:
>> In our previous episode, Reinier Olislagers said:
>>> However, I'm sure there must be quicker ways (e.g. less newbie code;
>>> using OS functions to quickly create empty memor, or alternatively
>>> create a sparse file and zip the file instead of the stream).
>>
>> Do not create the data, but generate it in an overriden tstream read() call?
>>
>> If you can define a function that can generate "count" bytes of data at
>> position n (in this case the function is constant), then you don't have to
>> write it out.
>>
>> Ken in mind that TStream is an abstraction, not necessarily a block of
>> (RAM or disk) memory.
>
> Mmm, yes, that sounds very smart, thanks!

Attached a NullStream implementation.

Michael.
-------------- next part --------------
{
    This file is part of the Free Component Library (FCL)
    Copyright (c) 1999-2000 by Michael Van Canneyt and Florian Klaempfl

    See the file COPYING.FPC, included in this distribution,
    for details about the copyright.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 **********************************************************************}
{$mode objfpc}

unit nullstream;

interface

uses Classes;

type
  ENullStreamError = class(EStreamError);

  { TNullStream }

  TNullStream = class(THandleStream)
  private
    FPos : Int64;
  protected
    function  GetPosition: Int64; override;
    procedure InvalidSeek; override;
  public
    function Read(var Buffer; Count : LongInt) : Longint; override;
    function Write(const Buffer; Count : LongInt) : LongInt; override;
    function Seek(const Offset: int64; Origin: TSeekOrigin): int64; override;
    end;

implementation

const
  SInvalidOperation = 'Cannot perform this operation on a IOStream.';

function TNullStream.GetPosition: Int64;
begin
  Result:=FPos;
end;

procedure TNullStream.InvalidSeek;
begin
  raise ENullStreamError.Create(SInvalidOperation);
end;

function TNullStream.Read(var Buffer; Count : LongInt) : Longint;
begin
  FillChar(Buffer,Count,0);
  Result:=Count;
  Inc(FPos,Count);
end;

function TNullStream.Write(const Buffer; Count : LongInt) : LongInt;
begin
  Inc(FPos,Count);
end;


function TNullStream.Seek(const Offset: int64; Origin: TSeekOrigin): int64;
begin
  if (Origin=soCurrent) and (Offset=0) then
    Result:=FPos
  else
    FakeSeekForward(Offset,Origin,FPos);
end;

end.


More information about the fpc-pascal mailing list