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.You are not allowed to attach a file to this page.