update NOTICE
[nit.git] / lib / c.nit
index c0bd650..ae1b875 100644 (file)
--- a/lib/c.nit
+++ b/lib/c.nit
 
 # Utilities and performant structure for the FFI with C
 module c
+import standard
+intrude import standard::collection::array
 
 # A thin wrapper around a `NativeCArray` adding length information
 abstract class CArray[E]
        super AbstractArrayRead[E]
 
-       private init(length: Int) do self._length = length
+       # The corresponding C type
+       type NATIVE: NativeCArray
+
+       # Pointer to the real C array
+       var native_array: NATIVE is noinit
+
+       private init(length: Int) is old_style_init do self._length = length
+
+       redef fun [](index)
+       do
+               assert not destroyed
+               assert index >= 0 and index < length
+               return native_array[index]
+       end
+
+       # Set `val` at `index`.
+       fun []=(index: Int, val: E)
+       do
+               assert not destroyed
+               assert index >= 0 and index < length
+               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
+
+               native_array.free
+               destroyed = true
+       end
 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
-       type SELF: NativeCArray
 
-       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
        #
@@ -41,45 +84,69 @@ end
 # Wrapper around an array of `int` in C (`int*`) with length and destroy state
 class CIntArray
        super CArray[Int]
+       redef type NATIVE: NativeCIntArray
 
-       var native_array: 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
 
-       redef fun [](index)
+       # Build from an `Array[Int]`
+       new from(array: Array[Int])
        do
-               assert not destroyed
-               assert index >= 0 and index < length
-               return native_array[index]
+               var carray = new CIntArray(array.length)
+               for i in array.length.times do
+                       carray[i] = array[i]
+               end
+               return carray
        end
+end
 
-       fun []=(index: Int, val: Int)
-       do
-               assert not destroyed
-               assert index >= 0 and index < length
-               native_array[index] = val
+# An array of `int` in C (`int*`)
+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; `}
+end
+
+# Wrapper around an array of `unsigned char` in C (`unsigned char*`) with length and destroy state
+class CByteArray
+       super CArray[Int]
+       redef type NATIVE: NativeCByteArray
+
+       # Allocate a new array of `size`
+       init(size: Int) is old_style_init do
+               native_array = new NativeCByteArray(size)
+               super size
        end
 
-       var destroyed = false
-       fun destroy
+       # Build from an `Array[Int]`
+       new from(array: Array[Int])
        do
-               if destroyed then return
-
-               native_array.free
-               destroyed = true
+               var carray = new CByteArray(array.length)
+               for i in array.length.times do
+                       carray[i] = array[i]
+               end
+               return carray
        end
 end
 
-# An array of `int` in C (`int*`)
-extern class NativeCIntArray `{ int* `}
+# An array of `unsigned char` in C (`unsigned char*`)
+extern class NativeCByteArray `{ unsigned char* `}
        super NativeCArray
        redef type E: Int
-       redef type SELF: NativeCIntArray
 
-       new(size: Int) `{ return calloc(size, sizeof(int)); `}
+       # 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; `}
 
@@ -89,7 +156,6 @@ end
 redef class NativeString
        super NativeCArray
        redef type E: Char
-       redef type SELF: NativeString
 
        redef fun +(offset) `{ return recv + offset; `}
 end