📄 macclassic.c
字号:
int __PHYSFS_platformIsSymLink(const char *fname){ OSErr err; FSSpec spec; Boolean a = 0; Boolean f = 0; CInfoPBRec infoPB; char *ptr; char *dir = alloca(strlen(fname) + 1); BAIL_IF_MACRO(dir == NULL, ERR_OUT_OF_MEMORY, 0); strcpy(dir, fname); ptr = strrchr(dir, ':'); if (ptr == NULL) /* just a volume name? Can't be a symlink. */ return(0); /* resolve aliases up to the actual file... */ *ptr = '\0'; BAIL_IF_MACRO(fnameToFSSpec(dir, &spec) != noErr, NULL, 0); *ptr = strlen(ptr + 1); /* ptr is now a pascal string. Yikes! */ memset(&infoPB, '\0', sizeof (CInfoPBRec)); infoPB.dirInfo.ioNamePtr = spec.name; infoPB.dirInfo.ioVRefNum = spec.vRefNum; infoPB.dirInfo.ioDrDirID = spec.parID; infoPB.dirInfo.ioFDirIndex = 0; BAIL_IF_MACRO(oserr(PBGetCatInfoSync(&infoPB)) != noErr, NULL, 0); err = FSMakeFSSpec(spec.vRefNum, infoPB.dirInfo.ioDrDirID, (const unsigned char *) ptr, &spec); BAIL_IF_MACRO(oserr(err) != noErr, NULL, 0); BAIL_IF_MACRO(oserr(IsAliasFile(&spec, &a, &f)) != noErr, NULL, 0); return(a);} /* __PHYSFS_platformIsSymlink */int __PHYSFS_platformIsDirectory(const char *fname){ FSSpec spec; CInfoPBRec infoPB; OSErr err; BAIL_IF_MACRO(fnameToFSSpec(fname, &spec) != noErr, NULL, 0); memset(&infoPB, '\0', sizeof (CInfoPBRec)); infoPB.dirInfo.ioNamePtr = spec.name; /* put name in here. */ infoPB.dirInfo.ioVRefNum = spec.vRefNum; /* ID of file's volume. */ infoPB.dirInfo.ioDrDirID = spec.parID; /* ID of bin's dir. */ infoPB.dirInfo.ioFDirIndex = 0; /* file (not parent) info. */ err = PBGetCatInfoSync(&infoPB); BAIL_IF_MACRO(oserr(err) != noErr, NULL, 0); return((infoPB.dirInfo.ioFlAttrib & kioFlAttribDirMask) != 0);} /* __PHYSFS_platformIsDirectory */char *__PHYSFS_platformCvtToDependent(const char *prepend, const char *dirName, const char *append){ int len = ((prepend) ? strlen(prepend) : 0) + ((append) ? strlen(append) : 0) + strlen(dirName) + 1; const char *src; char *dst; char *retval = malloc(len); BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL); if (prepend != NULL) { strcpy(retval, prepend); dst = retval + strlen(retval); } /* if */ else { *retval = '\0'; dst = retval; } /* else */ for (src = dirName; *src; src++, dst++) *dst = ((*src == '/') ? ':' : *src); *dst = '\0'; return(retval);} /* __PHYSFS_platformCvtToDependent */void __PHYSFS_platformTimeslice(void){ SystemTask();} /* __PHYSFS_platformTimeslice */LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname, int omitSymLinks){ LinkedStringList *ret = NULL, *p = NULL; UInt16 i; UInt16 max; FSSpec spec; CInfoPBRec infoPB; Str255 str255; long dirID; BAIL_IF_MACRO(fnameToFSSpec(dirname, &spec) != noErr, NULL, 0); /* get the dir ID of what we want to enumerate... */ memset(&infoPB, '\0', sizeof (CInfoPBRec)); infoPB.dirInfo.ioNamePtr = spec.name; /* name of dir to enum. */ infoPB.dirInfo.ioVRefNum = spec.vRefNum; /* ID of file's volume. */ infoPB.dirInfo.ioDrDirID = spec.parID; /* ID of dir. */ infoPB.dirInfo.ioFDirIndex = 0; /* file (not parent) info. */ BAIL_IF_MACRO(oserr(PBGetCatInfoSync(&infoPB)) != noErr, NULL, NULL); if ((infoPB.dirInfo.ioFlAttrib & kioFlAttribDirMask) == 0) BAIL_MACRO(ERR_NOT_A_DIR, NULL); dirID = infoPB.dirInfo.ioDrDirID; max = infoPB.dirInfo.ioDrNmFls; for (i = 1; i <= max; i++) { FSSpec aliasspec; Boolean alias = 0; Boolean folder = 0; memset(&infoPB, '\0', sizeof (CInfoPBRec)); str255[0] = 0; infoPB.dirInfo.ioNamePtr = str255; /* store name in here. */ infoPB.dirInfo.ioVRefNum = spec.vRefNum; /* ID of dir's volume. */ infoPB.dirInfo.ioDrDirID = dirID; /* ID of dir. */ infoPB.dirInfo.ioFDirIndex = i; /* next file's info. */ if (PBGetCatInfoSync(&infoPB) != noErr) continue; /* skip this file. Oh well. */ if (FSMakeFSSpec(spec.vRefNum, dirID, str255, &aliasspec) != noErr) continue; /* skip it. */ if (IsAliasFile(&aliasspec, &alias, &folder) != noErr) continue; /* skip it. */ if ((alias) && (omitSymLinks)) continue; /* still here? Add it to the list. */ ret = __PHYSFS_addToLinkedStringList(ret, &p, (const char *) &str255[1], str255[0]); } /* for */ return(ret);} /* __PHYSFS_platformEnumerateFiles */char *__PHYSFS_platformCurrentDir(void){ /* * I don't think MacOS has a concept of "current directory", beyond * what is grafted on by a given standard C library implementation, * so just return the base dir. * We don't use this for anything crucial at the moment anyhow. */ return(__PHYSFS_platformCalcBaseDir(NULL));} /* __PHYSFS_platformCurrentDir */char *__PHYSFS_platformRealPath(const char *path){ /* * fnameToFSSpec() will resolve any symlinks to get to the real * file's FSSpec, which, when converted, will contain the real * direct path to a given file. convFSSpecToPath() mallocs a * return value buffer. */ FSSpec spec; BAIL_IF_MACRO(fnameToFSSpec(path, &spec) != noErr, NULL, NULL); return(convFSSpecToPath(&spec, 1));} /* __PHYSFS_platformRealPath */int __PHYSFS_platformMkDir(const char *path){ SInt32 val = 0; FSSpec spec; OSErr err = fnameToFSSpec(path, &spec); BAIL_IF_MACRO(err == noErr, ERR_FILE_EXISTS, 0); BAIL_IF_MACRO(err != fnfErr, NULL, 0); err = DirCreate(spec.vRefNum, spec.parID, spec.name, &val); BAIL_IF_MACRO(oserr(err) != noErr, NULL, 0); return(1);} /* __PHYSFS_platformMkDir */static SInt16 *macDoOpen(const char *fname, SInt8 perm, int createIfMissing){ int created = 0; SInt16 *retval = NULL; FSSpec spec; OSErr err = fnameToFSSpec(fname, &spec); BAIL_IF_MACRO((err != noErr) && (err != fnfErr), NULL, NULL); if (err == fnfErr) { BAIL_IF_MACRO(!createIfMissing, ERR_NO_SUCH_FILE, NULL); err = HCreate(spec.vRefNum, spec.parID, spec.name, procInfo.processSignature, 'BINA'); BAIL_IF_MACRO(oserr(err) != noErr, NULL, NULL); created = 1; } /* if */ retval = (SInt16 *) malloc(sizeof (SInt16)); if (retval == NULL) { if (created) HDelete(spec.vRefNum, spec.parID, spec.name); BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL); } /* if */ err = HOpenDF(spec.vRefNum, spec.parID, spec.name, perm, retval); if (oserr(err) != noErr) { free(retval); if (created) HDelete(spec.vRefNum, spec.parID, spec.name); return(NULL); } /* if */ return(retval);} /* macDoOpen */void *__PHYSFS_platformOpenRead(const char *filename){ SInt16 *retval = macDoOpen(filename, fsRdPerm, 0); if (retval != NULL) /* got a file; seek to start. */ { if (oserr(SetFPos(*retval, fsFromStart, 0)) != noErr) { FSClose(*retval); return(NULL); } /* if */ } /* if */ return((void *) retval);} /* __PHYSFS_platformOpenRead */void *__PHYSFS_platformOpenWrite(const char *filename){ SInt16 *retval = macDoOpen(filename, fsRdWrPerm, 1); if (retval != NULL) /* got a file; truncate it. */ { if ((oserr(SetEOF(*retval, 0)) != noErr) || (oserr(SetFPos(*retval, fsFromStart, 0)) != noErr)) { FSClose(*retval); return(NULL); } /* if */ } /* if */ return((void *) retval);} /* __PHYSFS_platformOpenWrite */void *__PHYSFS_platformOpenAppend(const char *filename){ SInt16 *retval = macDoOpen(filename, fsRdWrPerm, 1); if (retval != NULL) /* got a file; seek to end. */ { if (oserr(SetFPos(*retval, fsFromLEOF, 0)) != noErr) { FSClose(*retval); return(NULL); } /* if */ } /* if */ return(retval);} /* __PHYSFS_platformOpenAppend */PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buffer, PHYSFS_uint32 size, PHYSFS_uint32 count){ SInt16 ref = *((SInt16 *) opaque); SInt32 br; PHYSFS_uint32 i; for (i = 0; i < count; i++) { br = size; BAIL_IF_MACRO(oserr(FSRead(ref, &br, buffer)) != noErr, NULL, i); BAIL_IF_MACRO(br != size, NULL, i); /* !!! FIXME: seek back if only read part of an object! */ buffer = ((PHYSFS_uint8 *) buffer) + size; } /* for */ return(count);} /* __PHYSFS_platformRead */PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer, PHYSFS_uint32 size, PHYSFS_uint32 count){ SInt16 ref = *((SInt16 *) opaque); SInt32 bw; PHYSFS_uint32 i; for (i = 0; i < count; i++) { bw = size; BAIL_IF_MACRO(oserr(FSWrite(ref, &bw, buffer)) != noErr, NULL, i); BAIL_IF_MACRO(bw != size, NULL, i); /* !!! FIXME: seek back if only wrote part of an object! */ buffer = ((PHYSFS_uint8 *) buffer) + size; } /* for */ return(count);} /* __PHYSFS_platformWrite */int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos){ SInt16 ref = *((SInt16 *) opaque); OSErr err = SetFPos(ref, fsFromStart, (SInt32) pos); BAIL_IF_MACRO(oserr(err) != noErr, NULL, 0); return(1);} /* __PHYSFS_platformSeek */PHYSFS_sint64 __PHYSFS_platformTell(void *opaque){ SInt16 ref = *((SInt16 *) opaque); SInt32 curPos; BAIL_IF_MACRO(oserr(GetFPos(ref, &curPos)) != noErr, NULL, -1); return((PHYSFS_sint64) curPos);} /* __PHYSFS_platformTell */PHYSFS_sint64 __PHYSFS_platformFileLength(void *opaque){ SInt16 ref = *((SInt16 *) opaque); SInt32 eofPos; BAIL_IF_MACRO(oserr(GetEOF(ref, &eofPos)) != noErr, NULL, -1); return((PHYSFS_sint64) eofPos);} /* __PHYSFS_platformFileLength */int __PHYSFS_platformEOF(void *opaque){ SInt16 ref = *((SInt16 *) opaque); SInt32 eofPos, curPos; BAIL_IF_MACRO(oserr(GetEOF(ref, &eofPos)) != noErr, NULL, 1); BAIL_IF_MACRO(oserr(GetFPos(ref, &curPos)) != noErr, NULL, 1); return(curPos >= eofPos);} /* __PHYSFS_platformEOF */int __PHYSFS_platformFlush(void *opaque){ SInt16 ref = *((SInt16 *) opaque); ParamBlockRec pb; memset(&pb, '\0', sizeof (ParamBlockRec)); pb.ioParam.ioRefNum = ref; BAIL_IF_MACRO(oserr(PBFlushFileSync(&pb)) != noErr, NULL, 0); return(1);} /* __PHYSFS_platformFlush */int __PHYSFS_platformClose(void *opaque){ SInt16 ref = *((SInt16 *) opaque); SInt16 vRefNum; Str63 volName; int flushVol = 0; if (GetVRefNum(ref, &vRefNum) == noErr) { HParamBlockRec hpbr; memset(&hpbr, '\0', sizeof (HParamBlockRec)); hpbr.volumeParam.ioNamePtr = volName; hpbr.volumeParam.ioVRefNum = vRefNum; hpbr.volumeParam.ioVolIndex = 0; if (PBHGetVInfoSync(&hpbr) == noErr) flushVol = 1; } /* if */ BAIL_IF_MACRO(oserr(FSClose(ref)) != noErr, NULL, 0); free(opaque); if (flushVol) FlushVol(volName, vRefNum); /* update catalog info, etc. */ return(1);} /* __PHYSFS_platformClose */int __PHYSFS_platformDelete(const char *path){ FSSpec spec; OSErr err; BAIL_IF_MACRO(fnameToFSSpec(path, &spec) != noErr, NULL, 0); err = HDelete(spec.vRefNum, spec.parID, spec.name); BAIL_IF_MACRO(oserr(err) != noErr, NULL, 0); return(1);} /* __PHYSFS_platformDelete */void *__PHYSFS_platformCreateMutex(void){ return((void *) 0x0001); /* no mutexes on MacOS Classic. */} /* __PHYSFS_platformCreateMutex */void __PHYSFS_platformDestroyMutex(void *mutex){ /* no mutexes on MacOS Classic. */} /* __PHYSFS_platformDestroyMutex */int __PHYSFS_platformGrabMutex(void *mutex){ return(1); /* no mutexes on MacOS Classic. */} /* __PHYSFS_platformGrabMutex */void __PHYSFS_platformReleaseMutex(void *mutex){ /* no mutexes on MacOS Classic. */} /* __PHYSFS_platformReleaseMutex */PHYSFS_sint64 __PHYSFS_platformGetLastModTime(const char *fname){ FSSpec spec; CInfoPBRec infoPB; UInt32 modDate; if (fnameToFSSpec(fname, &spec) != noErr) return(-1); /* fnameToFSSpec() sets physfs error message. */ memset(&infoPB, '\0', sizeof (CInfoPBRec)); infoPB.dirInfo.ioNamePtr = spec.name; infoPB.dirInfo.ioVRefNum = spec.vRefNum; infoPB.dirInfo.ioDrDirID = spec.parID; infoPB.dirInfo.ioFDirIndex = 0; BAIL_IF_MACRO(oserr(PBGetCatInfoSync(&infoPB)) != noErr, NULL, -1); modDate = ((infoPB.dirInfo.ioFlAttrib & kioFlAttribDirMask) != 0) ? infoPB.dirInfo.ioDrMdDat : infoPB.hFileInfo.ioFlMdDat; /* epoch is different on MacOS. They use Jan 1, 1904, apparently. */ /* subtract seconds between those epochs, counting leap years. */ modDate -= 2082844800; return((PHYSFS_sint64) modDate);} /* __PHYSFS_platformGetLastModTime *//* end of macclassic.c ... */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -