BEGIN {
use
vars
qw($VERSION @ISA @EXPORT %MacPack %MacUnpack)
;
$VERSION
=
'1.02'
;
@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"
),
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"
),
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;