Thread overview
std.socket + sending of structs
Jun 14, 2005
Alexander Panek
Jun 14, 2005
Regan Heath
Jun 14, 2005
Regan Heath
Jun 15, 2005
Derek Parnell
Jun 15, 2005
Regan Heath
Jun 15, 2005
Chris Sauls
Jun 15, 2005
Regan Heath
Jun 15, 2005
Derek Parnell
June 14, 2005
Hello,

I`m coding a little library for InSim (programmable interface for Live for Speed - an online racing simulator) and I`d have to send data in form of structs to the server, but socket.send() does only permit void[]`s as data.

So how do I send structs? Or how can i convert them?

Regards,
Alex

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
June 14, 2005
On Wed, 15 Jun 2005 01:41:57 +0200, Alexander Panek <alexander.panek@brainsware.org> wrote:
> Hello,
>
> I`m coding a little library for InSim (programmable interface for Live for Speed - an online racing simulator) and I`d have to send data in form of structs to the server, but socket.send() does only permit void[]`s as data.
>
> So how do I send structs? Or how can i convert them?

Convert them:

struct oof {}

void main() {
  TcpSocket s;
  oof foo;
  s.send((cast(void*)&foo)[0..oof.sizeof]);
}

Regan
June 14, 2005
Of course, you have to consider Endian issues i.e. sending from a Big Endian to a Little Endian machine will result in garbage, unless you convert the endian-ness of the data.

The other option is to convert the struct into some textual representation and transfer it that way, this uses more bandwidth, but is less complicated.

Regan

On Wed, 15 Jun 2005 11:54:10 +1200, Regan Heath <regan@netwin.co.nz> wrote:
> On Wed, 15 Jun 2005 01:41:57 +0200, Alexander Panek <alexander.panek@brainsware.org> wrote:
>> Hello,
>>
>> I`m coding a little library for InSim (programmable interface for Live for Speed - an online racing simulator) and I`d have to send data in form of structs to the server, but socket.send() does only permit void[]`s as data.
>>
>> So how do I send structs? Or how can i convert them?
>
> Convert them:
>
> struct oof {}
>
> void main() {
>    TcpSocket s;
>    oof foo;
>    s.send((cast(void*)&foo)[0..oof.sizeof]);
> }
>
> Regan

June 15, 2005
On Wed, 15 Jun 2005 01:41:57 +0200, Alexander Panek wrote:

> Hello,
> 
> I`m coding a little library for InSim (programmable interface for Live for Speed - an online racing simulator) and I`d have to send data in form of structs to the server, but socket.send() does only permit void[]`s as data.
> 
> So how do I send structs? Or how can i convert them?

This example code might be a starting point ...
<code>
import std.stdio;

struct data
{
  char[4] fldA;
  int     fldB;
  long    fldC;
}

void func(void[] a)
{
    writefln("Size %d", a.length);
    foreach(ubyte b; cast(ubyte[])a)
        writef("%2x", b);
}

void main()
{
   union db
   {
    // Here is where we update flds.
    data d;
    // Overlay the struct with a byte array.
    ubyte[data.sizeof] z;
   }
   db y;

   y.d.fldA[] = "abcd";
   y.d.fldB = 7281242;
   y.d.fldC = 987656676274;
   func( y.z );
}

</code>


-- 
Derek
Melbourne, Australia
15/06/2005 9:48:42 AM
June 15, 2005
On Wed, 15 Jun 2005 11:54:10 +1200, Regan Heath wrote:

> On Wed, 15 Jun 2005 01:41:57 +0200, Alexander Panek <alexander.panek@brainsware.org> wrote:
>> Hello,
>>
>> I`m coding a little library for InSim (programmable interface for Live for Speed - an online racing simulator) and I`d have to send data in form of structs to the server, but socket.send() does only permit void[]`s as data.
>>
>> So how do I send structs? Or how can i convert them?
> 
> Convert them:
> 
> struct oof {}
> 
> void main() {
>    TcpSocket s;
>    oof foo;
>    s.send((cast(void*)&foo)[0..oof.sizeof]);
> }
> 

Ok, that's neat.

So in the general case, can one 'cast' anything to a dynamic array of 'x' using the format ...

   (cast(x*)&q)[0..q.sizeof/x.sizeof]

so long as the q.sizeof was an integral multiple of x.sizeof

-- 
Derek
Melbourne, Australia
15/06/2005 10:13:29 AM
June 15, 2005
On Wed, 15 Jun 2005 10:24:45 +1000, Derek Parnell <derek@psych.ward> wrote:
> On Wed, 15 Jun 2005 11:54:10 +1200, Regan Heath wrote:
>
>> On Wed, 15 Jun 2005 01:41:57 +0200, Alexander Panek
>> <alexander.panek@brainsware.org> wrote:
>>> Hello,
>>>
>>> I`m coding a little library for InSim (programmable interface for Live
>>> for Speed - an online racing simulator) and I`d have to send data in
>>> form of structs to the server, but socket.send() does only permit
>>> void[]`s as data.
>>>
>>> So how do I send structs? Or how can i convert them?
>>
>> Convert them:
>>
>> struct oof {}
>>
>> void main() {
>>    TcpSocket s;
>>    oof foo;
>>    s.send((cast(void*)&foo)[0..oof.sizeof]);
>> }
>>
>
> Ok, that's neat.
>
> So in the general case, can one 'cast' anything to a dynamic array of 'x'
> using the format ...
>
>    (cast(x*)&q)[0..q.sizeof/x.sizeof]
>
> so long as the q.sizeof was an integral multiple of x.sizeof

Yeah, I believe so. Though consider/remember:

char[] a = "regan";
(cast(byte*)&a)[0..a.sizeof/byte.sizeof];

That would be incorrect. You'd need:

(cast(byte*)&a.ptr)[0..a.length];

Regan
June 15, 2005
Regan Heath wrote:
> struct oof {}
> 
> void main() {
>   TcpSocket s;
>   oof foo;
>   s.send((cast(void*)&foo)[0..oof.sizeof]);
> }

Maybe I'm forgetting something -- it's likely -- but couldn't one just cast directly to a void[]?  Aka:

# struct oof {}
#
# void main() {
#   TcpSocket s;
#   oof foo;
#   s.send(cast(void[])oof);
# }

I'm under the impression that type void[] is meant to be D's "I might be anything" type, rather than void*.  Could be wrong.  Haven't tested this.

-- Chris Sauls
June 15, 2005
On Wed, 15 Jun 2005 00:46:05 -0500, Chris Sauls <ibisbasenji@gmail.com> wrote:
> Regan Heath wrote:
>> struct oof {}
>>  void main() {
>>   TcpSocket s;
>>   oof foo;
>>   s.send((cast(void*)&foo)[0..oof.sizeof]);
>> }
>
> Maybe I'm forgetting something -- it's likely -- but couldn't one just cast directly to a void[]?  Aka:
>
> # struct oof {}
> #
> # void main() {
> #   TcpSocket s;
> #   oof foo;
> #   s.send(cast(void[])oof);
> # }
>
> I'm under the impression that type void[] is meant to be D's "I might be anything" type, rather than void*.  Could be wrong.  Haven't tested this.

Sadly, no, these attempts give these errors:

s.send(cast(void[])foo);  //e2ir: cannot cast from oof to void[]
s.send(cast(void[])&foo); //cannot cast oof * to void[]
s.send(cast(void[])&foo[0..foo.sizeof]); //oof cannot be sliced with []

The reason the initial suggestion works is due to the "type X* can be sliced to give X[]" rule. The other rule is "X[] is implicitly castable to void[]"... If we combine these rules we get:

s.send((&foo)[0..foo.sizeof]);

Which works!

NOTE: The () are required around &foo, as the [] 'slice' operator has higher precedence than the & 'address' operator.

Regan