mirror of
https://github.com/jorio/Pomme.git
synced 2024-12-26 14:29:38 +00:00
Implement Count1Types, Get1IndType, Get1IndResource, GetResInfo, DetachResource
This commit is contained in:
parent
630e8e9b24
commit
644ade79c3
@ -1,10 +1,12 @@
|
||||
#include "Pomme.h"
|
||||
#include "PommeFiles.h"
|
||||
#include "Memory/BlockDescriptor.h"
|
||||
#include "Utilities/bigendianstreams.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#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)
|
||||
|
24
src/Memory/BlockDescriptor.h
Normal file
24
src/Memory/BlockDescriptor.h
Normal file
@ -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);
|
||||
};
|
||||
}
|
@ -3,31 +3,36 @@
|
||||
#include <cstring>
|
||||
|
||||
#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<BlockDescriptor, UInt16, 1000> 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)
|
||||
|
15
src/Pomme.h
15
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);
|
||||
|
Loading…
Reference in New Issue
Block a user