packing a C structure

packing a C structure

am 26.10.2007 06:57:55 von haairam

hi ,,,

iam trying to pack a C structure to send via socket..i would like to
know how to frame the template for the C structure..

this is my structure

typedef struct buffer_t {
uint32_t a;
char b[16];
uint32_t c;
uint32_t d;
char e[6];
char f[8];
} buffer_t;

kindly suggest me the format for the pack function call..this will
help me to solve my issue...

Re: packing a C structure

am 26.10.2007 09:06:07 von Josef Moellers

haairam@gmail.com wrote:
> hi ,,,
>=20
> iam trying to pack a C structure to send via socket..i would like to
> know how to frame the template for the C structure..
>=20
> this is my structure
>=20
> typedef struct buffer_t {
> uint32_t a;
> char b[16];
> uint32_t c;
> uint32_t d;
> char e[6];
> char f[8];
> } buffer_t;
>=20
> kindly suggest me the format for the pack function call..this will
> help me to solve my issue...
>=20

Transferring binary structures is inherently non-portable, so there is=20
not a single way to deduce the actual binary layout of this structure,=20
as the alignment and even the format of the binary numbers (e.g.=20
endianness) will vary from machine type to machine type and even between =

compilers. It might even be impossible to transfer the data if the=20
receiving machine is unable to handle 32 bit data, but I guess that's=20
less of a problem.
That's why techniques like ASN.1 were developed.

If the amount of data is relatively small and you can live with some=20
time spent in conversion, a simple (and more portable (*)) means to=20
transfer this data is to transform it into ascii, with suitable=20
separators, e.g. commas or colons, terminated by a line feed.

(*) Sheesh, I sure hope Scott Nudds doesn't read this ;-) It's "more"=20
portable because you have removed alignment and endianness problems,=20
there's still a portability issue in that the receiving machine might=20
speak EBCDIC while the sending machine speaks ASCII.
--=20
These are my personal views and not those of Fujitsu Siemens Computers!
Josef Möllers (Pinguinpfleger bei FSC)
If failure had no penalty success would not be a prize (T. Pratchett)
Company Details: http://www.fujitsu-siemens.com/imprint.html

Re: packing a C structure

am 26.10.2007 09:23:37 von haairam

On Oct 26, 12:06 pm, Josef Moellers siemens.com> wrote:
> haai...@gmail.com wrote:
> > hi ,,,
>
> > iam trying to pack a C structure to send via socket..i would like to
> > know how to frame the template for the C structure..
>
> > this is my structure
>
> > typedef struct buffer_t {
> > uint32_t a;
> > char b[16];
> > uint32_t c;
> > uint32_t d;
> > char e[6];
> > char f[8];
> > } buffer_t;
>
> > kindly suggest me the format for the pack function call..this will
> > help me to solve my issue...
>
> Transferring binary structures is inherently non-portable, so there is
> not a single way to deduce the actual binary layout of this structure,
> as the alignment and even the format of the binary numbers (e.g.
> endianness) will vary from machine type to machine type and even between
> compilers. It might even be impossible to transfer the data if the
> receiving machine is unable to handle 32 bit data, but I guess that's
> less of a problem.
> That's why techniques like ASN.1 were developed.
>
> If the amount of data is relatively small and you can live with some
> time spent in conversion, a simple (and more portable (*)) means to
> transfer this data is to transform it into ascii, with suitable
> separators, e.g. commas or colons, terminated by a line feed.
>
> (*) Sheesh, I sure hope Scott Nudds doesn't read this ;-) It's "more"
> portable because you have removed alignment and endianness problems,
> there's still a portability issue in that the receiving machine might
> speak EBCDIC while the sending machine speaks ASCII.
> --
> These are my personal views and not those of Fujitsu Siemens Computers!
> Josef Möllers (Pinguinpfleger bei FSC)
> If failure had no penalty success would not be a prize (T. Pratc=
hett)
> Company Details:http://www.fujitsu-siemens.com/imprint.html- Hide quoted =
text -
>
> - Show quoted text -

hi Mollers,,
Thanks for the reply.iam an beginner in perl ..still not clear how to
convert the structure into an asciii string...i was stuck with this
issue for past 2 weeks..kindly throw some guidelines for this...

regards
Rams

Re: packing a C structure

am 26.10.2007 10:18:48 von Josef Moellers

rams wrote:
> On Oct 26, 12:06 pm, Josef Moellers > siemens.com> wrote:
>=20
>>haai...@gmail.com wrote:
>>
>>>hi ,,,
>>
>>>iam trying to pack a C structure to send via socket..i would like to
>>>know how to frame the template for the C structure..
>>
>>>this is my structure
>>
>>>typedef struct buffer_t {
>>> uint32_t a;
>>> char b[16];
>>> uint32_t c;
>>> uint32_t d;
>>> char e[6];
>>> char f[8];
>>>} buffer_t;
>>
>>>kindly suggest me the format for the pack function call..this will
>>>help me to solve my issue...
>>
>>Transferring binary structures is inherently non-portable, so there is
>>not a single way to deduce the actual binary layout of this structure,
>>as the alignment and even the format of the binary numbers (e.g.
>>endianness) will vary from machine type to machine type and even betwee=
n
>>compilers. It might even be impossible to transfer the data if the
>>receiving machine is unable to handle 32 bit data, but I guess that's
>>less of a problem.
>>That's why techniques like ASN.1 were developed.
>>
>>If the amount of data is relatively small and you can live with some
>>time spent in conversion, a simple (and more portable (*)) means to
>>transfer this data is to transform it into ascii, with suitable
>>separators, e.g. commas or colons, terminated by a line feed.
>>
>>(*) Sheesh, I sure hope Scott Nudds doesn't read this ;-) It's "more"
>>portable because you have removed alignment and endianness problems,
>>there's still a portability issue in that the receiving machine might
>>speak EBCDIC while the sending machine speaks ASCII.
>>--
>>These are my personal views and not those of Fujitsu Siemens Computers!=

>>Josef Möllers (Pinguinpfleger bei FSC)
>> If failure had no penalty success would not be a prize (T. Pra=
tchett)
>>Company Details:http://www.fujitsu-siemens.com/imprint.html- Hide quote=
d text -
>>
>>- Show quoted text -
>=20
>=20
> hi Mollers,,

No offence, but my first name is "Josef". (We have these problems=20
ourselves with people from e.g. Japan ;-)

> Thanks for the reply.iam an beginner in perl ..still not clear how to
> convert the structure into an asciii string...i was stuck with this
> issue for past 2 weeks..kindly throw some guidelines for this...

As usual, TMTOWTDI:

if you have the socket open, e.g. in $sock, just do

*** Sender ***
my $data =3D join(':', $a, @b, $c, $d, @e, @f);
print $sock $data, "\n";

*** Receiver ***
my $data =3D <$sock>;
chomp $data;
my @data =3D split(/:/, $data);
$a =3D $data[0];
@b =3D @data[1..16];
$c =3D $data[17];
$d =3D $data[18];
@e =3D @data[19..24];
@f =3D @data[25..32];

You could also use some kind of tagging:

*** Sender ***
print $sock "a=3D$a\n";
foreach (0..15) {
print $sock "b$_=3D$b[$_]\n";
}
..
print $sock "\n";

*** Receiver ***

while (<$sock>) {
if (/^a=3D(\d+)/) {
$a =3D $1;
} elsif (/^b(\d+)?(\d+)/) {
$b[$1] =3D $2;
} ... {
} elsif (/^\s+$/) {
last;
}
}

Maybe XML could be used.

You may also want to have a look at pack/unpack. They have data types=20
which are pretty well defined (e.g. L is an unsigned long of exactly 32=20
bits).

It's all a matter of
1. what you feel comfortable to use
2. what is most stable
3. what is best maintainable
4. what is fast
5. what takes little space

Obviously others will have more elegant solutions.

Josef
--=20
These are my personal views and not those of Fujitsu Siemens Computers!
Josef Möllers (Pinguinpfleger bei FSC)
If failure had no penalty success would not be a prize (T. Pratchett)
Company Details: http://www.fujitsu-siemens.com/imprint.html

Re: packing a C structure

am 26.10.2007 10:49:14 von haairam

On Oct 26, 1:18 pm, Josef Moellers siemens.com> wrote:
> rams wrote:
> > On Oct 26, 12:06 pm, Josef Moellers > > siemens.com> wrote:
>
> >>haai...@gmail.com wrote:
>
> >>>hi ,,,
>
> >>>iam trying to pack a C structure to send via socket..i would like to
> >>>know how to frame the template for the C structure..
>
> >>>this is my structure
>
> >>>typedef struct buffer_t {
> >>> uint32_t a;
> >>> char b[16];
> >>> uint32_t c;
> >>> uint32_t d;
> >>> char e[6];
> >>> char f[8];
> >>>} buffer_t;
>
> >>>kindly suggest me the format for the pack function call..this will
> >>>help me to solve my issue...
>
> >>Transferring binary structures is inherently non-portable, so there is
> >>not a single way to deduce the actual binary layout of this structure,
> >>as the alignment and even the format of the binary numbers (e.g.
> >>endianness) will vary from machine type to machine type and even between
> >>compilers. It might even be impossible to transfer the data if the
> >>receiving machine is unable to handle 32 bit data, but I guess that's
> >>less of a problem.
> >>That's why techniques like ASN.1 were developed.
>
> >>If the amount of data is relatively small and you can live with some
> >>time spent in conversion, a simple (and more portable (*)) means to
> >>transfer this data is to transform it into ascii, with suitable
> >>separators, e.g. commas or colons, terminated by a line feed.
>
> >>(*) Sheesh, I sure hope Scott Nudds doesn't read this ;-) It's "more"
> >>portable because you have removed alignment and endianness problems,
> >>there's still a portability issue in that the receiving machine might
> >>speak EBCDIC while the sending machine speaks ASCII.
> >>--
> >>These are my personal views and not those of Fujitsu Siemens Computers!
> >>Josef Möllers (Pinguinpfleger bei FSC)
> >> If failure had no penalty success would not be a prize (T. Pra=
tchett)
> >>Company Details:http://www.fujitsu-siemens.com/imprint.html-Hide quoted=
text -
>
> >>- Show quoted text -
>
> > hi Mollers,,
>
> No offence, but my first name is "Josef". (We have these problems
> ourselves with people from e.g. Japan ;-)
>
> > Thanks for the reply.iam an beginner in perl ..still not clear how to
> > convert the structure into an asciii string...i was stuck with this
> > issue for past 2 weeks..kindly throw some guidelines for this...
>
> As usual, TMTOWTDI:
>
> if you have the socket open, e.g. in $sock, just do
>
> *** Sender ***
> my $data =3D join(':', $a, @b, $c, $d, @e, @f);
> print $sock $data, "\n";
>
> *** Receiver ***
> my $data =3D <$sock>;
> chomp $data;
> my @data =3D split(/:/, $data);
> $a =3D $data[0];
> @b =3D @data[1..16];
> $c =3D $data[17];
> $d =3D $data[18];
> @e =3D @data[19..24];
> @f =3D @data[25..32];
>
> You could also use some kind of tagging:
>
> *** Sender ***
> print $sock "a=3D$a\n";
> foreach (0..15) {
> print $sock "b$_=3D$b[$_]\n";}
>
> ...
> print $sock "\n";
>
> *** Receiver ***
>
> while (<$sock>) {
> if (/^a=3D(\d+)/) {
> $a =3D $1;
> } elsif (/^b(\d+)?(\d+)/) {
> $b[$1] =3D $2;
> } ... {
> } elsif (/^\s+$/) {
> last;
> }
>
> }
>
> Maybe XML could be used.
>
> You may also want to have a look at pack/unpack. They have data types
> which are pretty well defined (e.g. L is an unsigned long of exactly 32
> bits).
>
> It's all a matter of
> 1. what you feel comfortable to use
> 2. what is most stable
> 3. what is best maintainable
> 4. what is fast
> 5. what takes little space
>
> Obviously others will have more elegant solutions.
>
> Josef
> --
> These are my personal views and not those of Fujitsu Siemens Computers!
> Josef Möllers (Pinguinpfleger bei FSC)
> If failure had no penalty success would not be a prize (T. Pratc=
hett)
> Company Details:http://www.fujitsu-siemens.com/imprint.html- Hide quoted =
text -
>
> - Show quoted text -

hi josef,,

sorry for the mis interpretation of ur name....here my problem is i
cannot modify reciever code...reciever is a C code expecting data in
binary mode....so that is 1 of the reason i would like to do pack...i
saw that pack is used for sending binary data...i dont know how to
combine all the five elements in structure into a single variable
using pack command..

thanks & Regards
Rams

Re: packing a C structure

am 26.10.2007 10:56:20 von haairam

On Oct 26, 1:18 pm, Josef Moellers siemens.com> wrote:
> rams wrote:
> > On Oct 26, 12:06 pm, Josef Moellers > > siemens.com> wrote:
>
> >>haai...@gmail.com wrote:
>
> >>>hi ,,,
>
> >>>iam trying to pack a C structure to send via socket..i would like to
> >>>know how to frame the template for the C structure..
>
> >>>this is my structure
>
> >>>typedef struct buffer_t {
> >>> uint32_t a;
> >>> char b[16];
> >>> uint32_t c;
> >>> uint32_t d;
> >>> char e[6];
> >>> char f[8];
> >>>} buffer_t;
>
> >>>kindly suggest me the format for the pack function call..this will
> >>>help me to solve my issue...
>
> >>Transferring binary structures is inherently non-portable, so there is
> >>not a single way to deduce the actual binary layout of this structure,
> >>as the alignment and even the format of the binary numbers (e.g.
> >>endianness) will vary from machine type to machine type and even between
> >>compilers. It might even be impossible to transfer the data if the
> >>receiving machine is unable to handle 32 bit data, but I guess that's
> >>less of a problem.
> >>That's why techniques like ASN.1 were developed.
>
> >>If the amount of data is relatively small and you can live with some
> >>time spent in conversion, a simple (and more portable (*)) means to
> >>transfer this data is to transform it into ascii, with suitable
> >>separators, e.g. commas or colons, terminated by a line feed.
>
> >>(*) Sheesh, I sure hope Scott Nudds doesn't read this ;-) It's "more"
> >>portable because you have removed alignment and endianness problems,
> >>there's still a portability issue in that the receiving machine might
> >>speak EBCDIC while the sending machine speaks ASCII.
> >>--
> >>These are my personal views and not those of Fujitsu Siemens Computers!
> >>Josef Möllers (Pinguinpfleger bei FSC)
> >> If failure had no penalty success would not be a prize (T. Pra=
tchett)
> >>Company Details:http://www.fujitsu-siemens.com/imprint.html-Hide quoted=
text -
>
> >>- Show quoted text -
>
> > hi Mollers,,
>
> No offence, but my first name is "Josef". (We have these problems
> ourselves with people from e.g. Japan ;-)
>
> > Thanks for the reply.iam an beginner in perl ..still not clear how to
> > convert the structure into an asciii string...i was stuck with this
> > issue for past 2 weeks..kindly throw some guidelines for this...
>
> As usual, TMTOWTDI:
>
> if you have the socket open, e.g. in $sock, just do
>
> *** Sender ***
> my $data =3D join(':', $a, @b, $c, $d, @e, @f);
> print $sock $data, "\n";
>
> *** Receiver ***
> my $data =3D <$sock>;
> chomp $data;
> my @data =3D split(/:/, $data);
> $a =3D $data[0];
> @b =3D @data[1..16];
> $c =3D $data[17];
> $d =3D $data[18];
> @e =3D @data[19..24];
> @f =3D @data[25..32];
>
> You could also use some kind of tagging:
>
> *** Sender ***
> print $sock "a=3D$a\n";
> foreach (0..15) {
> print $sock "b$_=3D$b[$_]\n";}
>
> ...
> print $sock "\n";
>
> *** Receiver ***
>
> while (<$sock>) {
> if (/^a=3D(\d+)/) {
> $a =3D $1;
> } elsif (/^b(\d+)?(\d+)/) {
> $b[$1] =3D $2;
> } ... {
> } elsif (/^\s+$/) {
> last;
> }
>
> }
>
> Maybe XML could be used.
>
> You may also want to have a look at pack/unpack. They have data types
> which are pretty well defined (e.g. L is an unsigned long of exactly 32
> bits).
>
> It's all a matter of
> 1. what you feel comfortable to use
> 2. what is most stable
> 3. what is best maintainable
> 4. what is fast
> 5. what takes little space
>
> Obviously others will have more elegant solutions.
>
> Josef
> --
> These are my personal views and not those of Fujitsu Siemens Computers!
> Josef Möllers (Pinguinpfleger bei FSC)
> If failure had no penalty success would not be a prize (T. Pratc=
hett)
> Company Details:http://www.fujitsu-siemens.com/imprint.html- Hide quoted =
text -
>
> - Show quoted text -

hi josef,,

sorry for the mis interpretation of your name....
actually the problem for me is i will not be able to modify the
reciever part...and the reciever part is a C code interpreting data in
binary mode....so i saw that pack functionality is used to send data
in binary format...the problem is iam not able to combine all the
elements in the structure into a single variable using the pack
format.... L is for long and but how to combine all those elements?..

Thanks & regards
Rams

Re: packing a C structure

am 26.10.2007 11:29:00 von Josef Moellers

rams wrote:
> On Oct 26, 1:18 pm, Josef Moellers > siemens.com> wrote:
>=20
>>rams wrote:
>>
>>>On Oct 26, 12:06 pm, Josef Moellers >>>siemens.com> wrote:
>>
>>>>haai...@gmail.com wrote:
>>
>>>>>hi ,,,
>>
>>>>>iam trying to pack a C structure to send via socket..i would like to=

>>>>>know how to frame the template for the C structure..
>>
>>>>>this is my structure
>>
>>>>>typedef struct buffer_t {
>>>>> uint32_t a;
>>>>> char b[16];
>>>>> uint32_t c;
>>>>> uint32_t d;
>>>>> char e[6];
>>>>> char f[8];
>>>>>} buffer_t;
>>
>>>>>kindly suggest me the format for the pack function call..this will
>>>>>help me to solve my issue...
>>
>>>>Transferring binary structures is inherently non-portable, so there i=
s
>>>>not a single way to deduce the actual binary layout of this structure=
,
>>>>as the alignment and even the format of the binary numbers (e.g.
>>>>endianness) will vary from machine type to machine type and even betw=
een
>>>>compilers. It might even be impossible to transfer the data if the
>>>>receiving machine is unable to handle 32 bit data, but I guess that's=

>>>>less of a problem.
>>>>That's why techniques like ASN.1 were developed.
>>
>>>>If the amount of data is relatively small and you can live with some
>>>>time spent in conversion, a simple (and more portable (*)) means to
>>>>transfer this data is to transform it into ascii, with suitable
>>>>separators, e.g. commas or colons, terminated by a line feed.
>>
>>>>(*) Sheesh, I sure hope Scott Nudds doesn't read this ;-) It's "more"=

>>>>portable because you have removed alignment and endianness problems,
>>>>there's still a portability issue in that the receiving machine might=

>>>>speak EBCDIC while the sending machine speaks ASCII.
>>>>--
>>>>These are my personal views and not those of Fujitsu Siemens Computer=
s!
>>>>Josef Möllers (Pinguinpfleger bei FSC)
>>>> If failure had no penalty success would not be a prize (T. Pr=
atchett)
>>>>Company Details:http://www.fujitsu-siemens.com/imprint.html-Hide quot=
ed text -
>>
>>>>- Show quoted text -
>>
>>>hi Mollers,,
>>
>>No offence, but my first name is "Josef". (We have these problems
>>ourselves with people from e.g. Japan ;-)
>>
>>
>>>Thanks for the reply.iam an beginner in perl ..still not clear how to
>>>convert the structure into an asciii string...i was stuck with this
>>>issue for past 2 weeks..kindly throw some guidelines for this...
>>
>>As usual, TMTOWTDI:
>>
>>if you have the socket open, e.g. in $sock, just do
>>
>>*** Sender ***
>>my $data =3D join(':', $a, @b, $c, $d, @e, @f);
>>print $sock $data, "\n";
>>
>>*** Receiver ***
>>my $data =3D <$sock>;
>>chomp $data;
>>my @data =3D split(/:/, $data);
>>$a =3D $data[0];
>>@b =3D @data[1..16];
>>$c =3D $data[17];
>>$d =3D $data[18];
>>@e =3D @data[19..24];
>>@f =3D @data[25..32];
>>
>>You could also use some kind of tagging:
>>
>>*** Sender ***
>>print $sock "a=3D$a\n";
>>foreach (0..15) {
>> print $sock "b$_=3D$b[$_]\n";}
>>
>>...
>>print $sock "\n";
>>
>>*** Receiver ***
>>
>>while (<$sock>) {
>> if (/^a=3D(\d+)/) {
>> $a =3D $1;
>> } elsif (/^b(\d+)?(\d+)/) {
>> $b[$1] =3D $2;
>> } ... {
>> } elsif (/^\s+$/) {
>> last;
>> }
>>
>>}
>>
>>Maybe XML could be used.
>>
>>You may also want to have a look at pack/unpack. They have data types
>>which are pretty well defined (e.g. L is an unsigned long of exactly 32=

>>bits).
>>
>>It's all a matter of
>>1. what you feel comfortable to use
>>2. what is most stable
>>3. what is best maintainable
>>4. what is fast
>>5. what takes little space
>>
>>Obviously others will have more elegant solutions.
>>
>>Josef
>>--
>>These are my personal views and not those of Fujitsu Siemens Computers!=

>>Josef Möllers (Pinguinpfleger bei FSC)
>> If failure had no penalty success would not be a prize (T. Pra=
tchett)
>>Company Details:http://www.fujitsu-siemens.com/imprint.html- Hide quote=
d text -
>>
>>- Show quoted text -
>=20
>=20
> hi josef,,
>=20
> sorry for the mis interpretation of ur name

No problem, as I said. (BTW it's "your", "ur" is kiddie-talk)

...here my problem is i
> cannot modify reciever code...reciever is a C code expecting data in
> binary mode....so that is 1 of the reason i would like to do pack...i
> saw that pack is used for sending binary data...i dont know how to
> combine all the five elements in structure into a single variable
> using pack command..

Ah, OK, I see. Then "pack" is your friend.
But, as I have written, you have to find out the receiving side's=20
endianness and alignment restrictions.
Usually data items have to be aligned on boundaries that are a multiple=20
of their own size, but since b is 16 bytes (which is a multiple of 4,=20
c's size), and e and f are char arrays, the following should do:

# make sure @b is of the correct size
die "Bad size of \@b\n" unless @b == 16;
# same for @e and @f ...
print $sock pack('LC16LLC6C8', $a, @b, $c, $d, @e, @f);

Note that you could combine 'LL' into 'L2' and 'C6C8' into 'C14', but I=20
find this more descriptive.

HTH,
--=20
These are my personal views and not those of Fujitsu Siemens Computers!
Josef Möllers (Pinguinpfleger bei FSC)
If failure had no penalty success would not be a prize (T. Pratchett)
Company Details: http://www.fujitsu-siemens.com/imprint.html

Re: packing a C structure

am 26.10.2007 18:09:36 von gbacon

In article <1193374675.362127.274760@i38g2000prf.googlegroups.com>,
wrote:

: iam trying to pack a C structure to send via socket..i would like to
: know how to frame the template for the C structure.. [...]

Is another program sending the data currently? If so, how are you
doing it?

Consider writing an extension, such as the one in the shell archive
below.

Enjoy,
Greg

#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.7).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `#!/bin/sh' line above, then type `sh FILE'.
#
lock_dir=_sh03320
# Made on 2007-10-26 11:05 CDT
# Source directory was `/tmp'.
#
# Existing files will *not* be overwritten, unless `-c' is specified.
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 277 -rw-r--r-- MyData/lib/MyData.pm
# 766 -rw-r--r-- MyData/Makefile.PL
# 56 -rw-r--r-- MyData/MANIFEST
# 947 -rw-r--r-- MyData/MyData.xs
# 977 -rw-r--r-- MyData/t/MyData.t
#
MD5SUM=${MD5SUM-md5sum}
f=`${MD5SUM} --version | egrep '^md5sum .*(core|text)utils'`
test -n "${f}" && md5check=true || md5check=false
${md5check} || \
echo 'Note: not verifying md5sums. Consider installing GNU coreutils.'
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=FAILED
locale_dir=FAILED
first_param="$1"
for dir in $PATH
do
if test "$gettext_dir" = FAILED && test -f $dir/gettext \
&& ($dir/gettext --version >/dev/null 2>&1)
then
case `$dir/gettext --version 2>&1 | sed 1q` in
*GNU*) gettext_dir=$dir ;;
esac
fi
if test "$locale_dir" = FAILED && test -f $dir/shar \
&& ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
then
locale_dir=`$dir/shar --print-text-domain-dir`
fi
done
IFS="$save_IFS"
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
then
echo=echo
else
TEXTDOMAINDIR=$locale_dir
export TEXTDOMAINDIR
TEXTDOMAIN=sharutils
export TEXTDOMAIN
echo="$gettext_dir/gettext -s"
fi
if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null
then if (echo -n test; echo 1,2,3) | grep n >/dev/null
then shar_n= shar_c='
'
else shar_n=-n shar_c= ; fi
else shar_n= shar_c='\c' ; fi
f=shar-touch.$$
st1=200112312359.59
st2=123123592001.59
st2tr=123123592001.5 # old SysV 14-char limit
st3=1231235901

if touch -am -t ${st1} ${f} >/dev/null 2>&1 && \
test ! -f ${st1} && test -f ${f}; then
shar_touch='touch -am -t $1$2$3$4$5$6.$7 "$8"'

elif touch -am ${st2} ${f} >/dev/null 2>&1 && \
test ! -f ${st2} && test ! -f ${st2tr} && test -f ${f}; then
shar_touch='touch -am $3$4$5$6$1$2.$7 "$8"'

elif touch -am ${st3} ${f} >/dev/null 2>&1 && \
test ! -f ${st3} && test -f ${f}; then
shar_touch='touch -am $3$4$5$6$2 "$8"'

else
shar_touch=:
echo
${echo} 'WARNING: not restoring timestamps. Consider getting and'
${echo} 'installing GNU `touch'\'', distributed in GNU coreutils...'
echo
fi
rm -f ${st1} ${st2} ${st2tr} ${st3} ${f}
#
if test ! -d ${lock_dir}
then : ; else ${echo} 'lock directory '${lock_dir}' exists'
exit 1
fi
if mkdir ${lock_dir}
then ${echo} 'x - created lock directory `'${lock_dir}\''.'
else ${echo} 'x - failed to create lock directory `'${lock_dir}\''.'
exit 1
fi
# ============= MyData/lib/MyData.pm ==============
if test ! -d 'MyData'; then
mkdir 'MyData'
if test $? -eq 0
then ${echo} 'x - created directory `MyData'\''.'
else ${echo} 'x - failed to create directory `MyData'\''.'
exit 1
fi
fi
if test ! -d 'MyData/lib'; then
mkdir 'MyData/lib'
if test $? -eq 0
then ${echo} 'x - created directory `MyData/lib'\''.'
else ${echo} 'x - failed to create directory `MyData/lib'\''.'
exit 1
fi
fi
if test -f 'MyData/lib/MyData.pm' && test "$first_param" != -c; then
${echo} 'x -SKIPPING MyData/lib/MyData.pm (file already exists)'
else
${echo} 'x - extracting MyData/lib/MyData.pm (text)'
sed 's/^X//' << 'SHAR_EOF' > 'MyData/lib/MyData.pm' &&
package MyData;
X
use 5.008008;
use strict;
use warnings;
X
require Exporter;
X
our @ISA = qw(Exporter);
X
our @EXPORT = qw(
X pack_buffer_t
X unpack_buffer_t
);
X
our $VERSION = '0.01';
X
require XSLoader;
XXSLoader::load('MyData', $VERSION);
X
# Preloaded methods go here.
X
1;
__END__
SHAR_EOF
(set 20 07 10 26 11 01 57 'MyData/lib/MyData.pm'; eval "$shar_touch") &&
chmod 0644 'MyData/lib/MyData.pm'
if test $? -ne 0
then ${echo} 'restore of MyData/lib/MyData.pm failed'
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'MyData/lib/MyData.pm: MD5 check failed'
) << \SHAR_EOF
33237a8b0ca46928e94e098dede72c2e MyData/lib/MyData.pm
SHAR_EOF
else
test `LC_ALL=C wc -c < 'MyData/lib/MyData.pm'` -ne 277 && \
${echo} 'restoration warning: size of MyData/lib/MyData.pm is not 277'
fi
fi
# ============= MyData/Makefile.PL ==============
if test -f 'MyData/Makefile.PL' && test "$first_param" != -c; then
${echo} 'x -SKIPPING MyData/Makefile.PL (file already exists)'
else
${echo} 'x - extracting MyData/Makefile.PL (text)'
sed 's/^X//' << 'SHAR_EOF' > 'MyData/Makefile.PL' &&
use 5.008008;
use ExtUtils::MakeMaker;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
WriteMakefile(
X NAME => 'MyData',
X VERSION_FROM => 'lib/MyData.pm', # finds $VERSION
X PREREQ_PM => {}, # e.g., Module::Name => 1.1
X ($] >= 5.005 ? ## Add these new keywords supported since 5.005
X (ABSTRACT => 'MyData',
X AUTHOR => 'Greg Bacon') : ()),
X LIBS => [''], # e.g., '-lm'
X DEFINE => '', # e.g., '-DHAVE_SOMETHING'
X INC => '-I.', # e.g., '-I. -I/usr/include/other'
X # Un-comment this if you add C files to link with later:
X # OBJECT => '$(O_FILES)', # link all the C files too
);
SHAR_EOF
(set 20 07 10 26 11 03 27 'MyData/Makefile.PL'; eval "$shar_touch") &&
chmod 0644 'MyData/Makefile.PL'
if test $? -ne 0
then ${echo} 'restore of MyData/Makefile.PL failed'
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'MyData/Makefile.PL: MD5 check failed'
) << \SHAR_EOF
021dcf62e88c7b4494a8ad34da64ee1c MyData/Makefile.PL
SHAR_EOF
else
test `LC_ALL=C wc -c < 'MyData/Makefile.PL'` -ne 766 && \
${echo} 'restoration warning: size of MyData/Makefile.PL is not 766'
fi
fi
# ============= MyData/MANIFEST ==============
if test -f 'MyData/MANIFEST' && test "$first_param" != -c; then
${echo} 'x -SKIPPING MyData/MANIFEST (file already exists)'
else
${echo} 'x - extracting MyData/MANIFEST (text)'
sed 's/^X//' << 'SHAR_EOF' > 'MyData/MANIFEST' &&
Makefile.PL
MANIFEST
MyData.xs
t/MyData.t
lib/MyData.pm
SHAR_EOF
(set 20 07 10 26 10 58 47 'MyData/MANIFEST'; eval "$shar_touch") &&
chmod 0644 'MyData/MANIFEST'
if test $? -ne 0
then ${echo} 'restore of MyData/MANIFEST failed'
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'MyData/MANIFEST: MD5 check failed'
) << \SHAR_EOF
60844f8ab1b71186ccf41401781307b4 MyData/MANIFEST
SHAR_EOF
else
test `LC_ALL=C wc -c < 'MyData/MANIFEST'` -ne 56 && \
${echo} 'restoration warning: size of MyData/MANIFEST is not 56'
fi
fi
# ============= MyData/MyData.xs ==============
if test -f 'MyData/MyData.xs' && test "$first_param" != -c; then
${echo} 'x -SKIPPING MyData/MyData.xs (file already exists)'
else
${echo} 'x - extracting MyData/MyData.xs (text)'
sed 's/^X//' << 'SHAR_EOF' > 'MyData/MyData.xs' &&
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
X
typedef struct buffer_t {
X uint32_t a;
X char b[16];
X uint32_t c;
X uint32_t d;
X char e[6];
X char f[8];
} buffer_t;
X
MODULE = MyData PACKAGE = MyData
X
SV *
pack_buffer_t(a, b, c, d, e, f)
X U32 a
X char *b
X U32 c
X U32 d
X char *e
X char *f
X INIT:
X buffer_t buf;
X CODE:
X buf.a = a;
X Copy(b, buf.b, sizeof buf.b, char);
X buf.c = c;
X buf.d = d;
X Copy(e, buf.e, sizeof buf.e, char);
X Copy(f, buf.f, sizeof buf.f, char);
X ST(0) = sv_2mortal(newSVpv((char *) &buf, sizeof buf));
X
void unpack_buffer_t(in)
X SV *in
X INIT:
X buffer_t *p;
X char *sin;
X STRLEN len;
X PPCODE:
X p = (buffer_t *) SvPV(in, len);
X XPUSHs(sv_2mortal(newSVuv(p->a)));
X XPUSHs(sv_2mortal(newSVpv(p->b, sizeof(p->b))));
X XPUSHs(sv_2mortal(newSVuv(p->c)));
X XPUSHs(sv_2mortal(newSVuv(p->d)));
X XPUSHs(sv_2mortal(newSVpv(p->e, sizeof(p->e))));
X XPUSHs(sv_2mortal(newSVpv(p->f, sizeof(p->f))));
SHAR_EOF
(set 20 07 10 26 11 01 26 'MyData/MyData.xs'; eval "$shar_touch") &&
chmod 0644 'MyData/MyData.xs'
if test $? -ne 0
then ${echo} 'restore of MyData/MyData.xs failed'
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'MyData/MyData.xs: MD5 check failed'
) << \SHAR_EOF
5f51de590db2ddb456aa1d0bcf3b4433 MyData/MyData.xs
SHAR_EOF
else
test `LC_ALL=C wc -c < 'MyData/MyData.xs'` -ne 947 && \
${echo} 'restoration warning: size of MyData/MyData.xs is not 947'
fi
fi
# ============= MyData/t/MyData.t ==============
if test ! -d 'MyData/t'; then
mkdir 'MyData/t'
if test $? -eq 0
then ${echo} 'x - created directory `MyData/t'\''.'
else ${echo} 'x - failed to create directory `MyData/t'\''.'
exit 1
fi
fi
if test -f 'MyData/t/MyData.t' && test "$first_param" != -c; then
${echo} 'x -SKIPPING MyData/t/MyData.t (file already exists)'
else
${echo} 'x - extracting MyData/t/MyData.t (text)'
sed 's/^X//' << 'SHAR_EOF' > 'MyData/t/MyData.t' &&
# Before `make install' is performed this script should be runnable with
# `make test'. After `make install' it should work as `perl MyData.t'
X
#########################
X
use Test::More tests => 9;
BEGIN { use_ok('MyData') };
X
#########################
X
# Insert your test code below, the Test::More module is use()ed here so read
# its man page ( perldoc Test::More ) for help writing this test script.
X
use constant {
X A => 0xdeadbeef,
X B => "0123456789abcdef",
X C => 0xffffffff,
X D => 0xa5a5a5a5,
X E => "123456",
X F => " eight",
};
X
$buf = pack_buffer_t A, B, C, D, E, F;
ok(defined $buf, "defined result from pack_buffer_t");
X
@fields = unpack_buffer_t $buf;
is(scalar(@fields), 6, "fields from unpack_buffer_t");
X
($a,$b,$c,$d,$e,$f) = @fields;
X
ok($a == A, "unpacked a");
ok($b eq B, "unpacked b");
ok($c == C, "unpacked c: got " . sprintf("%08x", $c));
ok($d == D, "unpacked d: got " . sprintf("%08x", $d));
ok($e eq E, "unpacked e");
ok($f eq F, "unpacked f");
SHAR_EOF
(set 20 07 10 26 10 47 31 'MyData/t/MyData.t'; eval "$shar_touch") &&
chmod 0644 'MyData/t/MyData.t'
if test $? -ne 0
then ${echo} 'restore of MyData/t/MyData.t failed'
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'MyData/t/MyData.t: MD5 check failed'
) << \SHAR_EOF
e09c94b9215735e712662458c8a5f95d MyData/t/MyData.t
SHAR_EOF
else
test `LC_ALL=C wc -c < 'MyData/t/MyData.t'` -ne 977 && \
${echo} 'restoration warning: size of MyData/t/MyData.t is not 977'
fi
fi
if rm -fr ${lock_dir}
then ${echo} 'x - removed lock directory `'${lock_dir}\''.'
else ${echo} 'x - failed to remove lock directory `'${lock_dir}\''.'
exit 1
fi
exit 0

--
Human ingenuity, not government, solves the problem of scarcity. The
nations in which poverty is greatest are those that restrain human
ingenuity -- that is, freedom -- and punish initiative.
-- Wendy McElroy

Re: packing a C structure

am 26.10.2007 19:37:05 von jl_post

On Oct 25, 10:57 pm, haai...@gmail.com wrote:
> hi ,,,
>
> iam trying to pack a C structure to send via socket..i would like to
> know how to frame the template for the C structure..
>
> this is my structure
>
> typedef struct buffer_t {
> uint32_t a;
> char b[16];
> uint32_t c;
> uint32_t d;
> char e[6];
> char f[8];
>
> } buffer_t;
>
> kindly suggest me the format for the pack function call..this will
> help me to solve my issue...


Hi,

I have the impression that what you want is to pack values in Perl
into a binary string of data that matches how a C program would do it.

If I'm right, this might work:

my $stringToSend = pack('I c16 I I c6 c8',
);

However, it's quite likely that the C program packs the data in a
way so that they are properly byte-aligned. If that's the case, the
above pack string may not work, and you'd probably have better luck
with the following pack string that inserts padding in the proper
places:

my $stringToSend = pack('I c16 x![I] I I c6 c8 x![I]',
);

Out of curiosity, when you declare b as a char array of 16 elements
is that because you're sending over 16 separate char values, or are
you sending one null-terminated string that can be a maximum of 15
characters long?

If your intention is to use b[16] as a single string (holding a
maximum of 15 characters), you probably want to replace "c16" in the
above pack strings to "Z16" (you may also want to replace "c6" and
"c8" with "Z6" and "Z8"). That way, instead of sending over 33
separate variables (that is, three ints plus 30 characters), you'd be
sending over six separate variables (that is, three ints plus three
strings).

So if it's the case that you want to send over three ints and three
strings, you might use code like this:

my $a = 1;
my $b = "Title of book";
my $c = 3;
my $d = 4;
my $e = "March";
my $f = "Sunday";
my $stringToSend = pack('I Z16 x![I] I I Z6 Z8 x![I]',
$a, $b, $c, $d, $e, $f);

Unfortunately, there's no real way to know what the proper pack
string should be unless you analyze the binary structure that your C
program writes out (or if can find one, reads in). But it's likely
that one of pack strings I gave you (or a variant) will work.

I hope this helps. Perl's pack() function is very powerful and
useful when dealing with C structures written out to disk.

-- Jean-Luc

Re: packing a C structure

am 27.10.2007 17:56:41 von Josef Moellers

jl_post@hotmail.com wrote:
> On Oct 25, 10:57 pm, haai...@gmail.com wrote:
>> hi ,,,
>>
>> iam trying to pack a C structure to send via socket..i would like to
>> know how to frame the template for the C structure..
>>
>> this is my structure
>>
>> typedef struct buffer_t {
>> uint32_t a;
>> char b[16];
>> uint32_t c;
>> uint32_t d;
>> char e[6];
>> char f[8];
>>
>> } buffer_t;
>>
>> kindly suggest me the format for the pack function call..this will
>> help me to solve my issue...
>
>
> Hi,
>
> I have the impression that what you want is to pack values in Perl
> into a binary string of data that matches how a C program would do it.
>
> If I'm right, this might work:
>
> my $stringToSend = pack('I c16 I I c6 c8',
> );
>
> However, it's quite likely that the C program packs the data in a
> way so that they are properly byte-aligned. If that's the case, the
> above pack string may not work, and you'd probably have better luck
> with the following pack string that inserts padding in the proper
> places:
>
> my $stringToSend = pack('I c16 x![I] I I c6 c8 x![I]',
> );
>
> Out of curiosity, when you declare b as a char array of 16 elements
> is that because you're sending over 16 separate char values, or are
> you sending one null-terminated string that can be a maximum of 15
> characters long?
>
> If your intention is to use b[16] as a single string (holding a
> maximum of 15 characters), you probably want to replace "c16" in the
> above pack strings to "Z16" (you may also want to replace "c6" and
> "c8" with "Z6" and "Z8"). That way, instead of sending over 33
> separate variables (that is, three ints plus 30 characters), you'd be
> sending over six separate variables (that is, three ints plus three
> strings).
>
> So if it's the case that you want to send over three ints and three
> strings, you might use code like this:
>
> my $a = 1;
> my $b = "Title of book";
> my $c = 3;
> my $d = 4;
> my $e = "March";
> my $f = "Sunday";
> my $stringToSend = pack('I Z16 x![I] I I Z6 Z8 x![I]',
> $a, $b, $c, $d, $e, $f);

I "is _at_least_ 32 bits wide", so, if the OP is on a 64 bit machine
which has 64 bit "int"s, you're toast!
Better use 'L', which more closely matches "uint32_t".

--
Mails please to josef dot moellers
and I'm on gmx dot de.

Re: packing a C structure

am 28.10.2007 17:50:05 von Mark Clements

haairam@gmail.com wrote:
> hi ,,,
>
> iam trying to pack a C structure to send via socket..i would like to
> know how to frame the template for the C structure..
>
> this is my structure
>
> typedef struct buffer_t {
> uint32_t a;
> char b[16];
> uint32_t c;
> uint32_t d;
> char e[6];
> char f[8];
> } buffer_t;
>
> kindly suggest me the format for the pack function call..this will
> help me to solve my issue...
>

Have you checked out Convert::Binary::C?

http://search.cpan.org/~mhx/Convert-Binary-C-0.68/lib/Conver t/Binary/C.pm

Mark

Re: packing a C structure

am 29.10.2007 12:04:19 von haairam

On Oct 26, 10:37 pm, "jl_p...@hotmail.com"
wrote:
> On Oct 25, 10:57 pm, haai...@gmail.com wrote:
>
>
>
>
>
> > hi ,,,
>
> > iam trying to pack a C structure to send via socket..i would like to
> > know how to frame the template for the C structure..
>
> > this is my structure
>
> > typedef struct buffer_t {
> > uint32_t a;
> > char b[16];
> > uint32_t c;
> > uint32_t d;
> > char e[6];
> > char f[8];
>
> > } buffer_t;
>
> > kindly suggest me the format for the pack function call..this will
> > help me to solve my issue...
>
> Hi,
>
> I have the impression that what you want is to pack values in Perl
> into a binary string of data that matches how a C program would do it.
>
> If I'm right, this might work:
>
> my $stringToSend = pack('I c16 I I c6 c8',
> );
>
> However, it's quite likely that the C program packs the data in a
> way so that they are properly byte-aligned. If that's the case, the
> above pack string may not work, and you'd probably have better luck
> with the following pack string that inserts padding in the proper
> places:
>
> my $stringToSend = pack('I c16 x![I] I I c6 c8 x![I]',
> );
>
> Out of curiosity, when you declare b as a char array of 16 elements
> is that because you're sending over 16 separate char values, or are
> you sending one null-terminated string that can be a maximum of 15
> characters long?
>
> If your intention is to use b[16] as a single string (holding a
> maximum of 15 characters), you probably want to replace "c16" in the
> above pack strings to "Z16" (you may also want to replace "c6" and
> "c8" with "Z6" and "Z8"). That way, instead of sending over 33
> separate variables (that is, three ints plus 30 characters), you'd be
> sending over six separate variables (that is, three ints plus three
> strings).
>
> So if it's the case that you want to send over three ints and three
> strings, you might use code like this:
>
> my $a = 1;
> my $b = "Title of book";
> my $c = 3;
> my $d = 4;
> my $e = "March";
> my $f = "Sunday";
> my $stringToSend = pack('I Z16 x![I] I I Z6 Z8 x![I]',
> $a, $b, $c, $d, $e, $f);
>
> Unfortunately, there's no real way to know what the proper pack
> string should be unless you analyze the binary structure that your C
> program writes out (or if can find one, reads in). But it's likely
> that one of pack strings I gave you (or a variant) will work.
>
> I hope this helps. Perl's pack() function is very powerful and
> useful when dealing with C structures written out to disk.
>
> -- Jean-Luc- Hide quoted text -
>
> - Show quoted text -


hi ,,

Thanks for ur help....when i used the format specified by you i
observed a strange behaviour..i have given $a value as 271 ans i
expect that the data while sending through socket would be 00 00 01 0f
that is hex value(271) 0x010F but what i saw as a output of my socket
is data as 32 37 31...since i tried with L option as well both are
giving the same result.how to send that value as a hex itself..

for a variable $b i need to send 16 characters iam wondering during
packing what will happen to the Null Character of the string.

kindly provide a feedback.
Regards
Rams

Re: packing a C structure

am 29.10.2007 22:40:09 von jl_post

On Oct 29, 5:04 am, rams wrote:
>
> Thanks for ur help....when i used the format specified by you i
> observed a strange behaviour..i have given $a value as 271 ans i
> expect that the data while sending through socket would be 00 00 01 0f
> that is hex value(271) 0x010F but what i saw as a output of my socket
> is data as 32 37 31...since i tried with L option as well both are
> giving the same result.how to send that value as a hex itself..

Okay, if you gave $a a value of 271, then the data you want to send
through the socket would be 00 00 01 0f (hexadecimal) BUT ONLY IF the
data is in big-endian order. If the platforms are little-endian, then
217 would be sent as 0f 01 00 00 (hexadecimal). Just keep this in
mind. (Most platforms I work on are little-endian, so it's good to be
aware of the ordering.)

You said that when you tried sending 271 through the socket, the
socket received the bytes 32 37 31 (hexadecimal) instead of what you
expected of 00 00 01 0f (hexadecimal). Well, the values 32, 37, 31
(hexadecimal) correspond to the values 50, 55, 49 (decimal) which
correspond to the ASCII characters '2', '7', '1'.

It looks like when you packed the value 271 you mistakenly packed
it as a string (with something like "Z*") and not as an integer (with
"I"). Go back into your perl code and make sure that the 271 value is
the first value given after the pack-string in the pack() function,
and that the first character in your pack-string is "I" (and not "Z",
"A", or "a").

> for a variable $b i need to send 16 characters iam wondering during
> packing what will happen to the Null Character of the string.

Are you trying to pack a null-terminated string in the "char b[16]"
field? If so, the "Z16" specifier will be sure to terminate whatever
perl string you give it with a null-byte. For example, if you write:

my $string = pack("Z5", "abcdefgh");

then $string will be set to "abcd\0". (Notice that it doesn't use any
more characters that you told it to (in this case, 5) and that the
resulting string is always null-terminated, even if it means
truncating the original string.)

Whether or not you need that string to be null-terminated when you
send it through the socket depends on the receiving program. If it
needs to be null-terminated, use "Z16". If it doesn't need to be null-
terminated, you might want to use "a16". If it's not a string at all
but rather sixteen different integer values, use "c16". This is just
a guess, but most likely you'll want to use "Z16" (but I'll never be
sure unless I can read how the receiving program handles the data it
gets).

Is is possible to post the hex output of a sample structure that
you are trying to match? (Just one would be good; any more would
probably be too much.) That way a lot of questions can get answered
and I can help you better.

By the way, if you're confused about how to use the pack()
function, you may consider reading the Perl tutorial on "pack" and
"unpack" by typing "perldoc perlpacktut" at the DOS/Unix prompt. (I
found this page after I used pack() and unpack() extensively, and it
still taught me a lot.)

I hope this helps, Rams.

-- Jean-Luc Romano

Re: packing a C structure

am 30.10.2007 02:02:07 von bgeer

rams writes:

>On Oct 26, 10:37 pm, "jl_p...@hotmail.com"
>wrote:
>> On Oct 25, 10:57 pm, haai...@gmail.com wrote:
>>
>> I have the impression that what you want is to pack values in Perl
>> into a binary string of data that matches how a C program would do it.
>>
>> If I'm right, this might work:
>>
>> my $stringToSend = pack('I c16 I I c6 c8',
>> );
>>

Check out "man perlfunc", then use "/" to search followed by " pack "
with the spaces & without the ".

Note especially that if you want to put the resulting binary structure
on a network, that you should consider the difference between I (32
bit int) & N (unsigned long in network order).

On a 32-bit Intel, a long & int are the same size - I don't know why
there isn't a specific template character for "unsigned int in network
order".

Cheers, Bob
--
<> Robert Geer & Donna Tomky | |||| We sure |||| <>
<> bgeer@xmission.com | == == find it == == <>
<> dtomky@xmission.com | == == enchanting == == <>
<> Albuquerque, NM USA | |||| here! |||| <>

Re: packing a C structure

am 30.10.2007 08:12:44 von Ben Morrow

Quoth bgeer :
>
> Check out "man perlfunc", then use "/" to search followed by " pack "
> with the spaces & without the ".

Or use perldoc -f pack .

> Note especially that if you want to put the resulting binary structure
> on a network, that you should consider the difference between I (32
> bit int) & N (unsigned long in network order).
>
> On a 32-bit Intel, a long & int are the same size - I don't know why
> there isn't a specific template character for "unsigned int in network
> order".

n and N are 'unsigned 16-bit in network order' and 'unsigned 32-bit in
network order' respectively. Since they're meant for operations where
you are trying to be portable, a format for 'native int in network
order, whatever size it may be' is not likely to be useful. If you care,
$Config{intsize} will tell you the size of C's 'int' and $Config{ivsize}
will tell you the size of perl's integer variables (which will be
different if your perl was built to use 64 bits on a 32bit arch).

Ben

Re: packing a C structure

am 30.10.2007 11:19:05 von haairam

On Oct 30, 2:40 am, "jl_p...@hotmail.com" wrote:
> On Oct 29, 5:04 am, rams wrote:
>
>
>
> > Thanks for ur help....when i used the format specified by you i
> > observed a strange behaviour..i have given $a value as 271 ans i
> > expect that the data while sending through socket would be 00 00 01 0f
> > that is hex value(271) 0x010F but what i saw as a output of my socket
> > is data as 32 37 31...since i tried with L option as well both are
> > giving the same result.how to send that value as a hex itself..
>
> Okay, if you gave $a a value of 271, then the data you want to send
> through the socket would be 00 00 01 0f (hexadecimal) BUT ONLY IF the
> data is in big-endian order. If the platforms are little-endian, then
> 217 would be sent as 0f 01 00 00 (hexadecimal). Just keep this in
> mind. (Most platforms I work on are little-endian, so it's good to be
> aware of the ordering.)
>
> You said that when you tried sending 271 through the socket, the
> socket received the bytes 32 37 31 (hexadecimal) instead of what you
> expected of 00 00 01 0f (hexadecimal). Well, the values 32, 37, 31
> (hexadecimal) correspond to the values 50, 55, 49 (decimal) which
> correspond to the ASCII characters '2', '7', '1'.
>
> It looks like when you packed the value 271 you mistakenly packed
> it as a string (with something like "Z*") and not as an integer (with
> "I"). Go back into your perl code and make sure that the 271 value is
> the first value given after the pack-string in the pack() function,
> and that the first character in your pack-string is "I" (and not "Z",
> "A", or "a").
>
> > for a variable $b i need to send 16 characters iam wondering during
> > packing what will happen to the Null Character of the string.
>
> Are you trying to pack a null-terminated string in the "char b[16]"
> field? If so, the "Z16" specifier will be sure to terminate whatever
> perl string you give it with a null-byte. For example, if you write:
>
> my $string = pack("Z5", "abcdefgh");
>
> then $string will be set to "abcd\0". (Notice that it doesn't use any
> more characters that you told it to (in this case, 5) and that the
> resulting string is always null-terminated, even if it means
> truncating the original string.)
>
> Whether or not you need that string to be null-terminated when you
> send it through the socket depends on the receiving program. If it
> needs to be null-terminated, use "Z16". If it doesn't need to be null-
> terminated, you might want to use "a16". If it's not a string at all
> but rather sixteen different integer values, use "c16". This is just
> a guess, but most likely you'll want to use "Z16" (but I'll never be
> sure unless I can read how the receiving program handles the data it
> gets).
>
> Is is possible to post the hex output of a sample structure that
> you are trying to match? (Just one would be good; any more would
> probably be too much.) That way a lot of questions can get answered
> and I can help you better.
>
> By the way, if you're confused about how to use the pack()
> function, you may consider reading the Perl tutorial on "pack" and
> "unpack" by typing "perldoc perlpacktut" at the DOS/Unix prompt. (I
> found this page after I used pack() and unpack() extensively, and it
> still taught me a lot.)
>
> I hope this helps, Rams.
>
> -- Jean-Luc Romano

hi Jean ,,

Thanks a lot for your response.The pack command you provided gave me
much needed output.I got this almost done.The only problem right now
iam facing is to convert a variable into a 6 byte hexa value.
i have variable $i=123456789012 then i would like to convert this into
a hexa value 12 34 56 78 90 12
and i would like this hexa value also to pack along with my
structure..

could plz provide me a feedback on the above query

Thanks and Regards
Rams

Re: packing a C structure

am 30.10.2007 17:22:32 von jl_post

On Oct 30, 4:19 am, rams wrote:
>
> Thanks a lot for your response.The pack command you provided gave me
> much needed output.I got this almost done.

You're very welcome. I'm glad I could help.


> The only problem right now
> iam facing is to convert a variable into a 6 byte hexa value.
> i have variable $i=123456789012 then i would like to convert this into
> a hexa value 12 34 56 78 90 12
> and i would like this hexa value also to pack along with my
> structure..

Okay, before you do this, you must realize that $i (or
123456789012) should be a string (surrounded by quotes) and NOT a
number -- otherwise, any leading zeroes (or letters A-F) you had in
your number could be lost or misinterpreted.

So if you had a line like:

my $i = "123456789012"; # notice the "" marks

and you wanted a string with the bytes 12 34 56 78 90 12
(hexadecimal), you should use the "H*" pack-string, like this:

my $string = pack('H*', $i);

Now $string is equal to "\x{12}\x{34}\x{56}\x{78}\x{90}\x{12}".
You can do this to prove it to yourself (remember to use "eq" (and not
"==") when comparing strings) with the following code:

if ($string eq "\x{12}\x{34}\x{56}\x{78}\x{90}\x{12}")
{
print "The strings are equal!\n"
}

The "H*" pack template tells pack() to interpret the variable it
packs as the hexadecimal values of the bytes the final (packed) string
will have.

If that's a confusing explanation for you, consider this unpack()
line:

$i = unpack('H*', $string);

This line reads the $string and returns another string which contains
the $string's values in hexadecimal form. The pack() example,
naturally, does the exact opposite.

If you want (or need) a quick way to check the $string contents
(for debugging purposes), you can use this line of code:

printf "0x%x\n", ord($_) foreach split(//, $string);

This will print out each character's hexadecimal value, one character
at a time. In fact, if $string is indeed what you wanted (that is,
made up of bytes 12 34 56 78 90 12 (hexadecimal)), then this line of
code should give you the following output:

0x12
0x34
0x56
0x78
0x90
0x12

I hope this helps, Rams.

Take care and God bless.

-- Jean-Luc Romano

Re: packing a C structure

am 30.10.2007 18:08:11 von jurgenex

rams wrote:
> iam facing is to convert a variable into a 6 byte hexa value.
> i have variable $i=123456789012 then i would like to convert this into
> a hexa value 12 34 56 78 90 12

Let me rephrase:
You got a string and want to insert a space character between every
other character of that string. Is this correct?

Then you can use the approach described in FAQ "How can I output my numbers
with commas added?", just replace the comma by a space character and a
spacing of 2 instead of 3.

jue