how would I go about creating a Socket receiveAll method?
Unazed Spectaculum
unazed at spec.org
Tue Dec 12 21:03:54 UTC 2017
On Tuesday, 12 December 2017 at 20:27:04 UTC, Ali Çehreli wrote:
> On 12/12/2017 12:10 PM, Unazed Spectaculum wrote:
> > string receiveAll(T)(T socket, int segment_size = 1024)
> > {
> > char[segment_size][] data;
>
> Unrelated, you most likely want to use ubyte. (char is for
> UTF-8.)
>
> The problem is, char[segment_size] is a static array, where the
> length must be known at compile time because length is a part
> of its type.
>
> So, depending on what you need you have two options:
>
> a) Use dynamic array if the length is known at run time
>
> b) Although (a) will work just fine, use template parameter for
> length if the length is known at compile time and you want to
> avoid dynamic allocation.
>
> However, too large arrays won't fit on the stack. (Further
> however, your 'data' is a slice anyway, just the elements are
> static.)
>
> The following program shows the two options with
> one-dimensional arrays:
>
> // Size is known at run time
> void foo(T)(T t, size_t size = 1024) {
> auto data = new ubyte[](size);
> }
>
> // Size is known at compile time
> void bar(size_t size = 1024, T)(T t) {
> ubyte[size] data;
> }
>
> void main() {
> int i;
> foo(i, 10);
> bar!20(i);
> }
>
> Here is one with two-dimensional arrays:
>
> import std.stdio;
>
> size_t counter = 0;
> bool done() {
> return (++counter % 4) == 0;
> }
>
> // Size is known at run time
> void foo(T)(T t, size_t size = 1024) {
> ubyte[][] data;
>
> while (!done) {
> data ~= new ubyte[size];
> // Use data[$-1]
> writeln("a) Will read here: ", data[$-1]);
> }
> }
>
> // Size is known at compile time
> void bar(size_t size = 1024, T)(T t) {
> ubyte[size][] data;
>
> while (!done) {
> ++data.length;
> writeln("b) Will read here: ", data[$-1]);
> }
> }
>
> void main() {
> int i;
> foo(i, 10);
> bar!20(i);
> }
>
> Ali
string receiveAll(T)(T socket, size_t segment_size = 1024)
{
ubyte[][] data;
size_t count = 0;
while (true)
{
data ~= new ubyte[segment_size];
auto received = socket.receive(data[count]);
data[count] = data[count][0 .. received];
if (!received)
break;
else if (received < segment_size)
break; /* early exit */
++count;
}
char[] stringData;
foreach (elem; data)
stringData ~= elem;
return to!string(stringData);
}
I've decided to go for the run-time approach to this, it works
fine with all of my tests so you have my greatest gratitude.
I might have created some weird inefficiencies but don't worry
take time telling me about them unless they're going to blow up
my program since I think you've explained enough already :D.
Since I'm only a few days into D I wouldn't expect much of my
code, I'm moreover from the generic Python and thereabouts C-ish
background.
again, thanks.
More information about the Digitalmars-d-learn
mailing list