📄 tclmacresource.c
字号:
if (objc == 4) { resourceRef = GetRsrcRefFromObj(objv[3], 1, "list", resultPtr); if (resourceRef == NULL) { return TCL_ERROR; } saveRef = CurResFile(); UseResFile((short) resourceRef->fileRef); limitSearch = true; } Tcl_ResetResult(interp); if (limitSearch) { count = Count1Resources(rezType); } else { count = CountResources(rezType); } SetResLoad(false); for (i = 1; i <= count; i++) { if (limitSearch) { resource = Get1IndResource(rezType, i); } else { resource = GetIndResource(rezType, i); } if (resource != NULL) { GetResInfo(resource, &id, (ResType *) &rezType, theName); if (theName[0] != 0) { objPtr = Tcl_NewStringObj((char *) theName + 1, theName[0]); } else { objPtr = Tcl_NewIntObj(id); } ReleaseResource(resource); result = Tcl_ListObjAppendElement(interp, resultPtr, objPtr); if (result != TCL_OK) { Tcl_DecrRefCount(objPtr); break; } } } SetResLoad(true); if (limitSearch) { UseResFile(saveRef); } return TCL_OK; case RESOURCE_OPEN: { Tcl_DString ds, buffer; CONST char *str, *native; int length; if (!((objc == 3) || (objc == 4))) { Tcl_WrongNumArgs(interp, 2, objv, "fileName ?permissions?"); return TCL_ERROR; } str = Tcl_GetStringFromObj(objv[2], &length); if (Tcl_TranslateFileName(interp, str, &buffer) == NULL) { return TCL_ERROR; } native = Tcl_UtfToExternalDString(NULL, Tcl_DStringValue(&buffer), Tcl_DStringLength(&buffer), &ds); err = FSpLocationFromPath(Tcl_DStringLength(&ds), native, &fileSpec); Tcl_DStringFree(&ds); Tcl_DStringFree(&buffer); if (!((err == noErr) || (err == fnfErr))) { Tcl_AppendStringsToObj(resultPtr, "invalid path", (char *) NULL); return TCL_ERROR; } /* * Get permissions for the file. We really only understand * read-only and shared-read-write. If no permissions are * given we default to read only. */ if (objc == 4) { stringPtr = Tcl_GetStringFromObj(objv[3], &length); mode = TclGetOpenMode(interp, stringPtr, &index); if (mode == -1) { /* TODO: TclGetOpenMode doesn't work with Obj commands. */ return TCL_ERROR; } switch (mode & (O_RDONLY | O_WRONLY | O_RDWR)) { case O_RDONLY: macPermision = fsRdPerm; break; case O_WRONLY: case O_RDWR: macPermision = fsRdWrShPerm; break; default: panic("Tcl_ResourceObjCmd: invalid mode value"); break; } } else { macPermision = fsRdPerm; } /* * Don't load in any of the resources in the file, this could * cause problems if you open a file that has CODE resources... */ SetResLoad(false); fileRef = (long) FSpOpenResFileCompat(&fileSpec, macPermision); SetResLoad(true); if (fileRef == -1) { err = ResError(); if (((err == fnfErr) || (err == eofErr)) && (macPermision == fsRdWrShPerm)) { /* * No resource fork existed for this file. Since we are * opening it for writing we will create the resource fork * now. */ HCreateResFile(fileSpec.vRefNum, fileSpec.parID, fileSpec.name); fileRef = (long) FSpOpenResFileCompat(&fileSpec, macPermision); if (fileRef == -1) { goto openError; } } else if (err == fnfErr) { Tcl_AppendStringsToObj(resultPtr, "file does not exist", (char *) NULL); return TCL_ERROR; } else if (err == eofErr) { Tcl_AppendStringsToObj(resultPtr, "file does not contain resource fork", (char *) NULL); return TCL_ERROR; } else { openError: Tcl_AppendStringsToObj(resultPtr, "error opening resource file", (char *) NULL); return TCL_ERROR; } } /* * The FspOpenResFile function does not set the ResFileAttrs. * Even if you open the file read only, the mapReadOnly * attribute is not set. This means we can't detect writes to a * read only resource fork until the write fails, which is bogus. * So set it here... */ if (macPermision == fsRdPerm) { SetResFileAttrs(fileRef, mapReadOnly); } Tcl_SetStringObj(resultPtr, "", 0); if (TclMacRegisterResourceFork(fileRef, resultPtr, TCL_RESOURCE_CHECK_IF_OPEN) != TCL_OK) { CloseResFile(fileRef); return TCL_ERROR; } return TCL_OK; } case RESOURCE_READ: if (!((objc == 4) || (objc == 5))) { Tcl_WrongNumArgs(interp, 2, objv, "resourceType resourceId ?resourceRef?"); return TCL_ERROR; } if (Tcl_GetOSTypeFromObj(interp, objv[2], &rezType) != TCL_OK) { return TCL_ERROR; } if (Tcl_GetLongFromObj((Tcl_Interp *) NULL, objv[3], &rsrcId) != TCL_OK) { resourceId = Tcl_GetStringFromObj(objv[3], &length); } if (objc == 5) { stringPtr = Tcl_GetStringFromObj(objv[4], &length); } else { stringPtr = NULL; } resource = Tcl_MacFindResource(interp, rezType, resourceId, rsrcId, stringPtr, &releaseIt); if (resource != NULL) { size = GetResourceSizeOnDisk(resource); Tcl_SetByteArrayObj(resultPtr, (unsigned char *) *resource, size); /* * Don't release the resource unless WE loaded it... */ if (releaseIt) { ReleaseResource(resource); } return TCL_OK; } else { Tcl_AppendStringsToObj(resultPtr, "could not load resource", (char *) NULL); return TCL_ERROR; } case RESOURCE_TYPES: if (!((objc == 2) || (objc == 3))) { Tcl_WrongNumArgs(interp, 2, objv, "?resourceRef?"); return TCL_ERROR; } if (objc == 3) { resourceRef = GetRsrcRefFromObj(objv[2], 1, "get types of", resultPtr); if (resourceRef == NULL) { return TCL_ERROR; } saveRef = CurResFile(); UseResFile((short) resourceRef->fileRef); limitSearch = true; } if (limitSearch) { count = Count1Types(); } else { count = CountTypes(); } for (i = 1; i <= count; i++) { if (limitSearch) { Get1IndType((ResType *) &rezType, i); } else { GetIndType((ResType *) &rezType, i); } objPtr = Tcl_NewOSTypeObj(rezType); result = Tcl_ListObjAppendElement(interp, resultPtr, objPtr); if (result != TCL_OK) { Tcl_DecrRefCount(objPtr); break; } } if (limitSearch) { UseResFile(saveRef); } return result; case RESOURCE_WRITE: if ((objc < 4) || (objc > 11)) { Tcl_WrongNumArgs(interp, 2, objv, "?-id resourceId? ?-name resourceName? ?-file resourceRef?\ ?-force? resourceType data"); return TCL_ERROR; } i = 2; gotInt = false; resourceId = NULL; limitSearch = false; force = 0; while (i < (objc - 2)) { if (Tcl_GetIndexFromObj(interp, objv[i], writeSwitches, "switch", 0, &index) != TCL_OK) { return TCL_ERROR; } switch (index) { case RESOURCE_WRITE_ID: if (Tcl_GetLongFromObj(interp, objv[i+1], &rsrcId) != TCL_OK) { return TCL_ERROR; } gotInt = true; i += 2; break; case RESOURCE_WRITE_NAME: resourceId = Tcl_GetStringFromObj(objv[i+1], &length); strcpy((char *) theName, resourceId); resourceId = (char *) theName; c2pstr(resourceId); i += 2; break; case RESOURCE_WRITE_FILE: resourceRef = GetRsrcRefFromObj(objv[i+1], 0, "write to", resultPtr); if (resourceRef == NULL) { return TCL_ERROR; } limitSearch = true; i += 2; break; case RESOURCE_FORCE: force = 1; i += 1; break; } } if (Tcl_GetOSTypeFromObj(interp, objv[i], &rezType) != TCL_OK) { return TCL_ERROR; } stringPtr = (char *) Tcl_GetByteArrayFromObj(objv[i+1], &length); if (gotInt == false) { rsrcId = UniqueID(rezType); } if (resourceId == NULL) { resourceId = (char *) "\p"; } if (limitSearch) { saveRef = CurResFile(); UseResFile((short) resourceRef->fileRef); } /* * If we are adding the resource by number, then we must make sure * there is not already a resource of that number. We are not going * load it here, since we want to detect whether we loaded it or * not. Remember that releasing some resources in particular menu * related ones, can be fatal. */ if (gotInt == true) { SetResLoad(false); resource = Get1Resource(rezType,rsrcId); SetResLoad(true); } if (resource == NULL) { /* * We get into this branch either if there was not already a * resource of this type & id, or the id was not specified. */ resource = NewHandle(length); if (resource == NULL) { resource = NewHandleSys(length); if (resource == NULL) { panic("could not allocate memory to write resource"); } } HLock(resource); memcpy(*resource, stringPtr, length); HUnlock(resource); AddResource(resource, rezType, (short) rsrcId, (StringPtr) resourceId); releaseIt = 1; } else { /* * We got here because there was a resource of this type * & ID in the file. */ if (*resource == NULL) { releaseIt = 1; } else { releaseIt = 0; } if (!force) { /* *We only overwrite extant resources * when the -force flag has been set. */ sprintf(errbuf,"%d", rsrcId); Tcl_AppendStringsToObj(resultPtr, "the resource ", errbuf, " already exists, use \"-force\"", " to overwrite it.", (char *) NULL); result = TCL_ERROR; goto writeDone; } else if (GetResAttrs(resource) & resProtected) { /* * * Next, check to see if it is protected... */ sprintf(errbuf,"%d", rsrcId); Tcl_AppendStringsToObj(resultPtr, "could not write resource id ", errbuf, " of type ", Tcl_GetStringFromObj(objv[i],&length), ", it was protected.",(char *) NULL); result = TCL_ERROR; goto writeDone; } else { /* * Be careful, the resource might already be in memory * if something else loaded it. */ if (*resource == 0) { LoadResource(resource); err = ResError(); if (err != noErr) { sprintf(errbuf,"%d", rsrcId); Tcl_AppendStringsToObj(resultPtr, "error loading resource ", errbuf, " of type ", Tcl_GetStringFromObj(objv[i],&length), " to overwrite it", (char *) NULL); goto writeDone; } } SetHandleSize(resource, length); if ( MemError() != noErr ) { panic("could not allocate memory to write resource"); } HLock(resource); memcpy(*resource, stringPtr, length); HUnlock(resource); ChangedResource(resource); /* * We also may have changed the name... */ SetResInfo(resource, rsrcId, (StringPtr) resourceId); } } err = ResError(); if (err != noErr) { Tcl_AppendStringsToObj(resultPtr, "error adding resource to resource map", (char *) NULL); result = TCL_ERROR; goto writeDone; } WriteResource(resource); err = ResError(); if (err != noErr) { Tcl_AppendStringsToObj(resultPtr, "error writing resource to disk", (char *) NULL); result = TCL_ERROR;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -