Recent

Author Topic: TMemorySream.SetSize problem....  (Read 569 times)

Prime

  • Jr. Member
  • **
  • Posts: 62
TMemorySream.SetSize problem....
« on: October 26, 2020, 10:29:04 pm »
Hi all,

I have a TMemoryStream decendent defined as follows :
Code: [Select]
  TRomChecksum = Class(TMemoryStream)
  PUBLIC
    Count   : BYTE; { Count of 512 byte blocks }
    CkSum   : BYTE; { Calculated checksum }
    CkByte  : BYTE; { Byte to be added to make checksum zero }

    Constructor Create;
    PROCEDURE CalculateChecksums;
  END;

Within my program's implementation I'm using SetSize to set the size of the stream before outputting it :

Code: [Select]
PROCEDURE ChecksumFile(FileToCheck      : STRING;
                       PadTo            : INTEGER);

VAR     RomFile : TRomChecksum;

BEGIN;
  RomFile:=TRomChecksum.Create;
  TRY
    WITH RomFile DO
    BEGIN;
      LoadFromFile(FileName);

      CalculateChecksums;

      { Update file *ONLY* if checksum not valid ! }
      IF (CkSum <> 0) THEN
      BEGIN;
        Position:=(Count*512)-1;   { Last byte }
        Write(CkByte,1);
      END;

WriteLn(Format('PadTo: %d, Count*512: %d, Romfile.Size:%d',[PadTo,(Count*512),RomFile.Size]));

      IF (PadTo>=(Count*512)) THEN
        RomFile.SetSize(PadTo);

      SaveToFile(FileName);

      WriteLn(Format('File         : %s',[FileToCheck]));
      WriteLn(Format('Blocks       : %d',[Count]));
      WriteLn(Format('Sum          : $%2.2Xh',[CkSum]));
      WriteLn(Format('CkByte       : $%2.2Xh',[CkByte]));
      WriteLn(Format('Final length : %d',[RomFile.Size]));
    END;
  FINALLY
    RomFile.Free;
  END;
END;

On entry Count is 4 (read from the rom being processed), and PadTo is fed in as 8192. Single stepping to make sure, it does execute the SetSize, but the size of the stream stubbonly stays at 2048 (Count * 512), as set by the checksum write above. Any idea what is going wrong here.

What I do find curious is that CTRL clicking on SetSize in my code takes me to the definition for TStream.SetSize which according to the docs does nothing. But I was under the impression that MemoryStream was a decendent of TStream that overrode that, and therefore TRomChecksum should too.

Tried in Laz 2.0.6 and then upgraded to 2.0.10 and problem still there.....

Cheers.

Phill.
« Last Edit: October 26, 2020, 10:30:50 pm by Prime »

Blaazen

  • Hero Member
  • *****
  • Posts: 3237
  • POKE 54296,15
    • Eye-Candy Controls
Re: TMemorySream.SetSize problem....
« Reply #1 on: October 26, 2020, 10:58:09 pm »
That's because TStream has three two overloaded virtual SetSize methods and TMemoryStream overrides the one with parameter Int64:
Code: Pascal  [Select][+][-]
  1. procedure SetSize({$ifdef CPU64}const NewSize: Int64{$else}NewSize: LongInt{$endif}); override;
I assume you have 64-bit platform. Declare PadTo as Int64 or call SetSize(Int64(PadTo));.

EDIT: only two overloaded virtual SetSize methods, the third is named SetSize64
« Last Edit: October 27, 2020, 12:37:26 am by Blaazen »
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

Prime

  • Jr. Member
  • **
  • Posts: 62
Re: TMemorySream.SetSize problem....
« Reply #2 on: October 27, 2020, 04:43:47 pm »
That's because TStream has three two overloaded virtual SetSize methods and TMemoryStream overrides the one with parameter Int64:
Code: Pascal  [Select][+][-]
  1. procedure SetSize({$ifdef CPU64}const NewSize: Int64{$else}NewSize: LongInt{$endif}); override;
I assume you have 64-bit platform. Declare PadTo as Int64 or call SetSize(Int64(PadTo));.

EDIT: only two overloaded virtual SetSize methods, the third is named SetSize64

That seemed to work, though it would be logical (and match with the documentatiion, and what people coming from Delphi would expect) to have both overridden even if one is just a casted call to the other.

Cheers.

Phill.

 

TinyPortal © 2005-2018