ffi 0.6.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of ffi might be problematic. Click here for more details.

Files changed (92) hide show
  1. data/History.txt +7 -0
  2. data/LICENSE +10 -21
  3. data/README.rdoc +70 -0
  4. data/Rakefile +56 -84
  5. data/ext/ffi_c/AbstractMemory.c +56 -38
  6. data/ext/ffi_c/AbstractMemory.h +15 -22
  7. data/ext/ffi_c/Buffer.c +61 -22
  8. data/ext/ffi_c/Call.c +52 -540
  9. data/ext/ffi_c/Call.h +1 -1
  10. data/ext/ffi_c/DataConverter.c +62 -0
  11. data/ext/ffi_c/DynamicLibrary.c +21 -1
  12. data/ext/ffi_c/Function.c +252 -30
  13. data/ext/ffi_c/MappedType.c +146 -0
  14. data/{libtest/FunctionTest.c → ext/ffi_c/MappedType.h} +32 -25
  15. data/ext/ffi_c/MemoryPointer.c +12 -33
  16. data/ext/ffi_c/Platform.c +2 -0
  17. data/ext/ffi_c/Pointer.c +66 -28
  18. data/ext/ffi_c/Struct.c +19 -306
  19. data/ext/ffi_c/Struct.h +6 -0
  20. data/ext/ffi_c/StructByReference.c +150 -0
  21. data/{libtest/LastErrorTest.c → ext/ffi_c/StructByReference.h} +30 -21
  22. data/ext/ffi_c/StructLayout.c +26 -16
  23. data/ext/ffi_c/Type.c +39 -68
  24. data/ext/ffi_c/Type.h +12 -22
  25. data/ext/ffi_c/Types.c +20 -5
  26. data/ext/ffi_c/Types.h +7 -7
  27. data/ext/ffi_c/Variadic.c +21 -17
  28. data/ext/ffi_c/extconf.rb +4 -0
  29. data/ext/ffi_c/ffi.c +8 -2
  30. data/ext/ffi_c/rbffi.h +1 -0
  31. data/lib/ffi/autopointer.rb +23 -22
  32. data/lib/ffi/enum.rb +36 -21
  33. data/lib/ffi/errno.rb +20 -0
  34. data/lib/ffi/ffi.rb +13 -80
  35. data/lib/ffi/io.rb +12 -20
  36. data/lib/ffi/library.rb +109 -92
  37. data/lib/ffi/managedstruct.rb +1 -1
  38. data/lib/ffi/memorypointer.rb +15 -21
  39. data/lib/ffi/platform.rb +27 -33
  40. data/lib/ffi/pointer.rb +14 -21
  41. data/lib/ffi/struct.rb +98 -49
  42. data/lib/ffi/struct_layout_builder.rb +158 -0
  43. data/lib/ffi/types.rb +99 -128
  44. data/lib/ffi/union.rb +20 -0
  45. data/lib/ffi/variadic.rb +33 -22
  46. data/spec/ffi/async_callback_spec.rb +23 -0
  47. data/spec/ffi/callback_spec.rb +62 -0
  48. data/spec/ffi/custom_param_type.rb +31 -0
  49. data/spec/ffi/custom_type_spec.rb +73 -0
  50. data/spec/ffi/enum_spec.rb +19 -0
  51. data/spec/ffi/ffi_spec.rb +24 -0
  52. data/spec/ffi/pointer_spec.rb +15 -0
  53. data/spec/ffi/rbx/memory_pointer_spec.rb +7 -1
  54. data/spec/ffi/strptr_spec.rb +36 -0
  55. data/spec/ffi/struct_packed_spec.rb +46 -0
  56. data/spec/ffi/struct_spec.rb +19 -5
  57. data/spec/ffi/typedef_spec.rb +14 -0
  58. data/tasks/ann.rake +80 -0
  59. data/tasks/extension.rake +25 -0
  60. data/tasks/gem.rake +200 -0
  61. data/tasks/git.rake +41 -0
  62. data/tasks/notes.rake +27 -0
  63. data/tasks/post_load.rake +34 -0
  64. data/tasks/rdoc.rake +50 -0
  65. data/tasks/rubyforge.rake +55 -0
  66. data/tasks/setup.rb +301 -0
  67. data/tasks/spec.rake +54 -0
  68. data/tasks/svn.rake +47 -0
  69. data/tasks/test.rake +40 -0
  70. metadata +139 -131
  71. data/README.md +0 -109
  72. data/ext/ffi_c/AutoPointer.c +0 -60
  73. data/ext/ffi_c/AutoPointer.h +0 -18
  74. data/ext/ffi_c/Ffi_c.iml +0 -12
  75. data/ffi.gemspec +0 -18
  76. data/gen/log +0 -1
  77. data/lib/Lib.iml +0 -21
  78. data/libtest/Benchmark.c +0 -73
  79. data/libtest/BoolTest.c +0 -52
  80. data/libtest/BufferTest.c +0 -52
  81. data/libtest/ClosureTest.c +0 -173
  82. data/libtest/EnumTest.c +0 -55
  83. data/libtest/GNUmakefile +0 -141
  84. data/libtest/GlobalVariable.c +0 -56
  85. data/libtest/NumberTest.c +0 -145
  86. data/libtest/PointerTest.c +0 -84
  87. data/libtest/ReferenceTest.c +0 -44
  88. data/libtest/StringTest.c +0 -55
  89. data/libtest/StructTest.c +0 -247
  90. data/libtest/UnionTest.c +0 -64
  91. data/libtest/VariadicTest.c +0 -57
  92. data/spec/ffi/Ffi.iml +0 -12
@@ -0,0 +1,146 @@
1
+ /*
2
+ * Copyright (c) 2010, Wayne Meissner
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions are met:
7
+ *
8
+ * * Redistributions of source code must retain the above copyright notice, this
9
+ * list of conditions and the following disclaimer.
10
+ * * Redistributions in binary form must reproduce the above copyright notice
11
+ * this list of conditions and the following disclaimer in the documentation
12
+ * and/or other materials provided with the distribution.
13
+ * * The name of the author or authors may not be used to endorse or promote
14
+ * products derived from this software without specific prior written permission.
15
+ *
16
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
+ */
27
+
28
+ #include <ruby.h>
29
+
30
+ #include <ffi.h>
31
+ #include "rbffi.h"
32
+
33
+ #include "Type.h"
34
+ #include "MappedType.h"
35
+
36
+
37
+ static VALUE mapped_allocate(VALUE);
38
+ static VALUE mapped_initialize(VALUE, VALUE);
39
+ static void mapped_mark(MappedType *);
40
+ static ID id_native_type, id_to_native, id_from_native;
41
+
42
+ VALUE rbffi_MappedTypeClass = Qnil;
43
+
44
+ static VALUE
45
+ mapped_allocate(VALUE klass)
46
+ {
47
+ MappedType* m;
48
+
49
+ VALUE obj = Data_Make_Struct(klass, MappedType, mapped_mark, -1, m);
50
+
51
+ m->rbConverter = Qnil;
52
+ m->rbType = Qnil;
53
+ m->type = NULL;
54
+ m->base.nativeType = NATIVE_MAPPED;
55
+ m->base.ffiType = &ffi_type_void;
56
+
57
+ return obj;
58
+ }
59
+
60
+ static VALUE
61
+ mapped_initialize(VALUE self, VALUE rbConverter)
62
+ {
63
+ MappedType* m = NULL;
64
+ Type* t = NULL;
65
+
66
+ if (!rb_respond_to(rbConverter, id_native_type)) {
67
+ rb_raise(rb_eNoMethodError, "native_type method not implemented");
68
+ }
69
+
70
+ if (!rb_respond_to(rbConverter, id_to_native)) {
71
+ rb_raise(rb_eNoMethodError, "to_native method not implemented");
72
+ }
73
+
74
+ if (!rb_respond_to(rbConverter, id_from_native)) {
75
+ rb_raise(rb_eNoMethodError, "from_native method not implemented");
76
+ }
77
+
78
+ Data_Get_Struct(self, MappedType, m);
79
+ m->rbType = rb_funcall2(rbConverter, id_native_type, 0, NULL);
80
+ if (!(rb_obj_is_kind_of(m->rbType, rbffi_TypeClass))) {
81
+ rb_raise(rb_eTypeError, "native_type did not return instance of FFI::Type");
82
+ }
83
+
84
+ m->rbConverter = rbConverter;
85
+ Data_Get_Struct(m->rbType, Type, m->type);
86
+ m->base.ffiType = m->type->ffiType;
87
+
88
+ return self;
89
+ }
90
+
91
+ static void
92
+ mapped_mark(MappedType* m)
93
+ {
94
+ rb_gc_mark(m->rbType);
95
+ rb_gc_mark(m->rbConverter);
96
+ }
97
+
98
+ static VALUE
99
+ mapped_native_type(VALUE self)
100
+ {
101
+ MappedType*m = NULL;
102
+ Data_Get_Struct(self, MappedType, m);
103
+
104
+ return m->rbType;
105
+ }
106
+
107
+ static VALUE
108
+ mapped_to_native(int argc, VALUE* argv, VALUE self)
109
+ {
110
+ MappedType*m = NULL;
111
+
112
+ Data_Get_Struct(self, MappedType, m);
113
+
114
+ return rb_funcall2(m->rbConverter, id_to_native, argc, argv);
115
+ }
116
+
117
+ static VALUE
118
+ mapped_from_native(int argc, VALUE* argv, VALUE self)
119
+ {
120
+ MappedType*m = NULL;
121
+
122
+ Data_Get_Struct(self, MappedType, m);
123
+
124
+ return rb_funcall2(m->rbConverter, id_from_native, argc, argv);
125
+ }
126
+
127
+ void
128
+ rbffi_MappedType_Init(VALUE moduleFFI)
129
+ {
130
+
131
+ rbffi_MappedTypeClass = rb_define_class_under(rbffi_TypeClass, "Mapped", rbffi_TypeClass);
132
+
133
+ rb_global_variable(&rbffi_MappedTypeClass);
134
+
135
+ id_native_type = rb_intern("native_type");
136
+ id_to_native = rb_intern("to_native");
137
+ id_from_native = rb_intern("from_native");
138
+
139
+ rb_define_alloc_func(rbffi_MappedTypeClass, mapped_allocate);
140
+ rb_define_method(rbffi_MappedTypeClass, "initialize", mapped_initialize, 1);
141
+ rb_define_method(rbffi_MappedTypeClass, "type", mapped_native_type, 0);
142
+ rb_define_method(rbffi_MappedTypeClass, "native_type", mapped_native_type, 0);
143
+ rb_define_method(rbffi_MappedTypeClass, "to_native", mapped_to_native, -1);
144
+ rb_define_method(rbffi_MappedTypeClass, "from_native", mapped_from_native, -1);
145
+ }
146
+
@@ -1,17 +1,17 @@
1
1
  /*
2
- * Copyright (c) 2009 Wayne Meissner. All rights reserved.
3
- *
2
+ * Copyright (c) 2010, Wayne Meissner
3
+ * All rights reserved.
4
+ *
4
5
  * Redistribution and use in source and binary forms, with or without
5
6
  * modification, are permitted provided that the following conditions are met:
6
7
  *
7
- * Redistributions of source code must retain the above copyright notice, this
8
- * list of conditions and the following disclaimer.
9
- * Redistributions in binary form must reproduce the above copyright notice
10
- * this list of conditions and the following disclaimer in the documentation
11
- * and/or other materials provided with the distribution.
12
- * Neither the name of the project nor the names of its contributors
13
- * may be used to endorse or promote products derived from this software
14
- * without specific prior written permission.
8
+ * * Redistributions of source code must retain the above copyright notice, this
9
+ * list of conditions and the following disclaimer.
10
+ * * Redistributions in binary form must reproduce the above copyright notice
11
+ * this list of conditions and the following disclaimer in the documentation
12
+ * and/or other materials provided with the distribution.
13
+ * * The name of the author or authors may not be used to endorse or promote
14
+ * products derived from this software without specific prior written permission.
15
15
  *
16
16
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
17
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -25,26 +25,33 @@
25
25
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
26
  */
27
27
 
28
- #include <unistd.h>
28
+ #ifndef RBFFI_MAPPEDTYPE_H
29
+ #define RBFFI_MAPPEDTYPE_H
30
+
31
+
32
+ #include <ruby.h>
29
33
 
30
- #ifdef __WIN32__
31
- #include <windows.h>
32
- #define sleep(x) Sleep(x)
34
+ #ifdef __cplusplus
35
+ extern "C" {
33
36
  #endif
34
37
 
35
- int testAdd(int a, int b)
36
- {
37
- return a + b;
38
- };
39
38
 
40
- int testFunctionAdd(int a, int b, int (*f)(int, int))
41
- {
42
- return f(a, b);
43
- };
39
+ typedef struct MappedType_ {
40
+ Type base;
41
+ Type* type;
42
+ VALUE rbConverter;
43
+ VALUE rbType;
44
+
45
+ } MappedType;
44
46
 
45
- void testBlocking(int seconds) {
46
- sleep(seconds);
47
- };
47
+ void rbffi_MappedType_Init(VALUE moduleFFI);
48
48
 
49
+ extern VALUE rbffi_MappedTypeClass;
50
+
51
+
52
+ #ifdef __cplusplus
53
+ }
54
+ #endif
49
55
 
56
+ #endif /* RBFFI_MAPPEDTYPE_H */
50
57
 
@@ -4,27 +4,19 @@
4
4
  *
5
5
  * All rights reserved.
6
6
  *
7
- * Redistribution and use in source and binary forms, with or without
8
- * modification, are permitted provided that the following conditions are met:
7
+ * This file is part of ruby-ffi.
9
8
  *
10
- * * Redistributions of source code must retain the above copyright notice, this
11
- * list of conditions and the following disclaimer.
12
- * * Redistributions in binary form must reproduce the above copyright notice
13
- * this list of conditions and the following disclaimer in the documentation
14
- * and/or other materials provided with the distribution.
15
- * * The name of the author or authors may not be used to endorse or promote
16
- * products derived from this software without specific prior written permission.
9
+ * This code is free software: you can redistribute it and/or modify it under
10
+ * the terms of the GNU Lesser General Public License version 3 only, as
11
+ * published by the Free Software Foundation.
17
12
  *
18
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
22
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13
+ * This code is distributed in the hope that it will be useful, but WITHOUT
14
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
16
+ * version 3 for more details.
17
+ *
18
+ * You should have received a copy of the GNU Lesser General Public License
19
+ * version 3 along with this work. If not, see <http://www.gnu.org/licenses/>.
28
20
  */
29
21
 
30
22
  #include <stdbool.h>
@@ -63,7 +55,7 @@ memptr_allocate(VALUE klass)
63
55
  {
64
56
  MemoryPointer* p;
65
57
  VALUE obj = Data_Make_Struct(klass, MemoryPointer, NULL, memptr_release, p);
66
- p->memory.access = MEM_RD | MEM_WR;
58
+ p->memory.flags = MEM_RD | MEM_WR;
67
59
 
68
60
  return obj;
69
61
  }
@@ -113,18 +105,6 @@ memptr_malloc(VALUE self, long size, long count, bool clear)
113
105
  return self;
114
106
  }
115
107
 
116
- static VALUE
117
- memptr_inspect(VALUE self)
118
- {
119
- MemoryPointer* ptr;
120
- char tmp[100];
121
-
122
- Data_Get_Struct(self, MemoryPointer, ptr);
123
-
124
- snprintf(tmp, sizeof(tmp), "#<FFI::MemoryPointer address=%p size=%lu>", ptr->memory.address, ptr->memory.size);
125
- return rb_str_new2(tmp);
126
- }
127
-
128
108
  static VALUE
129
109
  memptr_free(VALUE self)
130
110
  {
@@ -172,7 +152,6 @@ rbffi_MemoryPointer_Init(VALUE moduleFFI)
172
152
 
173
153
  rb_define_alloc_func(rbffi_MemoryPointerClass, memptr_allocate);
174
154
  rb_define_method(rbffi_MemoryPointerClass, "initialize", memptr_initialize, -1);
175
- rb_define_method(rbffi_MemoryPointerClass, "inspect", memptr_inspect, 0);
176
155
  rb_define_method(rbffi_MemoryPointerClass, "autorelease=", memptr_autorelease, 1);
177
156
  rb_define_method(rbffi_MemoryPointerClass, "free", memptr_free, 0);
178
157
  }
data/ext/ffi_c/Platform.c CHANGED
@@ -24,6 +24,8 @@ static VALUE PlatformModule = Qnil;
24
24
  #define CPU "sparc"
25
25
  #elif defined(__sparcv9__)
26
26
  #define CPU "sparcv9"
27
+ #elif defined(__arm__)
28
+ #define CPU "arm"
27
29
  #else
28
30
  #error "Unknown cpu type"
29
31
  #endif
data/ext/ffi_c/Pointer.c CHANGED
@@ -3,27 +3,19 @@
3
3
  *
4
4
  * All rights reserved.
5
5
  *
6
- * Redistribution and use in source and binary forms, with or without
7
- * modification, are permitted provided that the following conditions are met:
6
+ * This file is part of ruby-ffi.
8
7
  *
9
- * * Redistributions of source code must retain the above copyright notice, this
10
- * list of conditions and the following disclaimer.
11
- * * Redistributions in binary form must reproduce the above copyright notice
12
- * this list of conditions and the following disclaimer in the documentation
13
- * and/or other materials provided with the distribution.
14
- * * The name of the author or authors may not be used to endorse or promote
15
- * products derived from this software without specific prior written permission.
8
+ * This code is free software: you can redistribute it and/or modify it under
9
+ * the terms of the GNU Lesser General Public License version 3 only, as
10
+ * published by the Free Software Foundation.
16
11
  *
17
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12
+ * This code is distributed in the hope that it will be useful, but WITHOUT
13
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15
+ * version 3 for more details.
16
+ *
17
+ * You should have received a copy of the GNU Lesser General Public License
18
+ * version 3 along with this work. If not, see <http://www.gnu.org/licenses/>.
27
19
  */
28
20
 
29
21
  #include <stdbool.h>
@@ -59,7 +51,7 @@ rbffi_Pointer_NewInstance(void* addr)
59
51
  obj = Data_Make_Struct(rbffi_PointerClass, Pointer, NULL, -1, p);
60
52
  p->memory.address = addr;
61
53
  p->memory.size = LONG_MAX;
62
- p->memory.access = (addr == NULL) ? 0 : (MEM_RD | MEM_WR);
54
+ p->memory.flags = (addr == NULL) ? 0 : (MEM_RD | MEM_WR);
63
55
  p->memory.typeSize = 1;
64
56
  p->parent = Qnil;
65
57
 
@@ -72,9 +64,9 @@ ptr_allocate(VALUE klass)
72
64
  Pointer* p;
73
65
  VALUE obj;
74
66
 
75
- obj = Data_Make_Struct(klass, Pointer, NULL, -1, p);
67
+ obj = Data_Make_Struct(klass, Pointer, ptr_mark, -1, p);
76
68
  p->parent = Qnil;
77
- p->memory.access = MEM_RD | MEM_WR;
69
+ p->memory.flags = MEM_RD | MEM_WR;
78
70
 
79
71
  return obj;
80
72
  }
@@ -106,7 +98,7 @@ ptr_initialize(int argc, VALUE* argv, VALUE self)
106
98
  p->memory.address = (void*) (uintptr_t) NUM2LL(rbAddress);
107
99
  p->memory.size = LONG_MAX;
108
100
  if (p->memory.address == NULL) {
109
- p->memory.access = 0;
101
+ p->memory.flags = 0;
110
102
  }
111
103
  break;
112
104
 
@@ -143,7 +135,7 @@ slice(VALUE self, long offset, long size)
143
135
 
144
136
  p->memory.address = ptr->address + offset;
145
137
  p->memory.size = size;
146
- p->memory.access = ptr->access;
138
+ p->memory.flags = ptr->flags;
147
139
  p->memory.typeSize = ptr->typeSize;
148
140
  p->parent = self;
149
141
 
@@ -171,12 +163,12 @@ static VALUE
171
163
  ptr_inspect(VALUE self)
172
164
  {
173
165
  Pointer* ptr;
174
- char tmp[100];
175
-
166
+
176
167
  Data_Get_Struct(self, Pointer, ptr);
177
- snprintf(tmp, sizeof(tmp), "#<FFI::Pointer address=%p>", ptr->memory.address);
178
168
 
179
- return rb_str_new2(tmp);
169
+ return ptr->memory.size != LONG_MAX
170
+ ? rb_sprintf("#<%s address=%p size=%lu>", rb_obj_classname(self), ptr->memory.address, ptr->memory.size)
171
+ : rb_sprintf("#<%s address=%p>", rb_obj_classname(self), ptr->memory.address);
180
172
  }
181
173
 
182
174
  static VALUE
@@ -209,6 +201,50 @@ ptr_address(VALUE self)
209
201
  return ULL2NUM((uintptr_t) ptr->memory.address);
210
202
  }
211
203
 
204
+ #if BYTE_ORDER == LITTLE_ENDIAN
205
+ # define SWAPPED_ORDER BIG_ENDIAN
206
+ #else
207
+ # define SWAPPED_ORDER LITTLE_ENDIAN
208
+ #endif
209
+
210
+ static VALUE
211
+ ptr_order(int argc, VALUE* argv, VALUE self)
212
+ {
213
+ Pointer* ptr;
214
+
215
+ Data_Get_Struct(self, Pointer, ptr);
216
+ if (argc == 0) {
217
+ int order = (ptr->memory.flags & MEM_SWAP) == 0 ? BYTE_ORDER : SWAPPED_ORDER;
218
+ return order == BIG_ENDIAN ? ID2SYM(rb_intern("big")) : ID2SYM(rb_intern("little"));
219
+ } else {
220
+ VALUE rbOrder = Qnil;
221
+ int order = BYTE_ORDER;
222
+
223
+ if (rb_scan_args(argc, argv, "1", &rbOrder) < 1) {
224
+ rb_raise(rb_eArgError, "need byte order");
225
+ }
226
+ if (SYMBOL_P(rbOrder)) {
227
+ ID id = SYM2ID(rbOrder);
228
+ if (id == rb_intern("little")) {
229
+ order = LITTLE_ENDIAN;
230
+
231
+ } else if (id == rb_intern("big") || id == rb_intern("network")) {
232
+ order = BIG_ENDIAN;
233
+ }
234
+ }
235
+ if (order != BYTE_ORDER) {
236
+ Pointer* p2;
237
+ VALUE retval = slice(self, 0, ptr->memory.size);
238
+
239
+ Data_Get_Struct(retval, Pointer, p2);
240
+ p2->memory.flags |= MEM_SWAP;
241
+ return retval;
242
+ }
243
+
244
+ return self;
245
+ }
246
+ }
247
+
212
248
  static void
213
249
  ptr_mark(Pointer* ptr)
214
250
  {
@@ -226,12 +262,14 @@ rbffi_Pointer_Init(VALUE moduleFFI)
226
262
  rb_define_alloc_func(rbffi_PointerClass, ptr_allocate);
227
263
  rb_define_method(rbffi_PointerClass, "initialize", ptr_initialize, -1);
228
264
  rb_define_method(rbffi_PointerClass, "inspect", ptr_inspect, 0);
265
+ rb_define_method(rbffi_PointerClass, "to_s", ptr_inspect, 0);
229
266
  rb_define_method(rbffi_PointerClass, "+", ptr_plus, 1);
230
267
  rb_define_method(rbffi_PointerClass, "slice", ptr_slice, 2);
231
268
  rb_define_method(rbffi_PointerClass, "null?", ptr_null_p, 0);
232
269
  rb_define_method(rbffi_PointerClass, "address", ptr_address, 0);
233
270
  rb_define_alias(rbffi_PointerClass, "to_i", "address");
234
271
  rb_define_method(rbffi_PointerClass, "==", ptr_equals, 1);
272
+ rb_define_method(rbffi_PointerClass, "order", ptr_order, -1);
235
273
 
236
274
  rbffi_NullPointerSingleton = rb_class_new_instance(1, &rbNullAddress, rbffi_PointerClass);
237
275
  rb_define_const(rbffi_PointerClass, "NULL", rbffi_NullPointerSingleton);