fiddle 1.0.4 → 1.0.9

Sign up to get free protection for your applications and to get access to all the features.
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.