compress/decompress on OS X

Rob Cozens rcozens at pon.net
Wed Nov 3 14:35:54 EST 2004


>I'm trying to figure out a way to compress a Mac OS X application, 
>put in on an HTTP server, and have Revolution download that file and 
>decompress it.
>
>I haven't had luck with Rev's compress/decompress calls, due to OS 
>X's resource fork issues.  Did you ever find a solution?

Hi Rob,

My solution (from Serendipity Library & called by SDB Utilities and 
SDB Tools) is below; BUT it is a single-file solution:

on SDBCompressFile -- 3 Mar 04:RCC
   put sdbMessage(sdbCompressFileMenuItem) into compressFile
   put (the platform is "MacOS") into runningMacOS
   set the itemDelimiter to "/"
   put empty into lastSourceFolder
   put empty into lastDestinationFolder
   repeat
     answer file sdbMessage(sdbCompressFilePrompt) with lastSourceFolder
     play audioClip "click.au"
     if it is empty then exit SDBCompressFile
     put it into sourceFile
     put (item 1 to -2 of it)&"/" into lastSourceFolder
     put sourceFile&".sgz" into compressedFile
     put URL ("binfile:"&sourceFile) into sourceData
     if runningMacOS then put URL ("resfile:"&sourceFile) into sourceResource
     else put empty into sourceResource
     get sgzFooter(it)
     set the itemDelimiter to comma
     if the number of items of it < 2 then
       put length(sourceData) into item 2 of it
       put "????????" into item 11 of it
     end if
     put numToChar(29)&it into dataSuffix
     if sourceResource is empty then put 
compress(sourceData&dataSuffix) into compressedData
     else put compress(sourceData&sourceResource&dataSuffix) into compressedData
     get the result
     if it is not empty then
       beep
       answer error it with sdbMessage(sdbOKTranslated)
       play audioClip "click.au"
       exit SDBCompressFile
     end if
     put (runningMacOS and char 1 of the systemVersion > "6") into classicMac
     put sdbMessage(sdbSaveCompressedPrompt) into filePrompt
     if classicMac then
       set the itemDelimiter to "/"
       get item -1 of compressedFile
       repeat while length(it) > 31
         delete char -5 of it
       end repeat
       put it into item -1 of compressedFile
       put space&sdbMessage(sdbShortFileNamePrompt) after filePrompt
     else put ":" after filePrompt
     if lastDestinationFolder is empty then ask file filePrompt with 
compressedFile
     else ask file filePrompt with (lastDestinationFolder&(item -1 of 
compressedFile))
     play audioClip "click.au"
     if it is empty then exit SDBCompressFile
     put it into compressedFile
     put (item 1 to -2 of compressedFile)&"/" into lastDestinationFolder
     if char -4 to -1 of compressedFile is not ".sgz" then put ".sgz" 
after compressedFile
     if classicMac then
       get item -1 of compressedFile
       repeat while length(it) > 31
         delete char -5 of it
       end repeat
       put it into item -1 of compressedFile
     end if
     put "binfile:" before compressedFile
     put the fileType into savedType
     set the fileType to "sDIPsdb2"
     put compressedData into URL compressedFile
     set the fileType to savedFileType
     if the result is not empty then
       beep
       answer error sdbMessage(sdbFileWriteError) with 
sdbMessage(sdbOKTranslated)
     else answer information sdbMessage(sdbCompressionConfirmation) 
with compressFile or sdbMessage(sdbQuitToolTip)
     play audioClip "click.au"
     if it is not compressFile then exit repeat
   end repeat
end SDBCompressFile

function sgzFooter fullFileName
   set the itemDelimiter to "/"
   put item -1 of fullFileName into shortFileName
   put item 1 to -2 of fullFileName into filePath
   put the defaultFolder into savedDefaultFolder
   set the defaultFolder to filePath
   put the detailed files into folderContents
   set the defaultFolder to savedDefaultFolder
   set the itemDelimiter to comma
   repeat for each line fileEntry in folderContents
     if URLDecode(item 1 of fileEntry) <> shortFileName then next repeat
     put fileEntry into returnFooter
     exit repeat
   end repeat
   if the platform is "MacOS" then return returnFooter
   switch (char -4 to -1 of fullFileName)
   case ".rev"
     put "revoRSTK" into item 11 of returnFooter
     break
   case ".txt"
     put "ttxtTEXT" into item 11 of returnFooter
     break
   default
     if char -3 to -1 of fullFileName = ".mc" then put "MCRDMSTK" into 
item 11 of returnFooter
     else put "????????" into item 11 of returnFooter
   end switch
   return returnFooter
end sgzFooter

on SDBExpandFile -- 3 Mar 04:RCC
   put (the platform is "MacOS") into runningMacOS
   set the itemDelimiter to "/"
   put empty into lastSourceFolder
   put empty into lastDestinationFolder
   put sdbMessage(sdbExpandFileMenuItem) into expandFile
   repeat
     switch the platform
     case "MacOS"
       answer file sdbMessage(sdbExpandFilePrompt) with 
lastSourceFolder of type "sdb2"
       play audioClip "click.au"
       break
     case "Win32"
       answer file sdbMessage(sdbExpandFilePrompt) with 
lastSourceFolder with filter "Serendipity GZIP" & return & "*.sgz"
       play audioClip "click.au"
       break
     default
       answer file sdbMessage(sdbExpandFilePrompt) with 
lastSourceFolder with filter "*.sgz"
       play audioClip "click.au"
     end switch
     if it is empty then exit SDBExpandFile
     put (item 1 to -2 of it)&"/" into lastSourceFolder
     put char 1 to -5 of it into expandedFile
     put "binfile:"&it into compressedFile
     put decompress(URL compressedFile) into expandedData
     get the result
     if it is not empty then
       beep
       answer error it with sdbMessage(sdbOKTranslated)
       exit SDBExpandFile
     end if
     put numToChar(29) into groupSeparator
     put empty into expandedResource
     set the itemDelimiter to comma
     repeat with x = length(expandedData) down to 1
       get char x of expandedData
       if it is groupSeparator then
         put char (x+1) to -1 of expandedData into recordFooter
         put URLDecode(item 1 of recordFooter) into originalFileName
         put item 2 of recordFooter into dataForkBytes
         put item 11 of recordFooter into compressedFilesType
         delete char x to -1 of expandedData
         exit repeat
       end if
     end repeat
     if resourceForkBytes <> 0 then
       if not runningMacOS then
         beep
         answer error sdbMessage(sdbResourceForkError) with 
sdbMessage(sdbOKTranslated)
         exit SDBExpandFile
       else
         put dataForkBytes+1 into firstResourceChar
         put char firstResourceChar to -1 of expandedData into expandedResource
         delete char firstResourceChar to -1 of expandedData
       end if
     else put empty into expandedResource
     put (runningMacOS and char 1 of the systemVersion > "6") into classicMac
     put sdbMessage(sdbSaveExpandedPrompt) into filePrompt
     set the itemDelimiter to "/"
     put originalFileName into item -1 of expandedFile
     if classicMac then put space&sdbMessage(sdbShortFileNamePrompt) 
after filePrompt
     else put ":" after filePrompt
     if lastDestinationFolder is empty then ask file filePrompt with 
expandedFile
     else ask file filePrompt with (lastDestinationFolder&(item -1 of 
expandedFile))
     play audioClip "click.au"
     if it is empty then exit SDBExpandFile
     put it into expandedFile
     put (item 1 to -2 of expandedFile)&"/" into lastDestinationFolder
     if classicMac then
       get item -1 of expandedFile
       repeat while length(it) > 31
         delete char -1 of it
       end repeat
       put it into item -1 of expandedFile
     end if
     put the fileType into savedType
     if runningMacOS and compressedFilesType is "0" then
       mouseTrapOn
       ask question sdbmessage(sdbCreatorAndTypePrompt) with "ttxtTEXT"
       mouseTrapOff
       if length(it) <> 8 then get "ttxtTEXT"
       put it into compressedFilesType
     end if
     set the fileType to compressedFilesType
     put expandedData into URL ("binfile:"&expandedFile)
     if the result is not empty then
       beep
       answer error sdbMessage(sdbFileWriteError) with 
sdbMessage(sdbOKTranslated)
     else
       if expandedResource is not empty then
         put expandedResource into URL ("resfile:"&expandedFile)
         if the result is not empty then
           beep
           answer error sdbMessage(sdbFileWriteError) with 
sdbMessage(sdbOKTranslated)
         else answer information sdbMessage(sdbExpansionConfirmation) 
with  expandFile or sdbMessage(sdbQuitToolTip)
       else answer information sdbMessage(sdbExpansionConfirmation) 
with expandFile or sdbMessage(sdbQuitToolTip)
     end if
     play audioClip "click.au"
     set the fileType to savedFileType
     if it is not expandFile then exit repeat
   end repeat
end SDBExpandFile

What is needed is a solution that uses the Rev example function, 
directoryWalk to list the subordinate files & folders, a window to 
present them to the user for inclusion/exclusion & build the archive 
plus support decompression at the destination.  I believe the best 
design would incorporate a stack structure (eg one card per folder 
with links to the superior folder & all subordinate folders and a 
field listing the individual files.  The files could be individually 
compressed using SDBCompressFile and stored in the stack as card 
custom properties.  Encryption could be incorporated at the stack 
level.).
-- 
Rob Cozens, Staff Conservator
Mendonoma Marine Life Conservancy
P.O. Box 217
Manchester, CA 95459-0217
(707) 895-2584

"Promoting a healthy and bountiful offshore environment."


More information about the use-livecode mailing list