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("#{ftype.to_s.upcase}_OPTIONS") 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("#{ftype.to_s.upcase}_OPTIONS") aliases.each { |a| opthash[a]=opthash[name] } end
def self.option_type(type)
def self.option_type(type) cname="#{type.to_s.upcase}_OPTIONS" c=const_set(cname,{}) eval %Q< def #{type.to_s.downcase}_options(rt=nil) return #{cname}.map { |k,v| [k,v[:opt]] } if rt==:enum #{cname} end > end
def set_option(option, value, handle, type = :easy)
def set_option(option, value, handle, type = :easy) raise NameError, "Ethon::Curls::Options unknown type #{type}." unless respond_to?("#{type.to_s.downcase}_options") opthash=send("#{type.to_s.downcase}_options") raise Errors::InvalidOption.new(option) unless opthash.include?(option) case opthash[option][:type] when :none return if value.nil? value=1 func=:long when :int return if value.nil? func=:long value=value.to_i when :bool return if value.nil? func=:long value=(value&&value!=0) ? 1 : 0 when :time return if value.nil? func=:long value=value.to_i when :enum return if value.nil? func=:long value=opthash[option][:opts][value] if value.is_a? Symbol value=value.to_i when :bitmask return if value.nil? func=:long value=opthash[option][:opts][value] if value.is_a? Symbol value=value.inject(0) { |res,v| res|opthash[option][:opts][v] } if value.is_a? Array value=value.to_i when :string func=:string value=value.to_s unless value.nil? when :string_escape_null func=:string value=Util.escape_zero_byte(value) unless value.nil? when :ffipointer func=:ffipointer raise Errors::InvalidValue.new(option,value) unless value.nil? or value.is_a? FFI::Pointer when :curl_slist func=:ffipointer 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 func=:callback raise Errors::InvalidValue.new(option,value) unless value.nil? or value.is_a? Proc when :debug_callback func=:debug_callback raise Errors::InvalidValue.new(option,value) unless value.nil? or value.is_a? Proc when :off_t return if value.nil? func=:off_t value=value.to_i end if func==:long or func==:off_t then bits=FFI.type_size(:long)*8 if func==:long bits=FFI.type_size(:int64)*8 if func==:off_t tv=((value<0) ? value.abs-1 : value) raise Errors::InvalidValue.new(option,value) unless tv<(1<<bits) end send("#{type}_setopt_#{func}", handle, opthash[option][:opt], value) end