]> git.donarmstrong.com Git - biopieces.git/blob - code_ruby/lib/maasha/filesys.rb
fixed symlink flaw in file type detection
[biopieces.git] / code_ruby / lib / maasha / filesys.rb
1 # Copyright (C) 2007-2011 Martin A. Hansen.
2
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
7
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 # GNU General Public License for more details.
12
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16
17 # http://www.gnu.org/copyleft/gpl.html
18
19 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
20
21 # This software is part of the Biopieces framework (www.biopieces.org).
22
23 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
24
25 require 'zlib'
26 # require 'bzip2'
27 require 'open3'
28
29 # Error class for all exceptions to do with Filesys.
30 class FilesysError < StandardError; end
31
32 class Filesys
33   include Enumerable
34
35   # Class method that returns a path to a unique temporary file.
36   # If no directory is specified reverts to the systems tmp directory.
37   def self.tmpfile(tmp_dir = ENV["TMPDIR"])
38     time = Time.now.to_i
39     user = ENV["USER"]
40     pid  = $$
41     path = tmp_dir + [user, time + pid, pid].join("_") + ".tmp"
42     path
43   end
44
45   def self.open(*args)
46     file    = args.shift
47     mode    = args.shift
48     options = args.shift || {}
49
50     if mode == 'w'
51       case options[:compress]
52       when :gzip
53         ios = Zlib::GzipWriter.new File.open(file, mode, options)
54       when :bzip, :bzip2
55         # ios = Bzip2::Writer.new File.open(file, mode, options)   # TODO being pissed with buggy bzip2 gem.
56         ios, = Open3.pipeline_w("bzip2 -c", out: file)
57       else 
58         ios = File.open(file, mode, options)
59       end
60     else
61       if file == '-'
62         ios = STDIN
63       else
64         case `file -L #{file}`
65         when /gzip/
66           ios = Zlib::GzipReader.new File.open(file, mode, options)
67         when /bzip/
68           # ios = Bzip2::Reader.new File.open(file, mode, options)   # TODO this method is buggy, investigate
69           ios = IO.popen("bzcat #{file}")
70         else
71           ios = File.open(file, mode, options)
72         end
73       end
74     end
75
76     if block_given?
77       begin
78         yield self.new(ios)
79       ensure
80         ios.close
81       end
82     else
83       return self.new(ios)
84     end
85   end
86
87   def initialize(ios)
88     @io = ios
89   end
90
91   def puts(*args)
92     @io.puts(*args)
93   end
94
95   def close
96     @io.close
97   end
98
99   def eof?
100     @io.eof?
101   end
102
103   # Iterator method for parsing entries.
104   def each
105     while entry = get_entry do
106       yield entry
107     end
108   end
109 end
110