type PasString*[n: static byte] = object
size: byte
content: array[n,char]
proc `<<`*(s:var PasString, v:string)=
s.size=v.len.byte
if s.size > 0:
for ix,c in v:
s.content[ix]=c
proc `$`*(s:PasString):string=
result = newString(s.size)
copyMem(result[0].addr,s.content[0].unsafeAddr,s.size)
var
city: PasString[30]
city << "New York"
echo city
The objective of the code is to read and write files that contains Pascal's ShorString. ShortString is, basically, an array where the first position is the length of the string and next positions have the characters.
TIA
Can i raise an exception when create a variable with zero length e.g. PasString[0] ?
You can define it as PasString*[n: static range[1..255]] however unfortunately this does not create an error on PasString[0].
Is there any way to change operator << by = ?
The actual operator = is not directly overloadable. There is an old mechanism that acts on procs named =, but this has since been renamed to =copy.
Normally, you would be able to use converters:
type PasString*[n: static byte] = object
size: byte
content: array[n,char]
proc writeString*(s:var PasString, v:string)=
s.size=v.len.byte
if s.size > 0:
for ix,c in v:
s.content[ix]=c
converter toPasString*(s: string): PasString =
writeString(result, s)
var
city: PasString[30]
city = "New York"
However PasString is not a type by itself and has a generic parameter which is also a static value, so we would have to write this:
converter toPasString*[n: static byte](s: string): PasString[n] =
writeString(result, s)
However in current Nim the converter cannot infer n or some other issue is happening, so this gives an error.
For the record things like writeString(city, "New York") (though maybe with a better name) are common in Nim and not really frowned upon. But custom operators like << can complicate the namespace very quickly if people use them for different purposes.
I would do it this way:
type PasString*[n: static byte] = object
size: byte
content: array[n, char]
proc `!`*(v: string; n: static byte): PasString[n] =
result = PasString[n](size: v.len.byte)
if v.len > 0:
for ix, c in v:
result.content[ix] = c
proc `$`*(s:PasString):string=
result = newString(s.size)
copyMem(result[0].addr,s.content[0].unsafeAddr,s.size)
var
city: PasString[30]
city = "New York"!30
echo city