I have been developing Mac::iTunes on a Mac---no surprise there---but I meant for parts of it to work anywhere. Perl is mostly architecture independent, but I got bit with one of the bits it cannot help.
As part of the parser that reads the binary iTunes database file, I read two or four bytes and then unpack them into shorts or longs, which, in Perl, are just numbers.
Now, on a PowerPC, the big bits show up on the left just like our thousands place show up on the left of the hundreds place. This is not true on all processors though. Some mix up the bytes so the bits end up all over the place. Ick!
On the Mac, my parsing stuff worked because I do not have to worry about byte ordering, and the binary file has the bytes in the right order. When I tested the module on another unix account yesterday, everything exploded, sending goofy characters all over the screen and messing up my terminal (a windows client that is far inferior to Terminal). Somewhere the parser read something wrong, got confused, and starting slurping bytes it should not have slurped. Things that were not strings became strings with wierd characters.
At first I suspected a unicode boo-boo, since I had started to muck around with the unicode strings that iTunes uses, but "use bytes" did not do anything to help.
Now, since this explosion messed up my terminal, I had a hard time getting output I could read. I tried to redirect stderr to stdout and then stdout to a file (in BASH), but that did not work. I found a little BASH trick that did, though, and I still do not know why it worked and the other did not.
# does not work
% perl script 2>&1 > test.out
#works
% perl script &> test.out
I took the output back to my computer and stared at it for a bit. Really, just looked at it while I ate some Spaghettios I heated in my canteen cup.
I wondered how many bytes the first string was, for some reason. I counted 1280. That number does not look special to me, but I knew is was supposed to be 5.
I thought for a moment. I wondered "What is 5 if the byte order is reversed?", figuring I would get some other strange number. If I have the string "\000\005", and I turn it into a short with unpack, I get 5 on my PowerPC. If I turn it into a short on an Intel, I get...yep, I get 1280.
Huzzah.
I now have to deal with this in my code. I know unpack can figure this out because there is network order and VAX order formats, although I always get them mixed up. I need to turn this unpack into something that give the same answer on both architectures.
unpack( "S", $data );
With a two options, either the network or VAX order, I get it on the second try.
unpack( "n", $data );
Thus, with this fix, *BSD folks (and, if they play nicely, maybe the Linux folks) can parse the iTunes database format too. They will even find a spiffy new Makefile.PL that does not bother them with all the Mac specific bits.
Bash stuph (Score:3, Insightful)
I'm not entirely certain why, but when you do that, only what would originally have been sent to STDOUT is redirected to test.out and your warnings will go to STDOUT. Change that to:
Never seen that before, but then, I still don't understand Linux terribly well.
Reply to This
Re:Bash stuph (Score:4, Interesting)
From
man bash:Reply to This
Parent
Re:Bash stuph (Score:5, Funny)
man bash: directions for using the feminist shell :)
Reply to This
Parent
Re:Bash stuph (Score:1)
open(STDERR, ">&STDOUT"); open(STDOUT, ">dirlist");open(STDOUT, ">dirlist"); open(STDERR, ">&STDOUT");BTW, bash has a shorthand for redirectiny stdin and stderr together.
ls &> fileRe:Bash stuph (Score:2)
ah-ha! (Score:1)
Your post got me thinking...
In my File::SAUCE module [cpan.org] I have a pack template. A test on a solaris machine [perl.org] was giving me messages like this:
I was using 'S' in my template. So, on my win32 box, i plug in 'n' just to see what it would do. It was giving me the same errors as above.
So, as per perl-port [perldoc.com], i now do an endian-ness check and use 'n' or 'S' wh
Big endian, little endian (Score:1)
Then I realized that Perl does an excellent job of hiding byte order. With Perl, it is much less common to read binary structures than in C. Since pack does a good job of handling the differences, byte order just becomes part of the specification of the format.
Basically, there are two d
Re:Big endian, little endian (Score:2)
My first battle with endianness was moving a couple of gigabytes of data from an intel machine to a motorola based one. To make the analysis of this data easier, I needed to flip around the byte order of the longs. C was taking too long, s
Re:Big endian, little endian (Score:2)