summaryrefslogtreecommitdiff
path: root/lib/URI/file/Mac.pm
blob: 4d8e76631842e07df25885b8190b138026bb08eb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package URI::file::Mac;

use strict;
use warnings;

use parent 'URI::file::Base';

use URI::Escape qw(uri_unescape);

our $VERSION = "1.69";

sub _file_extract_path
{
    my $class = shift;
    my $path = shift;

    my @pre;
    if ($path =~ s/^(:+)//) {
	if (length($1) == 1) {
	    @pre = (".") unless length($path);
	} else {
	    @pre = ("..") x (length($1) - 1);
	}
    } else { #absolute
	$pre[0] = "";
    }

    my $isdir = ($path =~ s/:$//);
    $path =~ s,([%/;]), URI::Escape::escape_char($1),eg;

    my @path = split(/:/, $path, -1);
    for (@path) {
	if ($_ eq "." || $_ eq "..") {
	    $_ = "%2E" x length($_);
	}
	$_ = ".." unless length($_);
    }
    push (@path,"") if $isdir;
    (join("/", @pre, @path), 1);
}


sub file
{
    my $class = shift;
    my $uri = shift;
    my @path;

    my $auth = $uri->authority;
    if (defined $auth) {
	if (lc($auth) ne "localhost" && $auth ne "") {
	    my $u_auth = uri_unescape($auth);
	    if (!$class->_file_is_localhost($u_auth)) {
		# some other host (use it as volume name)
		@path = ("", $auth);
		# XXX or just return to make it illegal;
	    }
	}
    }
    my @ps = split("/", $uri->path, -1);
    shift @ps if @path;
    push(@path, @ps);

    my $pre = "";
    if (!@path) {
	return;  # empty path; XXX return ":" instead?
    } elsif ($path[0] eq "") {
	# absolute
	shift(@path);
	if (@path == 1) {
	    return if $path[0] eq "";  # not root directory
	    push(@path, "");           # volume only, effectively append ":"
	}
	@ps = @path;
	@path = ();
        my $part;
	for (@ps) {  #fix up "." and "..", including interior, in relatives
	    next if $_ eq ".";
	    $part = $_ eq ".." ? "" : $_;
	    push(@path,$part);
	}
	if ($ps[-1] eq "..") {  #if this happens, we need another :
	    push(@path,"");
	}
	
    } else {
	$pre = ":";
	@ps = @path;
	@path = ();
        my $part;
	for (@ps) {  #fix up "." and "..", including interior, in relatives
	    next if $_ eq ".";
	    $part = $_ eq ".." ? "" : $_;
	    push(@path,$part);
	}
	if ($ps[-1] eq "..") {  #if this happens, we need another :
	    push(@path,"");
	}
	
    }
    return unless $pre || @path;
    for (@path) {
	s/;.*//;  # get rid of parameters
	#return unless length; # XXX
	$_ = uri_unescape($_);
	return if /\0/;
	return if /:/;  # Should we?
    }
    $pre . join(":", @path);
}

sub dir
{
    my $class = shift;
    my $path = $class->file(@_);
    return unless defined $path;
    $path .= ":" unless $path =~ /:$/;
    $path;
}

1;