Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2021-06

TMemoryStream.SetSize question.

5 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

gabor

Why does TMemoryStream only implement one version of SetSize method?

https://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/rtl/objpas/classes/classesh.inc?revision=49038&view=markup#l1225

The TStream class has two versions of SetSize method (virtual, overload)
- one with a parameter of LongInt type and the other with the Int64 type. Since function is virtual, child classes can override it and can be called from code, but then a version of the SetSize function not implemented for a given platform in the TMemoryStream class can be called.

Michał.

Reply by email

Michael Van Canneyt
to gabor
gabor wrote 9 lines
Why does TMemoryStream only implement one version of SetSize method? https://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/rtl/objpas/classes/classesh.inc?revision=49038&view=markup#l1225 The TStream class has two versions of SetSize method (virtual, overload) - one with a parameter of LongInt type and the other with the Int64 type. Since function is virtual, child classes can override it and can be called from code, but then a version of the SetSize function not implemented for a given platform in the TMemoryStream class can be called.

The base method checks which one is overridden.
So it does not matter which one you override in the child. The "other" one will always fall back to the method in TStream.

Michael.

Reply by email

gabor
to Michael Van Canneyt

W dniu 2021-06-14 o 21:27, Michael Van Canneyt via fpc-pascal pisze:

Show quoted text 20 lines
On Mon, 14 Jun 2021, gabor via fpc-pascal wrote: > Why does TMemoryStream only implement one version of SetSize method? > > https://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/rtl/objpas/classes/classesh.inc?revision=49038&view=markup#l1225 > > > The TStream class has two versions of SetSize method (virtual, > overload) - one with a parameter of LongInt type and the other with > the Int64 type. Since function is virtual, child classes can override > it and can be called from code, but then a version of the SetSize > function not implemented for a given platform in the TMemoryStream > class can be called. The base method checks which one is overridden. So it does not matter which one you override in the child. The "other" one will always fall back to the method in TStream.

Unfortunately, on the 64bit platform it does not fully work. See the project below.

program Project1;
{$mode objfpc}
uses
   Classes;
type
   TMyMemStream = class(TMemoryStream)
     procedure Foo;
     procedure Bar;
   end;
procedure TMyMemStream.Foo;
begin
   SetSize(10);
end;
procedure TMyMemStream.Bar;
begin
   SetSize(Int64(10));
end;
var
   MS: TMyMemStream;
begin
   MS := TMyMemStream.Create;
   MS.Foo;
   WriteLn(MS.Size);
   MS.Bar;
   WriteLn(MS.Size);
   MS.Free;
   ReadLn;
end.

Michał.

Reply by email

Michael Van Canneyt
to gabor
gabor wrote 25 lines
W dniu 2021-06-14 o 21:27, Michael Van Canneyt via fpc-pascal pisze: > > > On Mon, 14 Jun 2021, gabor via fpc-pascal wrote: > >> Why does TMemoryStream only implement one version of SetSize method? >> >> https://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/rtl/objpas/classes/classesh.inc?revision=49038&view=markup#l1225 >> >> >> The TStream class has two versions of SetSize method (virtual, >> overload) - one with a parameter of LongInt type and the other with >> the Int64 type. Since function is virtual, child classes can override >> it and can be called from code, but then a version of the SetSize >> function not implemented for a given platform in the TMemoryStream >> class can be called. > > The base method checks which one is overridden. So it does not matter > which one you override in the child. > The "other" one will always fall back to the method in TStream. > Unfortunately, on the 64bit platform it does not fully work. See the project below.

Sorry, I was mixing up seek and setsize.

Indeed. You should not be calling the integer SetSize() directly.

People creating descendent classes are expected to know what to do, i.e. to use the 64-bit version.

Michael.

Reply by email

gabor
to Michael Van Canneyt

W dniu 2021-06-14 o 22:25, Michael Van Canneyt via fpc-pascal pisze:

Show quoted text 36 lines
On Mon, 14 Jun 2021, gabor via fpc-pascal wrote: > W dniu 2021-06-14 o 21:27, Michael Van Canneyt via fpc-pascal pisze: >> >> >> On Mon, 14 Jun 2021, gabor via fpc-pascal wrote: >> >>> Why does TMemoryStream only implement one version of SetSize method? >>> >>> > https://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/rtl/objpas/classes/classesh.inc?revision=49038&view=markup#l1225 > >>> >>> >>> The TStream class has two versions of SetSize method (virtual, >>> overload) - one with a parameter of LongInt type and the other with >>> the Int64 type. Since function is virtual, child classes can >>> override it and can be called from code, but then a version of the >>> SetSize function not implemented for a given platform in the >>> TMemoryStream class can be called. >> >> The base method checks which one is overridden. So it does not matter >> which one you override in the child. >> The "other" one will always fall back to the method in TStream. >> > > Unfortunately, on the 64bit platform it does not fully work. See the > project below. Sorry, I was mixing up seek and setsize. Indeed. You should not be calling the integer SetSize() directly. People creating descendent classes are expected to know what to do, i.e. to use the 64-bit version.

You are absolutely right. But why do we have different function for different platforms? Wouldn't it be better to implement either one function with an Int64 parameter for both platforms, or even both variants of this function? The Size property is of type int64 on both platforms so why should SetSize (that is public in TMemoryStream) be platform dependent?

Michał.

Reply by email