fiddle 1.0.4 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b7e244560b492c43b7458506409f4d624372766d882e306a48a08fc9ad32671b
4
- data.tar.gz: 9a166eb1dded473780e8ea89d1240da28ff6be73e72f2026eff14f6e55f060b9
3
+ metadata.gz: 05f04e2fc988a1635621c537e5836231c2ae496ed45990523be623b44c8557be
4
+ data.tar.gz: b81aec1d67a6a08413245b483c6aed84052df7f5b907e8111bf1b8a47c2e69bd
5
5
  SHA512:
6
- metadata.gz: 7c4509d95af60a2f16047e431580a3e6b1828b0bcf0820302d678c1b2f8e9462df767ce5a6c7e60ef728fa0d7a3afe667cbbe982e161802dafc49ed0a398bf2a
7
- data.tar.gz: 00623b0e514fad355b76ec9d59273c15759d5991c2832c6df10c23ad06ef98f628d5d6381cfd75449ee0c2811b3f58d66b55824993c5d3aef1a2d2be1d79a8de
6
+ metadata.gz: 7b1c8640fb5a93f6b8c36eb3062f7b795cc10160176fe6d8e3f1370c5ce4ffd2e3036581ed4a3842a8eeb6d595219e8ee370c9c0d996e6213dfcb400fea10c58
7
+ data.tar.gz: fcd3f9cf4d08f760065770d2529f95c17dc8c95f889d691824f98bad1cb03fbeee20dcf005493b4bc9b66850b7fecdf022b13aaa6c359949a2266696a313619f
data/ext/fiddle/closure.c CHANGED
@@ -130,6 +130,10 @@ with_gvl_callback(void *ptr)
130
130
  rb_ary_push(params, ULL2NUM(*(unsigned LONG_LONG *)x->args[i]));
131
131
  break;
132
132
  #endif
133
+ case TYPE_CONST_STRING:
134
+ rb_ary_push(params,
135
+ rb_str_new_cstr(*((const char **)(x->args[i]))));
136
+ break;
133
137
  default:
134
138
  rb_raise(rb_eRuntimeError, "closure args: %d", type);
135
139
  }
@@ -175,6 +179,10 @@ with_gvl_callback(void *ptr)
175
179
  *(unsigned LONG_LONG *)x->resp = NUM2ULL(ret);
176
180
  break;
177
181
  #endif
182
+ case TYPE_CONST_STRING:
183
+ /* Dangerous. Callback must keep reference of the String. */
184
+ *((const char **)(x->resp)) = StringValueCStr(ret);
185
+ break;
178
186
  default:
179
187
  rb_raise(rb_eRuntimeError, "closure retval: %d", type);
180
188
  }
@@ -221,6 +229,7 @@ initialize(int rbargc, VALUE argv[], VALUE self)
221
229
  {
222
230
  VALUE ret;
223
231
  VALUE args;
232
+ VALUE normalized_args;
224
233
  VALUE abi;
225
234
  fiddle_closure * cl;
226
235
  ffi_cif * cif;
@@ -239,21 +248,26 @@ initialize(int rbargc, VALUE argv[], VALUE self)
239
248
 
240
249
  cl->argv = (ffi_type **)xcalloc(argc + 1, sizeof(ffi_type *));
241
250
 
251
+ normalized_args = rb_ary_new_capa(argc);
242
252
  for (i = 0; i < argc; i++) {
243
- int type = NUM2INT(RARRAY_AREF(args, i));
244
- cl->argv[i] = INT2FFI_TYPE(type);
253
+ VALUE arg = rb_fiddle_type_ensure(RARRAY_AREF(args, i));
254
+ rb_ary_push(normalized_args, arg);
255
+ cl->argv[i] = rb_fiddle_int_to_ffi_type(NUM2INT(arg));
245
256
  }
246
257
  cl->argv[argc] = NULL;
247
258
 
259
+ ret = rb_fiddle_type_ensure(ret);
248
260
  rb_iv_set(self, "@ctype", ret);
249
- rb_iv_set(self, "@args", args);
261
+ rb_iv_set(self, "@args", normalized_args);
250
262
 
251
263
  cif = &cl->cif;
252
264
  pcl = cl->pcl;
253
265
 
254
- result = ffi_prep_cif(cif, NUM2INT(abi), argc,
255
- INT2FFI_TYPE(NUM2INT(ret)),
256
- cl->argv);
266
+ result = ffi_prep_cif(cif,
267
+ NUM2INT(abi),
268
+ argc,
269
+ rb_fiddle_int_to_ffi_type(NUM2INT(ret)),
270
+ cl->argv);
257
271
 
258
272
  if (FFI_OK != result)
259
273
  rb_raise(rb_eRuntimeError, "error prepping CIF %d", result);
@@ -24,7 +24,6 @@ typedef union
24
24
  void * pointer; /* ffi_type_pointer */
25
25
  } fiddle_generic;
26
26
 
27
- /* Deprecated. Use rb_fiddle_*() version. */
28
27
  VALUE rb_fiddle_type_ensure(VALUE type);
29
28
  ffi_type * rb_fiddle_int_to_ffi_type(int type);
30
29
  void rb_fiddle_value_to_generic(int type, VALUE *src, fiddle_generic *dst);
@@ -3,6 +3,47 @@ require 'mkmf'
3
3
 
4
4
  # :stopdoc:
5
5
 
6
+ def gcc?
7
+ RbConfig::CONFIG["GCC"] == "yes"
8
+ end
9
+
10
+ def disable_optimization_build_flag(flags)
11
+ if gcc?
12
+ expanded_flags = RbConfig.expand(flags.dup)
13
+ optimization_option_pattern = /(^|\s)?-O\d(\s|$)?/
14
+ if optimization_option_pattern.match?(expanded_flags)
15
+ expanded_flags.gsub(optimization_option_pattern, '\\1-Og\\2')
16
+ else
17
+ flags + " -Og"
18
+ end
19
+ else
20
+ flags
21
+ end
22
+ end
23
+
24
+ def enable_debug_build_flag(flags)
25
+ if gcc?
26
+ expanded_flags = RbConfig.expand(flags.dup)
27
+ debug_option_pattern = /(^|\s)-g(?:gdb)?\d?(\s|$)/
28
+ if debug_option_pattern.match?(expanded_flags)
29
+ expanded_flags.gsub(debug_option_pattern, '\\1-ggdb3\\2')
30
+ else
31
+ flags + " -ggdb3"
32
+ end
33
+ else
34
+ flags
35
+ end
36
+ end
37
+
38
+ checking_for(checking_message("--enable-debug-build option")) do
39
+ enable_debug_build = enable_config("debug-build", false)
40
+ if enable_debug_build
41
+ $CFLAGS = disable_optimization_build_flag($CFLAGS)
42
+ $CFLAGS = enable_debug_build_flag($CFLAGS)
43
+ end
44
+ enable_debug_build
45
+ end
46
+
6
47
  libffi_version = nil
7
48
  have_libffi = false
8
49
  bundle = enable_config('bundled-libffi')
@@ -137,8 +178,10 @@ else
137
178
  have_func('ffi_closure_alloc', ffi_header)
138
179
  end
139
180
 
140
- if libffi
141
- $defs << "-DHAVE_FFI_PREP_CIF_VAR"
181
+ if libffi_version
182
+ if (libffi_version <=> [3, 0, 11]) >= 0
183
+ $defs << "-DHAVE_FFI_PREP_CIF_VAR"
184
+ end
142
185
  else
143
186
  have_func('ffi_prep_cif_var', ffi_header)
144
187
  end
@@ -157,6 +200,8 @@ elsif have_header "windows.h"
157
200
  %w{ LoadLibrary FreeLibrary GetProcAddress }.each do |func|
158
201
  abort "missing function #{func}" unless have_func(func)
159
202
  end
203
+
204
+ have_library "ws2_32"
160
205
  end
161
206
 
162
207
  have_const('FFI_STDCALL', ffi_header)
@@ -375,10 +375,18 @@ function_call(int argc, VALUE argv[], VALUE self)
375
375
  (void)rb_thread_call_without_gvl(nogvl_ffi_call, &args, 0, 0);
376
376
  }
377
377
 
378
- rb_funcall(mFiddle, rb_intern("last_error="), 1, INT2NUM(errno));
378
+ {
379
+ int errno_keep = errno;
379
380
  #if defined(_WIN32)
380
- rb_funcall(mFiddle, rb_intern("win32_last_error="), 1, INT2NUM(errno));
381
+ DWORD error = WSAGetLastError();
382
+ int socket_error = WSAGetLastError();
383
+ rb_funcall(mFiddle, rb_intern("win32_last_error="), 1,
384
+ ULONG2NUM(error));
385
+ rb_funcall(mFiddle, rb_intern("win32_last_socket_error="), 1,
386
+ INT2NUM(socket_error));
381
387
  #endif
388
+ rb_funcall(mFiddle, rb_intern("last_error="), 1, INT2NUM(errno_keep));
389
+ }
382
390
 
383
391
  ALLOCV_END(alloc_buffer);
384
392
 
@@ -1,5 +1,6 @@
1
1
  #include <stdbool.h>
2
2
  #include <ruby/ruby.h>
3
+ #include <ruby/encoding.h>
3
4
 
4
5
  #ifdef HAVE_RUBY_MEMORY_VIEW_H
5
6
  # include <ruby/memory_view.h>
@@ -35,12 +36,25 @@ fiddle_memview_mark(void *ptr)
35
36
  }
36
37
 
37
38
  static void
38
- fiddle_memview_free(void *ptr)
39
+ fiddle_memview_release(struct memview_data *data)
39
40
  {
40
- struct memview_data *data = ptr;
41
+ if (NIL_P(data->view.obj)) return;
42
+
41
43
  rb_memory_view_release(&data->view);
42
- if (data->members)
44
+ data->view.obj = Qnil;
45
+ data->view.byte_size = 0;
46
+ if (data->members) {
43
47
  xfree(data->members);
48
+ data->members = NULL;
49
+ data->n_members = 0;
50
+ }
51
+ }
52
+
53
+ static void
54
+ fiddle_memview_free(void *ptr)
55
+ {
56
+ struct memview_data *data = ptr;
57
+ fiddle_memview_release(data);
44
58
  xfree(ptr);
45
59
  }
46
60
 
@@ -48,7 +62,7 @@ static size_t
48
62
  fiddle_memview_memsize(const void *ptr)
49
63
  {
50
64
  const struct memview_data *data = ptr;
51
- return sizeof(*data) + sizeof(rb_memory_view_item_component_t)*data->n_members + (size_t)data->view.len;
65
+ return sizeof(*data) + sizeof(rb_memory_view_item_component_t)*data->n_members + (size_t)data->view.byte_size;
52
66
  }
53
67
 
54
68
  static const rb_data_type_t fiddle_memview_data_type = {
@@ -62,11 +76,32 @@ rb_fiddle_memview_s_allocate(VALUE klass)
62
76
  struct memview_data *data;
63
77
  VALUE obj = TypedData_Make_Struct(klass, struct memview_data, &fiddle_memview_data_type, data);
64
78
  data->view.obj = Qnil;
79
+ data->view.byte_size = 0;
65
80
  data->members = NULL;
66
81
  data->n_members = 0;
67
82
  return obj;
68
83
  }
69
84
 
85
+ static VALUE
86
+ rb_fiddle_memview_release(VALUE obj)
87
+ {
88
+ struct memview_data *data;
89
+ TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
90
+
91
+ if (NIL_P(data->view.obj)) return Qnil;
92
+ fiddle_memview_release(data);
93
+ return Qnil;
94
+ }
95
+
96
+ static VALUE
97
+ rb_fiddle_memview_s_export(VALUE klass, VALUE target)
98
+ {
99
+ ID id_new;
100
+ CONST_ID(id_new, "new");
101
+ VALUE memview = rb_funcall(klass, id_new, 1, target);
102
+ return rb_ensure(rb_yield, memview, rb_fiddle_memview_release, memview);
103
+ }
104
+
70
105
  static VALUE
71
106
  rb_fiddle_memview_initialize(VALUE obj, VALUE target)
72
107
  {
@@ -74,6 +109,7 @@ rb_fiddle_memview_initialize(VALUE obj, VALUE target)
74
109
  TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
75
110
 
76
111
  if (!rb_memory_view_get(target, &data->view, 0)) {
112
+ data->view.obj = Qnil;
77
113
  rb_raise(rb_eArgError, "Unable to get a memory view from %+"PRIsVALUE, target);
78
114
  }
79
115
 
@@ -90,13 +126,13 @@ rb_fiddle_memview_get_obj(VALUE obj)
90
126
  }
91
127
 
92
128
  static VALUE
93
- rb_fiddle_memview_get_length(VALUE obj)
129
+ rb_fiddle_memview_get_byte_size(VALUE obj)
94
130
  {
95
131
  struct memview_data *data;
96
132
  TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
97
133
 
98
134
  if (NIL_P(data->view.obj)) return Qnil;
99
- return SSIZET2NUM(data->view.len);
135
+ return SSIZET2NUM(data->view.byte_size);
100
136
  }
101
137
 
102
138
  static VALUE
@@ -233,14 +269,46 @@ rb_fiddle_memview_aref(int argc, VALUE *argv, VALUE obj)
233
269
  return rb_memory_view_extract_item_members(ptr, data->members, data->n_members);
234
270
  }
235
271
 
272
+ static VALUE
273
+ rb_fiddle_memview_to_s(VALUE self)
274
+ {
275
+ struct memview_data *data;
276
+ const char *raw_data;
277
+ long byte_size;
278
+ VALUE string;
279
+
280
+ TypedData_Get_Struct(self,
281
+ struct memview_data,
282
+ &fiddle_memview_data_type,
283
+ data);
284
+
285
+ if (NIL_P(data->view.obj)) {
286
+ raw_data = NULL;
287
+ byte_size = 0;
288
+ } else {
289
+ raw_data = data->view.data;
290
+ byte_size = data->view.byte_size;
291
+ }
292
+
293
+ string = rb_enc_str_new_static(raw_data, byte_size, rb_ascii8bit_encoding());
294
+ {
295
+ ID id_memory_view;
296
+ CONST_ID(id_memory_view, "memory_view");
297
+ rb_ivar_set(string, id_memory_view, self);
298
+ }
299
+ return rb_obj_freeze(string);
300
+ }
301
+
236
302
  void
237
303
  Init_fiddle_memory_view(void)
238
304
  {
239
305
  rb_cMemoryView = rb_define_class_under(mFiddle, "MemoryView", rb_cObject);
240
306
  rb_define_alloc_func(rb_cMemoryView, rb_fiddle_memview_s_allocate);
307
+ rb_define_singleton_method(rb_cMemoryView, "export", rb_fiddle_memview_s_export, 1);
241
308
  rb_define_method(rb_cMemoryView, "initialize", rb_fiddle_memview_initialize, 1);
309
+ rb_define_method(rb_cMemoryView, "release", rb_fiddle_memview_release, 0);
242
310
  rb_define_method(rb_cMemoryView, "obj", rb_fiddle_memview_get_obj, 0);
243
- rb_define_method(rb_cMemoryView, "length", rb_fiddle_memview_get_length, 0);
311
+ rb_define_method(rb_cMemoryView, "byte_size", rb_fiddle_memview_get_byte_size, 0);
244
312
  rb_define_method(rb_cMemoryView, "readonly?", rb_fiddle_memview_get_readonly, 0);
245
313
  rb_define_method(rb_cMemoryView, "format", rb_fiddle_memview_get_format, 0);
246
314
  rb_define_method(rb_cMemoryView, "item_size", rb_fiddle_memview_get_item_size, 0);
@@ -249,6 +317,7 @@ Init_fiddle_memory_view(void)
249
317
  rb_define_method(rb_cMemoryView, "strides", rb_fiddle_memview_get_strides, 0);
250
318
  rb_define_method(rb_cMemoryView, "sub_offsets", rb_fiddle_memview_get_sub_offsets, 0);
251
319
  rb_define_method(rb_cMemoryView, "[]", rb_fiddle_memview_aref, -1);
320
+ rb_define_method(rb_cMemoryView, "to_s", rb_fiddle_memview_to_s, 0);
252
321
  }
253
322
 
254
323
  #endif /* FIDDLE_MEMORY_VIEW */
data/ext/fiddle/pointer.c CHANGED
@@ -102,19 +102,19 @@ fiddle_ptr_check_memory_view(VALUE obj)
102
102
  return data;
103
103
  }
104
104
 
105
- static int
105
+ static bool
106
106
  fiddle_ptr_memory_view_available_p(VALUE obj)
107
107
  {
108
108
  return fiddle_ptr_check_memory_view(obj) != NULL;
109
109
  }
110
110
 
111
- static int
111
+ static bool
112
112
  fiddle_ptr_get_memory_view(VALUE obj, rb_memory_view_t *view, int flags)
113
113
  {
114
114
  struct ptr_data *data = fiddle_ptr_check_memory_view(obj);
115
115
  rb_memory_view_init_as_byte_array(view, obj, data->ptr, data->size, true);
116
116
 
117
- return 1;
117
+ return true;
118
118
  }
119
119
 
120
120
  static const rb_memory_view_entry_t fiddle_ptr_memory_view_entry = {
@@ -770,6 +770,7 @@ rb_fiddle_ptr_s_to_ptr(VALUE self, VALUE val)
770
770
  }
771
771
  else if (RTEST(rb_obj_is_kind_of(val, rb_cString))){
772
772
  char *str = StringValuePtr(val);
773
+ wrap = val;
773
774
  ptr = rb_fiddle_ptr_new(str, RSTRING_LEN(val), NULL);
774
775
  }
775
776
  else if ((vptr = rb_check_funcall(val, id_to_ptr, 0, 0)) != Qundef){
data/lib/fiddle.rb CHANGED
@@ -17,6 +17,18 @@ module Fiddle
17
17
  def self.win32_last_error= error
18
18
  Thread.current[:__FIDDLE_WIN32_LAST_ERROR__] = error
19
19
  end
20
+
21
+ # Returns the last win32 socket +Error+ of the current executing
22
+ # +Thread+ or nil if none
23
+ def self.win32_last_socket_error
24
+ Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__]
25
+ end
26
+
27
+ # Sets the last win32 socket +Error+ of the current executing
28
+ # +Thread+ to +error+
29
+ def self.win32_last_socket_error= error
30
+ Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__] = error
31
+ end
20
32
  end
21
33
 
22
34
  # Returns the last +Error+ of the current executing +Thread+ or nil if none
@@ -148,9 +148,11 @@ module Fiddle
148
148
  #
149
149
  def parse_ctype(ty, tymap=nil)
150
150
  tymap ||= {}
151
- case ty
152
- when Array
151
+ if ty.is_a?(Array)
153
152
  return [parse_ctype(ty[0], tymap), ty[1]]
153
+ end
154
+ ty = ty.gsub(/\Aconst\s+/, "")
155
+ case ty
154
156
  when 'void'
155
157
  return TYPE_VOID
156
158
  when /\A(?:(?:signed\s+)?long\s+long(?:\s+int\s+)?|int64_t)(?:\s+\w+)?\z/
@@ -19,5 +19,11 @@ module Fiddle
19
19
  def to_i
20
20
  ptr.to_i
21
21
  end
22
+
23
+ # Turn this function in to a proc
24
+ def to_proc
25
+ this = self
26
+ lambda { |*args| this.call(*args) }
27
+ end
22
28
  end
23
29
  end
data/lib/fiddle/types.rb CHANGED
@@ -27,28 +27,29 @@ module Fiddle
27
27
  # * WORD
28
28
  module Win32Types
29
29
  def included(m) # :nodoc:
30
+ # https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types
30
31
  m.module_eval{
31
- typealias "DWORD", "unsigned long"
32
- typealias "PDWORD", "unsigned long *"
33
- typealias "DWORD32", "unsigned long"
34
- typealias "DWORD64", "unsigned long long"
35
- typealias "WORD", "unsigned short"
36
- typealias "PWORD", "unsigned short *"
32
+ typealias "ATOM", "WORD"
37
33
  typealias "BOOL", "int"
38
- typealias "ATOM", "int"
39
34
  typealias "BYTE", "unsigned char"
40
- typealias "PBYTE", "unsigned char *"
35
+ typealias "DWORD", "unsigned long"
36
+ typealias "DWORD32", "uint32_t"
37
+ typealias "DWORD64", "uint64_t"
38
+ typealias "HANDLE", "PVOID"
39
+ typealias "HDC", "HANDLE"
40
+ typealias "HINSTANCE", "HANDLE"
41
+ typealias "HWND", "HANDLE"
42
+ typealias "LPCSTR", "const char *"
43
+ typealias "LPSTR", "char *"
44
+ typealias "PBYTE", "BYTE *"
45
+ typealias "PDWORD", "DWORD *"
46
+ typealias "PHANDLE", "HANDLE *"
47
+ typealias "PVOID", "void *"
48
+ typealias "PWORD", "WORD *"
49
+ typealias "UCHAR", "unsigned char"
41
50
  typealias "UINT", "unsigned int"
42
51
  typealias "ULONG", "unsigned long"
43
- typealias "UCHAR", "unsigned char"
44
- typealias "HANDLE", "uintptr_t"
45
- typealias "PHANDLE", "void*"
46
- typealias "PVOID", "void*"
47
- typealias "LPCSTR", "char*"
48
- typealias "LPSTR", "char*"
49
- typealias "HINSTANCE", "unsigned int"
50
- typealias "HDC", "unsigned int"
51
- typealias "HWND", "unsigned int"
52
+ typealias "WORD", "unsigned short"
52
53
  }
53
54
  end
54
55
  module_function :included
@@ -1,3 +1,3 @@
1
1
  module Fiddle
2
- VERSION = "1.0.4"
2
+ VERSION = "1.0.9"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fiddle
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 1.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Patterson
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-12-10 00:00:00.000000000 Z
12
+ date: 2021-06-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -118,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
118
118
  - !ruby/object:Gem::Version
119
119
  version: '0'
120
120
  requirements: []
121
- rubygems_version: 3.1.4
121
+ rubygems_version: 3.3.0.dev
122
122
  signing_key:
123
123
  specification_version: 4
124
124
  summary: A libffi wrapper for Ruby.