Sign in Join

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

Mailing lists / lazarus / 2012-09

Passing a section of an array to a function.

10 messages · 6 people · –

Reply by email Subscribe to this list Your subscription

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

Dave Coventry

Hi,

I have an array of Byte which I have loaded from a file.

I want to process a 100 byte section of the array which starts at offset 32 in my array.

My function (or procedure) is as follows:

procedure decompress_r(cbuf: array of byte);
var
  len,i: integer;
begin
  i:=1;
  if (cbuf[0]and $F0)=$20 then
  begin
    Inc(i,2);
    len:=cbuf[i]and $7;
  end;
  ...
end;

I call my procedure by

decompress_r(&buf[32]);

It seems to work. the first element in the array is 0x20, but the rest of the array is garbage.

The array sent is:
buf[32]=32
buf[33]=0
buf[34]=0
buf[35]=7
buf[36]=0

The array received is
cbuf[0]=32
cbuf[1]=27
cbuf[2]=255
cbuf[3]=247
cbuf[4]=255

Can anyone tell me the correct way to pass the portion of the array to the function?

Many thanks.

Dave

Reply by email

Sven Barth
to Dave Coventry
Dave Coventry wrote 25 lines
Hi, I have an array of Byte which I have loaded from a file. I want to process a 100 byte section of the array which starts at offset 32 in my array. My function (or procedure) is as follows: procedure decompress_r(cbuf: array of byte); var len,i: integer; begin i:=1; if (cbuf[0]and $F0)=$20 then begin Inc(i,2); len:=cbuf[i]and $7; end; ... end; I call my procedure by decompress_r(&buf[32]);

Did you really write "&"? The address operator is "@", but this won't make your code work anyway. If you did indeed write "&" (which is for escaping keywords) you do indeed only pass the 32nd element to your function.

Show quoted text 20 lines
It seems to work. the first element in the array is 0x20, but the rest of the array is garbage. The array sent is: buf[32]=32 buf[33]=0 buf[34]=0 buf[35]=7 buf[36]=0 The array received is cbuf[0]=32 cbuf[1]=27 cbuf[2]=255 cbuf[3]=247 cbuf[4]=255 Can anyone tell me the correct way to pass the portion of the array to the function?

Dynamic arrays are internally pointers to an array (more or less). So if you would use "@buf[32]" you would be passing the address of one element to a function that takes an array. If you know the amount of bytes you want to copy then you should use "Copy(buf, 32, count)" as argument for decompress_r or if you don't know the amount you should change your function from "array of Byte" to "PByte" and pass the address of the 32nd byte using "@buf[32]". The remaining part of the function can stay the same.

Regards,
Sven

Reply by email

Howard Page-Clark
to Dave Coventry: I have an array of Byte which I have loaded from a file. I want to process a 100 byte…
Dave Coventry wrote 21 lines
Hi, I have an array of Byte which I have loaded from a file. I want to process a 100 byte section of the array which starts at offset 32 in my array. My function (or procedure) is as follows: procedure decompress_r(cbuf: array of byte); var len,i: integer; begin i:=1; if (cbuf[0]and $F0)=$20 then begin Inc(i,2); len:=cbuf[i]and $7; end; ... end;

There is no looping construct (while or repeat) in your decompress_r procedure.

Howard

Reply by email

leledumbo
to Sven Barth: Did you really write "&"? The address operator is "@", but this won't make your code work…
If you know the amount of bytes you

want to copy then you should use "Copy(buf, 32, count)" as argument for decompress_r or if you don't know the amount you should change your function from "array of Byte" to "PByte" and pass the address of the 32nd byte using "@buf[32]"

Or use the array slicing construct:

func(buf[32 .. <Last index of the array>]);
reference: http://www.freepascal.org/docs-html/ref/refsu59.html

Reply by email

Sven Barth
to leledumbo
leledumbo wrote 10 lines
> If you know the amount of bytes you want to copy then you should use "Copy(buf, 32, count)" as argument for decompress_r or if you don't know the amount you should change your function from "array of Byte" to "PByte" and pass the address of the 32nd byte using "@buf[32]" Or use the array slicing construct: func(buf[32 .. <Last index of the array>]); reference: http://www.freepascal.org/docs-html/ref/refsu59.html

And it's still true: even I as a compiler developer can learn something new as I didn't know yet that this was possible.

Regards,
Sven

Reply by email

Dave Coventry
to Sven Barth: Did you really write "&"? The address operator is "@", but this won't make your code work…
Sven Barth wrote
Did you really write "&"? The address operator is "@", but this won't make your code work anyway. If you did indeed write "&" (which is for escaping keywords) you do indeed only pass the 32nd element to your function.

:blush:

I did indeed. That would explain it!

Show quoted text 7 lines
Dynamic arrays are internally pointers to an array (more or less). So if you would use "@buf[32]" you would be passing the address of one element to a function that takes an array. If you know the amount of bytes you want to copy then you should use "Copy(buf, 32, count)" as argument for decompress_r or if you don't know the amount you should change your function from "array of Byte" to "PByte" and pass the address of the 32nd byte using "@buf[32]". The remaining part of the function can stay the same.

Thank you, Sven, that will help a lot.

Many thanks,

Dave

Reply by email

Mark Morgan Lloyd
to Sven Barth: And it's still true: even I as a compiler developer can learn something new as I didn't…
Sven Barth wrote 14 lines
Am 10.09.2012 10:39, schrieb leledumbo: >> If you know the amount of bytes you > want to copy then you should use "Copy(buf, 32, count)" as argument for > decompress_r or if you don't know the amount you should change your > function from "array of Byte" to "PByte" and pass the address of the > 32nd byte using "@buf[32]" > > Or use the array slicing construct: > > func(buf[32 .. <Last index of the array>]); > reference: http://www.freepascal.org/docs-html/ref/refsu59.html And it's still true: even I as a compiler developer can learn something new as I didn't know yet that this was possible.

:-) Wasn't there something in PL/1 that allowed a skewed slice of a 2-D array to be passed as a 1-D parameter?

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Marco van de Voort
to Sven Barth: And it's still true: even I as a compiler developer can learn something new as I didn't…
Sven Barth wrote 6 lines
> > func(buf[32 .. <Last index of the array>]); > reference: http://www.freepascal.org/docs-html/ref/refsu59.html And it's still true: even I as a compiler developer can learn something new as I didn't know yet that this was possible.

The delphi compatible way is slice, but ti was only documented after the last release:

http://bugs.freepascal.org/view.php?id=22681

Reply by email

Sven Barth
to Marco van de Voort
Marco van de Voort wrote 12 lines
On Mon, Sep 10, 2012 at 10:47:33AM +0200, Sven Barth wrote: >> >> func(buf[32 .. <Last index of the array>]); >> reference: http://www.freepascal.org/docs-html/ref/refsu59.html > > And it's still true: even I as a compiler developer can learn something > new as I didn't know yet that this was possible. The delphi compatible way is slice, but ti was only documented after the last release: http://bugs.freepascal.org/view.php?id=22681

I did know about Slice, but not about the possiblity to use ranges directly (and now I know what the corresponding code in the parser is for :P )

Regards,
Sven

Reply by email

Marco van de Voort
to Sven Barth
Sven Barth wrote 8 lines
> The delphi compatible way is slice, but ti was only documented after the > last release: > > http://bugs.freepascal.org/view.php?id=22681 I did know about Slice, but not about the possiblity to use ranges directly (and now I know what the corresponding code in the parser is for :P )

Afaik it was one of those "FPC must find its own way, and not slavishly follow Delphi" features. Usually orphans at birth.

Reply by email