digitalmars.D.learn - print ubyte[] as (ascii) string
- eugene (34/34) Dec 30 2021 I suspect the question was asked somewhere before.
- Era Scarecrow (10/13) Dec 30 2021 Few years ago i asked a similar question, not to do UTF-8 but to
- eugene (11/13) Dec 30 2021 For a moment I only have symbols from the lower half of ASCII
- Tejas (19/42) Dec 30 2021 ```d
- eugene (14/21) Dec 30 2021 There is one pecularity:
- Tejas (14/36) Dec 30 2021 I'll need to know the error message, because the following works:
- eugene (3/17) Dec 30 2021 There is nothing to strip here (spaces, new lines...).
- eugene (21/22) Dec 30 2021 Self-contained example:
- Tejas (6/29) Dec 30 2021 I'm not at my computer anymore, could you please replace the
- eugene (26/31) Dec 30 2021 Yes, you are right:
- eugene (17/18) Dec 30 2021 Nevertheless, I do have zeroes in the buffer, so:
- Jack Applegame (9/11) Jan 01 2022 You can also write
- eugene (18/29) Jan 02 2022 ```d
- eugene (6/13) Dec 30 2021 ```d
- Steven Schveighoffer (12/46) Dec 31 2021 Unless I'm misunderstanding:
- eugene (19/26) Jan 02 2022 ```d
- eugene (16/20) Jan 02 2022 oops...
- Paul Backus (17/21) Jan 02 2022 Here's a working version:
- eugene (4/29) Jan 07 2022 Well, just a Gross!
- Steven Schveighoffer (12/39) Jan 02 2022 Thanks for posting the entire example, that always helps to diagnose
- eugene (8/15) Jan 07 2022 That was lack of attention from my side, sorry :)
- H. S. Teoh (17/21) Jan 07 2022 No, it's one of the lazy range functions that lazily evaluates the
- eugene (2/4) Jan 07 2022 yes, this approach was used in some my previous traival
- eugene (9/10) Jan 07 2022 Nice term - "GC-phobic" :)
- Adam D Ruppe (12/14) Jan 07 2022 GC isn't actually there to prevent memory leaks. Its main job is
- eugene (18/28) Jan 07 2022 ```c
- Steven Schveighoffer (18/24) Jan 07 2022 No, `until` will iterate the string one character at a time until it
- eugene (8/10) Jan 07 2022 There are 2 buffers (RX one and TX one, both of 'reasonable' size)
- frame (13/20) Jan 07 2022 However, you should not rely on a terminating '\n' even you are
- Steven Schveighoffer (8/18) Jan 07 2022 Since the data is unmodified, then you can do this too after logging it
- Dukc (2/9) Jan 07 2022 Try `auto s = fromStringz(cast(char*)ioCtx.buf.ptr)`.
I suspect the question was asked somewhere before. If so just give a link. Anyway: ```d 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 ```d 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: ```d 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.
Dec 30 2021
On Thursday, 30 December 2021 at 09:34:27 UTC, eugene wrote: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 doFew years ago i asked a similar question, not to do UTF-8 but to do Ascii. I was working on a tool for Morrowind after determining the strings were not variable in length and instead much like ascii fixed at 256 combinations. The answer i ended up with was a quick conversion to a UTF in order to print it. Seems you might have to convert to Latin-1. Here's the old thread. https://forum.dlang.org/thread/lehgyzmwewgvkdgraizv forum.dlang.org
Dec 30 2021
On Thursday, 30 December 2021 at 16:00:59 UTC, Era Scarecrow wrote:The answer i ended up with was a quick conversion to a UTF in order to print it. Seems you might have to convert to Latin-1.For a moment I only have symbols from the lower half of ASCII table. I meant - can that be done as simple as in C, i.e: ```c u8 *buf; ... printf("%s", (char*)buf); ``` without any twists and turns.
Dec 30 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: ```d class IoContext { ... ubyte[] buf; ... this(uint bufSize) { buf = new ubyte[bufSize]; } } ``````d class IoContext { ... ubyte[] buf; ... this(uint bufSize) { buf.length = bufSize; //this should do the same thing, I believe } } ```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 ```d 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); ``````d char[] s = cast(char[])ioCtx.buf[0 .. $];// please remember that in `[0 .. $]` last index is automatically `length - 1` but just buf[$] will be an error since there the actual `length` will be used ``` I _think_ the above code is correct, please verify
Dec 30 2021
On Thursday, 30 December 2021 at 16:49:17 UTC, Tejas wrote:```d char[] s = cast(char[])ioCtx.buf[0 .. $];// please remember that in `[0 .. $]` last index is automatically `length - 1` but just buf[$] will be an error since there the actual `length` will be used ``` I _think_ the above code is correct, please verifyThere is one pecularity: ```d char[] s = fromStringz(cast(char*)ioCtx.buf.ptr); writefln("got '%s' from '%s:%d'", s.strip, client.addr, client.port); // strip works :) ``` ```d char[] s = cast(char[])ioCtx.buf[0 .. $]; writefln("got '%s' from '%s:%d'", s.strip, client.addr, client.port); // strip does not work :( ```
Dec 30 2021
On Thursday, 30 December 2021 at 17:07:20 UTC, eugene wrote:On Thursday, 30 December 2021 at 16:49:17 UTC, Tejas wrote:I'll need to know the error message, because the following works: ```d import std; void main() { ubyte[] c ; c.length = 100; char[] arr = cast(char[])c[0 .. $]; foreach(ref elem; arr) elem = 'a'; writeln(arr.strip); } ``````d char[] s = cast(char[])ioCtx.buf[0 .. $];// please remember that in `[0 .. $]` last index is automatically `length - 1` but just buf[$] will be an error since there the actual `length` will be used ``` I _think_ the above code is correct, please verifyThere is one pecularity: ```d char[] s = fromStringz(cast(char*)ioCtx.buf.ptr); writefln("got '%s' from '%s:%d'", s.strip, client.addr, client.port); // strip works :) ``` ```d char[] s = cast(char[])ioCtx.buf[0 .. $]; writefln("got '%s' from '%s:%d'", s.strip, client.addr, client.port); // strip does not work :( ```
Dec 30 2021
On Thursday, 30 December 2021 at 17:16:10 UTC, Tejas wrote:I'll need to know the error messageThere is none, see example in my prev messagebecause the following works: ```d import std; void main() { ubyte[] c ; c.length = 100; char[] arr = cast(char[])c[0 .. $]; foreach(ref elem; arr) elem = 'a'; writeln(arr.strip); } ```There is nothing to strip here (spaces, new lines...).
Dec 30 2021
On Thursday, 30 December 2021 at 16:49:17 UTC, Tejas wrote:I _think_ the above code is correct, please verifySelf-contained example: ```d 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 = fromStringz(cast(char*)b.ptr); writefln("'%s, world'", s.strip); s = cast(char[])b[0 .. $]; writefln("'%s, world'", s.strip); } ``` Output: ``` mono:~/2-coding/d-lang/misc$ ./p 'hello, world' 'hello , world' ```
Dec 30 2021
On Thursday, 30 December 2021 at 17:31:27 UTC, eugene wrote:On Thursday, 30 December 2021 at 16:49:17 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? I think the `fromstringz` is trimming the null bytes for you, making the `\n` the last character, allowing `strip` to work.I _think_ the above code is correct, please verifySelf-contained example: ```d 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 = fromStringz(cast(char*)b.ptr); writefln("'%s, world'", s.strip); s = cast(char[])b[0 .. $]; writefln("'%s, world'", s.strip); } ``` Output: ``` mono:~/2-coding/d-lang/misc$ ./p 'hello, world' 'hello , world' ```
Dec 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: ```d 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.
Dec 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: ```d 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 ```d char[] s = cast(char[])ioCtx.buf[0 .. strlen(cast(char*)ioCtx.buf.ptr) - 1]; ```
Dec 30 2021
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 initialYou can also write ```d auto s = cast(string)b; // or cast(string)(b) ``` instead of ```d char[] s = cast(char[])b[0 .. $]; ```
Jan 01 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:```d 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' ```On Thursday, 30 December 2021 at 17:52:20 UTC, eugene wrote: much better than my initialYou can also write ```d auto s = cast(string)b; // or cast(string)(b) ``` instead of ```d char[] s = cast(char[])b[0 .. $]; ```
Jan 02 2022
On Thursday, 30 December 2021 at 09:34:27 UTC, eugene wrote:```d 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?```d char[] s = fromStringz(cast(char*)ioCtx.buf.ptr).strip; writefln("got '%s' from '%s:%d'", s, client.addr, client.port); ``` Well, this will do:)
Dec 30 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: ```d 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 ```d 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: ```d 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: ```d 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
Dec 31 2021
On Friday, 31 December 2021 at 14:45:41 UTC, Steven Schveighoffer wrote:Unless I'm misunderstanding: ```d import std.algorithm : until; writefln("got '%s' from '%s:%d'", (cast(char[])ioCtx.buf[]).until('\n'), client.addr, client.port); ``````d 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 ```
Jan 02 2022
On Sunday, 2 January 2022 at 08:39:57 UTC, eugene wrote:```d import std.stdio; import std.string; ```oops... ```d 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[]` ```
Jan 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: ```d 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`).
Jan 02 2022
On Sunday, 2 January 2022 at 15:13:06 UTC, Paul Backus wrote:On Sunday, 2 January 2022 at 09:15:32 UTC, eugene wrote:Well, just a Gross! But I am not a fun of functional programming style :) (sorry for replying late)``` 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: ```d 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`).
Jan 07 2022
On 1/2/22 4:15 AM, eugene wrote:On Sunday, 2 January 2022 at 08:39:57 UTC, eugene wrote: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```d import std.stdio; import std.string; ```oops... ```d 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[]` ```
Jan 02 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: ```d 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
Jan 07 2022
On Fri, Jan 07, 2022 at 07:54:28PM +0000, eugene via Digitalmars-d-learn wrote: [...]* Does .until() make a copy of original string? And GC then will take care of it?No, it's one of the lazy range functions that lazily evaluates the string and does not allocate.* So many ways to do simple C printf("%s", (char*)buf)... I am feeling like Buridan's assD strings are different from C strings. Although D *can* handle C strings, it should not be surprising there's a bit of friction. The simplest way to handle a C string from D is just to use .fromStringz: import std.string : fromStringz; char *buf = some_c_function(); writeln(buf.fromStringz); Note that fromStringz is nogc, since it only takes a slice of the C string and does not copy anything. So it should be good even for GC-phobic code. T -- What do you get if you drop a piano down a mineshaft? A flat minor.
Jan 07 2022
On Friday, 7 January 2022 at 20:08:00 UTC, H. S. Teoh wrote:The simplest way to handle a C string from D is just to use .fromStringz:yes, this approach was used in some my previous traival
Jan 07 2022
On Friday, 7 January 2022 at 20:08:00 UTC, H. S. Teoh wrote:So it should be good even for GC-phobic code.Nice term - "GC-phobic" :) But looking from my cave - it's not a phobia, it's an observation. We've got a huge and complex project at my job, and... * python guys have memory leaks * js guys have memory leaks Both "systems" (I mean python and javascript) are GC-systems. And? Should I trust D with GC or accurate C-programmers? :)
Jan 07 2022
On Friday, 7 January 2022 at 20:33:05 UTC, eugene wrote:* python guys have memory leaks * js guys have memory leaksGC isn't actually there to prevent memory leaks. Its main job is to guard against use-after-free memory corruption bugs. Actually, technically, the paradigm is "infinite lifetime" and the garbage collection is just there as a practical matter because computers don't have infinite memory. They do a reasonably good job on memory leaks too, but that's not the main goal so they'd rather let memory leak than risk a use after free. That's why D lets you do a hybrid approach easily: where the lifetime is trivial, you can easily do it yourself to optimize memory use. But when it isn't so obvious, you can use the GC to play it safe at the cost of a lil more memory use.
Jan 07 2022
On Friday, 7 January 2022 at 20:40:02 UTC, Adam D Ruppe wrote:On Friday, 7 January 2022 at 20:33:05 UTC, eugene wrote:Aha, unless you'll build GC into OS core :)* python guys have memory leaks * js guys have memory leaksGC isn't actually there to prevent memory leaks.Its main job is to guard against use-after-free memory corruption bugs```c if (ptr) { free(ptr); ptr = NULL; } ... if (NULL == someptr) BUG()/PANIC()/WHATEVER() ```because computers don't have infinite memoryfirst time I've heard this ))) tell that to py/js super-coders :)where the lifetime is trivial, you can easily do it yourself to optimize memory use. But when it isn't so obvious, you can use the GC to play it safe at the cost of a lil more memory use.other way around * when the lifetime is trivial (whithin a function, including thread function) - trust GC * when the lifetime is not trivial (ptr goes through or a self-pipe or similar) - GC has no info about that
Jan 07 2022
On 1/7/22 2:54 PM, eugene wrote:A couple of impressions... * Does .until() make a copy of original string? And GC then will take care of it?No, `until` will iterate the string one character at a time until it sees that character (excluding it). It doesn't make a copy of the data. In effect, it's doing the "trim" and the iteration to print in one step. In your chosen solution earlier, you were doing it 3 times -- once to find the end of the null-terminated string (via `fromStringz`), once to strip the newline (well, this isn't too bad, since it goes from both ends), and once to actually print it.* So many ways to do simple C printf("%s", (char*)buf)... I am feeling like Buridan's assThere are a million ways to get what you want. I like to go for ones that: 1. don't allocate needlessly (I hate allocating a string just to print it, and then throw it away, regardless of whether it's GC or not) 2. read concisely and clearly. 3. Are as efficient as possible. The one wart here is the cast, but that's impossible to avoid unless you want to allocate. Adhering to 2 and 3 above sometimes are in conflict. But rule 1 is essential for performance. In C you have one choice (printf), but that choice may not fit your needs. -Steve
Jan 07 2022
On Friday, 7 January 2022 at 21:17:33 UTC, Steven Schveighoffer wrote:In C you have one choice (printf), but that choice may not fit your needs.There are 2 buffers (RX one and TX one, both of 'reasonable' size) (it's the effing echo-server, nothing more) * print content of RX-buffer, ommiting terminating '\n' ('\n' is the 'end of request') to (log/journal file)/stdout/ * ouptut received 'message' back to client, _with_ terminating '\n'
Jan 07 2022
On Friday, 7 January 2022 at 22:04:28 UTC, eugene wrote:There are 2 buffers (RX one and TX one, both of 'reasonable' size) (it's the effing echo-server, nothing more) * print content of RX-buffer, ommiting terminating '\n' ('\n' is the 'end of request') to (log/journal file)/stdout/ * ouptut received 'message' back to client, _with_ terminating '\n'However, you should not rely on a terminating '\n' even you are the source. You determine the length of string trough '\n' but maybe your buffer doesn't contain it (yet) if the connection wasn't blocking or the message is longer as the buffer size or you received just error data. Then, accessing the ubyte[] data directly via `.ptr`/ casting it to char* without knowing the possible content seems not a good idea - if you are using any function that returns bytes till it finds a needle or terminating '\0'. I know it's a little bit off topic but if the question is about the best concise way, the solution you choose should respect that too.
Jan 07 2022
On 1/7/22 5:04 PM, eugene wrote:On Friday, 7 January 2022 at 21:17:33 UTC, Steven Schveighoffer wrote:Irrelevant to how you log the data.In C you have one choice (printf), but that choice may not fit your needs.There are 2 buffers (RX one and TX one, both of 'reasonable' size) (it's the effing echo-server, nothing more)* print content of RX-buffer, ommiting terminating '\n' ('\n' is the 'end of request') to (log/journal file)/stdout/ * ouptut received 'message' back to client, _with_ terminating '\n'Since the data is unmodified, then you can do this too after logging it without the `\n`. Two separate needs, both well handled by using ranges and algorithms. Or if they don't suit you well enough, just write your own. Writing a wrapping range isn't hard. -Steve
Jan 07 2022
On Thursday, 30 December 2021 at 09:34:27 UTC, eugene wrote:```d 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?Try `auto s = fromStringz(cast(char*)ioCtx.buf.ptr)`.
Jan 07 2022