| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | #======================================================================== | 
| 2 |  |  |  |  |  |  | # | 
| 3 |  |  |  |  |  |  | # Badger::Filesystem::Universal | 
| 4 |  |  |  |  |  |  | # | 
| 5 |  |  |  |  |  |  | # DESCRIPTION | 
| 6 |  |  |  |  |  |  | #   Subclass of Badger::Filesystem which implements a universal | 
| 7 |  |  |  |  |  |  | #   filesystem for representing URIs.  It always uses forward slashes | 
| 8 |  |  |  |  |  |  | #   as path separators regardless of the local filesystem convention. | 
| 9 |  |  |  |  |  |  | # | 
| 10 |  |  |  |  |  |  | # AUTHOR | 
| 11 |  |  |  |  |  |  | #   Andy Wardley | 
| 12 |  |  |  |  |  |  | # | 
| 13 |  |  |  |  |  |  | #======================================================================== | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  | package Badger::Filesystem::Universal; | 
| 16 |  |  |  |  |  |  |  | 
| 17 | 1 |  |  | 1 |  | 6 | use Badger::Debug ':dump'; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 5 |  | 
| 18 |  |  |  |  |  |  | use Badger::Class | 
| 19 | 1 |  |  |  |  | 6 | version   => 0.01, | 
| 20 |  |  |  |  |  |  | debug     => 0, | 
| 21 |  |  |  |  |  |  | base      => 'Badger::Filesystem', | 
| 22 |  |  |  |  |  |  | constants => 'HASH', | 
| 23 |  |  |  |  |  |  | constant  => { | 
| 24 |  |  |  |  |  |  | UFS          => __PACKAGE__, | 
| 25 |  |  |  |  |  |  | ROOTDIR      => '/', | 
| 26 |  |  |  |  |  |  | CURDIR       => '.', | 
| 27 |  |  |  |  |  |  | UPDIR        => '..', | 
| 28 |  |  |  |  |  |  | FILESPEC     => 'Badger::Filesystem::FileSpec::Universal', | 
| 29 |  |  |  |  |  |  | spec         => 'Badger::Filesystem::FileSpec::Universal', | 
| 30 |  |  |  |  |  |  | }, | 
| 31 |  |  |  |  |  |  | exports   => { | 
| 32 |  |  |  |  |  |  | any   => 'UFS', | 
| 33 | 1 |  |  | 1 |  | 6 | }; | 
|  | 1 |  |  |  |  | 1 |  | 
| 34 |  |  |  |  |  |  |  | 
| 35 |  |  |  |  |  |  |  | 
| 36 |  |  |  |  |  |  | #----------------------------------------------------------------------- | 
| 37 |  |  |  |  |  |  | # Replacement for File::Spec implementing that various methods that the | 
| 38 |  |  |  |  |  |  | # filesystem needs to construct paths. | 
| 39 |  |  |  |  |  |  | #----------------------------------------------------------------------- | 
| 40 |  |  |  |  |  |  |  | 
| 41 |  |  |  |  |  |  | package Badger::Filesystem::FileSpec::Universal; | 
| 42 |  |  |  |  |  |  |  | 
| 43 |  |  |  |  |  |  | use Badger::Class | 
| 44 | 1 |  |  |  |  | 16 | version   => 0.01, | 
| 45 |  |  |  |  |  |  | debug     => 0, | 
| 46 |  |  |  |  |  |  | base      => 'Badger::Base', | 
| 47 |  |  |  |  |  |  | constant  => { | 
| 48 |  |  |  |  |  |  | SLASH   => '/', | 
| 49 |  |  |  |  |  |  | SLASHRX => qr{/}, | 
| 50 |  |  |  |  |  |  | COLON   => ':', | 
| 51 |  |  |  |  |  |  | rootdir => '/', | 
| 52 |  |  |  |  |  |  | curdir  => '.', | 
| 53 |  |  |  |  |  |  | updir   => '..', | 
| 54 | 1 |  |  | 1 |  | 7 | }; | 
|  | 1 |  |  |  |  | 1 |  | 
| 55 |  |  |  |  |  |  |  | 
| 56 |  |  |  |  |  |  |  | 
| 57 |  |  |  |  |  |  | sub catdir { | 
| 58 | 0 |  |  | 0 |  |  | my $self = shift; | 
| 59 | 0 |  |  |  |  |  | join(SLASH, @_); | 
| 60 |  |  |  |  |  |  | } | 
| 61 |  |  |  |  |  |  |  | 
| 62 |  |  |  |  |  |  | sub catpath { | 
| 63 | 0 |  |  | 0 |  |  | my ($self, $volume, $dir, $file) = @_; | 
| 64 | 0 |  |  |  |  |  | my $path = ''; | 
| 65 |  |  |  |  |  |  |  | 
| 66 |  |  |  |  |  |  | # yuk | 
| 67 | 0 | 0 | 0 |  |  |  | $volume = undef unless defined $volume and length $volume; | 
| 68 | 0 | 0 | 0 |  |  |  | $dir    = undef unless defined $dir    and length $dir; | 
| 69 | 0 | 0 | 0 |  |  |  | $file   = undef unless defined $file   and length $file; | 
| 70 |  |  |  |  |  |  |  | 
| 71 | 0 | 0 |  |  |  |  | $path .= $volume.COLON if defined $volume; | 
| 72 | 0 | 0 | 0 |  |  |  | $path .= SLASH         if defined $volume and defined $dir; | 
| 73 | 0 | 0 |  |  |  |  | $path .= $dir.SLASH    if defined $dir; | 
| 74 | 0 | 0 |  |  |  |  | $path .= $file         if defined $file; | 
| 75 | 0 | 0 |  |  |  |  | $self->debug("catpath() [$volume] [$dir] [$file] => [$path]") if $DEBUG; | 
| 76 | 0 |  |  |  |  |  | return $path; | 
| 77 |  |  |  |  |  |  | } | 
| 78 |  |  |  |  |  |  |  | 
| 79 |  |  |  |  |  |  | sub splitpath { | 
| 80 | 0 |  |  | 0 |  |  | my ($self, $path) = @_; | 
| 81 | 0 |  |  |  |  |  | my ($volume, $dir, $file); | 
| 82 | 0 |  |  |  |  |  | $dir    = $path; | 
| 83 | 0 | 0 |  |  |  |  | $volume = $1 if $dir =~ s/^(\w+)://; | 
| 84 | 0 | 0 |  |  |  |  | $file   = $1 if $dir =~ s/([^\/]+)$//; | 
| 85 | 0 |  |  |  |  |  | $dir    =~ s{(?<=.)/$}{}; | 
| 86 | 0 |  |  |  |  |  | $dir    =~ s{//}{/}g; | 
| 87 | 0 | 0 |  |  |  |  | $self->debug("splitpath() [$path] => [$volume] [$dir] [$file]") if $DEBUG; | 
| 88 | 0 |  |  |  |  |  | return ($volume, $dir, $file); | 
| 89 |  |  |  |  |  |  | } | 
| 90 |  |  |  |  |  |  |  | 
| 91 |  |  |  |  |  |  | sub splitdir { | 
| 92 | 0 |  |  | 0 |  |  | my ($self, $dir) = @_; | 
| 93 | 0 | 0 |  |  |  |  | $self->debug("splitdir($dir) => [", join('] [', split(SLASHRX, $dir)), ']') if $DEBUG; | 
| 94 | 0 |  |  |  |  |  | return split(SLASHRX, $dir); | 
| 95 |  |  |  |  |  |  | } | 
| 96 |  |  |  |  |  |  |  | 
| 97 |  |  |  |  |  |  | sub file_name_is_absolute { | 
| 98 | 0 |  |  | 0 |  |  | my ($self, $path) = @_; | 
| 99 | 0 |  |  |  |  |  | $self->debug("testing $path"); | 
| 100 | 0 |  |  |  |  |  | return $path =~ m{^/}; | 
| 101 |  |  |  |  |  |  | } | 
| 102 |  |  |  |  |  |  |  | 
| 103 |  |  |  |  |  |  | sub canonpath { | 
| 104 | 0 |  |  | 0 |  |  | my $self = shift; | 
| 105 | 0 |  |  |  |  |  | my ($volume, $dir, $name) = $self->splitpath(@_); | 
| 106 | 0 |  |  |  |  |  | my @dirs = $self->splitdir($dir); | 
| 107 | 0 |  |  |  |  |  | my ($node, @path); | 
| 108 | 0 |  |  |  |  |  | while (@dirs) { | 
| 109 | 0 |  |  |  |  |  | $node = shift @dirs; | 
| 110 | 0 | 0 |  |  |  |  | if ($node eq curdir) { | 
|  |  | 0 |  |  |  |  |  | 
| 111 |  |  |  |  |  |  | # do nothing | 
| 112 |  |  |  |  |  |  | } | 
| 113 |  |  |  |  |  |  | elsif ($node eq updir) { | 
| 114 | 0 | 0 |  |  |  |  | pop @path if @path; | 
| 115 |  |  |  |  |  |  | } | 
| 116 |  |  |  |  |  |  | else { | 
| 117 | 0 |  |  |  |  |  | push(@path, $node); | 
| 118 |  |  |  |  |  |  | } | 
| 119 |  |  |  |  |  |  | } | 
| 120 | 0 |  |  |  |  |  | return $self->catpath( | 
| 121 |  |  |  |  |  |  | $volume, | 
| 122 |  |  |  |  |  |  | $self->catdir(@path), | 
| 123 |  |  |  |  |  |  | $name | 
| 124 |  |  |  |  |  |  | ); | 
| 125 |  |  |  |  |  |  | } | 
| 126 |  |  |  |  |  |  |  | 
| 127 |  |  |  |  |  |  | sub abs2rel { | 
| 128 | 0 |  |  | 0 |  |  | shift->todo; | 
| 129 |  |  |  |  |  |  | } | 
| 130 |  |  |  |  |  |  |  | 
| 131 |  |  |  |  |  |  | sub no_upwards { | 
| 132 | 0 |  |  | 0 |  |  | shift->todo; | 
| 133 |  |  |  |  |  |  | } | 
| 134 |  |  |  |  |  |  |  | 
| 135 |  |  |  |  |  |  | 1; | 
| 136 |  |  |  |  |  |  |  |