How To Use Arrays
Print Hello World
Write Basic Syntax
Use Properties
Make An If Else Ladder
Make A Branch Statement
Declare Inits
Use Lists
Use Arrays
Make A Class Hierarchy
Use Nil And Nilable Types
Use Dynamic Typing
Declare Variable Number Of Args
Read And Write Files
Check Inheritance And Implementation
Customize Object Equality
Pass References To Methods
Translate Pseudo Code To Cobra 1
Translate Pseudo Code To Cobra 2
Implement IEnumerable 1
Implement IEnumerable 2
Iterate Through Recursive Data With Yield
Make A Collection Class
Declare Contracts
Threads
Win Forms
WPF
GTK
Qyoto
Access MySQL
XNA
Open TK
 
"""
Show how to use arrays including declaration, literals and allocation.

An array type is any type followed by empty square brackets such as:
    int[]
    bool[]
    Customer[]

An array literal is like a list literal, but prefixed by an @ such as:
    @[1, 2, 3]
    @['foo', 'bar']

An array instantiation follows the general form TYPE(ARGS) where ARGS is the size
of the array such as:
    int[](100)
    char[](bufSize)

Note that generic lists are more flexible and convenient than arrays. Therefore,
they are preferred over arrays except when a method interface requires an array
or in extreme performance situations.

For argument types, IList<of> is ideal because it can accept both arrays and
lists.
"""

class ArraysExample

    shared
     
        def sum(nums as int[]) as int  # nums arg is array of int
            test 
                nums = @[1, 2, 3]  # array literal inferred as type int[]
                assert nums.length == 3
                assert nums[2] == 3 
                assert ArraysExample.sum(nums) == 6
                
                # instantiate a 'blank' array of a specific size
                lottaNums = int[](100)

                # Array contents are initialized to the 'default value' for the
                # type (0 in this case). The general format for instantiation is:
                #     <var-name> = <type>(<args>)
                # and in the case of arrays, the <type> is an array type
                # (suffixed by "[]") and <args> is the length of the array,
                # so the array allocation form is:
                #     <var-name> = <type>[](<length>)
                # such as:
                #     nums = number[](100)

                assert lottaNums.length == 100
                assert lottaNums[9] == 0
                assert ArraysExample.sum(lottaNums) == 0 
            body 
                sum = 0 
                for num in nums, sum += num
                return sum 
        
        def sum(nums as IList<of int>) as int
            # This method is more easily reused because it accepts any array,
            # list or any object that implements IList.
            sum = 0
            for num in nums, sum += num
            return sum 

        def moreHowTo
            nums as int[] = int[](2)  # explicitly typed local var
            assert nums.length == 2
            assert ArraysExample.sum(nums) == 0
            nums[0] = 10
            nums[1] = 11
            assert ArraysExample.sum(nums) == 21

            # compare arrays
            assert nums == @[10, 11]

            # another example
            n = 1024
            ch = char[](n)
            for i in n, ch[i] = c'z'

            # convert a list to an array
            assert [10, 11].toArray == @[10, 11]

        def main 
            # example passing array to .NET library method
            # .NET String.split() expects an array of chars
            parts = 'a|b:c'.split(@[c'|', c':']) 
            assert parts.length == 3 
            for part in parts 
                assert part in ['a', 'b', 'c']
                
            
class BinaryFileReader is abstract
    """
    Abstract class that shows array handling for .NET binary file API.
    Reads a file in fixed size chunks.
    Subclass and override .handleBuf to provide content handling.
    
    Sample array code is in the _readStream method.
    """

    var _fileName as String?
    var _stream as Stream?
    var _bufSize as int

    cue init(fileName as String)
        .init(fileName, 1024)

    cue init(fileName as String, bufSize as int)
        base.init
        _fileName = fileName
        _bufSize = bufSize
    
    cue init(stream as Stream)
        .init(stream, 1024)

    cue init(stream as Stream, bufSize as int)
        base.init
        _stream = stream
        _bufSize = bufSize

    def readFile
        if _fileName
            using stream = FileStream(_fileName, FileMode.Open, FileAccess.Read)
                _readStream(stream)
        else
            _readStream(_stream to !)

    def readStandardInput
        using _stream = Console.openStandardInput
            _readStream(_stream to !)

    def _readStream(stream as Stream)
        bufSize = _bufSize
        buffer = uint8[](bufSize)
        offset = 0
        using br = BinaryReader(stream)
            nRead = br.read(buffer, 0, bufSize)
            while nRead > 0     
                .handleBuf(buffer, nRead, offset)
                offset += nRead
                nRead = br.read(buffer, 0, bufSize)
            .fileEnd(offset)

    def handleBuf(buffer as uint8[], nRead as int, offset as int) is abstract
        """ 
        Called on each buffer read, whether filled or partially filled.
        """

    def fileEnd(offset as int) is abstract
        """ 
        Called on eof before file closed.
        """