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