home *** CD-ROM | disk | FTP | other *** search
/ CLIX - Fazer Clix Custa Nix / CLIX-CD.cdr / mac / lib / Mac / Types.pm < prev    next >
Text File  |  1998-04-05  |  5KB  |  266 lines

  1. =head1 NAME
  2.  
  3. Mac::Types - Macintosh Toolbox Types and conversions.
  4.  
  5. =head1 SYNOPSIS
  6.  
  7. =head1 DESCRIPTION
  8.  
  9. Access to Inside Macintosh is essential for proper use of these functions.
  10. Explanations of terms, processes and procedures are provided there.
  11. Any attempt to use these functions without guidance can cause severe errors in 
  12. your machine, including corruption of data. B<You have been warned.>
  13.  
  14. =cut
  15.  
  16. use strict;
  17.  
  18. package Mac::Types;
  19.  
  20. BEGIN {
  21.     use Exporter   ();
  22.     use DynaLoader ();
  23.     use Carp;
  24.  
  25.     use vars qw(@ISA @EXPORT %MacPack %MacUnpack);
  26.     
  27.     @ISA = qw(Exporter DynaLoader);
  28.     
  29.     @EXPORT = qw(
  30.         Debugger
  31.         %MacPack
  32.         %MacUnpack
  33.         MacPack
  34.         MacUnpack
  35.     );
  36. }
  37.  
  38. =head2 Functions
  39.  
  40. =over 4
  41.  
  42. =cut
  43. sub _Identity {
  44.     return wantarray ? @_ : shift;
  45. }
  46.  
  47. sub _Packer {
  48.     my($template) = @_;
  49.     
  50.     return sub { return pack($template, @_); };
  51. }
  52.  
  53. sub _Unpacker {
  54.     my($template) = @_;
  55.     
  56.     return sub { return unpack($template, $_[0]); };
  57. }
  58.  
  59. sub _PackPStr {
  60.     my($string) = @_;
  61.     
  62.     return pack("Ca*", length($string), $string);
  63. }
  64.  
  65. sub _UnpackPStr {
  66.     my($string) = @_;
  67.     
  68.     return "" unless length($string);
  69.     
  70.     my ($length, $cstr) = unpack("Ca*", $string);
  71.     
  72.     return substr($cstr, 0, $length);
  73. }
  74.  
  75. sub _PackPStrList {
  76.     my($list) = pack("s", scalar(@_));
  77.     for (@_) {
  78.         $list .= _PackPStr($_);
  79.     }
  80.     return $list;
  81. }
  82.  
  83. sub _UnpackPStrList {
  84.     my($data) = @_;
  85.     my($count, @strings) = unpack("s", $data);
  86.     $data = substr($data,2);
  87.     while ($count--) {
  88.         my($str) = _UnpackPStr($data);
  89.         $data = substr($data, length($str)+1);
  90.         push(@strings, $str);
  91.     }
  92.     return @strings;
  93. }
  94.  
  95. sub _PackFSSpec {
  96.     my($spec) = MacPerl::MakeFSSpec($_[0]);
  97.     my($packed) = pack("SL", substr($spec, 1, 4), substr($spec, 5, 8)) 
  98.         . _PackPStr(substr($spec, 14));
  99.     return $packed . ('\0' x (70-length($packed)));
  100. }
  101.  
  102. sub _UnpackFSSpec {
  103.     my($spec) = @_;
  104.     
  105.     return 
  106.         MacPerl::MakeFSSpec(sprintf(
  107.             "\021%04x%08x:%s", 
  108.             unpack("SL", $spec), 
  109.             _UnpackPStr(substr($spec, 6))));
  110. }
  111.  
  112. %MacPack = (
  113.     TEXT => \&_Identity,
  114.     enum => _Packer("A4"),
  115.     type => _Packer("A4"),
  116.     keyw => _Packer("A4"),
  117.     sign => _Packer("A4"),
  118.     bool => _Packer("c"),
  119.     shor => _Packer("s"),
  120.     long => _Packer("l"),
  121.     sing => _Packer("f"),
  122.     doub => _Packer("d"),
  123.     magn => _Packer("L"),
  124.     qdrt => _Packer("s4"),
  125.     cRGB => _Packer("s3"),
  126.     
  127.     'STR ' => \&_PackPStr,
  128.     'STR#' => \&_PackPStrList,
  129.     'fss ' => \&_PackFSSpec,
  130. );
  131.  
  132. %MacUnpack = (
  133.     TEXT => \&_Identity,
  134.     enum => _Unpacker("a4"),
  135.     type => _Unpacker("a4"),
  136.     keyw => _Unpacker("a4"),
  137.     sign => _Unpacker("a4"),
  138.     bool => _Unpacker("c"),
  139.     shor => _Unpacker("s"),
  140.     long => _Unpacker("l"),
  141.     sing => _Unpacker("f"),
  142.     doub => _Unpacker("d"),
  143.     magn => _Unpacker("L"),
  144.     qdrt => _Unpacker("s4"),
  145.     cRGB => _Unpacker("S3"),
  146.     
  147.     'STR ' => \&_UnpackPStr,
  148.     'STR#' => \&_UnpackPStrList,
  149.     'fss ' => \&_UnpackFSSpec,
  150. );
  151.  
  152. sub _MacConvert {
  153.     my($type) = shift;
  154.     my(@methods) = ();
  155.     
  156.     while (ref($type) eq "HASH") {
  157.         unshift @methods, $type;
  158.         $type = shift;
  159.     }
  160.     my($table,$code);
  161.     for $table (@methods) {
  162.         $code = $table->{$type};
  163.         if (ref($code) eq "CODE") {
  164.             return &{$code}(@_);
  165.         }
  166.     }
  167.     croak "Don't know about type “$type”";
  168. }
  169.  
  170. =item MacPack [ CONVERTERS ...] CODE, DATA ...
  171.  
  172. Convert a perl value into a Mac toolbox type. Predefined codes are:
  173.  
  174. =over 4
  175.  
  176. =item TEXT 
  177.  
  178. Text (an identity operation).
  179.  
  180. =item enum
  181.  
  182. =item type 
  183.  
  184. =item keyw
  185.  
  186. A 4-byte string.
  187.  
  188. =item bool 
  189.  
  190. A boolean.
  191.  
  192. =item shor 
  193.  
  194. A short integer.
  195.  
  196. =item long 
  197.  
  198. A long integer.
  199.  
  200. =item sing 
  201.  
  202. A single precision float.
  203.  
  204. =item doub 
  205.  
  206. A double precision float.
  207.  
  208. =item magn 
  209.  
  210. An unsigned long.
  211.  
  212. =item qdrt
  213.  
  214. A QuickDraw C<Rect>.
  215.     
  216. =item 'STR ' 
  217.  
  218. A pascal style string.
  219.  
  220. =item 'STR#' 
  221.  
  222. A string list.
  223.  
  224. =item 'fss '
  225.  
  226. A file specification record.
  227.  
  228. =back
  229.  
  230. You can pass further code mappings as hash references.
  231.  
  232. =cut
  233. sub MacPack {
  234.     _MacConvert(\%MacPack, @_);
  235. }
  236.  
  237. =item MacUnpack [ CONVERTERS ...] CODE, DATA
  238.  
  239. Convert a Mac toolbox type into a perl value. Predefined codes are as for 
  240. C<MacPack>. You can pass further code mappings as hash references.
  241.  
  242. =cut
  243. sub MacUnpack {
  244.     _MacConvert(\%MacUnpack, @_);
  245. }
  246.  
  247. bootstrap Mac::Types;
  248.  
  249. =back
  250.  
  251. =include Types.xs
  252.  
  253. =head1 BUGS/LIMITATIONS
  254.  
  255. =head1 FILES
  256.  
  257. =head1 AUTHOR(S)
  258.  
  259. Matthias Ulrich Neeracher <neeri@iis.ee.ethz.ch> 
  260.  
  261. =cut
  262.  
  263. 1;
  264.  
  265. __END__
  266.