On Mon, Mar 19, 2001 at 06:49:19PM +0000, Alan Fry wrote:
> At 9:41 am -0500 19/03/01, Ronald J Kimball wrote:
>
> >I did provide sample code, in an earlier response to Alan. The correct and
> >robust approach is to start at the beginning of the string and process the
> >sections in order.
>
> (I had some difficulty getting that to work and revised it using
> 'substr', which is not nearly so elegant but was a bit easier to
> debug.)
>
> This takes that approach and works (up to a point):
>
> #!perl
> use Mac::LowMem;
>
> $lmh = LMGetScrapHandle;
> $str = $lmh->get;
>
> # diagnostics...
> #print "$str\n\n";
> #@l = split(//, $str);
> #foreach (@l) {print ord($_), '|'}; print "\n\n";
>
> while(length $str) {
> $key = substr($str, 0, 4);
> print $key, "/";
> $num = substr($str, 4, 4);
> $len = unpack("L", $num);
> print "$len\n";
> print substr($str, 8, $len), "\n";
> $str = substr($str, 8+$len);
> #print $str, "\n";
> }
>
> However there is a nasty bug.
>
> If the selected text ends on a boundary (a space or a newline) an
> arbitrary character (sometimes 0, sometimes 13, sometimes something
> strange) gets added to the end of the string but is _not_ included in
> the 'TEXT' count. Everything else that follows is then 'one out'.
>
> So far as I can see it is a bug in LowMem. That being so and bearing in mind:
>
Actually, according to the explanation John Baxter posted, each section
must use an even number of bytes. This means there will be an extra
padding byte added to a section whose length is odd.
I think adding a line to your code should fix this bug:
#!perl
use Mac::LowMem;
$lmh = LMGetScrapHandle;
$str = $lmh->get;
# diagnostics...
#print "$str\n\n";
#@l = split(//, $str);
#foreach (@l) {print ord($_), '|'}; print "\n\n";
while(length $str) {
$key = substr($str, 0, 4);
print $key, "/";
$num = substr($str, 4, 4);
$len = unpack("L", $num);
print "$len\n";
print substr($str, 8, $len), "\n";
$len % 2 and $len++;
# skip the extra padding byte when $len is odd
$str = substr($str, 8+$len);
#print $str, "\n";
}
Ronald