On Monday, 29 October 2012 at 18:50:58 UTC, bearophile wrote:
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?

Incredible situation because it is text-based protocol


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);
}


I am concerned about the extra allocations of temp arrays. here is it, or not? compiler optimizes it?

In my case it does not matter but for the future I would like to know how it can be implemented without overhead.

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:


Yes, already implemented similar.


struct BytesBuf {
    this(string s) {
        this.data = cast(typeof(data))(s ~ '\0');
    }
    byte[] data = [0];

Why not "byte[] data;" ?

    alias this = data; // new syntax

What difference between this syntax and "alias Something this"?

}
void main() {
   import std.stdio;
   string s = "hello";
   auto valueBin3 = BytesBuf(s);
   writeln(valueBin3);
}

Reply via email to