Dump resources to files for debugging

This commit is contained in:
Iliyas Jorio 2020-12-26 17:02:46 +01:00
parent d25687f9f0
commit 95fdba76bf
3 changed files with 61 additions and 9 deletions

View File

@ -5,6 +5,7 @@
#include <algorithm>
#include <fstream>
#include <iostream>
#include "CompilerSupport/filesystem.h"
#define LOG POMME_GENLOG(POMME_DEBUG_RESOURCES, "RSRC")
@ -20,6 +21,8 @@ static std::vector<ResourceFork> rezSearchStack;
static int rezSearchStackIndex = 0;
static fs::path rezDumpHostDestinationPath = "";
//-----------------------------------------------------------------------------
// Internal
@ -48,24 +51,50 @@ static void PrintStack(const char* msg) {
}
LOG << "------------------------------------\n";
}
#endif
static void DumpResource(ResourceMetadata& meta)
static void DumpResource(const ResourceMetadata& meta)
{
const FSSpec& spec = Pomme::Files::GetSpec(meta.forkRefNum);
Handle handle = NewHandle(meta.size);
auto& fork = Pomme::Files::GetStream(meta.forkRefNum);
fork.seekg(meta.dataOffset, std::ios::beg);
fork.read(*handle, meta.size);
fs::path outPath;
outPath = rezDumpHostDestinationPath;
outPath /= spec.cName;
outPath /= Pomme::FourCCString(meta.type, '_');
fs::create_directories(outPath);
std::stringstream ss;
ss << meta.id;
if (!meta.name.empty())
{
ss << "-";
for (auto c: meta.name)
ss << (char)(isalnum(c)? c: '_');
}
outPath /= ss.str();
outPath += "." + Pomme::FourCCString(meta.type, '_');
std::ofstream dump(outPath, std::ofstream::binary);
// Add a 512-byte blank header to PICTs so tools such as ImageMagick or Preview.app will display them
if (meta.type == 'PICT')
{
for (int i = 0; i < 512; i++)
dump.put(0);
}
std::stringstream fn;
fn << "rezdump/" << meta.id << "_" << meta.name << "." << Pomme::FourCCString(meta.type, '_');
std::ofstream dump(fn.str(), std::ofstream::binary);
dump.write(*handle, meta.size);
dump.close();
std::cout << "wrote " << fn.str() << "\n";
std::cout << "wrote " << outPath << "\n";
DisposeHandle(handle);
}
#endif
//-----------------------------------------------------------------------------
// Resource file management
@ -166,6 +195,10 @@ short FSpOpenResFile(const FSSpec* spec, char permission)
resMetadata.size = size;
resMetadata.name = name;
GetCurRF().resourceMap[resType][resID] = resMetadata;
// Dump resource to file (if user called Pomme_StartDumpingResource)
if (!rezDumpHostDestinationPath.empty())
DumpResource(resMetadata);
}
}
@ -258,6 +291,7 @@ Handle GetResource(ResType theType, short theID)
Handle handle = NewHandle(meta.size);
forkStream.seekg(meta.dataOffset, std::ios::beg);
forkStream.read(*handle, meta.size);
return handle;
}
@ -302,3 +336,15 @@ long SizeResource(Handle theResource)
{
return GetResourceSizeOnDisk(theResource);
}
void Pomme_StartDumpingResources(const char* hostDestinationPath)
{
if (hostDestinationPath)
{
rezDumpHostDestinationPath = hostDestinationPath;
}
else
{
rezDumpHostDestinationPath.clear();
}
}

View File

@ -99,6 +99,11 @@ long GetResourceSizeOnDisk(Handle);
long SizeResource(Handle);
// After calling this function, Pomme will dump all resources to separate files
// whenever a new resource fork is opened.
// Pass in NULL to stop dumping resources.
void Pomme_StartDumpingResources(const char* hostDestinationPath);
//-----------------------------------------------------------------------------
// QuickDraw 2D: Shapes

View File

@ -46,11 +46,12 @@ std::string Pomme::FourCCString(uint32_t t, char filler)
#if !(TARGET_RT_BIGENDIAN)
std::reverse(b, b + 4);
#endif
// replace non-ascii with '?'
// Replace any non-alphanumeric character with the filler character.
// This ensures that the resulting string is suitable for use as a filename.
for (int i = 0; i < 4; i++)
{
char c = b[i];
if (c < ' ' || c > '~') b[i] = filler;
if (!isalnum(b[i]))
b[i] = filler;
}
b[4] = '\0';
return b;