Раз в жизни захотел написать переносимый код и тут же зашел в тупик
.
Необходимо реализовать алгоритм чтения целых чисел из потока байтов (из файла), в котором числа не выровнены по байтам. Можно сказать, в этом потоке вообще такого понятия — "байт" нет, а есть лишь поток битов. Например первое число — 5 бит, второе — 11, третье — 3 и т.д. Т.е. нужно прочитать следующие N байт и интерпретировать их как, например, unsigned int.
Первое что приходит в голову (кстати, может быть кто подскажет способ получше?) — считать несколько бит (байт), сдвинуть влево (?), потом наложить маску из следующих нескольких бит и т.д.
Но тут возникают трудности с переносимостью, буквально на каждом шагу.
1) размер байта не обязательно 8 бит
2) sizeof() возвращает размер в char, а не в байтах. Кол-во бит в байтах вообще никак не узнаешь, похоже.
3) размер (unsigned) char не обязательно 1 байт и соответственно не обязательно 8 бит, более того, я подозреваю, что сhar и байт могут на одной и той же машине иметь разное кол-во бит
4) порядок байт в многобайтовых типах (вроде int) может быть little-endian или big-endian. Т.е. кастить массив байт через указатели в unsigned int не переносимо.
5) порядок бит в байтах (!!! пожалуйста, убедите меня в обратном
) может быть little-endian или big-endian. Т.е. побитовый сдвиг << и >> не всегда приводит к увеличению и уменьшению значения, соответственно.
6) padding — на некоторых системах на месте сдвинутых бит ставятся нули, а на некоторых... незнамо что
Вопрос: как будет выглядеть правильный и полностью переносимый вариант решения данной задачи?