COMMON: Add Macintosh Finder Info types and add parsing of it to StuffItArchive.

This commit is contained in:
elasota 2022-11-09 20:03:59 -05:00 committed by Eugene Sandulenko
parent c8da63062a
commit b3c70aa1ba
3 changed files with 127 additions and 4 deletions

View File

@ -37,6 +37,49 @@
namespace Common {
MacFinderInfo::MacFinderInfo() : type{0, 0, 0, 0}, creator{0, 0, 0, 0}, flags(0), position(0, 0), windowID(0) {
}
MacFinderInfo::MacFinderInfo(const MacFinderInfoData &data) {
memcpy(type, data.data + 0, 4);
memcpy(creator, data.data + 4, 4);
flags = READ_BE_UINT16(data.data + 8);
position.y = READ_BE_INT16(data.data + 10);
position.x = READ_BE_INT16(data.data + 12);
windowID = READ_BE_INT16(data.data + 14);
}
MacFinderInfoData MacFinderInfo::toData() const {
MacFinderInfoData data;
memcpy(data.data + 0, type, 4);
memcpy(data.data + 4, creator, 4);
WRITE_BE_UINT16(data.data + 8, flags);
WRITE_BE_INT16(data.data + 10, position.y);
WRITE_BE_INT16(data.data + 12, position.x);
WRITE_BE_INT16(data.data + 14, windowID);
return data;
}
MacFinderExtendedInfo::MacFinderExtendedInfo() : iconID(0), commentID(0), homeDirectoryID(0) {
}
MacFinderExtendedInfo::MacFinderExtendedInfo(const MacFinderExtendedInfoData &data) {
iconID = READ_BE_INT16(data.data + 0);
commentID = READ_BE_INT16(data.data + 10);
homeDirectoryID = READ_BE_INT32(data.data + 12);
}
MacFinderExtendedInfoData MacFinderExtendedInfo::toData() const {
MacFinderExtendedInfoData data;
WRITE_BE_INT16(data.data + 0, iconID);
memset(data.data + 2, 0, 8);
WRITE_BE_INT16(data.data + 10, commentID);
WRITE_BE_INT32(data.data + 12, homeDirectoryID);
return data;
}
#define MBI_ZERO1 0
#define MBI_NAMELEN 1
#define MBI_ZERO2 74

View File

@ -26,6 +26,7 @@
#include "common/array.h"
#include "common/fs.h"
#include "common/rect.h"
#include "common/str.h"
#include "common/str-array.h"
@ -41,8 +42,11 @@ namespace Common {
* @brief API for Macintosh resource fork manager.
*
* @details Used in engines:
* - director
* - groovie
* - kyra
* - mohawk
* - mtropolis
* - pegasus
* - sci
* - scumm
@ -52,6 +56,68 @@ namespace Common {
typedef Array<uint16> MacResIDArray;
typedef Array<uint32> MacResTagArray;
/**
* Class containing the raw data bytes for a Macintosh Finder Info data block.
*/
struct MacFinderInfoData {
byte data[16];
};
/**
* Class containing the raw data bytes for a Macintosh Extended Finder Info data block.
*/
struct MacFinderExtendedInfoData {
byte data[16];
};
/**
* Class containing Macintosh Finder Info.
*/
struct MacFinderInfo {
enum FinderFlags {
kFinderFlagAlias = (1 << 15),
kFinderFlagInvisible = (1 << 14),
kFinderFlagBundle = (1 << 13),
kFinderFlagNameLocked = (1 << 12),
kFinderFlagStationery = (1 << 11),
kFinderFlagCustomIcon = (1 << 10),
kFinderFlagInited = (1 << 8),
kFinderFlagNoInit = (1 << 7),
kFinderFlagShared = (1 << 6),
kFinderFlagColorBit2 = (1 << 3),
kFinderFlagColorBit1 = (1 << 2),
kFinderFlagColorBit0 = (1 << 1),
};
MacFinderInfo();
explicit MacFinderInfo(const MacFinderInfoData &data);
MacFinderInfoData toData() const;
byte type[4];
byte creator[4];
uint16 flags;
Common::Point position;
int16 windowID;
};
/**
* Class containing Macintosh Extended Finder Info.
*/
struct MacFinderExtendedInfo {
static const uint kDataSize = 16;
MacFinderExtendedInfo();
explicit MacFinderExtendedInfo(const MacFinderExtendedInfoData &data);
MacFinderExtendedInfoData toData() const;
int16 iconID;
int16 commentID;
int32 homeDirectoryID;
};
/**
* Class for handling Mac data and resource forks.
* It can read from raw, MacBinary, and AppleDouble formats.

View File

@ -29,6 +29,7 @@
#include "common/debug.h"
#include "common/hash-str.h"
#include "common/hashmap.h"
#include "common/macresman.h"
#include "common/memstream.h"
#include "common/substream.h"
@ -65,6 +66,9 @@ private:
typedef Common::HashMap<Common::String, FileEntry, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> FileMap;
FileMap _map;
typedef Common::HashMap<Common::String, Common::MacFinderInfoData, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> MetadataMap;
MetadataMap _metadataMap;
// Decompression Functions
Common::SeekableReadStream *decompress14(Common::SeekableReadStream *src, uint32 uncompressedSize) const;
@ -145,9 +149,11 @@ bool StuffItArchive::open(Common::SeekableReadStream *stream) {
// Skip remaining bytes
_stream->skip(63 - fileNameLength);
/* uint32 fileType = */ _stream->readUint32BE();
/* uint32 fileCreator = */ _stream->readUint32BE();
/* uint16 finderFlags = */ _stream->readUint16BE();
MacFinderInfo finfo;
_stream->read(finfo.type, 4);
_stream->read(finfo.creator, 4);
finfo.flags = _stream->readUint16BE();
/* uint32 creationDate = */ _stream->readUint32BE();
/* uint32 modificationDate = */ _stream->readUint32BE();
uint32 resForkUncompressedSize = _stream->readUint32BE();
@ -163,6 +169,8 @@ bool StuffItArchive::open(Common::SeekableReadStream *stream) {
if (dataForkCompression == 32 || dataForkCompression == 33)
continue;
_metadataMap[name + ".finf"] = finfo.toData();
if (dataForkUncompressedSize != 0) {
// We have a data fork
@ -224,8 +232,14 @@ const Common::ArchiveMemberPtr StuffItArchive::getMember(const Common::Path &pat
Common::SeekableReadStream *StuffItArchive::createReadStreamForMember(const Common::Path &path) const {
Common::String name = path.toString();
if (!_stream || !_map.contains(name))
if (!_stream || !_map.contains(name)) {
if (_metadataMap.contains(name)) {
const Common::MacFinderInfoData &metadata = _metadataMap[name];
return new Common::MemoryReadStream(reinterpret_cast<const byte *>(&metadata), sizeof(Common::MacFinderInfoData), DisposeAfterUse::NO);
}
return nullptr;
}
const FileEntry &entry = _map[name];