| Mac-Carbon documentation | Contained in the Mac-Carbon distribution. |
Mac::Types - Macintosh Toolbox Types and conversions.
Access to Inside Macintosh is essential for proper use of these functions. Explanations of terms, processes and procedures are provided there. Any attempt to use these functions without guidance can cause severe errors in your machine, including corruption of data. You have been warned.
Convert a perl value into a Mac toolbox type. Predefined codes are:
Text (an identity operation).
A 4-byte string.
A boolean.
A short integer.
A long integer.
A single precision float.
A double precision float.
An unsigned long.
A QuickDraw Rect.
A pascal style string.
A string list.
A file specification record.
You can pass further code mappings as hash references.
Convert a Mac toolbox type into a perl value. Predefined codes are as for
MacPack. You can pass further code mappings as hash references.
Written by Matthias Ulrich Neeracher <neeracher@mac.com>. Currently maintained by Chris Nandor <pudge@pobox.com>.
| Mac-Carbon documentation | Contained in the Mac-Carbon distribution. |
use strict; package Mac::Types; use MacPerl 'MakeFSSpec'; BEGIN { use Exporter (); use DynaLoader (); use Carp; use vars qw($VERSION @ISA @EXPORT %MacPack %MacUnpack); $VERSION = '1.04'; @ISA = qw(Exporter DynaLoader); @EXPORT = qw( Debugger %MacPack %MacUnpack MacPack MacUnpack ); }
sub _Identity { return wantarray ? @_ : shift; } sub _Packer { my($template) = @_; return sub { return pack($template, @_); }; } sub _Unpacker { my($template) = @_; return sub { return unpack($template, $_[0] || ''); }; } sub _PackPStr { my($string) = @_; return pack("Ca*", length($string), $string); } sub _UnpackPStr { my($string) = @_; return "" unless defined($string) && length($string); my ($length, $cstr) = unpack("Ca*", $string); return substr($cstr, 0, $length); } sub _PackPStrList { my($list) = pack("s", scalar(@_)); for (@_) { $list .= _PackPStr($_); } return $list; } sub _UnpackPStrList { my($data) = @_; my($count, @strings) = unpack("s", $data); $data = substr($data,2); while ($count--) { my($str) = _UnpackPStr($data); $data = substr($data, length($str)+1); push(@strings, $str); } return @strings; } sub _PackFSSpec { my($spec) = MacPerl::MakeFSSpec($_[0]); my($packed) = pack("SL", hex(substr($spec, 1, 4)), hex(substr($spec, 5, 8))) . _PackPStr(substr($spec, 14)); return $packed . ("\0" x (70-length($packed))); } sub _UnpackFSSpec { my($spec) = @_; return MacPerl::MakeFSSpec(sprintf( "\021%04x%08x:%s", unpack("SL", $spec), _UnpackPStr(substr($spec, 6)))); } %MacPack = ( TEXT => \&_Identity, enum => _Packer("A4"), type => _Packer("A4"), keyw => _Packer("A4"), sign => _Packer("A4"), prop => _Packer("A4"), bool => _Packer("c"), shor => _Packer("s"), long => _Packer("l"), sing => _Packer("f"), doub => _Packer("d"), magn => _Packer("L"), qdrt => _Packer("s4"), cRGB => _Packer("s3"), 'STR ' => \&_PackPStr, 'STR#' => \&_PackPStrList, 'fss ' => \&_PackFSSpec, ); %MacUnpack = ( TEXT => \&_Identity, enum => _Unpacker("a4"), type => _Unpacker("a4"), keyw => _Unpacker("a4"), sign => _Unpacker("a4"), prop => _Unpacker("a4"), bool => _Unpacker("c"), shor => _Unpacker("s"), long => _Unpacker("l"), sing => _Unpacker("f"), doub => _Unpacker("d"), magn => _Unpacker("L"), qdrt => _Unpacker("s4"), cRGB => _Unpacker("S3"), 'STR ' => \&_UnpackPStr, 'STR#' => \&_UnpackPStrList, 'fss ' => \&_UnpackFSSpec, ); sub _MacConvert { my($type) = shift; my(@methods) = (); while (ref($type) eq "HASH") { unshift @methods, $type; $type = shift; } my($table,$code); for $table (@methods) { $code = $table->{$type}; if (ref($code) eq "CODE") { return &{$code}(@_); } } croak "Don't know about type '$type'"; }
sub MacPack { _MacConvert(\%MacPack, @_); }
sub MacUnpack { _MacConvert(\%MacUnpack, @_); } bootstrap Mac::Types;
1; __END__