summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSylvain Daubert <sylvain.daubert@laposte.net>2011-09-18 20:11:43 +0200
committerSylvain Daubert <sylvain.daubert@laposte.net>2011-09-18 20:11:43 +0200
commit1888bad66bbda21edf8d94dc3ff35736bda6c66f (patch)
tree19a58a74cc1f2926f6795a58a882750adabebbf5
parentada05e3b7984f6e459d8410140a0f75877348650 (diff)
downloadffi-1888bad66bbda21edf8d94dc3ff35736bda6c66f.tar.gz
Documentation for FFI::Pointer, FFI::Type, FFI::Type::Builtin,
FFI::Type::Mapped, FFI::NativeType, FFI::StrPtrConverter. Minor correction for FFI::AbstractMemory#put_bytes (old doc seems to be for #get_bytes).
-rw-r--r--ext/ffi_c/AbstractMemory.c10
-rw-r--r--ext/ffi_c/MappedType.c22
-rw-r--r--ext/ffi_c/Pointer.c91
-rw-r--r--ext/ffi_c/Type.c103
-rw-r--r--ext/ffi_c/ffi.c5
-rw-r--r--lib/ffi/pointer.rb42
-rw-r--r--lib/ffi/types.rb22
7 files changed, 279 insertions, 16 deletions
diff --git a/ext/ffi_c/AbstractMemory.c b/ext/ffi_c/AbstractMemory.c
index d12ca4d..a5afd9c 100644
--- a/ext/ffi_c/AbstractMemory.c
+++ b/ext/ffi_c/AbstractMemory.c
@@ -458,12 +458,12 @@ memory_get_bytes(VALUE self, VALUE offset, VALUE length)
/*
* call-seq: memory.put_bytes(offset, str, index=0, length=nil)
- * Return string contained in memory.
+ * Put a string in memory.
* @param [Numeric] offset point in buffer to start from
* @param [String] str string to put to memory
* @param [Numeric] index
* @param [Numeric] length string's length in bytes. If nil, a (memory size - offset) length string is returned).
- * @return [String]
+ * @return [self]
* @raise {IndexError} if +length+ is too great
* @raise {NullPointerError} if memory not initialized
* @raise {RangeError} if +index+ is negative, or if index+length is greater than size of string
@@ -521,7 +521,7 @@ memory_read_bytes(VALUE self, VALUE length)
* @param [String] str string to put to memory
* @param [Numeric] index
* @param [Numeric] length string's length in bytes. If nil, a (memory size - offset) length string is returned).
- * @return [String]
+ * @return [self]
* equivalent to :
* memory.put_bytes(0, str, index, length)
*/
@@ -681,7 +681,9 @@ rbffi_AbstractMemory_Init(VALUE moduleFFI)
*/
VALUE classMemory = rb_define_class_under(moduleFFI, "AbstractMemory", rb_cObject);
rbffi_AbstractMemoryClass = classMemory;
- /* Document-variable: FFI::AbstractMemory */
+ /*
+ * Document-variable: FFI::AbstractMemory
+ */
rb_global_variable(&rbffi_AbstractMemoryClass);
rb_define_alloc_func(classMemory, memory_allocate);
diff --git a/ext/ffi_c/MappedType.c b/ext/ffi_c/MappedType.c
index 61b6d65..7a77842 100644
--- a/ext/ffi_c/MappedType.c
+++ b/ext/ffi_c/MappedType.c
@@ -50,6 +50,12 @@ mapped_allocate(VALUE klass)
return obj;
}
+/*
+ * call-seq: initialize(converter)
+ * @param [#native_type, #to_native, #from_native] converter +converter+ must respond to
+ * all these methods
+ * @return [self]
+ */
static VALUE
mapped_initialize(VALUE self, VALUE rbConverter)
{
@@ -88,6 +94,11 @@ mapped_mark(MappedType* m)
rb_gc_mark(m->rbConverter);
}
+/*
+ * call-seq: mapped_type.native_type
+ * @return [Type]
+ * Get native type of mapped type.
+ */
static VALUE
mapped_native_type(VALUE self)
{
@@ -97,6 +108,10 @@ mapped_native_type(VALUE self)
return m->rbType;
}
+/*
+ * call-seq: mapped_type.to_native(*args)
+ * @param args depends on {FFI::DataConverter} used to initialize +self+
+ */
static VALUE
mapped_to_native(int argc, VALUE* argv, VALUE self)
{
@@ -107,6 +122,10 @@ mapped_to_native(int argc, VALUE* argv, VALUE self)
return rb_funcall2(m->rbConverter, id_to_native, argc, argv);
}
+/*
+ * call-seq: mapped_type.from_native(*args)
+ * @param args depends on {FFI::DataConverter} used to initialize +self+
+ */
static VALUE
mapped_from_native(int argc, VALUE* argv, VALUE self)
{
@@ -121,6 +140,9 @@ void
rbffi_MappedType_Init(VALUE moduleFFI)
{
+ /*
+ * Document-class: FFI::Type::Mapped
+ */
rbffi_MappedTypeClass = rb_define_class_under(rbffi_TypeClass, "Mapped", rbffi_TypeClass);
rb_global_variable(&rbffi_MappedTypeClass);
diff --git a/ext/ffi_c/Pointer.c b/ext/ffi_c/Pointer.c
index 70f5af9..752b027 100644
--- a/ext/ffi_c/Pointer.c
+++ b/ext/ffi_c/Pointer.c
@@ -68,6 +68,13 @@ ptr_allocate(VALUE klass)
return obj;
}
+/*
+ * call-seq: initialize(type, address)
+ * @param [Type] type type for pointer
+ * @param [Integer, Pointer] address base address for pointer, or another pointer
+ * @return [self]
+ * Create a new pointer from a {Type} and a base adresse or another {Pointer}.
+ */
static VALUE
ptr_initialize(int argc, VALUE* argv, VALUE self)
{
@@ -117,6 +124,16 @@ ptr_initialize(int argc, VALUE* argv, VALUE self)
return self;
}
+/*
+ * call-seq: ptr.initialize_copy(other)
+ * @param [Pointer] other source for cloning or dupping
+ * @return [self]
+ * @raise {RuntimeError} if +other+ is an unbounded memory area, or is unreable/unwritable
+ * @raise {NoMemError} if failed to allocate memory for new object
+ * DO NOT CALL THIS METHOD.
+ *
+ * This method is internally used by #dup and #clone. Memory contents is copied from +other+.
+ */
static VALUE
ptr_initialize_copy(VALUE self, VALUE other)
{
@@ -179,6 +196,13 @@ slice(VALUE self, long offset, long size)
return retval;
}
+/*
+ * Document-method: +
+ * call-seq: ptr + offset
+ * @param [Numeric] offset
+ * @return [Pointer]
+ * Return a new {Pointer} from an existing pointer and an +offset+.
+ */
static VALUE
ptr_plus(VALUE self, VALUE offset)
{
@@ -190,12 +214,25 @@ ptr_plus(VALUE self, VALUE offset)
return slice(self, off, ptr->size == LONG_MAX ? LONG_MAX : ptr->size - off);
}
+/*
+ * call-seq: ptr.slice(offset, length)
+ * @param [Numeric] offset
+ * @param [Numeric] length
+ * @return [Pointer]
+ * Return a new {Pointer} from an existing one. This pointer points on same contents
+ * from +offset+ for a length +length+.
+ */
static VALUE
ptr_slice(VALUE self, VALUE rbOffset, VALUE rbLength)
{
return slice(self, NUM2LONG(rbOffset), NUM2LONG(rbLength));
}
+/*
+ * call-seq: ptr.inspect
+ * @return [String]
+ * Inspect pointer object.
+ */
static VALUE
ptr_inspect(VALUE self)
{
@@ -214,6 +251,12 @@ ptr_inspect(VALUE self)
return rb_str_new2(buf);
}
+/*
+ * Document-method: null?
+ * call-seq: ptr.null?
+ * @return [Boolean]
+ * Return +true+ if +self+ is a {NULL} pointer.
+ */
static VALUE
ptr_null_p(VALUE self)
{
@@ -224,6 +267,12 @@ ptr_null_p(VALUE self)
return ptr->memory.address == NULL ? Qtrue : Qfalse;
}
+/*
+ * Document-method: ==
+ * call-seq: ptr == other
+ * @param [Pointer] other
+ * Check equality between +self+ and +other+. Equality is tested on {#address}.
+ */
static VALUE
ptr_equals(VALUE self, VALUE other)
{
@@ -234,6 +283,11 @@ ptr_equals(VALUE self, VALUE other)
return ptr->memory.address == POINTER(other)->address ? Qtrue : Qfalse;
}
+/*
+ * call-seq: ptr.address
+ * @return [Numeric] pointer's base address
+ * Return +self+'s base address (alias: #to_i).
+ */
static VALUE
ptr_address(VALUE self)
{
@@ -250,6 +304,15 @@ ptr_address(VALUE self)
# define SWAPPED_ORDER LITTLE_ENDIAN
#endif
+/*
+ * Get or set +self+'s endianness
+ * @overload ptr.order
+ * @return [:big, :little] endianness of +self+
+ * @overload ptr.order(order)
+ * @param [Symbol] order endianness to set (+:little+, +:big+ or +:network+). +:big+ and +:network+
+ * are synonymous.
+ * @return [self]
+ */
static VALUE
ptr_order(int argc, VALUE* argv, VALUE self)
{
@@ -289,6 +352,11 @@ ptr_order(int argc, VALUE* argv, VALUE self)
}
+/*
+ * call-seq: ptr.free
+ * @return [self]
+ * Free memory pointed by +self+.
+ */
static VALUE
ptr_free(VALUE self)
{
@@ -307,6 +375,12 @@ ptr_free(VALUE self)
return self;
}
+/*
+ * call-seq: ptr.autorelease = autorelease
+ * @param [Boolean] autorelease
+ * @return [Boolean] +autorelease+
+ * Set +autorelease+ attribute. See also Autorelease section.
+ */
static VALUE
ptr_autorelease(VALUE self, VALUE autorelease)
{
@@ -318,6 +392,11 @@ ptr_autorelease(VALUE self, VALUE autorelease)
return autorelease;
}
+/*
+ * call-seq: ptr.autorelease?
+ * @return [Boolean]
+ * Get +autorelease+ attribute. See also Autorelease section.
+ */
static VALUE
ptr_autorelease_p(VALUE self)
{
@@ -350,7 +429,19 @@ rbffi_Pointer_Init(VALUE moduleFFI)
{
VALUE rbNullAddress = ULL2NUM(0);
+ /*
+ * Document-class: FFI::Pointer
+ * Pointer class is used to manage C pointers with ease. A {Pointer} object is defined by his
+ * {#address} (as a C pointer). It permits additions with an integer for pointer arithmetic.
+ *
+ * ==Autorelease
+ * A pointer object may autorelease his contents when freed (by default). This behaviour may be
+ * changed with {#autorelease=} method.
+ */
rbffi_PointerClass = rb_define_class_under(moduleFFI, "Pointer", rbffi_AbstractMemoryClass);
+ /*
+ * Document-variable: Pointer
+ */
rb_global_variable(&rbffi_PointerClass);
rb_define_alloc_func(rbffi_PointerClass, ptr_allocate);
diff --git a/ext/ffi_c/Type.c b/ext/ffi_c/Type.c
index 42b9eb7..d606ae9 100644
--- a/ext/ffi_c/Type.c
+++ b/ext/ffi_c/Type.c
@@ -51,6 +51,12 @@ type_allocate(VALUE klass)
return obj;
}
+/*
+ * Document-method: initialize
+ * call-seq: initialize(value)
+ * @param [Fixnum,Type] value
+ * @return [self]
+ */
static VALUE
type_initialize(VALUE self, VALUE value)
{
@@ -72,6 +78,11 @@ type_initialize(VALUE self, VALUE value)
return self;
}
+/*
+ * call-seq: type.size
+ * @return [Fixnum]
+ * Return type's size, in bytes.
+ */
static VALUE
type_size(VALUE self)
{
@@ -82,6 +93,10 @@ type_size(VALUE self)
return INT2FIX(type->ffiType->size);
}
+/*
+ * call-seq: type.alignment
+ * @return [Fixnum]
+ */
static VALUE
type_alignment(VALUE self)
{
@@ -92,6 +107,11 @@ type_alignment(VALUE self)
return INT2FIX(type->ffiType->alignment);
}
+/*
+ * call-seq: type.inspect
+ * @return [String]
+ * Inspect {Type} object.
+ */
static VALUE
type_inspect(VALUE self)
{
@@ -128,6 +148,11 @@ builtin_type_free(BuiltinType *type)
xfree(type);
}
+/*
+ * call-seq: type.inspect
+ * @return [String]
+ * Inspect {Type::Builtin} object.
+ */
static VALUE
builtin_type_inspect(VALUE self)
{
@@ -216,8 +241,18 @@ void
rbffi_Type_Init(VALUE moduleFFI)
{
VALUE moduleNativeType;
- VALUE classType = rbffi_TypeClass = rb_define_class_under(moduleFFI, "Type", rb_cObject);
-
+ /*
+ * Document-class: FFI::Type
+ * This class manages C types.
+ *
+ * It embbed {FFI::Type::Builtin} objects as constants (for names,
+ * see {FFI::NativeType}).
+ */
+ rbffi_TypeClass = rb_define_class_under(moduleFFI, "Type", rb_cObject);
+
+ /*
+ * Document-constant: FFI::TypeDefs
+ */
rb_define_const(moduleFFI, "TypeDefs", typeMap = rb_hash_new());
rb_define_const(moduleFFI, "SizeTypes", sizeMap = rb_hash_new());
rb_global_variable(&typeMap);
@@ -226,19 +261,62 @@ rbffi_Type_Init(VALUE moduleFFI)
id_type_size = rb_intern("type_size");
id_size = rb_intern("size");
-
+ /*
+ * Document-class: FFI::Type::Builtin
+ * Class for Built-in types.
+ */
classBuiltinType = rb_define_class_under(rbffi_TypeClass, "Builtin", rbffi_TypeClass);
+ /*
+ * Document-module: FFI::NativeType
+ * This module defines constants for native (C) types.
+ *
+ * ==Native type constants
+ * Native types are defined by constants :
+ * * INT8, SCHAR, CHAR
+ * * UINT8, UCHAR
+ * * INT16, SHORT, SSHORT
+ * * UINT16, USHORT
+ * * INT32,, INT, SINT
+ * * UINT32, UINT
+ * * INT64, LONG_LONG, SLONG_LONG
+ * * UINT64, ULONG_LONG
+ * * LONG, SLONG
+ * * ULONG
+ * * FLOAT32, FLOAT
+ * * FLOAT64, DOUBLE
+ * * POINTER
+ * * CALLBACK
+ * * FUNCTION
+ * * CHAR_ARRAY
+ * * BOOL
+ * * STRING (immutable string, nul terminated)
+ * * STRUCT (struct-b-value param or result)
+ * * ARRAY (array type definition)
+ * * MAPPED (custom native type)
+ * For function return type only :
+ * * VOID
+ * For function argument type only :
+ * * BUFFER_IN
+ * * BUFFER_OUT
+ * * VARARGS (function takes a variable number of arguments)
+ *
+ * All these constants are exported to {FFI} module prefixed with "TYPE_".
+ * They are objets from {FFI::Type::Builtin} class.
+ */
moduleNativeType = rb_define_module_under(moduleFFI, "NativeType");
+ /*
+ * Document-global: FFI::Type
+ */
rb_global_variable(&rbffi_TypeClass);
rb_global_variable(&classBuiltinType);
rb_global_variable(&moduleNativeType);
- rb_define_alloc_func(classType, type_allocate);
- rb_define_method(classType, "initialize", type_initialize, 1);
- rb_define_method(classType, "size", type_size, 0);
- rb_define_method(classType, "alignment", type_alignment, 0);
- rb_define_method(classType, "inspect", type_inspect, 0);
+ rb_define_alloc_func(rbffi_TypeClass, type_allocate);
+ rb_define_method(rbffi_TypeClass, "initialize", type_initialize, 1);
+ rb_define_method(rbffi_TypeClass, "size", type_size, 0);
+ rb_define_method(rbffi_TypeClass, "alignment", type_alignment, 0);
+ rb_define_method(rbffi_TypeClass, "inspect", type_inspect, 0);
// Make Type::Builtin non-allocatable
rb_undef_method(CLASS_OF(classBuiltinType), "new");
@@ -250,16 +328,19 @@ rbffi_Type_Init(VALUE moduleFFI)
// Define all the builtin types
#define T(x, ffiType) do { \
VALUE t = Qnil; \
- rb_define_const(classType, #x, t = builtin_type_new(classBuiltinType, NATIVE_##x, ffiType, #x)); \
+ rb_define_const(rbffi_TypeClass, #x, t = builtin_type_new(classBuiltinType, NATIVE_##x, ffiType, #x)); \
rb_define_const(moduleNativeType, #x, t); \
rb_define_const(moduleFFI, "TYPE_" #x, t); \
} while(0)
#define A(old_type, new_type) do { \
- VALUE t = rb_const_get(classType, rb_intern(#old_type)); \
- rb_const_set(classType, rb_intern(#new_type), t); \
+ VALUE t = rb_const_get(rbffi_TypeClass, rb_intern(#old_type)); \
+ rb_const_set(rbffi_TypeClass, rb_intern(#new_type), t); \
} while(0)
+ /*
+ * Document-constant: FFI::Type::Builtin::VOID
+ */
T(VOID, &ffi_type_void);
T(INT8, &ffi_type_sint8);
A(INT8, SCHAR);
diff --git a/ext/ffi_c/ffi.c b/ext/ffi_c/ffi.c
index f8c955f..1b92818 100644
--- a/ext/ffi_c/ffi.c
+++ b/ext/ffi_c/ffi.c
@@ -50,6 +50,11 @@ static VALUE moduleFFI = Qnil;
void
Init_ffi_c(void) {
+ /*
+ * Document-module: FFI
+ *
+ * This module embbed type constants from {FFI::NativeType}.
+ */
rbffi_FFIModule = moduleFFI = rb_define_module("FFI");
rb_global_variable(&moduleFFI);
diff --git a/lib/ffi/pointer.rb b/lib/ffi/pointer.rb
index 352eb65..16d2ecc 100644
--- a/lib/ffi/pointer.rb
+++ b/lib/ffi/pointer.rb
@@ -24,10 +24,15 @@ module FFI
SIZE = Platform::ADDRESS_SIZE / 8
# Return the size of a pointer on the current platform, in bytes
+ # @return [Numeric]
def self.size
SIZE
end
+ # @param [nil,Numeric] len length of string to return
+ # @return [String]
+ # Read pointer's contents as a string, or the first +len+ bytes of the
+ # equivalent string if +len+ is not +nil+.
def read_string(len=nil)
if len
get_bytes(0, len)
@@ -36,24 +41,54 @@ module FFI
end
end
+ # @param [Numeric] len length of string to return
+ # @return [String]
+ # Read the first +len+ bytes of pointer's contents as a string.
+ #
+ # Same as:
+ # ptr.read_string(len) # with len not nil
def read_string_length(len)
get_bytes(0, len)
end
+ # @return [String]
+ # Read pointer's contents as a string.
+ #
+ # Same as:
+ # ptr.read_string # with no len
def read_string_to_null
get_string(0)
end
+ # @param [String] str string to write
+ # @param [Numeric] len length of string to return
+ # @return [self]
+ # Write +len+ first bytes of +str+ in pointer's contents.
+ #
+ # Same as:
+ # ptr.write_string(str, len) # with len not nil
def write_string_length(str, len)
put_bytes(0, str, 0, len)
end
+ # @param [String] str string to write
+ # @param [Numeric] len length of string to return
+ # @return [self]
+ # Write +str+ in pointer's contents, or first +len+ bytes if
+ # +len+ is not +nil+.
def write_string(str, len=nil)
len = str.bytesize unless len
# Write the string data without NUL termination
put_bytes(0, str, 0, len)
end
+ # @param [Type] type type of data to read from pointer's contents
+ # @param [Symbol] reader method to send to +self+ to read +type+
+ # @param [Numeric] length
+ # @return [Array]
+ # Read an array of +type+ of length +length+.
+ # @example
+ # ptr.write_array_of_type(TYPE_UINT8, :get_uint8, 4) # -> [1, 2, 3, 4]
def read_array_of_type(type, reader, length)
ary = []
size = FFI.type_size(type)
@@ -65,6 +100,13 @@ module FFI
ary
end
+ # @param [Type] type type of data to write to pointer's contents
+ # @param [Symbol] writer method to send to +self+ to write +type+
+ # @param [Array] ary
+ # @return [self]
+ # Write +ary+ in pointer's contents as +type+.
+ # @example
+ # ptr.write_array_of_type(TYPE_UINT8, :put_uint8, [1, 2, 3 ,4])
def write_array_of_type(type, writer, ary)
size = FFI.type_size(type)
tmp = self
diff --git a/lib/ffi/types.rb b/lib/ffi/types.rb
index cd94722..e721ba6 100644
--- a/lib/ffi/types.rb
+++ b/lib/ffi/types.rb
@@ -17,17 +17,29 @@
# version 3 along with this work. If not, see <http://www.gnu.org/licenses/>.
#
+# see {file:README}
module FFI
+ # @param [Type, DataConverter, Symbol] old type definition used by {FFI.find_type}
+ # @param [Symbol] add new type definition's name to add
+ # @return [Type]
+ # Add a definition type to type definitions.
def self.typedef(old, add)
TypeDefs[add] = self.find_type(old)
end
+ # (see FFI.typedef)
def self.add_typedef(old, add)
typedef old, add
end
+ # @param [Type, DataConverter, Symbol] name
+ # @param [Hash] type_map if nil, {FFI::TypeDefs} is used
+ # @return [Type]
+ # Find a type in +type_map+ ({FFI::TypeDefs}, by default) from
+ # a type objet, a type name (symbol). If +name+ is a {DataConverter},
+ # a new {Type::Mapped} is created.
def self.find_type(name, type_map = nil)
if name.is_a?(Type)
name
@@ -46,6 +58,7 @@ module FFI
end
end
+ # List of type definitions
TypeDefs.merge!({
# The C void type; only useful for function return types
:void => Type::VOID,
@@ -120,11 +133,15 @@ module FFI
:varargs => Type::VARARGS,
})
- # Returns a [ String, Pointer ] tuple so the C memory for the string can be freed
+
class StrPtrConverter
extend DataConverter
native_type Type::POINTER
+ # @param [Pointer] val
+ # @param [] ctx
+ # @return [Array<String, Pointer>]
+ # Returns a [ String, Pointer ] tuple so the C memory for the string can be freed
def self.from_native(val, ctx)
[ val.null? ? nil : val.get_string(0), val ]
end
@@ -133,6 +150,9 @@ module FFI
typedef(StrPtrConverter, :strptr)
+ # @param type +type+ is an instance of class accepted by {FFI.find_type}
+ # @return [Numeric]
+ # Get +type+ size, in bytes.
def self.type_size(type)
find_type(type).size
end