Module: Snappy::FFI

Defined in:
lib/snappy_ffi.rb

Defined Under Namespace

Modules: Lib

Constant Summary collapse

Version =
"0.1.2"

Class Method Summary collapse

Class Method Details

.compress(input) ⇒ Object

Compresses a string, returning the compressed value



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/snappy_ffi.rb', line 73

def self.compress(input)
  # Set up our input
  input = input.to_s
  input_size = input.bytesize rescue input.size
  
  # Make a place to record our compressed size
  output_size = Lib::SizeT.new
  
  # Make a buffer big enough to hold the worst case
  max = Lib.max_compressed_length(input_size)
  FFI::MemoryPointer.new(max) { |output_buffer|
    # Compress
    Lib.raw_compress(input, input_size, output_buffer, output_size.pointer)

    # Get our string
    output = output_buffer.get_bytes(0, output_size[:value])

    # Return, copying taint as needed
    if input.tainted?
      return output.taint
    else
      return output
    end
  }
end

.uncompress(input) ⇒ Object

Decompresses a string, throwing ArgumentError if it’s somehow corrupt



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/snappy_ffi.rb', line 100

def self.uncompress(input)
  # Set up our input
  input = input.to_s
  input_size = input.bytesize rescue input.size
      
  # Make a place to record our uncompressed size
  output_size = Lib::SizeT.new
  
  # See how big our output will be
  if !Lib.get_uncompressed_length(input, input_size, output_size.pointer)
    # failure!
    raise ArgumentError, "invalid compressed data"
  end
  
  # Make the buffer
  FFI::MemoryPointer.new(output_size[:value]) { |output_buffer|
    # Decompress
    if !Lib.raw_uncompress(input, input_size, output_buffer)
      raise ArgumentError, "invalid compressed data"
    end
  
    # Get our string
    output = output_buffer.get_bytes(0, output_size[:value])
  
    # Return, copying taint as needed
    if input.tainted?
      return output.taint
    else
      return output
    end    
  }
end