module Ethon::Curls::Options
def self.option(ftype,name,type,num,opts=nil)
def self.option(ftype,name,type,num,opts=nil) case type when :enum if opts.is_a? Array then opts=Hash[opts.each_with_index.to_a] elsif not opts.is_a? Hash then raise TypeError, "Ethon::Curls::Options #{ftype} #{name} Expected opts to be an Array or a Hash." end when :bitmask if opts.is_a? Array then if opts.last.is_a? Hash then hopts=opts.pop else hopts={} end opts.each_with_index do |v,i| next if v.nil? if i==0 then hopts[v]=0 else hopts[v]=1<<(i-1) end end opts=hopts elsif not opts.is_a? Hash then raise TypeError, "Ethon::Curls::Options #{ftype} #{name} Expected opts to be an Array or a Hash." end opts[:all]=-1 unless opts.include? :all opts.each do |k,v| if v.is_a? Array then opts[k]=v.map { |b| opts[b] }.inject :| end end when :buffer raise TypeError, "Ethon::Curls::Options #{ftype} #{name} Expected opts to be an Array or a Hash." unless opts.is_a? Integer else raise ArgumentError, "Ethon::Curls::Options #{ftype} #{name} Expected no opts." unless opts.nil? end opthash=const_get(FOPTION_STRINGS[ftype]) opthash[name] = { :type => type, :opt => OPTION_TYPE_BASE[OPTION_TYPE_MAP[type]] + num, :opts => opts } end
def self.option_alias(ftype,name,*aliases)
def self.option_alias(ftype,name,*aliases) opthash=const_get(FOPTION_STRINGS[ftype]) aliases.each { |a| opthash[a]=opthash[name] } end
def self.option_type(type)
def self.option_type(type) cname = FOPTION_STRINGS[type] const_set(cname, {}) define_method(OPTION_STRINGS[type]) do |rt| return Ethon::Curls::Options.const_get(cname).map { |k, v| [k, v[:opt]] } if rt == :enum Ethon::Curls::Options.const_get(cname) end end
def set_option(option, value, handle, type = :easy)
def set_option(option, value, handle, type = :easy) type = type.to_sym unless type.is_a?(Symbol) raise NameError, "Ethon::Curls::Options unknown type #{type}." unless respond_to?(OPTION_STRINGS[type]) opthash=send(OPTION_STRINGS[type], nil) raise Errors::InvalidOption.new(option) unless opthash.include?(option) case opthash[option][:type] when :none return if value.nil? value=1 va_type=:long when :int return if value.nil? va_type=:long value=value.to_i when :bool return if value.nil? va_type=:long value=(value&&value!=0) ? 1 : 0 when :time return if value.nil? va_type=:long value=value.to_i when :enum return if value.nil? va_type=:long value = case value when Symbol opthash[option][:opts][value] when String opthash[option][:opts][value.to_sym] else value end.to_i when :bitmask return if value.nil? va_type=:long value = case value when Symbol opthash[option][:opts][value] when Array value.inject(0) { |res,v| res|opthash[option][:opts][v] } else value end.to_i when :string va_type=:string value=value.to_s unless value.nil? when :string_as_pointer va_type = :pointer s = '' s = value.to_s unless value.nil? value = FFI::MemoryPointer.new(:char, s.bytesize) value.put_bytes(0, s) when :string_escape_null va_type=:string value=Util.escape_zero_byte(value) unless value.nil? when :ffipointer va_type=:pointer raise Errors::InvalidValue.new(option,value) unless value.nil? or value.is_a? FFI::Pointer when :curl_slist va_type=:pointer raise Errors::InvalidValue.new(option,value) unless value.nil? or value.is_a? FFI::Pointer when :buffer raise NotImplementedError, "Ethon::Curls::Options option #{option} buffer type not implemented." when :dontuse_object raise NotImplementedError, "Ethon::Curls::Options option #{option} type not implemented." when :cbdata raise NotImplementedError, "Ethon::Curls::Options option #{option} callback data type not implemented. Use Ruby closures." when :callback va_type=:callback raise Errors::InvalidValue.new(option,value) unless value.nil? or value.is_a? Proc when :socket_callback va_type=:socket_callback raise Errors::InvalidValue.new(option,value) unless value.nil? or value.is_a? Proc when :timer_callback va_type=:timer_callback raise Errors::InvalidValue.new(option,value) unless value.nil? or value.is_a? Proc when :debug_callback va_type=:debug_callback raise Errors::InvalidValue.new(option,value) unless value.nil? or value.is_a? Proc when :progress_callback va_type=:progress_callback raise Errors::InvalidValue.new(option,value) unless value.nil? or value.is_a? Proc when :off_t return if value.nil? va_type=:int64 value=value.to_i end if va_type==:long or va_type==:int64 then bits=FFI.type_size(va_type)*8 tv=((value<0) ? value.abs-1 : value) raise Errors::InvalidValue.new(option,value) unless tv<(1<<bits) end send(FUNCS[type], handle, opthash[option][:opt], va_type, value) end