[Canberra-pm] Packing to big endian on old versions of perl

Jacinta Richardson jarich at perltraining.com.au
Fri May 1 17:05:00 PDT 2009


I originally only sent this to Paul (oops!).  Turns out that the module 
I suggest at the end (Convert::IBM390) might be the sought-after solution.

I still think there's a way of using layers/encoding to solve this, so 
I'll poke Paul Fenwick to show off how he does Ascii to EBCDIC stuff.

All the best,

	Jacinta

-----------------

Paul Matthews wrote:

> Perl 5.8 something.

Oh good!  I'm so used to people having to worry about 9+ year old Perls.
  5.8.something is just fine!

> These are machines at work, and no we cannot just upgrade them, infinite
> amounts of paperwork, service first requests, charge codes.... We are
> supposed to be grateful for what we have. (They make us use vi you know ...)

I'm sorry you have to use vi.  :(  Vim's much older than 10 years too.

> The long answer is;
> I am creating files that can be read by COBOL on the Mainframe directly.
> In particular encoding PIC S9(*) BINARY fields. The mainframe is big endian.
> 
>   sub encodeBIN4 {
>     return pack("n>",shift);
>   }
> 
> This would correctly encode to big endian on any machine. But the pack
> expression 'n>' is not available in 5.8.

The syntax for > and < came in in 5.9.2.  I suspect this was early in
the start of the Perl 5.10 branch, but I'd be happy to be corrected.  If
you can't use > and < then the perlpacktut provides the following
suggestion (http://perldoc.perl.org/perlpacktut.html#Byte-order-modifiers)

	my @data = unpack 's>*', $buf;

is equivalent to:

  	 my @data = unpack 's*', pack 'S*', unpack 'n*', $buf;

I don't have enough experience working with unpack and pack to give you
a solution that uses this principle to work with your code, but perhaps
it'll give you the clue you're looking for.

I'm mildly concerned that your comments don't match your code though.
You wrote:

	...pack('n>',$num) to encode a signed integer to big endian....

but the documentation says:

         n   An unsigned short in "network" (big-endian) order.

signed != unsigned.

I'm sure there must be a way to solve this problem without using pack
and unpack but instead using Perl's filters.  Unfortunately I can't
guess what that is right now, so I'll answer more later in the morning
if I come up with something.

There's also a very good chance that someone else has solved this and
put it up on CPAN, I presume you've looked at the Convert::IBM390 module
and rejected it for some reason?
http://search.cpan.org/perldoc?Convert::IBM390

All the best,

	Jacinta



More information about the Canberra-pm mailing list