added singleton
This commit is contained in:
parent
e7db196a29
commit
4a6b2d5739
189
lib/sane.rb
189
lib/sane.rb
|
@ -1,94 +1,109 @@
|
||||||
module Sane
|
class Sane
|
||||||
|
include Singleton
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
def init
|
extend Forwardable
|
||||||
version_code = FFI::MemoryPointer.new(:int)
|
delegate [:init, :exit, :get_devices, :open, :close, :get_option_descriptor, :get_option, :set_option, :strstatus] => :instance
|
||||||
check_status!(API.sane_init(version_code, FFI::Pointer::NULL))
|
end
|
||||||
version_code.read_int
|
|
||||||
end
|
|
||||||
|
|
||||||
def exit
|
def initialize
|
||||||
API.sane_exit
|
init
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_devices
|
def init
|
||||||
devices_pointer = FFI::MemoryPointer.new(:pointer)
|
version_code = FFI::MemoryPointer.new(:int)
|
||||||
check_status!(API.sane_get_devices(devices_pointer, 0))
|
check_status!(API.sane_init(version_code, FFI::Pointer::NULL))
|
||||||
devices = devices_pointer.read_pointer
|
version_code.read_int
|
||||||
[].tap do |result|
|
end
|
||||||
until devices.read_pointer.null?
|
|
||||||
result << API::Device.new(devices.read_pointer)
|
def exit
|
||||||
devices += FFI.type_size(:pointer)
|
API.sane_exit
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def get_devices
|
||||||
|
devices_pointer = FFI::MemoryPointer.new(:pointer)
|
||||||
|
check_status!(API.sane_get_devices(devices_pointer, 0))
|
||||||
|
devices = devices_pointer.read_pointer
|
||||||
|
[].tap do |result|
|
||||||
|
until devices.read_pointer.null?
|
||||||
|
result << API::Device.new(devices.read_pointer)
|
||||||
|
devices += FFI.type_size(:pointer)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
def open(device_name)
|
|
||||||
device_handle_pointer = FFI::MemoryPointer.new(:pointer)
|
def open(device_name)
|
||||||
check_status!(API.sane_open(device_name.to_s, device_handle_pointer))
|
device_handle_pointer = FFI::MemoryPointer.new(:pointer)
|
||||||
device_handle_pointer.read_pointer
|
check_status!(API.sane_open(device_name, device_handle_pointer))
|
||||||
end
|
device_handle_pointer.read_pointer
|
||||||
|
end
|
||||||
def close(device_handle)
|
|
||||||
API.sane_close(device_handle)
|
def close(device_handle)
|
||||||
end
|
API.sane_close(device_handle)
|
||||||
|
end
|
||||||
def get_option_descriptor(device_handle, option)
|
|
||||||
result = API.sane_get_option_descriptor(device_handle, option)
|
def get_option_descriptor(device_handle, option)
|
||||||
API::OptionDescriptor.new(result)
|
result = API.sane_get_option_descriptor(device_handle, option)
|
||||||
end
|
API::OptionDescriptor.new(result)
|
||||||
|
end
|
||||||
def get_option(device_handle, option)
|
|
||||||
descriptor = get_option_descriptor(device_handle, option)
|
def get_option(device_handle, option)
|
||||||
|
descriptor = get_option_descriptor(device_handle, option)
|
||||||
case descriptor[:type]
|
|
||||||
when :string
|
case descriptor[:type]
|
||||||
value_pointer = FFI::MemoryPointer.new(:pointer)
|
when :string
|
||||||
when :bool, :int, :fixed
|
value_pointer = FFI::MemoryPointer.new(:pointer)
|
||||||
value_pointer = FFI::MemoryPointer.new(:int)
|
when :bool, :int, :fixed
|
||||||
else
|
value_pointer = FFI::MemoryPointer.new(:int)
|
||||||
return nil
|
else
|
||||||
end
|
return nil
|
||||||
|
end
|
||||||
check_status!(API.sane_control_option(device_handle, option, :get_value, value_pointer, FFI::Pointer::NULL))
|
|
||||||
|
check_status!(API.sane_control_option(device_handle, option, :get_value, value_pointer, FFI::Pointer::NULL))
|
||||||
case descriptor[:type]
|
|
||||||
when :string
|
case descriptor[:type]
|
||||||
value_pointer.read_string
|
when :string
|
||||||
when :bool
|
value_pointer.read_string
|
||||||
!value_pointer.read_int.zero?
|
when :bool
|
||||||
when :int, :fixed
|
!value_pointer.read_int.zero?
|
||||||
value_pointer.read_int
|
when :int, :fixed
|
||||||
end
|
value_pointer.read_int
|
||||||
end
|
end
|
||||||
|
end
|
||||||
def set_option(device_handle, option, value)
|
|
||||||
descriptor = get_option_descriptor(device_handle, option)
|
def set_option(device_handle, option, value)
|
||||||
|
descriptor = get_option_descriptor(device_handle, option)
|
||||||
case descriptor[:type]
|
|
||||||
when :string
|
case descriptor[:type]
|
||||||
value_pointer = FFI::MemoryPointer.from_string(value)
|
when :string
|
||||||
when :int, :fixed
|
value_pointer = FFI::MemoryPointer.from_string(value)
|
||||||
value_pointer = FFI::MemoryPointer.new(:int).write_int(value)
|
when :int, :fixed
|
||||||
when :bool
|
value_pointer = FFI::MemoryPointer.new(:int).write_int(value)
|
||||||
value_pointer = FFI::MemoryPointer.new(:int).write_int(value ? 1 : 0)
|
when :bool
|
||||||
else
|
value_pointer = FFI::MemoryPointer.new(:int).write_int(value ? 1 : 0)
|
||||||
return nil
|
else
|
||||||
end
|
return nil
|
||||||
|
end
|
||||||
check_status!(API.sane_control_option(device_handle, option, :set_value, value_pointer, FFI::Pointer::NULL))
|
|
||||||
|
check_status!(API.sane_control_option(device_handle, option, :set_value, value_pointer, FFI::Pointer::NULL))
|
||||||
case descriptor[:type]
|
|
||||||
when :string
|
case descriptor[:type]
|
||||||
value_pointer.read_string
|
when :string
|
||||||
when :bool
|
value_pointer.read_string
|
||||||
!value_pointer.read_int.zero?
|
when :bool
|
||||||
when :int, :fixed
|
!value_pointer.read_int.zero?
|
||||||
value_pointer.read_int
|
when :int, :fixed
|
||||||
end
|
value_pointer.read_int
|
||||||
end
|
end
|
||||||
|
end
|
||||||
def check_status!(status)
|
|
||||||
raise Error.new(API.sane_strstatus(status), status) if status != :good
|
def strstatus(status)
|
||||||
end
|
API.sane_strstatus(status)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def check_status!(status)
|
||||||
|
raise Error.new(strstatus(status), status) if status != :good
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
module Sane
|
class Sane
|
||||||
module API
|
module API
|
||||||
extend FFI::Library
|
extend FFI::Library
|
||||||
|
|
||||||
|
@ -12,9 +12,6 @@ module Sane
|
||||||
|
|
||||||
class Device < FFI::Struct
|
class Device < FFI::Struct
|
||||||
layout :name, :string, :vendor, :string, :model, :string, :type, :string
|
layout :name, :string, :vendor, :string, :model, :string, :type, :string
|
||||||
|
|
||||||
def to_s; self[:name] end
|
|
||||||
def inspect; "#<#{self.class.name}:'#{to_s}'>" end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class OptionDescriptor < FFI::Struct
|
class OptionDescriptor < FFI::Struct
|
||||||
|
|
|
@ -1,11 +1,29 @@
|
||||||
module Sane
|
class Sane
|
||||||
class Device
|
class Device
|
||||||
def initialize(handle)
|
def initialize(name)
|
||||||
@handle = handle
|
@name = name
|
||||||
|
@handle = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def open
|
||||||
|
@handle = Sane.open(@name) if closed?
|
||||||
|
if block_given?
|
||||||
|
yield self
|
||||||
|
close
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def closed?
|
||||||
|
@handle.nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
def opened?
|
||||||
|
!closed?
|
||||||
end
|
end
|
||||||
|
|
||||||
def close
|
def close
|
||||||
Sane.close(@handle)
|
Sane.close(@handle) if opened?
|
||||||
|
@handle = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
module Sane
|
class Sane
|
||||||
class Error < StandardError
|
class Error < StandardError
|
||||||
attr_reader :status
|
attr_reader :status
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
|
require "singleton"
|
||||||
|
require "forwardable"
|
||||||
|
|
||||||
require "ffi"
|
require "ffi"
|
||||||
|
|
||||||
require "sane"
|
require "sane"
|
||||||
require "sane/api"
|
require "sane/api"
|
||||||
require "sane/error"
|
require "sane/error"
|
||||||
|
require "sane/device"
|
||||||
|
|
||||||
module Scanner
|
module Scanner
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue