| 1 | """ |
|---|
| 2 | Show how to use arrays including declaration, literals and allocation. |
|---|
| 3 | |
|---|
| 4 | An array type is any type followed by empty square brackets such as: |
|---|
| 5 | int[] |
|---|
| 6 | bool[] |
|---|
| 7 | Customer[] |
|---|
| 8 | |
|---|
| 9 | An array literal is like a list literal, but prefixed by an @ such as: |
|---|
| 10 | @[1, 2, 3] |
|---|
| 11 | @['foo', 'bar'] |
|---|
| 12 | |
|---|
| 13 | An array instantiation follows the general form TYPE(ARGS) where ARGS is the size |
|---|
| 14 | of the array such as: |
|---|
| 15 | int[](100) |
|---|
| 16 | char[](bufSize) |
|---|
| 17 | |
|---|
| 18 | Note that generic lists are more flexible and convenient than arrays. Therefore, |
|---|
| 19 | they are preferred over arrays except when a method interface requires an array |
|---|
| 20 | or in extreme performance situations. |
|---|
| 21 | |
|---|
| 22 | For argument types, IList<of> is ideal because it can accept both arrays and |
|---|
| 23 | lists. |
|---|
| 24 | """ |
|---|
| 25 | |
|---|
| 26 | class ArraysExample |
|---|
| 27 | |
|---|
| 28 | shared |
|---|
| 29 | |
|---|
| 30 | def sum(nums as int[]) as int # nums arg is array of int |
|---|
| 31 | test |
|---|
| 32 | nums = @[1, 2, 3] # array literal inferred as type int[] |
|---|
| 33 | assert nums.length == 3 |
|---|
| 34 | assert nums[2] == 3 |
|---|
| 35 | assert ArraysExample.sum(nums) == 6 |
|---|
| 36 | |
|---|
| 37 | # instantiate a 'blank' array of a specific size |
|---|
| 38 | lottaNums = int[](100) |
|---|
| 39 | |
|---|
| 40 | # Array contents are initialized to the 'default value' for the |
|---|
| 41 | # type (0 in this case). The general format for instantiation is: |
|---|
| 42 | # <var-name> = <type>(<args>) |
|---|
| 43 | # and in the case of arrays, the <type> is an array type |
|---|
| 44 | # (suffixed by "[]") and <args> is the length of the array, |
|---|
| 45 | # so the array allocation form is: |
|---|
| 46 | # <var-name> = <type>[](<length>) |
|---|
| 47 | # such as: |
|---|
| 48 | # nums = number[](100) |
|---|
| 49 | |
|---|
| 50 | assert lottaNums.length == 100 |
|---|
| 51 | assert lottaNums[9] == 0 |
|---|
| 52 | assert ArraysExample.sum(lottaNums) == 0 |
|---|
| 53 | body |
|---|
| 54 | sum = 0 |
|---|
| 55 | for num in nums, sum += num |
|---|
| 56 | return sum |
|---|
| 57 | |
|---|
| 58 | def sum(nums as IList<of int>) as int |
|---|
| 59 | # This method is more easily reused because it accepts any array, |
|---|
| 60 | # list or any object that implements IList. |
|---|
| 61 | sum = 0 |
|---|
| 62 | for num in nums, sum += num |
|---|
| 63 | return sum |
|---|
| 64 | |
|---|
| 65 | def moreHowTo |
|---|
| 66 | nums as int[] = int[](2) # explicitly typed local var |
|---|
| 67 | assert nums.length == 2 |
|---|
| 68 | assert ArraysExample.sum(nums) == 0 |
|---|
| 69 | nums[0] = 10 |
|---|
| 70 | nums[1] = 11 |
|---|
| 71 | assert ArraysExample.sum(nums) == 21 |
|---|
| 72 | |
|---|
| 73 | # compare arrays |
|---|
| 74 | assert nums == @[10, 11] |
|---|
| 75 | |
|---|
| 76 | # another example |
|---|
| 77 | n = 1024 |
|---|
| 78 | ch = char[](n) |
|---|
| 79 | for i in n, ch[i] = c'z' |
|---|
| 80 | |
|---|
| 81 | # convert a list to an array |
|---|
| 82 | assert [10, 11].toArray == @[10, 11] |
|---|
| 83 | |
|---|
| 84 | def main |
|---|
| 85 | # example passing array to .NET library method |
|---|
| 86 | # .NET String.split() expects an array of chars |
|---|
| 87 | parts = 'a|b:c'.split(@[c'|', c':']) |
|---|
| 88 | assert parts.length == 3 |
|---|
| 89 | for part in parts |
|---|
| 90 | assert part in ['a', 'b', 'c'] |
|---|
| 91 | |
|---|
| 92 | |
|---|
| 93 | class BinaryFileReader is abstract |
|---|
| 94 | """ |
|---|
| 95 | Abstract class that shows array handling for .NET binary file API. |
|---|
| 96 | Reads a file in fixed size chunks. |
|---|
| 97 | Subclass and override .handleBuf to provide content handling. |
|---|
| 98 | |
|---|
| 99 | Sample array code is in the _readStream method. |
|---|
| 100 | """ |
|---|
| 101 | |
|---|
| 102 | var _fileName as String? |
|---|
| 103 | var _stream as Stream? |
|---|
| 104 | var _bufSize as int |
|---|
| 105 | |
|---|
| 106 | cue init(fileName as String) |
|---|
| 107 | .init(fileName, 1024) |
|---|
| 108 | |
|---|
| 109 | cue init(fileName as String, bufSize as int) |
|---|
| 110 | base.init |
|---|
| 111 | _fileName = fileName |
|---|
| 112 | _bufSize = bufSize |
|---|
| 113 | |
|---|
| 114 | cue init(stream as Stream) |
|---|
| 115 | .init(stream, 1024) |
|---|
| 116 | |
|---|
| 117 | cue init(stream as Stream, bufSize as int) |
|---|
| 118 | base.init |
|---|
| 119 | _stream = stream |
|---|
| 120 | _bufSize = bufSize |
|---|
| 121 | |
|---|
| 122 | def readFile |
|---|
| 123 | if _fileName |
|---|
| 124 | using stream = FileStream(_fileName, FileMode.Open, FileAccess.Read) |
|---|
| 125 | _readStream(stream) |
|---|
| 126 | else |
|---|
| 127 | _readStream(_stream to !) |
|---|
| 128 | |
|---|
| 129 | def readStandardInput |
|---|
| 130 | using _stream = Console.openStandardInput |
|---|
| 131 | _readStream(_stream to !) |
|---|
| 132 | |
|---|
| 133 | def _readStream(stream as Stream) |
|---|
| 134 | bufSize = _bufSize |
|---|
| 135 | buffer = uint8[](bufSize) |
|---|
| 136 | offset = 0 |
|---|
| 137 | using br = BinaryReader(stream) |
|---|
| 138 | nRead = br.read(buffer, 0, bufSize) |
|---|
| 139 | while nRead > 0 |
|---|
| 140 | .handleBuf(buffer, nRead, offset) |
|---|
| 141 | offset += nRead |
|---|
| 142 | nRead = br.read(buffer, 0, bufSize) |
|---|
| 143 | .fileEnd(offset) |
|---|
| 144 | |
|---|
| 145 | def handleBuf(buffer as uint8[], nRead as int, offset as int) is abstract |
|---|
| 146 | """ |
|---|
| 147 | Called on each buffer read, whether filled or partially filled. |
|---|
| 148 | """ |
|---|
| 149 | |
|---|
| 150 | def fileEnd(offset as int) is abstract |
|---|
| 151 | """ |
|---|
| 152 | Called on eof before file closed. |
|---|
| 153 | """ |
|---|