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 <algorithm>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include "CompilerSupport/filesystem.h"
#define LOG POMME_GENLOG(POMME_DEBUG_RESOURCES, "RSRC") #define LOG POMME_GENLOG(POMME_DEBUG_RESOURCES, "RSRC")
@ -20,6 +21,8 @@ static std::vector<ResourceFork> rezSearchStack;
static int rezSearchStackIndex = 0; static int rezSearchStackIndex = 0;
static fs::path rezDumpHostDestinationPath = "";
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Internal // Internal
@ -48,24 +51,50 @@ static void PrintStack(const char* msg) {
} }
LOG << "------------------------------------\n"; 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); Handle handle = NewHandle(meta.size);
auto& fork = Pomme::Files::GetStream(meta.forkRefNum); auto& fork = Pomme::Files::GetStream(meta.forkRefNum);
fork.seekg(meta.dataOffset, std::ios::beg); fork.seekg(meta.dataOffset, std::ios::beg);
fork.read(*handle, meta.size); 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.write(*handle, meta.size);
dump.close(); dump.close();
std::cout << "wrote " << fn.str() << "\n";
std::cout << "wrote " << outPath << "\n";
DisposeHandle(handle); DisposeHandle(handle);
} }
#endif
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Resource file management // Resource file management
@ -166,6 +195,10 @@ short FSpOpenResFile(const FSSpec* spec, char permission)
resMetadata.size = size; resMetadata.size = size;
resMetadata.name = name; resMetadata.name = name;
GetCurRF().resourceMap[resType][resID] = resMetadata; 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); Handle handle = NewHandle(meta.size);
forkStream.seekg(meta.dataOffset, std::ios::beg); forkStream.seekg(meta.dataOffset, std::ios::beg);
forkStream.read(*handle, meta.size); forkStream.read(*handle, meta.size);
return handle; return handle;
} }
@ -302,3 +336,15 @@ long SizeResource(Handle theResource)
{ {
return GetResourceSizeOnDisk(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); 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 // QuickDraw 2D: Shapes

View File

@ -46,11 +46,12 @@ std::string Pomme::FourCCString(uint32_t t, char filler)
#if !(TARGET_RT_BIGENDIAN) #if !(TARGET_RT_BIGENDIAN)
std::reverse(b, b + 4); std::reverse(b, b + 4);
#endif #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++) for (int i = 0; i < 4; i++)
{ {
char c = b[i]; if (!isalnum(b[i]))
if (c < ' ' || c > '~') b[i] = filler; b[i] = filler;
} }
b[4] = '\0'; b[4] = '\0';
return b; return b;