how would I go about creating a Socket receiveAll method?

Ali Çehreli acehreli at yahoo.com
Wed Dec 13 06:53:55 UTC 2017


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



More information about the Digitalmars-d-learn mailing list