2

I have this function for reading data and cast them to any type I want

template <class T> inline T readBytes() {
    T result = {};
    if constexpr (std::is_same_v<T, char>)
        file.read(&result, sizeof(result));
    else
        file.read(reinterpret_cast<char*>(&result), sizeof(result));
    return result;
}

I can use it like this

uint32_t num = readBytes<uint32_t>();

It works like I expected. But one thing that I want is being able to read data in big-endian mode too, but I'm not sure what is the best option, maybe this one (I'm not sure if it works).

template<class T>
inline T binaryReader::readBytes(bool LE)
{
    T result = {};
    uint8_t size = sizeof(result);
    char* dst = reinterpret_cast<char*>(&result);
    char *buf = new char[size];
    file.get(buf, size);
    for (uint8_t i = 0; i < size; ++i)
        dst[i] = buf[size - i - 1];
    delete[] buf;
    return result;
}

by best option I mean what way can work the best (in both coding style, and performance)

file-tracer
  • 329
  • 1
  • 7
  • 2
    Do you want to know what the best option is? If yes, please define "best". If no, then you probably only want to know whether your version works? If so, please say it in your question (you can [edit] it). – anatolyg Sep 20 '21 at 13:00
  • @anatolyg sorry I edited it. I think its still not good, but a little better – file-tracer Sep 20 '21 at 13:05
  • 1
    Define "best". If you're happy to limit your code to unix/posix, then you can use network conversion functions (`htons()`, etc) since network byte order is big-endian. More generally (if you want your code truly portable using standard C++) however, you need to specify your file format and functions you create for reading/writing operations in a way that doesn't depend (for the caller) on endianness. – Peter Sep 20 '21 at 13:07
  • Your `buf` is one `char` and you read `size` bytes into it.... – CiaPan Sep 20 '21 at 13:09
  • Assuming a, b, c and d are uint32_t, and are the bytes read in from the big-endian file: `return (a << 24) | (b << 16) | (c << 8) | d;` And the advantage is that this code is platform endian agnostic. – Eljay Sep 20 '21 at 13:09
  • if you have access to c++20 you can use [`std::endian`](https://en.cppreference.com/w/cpp/types/endian) to check local, and then use `htonl` and cousins if you're on a big endian machine. – Mgetz Sep 20 '21 at 13:12
  • @Peter my platform is window only – file-tracer Sep 20 '21 at 13:20
  • Question is is this code your practice of programing or is it commercial code which suppose to be maintained in a future? If this is commercial code then I would try find some ready commonly used library to solve this problem. Please provide more context what kind of data are you reading (maybe there is ready solution for that). – Marek R Sep 20 '21 at 13:21
  • @file-tracer if you're using windows only then you can potentially just assume little endian CPUs. AFAIK NTKernel does not currently support big endian. If you want to hedge you can continue but otherwise this is a non-issue – Mgetz Sep 20 '21 at 13:22
  • @Mgetz Im reading a value from a file that stored as big endian, because of that I need it – file-tracer Sep 20 '21 at 13:36
  • 1
    @file-tracer [`ntohl`](https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-ntohl) and friends are your buddies then. – Mgetz Sep 20 '21 at 13:36
  • @Mgetz I dont think its suit my needs because the values that I read is as big as uint128, the above function that I mentioned work well, and I can read with it without problem, but Im not sure if its good in performance side... – file-tracer Sep 20 '21 at 18:56
  • and I also checked the https://stackoverflow.com/questions/105252/how-do-i-convert-between-big-endian-and-little-endian-values-in-c its very nice and working well, but at the end I wonder which one is better, my function or this. – file-tracer Sep 20 '21 at 19:02
  • the post that mentioned in for reason of closing my question is only for unsigned values, but I want it for both... – file-tracer Oct 07 '21 at 16:30

0 Answers0