From 644ade79c3b74b2b28550cac6a192739eae658cc Mon Sep 17 00:00:00 2001 From: Iliyas Jorio Date: Sun, 18 Jul 2021 13:16:43 +0200 Subject: [PATCH] Implement Count1Types, Get1IndType, Get1IndResource, GetResInfo, DetachResource --- src/Files/Resources.cpp | 88 +++++++++++++++++++++++++++++++++++- src/Memory/BlockDescriptor.h | 24 ++++++++++ src/Memory/Memory.cpp | 55 ++++++++++------------ src/Pomme.h | 15 ++++++ 4 files changed, 151 insertions(+), 31 deletions(-) create mode 100644 src/Memory/BlockDescriptor.h diff --git a/src/Files/Resources.cpp b/src/Files/Resources.cpp index a40b487..86903b2 100644 --- a/src/Files/Resources.cpp +++ b/src/Files/Resources.cpp @@ -1,10 +1,12 @@ #include "Pomme.h" #include "PommeFiles.h" +#include "Memory/BlockDescriptor.h" #include "Utilities/bigendianstreams.h" #include #include #include +#include #include "CompilerSupport/filesystem.h" #if _DEBUG @@ -295,6 +297,29 @@ short Count1Resources(ResType theType) } } +short Count1Types() +{ + return (short) GetCurRF().resourceMap.size(); +} + +void Get1IndType(ResType* theType, short index) +{ + const auto& resourceMap = GetCurRF().resourceMap; + + for (auto& it : resourceMap) + { + if (index == 1) // remember, index is 1-based here + { + *theType = it.first; + return; + } + + index--; + } + + *theType = 0; +} + Handle GetResource(ResType theType, short theID) { lastResError = noErr; @@ -310,9 +335,16 @@ Handle GetResource(ResType theType, short theID) if (resourcesOfType.end() == resourcesOfType.find(theID)) continue; + // Found it! const auto& meta = fork.resourceMap.at(theType).at(theID); auto& forkStream = Pomme::Files::GetStream(rezSearchStack[i].fileRefNum); + + // Allocate handle Handle handle = NewHandle(meta.size); + + // Set pointer to resource metadata + Pomme::Memory::BlockDescriptor::HandleToBlock(handle)->rezMeta = &meta; + forkStream.seekg(meta.dataOffset, std::ios::beg); forkStream.read(*handle, meta.size); @@ -323,6 +355,54 @@ Handle GetResource(ResType theType, short theID) return nil; } +Handle Get1IndResource(ResType theType, short index) +{ + lastResError = noErr; + + const auto& idsToResources = GetCurRF().resourceMap.at(theType); + + for (auto& it : idsToResources) + { + if (index == 1) // remember, index is 1-based here + { + return GetResource(theType, it.second.id); + } + + index--; + } + + lastResError = resNotFound; + return nullptr; +} + +void GetResInfo(Handle theResource, short* theID, ResType* theType, char* name256) +{ + lastResError = noErr; + + if (!theResource) + { + lastResError = resNotFound; + return; + } + + auto blockDescriptor = Pomme::Memory::BlockDescriptor::HandleToBlock(theResource); + + if (!blockDescriptor->rezMeta) + { + lastResError = resNotFound; + return; + } + + if (theID) + *theID = blockDescriptor->rezMeta->id; + + if (theType) + *theType = blockDescriptor->rezMeta->type; + + if (name256) + snprintf(name256, 256, "%s", blockDescriptor->rezMeta->name.c_str()); +} + void ReleaseResource(Handle theResource) { DisposeHandle(theResource); @@ -352,7 +432,13 @@ void WriteResource(Handle theResource) void DetachResource(Handle theResource) { lastResError = noErr; - ONCE(TODOMINOR()); + + auto* blockDescriptor = Pomme::Memory::BlockDescriptor::HandleToBlock(theResource); + + if (!blockDescriptor->rezMeta) + lastResError = resNotFound; + + blockDescriptor->rezMeta = nullptr; } long GetResourceSizeOnDisk(Handle theResource) diff --git a/src/Memory/BlockDescriptor.h b/src/Memory/BlockDescriptor.h new file mode 100644 index 0000000..f9689b5 --- /dev/null +++ b/src/Memory/BlockDescriptor.h @@ -0,0 +1,24 @@ +#pragma once + +namespace Pomme::Files +{ + struct ResourceMetadata; +} + +namespace Pomme::Memory +{ + class BlockDescriptor + { + public: + Ptr buf; + OSType magic; + Size size; + const Pomme::Files::ResourceMetadata* rezMeta; + + BlockDescriptor(Size theSize); + + ~BlockDescriptor(); + + static BlockDescriptor* HandleToBlock(Handle h); + }; +} diff --git a/src/Memory/Memory.cpp b/src/Memory/Memory.cpp index abab375..398ce99 100644 --- a/src/Memory/Memory.cpp +++ b/src/Memory/Memory.cpp @@ -3,31 +3,36 @@ #include #include "Pomme.h" -#include "Utilities/FixedPool.h" +#include "Memory/BlockDescriptor.h" + +using namespace Pomme; +using namespace Pomme::Memory; #define LOG POMME_GENLOG(POMME_DEBUG_MEMORY, "MEMO") //----------------------------------------------------------------------------- // Implementation-specific stuff -static const int HANDLE_MAGIC_LENGTH = 8; -static const char HANDLE_MAGIC[HANDLE_MAGIC_LENGTH] = "LIVEhdl"; -static const char HANDLE_MAGIC_DEAD[HANDLE_MAGIC_LENGTH] = "DEADhdl"; - -struct BlockDescriptor +BlockDescriptor::BlockDescriptor(Size theSize) { - Ptr buf; - char magic[HANDLE_MAGIC_LENGTH]; - Size size; -}; + buf = new char[theSize]; + magic = 'LIVE'; + size = theSize; +} -// these must not move around -static Pomme::FixedPool blocks; +BlockDescriptor::~BlockDescriptor() +{ + delete[] buf; + buf = nullptr; + size = 0; + rezMeta = nullptr; + magic = 'DEAD'; +} -static BlockDescriptor* HandleToBlock(Handle h) +BlockDescriptor* BlockDescriptor::HandleToBlock(Handle h) { auto bd = (BlockDescriptor*) h; - if (0 != memcmp(bd->magic, HANDLE_MAGIC, HANDLE_MAGIC_LENGTH)) + if (bd->magic != 'LIVE') throw std::runtime_error("corrupted handle"); return bd; } @@ -35,20 +40,16 @@ static BlockDescriptor* HandleToBlock(Handle h) //----------------------------------------------------------------------------- // Memory: Handle -Handle NewHandle(Size s) +Handle NewHandle(Size size) { - if (s < 0) throw std::invalid_argument("trying to alloc negative size handle"); + if (size < 0) + throw std::invalid_argument("trying to alloc negative size handle"); - BlockDescriptor* block = blocks.Alloc(); - block->buf = new char[s]; - memcpy(block->magic, HANDLE_MAGIC, HANDLE_MAGIC_LENGTH); - block->size = s; + BlockDescriptor* block = new BlockDescriptor(size); if ((Ptr) &block->buf != (Ptr) block) throw std::runtime_error("buffer address mismatches block address"); - LOG << (void*) block->buf << ", size " << s << "\n"; - return &block->buf; } @@ -78,7 +79,7 @@ Handle TempNewHandle(Size s, OSErr* err) Size GetHandleSize(Handle h) { - return HandleToBlock(h)->size; + return BlockDescriptor::HandleToBlock(h)->size; } void SetHandleSize(Handle handle, Size byteCount) @@ -88,13 +89,7 @@ void SetHandleSize(Handle handle, Size byteCount) void DisposeHandle(Handle h) { - LOG << (void*) *h << "\n"; - BlockDescriptor* b = HandleToBlock(h); - delete[] b->buf; - b->buf = 0; - b->size = -1; - memcpy(b->magic, HANDLE_MAGIC_DEAD, HANDLE_MAGIC_LENGTH); - blocks.Dispose(b); + delete BlockDescriptor::HandleToBlock(h); } OSErr PtrToHand(const void* srcPtr, Handle* dstHndl, Size size) diff --git a/src/Pomme.h b/src/Pomme.h index 9393f68..995a60b 100644 --- a/src/Pomme.h +++ b/src/Pomme.h @@ -97,8 +97,23 @@ void CloseResFile(short refNum); // in the current resource file only. short Count1Resources(ResType); +// Returns total number of resource types +// in the current resource file only. +short Count1Types(void); + +// Gets resource type available in current resource file. +// Note that the index is 1-based! +void Get1IndType(ResType* theType, short index); + Handle GetResource(ResType theType, short theID); +// Reads a resource from the current resource file. +// `index` isn't the actual resource ID! +// `index` ranges from 1 to the number returned by Get1IndType(). +Handle Get1IndResource(ResType theType, short index); + +void GetResInfo(Handle theResource, short* theID, ResType* theType, char* name256); + void ReleaseResource(Handle theResource); void RemoveResource(Handle theResource);