Fuse-PDF

 view release on metacpan or  search on metacpan

lib/Fuse/PDF/FS.pm  view on Meta::CPAN

   $xattr->{value}->{$key} = CAM::PDF::Node->new('string', $value, $o, $g);
   $self->{fs}->{mtime}->{value} = time;
   $self->{dirty} = 1;
   return 0;
}

sub fs_getxattr {
   my ($self, $abspath, $key) = @_;
   my $f = $self->_file($abspath);
   return -$f if !ref $f;
   my $xattr = $f->{xattr};
   return 0 if !$xattr;
   return 0 if !exists $xattr->{value}->{$key};
   return $xattr->{value}->{$key}->{value};
}

sub fs_listxattr {
   my ($self, $abspath, $key) = @_;
   my $f = $self->_file($abspath);
   return -$f if !ref $f;
   my $xattr = $f->{xattr};
   return ($xattr ? keys %{ $xattr->{value} } : ()), 0;
}

sub fs_removexattr {
   my ($self, $abspath, $key) = @_;
   my $f = $self->_file($abspath);
   return -$f if !ref $f;
   my $xattr = $f->{xattr};
   return -ENOATTR() if !$xattr;
   return -ENOATTR() if !exists $xattr->{value}->{$key};
   delete $xattr->{value}->{$key};
   $self->{fs}->{mtime}->{value} = time;
   $self->{dirty} = 1;
   return 0;
}

# --------------------------------------------------

sub _parent {
   my ($self, $path) = @_;
   my ($errno, $dirs, $paths) = $self->_readpath($path, 1);
   return $errno if $errno;
   return $dirs->[-2], $paths->[-1], $dirs->[-1];  ## no critic(MagicNumber)
}

sub _file {
   my ($self, $path) = @_;
   my ($errno, $dirs, $paths) = $self->_readpath($path);
   return $errno if $errno;
   return $dirs->[-1];
}


sub _readpath {
   my ($self, $path, $parent, $nsymlinks) = @_;

   $nsymlinks ||= 0;

   my @dirs = ($self->{fs}->{root}->{value});
   my @path = split m{/}xms, $path;
   my @realpath;

   for (my $i = 0; $i < @path; ++$i) {    ##no critic(ProhibitCStyleForLoops)
      my $entry = $path[$i];
      next if q{} eq $entry;

      my $type = $dirs[-1]->{type}->{value};
      return ENOTDIR() if 'd' ne $type;
      next if q{.} eq $entry;
      if (q{..} eq $entry) {
         pop @dirs;
         pop @realpath;
         return EACCESS() if !@dirs;      # tried to get parent of root
         next;
      }
      push @realpath, $entry;

      my $next = $dirs[-1]->{content}->{value}->{$entry};
      if (!$next) {
         if ($parent && $i == $#path) {
            push @dirs, undef;
            return 0, \@dirs, \@realpath;
         }
         return ENOENT();
      }
      my $f = $next->{value};
      if ('l' eq $f->{type}->{value}) {
         if ($i != $#path) {
            return ELOOP() if ++$nsymlinks >= $ELOOP_LIMIT;
            my $linkpath = $f->{content}->{value};

            # cannot leave the filesystem
            return EACCESS() if $linkpath =~ m{\A /}xms;

            splice @path, $i, 1, split m{/}xms, $linkpath;
            return $self->_readpath((join q{/}, @path), $parent, $nsymlinks);
         }
      }
      push @dirs, $f;
   }

   return 0, \@dirs, \@realpath;
}

sub _newfile {
   my ($self, $parent, $perm) = @_;
   my ($o, $g) = ($parent->{objnum}, $parent->{gennum});
   return $self->_newentry($o, $g, S_IFREG | $perm,
      'f', CAM::PDF::Node->new('string', q{}, $o, $g));
}

sub _newsymlink {
   my ($self, $parent, $src) = @_;
   my ($o, $g) = ($parent->{objnum}, $parent->{gennum});
   return $self->_newentry($o, $g, S_IFLNK | $DEFAULT_SYMLINK_PERMS,
      'l', CAM::PDF::Node->new('string', $src, $o, $g));
}

sub _newdir {
   my ($self, $parent, $perm) = @_;
   # MUST NOT create an new PDF objects
   my ($o, $g) = ($parent->{objnum}, $parent->{gennum});
   my $dir = $self->_newentry($o, $g, S_IFDIR() | $perm,
      'd', CAM::PDF::Node->new('dictionary', {}, $o, $g));
   $dir->{value}->{nlink}->{value}++;
   return $dir;
}

sub _newentry {    ##no critic(ProhibitManyArgs)
   my ($self, $o, $g, $perm, $type, $content) = @_;
   # MUST NOT create an new PDF objects if type = 'd'
   my $now = time;
   return CAM::PDF::Node->new('dictionary', {
      content => $content,
      type    => CAM::PDF::Node->new('string', $type, $o, $g),
      inode   => CAM::PDF::Node->new('number', 0, $o, $g),
      mode    => CAM::PDF::Node->new('number', $perm, $o, $g),
      nlink   => CAM::PDF::Node->new('number', 1, $o, $g),
      mtime   => CAM::PDF::Node->new('number', $now, $o, $g),
      ctime   => CAM::PDF::Node->new('number', $now, $o, $g),
   }, $o, $g);
}

1;

__END__

=pod

=for stopwords pdf runtime EIO

=head1 NAME

Fuse::PDF::FS - In-PDF implementation of a filesystem.



( run in 0.983 second using v1.01-cache-2.11-cpan-71847e10f99 )