Я смотрю в разборе TERMINFO файлы базы данных, которые являются типом двоичных файлов. Вы можете прочитать о его формат хранения и подтвердите проблему, с которой я столкнулся.
Руководство говорит —
Заголовок раздела начинается с файла. Этот раздел содержит
шесть коротких целых чисел в формате, описанном ниже. Эти
целые числа(1) магическое число (восьмеричное 0432);
…
…
Короткие целые числа хранятся в двух 8-битных байтах. Первый
байт содержит младшие 8 битов значения,
и второй байт содержит старшие 8 бит.
(Таким образом, представленное значение равно 256 * second + first.)
значение -1 представлено двумя байтами 0377, 0377; Другой
отрицательные значения незаконны. Это значение обычно означает
что соответствующая возможность отсутствует в этом
Терминал. Машины, где это не соответствует
аппаратное обеспечение должно прочитать целые числа как два байта и вычислить
значение с прямым порядком байтов.
Первая проблема при синтаксическом анализе этого типа входных данных заключается в том, что он фиксирует размер до 8 бит, поэтому нельзя использовать обычный старый символ, поскольку он не гарантирует, что размер будет ровно 8 бит. Так я смотрюЦелочисленные типы фиксированной шириныно опять столкнулся с дилеммой выбора ч / б int8_t
или же uint8_t
в котором четко говорится — «предоставляется только в том случае, если реализация напрямую поддерживает тип». Так что я должен выбрать, чтобы тип был достаточно портативным.
Вторая проблема — нет buffer.readInt16LE()
метод в стандартной библиотеке c ++, который может читать 16 байтов данных в формате Little Endian. Так как же мне продолжить, чтобы снова реализовать эту функцию в портативном & безопасный способ.
Я уже пытался читать это с char
тип данных, но он определенно производит мусор на моей машине. Правильный ввод может быть прочитан infocmp
команда например — $ infocmp xterm
,
#include <fstream>
#include <iostream>
#include <vector>
int main()
{
std::ifstream db(
"/usr/share/terminfo/g/gnome", std::ios::binary | std::ios::ate);
std::vector<unsigned char> buffer;
if (db) {
auto size = db.tellg();
buffer.resize(size);
db.seekg(0, std::ios::beg);
db.read(reinterpret_cast<char*>(&buffer.front()), size);
}
std::cout << "\n";
}
$1 = std::vector of length 3069, capacity 3069 = {26 '\032', 1 '\001', 21 '\025',
0 '\000', 38 '&', 0 '\000', 16 '\020', 0 '\000', 157 '\235', 1 '\001',
193 '\301', 4 '\004', 103 'g', 110 'n', 111 'o', 109 'm', 101 'e', 124 '|',
71 'G', 78 'N', 79 'O', 77 'M', 69 'E', 32 ' ', 84 'T', 101 'e', 114 'r',
109 'm', 105 'i', 110 'n', 97 'a', 108 'l', 0 '\000', 0 '\000', 1 '\001',
0 '\000', 0 '\000', 1 '\001', 0 '\000', 0 '\000', 0 '\000', 0 '\000',
0 '\000', 0 '\000', 0 '\000', 0 '\000', 1 '\001', 1 '\001', 0 '\000',
....
....
Первая проблема при синтаксическом анализе этого типа входных данных заключается в том, что он фиксирует размер до 8 бит, поэтому нельзя использовать обычный старый символ, поскольку он не гарантирует, что размер будет ровно 8 бит.
Любое целое число, которое по крайней мере 8 бит, в порядке. В то время как char
не гарантируется, что он будет точно 8 битами, он должен быть не менее 8 битов, поэтому с точки зрения размера, нет никаких проблем, кроме того, что в некоторых случаях вам может понадобиться маскировать старшие биты, если они существуют. Тем не мение, char
может не быть без знака, и вы не хотите, чтобы октеты интерпретировались как подписанные значения, поэтому используйте unsigned char
вместо.
Вторая проблема заключается в том, что в стандартной библиотеке c ++ отсутствует метод buffer.readInt16LE (), который мог бы считывать 16 байтов данных в формате Little Endian. Так как же мне продолжить, чтобы снова реализовать эту функцию в портативном & безопасный способ.
Читайте один октет за раз в unsigned char
, Присвойте первый октет переменной (достаточно большой, чтобы представить не менее 16 бит). Сдвиньте биты второго октета влево на 8 и присвойте переменной, используя битовое соединение или.
Или, что еще лучше, не используйте его заново, а используйте стороннюю библиотеку.
Я уже пробовал читать это с типом данных char, но это определенно производит мусор на моей машине.
Тогда ваша попытка была ошибочной. Нет проблем, присущих char
это приведет к выводу мусора. Я рекомендую использовать отладчик для решения этой проблемы.
Других решений пока нет …