"smart" buffer read

Run Settings
LanguageC++
Language Version
Run Command
#include <iostream> #include <vector> enum Endian { LITTLE, BIG, }; // template the function so we don't have to write it more than once template <typename RT> // RT = read type RT read_type(const std::vector<uint8_t>& buf, size_t idx, Endian end = LITTLE) // takes a const ref to the buffer, this prevents us (to some degree) // from modifying it in the function // size_t is just an unsigned int64 { RT* conv_buf = (RT*)&buf[0]; // interpret the ptr to the first element of the buff as // a ptr to the type we want to read as // because the memory is contiguous, we can index this ptr if (end == LITTLE) { return conv_buf[idx]; // it's already little endian, so just index and return } else { const auto type_size = sizeof(RT); // byte size of the read type RT val = conv_buf[idx]; // copy the value of the section we're looking at uint8_t* interm_buf = (uint8_t*)&val; // reinterpret the copied value's ptr as a byte // again, it's contiguous in memory, so we can index it safely for (int iii = 0; iii < (type_size / 2); iii++) { // for until halfway through the copied value (we're looking at its bytes) // swap the opposite bytes auto& a = interm_buf[iii]; auto& b = interm_buf[type_size - iii - 1]; std::swap(a, b); } return val; // return the value, because we were modifying the copy directly. } } int main() { std::vector<uint8_t> buf = { 0xfc, 0xc5, 0x3f, 0x2a, 0x4c, 0x53, 0x7d, 0xef }; printf("%.4lx\n", read_type<uint16_t>(buf, 3, BIG)); printf("%.8lx\n", read_type<uint32_t>(buf, 1, BIG)); printf("%.16lx\n", read_type<uint64_t>(buf, 0, BIG)); return 0; }
Editor Settings
Theme
Key bindings
Full width
Lines