Fix Stuffit5 conv and some code cleanup.

This commit is contained in:
Guillaume Gonnet 2019-03-10 11:12:10 +01:00
parent ea24dbaeff
commit e54e2f5b5e
12 changed files with 132 additions and 124 deletions

View File

@ -70,7 +70,7 @@ set(MACONV_SRC
"src/main.cc"
)
# Include "src" and "vendors" folder for resolving #include.
# Include "src" and "vendors" folders for resolving #include.
include_directories("src" "vendors")

View File

@ -37,7 +37,7 @@ Data are arranged as follows:
| 102 **³** | Word | Signature for indentification purposes (always `mBIN`) |
| 106 **³** | Byte | Script of file name (from the fdScript field of an fxInfo record) |
| 107 **³** | Byte | Extended Finder flags (from the fdXFlags field of an fxInfo record) |
| 108-115 | | Unused (must be zeroed by creators, must be ignored by readers) |
| 108 | 8 Bytes | Unused (must be zeroed by creators, must be ignored by readers) |
| 116 **²** | Word | Length of total files when packed files are unpacked. As of the writing of this document, this field has never been used. |
| 120 **²** | Half | Length of a secondary header. If this is non-zero, skip this many bytes (rounded up to the next multiple of 128). This is for future expansion only, when sending files with MacBinary, this word should be zero. |
| 122 **²** | Byte | Version number of MacBinary (`129` for MacBinary II, `130` for MacBinary III) |
@ -52,13 +52,13 @@ Cyclic redundancy check (CRC) used in header is CRC-16-CCITT, i.e. uses
polynomial number `0x1021` and starts with `0`.
## Data and ressource forks.
## Data and ressource forks
Data fork directly follow the header (at byte 128). The length of these data
Data fork directly follows the header (at byte 128). The length of these data
(which can be zero) must correspond with the length given in the header (at byte
83).
Data are completed with some padding bytes (normally `0x00` but some
Data are completed with some padding bytes (usually `0x00` but some
implementations use `0x7F`) until the total length of file is a multiple of 128.
If the total length is already a multiple of 128 after adding the data fork, no
padding is added.

View File

@ -178,7 +178,7 @@ void WriteMacBinary(fs::File &file, fs::FileWriter &base)
writer.Fill(0x0, 2);
writer.WriteByte(file.flags & 0xFF);
// Write MacBinray III magic strings/numbers.
// Write MacBinary III magic strings/numbers.
writer.WriteString("mBIN");
writer.Fill(0x0, 16);
writer.WriteByte(130);

View File

@ -39,7 +39,7 @@ extern "C" void LogDebug(const char *fmt, ...)
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
vprintf(fmt, args);
va_end(args);
printf("\n");
}

View File

@ -320,7 +320,7 @@ constexpr int kLzssEnd = -2;
void Algorithm13Method::InitializeLZSS()
{
int val = *(input.data++);
int code = (val >> 4);
int code = ((val & 0xFF) >> 4);
if (code == 0) {
HuffmanDecoder metacode;

View File

@ -26,6 +26,7 @@ this program. If not, see <https://www.gnu.org/licenses/>.
#include <path.hpp>
#include <cstdarg>
#include <algorithm>
namespace maconv {
namespace stuffit {
@ -61,6 +62,7 @@ static void ExtractFork(StuffitEntry &ent, bool is_res, fs::File &file,
return (void)WarnForkError(ent, is_res, "compression method %u not supported", info.method);
// Try extracting the fork.
LogDebug(" Extracting %s fork using algo %d", (is_res ? "ressource" : "data"), info.method);
try {
ptr->Extract(info, data, file.mem_pool);
} catch (ExtractException &e) {
@ -96,6 +98,7 @@ static void ExtractFile(fs::FileReader &reader, StuffitEntry &ent,
// Log information to user.
std::string filename = dest_folder + "/" + GetFilenameFor(ent.name, prefered_conv);
filename.erase(std::remove(filename.begin(), filename.end(), '\r'), filename.end());
LogDebug("Extracting %s ...", filename.c_str());
// Uncompress forks (if not empty).

View File

@ -3,6 +3,9 @@
Extract files from Stuffit (v5) archives.
See docs/stuffit/Stuffit_v5.md for more information on this format.
The code in this file is based on TheUnarchiver.
See README.md and docs/licenses/TheUnarchiver.txt for more information.
Copyright (C) 2019, Guillaume Gonnet
This program is free software: you can redistribute it and/or modify it under
@ -30,6 +33,7 @@ namespace stuffit {
// Stuffit (v5) entity flags.
constexpr uint8_t kFlagDirectory = 0x40;
constexpr uint8_t kFlagCrypted = 0x20;
constexpr uint8_t kFlagHasRessource = 0x1;
@ -85,7 +89,8 @@ static void ReadFileHeader(fs::FileReader &reader, StuffitEntry &ent)
reader.Skip(1);
// Read flags for knowing if entry is a file or a folder.
ent.etype = (reader.ReadByte() & kFlagDirectory) ? StuffitEntryType::Folder
int flags = reader.ReadByte();
ent.etype = (flags & kFlagDirectory) ? StuffitEntryType::Folder
: StuffitEntryType::File;
// Read creation and modification dates.
@ -99,10 +104,10 @@ static void ReadFileHeader(fs::FileReader &reader, StuffitEntry &ent)
// Read name and data lengths.
uint16_t name_length = reader.ReadHalfBE();
reader.Skip(2);
reader.Skip(2); // Skip header CRC.
ent.data.size = reader.ReadWordBE();
ent.data.comp_size = reader.ReadWordBE();
reader.Skip(4);
reader.Skip(4); // Skip data CRC.
// The entry is a folder: read the number of files.
@ -120,7 +125,7 @@ static void ReadFileHeader(fs::FileReader &reader, StuffitEntry &ent)
else {
ent.num_files = 0;
ent.data.method = reader.ReadByte();
reader.Skip(1);
reader.Skip(1); // Skip password length (as archive is not encrypted).
}
@ -149,9 +154,9 @@ static void ReadFileHeader(fs::FileReader &reader, StuffitEntry &ent)
if (has_res) {
ent.res.size = reader.ReadWordBE();
ent.res.comp_size = reader.ReadWordBE();
reader.Skip(4);
reader.Skip(4); // Skip ressource CRC.
ent.res.method = reader.ReadByte();
reader.Skip(1);
reader.Skip(1); // Skip password length (as archive is not encrypted).
} else {
ent.res.size = 0;
ent.res.comp_size = 0;
@ -163,11 +168,11 @@ static void ReadFileHeader(fs::FileReader &reader, StuffitEntry &ent)
// Set data and res offsets.
ent.data.offset = reader.Tell();
ent.res.offset = ent.data.offset + ent.data.comp_size;
ent.res.offset = reader.Tell();
ent.data.offset = ent.res.offset + ent.res.comp_size;
// Seek to the next entry (if it's a file).
reader.Seek(ent.res.offset + ent.res.comp_size);
reader.Seek(ent.data.offset + ent.data.comp_size);
}

View File

@ -204,16 +204,16 @@ void HuffmanDecoder::MakeTableRecursLE(int node, HuffmanTableEntry *table,
int curr_table_size = (1 << (table_size - depth));
int curr_stride = (1 << depth);
if (IsLeafNode(node)) {
if (IsInvalidNode(node)) {
for (int i = 0; i < curr_table_size; i++)
table[i * curr_stride].length = -1;
}
else if (IsLeafNode(node)) {
for (int i = 0; i < curr_table_size; i++) {
table[i * curr_stride].length = depth;
table[i * curr_stride].value = LeafValue(node);
}
}
else if (IsInvalidNode(node)) {
for (int i = 0; i < curr_table_size; i++)
table[i * curr_stride].length = -1;
}
else {
if (depth == table_size) {
table[0].length = table_size + 1;