Got FileSystem working with multi methods (pmichaud++)
[kakapo:kakapo.git] / src / FileSystem.nqp
1 # Copyright (C) 2010, Austin Hastings. See accompanying LICENSE file, or
2 # http://www.opensource.org/licenses/artistic-license-2.0.php for license.
3
4 # Provides a conventional framework for program execution.
5 class FileSystem;
6
7 INIT {
8         our %_Osname_class_map := Hash.new(
9                 :DEFAULT(       FileSystem::Unix),
10                 :linux( FileSystem::Unix),
11                 :MSWin32(       FileSystem::Windows),
12         );
13         
14         Kakapo::initload_done();
15 }
16
17 our method get_osname_map() {
18         our %_Osname_class_map;
19 }
20
21 our method _init_obj(*@pos, *%named) {
22         my %map := self.get_osname_map();
23         my $osname := 'DEFAULT';
24         
25         try {
26                 my $tmp := %*VM<osname>;
27                 $osname := $tmp if %map.contains: $tmp;
28
29                 # if not, whatever. Keep it at DEFAULT
30                 CATCH { }
31         }
32
33         my $class := %map{$osname};
34         my $obj := $class.new( |@pos, |%named );        # NB: Returns a different type than Path.
35         $obj;
36 }
37
38 our method instance($value?) {
39         if $value.defined {
40                 our $_Instance := $value;
41         }
42         elsif ! our $_Instance.defined {
43                 self.instance: self.new;
44         }
45
46         $_Instance;
47 }
48
49 class FileSystem::Unix
50         is FileSystem;
51
52 has     $!file;
53 has     $!os;
54
55 INIT {
56         pir::loadlib__ps('file');
57         pir::loadlib__ps('os');
58         
59         use(    Parrot::Unix::Stat );
60 }
61
62 our method chdir($path = '') {
63         $!os.chdir( ~ $path);
64 }
65
66 our method cwd() {
67         $!os.cwd;
68 }
69
70 our method directory_separator() { '/' }
71
72 our multi method exists( Path $path ) {
73         $!file.exists( ~$path );
74 }
75
76 #~ my method exists__Path($path) {
77         #~ $!file.exists( ~ $path );
78 #~ }
79
80 our multi method exists( String $path ) {
81         $!file.exists: $path;
82 }
83
84 #~ my method exists__String($path) {
85         #~ $!file.exists($path);
86 #~ }
87
88 my method exists__ANY($ignored) {
89         die( "Don't know how to check if ", pir::typeof__SP($ignored), " exists. Use a String or Path");
90 }
91
92 our method get_contents($path, *%named) {
93         my $contents;
94
95         if self.is_file: $path {
96                 %named<mode> := 'r';
97                 my $fh := self.open($path, |%named);
98                 $contents := $fh.readall;
99                 $fh.close;
100         }
101         elsif self.is_directory: $path {
102                 $contents := $!os.readdir: ~$path;
103         }
104         else {
105                 # What to do?
106                 die("Don't know how to get contents of non-file, non-directory: $path");
107         }
108
109         $contents;
110 }
111
112 my method _init_obj(*@pos, *%named) {
113         $!file := pir::new__PS( 'File' );
114         $!os := pir::new__PS( 'OS' );
115
116         self._init_args(|@pos, |%named);
117 }
118
119 our method is_device($path) {
120         my @stat := $!os.stat( ~$path );
121         my $mode := @stat[2];
122         S_ISBLK($mode) || S_ISCHR($mode) || S_ISFIFO($mode) || S_ISSOCK($mode);
123 }
124
125 our method is_directory($path) {
126         my @stat := $!os.stat( ~$path );
127         S_ISDIR(@stat[2]);
128 }
129
130 our method is_file($path) {
131         my @stat := $!os.stat( ~$path );
132         Parrot::Unix::Stat::S_ISREG(@stat[2]);
133 }
134
135 our method is_link($path) {
136         my @stat := $!os.lstat( ~$path );
137         S_ISLNK(@stat[2]);
138 }
139
140 our method open($path, *%named) {
141
142         my $fh  := pir::new__PS('FileHandle');
143         my $mode        := '' ~ %named<mode> // 'r';
144
145         $fh.open(~ $path, $mode);
146
147         # Not a loop because of prefix ops (+, ~)
148         $fh.buffer_size( +%named<buffer_size> )
149                 if %named.contains( <buffer_size> );
150         $fh.buffer_type( ~%named<buffer_type> )
151                 if %named.contains( <buffer_type> );
152         $fh.encoding( ~%named<encoding> )
153                 if %named.contains( <encoding> );
154
155         $fh;
156 }
157
158 our method volume_separator() { ':' }
159
160 class FileSystem::Windows
161         is FileSystem::Unix;
162
163 our method directory_separator() { '\\' }