I need to convert C# app which uses extensively bytes manipulation.
An example:
public abstract class BinRecord { public static int version => 1; public virtual int LENGTH => 1 + 7 + 8 + 2 + 1; // 19 public char type; public ulong timestamp; // 7 byte public double p; public ushort size; public char callbackType; public virtual void FillBytes(byte[] bytes) { bytes[0] = (byte)type; var t = BitConverter.GetBytes(timestamp); Buffer.BlockCopy(t, 0, bytes, 1, 7); Buffer.BlockCopy(BitConverter.GetBytes(p), 0, bytes, 8, 8); Buffer.BlockCopy(BitConverter.GetBytes(size), 0, bytes, 16, 2); bytes[18] = (byte)callbackType; } }
Basically BitConverter
and Buffer.BlockCopy
called 100s times per sec.
There are several classes that inherit from the base class above doing more specific tasks. For example:
public class SpecRecord : BinRecord { public override int LENGTH => base.LENGTH + 2; public ushort num; public SpecRecord() { } public SpecRecord(ushort num) { this.num = num; } public override void FillBytes(byte[] bytes) { var idx = base.LENGTH; base.FillBytes(bytes); Buffer.BlockCopy(BitConverter.GetBytes(num), 0, bytes, idx + 0, 2); } }
What approach in C++ should I look into?
Advertisement
Answer
Best option, in my opinion, is to actually go to C – use memcpy
to copy over the bytes of any object.
Your above code would then be re-written as follows:
void FillBytes(uint8_t* bytes) { bytes[0] = (uint8_t)type; memcpy((bytes + 1), &t, sizeof(uint64_t) - 1); memcpy((bytes + 8), &p, sizeof(double)); memcpy((bytes + 16), &size, sizeof(uint16_t)); bytes[18] = (uint8_t)callbackType; }
Here, I use uint8_t
, uint16_t
, and uint64_t
as replacements for the byte
, ushort
, and ulong
types.
Keep in mind, your timestamp copy is not portable to a big-endian CPU – it will cut off the lowest byte rather than the highest. Solving that would require copying in each byte manually, like so:
//Copy a 7 byte timestamp into the buffer. bytes[1] = (t >> 0) & 0xFF; bytes[2] = (t >> 8) & 0xFF; bytes[3] = (t >> 16) & 0xFF; bytes[4] = (t >> 24) & 0xFF; bytes[5] = (t >> 32) & 0xFF; bytes[6] = (t >> 40) & 0xFF; bytes[7] = (t >> 48) & 0xFF;