sane-ffi/lib/sane.rb

160 lines
3.9 KiB
Ruby
Raw Normal View History

2011-05-31 23:21:15 +02:00
class Sane
include Singleton
2011-06-01 14:07:08 +02:00
attr_reader :version
def self.open
instance.send(:init)
yield instance
ensure
instance.send(:exit)
end
def devices
get_devices.map { |device| Device.new(device) }
2011-05-31 23:21:15 +02:00
end
2011-05-31 18:26:57 +02:00
2011-06-01 14:07:08 +02:00
private
def not_initialized?
version.nil?
end
def initialized?
!not_initialized?
2011-05-31 23:21:15 +02:00
end
2011-05-31 18:26:57 +02:00
2011-05-31 23:21:15 +02:00
def init
2011-06-01 14:07:08 +02:00
ensure_not_initialized!
2011-05-31 23:21:15 +02:00
version_code = FFI::MemoryPointer.new(:int)
check_status!(API.sane_init(version_code, FFI::Pointer::NULL))
2011-06-01 14:07:08 +02:00
@version = version_code.read_int
2011-05-31 23:21:15 +02:00
end
2011-05-31 18:26:57 +02:00
2011-05-31 23:21:15 +02:00
def exit
2011-06-01 14:07:08 +02:00
ensure_initialized!
2011-05-31 23:21:15 +02:00
API.sane_exit
2011-06-01 14:07:08 +02:00
@version = nil
2011-05-31 23:21:15 +02:00
end
2011-05-31 18:26:57 +02:00
2011-05-31 23:21:15 +02:00
def get_devices
2011-06-01 14:07:08 +02:00
ensure_initialized!
devices_pointer_pointer = FFI::MemoryPointer.new(:pointer)
check_status!(API.sane_get_devices(devices_pointer_pointer, 0))
devices_pointer = devices_pointer_pointer.read_pointer
2011-05-31 23:21:15 +02:00
[].tap do |result|
2011-06-01 14:07:08 +02:00
until devices_pointer.read_pointer.null?
result << API::Device.new(devices_pointer.read_pointer).to_hash
devices_pointer += FFI.type_size(:pointer)
2011-05-31 23:21:15 +02:00
end
2011-05-31 18:26:57 +02:00
end
2011-05-31 23:21:15 +02:00
end
2011-05-31 18:26:57 +02:00
2011-05-31 23:21:15 +02:00
def open(device_name)
2011-06-01 14:07:08 +02:00
ensure_initialized!
2011-05-31 23:21:15 +02:00
device_handle_pointer = FFI::MemoryPointer.new(:pointer)
check_status!(API.sane_open(device_name, device_handle_pointer))
device_handle_pointer.read_pointer
end
2011-05-31 19:25:18 +02:00
2011-05-31 23:21:15 +02:00
def close(device_handle)
2011-06-01 14:07:08 +02:00
ensure_initialized!
2011-05-31 23:21:15 +02:00
API.sane_close(device_handle)
end
2011-05-31 19:25:18 +02:00
2011-05-31 23:21:15 +02:00
def get_option_descriptor(device_handle, option)
2011-06-01 14:07:08 +02:00
ensure_initialized!
2011-05-31 23:21:15 +02:00
result = API.sane_get_option_descriptor(device_handle, option)
2011-06-01 14:07:08 +02:00
API::OptionDescriptor.new(result).to_hash
2011-05-31 23:21:15 +02:00
end
2011-05-31 19:25:18 +02:00
2011-05-31 23:21:15 +02:00
def get_option(device_handle, option)
2011-06-01 14:07:08 +02:00
ensure_initialized!
2011-05-31 23:21:15 +02:00
descriptor = get_option_descriptor(device_handle, option)
2011-05-31 19:25:18 +02:00
2011-05-31 23:21:15 +02:00
case descriptor[:type]
when :string
value_pointer = FFI::MemoryPointer.new(:pointer)
when :bool, :int, :fixed
value_pointer = FFI::MemoryPointer.new(:int)
else
return nil
2011-05-31 19:25:18 +02:00
end
2011-05-31 23:21:15 +02:00
check_status!(API.sane_control_option(device_handle, option, :get_value, value_pointer, FFI::Pointer::NULL))
2011-05-31 19:25:18 +02:00
2011-05-31 23:21:15 +02:00
case descriptor[:type]
when :string
value_pointer.read_string
when :bool
!value_pointer.read_int.zero?
when :int, :fixed
value_pointer.read_int
end
end
2011-05-31 19:25:18 +02:00
2011-05-31 23:21:15 +02:00
def set_option(device_handle, option, value)
2011-06-01 14:07:08 +02:00
ensure_initialized!
2011-05-31 23:21:15 +02:00
descriptor = get_option_descriptor(device_handle, option)
case descriptor[:type]
when :string
value_pointer = FFI::MemoryPointer.from_string(value)
when :int, :fixed
value_pointer = FFI::MemoryPointer.new(:int).write_int(value)
when :bool
value_pointer = FFI::MemoryPointer.new(:int).write_int(value ? 1 : 0)
else
return nil
2011-05-31 19:25:18 +02:00
end
2011-05-31 23:21:15 +02:00
check_status!(API.sane_control_option(device_handle, option, :set_value, value_pointer, FFI::Pointer::NULL))
case descriptor[:type]
when :string
value_pointer.read_string
when :bool
!value_pointer.read_int.zero?
when :int, :fixed
value_pointer.read_int
2011-05-31 18:26:57 +02:00
end
end
2011-05-31 23:21:15 +02:00
2011-06-01 14:07:08 +02:00
def start(handle)
ensure_initialized!
API.sane_start(handle)
end
def read(handle, size = 64 * 1024)
ensure_initialized!
data_pointer = FFI::MemoryPointer.new(:char, size)
length_pointer = FFI::MemoryPointer.new(:int)
check_status!(API.sane_read(handle, data_pointer, size, length_pointer))
data_pointer.read_string(length_pointer.read_int)
end
2011-05-31 23:21:15 +02:00
def strstatus(status)
2011-06-01 14:07:08 +02:00
ensure_initialized!
2011-05-31 23:21:15 +02:00
API.sane_strstatus(status)
end
2011-06-01 14:07:08 +02:00
def get_parameters(handle)
ensure_initialized!
parameters_pointer = FFI::MemoryPointer.new(API::Parameters.size)
check_status!(API.sane_get_parameters(handle, parameters_pointer))
API::Parameters.new(parameters_pointer).to_hash
end
def ensure_not_initialized!
raise "SANE library is already initialized" if initialized?
end
def ensure_initialized!
raise "SANE library is not initialized" if not_initialized?
end
2011-05-31 23:21:15 +02:00
def check_status!(status)
2011-06-01 14:07:08 +02:00
raise Error.new(strstatus(status), status) unless status == :good
2011-05-31 23:21:15 +02:00
end
2011-05-31 18:26:57 +02:00
end