Class: RBzip2::FFI::Decompressor

Inherits:
Object
  • Object
show all
Extended by:
FFI::Library
Defined in:
lib/facter/util/rbzip2-0.3.0/lib/rbzip2/ffi/decompressor.rb

Overview

This code is free software; you can redistribute it and/or modify it under the terms of the new BSD License.

Copyright © 2013, Brian Lopez Copyright © 2013-2017, Sebastian Staudt

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(io) ⇒ Decompressor

Returns a new instance of Decompressor.



75
76
77
# File 'lib/facter/util/rbzip2-0.3.0/lib/rbzip2/ffi/decompressor.rb', line 75

def initialize(io)
  @io = io
end

Class Method Details

.decompress(data, factor = 2, small = 0, verbosity = 0) ⇒ Object



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
59
60
61
62
# File 'lib/facter/util/rbzip2-0.3.0/lib/rbzip2/ffi/decompressor.rb', line 33

def self.decompress(data, factor = 2, small = 0, verbosity = 0)
  out_len = data.bytesize * factor
  dst_buf = ::FFI::MemoryPointer.new :char, out_len
  dst_len = ::FFI::MemoryPointer.new :uint32
  dst_len.write_uint out_len

  src_buf = ::FFI::MemoryPointer.new :char, data.bytesize
  src_buf.put_bytes 0, data

  ret = BZ2_bzBuffToBuffDecompress dst_buf, dst_len, src_buf, data.bytesize,
                                   small, verbosity

  case ret
    when RBzip2::FFI::BZ_OK
      dst_buf.read_bytes dst_len.read_uint
    when RBzip2::FFI::BZ_PARAM_ERROR
      raise ArgumentError, 'One of sall or verbosity'
    when RBzip2::FFI::BZ_MEM_ERROR
      raise NoMemoryError, 'Out of memory'
    when RBzip2::FFI::BZ_OUTBUFF_FULL
      raise RBzip2::FFI::BufferError, "Output buffer isn't large enough"
    when RBzip2::FFI::BZ_DATA_ERROR, RBzip2::FFI::BZ_DATA_ERROR_MAGIC,
         RBzip2::FFI::BZ_UNEXPECTED_EOF
      raise RBzip2::FFI::CorruptError, 'Compressed data appears to be corrupt or unreadable'
    when RBzip2::FFI::BZ_CONFIG_ERROR
      raise RBzip2::FFI::ConfigError, 'libbz2 has been mis-compiled'
    else
      raise RBzip2::FFI::Error, "Unhandled error code: #{ret}"
  end
end

Instance Method Details

#closeObject



79
80
81
82
83
84
85
86
# File 'lib/facter/util/rbzip2-0.3.0/lib/rbzip2/ffi/decompressor.rb', line 79

def close
  if @io != $stdin
    @io = nil
    @data = nil
  end

  close_file unless @bz_file.nil?
end

#close_fileObject



88
89
90
91
92
# File 'lib/facter/util/rbzip2-0.3.0/lib/rbzip2/ffi/decompressor.rb', line 88

def close_file
  error = ::FFI::MemoryPointer.new :uint32
  BZ2_bzReadClose error, @bz_file
  fclose @file
end

#getcObject



94
95
96
# File 'lib/facter/util/rbzip2-0.3.0/lib/rbzip2/ffi/decompressor.rb', line 94

def getc
  read 1
end

#getsObject



98
99
100
101
102
103
104
105
106
# File 'lib/facter/util/rbzip2-0.3.0/lib/rbzip2/ffi/decompressor.rb', line 98

def gets
  line = ''
  loop do
    char = getc
    line += char
    break if char == "\n"
  end
  line
end

#inspectObject



159
160
161
# File 'lib/facter/util/rbzip2-0.3.0/lib/rbzip2/ffi/decompressor.rb', line 159

def inspect
  "#<#{self.class}: @io=#{@io.inspect} size=#{size} uncompressed=#{uncompressed}>"
end

#open_file(verbosity = 0, small = 0) ⇒ Object



108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/facter/util/rbzip2-0.3.0/lib/rbzip2/ffi/decompressor.rb', line 108

def open_file(verbosity = 0, small = 0)
  raise 'IO not a file' unless @io.is_a? File

  small = 0 if small < 0
  verbosity = 0 if verbosity < 0
  verbosity = 4 if verbosity > 4

  error = ::FFI::MemoryPointer.new :uint32

  @file = fopen @io.path, 'r'
  @bz_file = BZ2_bzReadOpen error, @file, verbosity, small, nil, 0
end

#read(length = nil) ⇒ Object



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/facter/util/rbzip2-0.3.0/lib/rbzip2/ffi/decompressor.rb', line 121

def read(length = nil)
  raise 'stream closed' if @io.nil?

  if length.nil?
    factor = 4
    compressed_data = @io.read
    data = nil
    while data.nil?
      begin
        data = self.class.decompress compressed_data, factor
      rescue RBzip2::FFI::BufferError
        factor = factor ** 2
      end
    end
  else
    if @io.is_a? File
      data = read_file length
    else
      raise NotImplementedError
    end
  end

  data
end

#read_file(length) ⇒ Object



64
65
66
67
68
69
70
71
72
73
# File 'lib/facter/util/rbzip2-0.3.0/lib/rbzip2/ffi/decompressor.rb', line 64

def read_file(length)
  error = ::FFI::MemoryPointer.new :uint32
  dst_buf = ::FFI::MemoryPointer.new :char, length

  open_file if @bz_file.nil?

  BZ2_bzRead error, @bz_file, dst_buf, length

  dst_buf.read_bytes length
end

#sizeObject



146
147
148
149
150
151
152
# File 'lib/facter/util/rbzip2-0.3.0/lib/rbzip2/ffi/decompressor.rb', line 146

def size
  if @io.is_a? StringIO
    @io.size
  elsif @io.is_a? File
    @io.stat.size
  end
end

#uncompressedObject



154
155
156
157
# File 'lib/facter/util/rbzip2-0.3.0/lib/rbzip2/ffi/decompressor.rb', line 154

def uncompressed
  @data = read
  @data.size
end