open-dis / open-dis-cpp

C++ implementation of the IEEE-1278.1 Distributed Interactive Simulation (DIS) application protocol v6 and v7
BSD 2-Clause "Simplified" License
91 stars 66 forks source link

example usage of std::vector<OneByteChunk> #47

Closed kurtsansom closed 1 year ago

kurtsansom commented 3 years ago

I have what feels like a dumb question.

I want to populate a variable length PDU SignalPdu with "fake" data and test it out.

e.g. I want to send an array of Ints, or 1 int for now.

I know that 1 int should get packed into a char array of size 4, int32 would be four bytes where each byte is an instance of OneByteChunk in the std::vector which should then be of size 4.

I am confused how to do this, and any help would be appreciated.

rodneyp290 commented 3 years ago

I had a fiddle, an was able to come up with the below example - using the DataStream DIS util:

#include "DataStream.h"
#include "OneByteChunk.h"
using namespace DIS;

#include <iostream>
#include <vector>
using namespace std;

int main () {
  DataStream ds(Endian::BIG);
  vector<OneByteChunk> chunks;

  int int32 = 0x48692100; // 0x48 0x69 0x21 0x00 ("Hi!") 

  ds << int32;
  while (ds.GetReadPos() < ds.size()) {
    OneByteChunk tmp;
    tmp.unmarshal(ds);
    chunks.push_back(tmp);
  } 

  cout << "chunks (4 bytes): ";
  for (OneByteChunk chunk : chunks) {
    // Note '*' to dereference from char*
    cout << *(chunk.getOtherParameters());
  }
  cout << endl;

  return 0;
}
// outputs: "chunks (4 bytes): Hi!"

Does that help with your question?

Basically, push your integer(s) into a data stream. Then unmarshal into single OneByteChunk, and store in your vector. Keep unmarshalling until you've read the whole data stream.

Note: Includes are local folder because I copied to another folder to test.

kurtsansom commented 3 years ago

This is exactly what I was struggling with. Thank you very much.

Every time I was reading about a "stream", it was in the context of sending it over a network. But this example describes what I was looking for. Using a datastream to pack (serialize?) c++ data into another data structure chunks. Where the chunks is the one that gets sent not a raw stream.

I am going to add this example into my branch.

kurtsansom commented 3 years ago

What would be the extension to this for a struct of data? I think it would be to create a new class like OneByteChunk or Vector3Double e.g. somedatatype

and replace this:

int int32 = 0x48692100;
ds << int32;

with:

DIS::somedatatype new_data;
... fill in new_data
new_data.marshal(ds);

Is this the right direction?

kurtsansom commented 3 years ago

are Marshalling/Unmarshalling synonyms with serialization and de-serialization?

rodneyp290 commented 3 years ago

Yeah, you're change for a new data type looks like it should work. Yeah, they seem pretty interchangeable, although skim reading this Wikipedia article here suggests there might be subtle differences.

leif81 commented 3 years ago

In open-dis-java we removed the OneByteChunk class and swapped it for a raw byte array. Probably worth doing same here.

Ref https://github.com/open-dis/open-dis-java/pull/44

leif81 commented 3 years ago

If someone wants to open a PR for replacing OneByteChunk I'll gladly merge!

leif81 commented 1 year ago

Closing. PR #81 replaced OneByteChunk class with uint8_t.