On 12/12/2017 10:21 PM, bauss wrote:
> On Tuesday, 12 December 2017 at 22:11:37 UTC, Adam D. Ruppe wrote:
>> On Tuesday, 12 December 2017 at 21:52:57 UTC, Ali Çehreli wrote:
>>> The same buffer is used for all segments and socket.receive should be
>>> inside while.
>>
>> The buffer is copied by the ~= operator, but indeed you're right that
>> I forgot to receive again inside the loop! That would just spin until
>> it ran out of memory lol.
>>
>> But I did put receive outside the loop for a reason: it just needs to
>> prime the return value before it gets checked the first time. But
>> then, of course, it should receive again at the end of the loop to
>> advance to the next chunk.
>
> do while would work better.
It's a bummer that the loop variable must be defined outside of do-while:
bool done = false; // Can't be inside
do {
// ...
} while(!done);
That's why I think an unconditional loop with an explicit break is
better in such situations:
while (true) {
// ... everything inside ...
if (!got) {
break;
}
// ...
}
Here is a short program that I played with:
import std.stdio;
import std.range;
import std.algorithm;
int[] makeData(int len) {
return iota(len).array;
}
struct SomeSource {
int[] data;
this(int len) {
this.data = makeData(len);
}
// Alternatively, this can return int[]
size_t read(int[] buffer) {
const len = min(data.length, buffer.length);
buffer[0..len] = data[0..len];
data = data[len..$]; // Alternatively, popFrontN
return len;
}
}
void main() {
enum len = 50;
auto foo = SomeSource(len);
int[] result;
while (true) { // <-- UNCONDITIONAL LOOP
int[17] buffer;
const got = foo.read(buffer[]);
if (!got) {
break;
}
result ~= buffer[0..got];
}
assert(result == makeData(len));
writeln(result);
}
Ali