mirror of
https://github.com/ksherlock/mpw.git
synced 2024-11-22 15:31:50 +00:00
LoadResource, GetResourceSizeOnDisk
This commit is contained in:
parent
51a435114a
commit
f028bd5697
@ -206,6 +206,8 @@ bool operator<(const resource &lhs, const resource &rhs) {
|
|||||||
return (lhs.type < rhs.type) || (lhs.type == rhs.type && lhs.id < rhs.id);
|
return (lhs.type < rhs.type) || (lhs.type == rhs.type && lhs.id < rhs.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* snake_case functions DO NOT set ResError.
|
* snake_case functions DO NOT set ResError.
|
||||||
* CamelCase functions set ResError.
|
* CamelCase functions set ResError.
|
||||||
@ -213,6 +215,8 @@ bool operator<(const resource &lhs, const resource &rhs) {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int refnum = 100;
|
int refnum = 100;
|
||||||
bool res_load = true;
|
bool res_load = true;
|
||||||
|
|
||||||
@ -220,6 +224,102 @@ namespace {
|
|||||||
resource_file *head = nullptr;
|
resource_file *head = nullptr;
|
||||||
|
|
||||||
|
|
||||||
|
inline macos_error SetResError(uint16_t error)
|
||||||
|
{
|
||||||
|
memoryWriteWord(error, MacOS::ResErr);
|
||||||
|
return (macos_error)error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* templates */
|
||||||
|
|
||||||
|
template<class T, class FRT, class F>
|
||||||
|
T with_resource_helper(F &&f, resource_file &rf, resource &r, typename std::enable_if<!std::is_void<FRT>::value>::type* = 0) {
|
||||||
|
T rv = f(rf, r);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class FRT, class F>
|
||||||
|
T with_resource_helper(F &&f, resource_file &rf, resource &r, typename std::enable_if<std::is_void<FRT>::value>::type* = 0) {
|
||||||
|
f(rf, r);
|
||||||
|
return tool_return<void>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class F,
|
||||||
|
typename FRT = typename std::result_of<F(resource_file &, resource &)>::type, // function return type
|
||||||
|
typename TRT = typename tool_return_type<FRT>::type> // tool return type.
|
||||||
|
TRT with_resource_handle(uint32_t theResource, F &&f){
|
||||||
|
|
||||||
|
if (!theResource) return SetResError(resNotFound);
|
||||||
|
|
||||||
|
for (auto rf = head; rf; rf = rf->next) {
|
||||||
|
for (auto &r : rf->resources) {
|
||||||
|
if (r.handle == theResource) {
|
||||||
|
|
||||||
|
TRT rv = with_resource_helper<TRT, FRT>(std::forward<F>(f), *rf, r);
|
||||||
|
SetResError(rv.error());
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SetResError(resNotFound);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
template<class F,
|
||||||
|
typename FRT = typename std::result_of<F(resource_file &, resource &)>::type, // function return type
|
||||||
|
typename TRT = typename tool_return_type<FRT>::type> // tool return type.
|
||||||
|
TRT with_resource(uint32_t type, uint16_t id, F &&f) {
|
||||||
|
|
||||||
|
for (auto rf = current; rf; rf = rf->next) {
|
||||||
|
|
||||||
|
auto &resources = rf.resources;
|
||||||
|
auto iter = std::lower_bound(resources.begin(), resources.end(), 0,
|
||||||
|
[type,id](const resource &lhs, int rhs){
|
||||||
|
if (lhs.type < type) return true;
|
||||||
|
if (lhs.type == type && lhs.id < id) return true;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
if (iter == resources.end()) continue;
|
||||||
|
if (iter->type != type || iter->id != id) continue;
|
||||||
|
|
||||||
|
TRT rv = with_resource_helper<TRT, FRT>(std::forward<F>(f), *rf, *iter);
|
||||||
|
SetResError(rv.error());
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
}
|
||||||
|
return SetResError(resNotFound);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* returns the resource size and set the seek position to read the resource */
|
||||||
|
tool_return<int32_t> get_resource_size(resource_file &rf, resource &r) {
|
||||||
|
|
||||||
|
if (r.size == -1) {
|
||||||
|
uint8_t buffer[4];
|
||||||
|
if (lseek(rf.fd, rf.offset_rdata + r.data_offset, SEEK_SET) < 0)
|
||||||
|
return macos_error_from_errno();
|
||||||
|
size_t ok = read(rf.fd, buffer, sizeof(buffer));
|
||||||
|
if (ok != 4) return mapReadErr;
|
||||||
|
|
||||||
|
return r.size = read_32(buffer);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (lseek(rf.fd, rf.offset_rdata + r.data_offset + 4, SEEK_SET) < 0)
|
||||||
|
return macos_error_from_errno();
|
||||||
|
|
||||||
|
return r.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
tool_return<void> read_resource_map(resource_file &rf) {
|
tool_return<void> read_resource_map(resource_file &rf) {
|
||||||
|
|
||||||
ssize_t ok;
|
ssize_t ok;
|
||||||
@ -301,7 +401,7 @@ namespace {
|
|||||||
ssize_t ok;
|
ssize_t ok;
|
||||||
uint32_t handle = r.handle;
|
uint32_t handle = r.handle;
|
||||||
|
|
||||||
if (!handle) return resNotFound;
|
//if (!handle) return resNotFound;
|
||||||
auto hi = MM::Native::GetHandleInfo(handle);
|
auto hi = MM::Native::GetHandleInfo(handle);
|
||||||
if (hi.error()) return hi.error();
|
if (hi.error()) return hi.error();
|
||||||
if (hi->address) return noErr;
|
if (hi->address) return noErr;
|
||||||
@ -309,22 +409,10 @@ namespace {
|
|||||||
|
|
||||||
// always loads, even if res_load is false.
|
// always loads, even if res_load is false.
|
||||||
|
|
||||||
if (r.size == -1) {
|
auto size = get_resource_size(rf, r);
|
||||||
uint8_t buffer[4];
|
if (!size) return size.error();
|
||||||
if (lseek(rf.fd, rf.offset_rdata + r.data_offset, SEEK_SET) < 0)
|
|
||||||
return macos_error_from_errno();
|
|
||||||
ok = read(rf.fd, buffer, sizeof(buffer));
|
|
||||||
if (ok != 4) return mapReadErr;
|
|
||||||
|
|
||||||
r.size = read_32(buffer);
|
auto ptr = MM::Native::ReallocHandle(handle, *size);
|
||||||
} else {
|
|
||||||
|
|
||||||
if (lseek(rf.fd, rf.offset_rdata + r.data_offset + 4, SEEK_SET) < 0)
|
|
||||||
return macos_error_from_errno();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ptr = MM::Native::ReallocHandle(handle, r.size);
|
|
||||||
if (ptr.error()) return ptr.error();
|
if (ptr.error()) return ptr.error();
|
||||||
|
|
||||||
unsigned attr = MM::attrResource;
|
unsigned attr = MM::attrResource;
|
||||||
@ -332,7 +420,7 @@ namespace {
|
|||||||
if (r.attr & resLocked) attr |= MM::attrLocked;
|
if (r.attr & resLocked) attr |= MM::attrLocked;
|
||||||
|
|
||||||
|
|
||||||
ok = read(rf.fd, memoryPointer(*ptr), r.size);
|
ok = read(rf.fd, memoryPointer(*ptr), *size);
|
||||||
if (ok < 0) {
|
if (ok < 0) {
|
||||||
auto rv = macos_error_from_errno();
|
auto rv = macos_error_from_errno();
|
||||||
// ???
|
// ???
|
||||||
@ -340,7 +428,7 @@ namespace {
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ok != r.size) {
|
if (ok != *size) {
|
||||||
MM::Native::EmptyHandle(handle);
|
MM::Native::EmptyHandle(handle);
|
||||||
return mapReadErr;
|
return mapReadErr;
|
||||||
}
|
}
|
||||||
@ -348,7 +436,6 @@ namespace {
|
|||||||
// locked blocks can't be purged.
|
// locked blocks can't be purged.
|
||||||
MM::Native::HSetState(handle, attr);
|
MM::Native::HSetState(handle, attr);
|
||||||
return noErr;
|
return noErr;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tool_return<uint32_t> read_resource(resource_file &rf, resource &r) {
|
tool_return<uint32_t> read_resource(resource_file &rf, resource &r) {
|
||||||
@ -366,37 +453,25 @@ namespace {
|
|||||||
return *hh;
|
return *hh;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r.size == -1) {
|
auto size = get_resource_size(rf, r);
|
||||||
uint8_t buffer[4];
|
if (!size) return size.error();
|
||||||
if (lseek(rf.fd, rf.offset_rdata + r.data_offset, SEEK_SET) < 0)
|
|
||||||
return macos_error_from_errno();
|
|
||||||
ok = read(rf.fd, buffer, sizeof(buffer));
|
|
||||||
if (ok != 4) return mapReadErr;
|
|
||||||
|
|
||||||
r.size = read_32(buffer);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if (lseek(rf.fd, rf.offset_rdata + r.data_offset + 4, SEEK_SET) < 0)
|
|
||||||
return macos_error_from_errno();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned attr = MM::attrResource;
|
unsigned attr = MM::attrResource;
|
||||||
if (r.attr & resPurgeable) attr |= MM::attrPurgeable;
|
if (r.attr & resPurgeable) attr |= MM::attrPurgeable;
|
||||||
if (r.attr & resLocked) attr |= MM::attrLocked;
|
if (r.attr & resLocked) attr |= MM::attrLocked;
|
||||||
|
|
||||||
|
|
||||||
auto hh = MM::Native::NewHandleWithAttr(r.size, attr);
|
auto hh = MM::Native::NewHandleWithAttr(*size, attr);
|
||||||
if (hh.error()) return hh.error();
|
if (hh.error()) return hh.error();
|
||||||
|
|
||||||
ok = read(rf.fd, memoryPointer(hh->pointer), r.size);
|
ok = read(rf.fd, memoryPointer(hh->pointer), *size);
|
||||||
if (ok < 0) {
|
if (ok < 0) {
|
||||||
auto rv = macos_error_from_errno();
|
auto rv = macos_error_from_errno();
|
||||||
MM::Native::DisposeHandle(hh->handle);
|
MM::Native::DisposeHandle(hh->handle);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ok != r.size) {
|
if (ok != *size) {
|
||||||
MM::Native::DisposeHandle(hh->handle);
|
MM::Native::DisposeHandle(hh->handle);
|
||||||
return mapReadErr;
|
return mapReadErr;
|
||||||
}
|
}
|
||||||
@ -405,11 +480,7 @@ namespace {
|
|||||||
return hh->handle;
|
return hh->handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline macos_error SetResError(uint16_t error)
|
|
||||||
{
|
|
||||||
memoryWriteWord(error, MacOS::ResErr);
|
|
||||||
return (macos_error)error;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1266,6 +1337,45 @@ namespace Native {
|
|||||||
return SetResError(rv.error() == MacOS::dupFNErr ? 0 : rv.error());
|
return SetResError(rv.error() == MacOS::dupFNErr ? 0 : rv.error());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t GetResourceSizeOnDisk(uint16_t trap)
|
||||||
|
{
|
||||||
|
// FUNCTION GetResourceSizeOnDisk (theResource: Handle): LongInt;
|
||||||
|
|
||||||
|
uint32_t sp;
|
||||||
|
uint32_t theResource;
|
||||||
|
|
||||||
|
sp = StackFrame<4>(theResource);
|
||||||
|
|
||||||
|
Log("%04x GetResourceSizeOnDisk(%08x)\n", trap, theResource);
|
||||||
|
|
||||||
|
|
||||||
|
auto rv = with_resource_handle(theResource, get_resource_size);
|
||||||
|
|
||||||
|
ToolReturn<4>(sp, rv.value_or(-1));
|
||||||
|
return rv.error();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t LoadResource(uint16_t trap)
|
||||||
|
{
|
||||||
|
// PROCEDURE LoadResource (theResource: Handle);
|
||||||
|
|
||||||
|
// this loads the resource from disk, if not already
|
||||||
|
// loaded. (if purgeable or SetResLoad(false))
|
||||||
|
|
||||||
|
// this needs cooperation with MM to check if
|
||||||
|
// handle was purged.
|
||||||
|
|
||||||
|
uint32_t theResource;
|
||||||
|
|
||||||
|
StackFrame<4>(theResource);
|
||||||
|
|
||||||
|
Log("%04x LoadResource(%08x)\n", trap, theResource);
|
||||||
|
|
||||||
|
return with_resource_handle(theResource, load_resource).error();
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - Not Yet Implemented.
|
#pragma mark - Not Yet Implemented.
|
||||||
|
|
||||||
|
|
||||||
@ -1294,26 +1404,7 @@ namespace Native {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint16_t LoadResource(uint16_t trap)
|
|
||||||
{
|
|
||||||
// PROCEDURE LoadResource (theResource: Handle);
|
|
||||||
|
|
||||||
// this loads the resource from disk, if not already
|
|
||||||
// loaded. (if purgeable or SetResLoad(false))
|
|
||||||
|
|
||||||
// this needs cooperation with MM to check if
|
|
||||||
// handle was purged.
|
|
||||||
|
|
||||||
uint32_t theResource;
|
|
||||||
|
|
||||||
StackFrame<4>(theResource);
|
|
||||||
|
|
||||||
Log("%04x LoadResource(%08x)\n", trap, theResource);
|
|
||||||
|
|
||||||
fprintf(stderr, "%s not yet implemented\n", __func__);
|
|
||||||
exit(1);
|
|
||||||
return SetResError(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t UpdateResFile(uint16_t trap)
|
uint16_t UpdateResFile(uint16_t trap)
|
||||||
{
|
{
|
||||||
@ -1359,21 +1450,8 @@ namespace Native {
|
|||||||
return SetResError(0);
|
return SetResError(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t GetResourceSizeOnDisk(uint16_t trap)
|
|
||||||
{
|
|
||||||
// FUNCTION GetResourceSizeOnDisk (theResource: Handle): LongInt;
|
|
||||||
|
|
||||||
uint32_t sp;
|
|
||||||
uint32_t theResource;
|
|
||||||
|
|
||||||
sp = StackFrame<4>(theResource);
|
|
||||||
|
|
||||||
Log("%04x GetResourceSizeOnDisk(%08x)\n", trap, theResource);
|
|
||||||
|
|
||||||
fprintf(stderr, "%s not yet implemented\n", __func__);
|
|
||||||
exit(1);
|
|
||||||
return SetResError(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t Count1Resources(uint16_t trap)
|
uint16_t Count1Resources(uint16_t trap)
|
||||||
|
Loading…
Reference in New Issue
Block a user