December 30, 2021

On Thursday, 30 December 2021 at 17:43:14 UTC, Tejas wrote:

>

I'm not at my computer anymore, could you please replace the 0x00 with 0x0A and tell me if strip still doesn't work for my solution?

Ok.

>

I think the fromstringz is trimming the null bytes for you, making the \n the last character, allowing strip to work.

Yes, you are right:

import std.stdio;
import std.string;

void main() {
    ubyte[8] b1 = [0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x00, 0x00];
    ubyte[8] b2 = [0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x0A, 0x0A];
    /* "hello\n\0\0" */

    char[] s1 = fromStringz(cast(char*)b1.ptr);
    writefln("'%s, world'", s1.strip);

    char[] s2 = cast(char[])b2[0 .. $];
    writefln("'%s, world'", s2.strip);
}

output:

mono:~/2-coding/d-lang/misc$ ./p
'hello, world'
'hello, world'

everything as needed.
thanks.

December 30, 2021

On Thursday, 30 December 2021 at 17:52:20 UTC, eugene wrote:

>

everything as needed.

Nevertheless, I do have zeroes in the buffer, so:

import std.stdio;
import std.string;

void main() {
    ubyte[8] b = [0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x00, 0x00];
    /* "hello\n\0\0" */

    char[] s = cast(char[])b[0 .. $];
    writefln("'%s, world'", s.strip("\n\x00"));
}

much better than my initial

char[] s = cast(char[])ioCtx.buf[0 .. strlen(cast(char*)ioCtx.buf.ptr) - 1];
December 31, 2021

On Thursday, 30 December 2021 at 09:34:27 UTC, eugene wrote:

>

I suspect the question was asked somewhere before.
If so just give a link.

Anyway:


class IoContext {
    ...
    ubyte[] buf;
    ...
    this(uint bufSize) {
        buf = new ubyte[bufSize];
    }
}

The buffer contains (ascii) string terminated with '\n'.
In order to print it not as an array of numbers (buf is 1024 bytes long),
but as usual string I do

char[] s = cast(char[])ioCtx.buf[0 .. strlen(cast(char*)ioCtx.buf.ptr) - 1];
// -1 is to eliminate terminating '\n'
writefln("got '%s' from '%s:%d'", s, client.addr, client.port);

Is there some more concise/elegant way to do that?

Of course, I could use old good printf() instead:

printf(
    "got '%s' from '%s:%d'\n",
    ioCtx.buf.ptr,            // '\n' still there
    toStringz(client.addr),
    client.port
);

but I want to use D stdlib, not libc.

Unless I'm misunderstanding:

import std.algorithm  : until;
writefln("got '%s' from '%s:%d'", (cast(char[])ioCtx.buf[]).until('\n'), client.addr, client.port);

Note that this does not save the "sliced" version of the buffer, so if you wanted to just search for the \n once, and keep using it, then you may want to use an algorithm that slices off everything until the character.

-Steve

January 01, 2022

On Thursday, 30 December 2021 at 18:07:15 UTC, eugene wrote:

>

On Thursday, 30 December 2021 at 17:52:20 UTC, eugene wrote:
much better than my initial

You can also write

auto s = cast(string)b; // or cast(string)(b)

instead of

char[] s = cast(char[])b[0 .. $];
January 02, 2022

On Friday, 31 December 2021 at 14:45:41 UTC, Steven Schveighoffer wrote:

>

Unless I'm misunderstanding:

import std.algorithm  : until;
writefln("got '%s' from '%s:%d'", (cast(char[])ioCtx.buf[]).until('\n'), client.addr, client.port);
import std.stdio;
import std.string;

void main() {
    ubyte[8] b = [0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x00, 0x00];
    /* "hello\n\0\0" */
    writefln("'%s, world'", cast(char[])b[].until('\n'));
}
@mono:~/2-coding/d-lang/misc$ dmd p1.d
p1.d(8): Error: no property `until` for type `ubyte[]`
@mono:~/2-coding/d-lang/misc$ dmd --version
DMD64 D Compiler v2.098.1
January 02, 2022

On Saturday, 1 January 2022 at 09:34:10 UTC, Jack Applegame wrote:

>

On Thursday, 30 December 2021 at 18:07:15 UTC, eugene wrote:

>

On Thursday, 30 December 2021 at 17:52:20 UTC, eugene wrote:
much better than my initial

You can also write

auto s = cast(string)b; // or cast(string)(b)

instead of

char[] s = cast(char[])b[0 .. $];
import std.stdio;
import std.string;

void main() {
    ubyte[8] b = [0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x00, 0x00];
    /* "hello\n\0\0" */

    auto s = cast(string)b;
    writefln("'%s, world'", s);
    writefln("'%s, world'", s.strip("\n\x00"));
}

@mono:~/2-coding/d-lang/misc$ ./p2
'hello
, world'
'hello, world'

January 02, 2022

On Sunday, 2 January 2022 at 08:39:57 UTC, eugene wrote:

>
import std.stdio;
import std.string;

oops...

import std.stdio;
import std.string;
import std.algorithm : until;

void main() {
    ubyte[8] b = [0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x00, 0x00];
    /* "hello\n\0\0" */
    writefln("'%s, world'", cast(char[])b[].until('\n'));
}

p1.d(9): Error: cannot cast expression `until(b[], '\x0a', Flag.yes)` of type `Until!("a == b", ubyte[], char)` to `char[]`

January 02, 2022

On Sunday, 2 January 2022 at 09:15:32 UTC, eugene wrote:

>
p1.d(9): Error: cannot cast expression `until(b[], '\x0a', Flag.yes)` of type `Until!("a == b", ubyte[], char)` to `char[]`

Here's a working version:

import std.stdio;
import std.string;
import std.algorithm : until, map;
import std.conv : to;

void main() {
    ubyte[8] b = [0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x00, 0x00];
    /* "hello\n\0\0" */
    writefln("'%-(%s%), world'", b[].until('\n').map!(to!char));
}

This code uses map!(to!char) to convert the elements of the range from ubyte to char, then uses a %-(...%) format specifier to print out each element of the range using the format string inside the parentheses (in this case, %s).

January 02, 2022

On 1/2/22 4:15 AM, eugene wrote:

>

On Sunday, 2 January 2022 at 08:39:57 UTC, eugene wrote:

>
import std.stdio;
import std.string;

oops...

import std.stdio;
import std.string;
import std.algorithm : until;

void main() {
     ubyte[8] b = [0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x00, 0x00];
     /* "hello\n\0\0" */
     writefln("'%s, world'", cast(char[])b[].until('\n'));
}

p1.d(9): Error: cannot cast expression `until(b[], '\x0a', Flag.yes)` of type `Until!("a == b", ubyte[], char)` to `char[]`

Thanks for posting the entire example, that always helps to diagnose unexpected errors.

You missed a set of parentheses. cast is quite low for operator precedence.

What is happening in your code is:

b[].until('\n') is being evaluated first, which returns an Until!... struct, which then cannot be cast into char[].

But if you run my code, I do (cast(char[])b[]).until('\n'), which first casts the ubyte array into a char array, and then runs until on it.

-Steve

January 07, 2022

On Monday, 3 January 2022 at 02:50:46 UTC, Steven Schveighoffer wrote:

>

On 1/2/22 4:15 AM, eugene wrote:

>

On Sunday, 2 January 2022 at 08:39:57 UTC, eugene wrote:

     writefln("'%s, world'", cast(char[])b[].until('\n'));
}
>

You missed a set of parentheses.

That was lack of attention from my side, sorry :)

A couple of impressions...

  • Does .until() make a copy of original string? And GC then will take care of it?
  • So many ways to do simple C printf("%s", (char*)buf)... I am feeling like Buridan's ass