X-Git-Url: http://nitlanguage.org diff --git a/lib/c.nit b/lib/c.nit index 3732085..7db5945 100644 --- a/lib/c.nit +++ b/lib/c.nit @@ -14,10 +14,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Utilities and performant structure for the FFI with C +# Structures and services for compatibility with the C language module c -import standard -intrude import standard::collection::array + +import core +intrude import core::collection::array # A thin wrapper around a `NativeCArray` adding length information abstract class CArray[E] @@ -29,7 +30,7 @@ abstract class CArray[E] # Pointer to the real C array var native_array: NATIVE is noinit - private init(length: Int) do self._length = length + init(length: Int) is old_style_init do self._length = length redef fun [](index) do @@ -38,6 +39,7 @@ abstract class CArray[E] return native_array[index] end + # Set `val` at `index`. fun []=(index: Int, val: E) do assert not destroyed @@ -45,7 +47,14 @@ abstract class CArray[E] native_array[index] = val end + # Was this instance destroyed? + # + # See `CArray::destroy`. var destroyed = false + + # Free used memory used by `native_array`. + # + # Also set `destroyed` to true. fun destroy do if destroyed then return @@ -57,10 +66,15 @@ end # A native C array, as in a pointer to the first element of the array extern class NativeCArray `{ void * `} + + # Type of contained elements. type E: nullable Object - fun [](index: E): E is abstract - fun []=(index: E, val: E) is abstract + # Get element at `index`. + fun [](index: Int): E is abstract + + # Set `val` at `index`. + fun []=(index: Int, val: E) is abstract # Return pointer to the address to the second element of this array # @@ -73,14 +87,14 @@ class CIntArray super CArray[Int] redef type NATIVE: NativeCIntArray - init(size: Int) - do + # Initialize a new CIntArray of `size` elements. + init(size: Int) is old_style_init do native_array = new NativeCIntArray(size) super size end - # Build from an `Array[Int]` - new from(array: Array[Int]) + # Create from a `SequenceRead[Int]` + new from(array: SequenceRead[Int]) do var carray = new CIntArray(array.length) for i in array.length.times do @@ -95,27 +109,64 @@ extern class NativeCIntArray `{ int* `} super NativeCArray redef type E: Int + # Initialize a new NativeCIntArray of `size` elements. new(size: Int) `{ return calloc(size, sizeof(int)); `} - redef fun [](index) `{ return recv[index]; `} - redef fun []=(index, val) `{ recv[index] = val; `} - redef fun +(offset) `{ return recv + offset; `} + redef fun [](index) `{ return self[index]; `} + redef fun []=(index, val) `{ self[index] = val; `} + + redef fun +(offset) `{ return self + offset; `} +end + +# Wrapper of a C array of type `uint16_t*` with length and destroy state +class CUInt16Array + super CArray[Int] + redef type NATIVE: NativeCUInt16Array + + # Initialize a new CIntArray of `size` elements. + init(size: Int) is old_style_init do + native_array = new NativeCUInt16Array(size) + super size + end + + # Create from a `SequenceRead[Int]` + new from(array: SequenceRead[Int]) + do + var carray = new CUInt16Array(array.length) + for i in array.length.times do + carray[i] = array[i] + end + return carray + end +end + +# An array of `uint16_t` in C +extern class NativeCUInt16Array `{ uint16_t* `} + super NativeCArray + redef type E: Int + + # Initialize a new NativeCUInt16Array of `size` elements. + new(size: Int) `{ return calloc(size, sizeof(uint16_t)); `} + + redef fun [](index) `{ return self[index]; `} + redef fun []=(index, val) `{ self[index] = val; `} + + redef fun +(offset) `{ return self + offset; `} end # Wrapper around an array of `unsigned char` in C (`unsigned char*`) with length and destroy state class CByteArray - super CArray[Int] + super CArray[Byte] redef type NATIVE: NativeCByteArray # Allocate a new array of `size` - init(size: Int) - do + init(size: Int) is old_style_init do native_array = new NativeCByteArray(size) super size end - # Build from an `Array[Int]` - new from(array: Array[Int]) + # Create from a `SequenceRead[Byte]` + new from(array: SequenceRead[Byte]) do var carray = new CByteArray(array.length) for i in array.length.times do @@ -123,25 +174,79 @@ class CByteArray end return carray end + + # Safely move `n` bytes from `dst_offset` to `src_offset`, inside this array + # + # Require: all arguments greater than 0 and ranges within `length` + fun move(dst_offset, src_offset, n: Int) + do + assert dst_offset >= 0 and src_offset >= 0 and n >= 0 + assert dst_offset + n <= length + assert src_offset + n <= length + + native_array.move(dst_offset, src_offset, n) + end end # An array of `unsigned char` in C (`unsigned char*`) extern class NativeCByteArray `{ unsigned char* `} super NativeCArray - redef type E: Int + redef type E: Byte # Allocate a new array of `size` new(size: Int) `{ return calloc(size, sizeof(unsigned char)); `} - redef fun [](index) `{ return recv[index]; `} - redef fun []=(index, val) `{ recv[index] = val; `} + redef fun [](index) `{ return self[index]; `} + redef fun []=(index, val) `{ self[index] = val; `} + + redef fun +(offset) `{ return self + offset; `} + + # Move `n` bytes from `dst_offset` to `src_offset` + fun move(dst_offset, src_offset, n: Int) `{ + memmove(self+dst_offset, self+src_offset, n); + `} +end + +# Wrapper around an array of `CString` in C (`char**`) with length and destroy state. +class CCStringArray + super CArray[CString] + + redef type NATIVE: NativeCStringArray + + # Initialize a new NativeCStringArray of `size` elements. + init(size: Int) is old_style_init do + native_array = new NativeCStringArray(size) + super size + end + + # Create from an `SequenceRead[CString]` + new from(array: SequenceRead[CString]) + do + var carray = new CCStringArray(array.length) + for i in array.length.times do + carray[i] = array[i] + end + return carray + end +end + +# An array of `CString` in C (`char**`) +extern class NativeCStringArray `{ char** `} + super NativeCArray + + redef type E: CString + + # Initialize a new NativeCStringArray of `size` elements. + new(size: Int) `{ return calloc(size, sizeof(char*)); `} - redef fun +(offset) `{ return recv + offset; `} + redef fun [](index) `{ return self[index]; `} + redef fun []=(index, val) `{ self[index] = val; `} + redef fun +(offset) `{ return self + offset; `} end -redef class NativeString +redef class CString super NativeCArray redef type E: Char - redef fun +(offset) `{ return recv + offset; `} + redef fun +(offset) `{ return self + offset; `} end