Class: FFI::Tcl::EvalResult

Inherits:
Object show all
Defined in:
lib/ffi-tk/ffi/tcl/eval_result.rb

Overview

This whole class feels very awkward, maybe it should be merged with Obj.

Constant Summary collapse

TYPES =
{}

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.guess(interp, obj, fallback = nil) ⇒ Object



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
# File 'lib/ffi-tk/ffi/tcl/eval_result.rb', line 33

def self.guess(interp, obj, fallback = nil)
  obj = Obj.new(obj) unless obj.respond_to?(:type)
  # p obj: obj, obj_type: obj.type
  type = TYPES[obj.type.to_i]

  case type
  when :list
    to_list(interp, obj)
  when :string, :pixel, :cmdName
    to_string(interp, obj)
  when :int
    to_int(interp, obj)
  when :double
    to_double(interp, obj)
  when :dict
    to_dict(interp, obj)
  when :window
    to_window(interp, obj)
  else
    if fallback
      __send__(fallback, interp, obj)
    elsif type.nil? && obj.bytes == ''
      nil
    elsif type.nil?
      to_string(interp, obj)
    else
      raise 'Unknown type: %p' % [type]
    end
  end
end

.map_list_core(interp, obj, &block) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/ffi-tk/ffi/tcl/eval_result.rb', line 107

def self.map_list_core(interp, obj, &block)
  objc_ptr = MemoryPointer.new(:int)
  objv_ptr = MemoryPointer.new(:pointer)

  if Tcl.list_obj_get_elements(interp, obj, objc_ptr, objv_ptr) == 0
    return [] if objv_ptr.get_pointer(0).null?
    objv_ptr.get_pointer(0)
            .read_array_of_pointer(objc_ptr.get_int(0))
            .map(&block)
  else
    panic(interp, 'Tcl_ListObjGetElements')
  end
end

.panic(interp, function) ⇒ Object



150
151
152
153
154
155
156
157
158
# File 'lib/ffi-tk/ffi/tcl/eval_result.rb', line 150

def self.panic(interp, function)
  message = guess(interp, Obj.new(Tcl.get_obj_result(interp))).to_s

  if message.empty?
    raise 'Failure during call of: %p' % [function]
  else
    raise '%s during call of: %p' % [message, function]
  end
end

.reset_types(interp) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/ffi-tk/ffi/tcl/eval_result.rb', line 8

def self.reset_types(interp)
  TYPES.clear
  list = Tcl.new_list_obj(0, nil)
  Tcl.append_all_obj_types(interp, list)

  objc_ptr = MemoryPointer.new(:int)
  objv_ptr = MemoryPointer.new(:pointer)

  string_length_ptr = MemoryPointer.new(:int)

  if Tcl.list_obj_get_elements(interp, list, objc_ptr, objv_ptr) == 0
    return [] if objv_ptr.get_pointer(0).null?
    array_ptr = objv_ptr.get_pointer(0)
    array_length = objc_ptr.get_int(0)
    array = array_ptr.read_array_of_pointer(array_length)
    array.each do |type_ptr|
      name = Tcl.get_string_from_obj(type_ptr, string_length_ptr)
      type = Tcl.get_obj_type(name)
      TYPES[type.to_i] = name.to_sym
    end
  else
    panic 'Tcl_ListObjGetElements'
  end
end

.to_boolean(interp, obj) ⇒ Object



121
122
123
124
125
126
127
128
129
# File 'lib/ffi-tk/ffi/tcl/eval_result.rb', line 121

def self.to_boolean(interp, obj)
  boolean_pointer = MemoryPointer.new(:int)

  if Tcl.get_boolean_from_obj(interp, obj, boolean_pointer) == 0
    boolean_pointer.get_int(0) == 1
  else
    panic(interp, 'Tcl_GetBooleanFromObj')
  end
end

.to_dict(interp, obj) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/ffi-tk/ffi/tcl/eval_result.rb', line 68

def self.to_dict(interp, obj)
  out = {}

  search = MemoryPointer.new(:pointer)
  done = MemoryPointer.new(:int)
  key_ptr = MemoryPointer.new(:pointer)
  value_ptr = MemoryPointer.new(:pointer)
  strlen = MemoryPointer.new(:int)

  Tcl.dict_obj_first(interp, obj, search, key_ptr, value_ptr, done)

  while done.get_int(0) != 1
    key = Tcl.get_string_from_obj(key_ptr.get_pointer(0), strlen)
    value = Tcl.get_string_from_obj(value_ptr.get_pointer(0), strlen)
    out[key] = value

    Tcl.dict_obj_next(search, key_ptr, value_ptr, done)
  end

  out
end

.to_double(interp, obj) ⇒ Object



90
91
92
93
94
95
96
97
98
# File 'lib/ffi-tk/ffi/tcl/eval_result.rb', line 90

def self.to_double(interp, obj)
  double_pointer = MemoryPointer.new(:double)

  if Tcl.get_double_from_obj(interp, obj, double_pointer) == 0
    double_pointer.get_double(0)
  else
    raise "Couldn't get double from %p" % [obj]
  end
end

.to_int(interp, obj) ⇒ Object



131
132
133
134
135
136
137
138
139
140
141
# File 'lib/ffi-tk/ffi/tcl/eval_result.rb', line 131

def self.to_int(interp, obj)
  int_pointer = MemoryPointer.new(:int)

  if obj.bytes == ''
    '' # used by text widget -endline
  elsif Tcl.get_int_from_obj(interp, obj, int_pointer) == 0
    int_pointer.get_int(0)
  else
    panic(interp, 'Tcl_GetIntFromObj')
  end
end

.to_list(interp, obj) ⇒ Object



100
101
102
103
104
105
# File 'lib/ffi-tk/ffi/tcl/eval_result.rb', line 100

def self.to_list(interp, obj)
  map_list_core(interp, obj) do |pointer|
    value = guess(interp, pointer, :to_string)
    block_given? ? yield(value) : value
  end
end

.to_string(_interp, obj) ⇒ Object



143
144
145
146
147
148
# File 'lib/ffi-tk/ffi/tcl/eval_result.rb', line 143

def self.to_string(_interp, obj)
  length_pointer = MemoryPointer.new(:int)

  string = Tcl.get_string_from_obj(obj, length_pointer)
  string.force_encoding(Encoding.default_external)
end

.to_window(interp, obj) ⇒ Object



64
65
66
# File 'lib/ffi-tk/ffi/tcl/eval_result.rb', line 64

def self.to_window(interp, obj)
  p interp: interp, obj: obj
end

Instance Method Details

#inspectObject



203
204
205
# File 'lib/ffi-tk/ffi/tcl/eval_result.rb', line 203

def inspect
  "#<EvalResult #{self}>"
end

#to_a(&block) ⇒ Object



160
161
162
# File 'lib/ffi-tk/ffi/tcl/eval_result.rb', line 160

def to_a(&block)
  self.class.to_list(interp, obj, &block)
end

#to_a?(&block) ⇒ Boolean

Returns:

  • (Boolean)


164
165
166
167
# File 'lib/ffi-tk/ffi/tcl/eval_result.rb', line 164

def to_a?(&block)
  value = self.class.to_list(interp, obj, &block)
  value.empty? ? nil : value
end

#to_booleanObject



195
196
197
# File 'lib/ffi-tk/ffi/tcl/eval_result.rb', line 195

def to_boolean
  self.class.to_boolean(interp, obj)
end

#to_fObject



182
183
184
# File 'lib/ffi-tk/ffi/tcl/eval_result.rb', line 182

def to_f
  self.class.to_double(interp, obj)
end

#to_iObject



178
179
180
# File 'lib/ffi-tk/ffi/tcl/eval_result.rb', line 178

def to_i
  self.class.to_int(interp, obj)
end

#to_sObject



186
187
188
# File 'lib/ffi-tk/ffi/tcl/eval_result.rb', line 186

def to_s
  self.class.to_string(interp, obj)
end

#to_s?Boolean

Returns:

  • (Boolean)


190
191
192
193
# File 'lib/ffi-tk/ffi/tcl/eval_result.rb', line 190

def to_s?
  value = self.class.to_string(interp, obj)
  value.empty? ? nil : value
end

#to_symObject



169
170
171
# File 'lib/ffi-tk/ffi/tcl/eval_result.rb', line 169

def to_sym
  self.class.to_string(interp, obj).to_sym
end

#to_sym?Boolean

Returns:

  • (Boolean)


173
174
175
176
# File 'lib/ffi-tk/ffi/tcl/eval_result.rb', line 173

def to_sym?
  value = self.class.to_string(interp, obj).to_sym
  value.empty? ? nil : value.to_sym
end

#to_tclObject



199
200
201
# File 'lib/ffi-tk/ffi/tcl/eval_result.rb', line 199

def to_tcl
  to_s.to_tcl
end