{ File: dpMisc.inc.p Written by: Nick Kledzik Copyright: © 1989-1990 by Apple Computer, Inc., all rights reserved. This file is used in these builds: BigBang Change History (most recent first): <13> 11/26/90 ngk Add warning handlers FailNonWrn and IgnoreWrn. Moved dp_GetCurrentAppRefNum to dpMisc.a <12> 9/13/90 ngk Changed file type for edition files to be all lowercase. <11> 7/16/90 RLC Change GetAppSignature routine to set info.processAppSpec to NIL instead of .processFileName. <10> 7/2/90 ngk Added IsEditionFile. <9> 5/31/90 ngk Changed em globals from a handle to a pointer. <8> 4/7/90 ngk Add dynamic array. Add new failure handlers. <7> 3/10/90 ngk Removed GetStateAndLock and RestoreState. Added dpSameBytes. <6> 3/4/90 ngk Fix bug in calling GetProcessInformation with setting up processInfoLength field. <5> 2/25/90 ngk Use SameProcess in dp_GetCurrentAppRefNum instead of comparing bits. Changed GetCurrentAppSignature to GetAppSignature. <4> 2/4/90 ngk Removed Desktop database routines <3> 1/8/90 ngk renamed dp_GetCurrentAppRefNum <2> 1/6/90 ngk Convert to BBS To Do: } { the following are actually in dpMisc.a } PROCEDURE UnSignedDivide; EXTERNAL; PROCEDURE UnSignedMultiply; EXTERNAL; FUNCTION dpGetGlobalsLocation; EXTERNAL; PROCEDURE dpSetCurrentAppRefNum(app: AppRefNum); EXTERNAL; FUNCTION dp_GetCurrentAppRefNum(VAR app: AppRefNum): OSErr; EXTERNAL; FUNCTION dp_CallEditionOpenerProc; EXTERNAL; FUNCTION dp_CallFormatIOProc; EXTERNAL; PROCEDURE FailOSErr; EXTERNAL; FUNCTION IsFailure; EXTERNAL; {------------- GetAppSignature -------------} FUNCTION GetAppSignature(PSN: ProcessSerialNumber; VAR signature: OSType): OSErr; VAR info: ProcessInfoRec; BEGIN info.processInfoLength := SizeOf(info); info.processName := NIL; info.processAppSpec := NIL; {info.processFileName := NIL; This was the old wayÉ} GetAppSignature := GetProcessInformation(PSN, info); signature := info.processSignature; END; { GetAppSignature } {------------- RemoveAppsGlobals -------------} PROCEDURE RemoveAppsGlobals(whichApp: AppRefNum); { called only by dp_QuitEditionPack } VAR prevAppGlobal: PerAppGlobalsHandle; nextAppGlobal: PerAppGlobalsHandle; globals: EdtnMgrGlobalsPtr; BEGIN globals := dpGetGlobalsLocation^; IF globals = NIL THEN EXIT(RemoveAppsGlobals); nextAppGlobal := globals^.perAppListHead; IF nextAppGlobal = NIL THEN EXIT(RemoveAppsGlobals); IF nextAppGlobal = whichApp THEN BEGIN { is first in list } dpGetGlobalsLocation^^.perAppListHead := nextAppGlobal^^.nextApp; END ELSE BEGIN { is not first in list } REPEAT prevAppGlobal := nextAppGlobal; nextAppGlobal := prevAppGlobal^^.nextApp; IF nextAppGlobal = NIL THEN BEGIN { cant find??? } {$IFC qCatchFailures } DebugStr('RemoveAppsGlobals: cannot find app'); {$ENDC } EXIT(RemoveAppsGlobals); END; UNTIL (nextAppGlobal = whichApp); { remove whichApp's globals from list } prevAppGlobal^^.nextApp := nextAppGlobal^^.nextApp; END; { clear switched expandmem global } dpSetCurrentAppRefNum(NIL); { actually dispose of app's global memory } DisposHandle(Handle(whichApp)); END; { RemoveAppsGlobals } {------------- dpSameBytes -------------} FUNCTION dpSameBytes(aPtr, bPtr: UNIV Ptr; byteCount: INTEGER): BOOLEAN; TYPE BytePtr = ^SignedByte; VAR i: INTEGER; BEGIN dpSameBytes := FALSE; FOR i := (byteCount - 1) DOWNTO 0 DO BEGIN IF BytePtr(aPtr)^ <> BytePtr(bPtr)^ THEN EXIT(dpSameBytes); aPtr := POINTER(ORD(aPtr) + 1); bPtr := POINTER(ORD(bPtr) + 1); END; dpSameBytes := TRUE; END; { dpSameBytes } {------------- dpNewDynamicArray -------------} FUNCTION dpNewDynamicArray(headerSize: Size; slotSize, initialSlots: INTEGER; FUNCTION MyNewHandle(amount: Size): Handle; VAR arrayH: DyanmicArrayHandle): OSErr; VAR initialSlotDataSize: Size; arrayP: DyanmicArrayPtr; BEGIN UnSignedMultiply(slotSize, initialSlots, initialSlotDataSize); arrayH := DyanmicArrayHandle(MyNewHandle(initialSlotDataSize + headerSize + SizeOf(DyanmicArray)) ); IF MemError = noErr THEN BEGIN arrayP := DyanmicArrayPtr( ORD(arrayH^) + headerSize ); arrayP^.slotSize := slotSize; arrayP^.maxSlots := initialSlots; arrayP^.lastUsedSlot := 0; dpNewDynamicArray := noErr; END ELSE BEGIN dpNewDynamicArray := MemError; END; END; { dpNewDynamicArray } {------------- dpFindElement -------------} FUNCTION dpFindElement(arrayH: DyanmicArrayHandle; headerSize: Size; FUNCTION Matches(anEntryIndex: INTEGER; anEntryPtr: UNIV Ptr): BOOLEAN; VAR foundIndex: INTEGER; VAR foundPtr: UNIV Ptr): BOOLEAN; VAR slotSize: INTEGER; elemPtr: Ptr; lastUsedSlot: INTEGER; i: INTEGER; BEGIN elemPtr := POINTER( ORD(arrayH^) + headerSize ); lastUsedSlot := DyanmicArrayPtr(elemPtr)^.lastUsedSlot; slotSize := DyanmicArrayPtr(elemPtr)^.slotSize; elemPtr := POINTER( ORD(arrayH^) + headerSize + SizeOf(DyanmicArray) ); FOR i := 1 TO lastUsedSlot DO BEGIN IF Matches(i, elemPtr) THEN BEGIN foundIndex := i; foundPtr := elemPtr; dpFindElement := TRUE; EXIT(dpFindElement); END; {if} elemPtr := POINTER( ORD(elemPtr) + slotSize ); END; {for} dpFindElement := FALSE; END; { dpFindElement } {------------- dpGetDynamicArrayEntry -------------} FUNCTION dpGetDynamicArrayEntry(arrayH: DyanmicArrayHandle; headerSize: Size; entryIndex: INTEGER; VAR entryPtr: UNIV Ptr): OSErr; VAR arrayP: DyanmicArrayPtr; newSlotOffset: Size; BEGIN arrayP := DyanmicArrayPtr( ORD(arrayH^) + headerSize ); UnSignedMultiply(arrayP^.slotSize, entryIndex-1, newSlotOffset); entryPtr := Ptr( ORD(arrayP) + SizeOf(DyanmicArray) + newSlotOffset ); dpGetDynamicArrayEntry := noErr; END; { dpGetDynamicArrayEntry } {------------- dpAddDynamicArrayEntry -------------} FUNCTION dpAddDynamicArrayEntry(arrayH: DyanmicArrayHandle; headerSize: Size; VAR entryIndex: INTEGER; VAR entryPtr: UNIV Ptr): OSErr; VAR slotToUse: INTEGER; maxSlots: INTEGER; slotSize: INTEGER; dummy: INTEGER; arrayP: DyanmicArrayPtr; newSlotDataSize:Size; newSlotOffset: Size; BEGIN arrayP := DyanmicArrayPtr( ORD(arrayH^) + headerSize ); slotSize := arrayP^.slotSize; slotToUse := arrayP^.lastUsedSlot + 1; maxSlots := arrayP^.maxSlots; IF slotToUse > maxSlots THEN BEGIN {$IFC qRangeCheck } { find how many slots there currently is } UnSignedDivide(GetHandleSize(Handle(arrayH)) - SizeOf(DyanmicArray) - headerSize, {numer} arrayP^.slotSize, {denom} maxSlots, {quotient} dummy); {remainder} IF dummy <> 0 THEN DebugStr('dpAddDynamicArrayEntry: bad dynamic record size'); {$ENDC } maxSlots := 2 * maxSlots; { double the number of slots } UnSignedMultiply(slotSize, maxSlots, newSlotDataSize); SetHandleSize(Handle(arrayH), headerSize + SizeOf(DyanmicArray) + newSlotDataSize); IF MemError <> noErr THEN BEGIN dpAddDynamicArrayEntry := MemError; EXIT(dpAddDynamicArrayEntry); END; {if} { re-derefence handle } arrayP := DyanmicArrayPtr( ORD(arrayH^) + headerSize ); arrayP^.maxSlots := maxSlots; END; {if} entryIndex := slotToUse; arrayP^.lastUsedSlot:= slotToUse; UnSignedMultiply(slotSize, slotToUse-1, newSlotOffset); entryPtr := Ptr( ORD(arrayP) + SizeOf(DyanmicArray) + newSlotOffset ); dpAddDynamicArrayEntry := noErr; END; { dpAddDynamicArrayEntry } {------------- FailNonWrn -------------} FUNCTION FailNonWrn(anErr: OSErr): OSErr; BEGIN IgnoreWrn(anErr); FailNonWrn := anErr; END; { FailNonWrn } {------------- IgnoreWrn -------------} PROCEDURE IgnoreWrn(anErr: OSErr); BEGIN IF (anErr <> noErr) {&} THEN IF (anErr <> containerNotFoundWrn) {&} THEN IF (anErr <> multiplePublisherWrn) {&} THEN IF (anErr <> notThePublisherWrn) {&} THEN IF (anErr <> userCanceledErr) THEN FailOSErr(anErr); END; { IgnoreWrn } {------------- Success -------------} PROCEDURE Success(VAR info: FailInfo); BEGIN {$IFC qRangeCheck} IF dpGetGlobalsLocation^^.failureHandler <> @info THEN DebugStr('Success: wrong FailInfo record'); {$ENDC} dpGetGlobalsLocation^^.failureHandler := info.nextInfo; END; { Success } {------------- IsEditionFile -------------} FUNCTION IsEditionFile(fdType: OSType): BOOLEAN; BEGIN IsEditionFile := TRUE; IF LONGINT(fdType) <> LONGINT(kPICTEditionFileType) {&} THEN IF LONGINT(fdType) <> LONGINT(kTEXTEditionFileType) {&} THEN IF LONGINT(fdType) <> LONGINT(ksndEditionFileType) {&} THEN IF LONGINT(fdType) <> LONGINT(kUnknownEditionFileType) {&} THEN IF LONGINT(fdType) <> LONGINT('edtP') { grandfather in this type } {&} THEN IF LONGINT(fdType) <> LONGINT('edtT') { grandfather in this type } {&} THEN IF LONGINT(fdType) <> LONGINT('publ') { grandfather in this type } THEN IsEditionFile := FALSE; END; { IsEditionFile }