Я пролил описание формата и исходный код для формата архива 7z, но все еще не могу написать действительный контейнер. Я предполагаю, что могу создать пустой контейнер ... в любом случае, вот мой старт:
std::ofstream ofs(archivename.c_str(), std::ios::binary|std::ios::trunc);
Byte signature[6] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
Byte major = 0;
Byte minor = 3;
ofs.write((const char*)signature, 6);
ofs.write((const char*)major, 1);
ofs.write((const char*)minor, 1);
UInt64 offset = 0;
UInt64 size = 0;
UInt32 crc = 0;
ofs.write((const char*)offset, 4);
ofs.write((const char*)size, 8);
ofs.write((const char*)crc, 8);
ofs.write((const char*)CrcCalc(0, 0), 8);
ofs.close();
Я думаю, что моей главной проблемой является отсутствие понимания std :: ofstream :: write (). Байт - это «unsigned char», UInt64 и UInt32 оба являются «unsigned long».
UPDATE0 : Как все указывают, было бы проблемой, если бы я запустил это на машине с прямым порядком байтов. Это не тот случай, здесь. Согласно Фредрику Янссену, я должен использовать адрес не массивов. Я должен также упомянуть, что CrcCalc () является функцией в LZMA SDK. Добавление & немного помогает, это первый неподписанный символ [6], у которого есть некоторые проблемы.
UPDATE1 : рабочий код для получения пустого файла архива ниже.
static void SetUInt32(Byte *p, UInt32 d)
{
for (int i = 0; i < 4; i++, d >>= 8)
p[i] = (Byte)d;
}
static void SetUInt64(Byte *p, UInt64 d)
{
for (int i = 0; i < 8; i++, d >>= 8)
p[i] = (Byte)d;
}
void make_7z_archive()
{
CrcGenerateTable();
std::ofstream ofs(archivename.c_str(), std::ios::binary|std::ios::trunc);
Byte signature[6] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
Byte major = 0;
Byte minor = 3;
ofs.write((const char*)signature, 6);
ofs.write((const char*)&major, 1);
ofs.write((const char*)&minor, 1);
UInt64 offset = 0;
UInt64 size = 0;
UInt32 crc = 0;
Byte buf[24];
SetUInt64(buf + 4, offset);
SetUInt64(buf + 12, size);
SetUInt32(buf + 20, crc);
SetUInt32(buf, CrcCalc(buf + 4, 20));
ofs.write((const char*)buf, 24);
ofs.close();
}
ПРИМЕЧАНИЕ. CrcGenerateTable () и CrcCalc () взяты из LZMA SDK.