Frage

Ich habe für das 7z-Archivformat über die Formatbeschreibung und Quellcode wurde Gießen, aber ich habe immer noch Probleme, einen gültigen Container zu schreiben. Ich nehme an, ich kann einen leeren Behälter schaffen ... wie auch immer hier ist mein Anfang:

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();

Ich glaube, mein Hauptproblem ein Mangel an Verständnis für std :: ofstream ist :: write (). Byte ist ein 'unsigned char', UInt64 & UInt32 sind beide 'unsigned long'.

UPDATE0 : Wie jeder darauf hinweist, wäre es ein Problem, wenn ich das laufe auf einer Big-Endian-Maschine. Das ist hier nicht der Fall. Per Fredrik Janssen, soll ich die Adresse des nicht-Arrays wurde Gießen. Ich sollte auch erwähnen, dass CrcCalc () eine Funktion im LZMA SDK ist. Hinzufügen & hilft ein bisschen, es ist das erste unsigned char [6], die einige Probleme hat das.

UPDATE1 :. Code Arbeiten eine leere Archivdatei unten zu bekommen

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();
}

Hinweis: CrcGenerateTable () und CrcCalc () ist aus dem LZMA SDK

.
War es hilfreich?

Lösung

nicht wissen, das Format 7z, aber ich feststellen, wenn Sie aufschreiben Offset, die Größe und crc, dass diese im Little-Endian-Format in die Datei geschrieben werden (ich nehme an, Sie haben einen Little-Endian-CPU).

Edit:. Ein wahrscheinlich noch schlimmer, Sie vermissen die & vor Dur, Moll, Offset, die Größe und crc, das heißt Sie die aktuellen Werte auf einen Zeiger werfen

Andere Tipps

Uh ... Ich bin verwirrt. Es verfügt über einen SDK ... die Sie in Ihrem Beitrag erwähnen ... auch die 7-zip Quellen sind online . siehe auch p7zip auf Source. Ich schaute nur auf die Quellen für p7zip und es gibt eine Reihe von Dateien, die mit „7z“ starten, wie sie aussehen würde den Trick tun.

Ich habe nicht das Format 7z programattically selbst (nur über die Befehlszeile util / GUI) verwendet, aber warum würden Sie brauchen, um diese Low-Level Dinge selbst und nicht über das SDK zu behandeln? (Anders als wegen der LGPL Lizenzierung)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top