root/Mac-Macbinary/trunk/Macbinary.pm

Revision 22 (checked in by miyagawa, 20 years ago)

improved document.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 package Mac::Macbinary;
2
3 use strict;
4 use vars qw($VERSION $AUTOLOAD);
5 $VERSION = '0.02';
6
7 use Carp;
8
9 sub new {
10     my ($class, $thingy) = @_;
11     my $self = bless { }, $class;
12
13     my $fh = _make_handle($thingy);
14     $self->_parse_handle($fh);
15     return $self;
16 }
17
18 sub _parse_handle {
19     my $self = shift;
20     my ($fh) = @_;
21
22     read $fh, my ($header), 128;
23     $self->{header} = Mac::Macbinary::Header->new($header);
24     read $fh, $self->{data}, $self->header->dflen;
25     read $fh, $self->{resource}, $self->header->rflen;
26
27     return $self;
28 }
29
30 sub _make_handle($) {
31     my $thingy = shift;
32    
33     if (-f $thingy && ! ref($thingy)) {
34         require FileHandle;
35         my $fh = FileHandle->new($thingy) or Carp::croak "$thingy: $!";
36         return $fh;
37     } else {
38         # tries to read it
39         eval {
40             read $thingy, my($tmp), 0;
41         };
42         if ($@) {
43           Carp::croak "Can't read $thingy!";
44         }
45         return $thingy;
46     }
47 }       
48
49 sub AUTOLOAD {
50     my $self = shift;
51     $AUTOLOAD =~ s/.*://o;
52     return $self->{$AUTOLOAD};
53 }
54
55
56 package Mac::Macbinary::Header;
57
58 use vars qw($AUTOLOAD);
59
60 sub new {
61     my ($class, $h) = @_;
62     my $self = bless { }, $class;
63     $self->_parse_header($h);
64     return $self;
65 }
66
67 sub _parse_header {
68     my $self = shift;
69     my ($h) = @_;
70
71     $self->{name}       = unpack("A*", substr($h, 2, 63));
72     $self->{type}       = unpack("A*", substr($h, 65, 4));
73     $self->{creator}    = unpack("A*", substr($h, 69, 4));
74     $self->{flags}      = unpack("C", substr($h, 73, 1));
75     $self->{location}   = unpack("C", substr($h, 80, 6));
76     $self->{dflen}      = unpack("N", substr($h, 83, 4));
77     $self->{rflen}      = unpack("N", substr($h, 87, 4));
78     $self->{cdate}      = unpack("N", substr($h, 91, 4));
79     $self->{mdate}      = unpack("N", substr($h, 95, 4));
80
81     return $self;
82 }
83
84
85 sub AUTOLOAD {
86     my $self = shift;
87     $AUTOLOAD =~ s/.*://o;
88     return $self->{$AUTOLOAD};
89 }
90
91 1;
92 __END__
93
94 =head1 NAME
95
96 Mac::Macbinary - Decodes Macbinary files.
97
98 =head1 SYNOPSIS
99
100   use Mac::Macbinary;
101
102   $mb = new Mac::Macbinary(\*FH);       # filehandle
103   $mb = new Mac::Macbinary($fh);        # IO::* instance
104   $mb = new Mac::Macbinary("/path/to/file");
105
106   $header = $mb->header;                # Mac::Macbinary::Header instance
107   $name = $header->name;
108  
109
110 =head1 DESCRIPTION
111
112 This module provides an object-oriented way to extract various kinds
113 of information from Macintosh Macbinary files.
114
115 =head1 METHODS
116
117 Following methods are available.
118
119 =head2 Class method
120
121 =over 4
122
123 =item new( THINGY )
124
125 Constructor of Mac::Macbinary. Accepts filhandle GLOB reference,
126 FileHandle instance, IO::* instance, or whatever objects that can do
127 C<read> methods.
128
129 If the argument belongs none of those above, C<new()> treats it as a
130 path to file. Any of following examples are valid constructors.
131
132   open FH, "path/to/file";
133   $mb = new Mac::Macbinary(\*FH);
134
135   $fh = new FileHandle "path/to/file";
136   $mb = new Mac::Macbinary($fh);
137
138   $io = new IO::File "path/to/file";
139   $mb = new Mac::Macbinary($io);
140
141   $mb = new Mac::Macbinary "path/to/file";
142
143 C<new()> throws an exception "Can't read blahblah" if the given
144 argument to the constructor is neither a valid filehandle nor an
145 existing file.
146
147
148 =back
149
150 =head2 Instance Method
151
152 =over 4
153
154 =item data
155
156 returns the data range of original file.
157
158 =item header
159
160 returns the header object (instance of Mac::Macbinary::Header).
161
162 =back
163
164 Following accessors are available via Mac::Macbinary instance.
165
166 =over 4
167
168 =item name, type, creator, flags, location, dflen, rflen, cdate, mdate
169
170 returns the original entry in the header of Macbinary file.
171 Below is a structure of the info file, taken from MacBin.C
172
173   char zero1;
174   char nlen;
175   char name[63];
176   char type[4];           65      0101
177   char creator[4];        69
178   char flags;             73
179   char zero2;             74      0112
180   char location[6];       80
181   char protected;         81      0121
182   char zero3;             82      0122
183   char dflen[4];
184   char rflen[4];
185   char cdate[4];
186   char mdate[4];
187
188 =back
189
190 =head1 EXAMPLE
191
192 Some versions of MSIE for Macintosh sends their local files as
193 Macbinary format via forms. You can decode them in a following way:
194
195   use CGI;
196   use Mac::Macbinary;
197
198   $q = new CGI;
199   $filename = $q->param('uploaded_file');
200   $type = $q->uploadInfo($filename)->{'Content-Type'};
201  
202   if ($type eq 'application/x-macbinary') {
203       $mb = Mac::Macbinary->new($q->upload('uploaded_file'));
204       # now, you can get data via $mb->data;
205   }
206
207
208 =head1 TODO
209
210 should add C<is_macbinary()>, to detect if a file is a Macbinary file
211 or not.
212
213 =head1 AUTHOR
214
215 Tatsuhiko Miyagawa <miyagawa@bulknews.net>
216
217 =head1 ACKNOWLEDGEMENT
218
219 Macbinary.pm is originally written by Dan Kogai <dankogai@dan.co.jp>.
220
221 There are also C<Mac::Conversions> and C<Convert::BinHex>, working
222 kind similar to this module. (However, C<Mac::Conversions> works only
223 on MacPerl, and C<Convert::BinHex> is now deprecated.) Many thanks to
224 Paul J. Schinder and Eryq, authors of those ones.
225
226 =head1 SEE ALSO
227
228 perl(1), L<Mac::Conversions>, L<Convert::BinHex>.
229
230 =cut
231
232
Note: See TracBrowser for help on using the browser.