denizzzka:

I am trying to send to remote host utf8 text with zero byte at end (required by protocol)

What if your UTF8 string coming from D already contains several zeros?

toStringz(s) returns a pointer, so you can't cast a pointer (that doesn't know the length the buffer it points to) to an array. You have to tell it the length in some way. One way is to slice the pointer, another solution is to append a '\0' and then cast it to an immutable array. Two solutions:


import std.stdio, std.string;
void main() {
   string s = "hello";
   auto valueBin1 = cast(immutable ubyte[])(s ~ '\0');
   writeln(valueBin1);
auto valueBin2 = cast(immutable ubyte[])(s.toStringz()[0 .. s.length + 1]);
   writeln(valueBin2);
}

If you have to do this more than two or three times it's better to write a little function to do it, to avoid bugs.

Even better is to define with strong typing the type of such nil-terminated array of bytes, to avoid other mistakes. This used to be possible in D with typedef. Now one a little clumsy way to do it is to use a struct with "alias this". This is just a sketch:


struct BytesBuf {
    this(string s) {
        this.data = cast(typeof(data))(s ~ '\0');
    }
    byte[] data = [0];
    alias this = data; // new syntax
}
void main() {
   import std.stdio;
   string s = "hello";
   auto valueBin3 = BytesBuf(s);
   writeln(valueBin3);
}


Bye,
bearophile

Reply via email to