Attachment 'sfZip.v1.1.txt'

Download

   1 :Namespace sfZip
   2 
   3 ⍝ Version 1.0 December 2014
   4 
   5 ⍝ Version 1.1 September 2015
   6 ⍝      UnZipFile updated to open multiple items with decoding
   7 
   8     (⎕IO ⎕ML ⎕WX)←1 3 3    
   9 
  10     ∇ r←{nsOrKey}AplToZipFile fileName;case;dataStream;item;key;ns;sfDir;val;zipArchive;⎕USING
  11     ⍝ Function to Save and Retrieve to disk a Namespace of only characters.
  12     ⍝ The characters will be zipped using the Syncfusion ZipArchive library.
  13 
  14     ⍝ fileName = Fully qualified file name
  15     ⍝ nsOrKey  = Namespace to save under fileName
  16     ⍝          = Key of retrieved Namespace saved under fileName
  17     ⍝          = if empty returns the full Namespace saved under fileName
  18 
  19     ⍝ r ← 1 'text' or r ← 1 Namespace  ⍝ If successfull
  20     ⍝ r ← 0 (error description)        ⍝ If failure
  21      
  22       ⎕USING←0⍴⊂''  ⍝ To Speed up ⎕NC
  23      
  24     ⍝ Check for 'nsOrKey' and select the case:
  25       :If 0=⎕NC'nsOrKey'
  26         ⍝ nsOrKey does not exist. Read the fileName and return a NameSpace.
  27           case←'ReadFile'
  28      
  29       :ElseIf 9=⎕NC'nsOrKey'
  30         ⍝ nsOrKey is a NameSpace. Save it under FileName.
  31           ns←nsOrKey ⋄ case←'SaveNS'
  32      
  33       :ElseIf ' '=↑1↑0⍴nsOrKey
  34         ⍝ nsOrKey is character(s). Read the fileName and return only this Key.
  35           key←nsOrKey ⋄ case←'ReturnKey'
  36      
  37       :Else
  38           r←0 'AplToZipFile Error: Left Argument Must be a NameSpace or a Character Vector(Key)'
  39           →0
  40      
  41       :End
  42      
  43     ⍝ Required for all the cases.
  44       sfDir←'Syncfusion/4.5/' ⍝ Location of the Syncfusion librairies
  45       ⎕USING←('Syncfusion.Compression.Zip,',sfDir,'Syncfusion.Compression.Base.dll')'System.IO,mscorlib.dll' 'System,mscorlib.dll'
  46       zipArchive←⎕NEW ZipArchive
  47       zipArchive.DefaultCompressionLevel←zipArchive.DefaultCompressionLevel.BestSpeed ⍝ AboveNormal  BelowNormal  Best  BestSpeed  NoCompression  Normal
  48      
  49       :Select case
  50       :Case 'ReadFile'
  51         ⍝ Read the file and return a namespace
  52           :Trap 0
  53               zipArchive.Open(⊂,fileName)
  54               ns←⎕NS''
  55      
  56               :For key :In zipArchive.Items.ItemName
  57                   val←'UTF-8'⎕UCS zipArchive.Item[⊂,key].DataStream.ToArray
  58                   ⍎'ns.',(¯4↓key),'←val'
  59               :End
  60      
  61               zipArchive.Close ⋄ zipArchive.Dispose ⋄ zipArchive←⎕NULL
  62               r←1 ns
  63      
  64           :Else
  65               →ERROR
  66           :EndTrap
  67      
  68       :Case 'ReturnKey'
  69         ⍝ Return the value of only one Key.
  70           :Trap 0
  71               zipArchive.Open(⊂,fileName)
  72      
  73               :If (⊂key,'.txt')∊zipArchive.Items.ItemName
  74                 ⍝ key is valid.
  75                   val←'UTF-8'⎕UCS zipArchive.Item[⊂,key,'.txt'].DataStream.ToArray
  76                   zipArchive.Close ⋄ zipArchive.Dispose ⋄ zipArchive←⎕NULL
  77                   r←1 val
  78      
  79               :Else
  80                 ⍝ key does not exist.
  81                   r←0 'AplToZipFile: Invalid Key: ',∊key
  82                   zipArchive.Close ⋄ zipArchive.Dispose ⋄ zipArchive←⎕NULL
  83      
  84               :End
  85           :Else
  86               →ERROR
  87           :EndTrap
  88      
  89       :Case 'SaveNS'
  90         ⍝ Save the Namespace to the file name.
  91           :Trap 0
  92               :For key :In ns.⎕NL-2
  93                   val←ns.⍎key
  94                   dataStream←⎕NEW MemoryStream(⊂'UTF-8'⎕UCS val)
  95                   dataStream.Position←Convert.ToInt64 0   ⍝ Starting Position Set to 0
  96                   item←⎕NEW ZipArchiveItem(zipArchive(key,'.txt')dataStream 0 FileAttributes.Archive)
  97                   {}zipArchive.AddItem(item)
  98               :End
  99      
 100               zipArchive.Save(⊂,fileName)
 101               zipArchive.Close ⋄ zipArchive.Dispose ⋄ zipArchive←⎕NULL
 102               r←1
 103      
 104           :Else
 105               →ERROR
 106           :EndTrap
 107       :EndSelect
 108      
 109       →0
 110      
 111      ERROR:
 112      
 113     ⍝ Show the Error:
 114       :If 90=⎕EN
 115           r←0('AplToFile EXCEPTION: ',⎕EXCEPTION.Message)
 116       :Else
 117           r←0((1⊃⎕DM),': ',{(~(∧\' '=⍵)∨(⌽∧\⌽' '=⍵))/⍵}(2⊃⎕DM))
 118       :EndIf
 119      
 120      ⍝ Try to close zipArchive in case the error happened before closing it:
 121       :Trap 0
 122           zipArchive.Close ⋄ zipArchive.Dispose ⋄ zipArchive←⎕NULL
 123       :EndTrap
 124 
 125 
 126     ∇ r←ZipFile fileName;sfDir;zipArchive;⎕USING
 127     ⍝ Compress a file on disk using Syncfusion ZipArchive library.
 128     ⍝ The file will be saved at the same location with a .zip extension.
 129 
 130     ⍝ fileName = fully qualified file name with extension.
 131 
 132     ⍝ r ← 1                      ⍝ if successfull
 133     ⍝ r ← 0 (error description)  ⍝ if failure
 134      
 135     ⍝ Set ⎕USING for the Syncfusion library.
 136       sfDir←'Syncfusion/4.5/' ⍝ Location of the Syncfusion librairies
 137       ⎕USING←'Syncfusion.Compression.Zip,',sfDir,'Syncfusion.Compression.Base.dll'
 138      
 139       :Trap 0
 140         ⍝ Get a ZipArchive object
 141           zipArchive←⎕NEW ZipArchive
 142           zipArchive.DefaultCompressionLevel←zipArchive.DefaultCompressionLevel.Best
 143      
 144         ⍝ Add the file to the ZipArchive object
 145           {}zipArchive.AddFile(⊂,fileName)
 146      
 147         ⍝ Change the fileName extension to zip
 148           fileName←({⌽(a⍳'.')↓a←⌽⍵}fileName),'.zip'
 149      
 150         ⍝ Save the zipped file
 151           zipArchive.Save(⊂,fileName)
 152      
 153         ⍝ Clean-up
 154           zipArchive.Close ⋄ zipArchive.Dispose ⋄ zipArchive←⎕NULL
 155      
 156           r←1
 157      
 158       :Else
 159         ⍝ Show the Error:
 160           :If 90=⎕EN
 161               r←0('ZipFile EXCEPTION: ',⎕EXCEPTION.Message)
 162           :Else
 163               r←0((1⊃⎕DM),': ',{(~(∧\' '=⍵)∨(⌽∧\⌽' '=⍵))/⍵}(2⊃⎕DM))
 164           :EndIf
 165      
 166         ⍝ Try to close zipArchive in case the error happened before closing it:
 167           :Trap 0
 168               zipArchive.Close ⋄ zipArchive.Dispose ⋄ zipArchive←⎕NULL
 169           :EndTrap
 170      
 171       :EndTrap
 172 
 173 
 174     ∇ r←UnZipFile fileName;item;ns;sfDir;string;zipArchive;⎕USING
 175     ⍝ Decompress a file to Apl. Can be used to Unzip an Excel .xlsx or .ods file.
 176 
 177     ⍝ fileName = fully qualified file name with extension.
 178 
 179     ⍝ r ← 1 (namespace)          ⍝ if successfull
 180     ⍝ r ← 0 (error description)  ⍝ if failure
 181 
 182     ⍝ The namespace will have 4 properties:
 183     ⍝ Count:    Number of item(s) that are unzipped
 184     ⍝ ItemName: Name of the item(s) that are unzipped
 185     ⍝ Encoding: Encoding detected (UTF-32LE, UTF-32BE, UTF-8 W/Bom, UTF-16LE, UTF-16BE, UTF-8 WO/Bom, ASCII, DEFAULT)
 186     ⍝ Data:     decoded and unzip data
 187      
 188     ⍝ Set ⎕USING for the Syncfusion library.
 189       sfDir←'Syncfusion/4.5/' ⍝ Location of the Syncfusion librairies
 190       ⎕USING←'Syncfusion.Compression.Zip,',sfDir,'Syncfusion.Compression.Base.dll'
 191      
 192       :Trap 0
 193         ⍝ Get a ZipArchive object
 194           zipArchive←⎕NEW ZipArchive
 195      
 196         ⍝ Open the file with the ZipArchive object
 197           zipArchive.Open(⊂,fileName)
 198      
 199         ⍝ Prepare the nameless namespace
 200           ns←⎕NS''
 201           ns.Count←zipArchive.Count
 202      
 203           :If 0≠ns.Count
 204             ⍝ zipArchive is not empty.
 205               ns.ItemName←zipArchive.Items.ItemName
 206               ns.Data←''
 207               ns.Encoding←''
 208      
 209             ⍝ Decode each item. Find the encoding with the function EncodingDetector.
 210               :For item :In zipArchive.Items.DataStream.ToArray
 211                   :Trap 0
 212                       string←EncodingDetector item
 213                       ns.Encoding,←⊂1⊃string
 214                       ns.Data,←⊂2⊃string
 215                   :Else
 216                       ns.Encoding,←⊂'Unknow'
 217                       ns.Data,←⊂⎕UCS item
 218                   :EndTrap
 219      
 220               :EndFor
 221           :EndIf
 222      
 223         ⍝ Clean-up
 224           zipArchive.Close ⋄ zipArchive.Dispose ⋄ zipArchive←⎕NULL
 225      
 226           r←1 ns
 227      
 228       :Else
 229         ⍝ Show the Error:
 230           :If 90=⎕EN
 231               r←0('ZipFile EXCEPTION: ',⎕EXCEPTION.Message)
 232           :Else
 233               r←0((1⊃⎕DM),': ',{(~(∧\' '=⍵)∨(⌽∧\⌽' '=⍵))/⍵}(2⊃⎕DM))
 234           :EndIf
 235      
 236         ⍝ Try to close zipArchive in case the error happened before closing it:
 237           :Trap 0
 238               zipArchive.Close ⋄ zipArchive.Dispose ⋄ zipArchive←⎕NULL
 239           :EndTrap
 240       :EndTrap
 241 
 242 
 243     ∇ r←EncodingDetector BA;ENC;string;⎕USING
 244     ⍝ Returns The Encoding of a File And it's Content.
 245     ⍝ Detected From Their BOM: UTF-32LE, UTF-32BE, UTF-8, UTF-16LE, UTF-16BE.
 246     ⍝ An UTF-8 File Without BOM or ASCII Encoding Can Also be Detected.
 247 
 248     ⍝ BA = Byte array (numeric)
 249     ⍝ r = (ENCODING NAME) (decoded byte array as characters)
 250      
 251       ⎕USING←',mscorlib.dll'
 252      
 253      ⍝ DETECTION WITH THE BYTE ORDER MARK (BOM)
 254       :If 255 254 0 0≡4⍴BA      ⍝ 0xFF FE 00 00
 255         ⍝ UTF-32LE Detected
 256           ENC←⎕NEW System.Text.UTF32Encoding(0 1 1)
 257           string←ENC.GetString((⊂,BA),4,¯4+⍴BA)
 258           r←'UTF-32LE'string ⋄ →0
 259      
 260       :ElseIf 0 0 254 255≡4⍴BA  ⍝ 0x00 00 FE FF
 261         ⍝ UTF-32BE Detected
 262           ENC←⎕NEW System.Text.UTF32Encoding(1 1 1)
 263           string←ENC.GetString((⊂,BA),4,¯4+⍴BA)
 264           r←'UTF-32BE'string ⋄ →0
 265      
 266       :ElseIf 239 187 191≡3⍴BA  ⍝ 0xEF BB BF
 267         ⍝ UTF-8 Detected
 268           ENC←⎕NEW System.Text.UTF8Encoding(1 1)
 269           string←ENC.GetString((⊂,BA),3,¯3+⍴BA)
 270           r←'UTF-8 W/Bom'string ⋄ →0
 271      
 272       :ElseIf 255 254≡2⍴BA      ⍝ 0xFF FE
 273         ⍝ UTF-16LE Detected
 274           ENC←⎕NEW System.Text.UnicodeEncoding(0 1 1)
 275           string←ENC.GetString((⊂,BA),2,¯2+⍴BA)
 276           r←'UTF-16LE'string ⋄ →0
 277      
 278       :ElseIf 254 255≡2⍴BA      ⍝ 0xFE FF
 279         ⍝ UTF-16BE Detected
 280           ENC←⎕NEW System.Text.UnicodeEncoding(1 1 1)
 281           string←ENC.GetString((⊂,BA),2,¯2+⍴BA)
 282           r←'UTF-16BE'string ⋄ →0
 283       :End
 284      
 285     ⍝ 0xFE and 0xFF not permitted for UTF-8
 286       →(∨/254 255∊BA)/ASCII
 287      
 288     ⍝ If there is no BOM the only way to test for UTF-8 is to try to Decode
 289     ⍝ and verify if there is an error or not doing so.
 290       :Trap 0
 291           string←'UTF-8'⎕UCS BA
 292           r←'UTF-8 WO/BOM'string ⋄ →0
 293       :End
 294      
 295      ASCII: ⍝ *** DECODE TEST FOR ASCII ***
 296       :If 1=∧/BA≤127
 297         ⍝ ASCII DETECTED
 298           ENC←⎕NEW System.Text.ASCIIEncoding
 299           string←ENC.GetString((⊂,BA),0,⍴BA)
 300           r←'ASCII'string ⋄ →0
 301       :End
 302      
 303     ⍝ When All The Other Test Fails, We Use Then The Default Page of The Computer
 304     ⍝ This  may be incorrect if the file is send from a computer that has a different
 305     ⍝ default encoding of the receiving computer.
 306       ENC←System.Text.Encoding
 307       string←ENC.Default.GetString((⊂,BA),0,⍴BA)
 308       r←'DEFAULT'string
 309 
 310 
 311     ∇ zipString←ZipText string;dataStream;item;outStream;sfDir;zipArchive;⎕USING
 312     ⍝ Compress a vector of character using Syncfusion ZipArchive library.
 313      
 314     ⍝ Set ⎕USING for the Syncfusion dll.
 315       sfDir←'Syncfusion/4.5/' ⍝ Location of the Syncfusion librairies
 316       ⎕USING←('Syncfusion.Compression.Zip,',sfDir,'Syncfusion.Compression.Base.dll')'System.IO,mscorlib.dll' 'System,mscorlib.dll'
 317      
 318     ⍝ Convert the APL character vector to a MemoryStream.
 319       dataStream←⎕NEW MemoryStream(⊂'UTF-8'⎕UCS string)
 320       dataStream.Position←Convert.ToInt64 0   ⍝ Set starting position to 0
 321      
 322     ⍝ Get a ZipArchive object
 323       zipArchive←⎕NEW ZipArchive
 324       zipArchive.DefaultCompressionLevel←zipArchive.DefaultCompressionLevel.Best
 325      
 326     ⍝ Add a ZipArchiveItem to ZipArchive
 327       item←⎕NEW ZipArchiveItem(zipArchive'dir'dataStream 0 FileAttributes.Archive)
 328       {}zipArchive.AddItem(item)
 329      
 330     ⍝ Return the Compress character vector.
 331       outStream←⎕NEW MemoryStream
 332       zipArchive.Save(outStream 0)
 333       zipString←⎕UCS outStream.ToArray
 334      
 335     ⍝ Clean-up.
 336       dataStream.Close ⋄ dataStream.Dispose ⋄ dataStream←⎕NULL
 337       outStream.Close ⋄ outStream.Dispose ⋄ outStream←⎕NULL
 338       zipArchive.Close ⋄ zipArchive.Dispose ⋄ zipArchive←⎕NULL
 339 
 340 
 341 
 342     ∇ string←UnZipText zipString;dataStream;sfDir;zipArchive;⎕USING
 343     ⍝ Decompress a string obtained from ZipCompressText
 344      
 345     ⍝ Set ⎕USING for the Syncfusion dll.
 346       sfDir←'Syncfusion/4.5/' ⍝ Location of the Syncfusion librairies
 347       ⎕USING←('Syncfusion.Compression.Zip,',sfDir,'Syncfusion.Compression.Base.dll')'System.IO,mscorlib.dll'
 348      
 349     ⍝ Save the compressed string to a MemoryStream
 350       dataStream←⎕NEW MemoryStream(⊂⎕UCS zipString)
 351      
 352     ⍝ Decompress the MemoryStream and return result.
 353       zipArchive←⎕NEW ZipArchive
 354       zipArchive.Open(dataStream 0)
 355       string←'UTF-8'⎕UCS zipArchive.Item[0].DataStream.ToArray
 356      
 357     ⍝ Clean-up.
 358       dataStream.Close ⋄ dataStream.Dispose ⋄ dataStream←⎕NULL
 359       zipArchive.Close ⋄ zipArchive.Dispose ⋄ zipArchive←⎕NULL
 360 
 361 
 362 :EndNamespace

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2015-01-27 14:26:37, 9.7 KB) [[attachment:sfZip.v1.0.txt]]
  • [get | view] (2015-09-18 19:35:59, 13.6 KB) [[attachment:sfZip.v1.1.txt]]
 All files | Selected Files: delete move to page

You are not allowed to attach a file to this page.