Geminstaller C0 Coverage Information - RCov

spec/fixture/rubygems_dist/rubygems-trunk/lib/rubygems/package/tar_writer.rb

Name Total Lines Lines of Code Total Coverage Code Coverage
spec/fixture/rubygems_dist/rubygems-trunk/lib/rubygems/package/tar_writer.rb 241 120
43.98%
16.67%

Key

Code reported as executed by Ruby looks like this...and this: this line is also marked as covered.Lines considered as run by rcov, but not reported by Ruby, look like this,and this: these lines were inferred by rcov (using simple heuristics).Finally, here's a line marked as not executed.

Coverage Details

1 # -*- coding: utf-8 -*-
2 #--
3 # Copyright (C) 2004 Mauricio Julio Fernández Pradier
4 # See LICENSE.txt for additional licensing information.
5 #++
6 
7 ##
8 # Allows writing of tar files
9 
10 class Gem::Package::TarWriter
11 
12   class FileOverflow < StandardError; end
13 
14   ##
15   # IO wrapper that allows writing a limited amount of data
16 
17   class BoundedStream
18 
19     ##
20     # Maximum number of bytes that can be written
21 
22     attr_reader :limit
23 
24     ##
25     # Number of bytes written
26 
27     attr_reader :written
28 
29     ##
30     # Wraps +io+ and allows up to +limit+ bytes to be written
31 
32     def initialize(io, limit)
33       @io = io
34       @limit = limit
35       @written = 0
36     end
37 
38     ##
39     # Writes +data+ onto the IO, raising a FileOverflow exception if the
40     # number of bytes will be more than #limit
41 
42     def write(data)
43       if data.size + @written > @limit
44         raise FileOverflow, "You tried to feed more data than fits in the file."
45       end
46       @io.write data
47       @written += data.size
48       data.size
49     end
50 
51   end
52 
53   ##
54   # IO wrapper that provides only #write
55 
56   class RestrictedStream
57 
58     ##
59     # Creates a new RestrictedStream wrapping +io+
60 
61     def initialize(io)
62       @io = io
63     end
64 
65     ##
66     # Writes +data+ onto the IO
67 
68     def write(data)
69       @io.write data
70     end
71 
72   end
73 
74   ##
75   # Creates a new TarWriter, yielding it if a block is given
76 
77   def self.new(io)
78     writer = super
79 
80     return writer unless block_given?
81 
82     begin
83       yield writer
84     ensure
85       writer.close
86     end
87 
88     nil
89   end
90 
91   ##
92   # Creates a new TarWriter that will write to +io+
93 
94   def initialize(io)
95     @io = io
96     @closed = false
97   end
98 
99   ##
100   # Adds file +name+ with permissions +mode+, and yields an IO for writing the
101   # file to
102 
103   def add_file(name, mode) # :yields: io
104     check_closed
105 
106     raise Gem::Package::NonSeekableIO unless @io.respond_to? :pos=
107 
108     name, prefix = split_name name
109 
110     init_pos = @io.pos
111     @io.write "\0" * 512 # placeholder for the header
112 
113     yield RestrictedStream.new(@io) if block_given?
114 
115     size = @io.pos - init_pos - 512
116 
117     remainder = (512 - (size % 512)) % 512
118     @io.write "\0" * remainder
119 
120     final_pos = @io.pos
121     @io.pos = init_pos
122 
123     header = Gem::Package::TarHeader.new :name => name, :mode => mode,
124                                          :size => size, :prefix => prefix
125 
126     @io.write header
127     @io.pos = final_pos
128 
129     self
130   end
131 
132   ##
133   # Add file +name+ with permissions +mode+ +size+ bytes long.  Yields an IO
134   # to write the file to.
135 
136   def add_file_simple(name, mode, size) # :yields: io
137     check_closed
138 
139     name, prefix = split_name name
140 
141     header = Gem::Package::TarHeader.new(:name => name, :mode => mode,
142                                          :size => size, :prefix => prefix).to_s
143 
144     @io.write header
145     os = BoundedStream.new @io, size
146 
147     yield os if block_given?
148 
149     min_padding = size - os.written
150     @io.write("\0" * min_padding)
151 
152     remainder = (512 - (size % 512)) % 512
153     @io.write("\0" * remainder)
154 
155     self
156   end
157 
158   ##
159   # Raises IOError if the TarWriter is closed
160 
161   def check_closed
162     raise IOError, "closed #{self.class}" if closed?
163   end
164 
165   ##
166   # Closes the TarWriter
167 
168   def close
169     check_closed
170 
171     @io.write "\0" * 1024
172     flush
173 
174     @closed = true
175   end
176 
177   ##
178   # Is the TarWriter closed?
179 
180   def closed?
181     @closed
182   end
183 
184   ##
185   # Flushes the TarWriter's IO
186 
187   def flush
188     check_closed
189 
190     @io.flush if @io.respond_to? :flush
191   end
192 
193   ##
194   # Creates a new directory in the tar file +name+ with +mode+
195 
196   def mkdir(name, mode)
197     check_closed
198 
199     name, prefix = split_name(name)
200 
201     header = Gem::Package::TarHeader.new :name => name, :mode => mode,
202                                          :typeflag => "5", :size => 0,
203                                          :prefix => prefix
204 
205     @io.write header
206 
207     self
208   end
209 
210   ##
211   # Splits +name+ into a name and prefix that can fit in the TarHeader
212 
213   def split_name(name) # :nodoc:
214     raise Gem::Package::TooLongFileName if name.size > 256
215 
216     if name.size <= 100 then
217       prefix = ""
218     else
219       parts = name.split(/\//)
220       newname = parts.pop
221       nxt = ""
222 
223       loop do
224         nxt = parts.pop
225         break if newname.size + 1 + nxt.size > 100
226         newname = nxt + "/" + newname
227       end
228 
229       prefix = (parts + [nxt]).join "/"
230       name = newname
231 
232       if name.size > 100 or prefix.size > 155 then
233         raise Gem::Package::TooLongFileName 
234       end
235     end
236 
237     return name, prefix
238   end
239 
240 end
241 

Generated on Mon May 10 23:40:28 -0700 2010 with rcov 0.9.8