0

I got some data coming in over an RS485 line. I store that data in a vector<char> and now I need to cast that to several types. Currently that is done by the following function:

template<typename To>
static std::size_t parseBinaryToType(const char* input, To& destination) {
    destination = *(reinterpret_cast<const To*>(input)); //FIXME 
    return sizeof(destination);
}
//EXAMPLE
enum class SomeEnum: uint16_t {
  BAR,
  BAZ
}

class Foo {
  SomeEnum m_Enum;
  uint8_t m_Int;
  bool m_Bool;
public: 
  static Foo deserializeFrom(const char* const buffer) {
    Foo result;
    offset = 0;
    offset+= parseBinaryToType(buffer + offset, result.m_Enum);
    offset+= parseBinaryToType(buffer + offset, result.m_Int);
    offset+= parseBinaryToType(buffer + offset, result.m_Bool);
    return result;
  }
}

But I find this very unsafe. Especially due to the reinterpret_cast and the fact that it doesn't check for endianness.. Is there a safe way to do this in cpp?

Note that I'm only trying to parse types like bool or int, not whole structs.

Typhaon
  • 828
  • 8
  • 27
  • endianess isnt about safety, its either wrong or not. – 463035818_is_not_an_ai Dec 14 '22 at 09:17
  • 2
    Please create a [mre] to show us. What is `destination`? What is the type `To`? – Some programmer dude Dec 14 '22 at 09:17
  • 1
    Presumable there is some structure in the "some data" you mention. If so, I would use a parser generator like Kaitai struct that interprets a high-level description of a binary format and returns you a nice parsed representation. – Botje Dec 14 '22 at 09:21
  • Does this answer your question? [C++ serialization - use of reinterpret\_cast from char \* to a struct](https://stackoverflow.com/questions/27055729/c-serialization-use-of-reinterpret-cast-from-char-to-a-struct) – Den-Jason Dec 14 '22 at 09:22
  • @Someprogrammerdude Good point, here you go :) – Typhaon Dec 14 '22 at 09:26
  • Seems like you are looking for the serializaton, i.e. something like boost serialize etc. – Victor Gubin Dec 14 '22 at 12:51
  • @VictorGubin Yes I do, but I need to control the exact byte layout, and boost serialize is very opinionated. So I implemented my own, and I only need to fix this line to tie everything together – Typhaon Dec 14 '22 at 14:05
  • 1
    Proper and working *generic* binary serialization is hard, which is why you should find a library or framework for that. On the other hand, binary communication over a serial line is *not* hard, if you don't bother with generic serialization and instead use knowledge of the protocol used to extract just the bytes and bits you need for each piece of data. Which is basically what you already is doing. The problem is the multi-byte values, whose order will be defined by the protocol, and might need byte-swapping. In other words, besides endianness, your way is fine. – Some programmer dude Dec 14 '22 at 14:47
  • @Typhaon you can implement your own [archive](https://stackoverflow.com/questions/3921151/creating-own-implementation-of-boostarchive) – Victor Gubin Dec 14 '22 at 17:36
  • @Typhaon BTW during de-serialization more likely you will need to do something like `int destination; std::memmove(destination, input, sizeof(destination) ); return destination;` In any case you'd better implement it as an archive to boost serialize and used it instead reinventing a wheal. – Victor Gubin Dec 14 '22 at 21:38

0 Answers0