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