stream: Get rid of undefined behavior

It's undefined behavior to cast down to any other type and dereference
that pointer unless:

1. It's similar (*extremely* vague definition at face value, see below
   for clarification)

2. The casted to type is either the signed/unsigned variant of the
   original type. (e.g. it's fine to cast an int* to an unsigned int*
   and vice-versa).

3. The casted to pointer type is either std::byte*, char*, or unsigned
   char*.

With regards to type similarity, two types (X and Y) are considered
"similar" if:

1. They're the same type (naturally)

2. They're both pointers and the pointed-to types are similar (basically
   1. but for pointers)

3. They're both pointers to members of the same class and the types of
   the pointed-to members are similar in type.

4. They're both arrays of the same size or both arrays of unknown size
   *and* the array element types are similar.

Plus, doing it this way doesn't do a byte-by-byte appending to the
underlying std::vector and instead allocates all the necessary memory up
front and slaps the elements at the end of it.
This commit is contained in:
Lioncash 2019-03-14 19:35:58 -04:00 committed by ReinUsesLisp
parent 47d85b81a7
commit 326c69896b

View File

@ -24,21 +24,18 @@ void Stream::Write(std::string string) {
}
void Stream::Write(u64 value) {
const auto mem{reinterpret_cast<u32*>(&value)};
Write(mem[0]);
Write(mem[1]);
const auto* const mem = reinterpret_cast<const u8*>(&value);
bytes.insert(bytes.end(), mem, mem + sizeof(u64));
}
void Stream::Write(u32 value) {
const auto mem{reinterpret_cast<u16*>(&value)};
Write(mem[0]);
Write(mem[1]);
const auto* const mem = reinterpret_cast<const u8*>(&value);
bytes.insert(bytes.end(), mem, mem + sizeof(u32));
}
void Stream::Write(u16 value) {
const auto mem{reinterpret_cast<u8*>(&value)};
Write(mem[0]);
Write(mem[1]);
const auto* const mem{reinterpret_cast<const u8*>(&value)};
bytes.insert(bytes.end(), mem, mem + sizeof(u16));
}
void Stream::Write(u8 value) {