var s = @[1,2,3,4]
var f = open("foo", fmWrite)
f.write(s) # writes the string "@[1,2,3,4]"
f.writeln(s) # writes the string "1234\n"
discard f.writeBuffer(addr s[0], len(s) * sizeof(s[0])) # writes s as binary
Basically what you need is a pointer to the start of the data (addr s[0]) and the total length in bytes (len(s) * sizeof(s[0]))
Thanks, One more question. I get around my earlier question but using writeBytes proc which takes an openArray:
var www: seq[int8] = newSeq[int8](3)
www = @[int8 1,2,3]
var f = open("test", fmWrite)
var written = f.writeBytes (www ,sizeof(0),sizeof(3))
I get a type mismatch if I use uint8 as the seq type. Is there any reason writeBytes forces me to use int8 instead? Well, but there is even byte* = uint8 in the system module. For me a byte is better represented as a uint8 (0-255).
While we're at it, isn't it a bit strange that ByteAddress* = int? So pointers can be negative now?
Also, var written = f.writeBytes (www ,sizeof(0),sizeof(3)) is wrong, it should be var written = f.writeBytes(www, 0, 3) instead. Could also use www.low and www.len instead of 0 and 3.
Edit: Now with a pull request: https://github.com/Araq/Nim/pull/2165
def: While we're at it, isn't it a bit strange that ByteAddress* = int ? So pointers can be negative now?
That isn't strange. Nim requires that Nim's int be at least C's intptr_t, which can store pointers losslessly. And whether you think of pointer representations as signed or unsigned is just a matter of convention.
So, why a signed instead of an unsigned value? Because mixing signed and unsigned arithmetic is ill-defined (especially when generating C/C++), so you want to settle for one kind of representation and use the other only selectively when needed. Since signed integers are generally the more useful case, Nim uses the signed version most of the time.
How does one deal with unsigned arithmethic in Nim? First of all, Nim has a set of operators that perform unsigned operations and comparisons (modulo 2^n) on nominally signed integers, e.g.:
var a = 1
var b = -1
echo(b >% a)
This allows you to technically do everything on signed integers without ever declaring something as a uint.
There are a few problems/inconsistencies in practice:
First of all, the right-shift operator shr. This is implementation-defined in C/C++ for negative numbers, so for a shr b, Nim will operate on a and b as unsigned numbers. There is, consequently, no way to do an arithmetic right shift (because there's no way to portably do that in C/C++ without overhead). If you do absolutely need an arithmetic right shift, then you have to either escape to platform-dependent C or have to write (slower) code that depends on the sign of x, e.g.:
proc asr(x, y: int): int =
result = x shr y
if x < 0:
result = result or int.low
Second, if you do use unsigned types (e.g. to avoid the line noise from all the % operators or for C interoperability), then you have to import unsigned, and the unsigned module does not allow for operations on differently sized unsigned integers. This is mostly annoying with shl and shr, where this doesn't make any real sense; for other operations, it does make sense, because you'd be performing modulo arithmetic with an ambiguous modulus.
However (and third), modulo operators on smaller int types (e.g. int8 or int16) will quietly coerce data to the largest int type if the arguments are of a different size, which may or may not be what you want. (And shift operators will use the larger size of the two operands, though they should probably use the size of the left operand.)
Finally, there's no unary minus for unsigned/modulo arithmetic, so you have to instead use 0-%x or 0-x.