
1 // 2 // Copyright (c) 2006, Brian Frank and Andy Frank 3 // Licensed under the Academic Free License version 3.0 4 // 5 // History: 6 // 18 Aug 06 Brian Frank Creation 7 // 8 9 ** 10 ** Zip is used to read/write compressed zip files and streams. Zip may be 11 ** used in three modes: 12 ** 13 ** 1. `Zip.open` is used to read a random access file and provides 14 ** access to the entire contents with the ability to read select 15 ** entries 16 ** 2. `Zip.read` is used to read a zip file from an input stream. 17 ** Each entry is pulled off the stream using `readNext` 18 ** 3. `Zip.write` is used to write a zip file to an output stream. 19 ** Each entry must is written to the stream using `writeNext` 20 ** 21 final class Zip 22 { 23 24 ////////////////////////////////////////////////////////////////////////// 25 // Construction 26 ////////////////////////////////////////////////////////////////////////// 27 28 ** 29 ** Open the specified file as a zip file for reading. If the specified 30 ** file does not exist, is not a valid file, or does not support random 31 ** access then throw IOErr. 32 ** 33 ** Example: 34 ** zip := Zip.open(File.make(`test.zip`)) 35 ** txt := zip.contents[`/notice.txt`].readAllStr 36 ** zip.close 37 ** 38 static Zip open(File file) 39 40 ** 41 ** Create a Zip used to read a zip file from the specified input stream. 42 ** 43 ** Example: 44 ** zip := Zip.read(File.make(`test.zip`).in) 45 ** File entry 46 ** while ((entry = zip.readNext()) != null) 47 ** { 48 ** data := entry.readAllBuf 49 ** echo("$entry size=$data.size") 50 ** } 51 ** zip.close 52 ** 53 static Zip read(InStream out) 54 55 ** 56 ** Create a Zip used to write a zip file to the specified output stream. 57 ** 58 ** Example: 59 ** zip := Zip.write(File.make(`test.zip`).out) 60 ** out := zip.writeNext(`/path/hello.txt`) 61 ** out.writeLine("hello zip") 62 ** out.close 63 ** zip.close 64 ** 65 static Zip write(OutStream out) 66 67 ** 68 ** Private constructor 69 ** 70 private new init(Uri uri) 71 72 ////////////////////////////////////////////////////////////////////////// 73 // Methods 74 ////////////////////////////////////////////////////////////////////////// 75 76 ** 77 ** Get the underlying file or null if using streams. 78 ** 79 File file() 80 81 ** 82 ** Return the contents of this zip as a map of Files. The Uri 83 ** keys will start with a slash and be relative to this zip file. 84 ** Return null if using streams. 85 ** 86 Uri:File contents() 87 88 ** 89 ** Read the next entry in the zip. Use the File's input stream to read the 90 ** file contents. Some file meta-data such as size may not be available. 91 ** Throw UnsupportedErr if not reading from an input stream. 92 ** 93 File readNext() 94 95 ** 96 ** Append a new file to the end of this zip file and return an OutStream 97 ** which may be used to write the file contents. The Uri must not contain 98 ** a query or fragment; it may optionally start with a slash. Closing the 99 ** OutStream will close only this file entry - use Zip.close() when finished 100 ** writing the entire zip file. Throw UnsupportedErr if zip is not writing 101 ** to an output stream. 102 ** 103 ** Examples: 104 ** out := zip.writeNext(`/docs/test.txt`) 105 ** out.writeLine("test") 106 ** out.close 107 ** 108 OutStream writeNext(Uri path, DateTime modifyTime := DateTime.now) 109 110 ** 111 ** Finish writing the contents of this zip file, but leave the underlying 112 ** OutStream open. This method is guaranteed to never throw an IOErr. 113 ** Return true if the stream was finished successfully or false if the 114 ** an error occurred. Throw UnsupportedErr if zip is not not writing to 115 ** an output stream. 116 ** 117 Bool finish() 118 119 ** 120 ** Close this zip file for reading and writing. If this zip file is 121 ** reading or writing an stream, then the underlying stream is also 122 ** closed. This method is guaranteed to never throw an IOErr. Return 123 ** true if the close was successful or false if the an error occurred. 124 ** 125 Bool close() 126 127 ** 128 ** If file is not null then return file.toStr, otherwise return 129 ** a suitable string representation. 130 ** 131 override Str toStr() 132 133 }