MacOSX::File::Info - Gets/Sets (HFS) File Attributes


MacOSX-File documentation Contained in the MacOSX-File distribution.

Index


Code Index:

NAME

Top

MacOSX::File::Info - Gets/Sets (HFS) File Attributes

SYNOPSIS

Top

  use MacOSX::File::Info;
  $finfo = MacOSX::File::Info->get($path);
  $finfo->type('TEXT');
  $finfo->creator('ttxt');
  $finfo->flags(-invisible => 1);
  $finfo->set;

DESCRIPTION

Top

This module implements what /Developer/Tools/{GetFileInfo,SetFile} does within perl.

EXPORT

Subs: getfinfo(), setfinfo()

METHODS

Top

$finfo = MacOSX::File::Info->get($path);
$finfo = getfileinfo($path);

Constructs MacOSX::File::Info from which you can manipulate file attributes. On failure, it returns undef and $MacOSX::File::OSErr is set.

$finfo->set([$path]);
setfinfo($finfo, [$path]);

Sets file attributes of file $path. If $path is omitted the file you used to construct $finfo is used. On success, it returns 1. On failure, it returns 0 and $MacOSX::File::OSErr is set.

Remember any changes to $finfo will not be commited until you call these functions.

  ex)
    setfinfo(getfinfo("foo"), "bar"); 
    #Copies file attributes from foo to bar

$clone = $finfo->clone;

Returns a cloned (deep-copied) object. Handy when you want to compare changes.

$finfo->ref(), $finfo->nodeFlags(),

returns FSRef and nodeFlags of the file. these attributes are read only. Use of these methods are unlikely except for debugging purpose.

$finfo->type([$type]), $finfo->creator([$creator])

Gets and sets file type and creator, respectively. Though they accept strings longer than 4 bytes, only the first 4 bytes are used.

$finfo->ctime($ctime), $finfo->mtime($mtime)

Gets and sets file creation time and content modification time, respectively.

  ex)
    $finfo->mtime(time());

Time is specified by seconds passed since Unix Epoch, January 1, 1970 00:00:00 UTC. Beware this is different from Native Macintosh Epoch, January 1, 1904, 00:00:00 UTC. I made it that way because perl on MacOSX uses Unix notion of Epoch. (FYI MacPerl uses Mac notion of Epoch).

These methods accept fractional numbers since Carbon supports it. It also accepts numbers larger than UINT_MAX for the same reason.

$finfo->fdflags($fdflags)

Gets and sets fdflags values. However, the use of this method is discouraged unless you are happy with bitwise operation. Use $finfo->flags method instead.

  ex)
    $finfo->fdflags($finfo->fdflags | kIsInvisible)
    # makes the file invisible

$flags = $finfo->flags($attributes), %flags = $finfo->flags(%attributes)

Gets and sets fdflags like /Developer/Tools/SetFile. You can use SetFile-compatible letter notation or more intuitive args-by-hash notation.

When you use Attribute letters and corresponding swithes as follows. Uppercase to flag and lowercase to flag.

    Letter Hash key         Description
    -----------------------------------
    [Aa]   -alias           Alias file
    [Vv]   -invisible       Invisible*
    [Bb]   -bundle          Bundle
    [Ss]   -system          System (name locked)
    [Tt]   -stationery      Stationary
    [Cc]   -customicon      Custom icon*
    [Ll]   -locked          Locked
    [Ii]   -inited          Inited*
    [Nn]   -noinit          No INIT resources
    [Mm]   -shared          Shared (can run multiple times)
    [Ee]   -hiddenx         Hidden extension*
    [Dd]   -desktop         Desktop*

Attributes with asterisk can be applied to folders and files. Any other can be applied to files only.

  ex)
    $attr = $finfo->flags("avbstclinmed"); 
    # unflag eveythinng
    $attr = $finfo->flags("L");
    # locks file with the rest of attributes untouched
    $attr = $finfo->flags(-locked => 1);
    # same thing but more intuitive

On scalar context, it returns attrib. letters. On list context, it returns hash notation shown above;

AUTHOR

Top

Dan Kogai <dankogai@dan.co.jp>

SEE ALSO

Top

  L<MacPerl>
  F</Developer/Tools/GetFileInfo>
  F</Developer/Tools/SetFile>

COPYRIGHT

Top


MacOSX-File documentation Contained in the MacOSX-File distribution.
package MacOSX::File::Info;

use 5.006;
use strict;
use warnings;
use Carp;

our $RCSID = q$Id: Info.pm,v 0.70 2005/08/09 15:47:00 dankogai Exp $;
our $VERSION = do { my @r = (q$Revision: 0.70 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r };
our $DEBUG;

require Exporter;
require DynaLoader;
use AutoLoader;

our @ISA = qw(Exporter DynaLoader);

# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.

# This allows declaration	use MacOSX::File::Info ':all';
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
# will save memory.

our %EXPORT_TAGS = ( 'all' => [ qw(

) ] );

our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );

our @EXPORT = qw(
		 getfinfo
		 setfinfo
		 );

bootstrap MacOSX::File::Info $VERSION;
use MacOSX::File;

# Preloaded methods go here.

sub DESTROY{
    $DEBUG or return;
    carp "Destroying ", __PACKAGE__;
    return;
}

sub getfinfo{
    my ($path) = @_;
    my $self = xs_getfinfo($path);
    defined $self or return;
    bless $self;
}

sub get{
    my ($class, $path) = @_;
    my $self = xs_getfinfo($path);
    defined $self or return;
    bless $self => $class;
}

sub setfinfo{
    my ($info, $path) = @_;
    ref $info eq __PACKAGE__ or return;
    $path ||= ""; # to keep warnings quiet;
    return !xs_setfinfo(@$info, $path);
}

sub set{
    my ($self, $path) = @_;
    ref $self eq __PACKAGE__ or return;
    $path ||= ""; # to keep warnings quiet;
    return !xs_setfinfo(@$self, $path);
}

sub clone{
    my $self = shift;
    my (@new) = @$self;
    bless \@new, (ref $self);
}

# Construct accessor methods all at once

my %_ro = (
	   ref        => 0,
	   nodeFlags  => 1,
	   );

while(my($field, $index) = each %_ro){
    no strict 'refs';
    *$field = sub { $_[0]->[$index] };
}

my %_rw = (
	   type              => 2,
	   creator           => 3,
	   fdFlags           => 4,
	   ctime             => 5,
	   mtime             => 6,
	   );


while(my($field, $index) = each %_rw){
    no strict 'refs';
    *$field = sub  {
	my $self = shift;
	@_ and $self->[$index] = shift;
	$self->[$index];
    };
}


use MacOSX::File::Constants;

my %Key2Letter =
    qw(
       -alias      a
       -invisible  v
       -bundle     b
       -system     s
       -stationery t
       -customicon c
       -locked     l
       -inited     i
       -noinit     n
       -shared     m
       -hiddenx    e
       -desktop    d
       );
my %Letter2Key = reverse %Key2Letter;
my @Letters    = qw(a v b s t c l i n m e d);
my %key2Flags = 
    (
     -alias      =>  kIsAlias,
     -invisible  =>  kIsInvisible,
     -bundle     =>  kHasBundle,
     -system     =>  kNameLocked,
     -stationery =>  kIsStationery,
     -customicon =>  kHasCustomIcon,
     -locked     =>  kFSNodeLockedMask,
     -inited     =>  kHasBeenInited,
     -noinit     =>  kHasNoINITs,
     -shared     =>  kIsShared,
     -hiddenx    =>  kIsHiddenExtention,
     -desktop    =>  kIsOnDesk,
     );

sub locked{
    my $self = shift;
    return $self->nodeFlags & kFSNodeLockedMask;
}

sub lock{
    my $self = shift;
    $self->[1] = $self->nodeFlags | kFSNodeLockedMask;
    return $self;
}

sub unlock{
    my $self = shift;
    $self->[1] = $self->nodeFlags & ~kFSNodeLockedMask;
    return $self;
}

sub flags{
    my $self = shift;
    my ($fdFlags, $nodeFlags) = ($self->fdFlags, $self->nodeFlags);
    my %attrib = (
		  -alias      => $fdFlags & kIsAlias,
		  -invisible  => $fdFlags & kIsInvisible,
		  -bundle     => $fdFlags & kHasBundle,
		  -system     => $fdFlags & kNameLocked,
		  -stationery => $fdFlags & kIsStationery,
		  -customicon => $fdFlags & kHasCustomIcon,
		  -locked     => $nodeFlags & kFSNodeLockedMask,
		  -inited     => $fdFlags & kHasBeenInited,
		  -noinit     => $fdFlags & kHasNoINITs,
		  -shared     => $fdFlags & kIsShared,
		  -hiddenx    => $fdFlags & kIsHiddenExtention,
		  -desktop    => $fdFlags & kIsOnDesk,
		  );
    my $attrib = "";
    unless (@_){
	wantarray and return %attrib;
	for my $l (@Letters){
	    $attrib .=  $attrib{$Letter2Key{$l}} ? uc($l) : $l;
	}
	return $attrib;
    }
    if (scalar(@_) == 1){ # Letter notation
	my $letters = shift;
	for my $l (map { chr } unpack("C*", $letters)){
	    $attrib{$Letter2Key{lc($l)}} = ($l =~ tr/[A-Z]/[A-Z]/) ? 1 : 0;
	}
    }else{
	my %args = @_;
	for my $k (keys %args){
	    exists $attrib{$k} and $attrib{$k} = $args{$k};
	}
    }
    $fdFlags = 0;
    for my $k (keys %attrib){
	if ($k eq '-locked'){
	    $attrib{$k} ? $self->lock : $self->unlock;
	}else{
	    $fdFlags |= $attrib{$k} ? $key2Flags{$k} : 0;
	}
    }
    $self->fdFlags($fdFlags);

    defined wantarray or return;
    wantarray and return %attrib;
    for my $l (@Letters){
	$attrib .=  $attrib{$Letter2Key{$l}} ? uc($l) : $l;
    }
    return $attrib;
}
# Autoload methods go after =cut, and are processed by the autosplit program.

1;
__END__