mogilefs-client.git  about / heads / tags
MogileFS client library for Ruby
blob e3b6874a00293750dc00e94cafb440632c4b3c36 1328 bytes (raw)
$ git show HEAD:lib/mogilefs/bigfile/filter.rb	# shows this blob on the CLI

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
 
# -*- encoding: binary -*-
require 'zlib'
require 'digest/md5'

# Filter class to wrap IO objects and uncompress DEFLATE'd files
#
# This is used for reading "bigfile" objects generated by the
# (deprecated) mogtool(1)
class MogileFS::Bigfile::Filter
  GZIP_HEADER = "\x1f\x8b"
  INFLATABLE_TYPES = { "file" => true }
  attr_reader :flushed_bytes

  def initialize(io, info, opts)
    @io = io
    @info = info
    @md5 = opts[:verify] ? Digest::MD5.new : nil
    @zi = nil
    @flushed_bytes = 0
  end

  def md5_check!(expect)
    return unless @md5
    current = @md5.hexdigest
    current == expect or
      raise MogileFS::ChecksumMismatchError, "#{current} != #{expect}"
    @md5.reset
  end

  def flush
    @flushed_bytes = @io.write(@zi.finish) if @zi
    @io.flush
  end

  def write(buf)
    unless @zi
      if @info[:compressed] &&
         INFLATABLE_TYPES.include?(@info[:type]) &&
         buf.bytesize >= 2 &&
         buf[0,2] != GZIP_HEADER

        @zi = Zlib::Inflate.new

        # mogtool(1) seems to have a bug that causes it to generate bogus
        # MD5s if zlib deflate is used.  Don't trust those MD5s for now...
        @md5 = nil
      else
        @zi = false
      end
    end
    if @zi
      buf = @zi.inflate(buf)
    else
      @md5.update(buf) if @md5
    end
    @io.write(buf)
  end
end

git clone https://yhbt.net/mogilefs-client.git