From 4a6b2d5739e33ff61f083e66306d358f3e517110 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ku=C5=BAma?= Date: Tue, 31 May 2011 23:21:15 +0200 Subject: [PATCH] added singleton --- lib/sane.rb | 189 ++++++++++++++++++++++++--------------------- lib/sane/api.rb | 5 +- lib/sane/device.rb | 26 ++++++- lib/sane/error.rb | 2 +- lib/scanner.rb | 4 + 5 files changed, 130 insertions(+), 96 deletions(-) diff --git a/lib/sane.rb b/lib/sane.rb index 73c9c15..53727c0 100644 --- a/lib/sane.rb +++ b/lib/sane.rb @@ -1,94 +1,109 @@ -module Sane +class Sane + include Singleton + class << self - def init - version_code = FFI::MemoryPointer.new(:int) - check_status!(API.sane_init(version_code, FFI::Pointer::NULL)) - version_code.read_int - end + extend Forwardable + delegate [:init, :exit, :get_devices, :open, :close, :get_option_descriptor, :get_option, :set_option, :strstatus] => :instance + end - def exit - API.sane_exit - end + def initialize + init + 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 + def init + version_code = FFI::MemoryPointer.new(:int) + check_status!(API.sane_init(version_code, FFI::Pointer::NULL)) + version_code.read_int + end + + def exit + API.sane_exit + 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 - - def open(device_name) - device_handle_pointer = FFI::MemoryPointer.new(:pointer) - check_status!(API.sane_open(device_name.to_s, device_handle_pointer)) - device_handle_pointer.read_pointer - end - - def close(device_handle) - API.sane_close(device_handle) - end - - def get_option_descriptor(device_handle, option) - result = API.sane_get_option_descriptor(device_handle, option) - API::OptionDescriptor.new(result) - end - - def get_option(device_handle, option) - descriptor = get_option_descriptor(device_handle, option) - - case descriptor[:type] - when :string - value_pointer = FFI::MemoryPointer.new(:pointer) - when :bool, :int, :fixed - value_pointer = FFI::MemoryPointer.new(:int) - else - return nil - end - - check_status!(API.sane_control_option(device_handle, option, :get_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 - end - end - - def set_option(device_handle, option, value) - 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 - end - - 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 - end - end - - def check_status!(status) - raise Error.new(API.sane_strstatus(status), status) if status != :good - end + end + + def open(device_name) + device_handle_pointer = FFI::MemoryPointer.new(:pointer) + check_status!(API.sane_open(device_name, device_handle_pointer)) + device_handle_pointer.read_pointer + end + + def close(device_handle) + API.sane_close(device_handle) + end + + def get_option_descriptor(device_handle, option) + result = API.sane_get_option_descriptor(device_handle, option) + API::OptionDescriptor.new(result) + end + + def get_option(device_handle, option) + descriptor = get_option_descriptor(device_handle, option) + + case descriptor[:type] + when :string + value_pointer = FFI::MemoryPointer.new(:pointer) + when :bool, :int, :fixed + value_pointer = FFI::MemoryPointer.new(:int) + else + return nil + end + + check_status!(API.sane_control_option(device_handle, option, :get_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 + end + end + + def set_option(device_handle, option, value) + 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 + end + + 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 + end + end + + def strstatus(status) + API.sane_strstatus(status) + end + + private + + def check_status!(status) + raise Error.new(strstatus(status), status) if status != :good end end diff --git a/lib/sane/api.rb b/lib/sane/api.rb index 88d5201..aaef9f4 100644 --- a/lib/sane/api.rb +++ b/lib/sane/api.rb @@ -1,4 +1,4 @@ -module Sane +class Sane module API extend FFI::Library @@ -12,9 +12,6 @@ module Sane class Device < FFI::Struct layout :name, :string, :vendor, :string, :model, :string, :type, :string - - def to_s; self[:name] end - def inspect; "#<#{self.class.name}:'#{to_s}'>" end end class OptionDescriptor < FFI::Struct diff --git a/lib/sane/device.rb b/lib/sane/device.rb index ed53351..94ebefe 100644 --- a/lib/sane/device.rb +++ b/lib/sane/device.rb @@ -1,11 +1,29 @@ -module Sane +class Sane class Device - def initialize(handle) - @handle = handle + def initialize(name) + @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 def close - Sane.close(@handle) + Sane.close(@handle) if opened? + @handle = nil end end end diff --git a/lib/sane/error.rb b/lib/sane/error.rb index d9ce8ee..0a929aa 100644 --- a/lib/sane/error.rb +++ b/lib/sane/error.rb @@ -1,4 +1,4 @@ -module Sane +class Sane class Error < StandardError attr_reader :status diff --git a/lib/scanner.rb b/lib/scanner.rb index 0f4e542..3e1a03b 100644 --- a/lib/scanner.rb +++ b/lib/scanner.rb @@ -1,8 +1,12 @@ +require "singleton" +require "forwardable" + require "ffi" require "sane" require "sane/api" require "sane/error" +require "sane/device" module Scanner