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.
- data/History.txt +7 -0
- data/LICENSE +10 -21
- data/README.rdoc +70 -0
- data/Rakefile +56 -84
- data/ext/ffi_c/AbstractMemory.c +56 -38
- data/ext/ffi_c/AbstractMemory.h +15 -22
- data/ext/ffi_c/Buffer.c +61 -22
- data/ext/ffi_c/Call.c +52 -540
- data/ext/ffi_c/Call.h +1 -1
- data/ext/ffi_c/DataConverter.c +62 -0
- data/ext/ffi_c/DynamicLibrary.c +21 -1
- data/ext/ffi_c/Function.c +252 -30
- data/ext/ffi_c/MappedType.c +146 -0
- data/{libtest/FunctionTest.c → ext/ffi_c/MappedType.h} +32 -25
- data/ext/ffi_c/MemoryPointer.c +12 -33
- data/ext/ffi_c/Platform.c +2 -0
- data/ext/ffi_c/Pointer.c +66 -28
- data/ext/ffi_c/Struct.c +19 -306
- data/ext/ffi_c/Struct.h +6 -0
- data/ext/ffi_c/StructByReference.c +150 -0
- data/{libtest/LastErrorTest.c → ext/ffi_c/StructByReference.h} +30 -21
- data/ext/ffi_c/StructLayout.c +26 -16
- data/ext/ffi_c/Type.c +39 -68
- data/ext/ffi_c/Type.h +12 -22
- data/ext/ffi_c/Types.c +20 -5
- data/ext/ffi_c/Types.h +7 -7
- data/ext/ffi_c/Variadic.c +21 -17
- data/ext/ffi_c/extconf.rb +4 -0
- data/ext/ffi_c/ffi.c +8 -2
- data/ext/ffi_c/rbffi.h +1 -0
- data/lib/ffi/autopointer.rb +23 -22
- data/lib/ffi/enum.rb +36 -21
- data/lib/ffi/errno.rb +20 -0
- data/lib/ffi/ffi.rb +13 -80
- data/lib/ffi/io.rb +12 -20
- data/lib/ffi/library.rb +109 -92
- data/lib/ffi/managedstruct.rb +1 -1
- data/lib/ffi/memorypointer.rb +15 -21
- data/lib/ffi/platform.rb +27 -33
- data/lib/ffi/pointer.rb +14 -21
- data/lib/ffi/struct.rb +98 -49
- data/lib/ffi/struct_layout_builder.rb +158 -0
- data/lib/ffi/types.rb +99 -128
- data/lib/ffi/union.rb +20 -0
- data/lib/ffi/variadic.rb +33 -22
- data/spec/ffi/async_callback_spec.rb +23 -0
- data/spec/ffi/callback_spec.rb +62 -0
- data/spec/ffi/custom_param_type.rb +31 -0
- data/spec/ffi/custom_type_spec.rb +73 -0
- data/spec/ffi/enum_spec.rb +19 -0
- data/spec/ffi/ffi_spec.rb +24 -0
- data/spec/ffi/pointer_spec.rb +15 -0
- data/spec/ffi/rbx/memory_pointer_spec.rb +7 -1
- data/spec/ffi/strptr_spec.rb +36 -0
- data/spec/ffi/struct_packed_spec.rb +46 -0
- data/spec/ffi/struct_spec.rb +19 -5
- data/spec/ffi/typedef_spec.rb +14 -0
- data/tasks/ann.rake +80 -0
- data/tasks/extension.rake +25 -0
- data/tasks/gem.rake +200 -0
- data/tasks/git.rake +41 -0
- data/tasks/notes.rake +27 -0
- data/tasks/post_load.rake +34 -0
- data/tasks/rdoc.rake +50 -0
- data/tasks/rubyforge.rake +55 -0
- data/tasks/setup.rb +301 -0
- data/tasks/spec.rake +54 -0
- data/tasks/svn.rake +47 -0
- data/tasks/test.rake +40 -0
- metadata +139 -131
- data/README.md +0 -109
- data/ext/ffi_c/AutoPointer.c +0 -60
- data/ext/ffi_c/AutoPointer.h +0 -18
- data/ext/ffi_c/Ffi_c.iml +0 -12
- data/ffi.gemspec +0 -18
- data/gen/log +0 -1
- data/lib/Lib.iml +0 -21
- data/libtest/Benchmark.c +0 -73
- data/libtest/BoolTest.c +0 -52
- data/libtest/BufferTest.c +0 -52
- data/libtest/ClosureTest.c +0 -173
- data/libtest/EnumTest.c +0 -55
- data/libtest/GNUmakefile +0 -141
- data/libtest/GlobalVariable.c +0 -56
- data/libtest/NumberTest.c +0 -145
- data/libtest/PointerTest.c +0 -84
- data/libtest/ReferenceTest.c +0 -44
- data/libtest/StringTest.c +0 -55
- data/libtest/StructTest.c +0 -247
- data/libtest/UnionTest.c +0 -64
- data/libtest/VariadicTest.c +0 -57
- 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)
|
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
|
-
*
|
9
|
-
* Redistributions in binary form must reproduce the above copyright notice
|
10
|
-
*
|
11
|
-
*
|
12
|
-
*
|
13
|
-
*
|
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
|
-
#
|
28
|
+
#ifndef RBFFI_MAPPEDTYPE_H
|
29
|
+
#define RBFFI_MAPPEDTYPE_H
|
30
|
+
|
31
|
+
|
32
|
+
#include <ruby.h>
|
29
33
|
|
30
|
-
#ifdef
|
31
|
-
|
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
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
39
|
+
typedef struct MappedType_ {
|
40
|
+
Type base;
|
41
|
+
Type* type;
|
42
|
+
VALUE rbConverter;
|
43
|
+
VALUE rbType;
|
44
|
+
|
45
|
+
} MappedType;
|
44
46
|
|
45
|
-
void
|
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
|
|
data/ext/ffi_c/MemoryPointer.c
CHANGED
@@ -4,27 +4,19 @@
|
|
4
4
|
*
|
5
5
|
* All rights reserved.
|
6
6
|
*
|
7
|
-
*
|
8
|
-
* modification, are permitted provided that the following conditions are met:
|
7
|
+
* This file is part of ruby-ffi.
|
9
8
|
*
|
10
|
-
*
|
11
|
-
*
|
12
|
-
*
|
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
|
-
*
|
19
|
-
*
|
20
|
-
*
|
21
|
-
*
|
22
|
-
*
|
23
|
-
*
|
24
|
-
*
|
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.
|
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
data/ext/ffi_c/Pointer.c
CHANGED
@@ -3,27 +3,19 @@
|
|
3
3
|
*
|
4
4
|
* All rights reserved.
|
5
5
|
*
|
6
|
-
*
|
7
|
-
* modification, are permitted provided that the following conditions are met:
|
6
|
+
* This file is part of ruby-ffi.
|
8
7
|
*
|
9
|
-
*
|
10
|
-
*
|
11
|
-
*
|
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
|
-
*
|
18
|
-
*
|
19
|
-
*
|
20
|
-
*
|
21
|
-
*
|
22
|
-
*
|
23
|
-
*
|
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.
|
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,
|
67
|
+
obj = Data_Make_Struct(klass, Pointer, ptr_mark, -1, p);
|
76
68
|
p->parent = Qnil;
|
77
|
-
p->memory.
|
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.
|
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.
|
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
|
-
|
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
|
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);
|