DiscIO: Make factory methods return unique_ptrs

Rather than rely on the developer to do the right thing,
just make the default behavior safely deallocate resources.

If shared semantics are ever needed in the future, the
constructor that takes a unique_ptr for shared_ptr can
be used.
This commit is contained in:
Lioncash
2015-12-06 23:15:51 -05:00
parent a0ac2b8673
commit edbbf493f8
22 changed files with 204 additions and 231 deletions

View File

@ -34,7 +34,7 @@ static int m_BlocksPerCluster;
static bool m_isScrubbing = false;
static std::string m_Filename;
static IVolume* m_Disc = nullptr;
static std::unique_ptr<IVolume> s_disc;
struct SPartitionHeader
{
@ -94,11 +94,11 @@ bool SetupScrub(const std::string& filename, int block_size)
m_BlocksPerCluster = CLUSTER_SIZE / m_BlockSize;
m_Disc = CreateVolumeFromFilename(filename);
if (!m_Disc)
s_disc = CreateVolumeFromFilename(filename);
if (!s_disc)
return false;
m_FileSize = m_Disc->GetSize();
m_FileSize = s_disc->GetSize();
u32 numClusters = (u32)(m_FileSize / CLUSTER_SIZE);
@ -112,9 +112,9 @@ bool SetupScrub(const std::string& filename, int block_size)
// Fill out table of free blocks
success = ParseDisc();
// Done with it; need it closed for the next part
delete m_Disc;
m_Disc = nullptr;
s_disc.reset();
m_BlockCount = 0;
// Let's not touch the file if we've failed up to here :p
@ -194,12 +194,12 @@ void MarkAsUsedE(u64 _PartitionDataOffset, u64 _Offset, u64 _Size)
// Helper functions for reading the BE volume
void ReadFromVolume(u64 _Offset, u32& _Buffer, bool _Decrypt)
{
m_Disc->Read(_Offset, sizeof(u32), (u8*)&_Buffer, _Decrypt);
s_disc->Read(_Offset, sizeof(u32), (u8*)&_Buffer, _Decrypt);
_Buffer = Common::swap32(_Buffer);
}
void ReadFromVolume(u64 _Offset, u64& _Buffer, bool _Decrypt)
{
m_Disc->Read(_Offset, sizeof(u32), (u8*)&_Buffer, _Decrypt);
s_disc->Read(_Offset, sizeof(u32), (u8*)&_Buffer, _Decrypt);
_Buffer = Common::swap32((u32)_Buffer);
_Buffer <<= 2;
}
@ -259,71 +259,71 @@ bool ParseDisc()
}
// Operations dealing with encrypted space are done here - the volume is swapped to allow this
bool ParsePartitionData(SPartition& _rPartition)
bool ParsePartitionData(SPartition& partition)
{
bool ParsedOK = true;
bool parsed_ok = true;
// Switch out the main volume temporarily
IVolume *OldVolume = m_Disc;
std::unique_ptr<IVolume> old_volume;
s_disc.swap(old_volume);
// Ready some stuff
m_Disc = CreateVolumeFromFilename(m_Filename, _rPartition.GroupNumber, _rPartition.Number);
if (m_Disc == nullptr)
s_disc = CreateVolumeFromFilename(m_Filename, partition.GroupNumber, partition.Number);
if (s_disc == nullptr)
{
ERROR_LOG(DISCIO, "Failed to create volume from file %s", m_Filename.c_str());
m_Disc = OldVolume;
s_disc.swap(old_volume);
return false;
}
std::unique_ptr<IFileSystem> filesystem(CreateFileSystem(m_Disc));
std::unique_ptr<IFileSystem> filesystem(CreateFileSystem(s_disc.get()));
if (!filesystem)
{
ERROR_LOG(DISCIO, "Failed to create filesystem for group %d partition %u", _rPartition.GroupNumber, _rPartition.Number);
ParsedOK = false;
ERROR_LOG(DISCIO, "Failed to create filesystem for group %d partition %u", partition.GroupNumber, partition.Number);
parsed_ok = false;
}
else
{
// Mark things as used which are not in the filesystem
// Header, Header Information, Apploader
ReadFromVolume(0x2440 + 0x14, _rPartition.Header.ApploaderSize, true);
ReadFromVolume(0x2440 + 0x18, _rPartition.Header.ApploaderTrailerSize, true);
MarkAsUsedE(_rPartition.Offset
+ _rPartition.Header.DataOffset
ReadFromVolume(0x2440 + 0x14, partition.Header.ApploaderSize, true);
ReadFromVolume(0x2440 + 0x18, partition.Header.ApploaderTrailerSize, true);
MarkAsUsedE(partition.Offset
+ partition.Header.DataOffset
, 0
, 0x2440
+ _rPartition.Header.ApploaderSize
+ _rPartition.Header.ApploaderTrailerSize);
+ partition.Header.ApploaderSize
+ partition.Header.ApploaderTrailerSize);
// DOL
ReadFromVolume(0x420, _rPartition.Header.DOLOffset, true);
_rPartition.Header.DOLSize = filesystem->GetBootDOLSize(_rPartition.Header.DOLOffset);
MarkAsUsedE(_rPartition.Offset
+ _rPartition.Header.DataOffset
, _rPartition.Header.DOLOffset
, _rPartition.Header.DOLSize);
ReadFromVolume(0x420, partition.Header.DOLOffset, true);
partition.Header.DOLSize = filesystem->GetBootDOLSize(partition.Header.DOLOffset);
MarkAsUsedE(partition.Offset
+ partition.Header.DataOffset
, partition.Header.DOLOffset
, partition.Header.DOLSize);
// FST
ReadFromVolume(0x424, _rPartition.Header.FSTOffset, true);
ReadFromVolume(0x428, _rPartition.Header.FSTSize, true);
MarkAsUsedE(_rPartition.Offset
+ _rPartition.Header.DataOffset
, _rPartition.Header.FSTOffset
, _rPartition.Header.FSTSize);
ReadFromVolume(0x424, partition.Header.FSTOffset, true);
ReadFromVolume(0x428, partition.Header.FSTSize, true);
MarkAsUsedE(partition.Offset
+ partition.Header.DataOffset
, partition.Header.FSTOffset
, partition.Header.FSTSize);
// Go through the filesystem and mark entries as used
for (SFileInfo file : filesystem->GetFileList())
{
DEBUG_LOG(DISCIO, "%s", file.m_FullPath.empty() ? "/" : file.m_FullPath.c_str());
if ((file.m_NameOffset & 0x1000000) == 0)
MarkAsUsedE(_rPartition.Offset + _rPartition.Header.DataOffset, file.m_Offset, file.m_FileSize);
MarkAsUsedE(partition.Offset + partition.Header.DataOffset, file.m_Offset, file.m_FileSize);
}
}
// Swap back
delete m_Disc;
m_Disc = OldVolume;
s_disc.swap(old_volume);
return ParsedOK;
return parsed_ok;
}
} // namespace DiscScrubber