mirror of
https://github.com/elasota/Aerofoil.git
synced 2025-12-14 03:59:36 +00:00
File system refactor, bug fixes
This commit is contained in:
@@ -1,63 +1,185 @@
|
||||
#include "MacFileInfo.h"
|
||||
#include "PLBigEndian.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
|
||||
static const unsigned int kOffsetFileType = 0;
|
||||
static const unsigned int kOffsetFileCreator = 4;
|
||||
static const unsigned int kOffsetXPos = 8;
|
||||
static const unsigned int kOffsetYPos = 10;
|
||||
static const unsigned int kOffsetFinderFlags = 12;
|
||||
static const unsigned int kProtected = 14;
|
||||
static const unsigned int kCreationDate = 15;
|
||||
static const unsigned int kModifiedDate = 19;
|
||||
|
||||
static const unsigned int kSize = 23;
|
||||
|
||||
uint8_t m_data[kSize];
|
||||
|
||||
void MacFilePropertiesSerialized::Deserialize(MacFileProperties &props) const
|
||||
{
|
||||
memcpy(props.m_fileType, m_data + kOffsetFileType, 4);
|
||||
memcpy(props.m_fileCreator, m_data + kOffsetFileCreator, 4);
|
||||
memcpy(&props.m_xPos, m_data + kOffsetXPos, 2);
|
||||
memcpy(&props.m_yPos, m_data + kOffsetYPos, 2);
|
||||
memcpy(&props.m_finderFlags, m_data + kOffsetFinderFlags, 2);
|
||||
memcpy(&props.m_protected, m_data + kProtected, 1);
|
||||
memcpy(&props.m_creationDate, m_data + kCreationDate, 8);
|
||||
memcpy(&props.m_modifiedDate, m_data + kModifiedDate, 8);
|
||||
|
||||
PortabilityLayer::ByteSwap::BigInt16(props.m_xPos);
|
||||
PortabilityLayer::ByteSwap::BigInt16(props.m_yPos);
|
||||
PortabilityLayer::ByteSwap::BigUInt16(props.m_finderFlags);
|
||||
PortabilityLayer::ByteSwap::BigInt64(props.m_creationDate);
|
||||
PortabilityLayer::ByteSwap::BigInt64(props.m_modifiedDate);
|
||||
}
|
||||
|
||||
void MacFilePropertiesSerialized::Serialize(const MacFileProperties &props)
|
||||
{
|
||||
int16_t xPos = props.m_xPos;
|
||||
int16_t yPos = props.m_yPos;
|
||||
uint16_t finderFlags = props.m_finderFlags;
|
||||
uint64_t creationDate = props.m_creationDate;
|
||||
uint64_t modifiedDate = props.m_modifiedDate;
|
||||
|
||||
PortabilityLayer::ByteSwap::BigInt16(xPos);
|
||||
PortabilityLayer::ByteSwap::BigInt16(yPos);
|
||||
PortabilityLayer::ByteSwap::BigUInt16(finderFlags);
|
||||
PortabilityLayer::ByteSwap::BigUInt64(creationDate);
|
||||
PortabilityLayer::ByteSwap::BigUInt64(modifiedDate);
|
||||
|
||||
memcpy(m_data + kOffsetFileType, props.m_fileType, 4);
|
||||
memcpy(m_data + kOffsetFileCreator, props.m_fileCreator, 4);
|
||||
memcpy(m_data + kOffsetXPos, &xPos, 2);
|
||||
memcpy(m_data + kOffsetYPos, &yPos, 2);
|
||||
memcpy(m_data + kOffsetFinderFlags, &finderFlags, 2);
|
||||
memcpy(m_data + kProtected, &props.m_protected, 1);
|
||||
memcpy(m_data + kCreationDate, &creationDate, 8);
|
||||
memcpy(m_data + kModifiedDate, &modifiedDate, 8);
|
||||
}
|
||||
}
|
||||
#include "MacFileInfo.h"
|
||||
|
||||
#include "DeflateCodec.h"
|
||||
#include "GpIOStream.h"
|
||||
#include "ZipFile.h"
|
||||
#include "PLBigEndian.h"
|
||||
#include "CombinedTimestamp.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
void MacFilePropertiesSerialized::Deserialize(MacFileProperties &props) const
|
||||
{
|
||||
memcpy(props.m_fileType, m_data + kOffsetFileType, 4);
|
||||
memcpy(props.m_fileCreator, m_data + kOffsetFileCreator, 4);
|
||||
memcpy(&props.m_xPos, m_data + kOffsetXPos, 2);
|
||||
memcpy(&props.m_yPos, m_data + kOffsetYPos, 2);
|
||||
memcpy(&props.m_finderFlags, m_data + kOffsetFinderFlags, 2);
|
||||
memcpy(&props.m_protected, m_data + kOffsetProtected, 1);
|
||||
memcpy(&props.m_createdTimeMacEpoch, m_data + kOffsetCreatedDate, 8);
|
||||
memcpy(&props.m_modifiedTimeMacEpoch, m_data + kOffsetModifiedDate, 8);
|
||||
|
||||
PortabilityLayer::ByteSwap::BigInt16(props.m_xPos);
|
||||
PortabilityLayer::ByteSwap::BigInt16(props.m_yPos);
|
||||
PortabilityLayer::ByteSwap::BigUInt16(props.m_finderFlags);
|
||||
PortabilityLayer::ByteSwap::BigInt64(props.m_createdTimeMacEpoch);
|
||||
PortabilityLayer::ByteSwap::BigInt64(props.m_modifiedTimeMacEpoch);
|
||||
}
|
||||
|
||||
void MacFilePropertiesSerialized::Serialize(const MacFileProperties &props)
|
||||
{
|
||||
int16_t xPos = props.m_xPos;
|
||||
int16_t yPos = props.m_yPos;
|
||||
uint16_t finderFlags = props.m_finderFlags;
|
||||
uint64_t createdDate = props.m_createdTimeMacEpoch;
|
||||
uint64_t modifiedDate = props.m_modifiedTimeMacEpoch;
|
||||
|
||||
PortabilityLayer::ByteSwap::BigInt16(xPos);
|
||||
PortabilityLayer::ByteSwap::BigInt16(yPos);
|
||||
PortabilityLayer::ByteSwap::BigUInt16(finderFlags);
|
||||
PortabilityLayer::ByteSwap::BigUInt64(createdDate);
|
||||
PortabilityLayer::ByteSwap::BigUInt64(modifiedDate);
|
||||
|
||||
memcpy(m_data + kOffsetFileType, props.m_fileType, 4);
|
||||
memcpy(m_data + kOffsetFileCreator, props.m_fileCreator, 4);
|
||||
memcpy(m_data + kOffsetXPos, &xPos, 2);
|
||||
memcpy(m_data + kOffsetYPos, &yPos, 2);
|
||||
memcpy(m_data + kOffsetFinderFlags, &finderFlags, 2);
|
||||
memcpy(m_data + kOffsetProtected, &props.m_protected, 1);
|
||||
memcpy(m_data + kOffsetCreatedDate, &createdDate, 8);
|
||||
memcpy(m_data + kOffsetModifiedDate, &modifiedDate, 8);
|
||||
}
|
||||
|
||||
bool MacFilePropertiesSerialized::WriteAsPackage(GpIOStream &stream, const CombinedTimestamp &ts) const
|
||||
{
|
||||
if (!WriteIsolated(stream, ts))
|
||||
return false;
|
||||
|
||||
const char *packagedName = GetPackagedName();
|
||||
|
||||
uint16_t msdosDate, msdosTime;
|
||||
ts.GetAsMSDOSTimestamp(msdosDate, msdosTime);
|
||||
|
||||
ZipCentralDirectoryFileHeader cdh;
|
||||
cdh.m_signature = ZipCentralDirectoryFileHeader::kSignature;
|
||||
cdh.m_versionCreated = ZipConstants::kCompressedRequiredVersion;
|
||||
cdh.m_versionRequired = ZipConstants::kStoredRequiredVersion;
|
||||
cdh.m_flags = 0;
|
||||
cdh.m_method = ZipConstants::kStoredMethod;
|
||||
cdh.m_modificationTime = msdosTime;
|
||||
cdh.m_modificationDate = msdosDate;
|
||||
cdh.m_crc = PortabilityLayer::DeflateContext::CRC32(0, m_data, sizeof(m_data));
|
||||
cdh.m_compressedSize = sizeof(m_data);
|
||||
cdh.m_uncompressedSize = sizeof(m_data);
|
||||
cdh.m_fileNameLength = strlen(packagedName);
|
||||
cdh.m_extraFieldLength = 0;
|
||||
cdh.m_commentLength = 0;
|
||||
cdh.m_diskNumber = 0;
|
||||
cdh.m_internalAttributes = ZipConstants::kArchivedAttributes;
|
||||
cdh.m_externalAttributes = PortabilityLayer::ZipConstants::kArchivedAttributes;
|
||||
cdh.m_localHeaderOffset = 0;
|
||||
|
||||
if (!stream.WriteExact(&cdh, sizeof(cdh)))
|
||||
return false;
|
||||
|
||||
if (!stream.WriteExact(packagedName, strlen(packagedName)))
|
||||
return false;
|
||||
|
||||
ZipEndOfCentralDirectoryRecord eod;
|
||||
eod.m_signature = ZipEndOfCentralDirectoryRecord::kSignature;
|
||||
eod.m_thisDiskNumber = 0;
|
||||
eod.m_centralDirDisk = 0;
|
||||
eod.m_numCentralDirRecordsThisDisk = 1;
|
||||
eod.m_numCentralDirRecords = 1;
|
||||
eod.m_centralDirectorySizeBytes = sizeof(ZipCentralDirectoryFileHeader) + strlen(packagedName);
|
||||
eod.m_centralDirStartOffset = sizeof(ZipFileLocalHeader) + strlen(packagedName) + sizeof(m_data);
|
||||
eod.m_commentLength = 0;
|
||||
|
||||
if (stream.Write(&eod, sizeof(eod)) != sizeof(eod))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MacFilePropertiesSerialized::WriteIsolated(GpIOStream &stream, const CombinedTimestamp &ts) const
|
||||
{
|
||||
static const char *packagedName = GetPackagedName();
|
||||
|
||||
ZipFileLocalHeader lh;
|
||||
static const uint32_t kSignature = 0x04034b50;
|
||||
|
||||
uint16_t msdosDate, msdosTime;
|
||||
ts.GetAsMSDOSTimestamp(msdosDate, msdosTime);
|
||||
|
||||
lh.m_signature = ZipFileLocalHeader::kSignature;
|
||||
lh.m_versionRequired = ZipConstants::kStoredRequiredVersion;
|
||||
lh.m_flags = 0;
|
||||
lh.m_method = ZipConstants::kStoredMethod;
|
||||
lh.m_modificationTime = msdosTime;
|
||||
lh.m_modificationDate = msdosDate;
|
||||
lh.m_crc = DeflateContext::CRC32(0, m_data, sizeof(m_data));
|
||||
lh.m_compressedSize = sizeof(m_data);
|
||||
lh.m_uncompressedSize = sizeof(m_data);
|
||||
lh.m_fileNameLength = strlen(packagedName);
|
||||
lh.m_extraFieldLength = 0;
|
||||
|
||||
if (stream.Write(&lh, sizeof(lh)) != sizeof(lh))
|
||||
return false;
|
||||
|
||||
if (stream.Write(packagedName, strlen(packagedName)) != strlen(packagedName))
|
||||
return false;
|
||||
|
||||
if (stream.Write(m_data, sizeof(m_data)) != sizeof(m_data))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MacFilePropertiesSerialized::ReadFromPackage(GpIOStream &stream)
|
||||
{
|
||||
const char *packagedName = GetPackagedName();
|
||||
|
||||
ZipFileLocalHeader lh;
|
||||
if (stream.Read(&lh, sizeof(lh)) != sizeof(lh))
|
||||
return false;
|
||||
|
||||
if (lh.m_signature != ZipFileLocalHeader::kSignature)
|
||||
return false;
|
||||
if (lh.m_versionRequired != ZipConstants::kStoredRequiredVersion)
|
||||
return false;
|
||||
if (lh.m_flags != 0)
|
||||
return false;
|
||||
if (lh.m_method != ZipConstants::kStoredMethod)
|
||||
return false;
|
||||
|
||||
if (lh.m_compressedSize != sizeof(m_data))
|
||||
return false;
|
||||
|
||||
if (lh.m_uncompressedSize != sizeof(m_data))
|
||||
return false;
|
||||
|
||||
if (lh.m_fileNameLength != strlen(packagedName))
|
||||
return false;
|
||||
|
||||
if (lh.m_extraFieldLength != 0)
|
||||
return false;
|
||||
|
||||
if (!stream.SeekCurrent(lh.m_fileNameLength))
|
||||
return false;
|
||||
|
||||
if (stream.Read(m_data, sizeof(m_data)) != sizeof(m_data))
|
||||
return false;
|
||||
|
||||
if (lh.m_crc != DeflateContext::CRC32(0, m_data, sizeof(m_data)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *MacFilePropertiesSerialized::GetPackagedName()
|
||||
{
|
||||
return "!!meta";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user