Recent

Author Topic: Is it possible to chage value type without explicitly casting it ?  (Read 2317 times)

andresayang

  • Full Member
  • ***
  • Posts: 108
Is it possible to chage value type without explicitly casting it ?
« on: September 19, 2018, 05:42:18 pm »
Hi,

Is it possible to do something like this:

Code: Pascal  [Select][+][-]
  1. type
  2.  TData = Array of Int32;
  3.  TSamples = Array of Single;
  4.  PSamples = ^TSamples;
  5. var
  6.   Data: TData;
  7.  
  8.  SetLength(Data, 1024);
  9.  MyFile:TFileStream.Create('c:\binfile.bin'); // all after is within a try .. finally
  10.  ReadBuffer(Pointer(Data)^, 1024 * 4); // up to here, no pb
  11.  PSamples:= @Data[512];
  12.  
  13.  And then have access to PSamples^[0] as single ?
  14.  
  15.  

Thanks
Linux, Debian 12
Lazarus: always latest release

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Is it possible to chage value type without explicitly casting it ?
« Reply #1 on: September 19, 2018, 05:52:11 pm »
The best way to know if it's possible is simply trying it. Just a hint: remember to disable strict pointer checking.  :)
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

andresayang

  • Full Member
  • ***
  • Posts: 108
Re: Is it possible to chage value type without explicitly casting it ?
« Reply #2 on: September 19, 2018, 05:58:14 pm »
The best way to know if it's possible is simply trying it. Just a hint: remember to disable strict pointer checking.  :)

Well well, I think it is possible, try without luck so 2 possibilities:

- Not possible
- I do not have the good codding (I think about this one)

That is why I ask if it is possible or not.

Thanks for your hint, I'll try to do without pointer checking.

thx
« Last Edit: September 19, 2018, 05:59:47 pm by andresayang »
Linux, Debian 12
Lazarus: always latest release

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Is it possible to chage value type without explicitly casting it ?
« Reply #3 on: September 19, 2018, 06:23:04 pm »
Well well, I think it is possible, try without luck so 2 possibilities:

- Not possible
- I do not have the good codding (I think about this one)

That is why I ask if it is possible or not.

OK, then; it is possible. It's basically the same as if you declared:
Code: [Select]
var
  Data: TData;
  Samples: TSamples absolute Data;

The code you have shown, however, is clearly incomplete so it's difficult to say where and why it's failing. Can you share a complete, compilable example?
« Last Edit: September 19, 2018, 06:26:37 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

andresayang

  • Full Member
  • ***
  • Posts: 108
Re: Is it possible to chage value type without explicitly casting it ?
« Reply #4 on: September 19, 2018, 06:41:35 pm »
Yes,

I test your tips:

Code: Pascal  [Select][+][-]
  1. var
  2.   Data: TData;
  3.   Samples: TSamples absolute Data;
  4.  

Thanks a lot, this is doing exactly what I want to do.
For the remaining, I can easily manage with offsets.

Cheers

« Last Edit: September 19, 2018, 07:46:14 pm by andresayang »
Linux, Debian 12
Lazarus: always latest release

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Is it possible to chage value type without explicitly casting it ?
« Reply #5 on: September 19, 2018, 09:08:23 pm »
I test your tips:

Code: Pascal  [Select][+][-]
  1. var
  2.   Data: TData;
  3.   Samples: TSamples absolute Data;
  4.  

Thanks a lot, this is doing exactly what I want to do.
For the remaining, I can easily manage with offsets.

It wasn't exactly a tip; more of an example (kind of)  :)
What you were doing should work, provided the Typed Address Operator check is off--as it's by default, and it has the added bonus of being able to make the pointer point to any member of the Data array, in case you need to read a mixed Integers+Singles file.

Incidentally, yet another common way of hide-casting is like this:
Code: [Select]
type
  TData = Array of Int32;
  TSamples = Array of Single;

  TMixedRecord = packed record
    case boolean of
    True: (Data: TData);
    False:(Samples: TSamples);
  end;

var
  AMixedRecord: TMixedRecord;

With that you may v.g. read into AMixedRecord.Data from the file but use AMixedRecord.Samples afterwards. It's a good way of avoiding absolute, which lots of people don't like, while doing basically the same :D
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

andresayang

  • Full Member
  • ***
  • Posts: 108
Re: Is it possible to chage value type without explicitly casting it ?
« Reply #6 on: September 19, 2018, 11:50:41 pm »
Well,

In fact, what exactly I want to do is to optimize the speed of the binary file reading.
My file structure is:
N times
- a Header of 64 "4-bytes integer"
- Samples of X "4-Bytes float IEEE" (so single, but variable array lenght)

One set of (Header + samples) are a multiple of 512 bytes. (I think this was due to network communications years ago, but standard remain)

So this is now my code:
Code: Pascal  [Select][+][-]
  1. unit ReadBin;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
  9.  
  10. type
  11.  
  12.   TForm1 = class(TForm)
  13.     BtnRun: TButton;
  14.     DlgOpenBin: TOpenDialog;
  15.     procedure BtnRunClick(Sender: TObject);
  16.   private
  17.     procedure SwapByte(ToSwap: boolean; var BytesToSwap: Array of int32);
  18.   public
  19.  
  20.   end;
  21.  
  22. var
  23.   Form1: TForm1;
  24.  
  25. implementation
  26.  
  27. {$R *.lfm}
  28. const
  29.   HeadSize = 64;
  30.  
  31. type
  32.   TData= Array of int32;
  33.   TSamples= Array of single;
  34.  
  35. var
  36.   BinFile: TFileStream;
  37.   TraceSize: integer;
  38.   Data: TData;
  39.   Samples: TSamples absolute Data;
  40.   IsBigEndian: boolean;
  41.  
  42. { TForm1 }
  43.  
  44. procedure TForm1.BtnRunClick(Sender: TObject);
  45. var
  46.   abyte: byte = 0;
  47.   nbjd, test: integer;
  48. begin
  49.   DlgOpenBin.Filter:= 'Bin file | *.bin';
  50.   if DlgOpenBin.Execute then
  51.     begin
  52.       SetLength(Data, HeadSize);
  53.       BinFile:= TFileStream.Create(DlgOpenBin.Files[0], fmOpenRead);
  54.       try
  55.         BinFile.Seek(40, soFromBeginning);
  56.         BinFile.Read(abyte, 1);
  57.         IsBigEndian:= (abyte > 20);
  58.         BinFile.Seek(0, soFromBeginning);
  59.         BinFile.ReadBuffer(Pointer(Data)^, HeadSize * 4);
  60.         SwapByte(IsBigEndian, Header);
  61.         TraceSize:= (((Data[9] * 1000) div Data[8]) + 64) * 4;
  62.         TraceSize:= (TraceSize + (512 - TraceSize mod 512)) div 4;
  63.         BinFile.Seek(0, soFromBeginning);
  64.         SetLength(Data, TraceSize);
  65.         BinFile.ReadBuffer(Pointer(Data)^, TraceSize * 4);
  66.         SwapByte(IsBigEndian, Data);
  67.         .....
  68.      finally
  69.         BinFile.Free;
  70.       end;
  71.     end;
  72. end;
  73.  
  74. procedure TForm1.SwapByte(ToSwap: boolean; var BytesToSwap: Array of int32);
  75. var
  76.   i: integer;
  77. begin
  78.   if ToSwap then
  79.     for i:= 0 to Length(BytesToSwap) -1 do BytesToSwap[i]:= SwapEndian(BytesToSwap[i]);
  80. end;
  81. end.
  82.  
  83.  

With your example, I can read my data as integer or as single, so it is perfect.
Doing like this allows me also to use the same swap byte function, regardless the type of data.
While typing this post, I optimize also my code, removing useless remaining declarations.

I'll give a try to your second example.

Thanks a lot

Cheers
« Last Edit: September 20, 2018, 12:00:44 am by andresayang »
Linux, Debian 12
Lazarus: always latest release

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Is it possible to chage value type without explicitly casting it ?
« Reply #7 on: September 20, 2018, 12:20:22 am »
Well, I wouldn't do it quite like that, although there doesn't seems to be nothing egregiously wrong and my solution would probably end up looking very similar, so good job and kudos to you :)
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

 

TinyPortal © 2005-2018