ffi 0.6.0 → 1.0.0

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.
Files changed (76) hide show
  1. data/History.txt +109 -0
  2. data/LICENSE +10 -21
  3. data/README.rdoc +1 -0
  4. data/Rakefile +3 -2
  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 +55 -543
  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 +255 -32
  13. data/ext/ffi_c/MappedType.c +146 -0
  14. data/ext/ffi_c/MappedType.h +57 -0
  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 +106 -318
  19. data/ext/ffi_c/Struct.h +6 -0
  20. data/ext/ffi_c/StructByReference.c +150 -0
  21. data/ext/ffi_c/StructByReference.h +50 -0
  22. data/ext/ffi_c/StructLayout.c +25 -14
  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 +21 -6
  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/libffi/configure +1 -1
  31. data/ext/ffi_c/libffi.gnu.mk +1 -1
  32. data/ext/ffi_c/libffi.mk +1 -1
  33. data/ext/ffi_c/rbffi.h +1 -0
  34. data/gen/Rakefile +4 -2
  35. data/lib/ffi/autopointer.rb +23 -22
  36. data/lib/ffi/enum.rb +36 -21
  37. data/lib/ffi/errno.rb +20 -0
  38. data/lib/ffi/ffi.rb +13 -79
  39. data/lib/ffi/io.rb +12 -20
  40. data/lib/ffi/library.rb +110 -93
  41. data/lib/ffi/managedstruct.rb +1 -1
  42. data/lib/ffi/memorypointer.rb +15 -21
  43. data/lib/ffi/platform.rb +24 -28
  44. data/lib/ffi/pointer.rb +14 -21
  45. data/lib/ffi/struct.rb +100 -51
  46. data/lib/ffi/struct_layout_builder.rb +158 -0
  47. data/lib/ffi/types.rb +99 -128
  48. data/lib/ffi/union.rb +20 -0
  49. data/lib/ffi/variadic.rb +33 -22
  50. data/spec/ffi/async_callback_spec.rb +23 -0
  51. data/spec/ffi/callback_spec.rb +62 -0
  52. data/spec/ffi/custom_param_type.rb +31 -0
  53. data/spec/ffi/custom_type_spec.rb +73 -0
  54. data/spec/ffi/enum_spec.rb +19 -0
  55. data/spec/ffi/ffi_spec.rb +24 -0
  56. data/spec/ffi/pointer_spec.rb +15 -0
  57. data/spec/ffi/rbx/memory_pointer_spec.rb +7 -1
  58. data/spec/ffi/strptr_spec.rb +36 -0
  59. data/spec/ffi/struct_packed_spec.rb +46 -0
  60. data/spec/ffi/struct_spec.rb +39 -7
  61. data/spec/ffi/typedef_spec.rb +14 -0
  62. data/tasks/ann.rake +80 -0
  63. data/tasks/extension.rake +25 -0
  64. data/tasks/gem.rake +200 -0
  65. data/tasks/git.rake +41 -0
  66. data/tasks/notes.rake +27 -0
  67. data/tasks/post_load.rake +34 -0
  68. data/tasks/rdoc.rake +50 -0
  69. data/tasks/rubyforge.rake +55 -0
  70. data/tasks/setup.rb +301 -0
  71. data/tasks/spec.rake +54 -0
  72. data/tasks/svn.rake +47 -0
  73. data/tasks/test.rake +40 -0
  74. metadata +64 -11
  75. data/ext/ffi_c/AutoPointer.c +0 -60
  76. data/ext/ffi_c/AutoPointer.h +0 -18
data/History.txt ADDED
@@ -0,0 +1,109 @@
1
+ == 1.0.0 / 2010-11-30
2
+ * Major improvements
3
+ * Better handling of non-ruby thread callbacks
4
+ * Support for releasing the GIL during C function calls
5
+ * Minor improvements
6
+ * code cleanups
7
+
8
+ == 0.5.0 / 2009-10-06
9
+
10
+ * Major improvements
11
+ * New Function class
12
+ * Structs can be passed and returned by value
13
+ * Implement a custom trampoline for x86_64, resulting in roughly 30% speedup
14
+ * Improve dispatch of functions which take (0..6) char/short/int/long/pointer arguments by between 50% and 200% on x86_64
15
+ * Callbacks are now approximately 100% faster on x86_64
16
+ * Minor improvements
17
+ * Add support for MacOSX Snow Leopard
18
+ * Improve support for Windows releasing fat binaries on rubyforge
19
+ * Better introspection in structs:
20
+ * Add StructLayout::Field#type, size, offset, alignment and name
21
+ methods
22
+ * Add StructLayout#fields which returns an array of
23
+ StructLayout::Field objects
24
+ * Add automagic deducing of library name from module name.
25
+ Idea and prototype implementation from Matt Hulse
26
+ * Callback fields in structs can now be both read and written
27
+ * Add a bunch of new benchmarks
28
+ * Lots of refactoring
29
+ * Experimental features
30
+ * blocking functions (i.e. native code that blocks the thread) support
31
+ * Bug fixes
32
+ * Fix RUBY-FFI_43 (rake gem dependency)
33
+
34
+ == 0.4.0 / 2009-08-05
35
+
36
+ * Major improvements
37
+ * Add support for boolean types
38
+ * Add support for methods as callbacks
39
+ * Add FFI::IO.read as described in JRUBY-3636
40
+ * Minor improvements
41
+ * Add Pointer::NULL constant
42
+ * Add AbstractMemory#get_array_of_string()
43
+ * Implement Pointer.new(address) and Pointer.new(:type, address)
44
+ * Bug fixes
45
+ * Fix RUBY_FFI-38
46
+ * Fix issues related to 1.9.1 build
47
+ * Fix issues related to OSX build
48
+ * Fix issues related to FreeBSD build
49
+ * Fix issues related to OpenSolaris build
50
+
51
+ == 0.3.5 / 2009-05-08
52
+
53
+ * Bug fixes
54
+ * Fix RUBY_FFI-17
55
+ * Fix RUBY_FFI-21
56
+
57
+ == 0.3.4 / 2009-05-01
58
+
59
+ * Minor improvements
60
+ * Add return statements to functions that call rb_raise(), in case
61
+ rb_raise is not declared noreturn, to avoid gcc warnings.
62
+
63
+ == 0.3.3 / 2009-04-27
64
+
65
+ * Minor improvements
66
+ * Implement RUBY_FFI-16 - Add support for anonymous callbacks
67
+ * Add support for callback parameters in callbacks
68
+ * Add support for function pointer return values
69
+ * Callbacks can now coerce proc objects into function pointers for
70
+ return values.
71
+ * Implement FFI::Type and FFI::Type::Builtin
72
+ * Add support for enumerations
73
+ * Bug fixes
74
+ * Fix RUBY_FFI-19
75
+ * Fix RUBY_FFI-15
76
+
77
+ == 0.3.2 / 2009-05-01
78
+
79
+ * Bug fixes
80
+ * Fix JRUBY-3527 by passing RTLD_GLOBAL instead of RTLD_LOCAL
81
+
82
+ == 0.3.1 / 2009-03-23
83
+
84
+ * Bug fixes
85
+ * Correctly save errno/GetLastError after each call.
86
+
87
+ == 0.3.0 / 2009-03-19
88
+
89
+ * Switch compilation to rake-compiler
90
+ * Makes cross-compilation from linux -> win32 super easy
91
+ * win32 support is available now, but highly experimental
92
+ * Performance improvements
93
+ * struct field access approx 3x faster than 0.2.0
94
+ * function invocation approx 20% faster than 0.2.0
95
+ * A bunch of minor improvements
96
+ * Struct instances can now be passed as :pointer parameters without calling
97
+ Struct#pointer
98
+ * Support for array struct members
99
+ * Structs are now padded correctly to the alignment of the struct's
100
+ largest field
101
+ * Global library variables
102
+ * Callbacks in global library variables
103
+ * Strings passed in as :string arguments are scrubbed to avoid
104
+ poison-null-byte attacks.
105
+ * Union support
106
+ * nil can be passed as a :string argument (passed as NULL)
107
+ * Structs can now be fields inside another struct
108
+ * Lots of internal cleanups and refactorings.
109
+
data/LICENSE CHANGED
@@ -1,25 +1,14 @@
1
- Copyright (c) 2008, 2009 Ruby FFI contributors
1
+ Copyright (c) 2008-2010 Ruby-FFI contributors
2
2
  All rights reserved.
3
3
 
4
- Redistribution and use in source and binary forms, with or without
5
- modification, are permitted provided that the following conditions are met:
4
+ This code is free software: you can redistribute it and/or modify it under
5
+ the terms of the GNU Lesser General Public License version 3 only, as
6
+ published by the Free Software Foundation.
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 JRuby 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
+ This code is distributed in the hope that it will be useful, but WITHOUT
9
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11
+ version 3 for more details.
15
12
 
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.
13
+ You should have received a copy of the GNU Lesser General Public License
14
+ version 3 along with this work. If not, see <http://www.gnu.org/licenses/>.
data/README.rdoc CHANGED
@@ -24,6 +24,7 @@ using Ruby-FFI here[http://wiki.github.com/ffi/ffi/why-use-ffi].
24
24
 
25
25
  module MyLib
26
26
  extend FFI::Library
27
+ ffi_lib 'c'
27
28
  attach_function :puts, [ :string ], :int
28
29
  end
29
30
 
data/Rakefile CHANGED
@@ -75,7 +75,7 @@ PROJ.name = 'ffi'
75
75
  PROJ.authors = 'Wayne Meissner'
76
76
  PROJ.email = 'wmeissner@gmail.com'
77
77
  PROJ.url = 'http://wiki.github.com/ffi/ffi'
78
- PROJ.version = '0.6.0'
78
+ PROJ.version = '1.0.0'
79
79
  PROJ.rubyforge.name = 'ffi'
80
80
  PROJ.readme_file = 'README.rdoc'
81
81
 
@@ -88,7 +88,7 @@ PROJ.ann.email[:server] = 'smtp.gmail.com'
88
88
 
89
89
  # Gem specifications
90
90
  PROJ.gem.need_tar = false
91
- PROJ.gem.files = %w(LICENSE README.rdoc Rakefile) + Dir.glob("{ext,gen,lib,spec}/**/*")
91
+ PROJ.gem.files = %w(History.txt LICENSE README.rdoc Rakefile) + Dir.glob("{ext,gen,lib,spec,tasks}/**/*")
92
92
  PROJ.gem.platform = Gem::Platform::RUBY
93
93
 
94
94
  # Override Mr. Bones autogenerated extensions and force ours in
@@ -147,6 +147,7 @@ task :distclean => :clobber do
147
147
  FileUtils.rm_rf(Dir["lib/**/ffi_c.#{Config::CONFIG['DLEXT']}"])
148
148
  FileUtils.rm_rf('lib/1.8')
149
149
  FileUtils.rm_rf('lib/1.9')
150
+ FileUtils.rm_rf('lib/ffi/types.conf')
150
151
  FileUtils.rm_rf('conftest.dSYM')
151
152
  FileUtils.rm_rf('pkg')
152
153
  end
@@ -3,33 +3,26 @@
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 <sys/types.h>
30
22
  #include <sys/param.h>
31
23
  #include <stdint.h>
32
24
  #include <stdbool.h>
25
+ #include <limits.h>
33
26
  #include <ruby.h>
34
27
  #include "rbffi.h"
35
28
  #include "compat.h"
@@ -49,17 +42,18 @@ memory_allocate(VALUE klass)
49
42
  AbstractMemory* memory;
50
43
  VALUE obj;
51
44
  obj = Data_Make_Struct(klass, AbstractMemory, NULL, -1, memory);
52
- memory->access = MEM_RD | MEM_WR;
45
+ memory->flags = MEM_RD | MEM_WR;
53
46
 
54
47
  return obj;
55
48
  }
49
+ #define VAL(x, swap) (unlikely(((memory->flags & MEM_SWAP) != 0)) ? swap((x)) : (x))
56
50
 
57
- #define NUM_OP(name, type, toNative, fromNative) \
51
+ #define NUM_OP(name, type, toNative, fromNative, swap) \
58
52
  static void memory_op_put_##name(AbstractMemory* memory, long off, VALUE value); \
59
53
  static void \
60
54
  memory_op_put_##name(AbstractMemory* memory, long off, VALUE value) \
61
55
  { \
62
- type tmp = (type) toNative(value); \
56
+ type tmp = (type) VAL(toNative(value), swap); \
63
57
  checkWrite(memory); \
64
58
  checkBounds(memory, off, sizeof(type)); \
65
59
  memcpy(memory->address + off, &tmp, sizeof(tmp)); \
@@ -81,7 +75,7 @@ memory_op_get_##name(AbstractMemory* memory, long off) \
81
75
  checkRead(memory); \
82
76
  checkBounds(memory, off, sizeof(type)); \
83
77
  memcpy(&tmp, memory->address + off, sizeof(tmp)); \
84
- return fromNative(tmp); \
78
+ return fromNative(VAL(tmp, swap)); \
85
79
  } \
86
80
  static VALUE memory_get_##name(VALUE self, VALUE offset); \
87
81
  static VALUE \
@@ -104,7 +98,7 @@ memory_put_array_of_##name(VALUE self, VALUE offset, VALUE ary) \
104
98
  checkWrite(memory); \
105
99
  checkBounds(memory, off, count * sizeof(type)); \
106
100
  for (i = 0; i < count; i++) { \
107
- type tmp = (type) toNative(RARRAY_PTR(ary)[i]); \
101
+ type tmp = (type) VAL(toNative(RARRAY_PTR(ary)[i]), swap); \
108
102
  memcpy(memory->address + off + (i * sizeof(type)), &tmp, sizeof(tmp)); \
109
103
  } \
110
104
  return self; \
@@ -123,23 +117,47 @@ memory_get_array_of_##name(VALUE self, VALUE offset, VALUE length) \
123
117
  for (i = 0; i < count; ++i) { \
124
118
  type tmp; \
125
119
  memcpy(&tmp, memory->address + off + (i * sizeof(type)), sizeof(tmp)); \
126
- rb_ary_push(retVal, fromNative(tmp)); \
120
+ rb_ary_push(retVal, fromNative(VAL(tmp, swap))); \
127
121
  } \
128
122
  return retVal; \
129
123
  }
130
124
 
131
- NUM_OP(int8, int8_t, NUM2INT, INT2NUM);
132
- NUM_OP(uint8, uint8_t, NUM2UINT, UINT2NUM);
133
- NUM_OP(int16, int16_t, NUM2INT, INT2NUM);
134
- NUM_OP(uint16, uint16_t, NUM2UINT, UINT2NUM);
135
- NUM_OP(int32, int32_t, NUM2INT, INT2NUM);
136
- NUM_OP(uint32, uint32_t, NUM2UINT, UINT2NUM);
137
- NUM_OP(int64, int64_t, NUM2LL, LL2NUM);
138
- NUM_OP(uint64, uint64_t, NUM2ULL, ULL2NUM);
139
- NUM_OP(long, long, NUM2LONG, LONG2NUM);
140
- NUM_OP(ulong, unsigned long, NUM2ULONG, ULONG2NUM);
141
- NUM_OP(float32, float, NUM2DBL, rb_float_new);
142
- NUM_OP(float64, double, NUM2DBL, rb_float_new);
125
+ #define NOSWAP(x) (x)
126
+ #define bswap16(x) (((x) >> 8) & 0xff) | (((x) << 8) & 0xff00);
127
+ static inline int16_t
128
+ SWAPS16(int16_t x)
129
+ {
130
+ return bswap16(x);
131
+ }
132
+
133
+ static inline uint16_t
134
+ SWAPU16(uint16_t x)
135
+ {
136
+ return bswap16(x);
137
+ }
138
+
139
+ #define SWAP16(x) (x)
140
+ #define SWAP32(x) __builtin_bswap32(x)
141
+ #define SWAP64(x) __builtin_bswap64(x)
142
+
143
+ #if LONG_MAX > INT_MAX
144
+ # define SWAPLONG SWAP64
145
+ #else
146
+ # define SWAPLONG SWAP32
147
+ #endif
148
+
149
+ NUM_OP(int8, int8_t, NUM2INT, INT2NUM, NOSWAP);
150
+ NUM_OP(uint8, uint8_t, NUM2UINT, UINT2NUM, NOSWAP);
151
+ NUM_OP(int16, int16_t, NUM2INT, INT2NUM, SWAP16);
152
+ NUM_OP(uint16, uint16_t, NUM2UINT, UINT2NUM, SWAP16);
153
+ NUM_OP(int32, int32_t, NUM2INT, INT2NUM, SWAP32);
154
+ NUM_OP(uint32, uint32_t, NUM2UINT, UINT2NUM, SWAP32);
155
+ NUM_OP(int64, int64_t, NUM2LL, LL2NUM, SWAP64);
156
+ NUM_OP(uint64, uint64_t, NUM2ULL, ULL2NUM, SWAP64);
157
+ NUM_OP(long, long, NUM2LONG, LONG2NUM, SWAPLONG);
158
+ NUM_OP(ulong, unsigned long, NUM2ULONG, ULONG2NUM, SWAPLONG);
159
+ NUM_OP(float32, float, NUM2DBL, rb_float_new, NOSWAP);
160
+ NUM_OP(float64, double, NUM2DBL, rb_float_new, NOSWAP);
143
161
 
144
162
  static inline void*
145
163
  get_pointer_value(VALUE value)
@@ -161,7 +179,7 @@ get_pointer_value(VALUE value)
161
179
  }
162
180
  }
163
181
 
164
- NUM_OP(pointer, void *, get_pointer_value, rbffi_Pointer_NewInstance);
182
+ NUM_OP(pointer, void *, get_pointer_value, rbffi_Pointer_NewInstance, NOSWAP);
165
183
 
166
184
  static VALUE
167
185
  memory_clear(VALUE self)
@@ -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
  #ifndef RBFFI_ABSTRACTMEMORY_H
@@ -44,6 +36,7 @@ extern "C" {
44
36
  #define MEM_RD 0x01
45
37
  #define MEM_WR 0x02
46
38
  #define MEM_CODE 0x04
39
+ #define MEM_SWAP 0x08
47
40
 
48
41
  typedef struct AbstractMemory_ AbstractMemory;
49
42
 
@@ -72,7 +65,7 @@ typedef struct {
72
65
  struct AbstractMemory_ {
73
66
  char* address; // Use char* instead of void* to ensure adding to it works correctly
74
67
  long size;
75
- int access;
68
+ int flags;
76
69
  int typeSize;
77
70
  };
78
71
 
@@ -98,7 +91,7 @@ checkBounds(AbstractMemory* mem, long off, long len)
98
91
  static inline void
99
92
  checkRead(AbstractMemory* mem)
100
93
  {
101
- if (unlikely((mem->access & MEM_RD) == 0)) {
94
+ if (unlikely((mem->flags & MEM_RD) == 0)) {
102
95
  rbffi_AbstractMemory_Error(mem, MEM_RD);
103
96
  }
104
97
  }
@@ -106,7 +99,7 @@ checkRead(AbstractMemory* mem)
106
99
  static inline void
107
100
  checkWrite(AbstractMemory* mem)
108
101
  {
109
- if (unlikely((mem->access & MEM_WR) == 0)) {
102
+ if (unlikely((mem->flags & MEM_WR) == 0)) {
110
103
  rbffi_AbstractMemory_Error(mem, MEM_WR);
111
104
  }
112
105
  }
data/ext/ffi_c/Buffer.c CHANGED
@@ -1,28 +1,21 @@
1
1
  /*
2
- * Copyright (c) 2008, 2009, Wayne Meissner
2
+ * Copyright (c) 2008-2010 Wayne Meissner
3
+ *
3
4
  * All rights reserved.
4
5
  *
5
- * Redistribution and use in source and binary forms, with or without
6
- * modification, are permitted provided that the following conditions are met:
6
+ * This file is part of ruby-ffi.
7
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.
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.
15
11
  *
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.
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/>.
26
19
  */
27
20
 
28
21
  #include <stdbool.h>
@@ -54,7 +47,7 @@ buffer_allocate(VALUE klass)
54
47
 
55
48
  obj = Data_Make_Struct(klass, Buffer, NULL, buffer_release, buffer);
56
49
  buffer->rbParent = Qnil;
57
- buffer->memory.access = MEM_RD | MEM_WR;
50
+ buffer->memory.flags = MEM_RD | MEM_WR;
58
51
 
59
52
  return obj;
60
53
  }
@@ -122,7 +115,7 @@ slice(VALUE self, long offset, long len)
122
115
  obj = Data_Make_Struct(BufferClass, Buffer, buffer_mark, -1, result);
123
116
  result->memory.address = ptr->memory.address + offset;
124
117
  result->memory.size = len;
125
- result->memory.access = ptr->memory.access;
118
+ result->memory.flags = ptr->memory.flags;
126
119
  result->memory.typeSize = ptr->memory.typeSize;
127
120
  result->rbParent = self;
128
121
 
@@ -159,6 +152,51 @@ buffer_inspect(VALUE self)
159
152
  return rb_str_new2(tmp);
160
153
  }
161
154
 
155
+
156
+ #if BYTE_ORDER == LITTLE_ENDIAN
157
+ # define SWAPPED_ORDER BIG_ENDIAN
158
+ #else
159
+ # define SWAPPED_ORDER LITTLE_ENDIAN
160
+ #endif
161
+
162
+ static VALUE
163
+ buffer_order(int argc, VALUE* argv, VALUE self)
164
+ {
165
+ Buffer* ptr;
166
+
167
+ Data_Get_Struct(self, Buffer, ptr);
168
+ if (argc == 0) {
169
+ int order = (ptr->memory.flags & MEM_SWAP) == 0 ? BYTE_ORDER : SWAPPED_ORDER;
170
+ return order == BIG_ENDIAN ? ID2SYM(rb_intern("big")) : ID2SYM(rb_intern("little"));
171
+ } else {
172
+ VALUE rbOrder = Qnil;
173
+ int order = BYTE_ORDER;
174
+
175
+ if (rb_scan_args(argc, argv, "1", &rbOrder) < 1) {
176
+ rb_raise(rb_eArgError, "need byte order");
177
+ }
178
+ if (SYMBOL_P(rbOrder)) {
179
+ ID id = SYM2ID(rbOrder);
180
+ if (id == rb_intern("little")) {
181
+ order = LITTLE_ENDIAN;
182
+
183
+ } else if (id == rb_intern("big") || id == rb_intern("network")) {
184
+ order = BIG_ENDIAN;
185
+ }
186
+ }
187
+ if (order != BYTE_ORDER) {
188
+ Buffer* p2;
189
+ VALUE retval = slice(self, 0, ptr->memory.size);
190
+
191
+ Data_Get_Struct(retval, Buffer, p2);
192
+ p2->memory.flags |= MEM_SWAP;
193
+ return retval;
194
+ }
195
+
196
+ return self;
197
+ }
198
+ }
199
+
162
200
  /* Only used to free the buffer if the yield in the initializer throws an exception */
163
201
  static VALUE
164
202
  buffer_free(VALUE self)
@@ -196,6 +234,7 @@ rbffi_Buffer_Init(VALUE moduleFFI)
196
234
  rb_define_alias(rb_singleton_class(BufferClass), "new_inout", "alloc_inout");
197
235
 
198
236
  rb_define_method(BufferClass, "initialize", buffer_initialize, -1);
237
+ rb_define_method(BufferClass, "order", buffer_order, -1);
199
238
  rb_define_method(BufferClass, "inspect", buffer_inspect, 0);
200
239
  rb_define_alias(BufferClass, "length", "total");
201
240
  rb_define_method(BufferClass, "+", buffer_plus, 1);