assemblying a packet of data

assemblying a packet of data

Postby rogerdv » 06 Feb 2014, 15:00

Im doing some tests and found that Im not very clear about the optimal way to put several data in a "packet". What I want is to put different values of different data types in a void*, like: int/float/float/float or int/int/chars and dissasemble it back to its components. Any suggestions about this?
User avatar
rogerdv
 
Posts: 289
Joined: 10 Dec 2009, 18:26

Re: assemblying a packet of data

Postby Buch » 06 Feb 2014, 16:29

I don't really understand what you are asking here: do you mean you want to take a known group of variables (where known means: you always know in advance that they will be in a given number and that their types are always the same, so you always get the same pattern int/float/float/float) and turn it into a void pointer? (If not, just skip to the next paragraph.) The best way to go would likely be to create a structure containing those variables, create a pointer to the struct and convert it to a void pointer. When you need to disassemble, you just have to reconvert the void pointer to a struct pointer and then access the members.

If you mean you want to take an arbitrary group of variables (where arbitrary means all the opposite of the known group above), your question turns into something like "how to create an array of multiple types", and things are a bit more complicated.
Ideally, you could point to (almost) any position in memory using a void pointer. Thus, you could store the variables you need to "pack" inside an array of raw bytes (a char array should do the trick). However, this prevents you from unpacking them if you don't know what the variables and their types were before packing. So you should prefix the array with a variable containing the sequence of the types of the variables contained in the array. The easiest way to do this would probably be to add a char* at the beginning of the array containing a string sequence of the types. Your array would be something like:

{l Code}: {l Select All Code}
0          4     8       12      16
[ "ifff" ],[int],[float],[float],[float]


where I described the sequence int,float,float,float with the string "ifff" (i obviously means int and f stands for float).

Now I won't go into the detail of how to practically pack and unpack data, but this should have given you a basic idea of how to do it. There are obviously other ways to go, maybe also something easier than this.

Hope this helps
User avatar
Buch
 
Posts: 51
Joined: 15 Jan 2013, 14:30
Location: Castel del Piano, Grosseto, Italy

Re: assemblying a packet of data

Postby rogerdv » 06 Feb 2014, 18:01

The second variant is the one Im implementing, there are too many variations to use structs. What I need is the best way to do it: memcpy, strcpy? I think I once did it incrementing the pointer topoint to the needed offset, but lost that code and Im looking for the best solution for this.
User avatar
rogerdv
 
Posts: 289
Joined: 10 Dec 2009, 18:26

Re: assemblying a packet of data

Postby Buch » 07 Feb 2014, 16:48

A little gift for you: https://gist.github.com/buch415/8865157
This could be what you're looking for... And even if it is not, it was fun to make.
User avatar
Buch
 
Posts: 51
Joined: 15 Jan 2013, 14:30
Location: Castel del Piano, Grosseto, Italy

Re: assemblying a packet of data

Postby dusted » 10 Feb 2014, 17:56

What you search is the good old struct.

Such as this rough example:

{l Code}: {l Select All Code}
typedef struct
{
  float x,y;
  float velx,vely;
  float rot;
  uint8_t isShooting;
} playerUpdatePacket_t


playerUpdatePacket_t player;

player.x = 1;
player.y = 2;
player.velx = 0;
player.vely = 0;
player.rot = 90;
player.isShooting = 1;

sendMyPacket( &thatScoket,  (void*)(&player), sizeof( playerUpdatePacket_t ) );
User avatar
dusted
 
Posts: 83
Joined: 27 Feb 2010, 04:35

Re: assemblying a packet of data

Postby Lyberta » 13 Feb 2014, 18:03

Sending structs is bad because on different platforms there can be different padding and endianness. I've solved the problem using my very own BinaryStream classes. Can be found here.

Usage would be roughly as follows:
{l Code}: {l Select All Code}
#include <ftz/General/MemoryStream.h>


//Send code.
{
    ftz::General::MemoryStream stream;
    stream << x << y << z << rot << vel;
    auto size = stream.GetWritePosition();
    auto rawdata = std::vector<char>(size);
    stream.Read(rawdata.data(), size);
   //rawdata now contains all variables packed together in big endian format. You can send it.
}

//Receive code.
{
    char* data; // our data
    std::size_t size; // size of our data;
    ftz::General::MemoryOutputStream stream(data, size);
    stream >> x >> y >> z >> rot >> vel;
}


Then you just overload operator<< and operator>> for your own classes and you now have a fully serilazable set of classes.
Lyberta
 
Posts: 765
Joined: 19 Jun 2013, 10:45

Who is online

Users browsing this forum: No registered users and 1 guest