digitalmars.D.learn - How to place char* of stringZ to ubyte[]?
- denizzzka (4/4) Oct 29 2012 immutable ubyte[] valueBin = cast(immutable(ubyte[]))
- bearophile (11/15) Oct 29 2012 One way to do it:
- denizzzka (4/18) Oct 29 2012 I am trying to send to remote host utf8 text with zero byte at
- bearophile (38/40) Oct 29 2012 What if your UTF8 string coming from D already contains several
- denizzzka (9/48) Oct 29 2012 I am concerned about the extra allocations of temp arrays. here
- bearophile (17/25) Oct 30 2012 There is one allocation, and usually the D compilers can't
- Nick Sabalausky (7/15) Oct 30 2012 If you need to send a string with an embedded null through a
immutable ubyte[] valueBin = cast(immutable(ubyte[])) toStringz(s); // s is string type Error: e2ir: cannot cast toStringz(s) of type immutable(char)* to type immutable(ubyte[])
Oct 29 2012
denizzzka:immutable ubyte[] valueBin = cast(immutable(ubyte[])) toStringz(s); // s is string type Error: e2ir: cannot cast toStringz(s) of type immutable(char)* to type immutable(ubyte[])One way to do it: import std.stdio; void main() { string s = "hello"; auto valueBin = cast(immutable ubyte[])s.dup; writeln(valueBin); } But what are you trying to do? Bye, bearophile
Oct 29 2012
On Monday, 29 October 2012 at 17:51:56 UTC, bearophile wrote:denizzzka:I am trying to send to remote host utf8 text with zero byte at end (required by protocol) But sending function accepts only ubyte[]immutable ubyte[] valueBin = cast(immutable(ubyte[])) toStringz(s); // s is string type Error: e2ir: cannot cast toStringz(s) of type immutable(char)* to type immutable(ubyte[])One way to do it: import std.stdio; void main() { string s = "hello"; auto valueBin = cast(immutable ubyte[])s.dup; writeln(valueBin); } But what are you trying to do?
Oct 29 2012
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
Oct 29 2012
On Monday, 29 October 2012 at 18:50:58 UTC, bearophile wrote:denizzzka:Incredible situation because it is text-based protocolI 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); }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 syntaxWhat difference between this syntax and "alias Something this"?} void main() { import std.stdio; string s = "hello"; auto valueBin3 = BytesBuf(s); writeln(valueBin3); }
Oct 29 2012
denizzzka:I am concerned about the extra allocations of temp arrays. here is it, or not? compiler optimizes it?There is one allocation, and usually the D compilers can't optimize it away.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 don't want overhead you need some static buffer, bigger than any possible string, and to copy data on it and slice it as needed. Otherwise appending one null char risks allocating. If you append it in-place in the original string the risk of allocations is lower, but not zero.I was thinking about keeping the protocol invariant, but you are right, it's probably useless. A null is enough to denote an empty string.byte[] data = [0];Why not "byte[] data;" ?There's no difference. Instead of focusing on other syntaxes that actually do something useful (like [$] to define fixed-size arrays automatically, or somehting else), Walter has accepted to add one more way to do the same thing. I don't like this change. Bye, bearophilealias this = data; // new syntaxWhat difference between this syntax and "alias Something this"?
Oct 30 2012
On Mon, 29 Oct 2012 19:50:57 +0100 "bearophile" <bearophileHUGS lycos.com> wrote:denizzzka:If you need to send a string with an embedded null through a null-terminated-string protocol, then you're pretty much screwed anyway. FWIW ;) ('Course, the embedded nulls could be stripped if they're not actually important.)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?
Oct 30 2012