Module: Ethon::Curls::Options

Included in:
Ethon::Curl
Defined in:
lib/ethon/curls/options.rb

Overview

This module contains logic for setting options on easy or multi interface.

Constant Summary collapse

OPTION_TYPE_BASE =
{
  :long => 0,
  :objectpoint => 10000,
  :functionpoint => 20000,
  :off_t => 30000
}
OPTION_TYPE_MAP =
{
  :none => :long,
  :int => :long,
  :bool => :long,
  :time => :long,
  :enum => :long, # Two ways to specify values (as opts parameter):
                  #   * Array of symbols, these will number sequentially
                  #     starting at 0. Skip elements with nil. (see :netrc)
                  #   * Hash of :symbol => enum_value (See :proxytype)
  :bitmask => :long, # Three ways to specify values (as opts parameter):
                     #   * Hash of :symbol => bitmask_value or Array.
                     #     An Array can be an array of already defined
                     #     Symbols, which represents a bitwise or of those
                     #     symbols. (See :httpauth)
                     #   * Array of symbols, these will number the bits
                     #     sequentially (i.e. 0, 1, 2, 4, etc.). Skip
                     #     elements with nil. The last element can be a
                     #     Hash, which will be interpreted as above.
                     #     (See :protocols)
                     # :all defaults to all bits set
  :string => :objectpoint,
  :string_escape_null => :objectpoint,
  :ffipointer => :objectpoint, # FFI::Pointer
  :curl_slist => :objectpoint,
  :buffer => :objectpoint, # A memory buffer of size defined in the options
  :dontuse_object => :objectpoint, # An object we don't support (e.g. FILE*)
  :cbdata => :objectpoint,
  :callback => :functionpoint,
  :debug_callback => :functionpoint,
  :off_t => :off_t,
}

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.option(ftype, name, type, num, opts = nil) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/ethon/curls/options.rb', line 120

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

.option_alias(ftype, name, *aliases) ⇒ Object



166
167
168
169
# File 'lib/ethon/curls/options.rb', line 166

def self.option_alias(ftype,name,*aliases)
  opthash=const_get("#{ftype.to_s.upcase}_OPTIONS")
  aliases.each { |a| opthash[a]=opthash[name] }
end

.option_type(type) ⇒ Object



171
172
173
174
175
176
177
178
179
180
# File 'lib/ethon/curls/options.rb', line 171

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

Instance Method Details

#easyObject

TELNET OPTIONS



213
# File 'lib/ethon/curls/options.rb', line 213

option :easy, :writefunction, :callback, 11

#set_option(option, value, handle, type = :easy) ⇒ Object

Sets appropriate option for easy, depending on value type.

Raises:

  • (NameError)


9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/ethon/curls/options.rb', line 9

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