How do I address bytes in a Buf/binary variable?

Hi All!

Question: I am using `read` to read the first 400 bytes of an unknown 
file (could be a binary file).  The 400 bytes go into a variable
of type "Buf".  This is not a string.

p6 'my $fh=open "/home/linuxutil/To", :r; my Buf $f = $fh.read( 400 ); 
$fh.close;'

Now in $f, I want to look at each byte one at a time for a
bitwise pattern using bitwise AND.

How do I address each byte?

`dd` seems to get me the information I need, but it prints it:

     $ p6 'my $fh=open "/home/linuxutil/To", :r; my Buf $f = $fh.read( 
10 ); $fh.close; dd $f;'

     Buf[uint8] $f = Buf[uint8].new(87,111,114,100,80,114,111,0,0,0)

An array of bytes would be great.

Many thanks,
-T
0
perl6
10/8/2018 8:25:31 AM
perl.perl6.users 1085 articles. 0 followers. Follow

5 Replies
15 Views

Similar Articles

[PageSpeed] 19

--GpGaEY17fSl8rd50
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Mon, Oct 08, 2018 at 01:25:31AM -0700, ToddAndMargo via perl6-users wrot=
e:
> Hi All!
>=20
> Question: I am using `read` to read the first 400 bytes of an unknown file
> (could be a binary file).  The 400 bytes go into a variable
> of type "Buf".  This is not a string.
>=20
> p6 'my $fh=3Dopen "/home/linuxutil/To", :r; my Buf $f =3D $fh.read( 400 );
> $fh.close;'
>=20
> Now in $f, I want to look at each byte one at a time for a
> bitwise pattern using bitwise AND.
>=20
> How do I address each byte?
>=20
> `dd` seems to get me the information I need, but it prints it:
>=20
>     $ p6 'my $fh=3Dopen "/home/linuxutil/To", :r; my Buf $f =3D $fh.read(=
 10 );
> $fh.close; dd $f;'
>=20
>     Buf[uint8] $f =3D Buf[uint8].new(87,111,114,100,80,114,111,0,0,0)
>=20
> An array of bytes would be great.

Point a browser at https://docs.perl6.org/ and click on "Types" in
the top ribbon.  You will see a list of all the Perl 6 built-in types;
"Buf" is there near the top.  Click on "Buf".

Now there are two clues as to what you want: one of them is that
the table of contents on the left has a section "Routines supplied by
role Positional", and the other one is that the very first example
has a line saying "$b[1] =3D 42".

So you can use a Buf object as an array of whatever it contains.

G'luck,
Peter

--=20
Peter Pentchev  roam@{ringlet.net,debian.org,FreeBSD.org} pp@storpool.com
PGP key:        http://people.FreeBSD.org/~roam/roam.key.asc
Key fingerprint 2EE7 A7A5 17FC 124C F115  C354 651E EFB0 2527 DF13

--GpGaEY17fSl8rd50
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQIzBAABCAAdFiEELuenpRf8EkzxFcNUZR7vsCUn3xMFAlu7FowACgkQZR7vsCUn
3xOzag//RwcN3C7uULNEQ/364mr806GFitQGfvoTtZ47xx6c3j2yhlp3bASofbXC
A5nawcnumyA/WKyaray9o+neM7tR3TWgVAwMESdfsuTOO0RFoaDS5wb3UPrV2FQi
FXzsEZf8hoZEWgVp8+PbsjPNFAcfN9z5IbwwWxQJXzkvaNd3nzliWkCok3YEye8f
iPC+jIf/WDovYPzpTYFjpsOpz4g1cV/3KkOEGahK1TUMJsSRqrXiXel40orHmxaz
CBMGi2GhTFx7vyXq9Hkm+6CPKhx3S6SCohe9KZMGC3XlFC8Yh+Tw56RLuPfQt63x
UeDHIZj4TPrG9K+txvPQU9tRrSDvZznNfBKvXsfyH4ebxqeQbEKIOuHFTq8GX97w
hQUwiNsM13cZMU+H2sqbaBArcZgg0psfQIpU/msHB38itSFuFu9FRcDcUlxVqcBB
rmUpCzbFDwm04KZ9Chy5OpKNTE4ezrhGCPgN79Tm4QXfbt+h3FnWWgIEJ3g/g/yd
MlfzPKA5kNHy26wDwPKDAypL4nS5P0RX3eOTnLNaHIvgDLVExsa7APO3o+XUZk88
1siKf24pX9DlgEbHqd0Fu2o82DDa0s/TL4LJ73HR/cr+Z9op5gEgQ1C0baso6227
EVuc+NXnfAiyluzjLVQsHGju6NhHlA2jI0T+Qm9pr/RhsV76GCY=
=D2Ag
-----END PGP SIGNATURE-----

--GpGaEY17fSl8rd50--
0
roam
10/8/2018 8:34:20 AM
On 10/8/18 1:34 AM, Peter Pentchev wrote:
> On Mon, Oct 08, 2018 at 01:25:31AM -0700, ToddAndMargo via perl6-users wrote:
>> Hi All!
>>
>> Question: I am using `read` to read the first 400 bytes of an unknown file
>> (could be a binary file).  The 400 bytes go into a variable
>> of type "Buf".  This is not a string.
>>
>> p6 'my $fh=open "/home/linuxutil/To", :r; my Buf $f = $fh.read( 400 );
>> $fh.close;'
>>
>> Now in $f, I want to look at each byte one at a time for a
>> bitwise pattern using bitwise AND.
>>
>> How do I address each byte?
>>
>> `dd` seems to get me the information I need, but it prints it:
>>
>>      $ p6 'my $fh=open "/home/linuxutil/To", :r; my Buf $f = $fh.read( 10 );
>> $fh.close; dd $f;'
>>
>>      Buf[uint8] $f = Buf[uint8].new(87,111,114,100,80,114,111,0,0,0)
>>
>> An array of bytes would be great.
> 
> Point a browser at https://docs.perl6.org/ and click on "Types" in
> the top ribbon.  You will see a list of all the Perl 6 built-in types;
> "Buf" is there near the top.  Click on "Buf".

Been there, done that already.  No idea what it said.
> 
> Now there are two clues as to what you want: one of them is that
> the table of contents on the left has a section "Routines supplied by
> role Positional", and the other one is that the very first example
> has a line saying "$b[1] = 42".
> 
> So you can use a Buf object as an array of whatever it contains.
> 
> G'luck,
> Peter
> 

Hi Peter,

Perfect!  Exactly what I was after!

Thank you!

$ p6 'my $fh=open "/home/linuxutil/To", :r; my Buf $f = $fh.read( 10 ); 
$fh.close; say $f[1..3]; say $f;'

(111 114 100)

Buf[uint8]:0x<57 6f 72 64 50 72 6f 00 00 00>

-T
0
perl6
10/8/2018 8:38:54 AM
On 10/8/18 1:38 AM, ToddAndMargo via perl6-users wrote:
> On 10/8/18 1:34 AM, Peter Pentchev wrote:
>> On Mon, Oct 08, 2018 at 01:25:31AM -0700, ToddAndMargo via perl6-users=
=20
>> wrote:
>>> Hi All!
>>>
>>> Question: I am using `read` to read the first 400 bytes of an unknown=
=20
>>> file
>>> (could be a binary file).=C2=A0 The 400 bytes go into a variable
>>> of type "Buf".=C2=A0 This is not a string.
>>>
>>> p6 'my $fh=3Dopen "/home/linuxutil/To", :r; my Buf $f =3D $fh.read( 4=
00 );
>>> $fh.close;'
>>>
>>> Now in $f, I want to look at each byte one at a time for a
>>> bitwise pattern using bitwise AND.
>>>
>>> How do I address each byte?
>>>
>>> `dd` seems to get me the information I need, but it prints it:
>>>
>>> =C2=A0=C2=A0=C2=A0=C2=A0 $ p6 'my $fh=3Dopen "/home/linuxutil/To", :r=
; my Buf $f =3D=20
>>> $fh.read( 10 );
>>> $fh.close; dd $f;'
>>>
>>> =C2=A0=C2=A0=C2=A0=C2=A0 Buf[uint8] $f =3D Buf[uint8].new(87,111,114,=
100,80,114,111,0,0,0)
>>>
>>> An array of bytes would be great.
>>
>> Point a browser at https://docs.perl6.org/ and click on "Types" in
>> the top ribbon.=C2=A0 You will see a list of all the Perl 6 built-in t=
ypes;
>> "Buf" is there near the top.=C2=A0 Click on "Buf".
>=20
> Been there, done that already.=C2=A0 No idea what it said.
>>
>> Now there are two clues as to what you want: one of them is that
>> the table of contents on the left has a section "Routines supplied by
>> role Positional", and the other one is that the very first example
>> has a line saying "$b[1] =3D 42".
>>
>> So you can use a Buf object as an array of whatever it contains.
>>
>> G'luck,
>> Peter
>>
>=20
> Hi Peter,
>=20
> Perfect!=C2=A0 Exactly what I was after!
>=20
> Thank you!
>=20
> $ p6 'my $fh=3Dopen "/home/linuxutil/To", :r; my Buf $f =3D $fh.read( 1=
0 );=20
> $fh.close; say $f[1..3]; say $f;'
>=20
> (111 114 100)
>=20
> Buf[uint8]:0x<57 6f 72 64 50 72 6f 00 00 00>
>=20
> -T


Better looking example:

$ p6 'my $fh=3Dopen "/home/linuxutil/To", :r; my Buf $f =3D $fh.read( 10 =
);=20
$fh.close; say $f[1..3]; dd $f;'

(111 114 100)
Buf[uint8] $f =3D Buf[uint8].new(87,111,114,100,80,114,111,0,0,0)
0
perl6
10/8/2018 8:46:13 AM
--VUDLurXRWRKrGuMn
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Mon, Oct 08, 2018 at 01:38:54AM -0700, ToddAndMargo via perl6-users wrot=
e:
> On 10/8/18 1:34 AM, Peter Pentchev wrote:
> > On Mon, Oct 08, 2018 at 01:25:31AM -0700, ToddAndMargo via perl6-users =
wrote:
> > > Hi All!
> > >=20
> > > Question: I am using `read` to read the first 400 bytes of an unknown=
 file
> > > (could be a binary file).  The 400 bytes go into a variable
> > > of type "Buf".  This is not a string.
> > >=20
> > > p6 'my $fh=3Dopen "/home/linuxutil/To", :r; my Buf $f =3D $fh.read( 4=
00 );
> > > $fh.close;'
> > >=20
> > > Now in $f, I want to look at each byte one at a time for a
> > > bitwise pattern using bitwise AND.
> > >=20
> > > How do I address each byte?
> > >=20
> > > `dd` seems to get me the information I need, but it prints it:
> > >=20
> > >      $ p6 'my $fh=3Dopen "/home/linuxutil/To", :r; my Buf $f =3D $fh.=
read( 10 );
> > > $fh.close; dd $f;'
> > >=20
> > >      Buf[uint8] $f =3D Buf[uint8].new(87,111,114,100,80,114,111,0,0,0)
> > >=20
> > > An array of bytes would be great.
> >=20
> > Point a browser at https://docs.perl6.org/ and click on "Types" in
> > the top ribbon.  You will see a list of all the Perl 6 built-in types;
> > "Buf" is there near the top.  Click on "Buf".
>=20
> Been there, done that already.  No idea what it said.

OK, so for future reference, when you see a reference page for a type
like that, look at the left side to see which roles it implements and
which methods it takes from these roles.  As I wrote below, in this case
the Positional role could have been a clue that you can address a Buf
object using [index] (I seem to remember another thread of yours with
people explaining the Positional role).

Also, in the future, take a look at the code in the examples; in this
particular case, the use of "$b[1]" could have been a hint.

> > Now there are two clues as to what you want: one of them is that
> > the table of contents on the left has a section "Routines supplied by
> > role Positional", and the other one is that the very first example
> > has a line saying "$b[1] =3D 42".
> >=20
> > So you can use a Buf object as an array of whatever it contains.
> >=20
> > G'luck,
> > Peter
> >=20
>=20
> Hi Peter,
>=20
> Perfect!  Exactly what I was after!

Glad it worked out for you!

G'luck,
Peter

--=20
Peter Pentchev  roam@{ringlet.net,debian.org,FreeBSD.org} pp@storpool.com
PGP key:        http://people.FreeBSD.org/~roam/roam.key.asc
Key fingerprint 2EE7 A7A5 17FC 124C F115  C354 651E EFB0 2527 DF13

--VUDLurXRWRKrGuMn
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQIzBAABCAAdFiEELuenpRf8EkzxFcNUZR7vsCUn3xMFAlu7GVcACgkQZR7vsCUn
3xMCHg/+LltQJe8WoeQspWH0ocM5YybL2p2vn2VnbsvIaOFi0ejO9afWjsU7T9Kr
WIW1XWmP9SiZ4O8l+Ml8hE5ImE4ZguFaa/79zk0SBQ0k0GNbhB+MDuwDTj8dbyDp
BRJ09lWr6Vbux/MgMzUTOO8oyGv8Ioxqm6uy+8V3R+A/Qj6rXFN8t4Ef1ICMJ0QQ
dPNw7VYYI+EyCWIqAaY+/8w7OBf8y92w3fx+dQL+1VoD1Hyo5dfQ83XKBFKi2xP5
EYel9Os83i3mfCuFRA/+dUJU0pGHkEszizph2zidwOBvo+iUQnRPtaq72I+PZwai
Ajo2S3+5qo8H+tX4M6I1w2XR0vlSxXlQ+tWHBtLtPPG/9gQEAN6py30UQAyAu+GG
nUAfAxZww2ZwHehgFsXVSV609bqJU70NmO8495nT25DD0fqqO0n/WRuP8UoZjz0r
4PTZsCaX48TJmPi9jI2K1QpHDe25NWjYcVzACptqppm5qhguqRRrscAtqazRxAcM
dkM4O6QAhWdqfFkF4bQroC5VsalGqtvmb8ETZj1/8qcvolpaxQeHBJ1aB0nyMHFP
XEMF0/jxXHPlOCVG+QbLjUBhB0RS6m0VTSy+kynp6NpNsTqDoj/7JQXZ3Yasmt2O
kCdNV7UnROGek5a4Hg0GoswlCORfWdeEjzGc0iLjFFa7QbwpsZ8=
=jIXg
-----END PGP SIGNATURE-----

--VUDLurXRWRKrGuMn--
0
roam
10/8/2018 8:46:15 AM
On 10/8/18 1:46 AM, Peter Pentchev wrote:
> On Mon, Oct 08, 2018 at 01:38:54AM -0700, ToddAndMargo via perl6-users wrote:
>> On 10/8/18 1:34 AM, Peter Pentchev wrote:
>>> On Mon, Oct 08, 2018 at 01:25:31AM -0700, ToddAndMargo via perl6-users wrote:
>>>> Hi All!
>>>>
>>>> Question: I am using `read` to read the first 400 bytes of an unknown file
>>>> (could be a binary file).  The 400 bytes go into a variable
>>>> of type "Buf".  This is not a string.
>>>>
>>>> p6 'my $fh=open "/home/linuxutil/To", :r; my Buf $f = $fh.read( 400 );
>>>> $fh.close;'
>>>>
>>>> Now in $f, I want to look at each byte one at a time for a
>>>> bitwise pattern using bitwise AND.
>>>>
>>>> How do I address each byte?
>>>>
>>>> `dd` seems to get me the information I need, but it prints it:
>>>>
>>>>       $ p6 'my $fh=open "/home/linuxutil/To", :r; my Buf $f = $fh.read( 10 );
>>>> $fh.close; dd $f;'
>>>>
>>>>       Buf[uint8] $f = Buf[uint8].new(87,111,114,100,80,114,111,0,0,0)
>>>>
>>>> An array of bytes would be great.
>>>
>>> Point a browser at https://docs.perl6.org/ and click on "Types" in
>>> the top ribbon.  You will see a list of all the Perl 6 built-in types;
>>> "Buf" is there near the top.  Click on "Buf".
>>
>> Been there, done that already.  No idea what it said.
> 
> OK, so for future reference, when you see a reference page for a type
> like that, look at the left side to see which roles it implements and
> which methods it takes from these roles.  As I wrote below, in this case
> the Positional role could have been a clue that you can address a Buf
> object using [index] (I seem to remember another thread of yours with
> people explaining the Positional role).
> 
> Also, in the future, take a look at the code in the examples; in this
> particular case, the use of "$b[1]" could have been a hint.
> 
>>> Now there are two clues as to what you want: one of them is that
>>> the table of contents on the left has a section "Routines supplied by
>>> role Positional", and the other one is that the very first example
>>> has a line saying "$b[1] = 42".

When I first looked at it, I was trying to convert it
into a latin-1 string.  So I skipped over it looking
for Stringy or Str or something similar.

When I posted this, I changed my thinking to "why do I want
it in a string?"  I just want an array of bytes.  Had I
looked again, "$b[1] = 42" would have made total sense.


>>> So you can use a Buf object as an array of whatever it contains.
>>>
>>> G'luck,
>>> Peter
>>>
>>
>> Hi Peter,
>>
>> Perfect!  Exactly what I was after!
> 
> Glad it worked out for you!
> 
> G'luck,
> Peter

Thank you for helping me with this.  I can be thick at times.

-T
0
perl6
10/8/2018 11:09:25 AM
Reply: