Class: Tb::Cmd::TarReader

Inherits:
Object
  • Object
show all
Defined in:
lib/tb/cmd_tar.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(input) ⇒ TarReader

Returns a new instance of TarReader.



184
185
186
187
# File 'lib/tb/cmd_tar.rb', line 184

def initialize(input)
  @input = input
  @offset = 0
end

Instance Attribute Details

#offsetObject (readonly)

Returns the value of attribute offset.



188
189
190
# File 'lib/tb/cmd_tar.rb', line 188

def offset
  @offset
end

Instance Method Details

#calculate_hash(blocklength, filesize, alg_list) ⇒ Object

:yield: alg, result



248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
# File 'lib/tb/cmd_tar.rb', line 248

def calculate_hash(blocklength, filesize, alg_list) # :yield: alg, result
  digests = {}
  alg_list.each {|alg|
    c = Digest.const_get(Tb::Cmd::TAR_HASH_ALGORITHMS.fetch(alg))
    digests[alg] = c.new
  }
  rest = blocklength
  while 0 < rest
    if rest < 4096
      s = rest
    else
      s = 4096
    end
    ret = @input.read(s)
    if !ret || ret.length != s
      warn "premature end of tar archive content (#{kind})"
      raise Tb::Cmd::TarFormatError
    end
    if filesize < s
      ret = ret[0, filesize]
    end
    digests.each {|alg, d|
      d.update ret
    }
    filesize -= s
    rest -= s
  end
  @offset += blocklength
  result = {}
  digests.each {|alg, d|
    result[alg] = d.hexdigest
  }
  result
end

#get_single_record(kind) ⇒ Object



190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/tb/cmd_tar.rb', line 190

def get_single_record(kind)
  record = @input.read(Tb::Cmd::TAR_RECORD_LENGTH)
  if !record
    return nil
  end
  if record.length != Tb::Cmd::TAR_RECORD_LENGTH
    warn "premature end of tar archive (#{kind})"
    raise Tb::Cmd::TarFormatError
  end
  @offset += Tb::Cmd::TAR_RECORD_LENGTH
  record
end

#read_exactly(size, kind) ⇒ Object



212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/tb/cmd_tar.rb', line 212

def read_exactly(size, kind)
  record = @input.read(size)
  if !record
    warn "premature end of tar archive (#{kind})"
    raise Tb::Cmd::TarFormatError
  end
  if record.length != size
    warn "premature end of tar archive (#{kind})"
    raise Tb::Cmd::TarFormatError
  end
  @offset += size
  record
end

#read_single_record(kind) ⇒ Object



203
204
205
206
207
208
209
210
# File 'lib/tb/cmd_tar.rb', line 203

def read_single_record(kind)
  record = get_single_record(kind)
  if !record
    warn "premature end of tar archive (#{kind})"
    raise Tb::Cmd::TarFormatError
  end
  record
end

#skip(size, kind) ⇒ Object



226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/tb/cmd_tar.rb', line 226

def skip(size, kind)
  begin
    @input.seek(size, IO::SEEK_CUR)
  rescue Errno::ESPIPE
    rest = size
    while 0 < rest
      if rest < 4096
        s = rest
      else
        s = 4096
      end
      ret = @input.read(s)
      if !ret || ret.length != s
        warn "premature end of tar archive content (#{kind})"
        raise Tb::Cmd::TarFormatError
      end
      rest -= s
    end
  end
  @offset += size
end