Skip to content

Instantly share code, notes, and snippets.

@depp
Created April 10, 2022 15:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save depp/9eb57f49c2a0fa7de942e52694add012 to your computer and use it in GitHub Desktop.
Save depp/9eb57f49c2a0fa7de942e52694add012 to your computer and use it in GitHub Desktop.
Classic Mac file reading
// Location of the application: volume & directory, or 0 if unknown.
static short gAppVolRefNum;
static long gAppParID;
// Get an FSSpec pointing to a file with the given name.
static OSErr GetDataFile(FSSpec *spec, const char *filename) {
ProcessSerialNumber psn = {0, kCurrentProcess};
ProcessInfoRec info = {0};
FSSpec app_spec;
Str255 pname;
size_t len;
// Get the volume & directory containing the application.
if (gAppVolRefNum == 0) {
info.processInfoLength = sizeof(info);
info.processAppSpec = &app_spec;
;
err = GetProcessInformation(&psn, info);
if (err != noErr) {
return err;
}
gAppVolRefNum = app_spec.volRefNum;
gAppParID = app_spec.parID;
}
// Convert filename to Pascal string.
len = strlen(filename);
assert(len <= 255);
pname[0] = len;
memcpy(pname + 1, filename, len);
return FSMakeFSSpec(gAppVolRef, gAppParID, pname, spec);
}
// Takes a Pascal string as an argument.
FILE *OpenData(const char *filename) {
FSSpec spec;
OSErr err;
err = GetDataFile(&spec, filename);
if (err != noErr) {
printf("FSMakeFSSpec: %d\n", err);
return NULL;
}
return FSp_fopen(&spec, "rb");
}
// Read an entire file into memory.
uint8_t *readFully(const char *filename) {
short refNum;
FSSpec spec;
OSErr err;
long size, count;
uint8_t *resultBuffer;
err = GetDataFile(&spec, filename);
if (err != noErr) {
printf("GetDataFile: %d\n", err);
return NULL;
}
err = FSpOpenDF(&spec, fsRdPerm, &refNum);
if (err != noErr) {
printf("FSpOpenDF: %d\n", err);
return NULL;
}
err = GetEOF(refNum, &size);
if (err != noErr) {
printf("GetEOF: %d\n", err);
FSClose(refNum);
return NULL;
}
resultBuffer = calloc(1, size);
assert(resultBuffer);
count = size;
err = FSRead(refNum, &count, resultBuffer);
FSClose(refNum);
if (err != noErr) {
printf("FSRead: %d\n", err);
free(resultBuffer);
return NULL;
}
return resultBuffer;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment