├── .gitignore ├── README.md ├── index.html ├── js ├── wp2md.js ├── bsp.js ├── to-markdown.js └── filereader.js ├── style.css └── js-zip ├── jszip-load.js ├── jszip-inflate.js ├── jszip.js ├── LICENSE.markdown └── jszip-deflate.js /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | wordpress-to-markdown 2 | ===================== 3 | 4 | change the wordpress.xml to the format in markdown, which one farbox.com will understand it! -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Wordpress to Markdown - for FarBox.com 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 24 | 25 |
26 | WordPress、BlogBus, the backup .xml: 27 | 28 | 29 | 30 |
31 | 32 | DownLoad ZIP File 33 | 34 |
35 | 36 |
37 | 38 |
39 | 40 | 41 | 42 | 53 | 54 | 55 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /js/wp2md.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created with PyCharm. 3 | * User: hepochen 4 | * Date: 12-12-24 5 | * Time: 下午12:18 6 | * To change this template use File | Settings | File Templates. 7 | */ 8 | 9 | var zip_content; 10 | var entries = []; 11 | 12 | 13 | function zip_entries(entries){ 14 | zip_content = 'no'; // reset it first 15 | 16 | var zip = new JSZip(); 17 | 18 | entries.each(function(entry){ 19 | var filename = entry.title + '.md'; 20 | 21 | var content = 'Title: ' + entry.title + '\n\n'; 22 | content += 'Date: ' + entry.created + '\n\n'; 23 | if (entry.status!='public') content += 'Status: ' + entry.status + '\n\n'; 24 | if (entry.url && entry.url.indexOf('?')==-1) content += 'URL: ' + entry.url + '\n\n'; 25 | if (entry.tags && entry.tags.length) content += 'Tags: ' + entry.tags.join(' , ') + '\n\n'; 26 | 27 | content += entry.content; 28 | 29 | if (entry.category) { 30 | var folder = zip.folder(entry.category); 31 | folder.file(filename, content); 32 | } 33 | else{ 34 | zip.file(filename, content); 35 | } 36 | }); 37 | 38 | zip_content = zip.generate(); 39 | } 40 | 41 | function download_zip(){ 42 | if (zip_content && zip_content!='no' && entries.length){ 43 | $('file-input').value = ''; 44 | entries = []; 45 | var zip_content_cached = zip_content; 46 | zip_content = null; // clear it now 47 | location.href = "data:application/zip;base64," + zip_content_cached; 48 | } 49 | else if (entries.length && zip_content=='no'){ 50 | alert('waiting...') 51 | } 52 | else if(!zip_content){ 53 | alert('select a xml file to upload') 54 | } 55 | } 56 | 57 | 58 | var opts = { 59 | accept: false, 60 | readAsMap: { 61 | 'text/xml' : 'Text' 62 | }, 63 | readAsDefault: 'Text', 64 | on: { 65 | load: function(e, file) { 66 | // Native ProgressEvent 67 | content = e.target.result; 68 | content = content.replace(/[\s\S]*?<\/wp:comment>/gi, ''); 69 | bsp = new BSP(content); 70 | 71 | entries = bsp.format_entries(); 72 | 73 | zip_entries(entries); 74 | 75 | } 76 | } 77 | }; 78 | 79 | 80 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | 4 | hr { 5 | margin: 2.2em 0; 6 | border-top: 1px dashed #d0d0d0; 7 | border-bottom: 1px dashed #f9f9f9; 8 | } 9 | 10 | h1, h2, h3{ 11 | font-weight: normal; 12 | color: #222222; 13 | } 14 | 15 | h4{ 16 | color: #222; 17 | } 18 | 19 | h1{ 20 | line-height: 1.5em; 21 | margin-top: 1.2em; 22 | } 23 | 24 | 25 | 26 | a{ 27 | color: #333; 28 | text-decoration: none; 29 | } 30 | 31 | a:hover{ 32 | color: #E60900; 33 | } 34 | 35 | 36 | body { 37 | font-size: 14px; 38 | font-family: "Hiragino Sans GB", "Microsoft YaHei", sans-serif; 39 | color: #555555; 40 | width:1000px; 41 | margin: 0 auto; 42 | -webkit-text-size-adjust:none; 43 | } 44 | 45 | 46 | 47 | #head{ 48 | position: relative; 49 | } 50 | #head h1{ 51 | margin: 130px 0 30px 60px; 52 | letter-spacing: 5px; 53 | font-size: 32px; 54 | font-weight: bold; 55 | color:#111; 56 | text-align: center; 57 | margin-top: 80px; 58 | margin-bottom: 60px; 59 | } 60 | 61 | #head small{ 62 | font-size: 13px; 63 | font-weight: normal; 64 | } 65 | 66 | 67 | #content { 68 | text-align: center; 69 | margin-bottom: 120px; 70 | } 71 | 72 | #content a:hover { 73 | background: #1c87ff; 74 | color: #fff; 75 | text-decoration: none; 76 | } 77 | 78 | 79 | .button { 80 | display: inline-block; 81 | font-family: "Hiragino Sans GB", "Microsoft YaHei", sans-serif; 82 | font-size: 1.5em; 83 | letter-spacing: 1px; 84 | padding: 5px 30px; 85 | background: #E60900; 86 | color: #fff; 87 | margin: 55px 10px; 88 | border-radius: 5px; 89 | border: 1px solid #e6e6e6; 90 | } 91 | 92 | 93 | 94 | /*for template*/ 95 | 96 | 97 | 98 | input, select{ 99 | height:35px; 100 | width:250px; 101 | margin-right: 30px; 102 | font-size:18px; 103 | color:#1c87ff; 104 | padding: 2px 5px; 105 | } 106 | 107 | 108 | 109 | select{ 110 | border: 1px solid #ccc; 111 | color:#333; 112 | font-size: 14px; 113 | letter-spacing: 1px; 114 | } 115 | 116 | #console{ 117 | position: relative; 118 | } 119 | 120 | 121 | #file-input { 122 | font-size:14px; 123 | line-height: 14px; 124 | overflow: hidden; 125 | } 126 | 127 | 128 | 129 | 130 | /*footer starts*/ 131 | 132 | #footer{ 133 | margin-top: 100px; 134 | } 135 | 136 | #footer a{ 137 | color:#666; 138 | font-size: 0.8em ; 139 | } 140 | #footer a:hover{ 141 | color:#E60900; 142 | text-decoration: underline; 143 | } 144 | 145 | #footer .powered_by{ 146 | margin-bottom: 20px; 147 | text-align: center; 148 | font-size: 0.8em; 149 | } 150 | 151 | #footer .powered_by span{ 152 | font-size: 9px; 153 | padding: 0 15px; 154 | } 155 | 156 | 157 | 158 | 159 | #footer .footer_links{ 160 | margin-left: -35px; 161 | display: inline-block; 162 | line-height: 1; 163 | text-align: center; 164 | width: 100%; 165 | } 166 | 167 | 168 | #footer .footer_links li{ 169 | list-style-type: none; 170 | display: inline; 171 | margin: 0; 172 | padding: 0; 173 | } 174 | 175 | #footer .footer_links li a{ 176 | margin: 0 15px; 177 | } 178 | 179 | #footer .footer_links li:before { 180 | content: ' | ' ; 181 | color: #ccc; 182 | } 183 | #footer .footer_links li:first-child:before { 184 | content: " "; 185 | } 186 | 187 | -------------------------------------------------------------------------------- /js/bsp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by PyCharm. 3 | * User: hepochen 4 | * Date: 12-2-13 5 | * Time: 下午9:17 6 | * To change this template use File | Settings | File Templates. 7 | */ 8 | 9 | 10 | 11 | function ubbTohHml(str){ 12 | str = str.replace(/\[img\]([^\[]*)\[\/img\]/ig,''); 13 | str = str.replace(/\[url=([^\]]+)\]([^\[]+)\[\/url\]/ig, ''+'$2'+''); 14 | str = str.replace(/\[url\]([^\[]+)\[\/url\]/ig, ''+'$1'+''); 15 | return str; 16 | } 17 | 18 | function getValue(entry, key){ 19 | var value = ''; 20 | if (key.indexOf(":") != -1){ 21 | var key2 = key.split(':')[1]; 22 | var es = entry.getElementsByTagName(key2); 23 | for (var i=0; i/gmi,'$1').trim(); 69 | value = value.replace(/ /gi, ''); 70 | value = ubbTohHml(value); 71 | } 72 | 73 | return value 74 | } 75 | 76 | 77 | var BSP = new Class({ 78 | Implements: [Options, Events], 79 | 80 | initialize: function(raw_content){ 81 | this.dom = new Element('div', {'html': raw_content}); 82 | var parser=new DOMParser(); 83 | var doc = parser.parseFromString(raw_content, "text/xml"); 84 | 85 | this.entries = doc.getElementsByTagName('item');//for wordpress 86 | 87 | this.properties = { 88 | title:'title', 89 | url: 'link', 90 | created:'wp:post_date', 91 | content:'content:encoded', 92 | category:'category', 93 | tags: 'wp_tags', //特别定义的 94 | type:'wp:post_type', 95 | status:'wp:status', 96 | password:'wp:post_password' 97 | }; 98 | 99 | 100 | if (this.entries.length ==0) { 101 | this.entries = doc.getElementsByTagName('Log');//for blogbus 102 | this.properties ={ 103 | title:'Title', 104 | created:'LogDate', 105 | content:'Content', 106 | tags:'Tags', 107 | status:'Status', 108 | password:'AccessPassword' 109 | }; 110 | } 111 | 112 | if (this.entries.length ==0){ 113 | alert('这个备份文档格式错误,目前支持Wordpress、BlogCN、BlogBus') 114 | } 115 | 116 | }, 117 | 118 | 119 | format_entry: function(entry){ 120 | var formatted_e={}; 121 | var properties = this.properties; 122 | var ks = Object.keys(properties); 123 | ks.each(function(key){ 124 | var value = getValue(entry, properties[key]); 125 | if (key == 'content'){ 126 | value = toMarkdown(value); 127 | value = value.replace(/<\/?[^<]+?>/gi, ''); 128 | value = value.replace(/(?:[^\n])\n([^\n])/gi, '\n\n$1'); //单\n的转\n\n 129 | } 130 | else if(key == 'url'){ 131 | if (value.indexOf('?') == -1){ // not contain ? in url 132 | value = new Element('a',{'href':value}).pathname; 133 | } 134 | else{ //ignore 135 | value = ''; 136 | } 137 | } 138 | formatted_e[key] = value; 139 | }); 140 | if (formatted_e.content && formatted_e.type=='post'){//for wordpress 141 | formatted_e.category = formatted_e.category.replace(/(未分类)|(Uncategorized)/gi,''); 142 | if (formatted_e.status.test('draft')){ 143 | formatted_e.status = 'draft' 144 | } 145 | else if (formatted_e.status.test('private') || formatted_e.password){ 146 | formatted_e.status = 'private' 147 | } 148 | else{ 149 | formatted_e.status = 'public' 150 | } 151 | return formatted_e; 152 | } 153 | else if (formatted_e.content && !formatted_e.type){//for blogbus 154 | formatted_e.timezone = 'Etc/GMT-8'; 155 | if (formatted_e.status.test('0') || formatted_e.password){ 156 | formatted_e.status = 'private' 157 | } 158 | else{ 159 | formatted_e.status = 'public' 160 | } 161 | return formatted_e; 162 | } 163 | }, 164 | 165 | format_entries:function(){ 166 | var blog = this; 167 | var entries_formatted = []; 168 | for (var i=0; i]*)\\/?>' : '<' + elProperties.tag + '\\b([^>]*)>([\\s\\S]*?)<\\/' + elProperties.tag + '>', 89 | regex = new RegExp(pattern, 'gi'), 90 | markdown = ''; 91 | if(typeof elProperties.replacement === 'string') { 92 | markdown = html.replace(regex, elProperties.replacement); 93 | } 94 | else { 95 | markdown = html.replace(regex, function(str, p1, p2, p3) { 96 | return elProperties.replacement.call(this, str, p1, p2, p3); 97 | }); 98 | } 99 | return markdown; 100 | } 101 | 102 | function attrRegExp(attr) { 103 | return new RegExp(attr + '\\s*=\\s*["\']?([^"\']*)["\']?', 'i'); 104 | } 105 | 106 | // Pre code blocks 107 | 108 | string = string.replace(/]*>`([\s\S]*)`<\/pre>/gi, function(str, innerHTML) { 109 | innerHTML = innerHTML.replace(/^\t+/g, ' '); // convert tabs to spaces (you know it makes sense) 110 | innerHTML = innerHTML.replace(/\n/g, '\n '); 111 | return '\n\n ' + innerHTML + '\n'; 112 | }); 113 | 114 | // Lists 115 | 116 | // Escape numbers that could trigger an ol 117 | // If there are more than three spaces before the code, it would be in a pre tag 118 | // Make sure we are escaping the period not matching any character 119 | string = string.replace(/^(\s{0,3}\d+)\. /g, '$1\\. '); 120 | 121 | // Converts lists that have no child lists (of same type) first, then works it's way up 122 | var noChildrenRegex = /<(ul|ol)\b[^>]*>(?:(?!/gi; 123 | while(string.match(noChildrenRegex)) { 124 | string = string.replace(noChildrenRegex, function(str) { 125 | return replaceLists(str); 126 | }); 127 | } 128 | 129 | function replaceLists(html) { 130 | 131 | html = html.replace(/<(ul|ol)\b[^>]*>([\s\S]*?)<\/\1>/gi, function(str, listType, innerHTML) { 132 | var lis = innerHTML.split(''); 133 | lis.splice(lis.length - 1, 1); 134 | 135 | for(i = 0, len = lis.length; i < len; i++) { 136 | if(lis[i]) { 137 | var prefix = (listType === 'ol') ? (i + 1) + ". " : "* "; 138 | lis[i] = lis[i].replace(/\s*]*>([\s\S]*)/i, function(str, innerHTML) { 139 | 140 | innerHTML = innerHTML.replace(/^\s+/, ''); 141 | innerHTML = innerHTML.replace(/\n\n/g, '\n\n '); 142 | // indent nested lists 143 | innerHTML = innerHTML.replace(/\n([ ]*)+(\*|\d+\.) /g, '\n$1 $2 '); 144 | return prefix + innerHTML; 145 | }); 146 | } 147 | } 148 | return lis.join('\n'); 149 | }); 150 | return '\n\n' + html.replace(/[ \t]+\n|\s+$/g, ''); 151 | } 152 | 153 | // Blockquotes 154 | var deepest = /]*>((?:(?!/gi; 155 | while(string.match(deepest)) { 156 | string = string.replace(deepest, function(str) { 157 | return replaceBlockquotes(str); 158 | }); 159 | } 160 | 161 | function replaceBlockquotes(html) { 162 | html = html.replace(/]*>([\s\S]*?)<\/blockquote>/gi, function(str, inner) { 163 | inner = inner.replace(/^\s+|\s+$/g, ''); 164 | inner = cleanUp(inner); 165 | inner = inner.replace(/^/gm, '> '); 166 | inner = inner.replace(/^(>([ \t]{2,}>)+)/gm, '> >'); 167 | return inner; 168 | }); 169 | return html; 170 | } 171 | 172 | function cleanUp(string) { 173 | string = string.replace(/^[\t\r\n]+|[\t\r\n]+$/g, ''); // trim leading/trailing whitespace 174 | string = string.replace(/\n\s+\n/g, '\n\n'); 175 | string = string.replace(/\n{3,}/g, '\n\n'); // limit consecutive linebreaks to 2 176 | return string; 177 | } 178 | 179 | return cleanUp(string); 180 | }; 181 | 182 | if (typeof exports === 'object') { 183 | exports.toMarkdown = toMarkdown; 184 | } -------------------------------------------------------------------------------- /js/filereader.js: -------------------------------------------------------------------------------- 1 | /*! 2 | FileReader.js - v0.9 3 | A lightweight wrapper for common FileReader usage. 4 | Copyright 2012 Brian Grinstead - MIT License. 5 | See http://github.com/bgrins/filereader.js for documentation. 6 | */ 7 | 8 | (function(window, document) { 9 | 10 | var FileReader = window.FileReader; 11 | var FileReaderSyncSupport = false; 12 | var workerScript = "self.addEventListener('message', function(e) { var data=e.data; try { var reader = new FileReaderSync; postMessage({ result: reader[data.readAs](data.file), extra: data.extra, file: data.file})} catch(e){ postMessage({ result:'error', extra:data.extra, file:data.file}); } }, false);"; 13 | var syncDetectionScript = "self.addEventListener('message', function(e) { postMessage(!!FileReaderSync); }, false);"; 14 | var fileReaderEvents = ['loadstart', 'progress', 'load', 'abort', 'error', 'loadend']; 15 | 16 | var FileReaderJS = window.FileReaderJS = { 17 | enabled: false, 18 | setupInput: setupInput, 19 | setupDrop: setupDrop, 20 | setupClipboard: setupClipboard, 21 | sync: false, 22 | output: [], 23 | opts: { 24 | dragClass: "drag", 25 | accept: false, 26 | readAsDefault: 'BinaryString', 27 | readAsMap: { 28 | 'image/*': 'DataURL', 29 | 'text/*' : 'Text' 30 | }, 31 | on: { 32 | loadstart: noop, 33 | progress: noop, 34 | load: noop, 35 | abort: noop, 36 | error: noop, 37 | loadend: noop, 38 | skip: noop, 39 | groupstart: noop, 40 | groupend: noop, 41 | beforestart: noop 42 | } 43 | } 44 | }; 45 | 46 | // Setup jQuery plugin (if available) 47 | if (typeof(jQuery) !== "undefined") { 48 | jQuery.fn.fileReaderJS = function(opts) { 49 | return this.each(function() { 50 | if ($(this).is("input")) { 51 | setupInput(this, opts); 52 | } 53 | else { 54 | setupDrop(this, opts); 55 | } 56 | }); 57 | }; 58 | 59 | jQuery.fn.fileClipboard = function(opts) { 60 | return this.each(function() { 61 | setupClipboard(this, opts); 62 | }); 63 | }; 64 | } 65 | 66 | // Not all browsers support the FileReader interface. Return with the enabled bit = false. 67 | if (!FileReader) { 68 | return; 69 | } 70 | 71 | // WorkerHelper is a little wrapper for generating web workers from strings 72 | var WorkerHelper = (function() { 73 | 74 | var URL = window.URL || window.webkitURL; 75 | var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder; 76 | 77 | // May need to get just the URL in case it is needed for things beyond just creating a worker. 78 | function getURL (script) { 79 | if (window.Worker && BlobBuilder && URL) { 80 | var bb = new BlobBuilder(); 81 | bb.append(script); 82 | return URL.createObjectURL(bb.getBlob()); 83 | } 84 | 85 | return null; 86 | } 87 | 88 | // If there is no need to revoke a URL later, or do anything fancy then just return the worker. 89 | function getWorker (script, onmessage) { 90 | var url = getURL(script); 91 | if (url) { 92 | var worker = new Worker(url); 93 | worker.onmessage = onmessage; 94 | return worker; 95 | } 96 | 97 | return null; 98 | } 99 | 100 | return { 101 | getURL: getURL, 102 | getWorker: getWorker 103 | }; 104 | 105 | })(); 106 | 107 | // setupClipboard: bind to clipboard events (intended for document.body) 108 | function setupClipboard(element, opts) { 109 | 110 | if (!FileReaderJS.enabled) { 111 | return; 112 | } 113 | var instanceOptions = extend(extend({}, FileReaderJS.opts), opts); 114 | 115 | element.addEventListener("paste", onpaste, false); 116 | 117 | function onpaste(e) { 118 | var files = []; 119 | var clipboardData = e.clipboardData || {}; 120 | var items = clipboardData.items || []; 121 | 122 | for (var i = 0; i < items.length; i++) { 123 | var file = items[i].getAsFile(); 124 | 125 | if (file) { 126 | 127 | // Create a fake file name for images from clipboard, since this data doesn't get sent 128 | var matches = new RegExp("/\(.*\)").exec(file.type); 129 | if (!file.name && matches) { 130 | var extension = matches[1]; 131 | file.name = "clipboard" + i + "." + extension; 132 | } 133 | 134 | files.push(file); 135 | } 136 | } 137 | 138 | if (files.length) { 139 | processFileList(e, files, instanceOptions); 140 | e.preventDefault(); 141 | e.stopPropagation(); 142 | } 143 | } 144 | } 145 | 146 | // setupInput: bind the 'change' event to an input[type=file] 147 | function setupInput(input, opts) { 148 | 149 | if (!FileReaderJS.enabled) { 150 | return; 151 | } 152 | var instanceOptions = extend(extend({}, FileReaderJS.opts), opts); 153 | 154 | input.addEventListener("change", inputChange, false); 155 | input.addEventListener("drop", inputDrop, false); 156 | 157 | function inputChange(e) { 158 | processFileList(e, input.files, instanceOptions); 159 | } 160 | 161 | function inputDrop(e) { 162 | e.stopPropagation(); 163 | e.preventDefault(); 164 | processFileList(e, e.dataTransfer.files, instanceOptions); 165 | } 166 | } 167 | 168 | // setupDrop: bind the 'drop' event for a DOM element 169 | function setupDrop(dropbox, opts) { 170 | 171 | if (!FileReaderJS.enabled) { 172 | return; 173 | } 174 | var instanceOptions = extend(extend({}, FileReaderJS.opts), opts); 175 | var dragClass = instanceOptions.dragClass; 176 | var initializedOnBody = false; 177 | 178 | // Bind drag events to the dropbox to add the class while dragging, and accept the drop data transfer. 179 | dropbox.addEventListener("dragenter", onlyWithFiles(dragenter), false); 180 | dropbox.addEventListener("dragleave", onlyWithFiles(dragleave), false); 181 | dropbox.addEventListener("dragover", onlyWithFiles(dragover), false); 182 | dropbox.addEventListener("drop", onlyWithFiles(drop), false); 183 | 184 | // Bind to body to prevent the dropbox events from firing when it was initialized on the page. 185 | document.body.addEventListener("dragstart", bodydragstart, true); 186 | document.body.addEventListener("dragend", bodydragend, true); 187 | document.body.addEventListener("drop", bodydrop, false); 188 | 189 | function bodydragend(e) { 190 | initializedOnBody = false; 191 | } 192 | 193 | function bodydragstart(e) { 194 | initializedOnBody = true; 195 | } 196 | 197 | function bodydrop(e) { 198 | if (e.dataTransfer.files && e.dataTransfer.files.length ){ 199 | e.stopPropagation(); 200 | e.preventDefault(); 201 | } 202 | } 203 | 204 | function onlyWithFiles(fn) { 205 | return function() { 206 | if (!initializedOnBody) { 207 | fn.apply(this, arguments); 208 | } 209 | }; 210 | } 211 | 212 | function drop(e) { 213 | e.stopPropagation(); 214 | e.preventDefault(); 215 | if (dragClass) { 216 | removeClass(dropbox, dragClass); 217 | } 218 | processFileList(e, e.dataTransfer.files, instanceOptions); 219 | } 220 | 221 | function dragenter(e) { 222 | e.stopPropagation(); 223 | e.preventDefault(); 224 | if (dragClass) { 225 | addClass(dropbox, dragClass); 226 | } 227 | } 228 | 229 | function dragleave(e) { 230 | if (dragClass) { 231 | removeClass(dropbox, dragClass); 232 | } 233 | } 234 | 235 | function dragover(e) { 236 | e.stopPropagation(); 237 | e.preventDefault(); 238 | if (dragClass) { 239 | addClass(dropbox, dragClass); 240 | } 241 | } 242 | } 243 | 244 | // setupCustomFileProperties: modify the file object with extra properties 245 | function setupCustomFileProperties(files, groupID) { 246 | for (var i = 0; i < files.length; i++) { 247 | var file = files[i]; 248 | file.extra = { 249 | nameNoExtension: file.name.substring(0, file.name.lastIndexOf('.')), 250 | extension: file.name.substring(file.name.lastIndexOf('.') + 1), 251 | fileID: i, 252 | uniqueID: getUniqueID(), 253 | groupID: groupID, 254 | prettySize: prettySize(file.size) 255 | }; 256 | } 257 | } 258 | 259 | // getReadAsMethod: return method name for 'readAs*' - http://www.w3.org/TR/FileAPI/#reading-a-file 260 | function getReadAsMethod(type, readAsMap, readAsDefault) { 261 | for (var r in readAsMap) { 262 | if (type.match(new RegExp(r))) { 263 | return 'readAs' + readAsMap[r]; 264 | } 265 | } 266 | return 'readAs' + readAsDefault; 267 | } 268 | 269 | // processFileList: read the files with FileReader, send off custom events. 270 | function processFileList(e, files, opts) { 271 | 272 | var filesLeft = files.length; 273 | var group = { 274 | groupID: getGroupID(), 275 | files: files, 276 | started: new Date() 277 | }; 278 | 279 | function groupEnd() { 280 | group.ended = new Date(); 281 | opts.on.groupend(group); 282 | } 283 | 284 | function groupFileDone() { 285 | if (--filesLeft === 0) { 286 | groupEnd(); 287 | } 288 | } 289 | 290 | FileReaderJS.output.push(group); 291 | setupCustomFileProperties(files, group.groupID); 292 | 293 | opts.on.groupstart(group); 294 | 295 | // No files in group - end immediately 296 | if (!files.length) { 297 | groupEnd(); 298 | return; 299 | } 300 | 301 | var sync = FileReaderJS.sync && FileReaderSyncSupport; 302 | var syncWorker; 303 | 304 | // Only initialize the synchronous worker if the option is enabled - to prevent the overhead 305 | if (sync) { 306 | syncWorker = WorkerHelper.getWorker(workerScript, function(e) { 307 | var file = e.data.file; 308 | var result = e.data.result; 309 | 310 | // Workers seem to lose the custom property on the file object. 311 | if (!file.extra) { 312 | file.extra = e.data.extra; 313 | } 314 | 315 | file.extra.ended = new Date(); 316 | 317 | // Call error or load event depending on success of the read from the worker. 318 | opts.on[result === "error" ? "error" : "load"]({ target: { result: result } }, file); 319 | groupFileDone(); 320 | 321 | }); 322 | } 323 | 324 | Array.prototype.forEach.call(files, function(file) { 325 | 326 | file.extra.started = new Date(); 327 | 328 | if (opts.accept && !file.type.match(new RegExp(opts.accept))) { 329 | opts.on.skip(file); 330 | groupFileDone(); 331 | return; 332 | } 333 | 334 | if (opts.on.beforestart(file) === false) { 335 | opts.on.skip(file); 336 | groupFileDone(); 337 | return; 338 | } 339 | 340 | var readAs = getReadAsMethod(file.type, opts.readAsMap, opts.readAsDefault); 341 | 342 | if (sync && syncWorker) { 343 | syncWorker.postMessage({ 344 | file: file, 345 | extra: file.extra, 346 | readAs: readAs 347 | }); 348 | } 349 | else { 350 | 351 | var reader = new FileReader(); 352 | reader.originalEvent = e; 353 | 354 | fileReaderEvents.forEach(function(eventName) { 355 | reader['on' + eventName] = function(e) { 356 | if (eventName == 'load' || eventName == 'error') { 357 | file.extra.ended = new Date(); 358 | } 359 | opts.on[eventName](e, file); 360 | if (eventName == 'loadend') { 361 | groupFileDone(); 362 | } 363 | }; 364 | }); 365 | 366 | reader[readAs](file); 367 | } 368 | }); 369 | } 370 | 371 | // checkFileReaderSyncSupport: Create a temporary worker and see if FileReaderSync exists 372 | function checkFileReaderSyncSupport() { 373 | var worker = WorkerHelper.getWorker(syncDetectionScript, function(e) { 374 | FileReaderSyncSupport = e.data; 375 | }); 376 | 377 | if (worker) { 378 | worker.postMessage({}); 379 | } 380 | } 381 | 382 | // noop: do nothing 383 | function noop() { 384 | 385 | } 386 | 387 | // extend: used to make deep copies of options object 388 | function extend(destination, source) { 389 | for (var property in source) { 390 | if (source[property] && source[property].constructor && 391 | source[property].constructor === Object) { 392 | destination[property] = destination[property] || {}; 393 | arguments.callee(destination[property], source[property]); 394 | } 395 | else { 396 | destination[property] = source[property]; 397 | } 398 | } 399 | return destination; 400 | } 401 | 402 | // hasClass: does an element have the css class? 403 | function hasClass(el, name) { 404 | return new RegExp("(?:^|\\s+)" + name + "(?:\\s+|$)").test(el.className); 405 | } 406 | 407 | // addClass: add the css class for the element. 408 | function addClass(el, name) { 409 | if (!hasClass(el, name)) { 410 | el.className = el.className ? [el.className, name].join(' ') : name; 411 | } 412 | } 413 | 414 | // removeClass: remove the css class from the element. 415 | function removeClass(el, name) { 416 | if (hasClass(el, name)) { 417 | var c = el.className; 418 | el.className = c.replace(new RegExp("(?:^|\\s+)" + name + "(?:\\s+|$)", "g"), " ").replace(/^\s\s*/, '').replace(/\s\s*$/, ''); 419 | } 420 | } 421 | 422 | // prettySize: convert bytes to a more readable string. 423 | function prettySize(bytes) { 424 | var s = ['bytes', 'kb', 'MB', 'GB', 'TB', 'PB']; 425 | var e = Math.floor(Math.log(bytes)/Math.log(1024)); 426 | return (bytes/Math.pow(1024, Math.floor(e))).toFixed(2)+" "+s[e]; 427 | } 428 | 429 | // getGroupID: generate a unique int ID for groups. 430 | var getGroupID = (function(id) { 431 | return function() { 432 | return id++; 433 | }; 434 | })(0); 435 | 436 | // getUniqueID: generate a unique int ID for files 437 | var getUniqueID = (function(id) { 438 | return function() { 439 | return id++; 440 | }; 441 | })(0); 442 | 443 | // The interface is supported, bind the FileReaderJS callbacks 444 | FileReaderJS.enabled = true; 445 | 446 | })(this, document); -------------------------------------------------------------------------------- /js-zip/jszip-load.js: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | JSZip - A Javascript class for generating and reading zip files 4 | 5 | 6 | (c) 2011 David Duponchel 7 | Dual licenced under the MIT license or GPLv3. See LICENSE.markdown. 8 | 9 | **/ 10 | /*global JSZip,JSZipBase64 */ 11 | (function () { 12 | 13 | /** 14 | * Prettify a string read as binary. 15 | * @param {string} str the string to prettify. 16 | * @return {string} a pretty string. 17 | */ 18 | var pretty = function (str) { 19 | var res = '', code, i; 20 | for (i = 0; i < str.length; i++) 21 | { 22 | code = str.charCodeAt(i); 23 | res += '\\x' + (code < 10 ? "0" : "") + code.toString(16); 24 | } 25 | return res; 26 | }; 27 | 28 | /** 29 | * Find a compression registered in JSZip. 30 | * @param {string} compressionMethod the method magic to find. 31 | * @return {Object|null} the JSZip compression object, null if none found. 32 | */ 33 | var findCompression = function (compressionMethod) { 34 | for (var method in JSZip.compressions) 35 | { 36 | if (JSZip.compressions[method].magic === compressionMethod) 37 | { 38 | return JSZip.compressions[method]; 39 | } 40 | } 41 | return null; 42 | }; 43 | 44 | // class StreamReader {{{ 45 | /** 46 | * Read bytes from a stream. 47 | * @constructor 48 | * @param {string} stream the stream to read. 49 | */ 50 | function StreamReader(stream) { 51 | this.stream = stream; 52 | this.index = 0; 53 | } 54 | StreamReader.prototype = { 55 | /** 56 | * Check that the offset will not go too far. 57 | * @param {string} offset the additional offset to check. 58 | * @throws {Error} an Error if the offset is out of bounds. 59 | */ 60 | checkOffset : function (offset) 61 | { 62 | this.checkIndex(this.index + offset); 63 | }, 64 | /** 65 | * Check that the specifed index will not be too far. 66 | * @param {string} newIndex the index to check. 67 | * @throws {Error} an Error if the index is out of bounds. 68 | */ 69 | checkIndex : function (newIndex) 70 | { 71 | if (this.stream.length < newIndex || newIndex < 0) 72 | { 73 | throw new Error("End of stream reached (stream length = " + 74 | this.stream.length + ", asked index = " + 75 | (newIndex) + "). Corrupted zip ?"); 76 | } 77 | }, 78 | /** 79 | * Change the index. 80 | * @param {number} newIndex The new index. 81 | * @throws {Error} if the new index is out of the stream. 82 | */ 83 | setIndex : function (newIndex) 84 | { 85 | this.checkIndex(newIndex); 86 | this.index = newIndex; 87 | }, 88 | /** 89 | * Check if the end of the file has been reached. 90 | * @return {boolean} true if it is the case, false otherwise. 91 | */ 92 | eof : function () 93 | { 94 | return this.index >= this.stream.length; 95 | }, 96 | /** 97 | * Get the byte at the specified index. 98 | * @param {number} i the index to use. 99 | * @return {number} a byte. 100 | */ 101 | byteAt : function(i) 102 | { 103 | return this.stream.charCodeAt(i) & 0xff; 104 | }, 105 | /** 106 | * Get the next byte of this stream. 107 | * @return {string} the next byte. 108 | */ 109 | readByte : function () 110 | { 111 | this.checkOffset(1); 112 | return this.byteAt(1 + this.index++); 113 | }, 114 | /** 115 | * Get the next number with a given byte size. 116 | * @param {number} size the number of bytes to read. 117 | * @return {number} the corresponding number. 118 | */ 119 | readInt : function (size) 120 | { 121 | var result = 0, i; 122 | this.checkOffset(size); 123 | for(i = size - 1; i >= 0; i--) 124 | { 125 | result = (result << 8) + this.byteAt(this.index + i); 126 | } 127 | this.index += size; 128 | return result; 129 | }, 130 | /** 131 | * Get the next string with a given byte size. 132 | * @param {number} size the number of bytes to read. 133 | * @return {string} the corresponding string. 134 | */ 135 | readString : function (size) 136 | { 137 | var result = "", i, code; 138 | this.checkOffset(size); 139 | for(i = 0; i < size; i++) 140 | { 141 | code = this.byteAt(this.index + i); 142 | result += String.fromCharCode(code); 143 | } 144 | this.index += size; 145 | return result; 146 | }, 147 | /** 148 | * Get the next date. 149 | * @return {Date} the date. 150 | */ 151 | readDate : function () 152 | { 153 | var dostime = this.readInt(4); 154 | return new Date( 155 | ((dostime >> 25) & 0x7f) + 1980, // year 156 | ((dostime >> 21) & 0x0f) - 1, // month 157 | (dostime >> 16) & 0x1f, // day 158 | (dostime >> 11) & 0x1f, // hour 159 | (dostime >> 5) & 0x3f, // minute 160 | (dostime & 0x1f) << 1); // second 161 | } 162 | }; 163 | // }}} end of StreamReader 164 | 165 | // class ZipEntry {{{ 166 | /** 167 | * An entry in the zip file. 168 | * @constructor 169 | * @param {Object} options Options of the current file. 170 | * @param {Object} loadOptions Options for loading the stream. 171 | */ 172 | function ZipEntry(options, loadOptions) { 173 | this.options = options; 174 | this.loadOptions = loadOptions; 175 | } 176 | ZipEntry.prototype = { 177 | /** 178 | * say if the file is encrypted. 179 | * @return {boolean} true if the file is encrypted, false otherwise. 180 | */ 181 | isEncrypted : function () 182 | { 183 | // bit 1 is set 184 | return (this.bitFlag & 0x0001) === 0x0001; 185 | }, 186 | /** 187 | * say if the file has a data decriptor. 188 | * @return {boolean} true if the file has a data descriptor, false otherwise. 189 | */ 190 | hasDataDescriptor : function () 191 | { 192 | // bit 3 is set 193 | return (this.bitFlag & 0x0008) === 0x0008; 194 | }, 195 | /** 196 | * say if the file has utf-8 filename/comment. 197 | * @return {boolean} true if the filename/comment is in utf-8, false otherwise. 198 | */ 199 | useUTF8 : function () 200 | { 201 | // bit 11 is set 202 | return (this.bitFlag & 0x0800) === 0x0800; 203 | }, 204 | /** 205 | * say if the file is a zip64 file. 206 | * @return {boolean} true if the file is zip64, false otherwise. 207 | */ 208 | isZIP64 : function () 209 | { 210 | return this.options.zip64; 211 | }, 212 | /** 213 | * Read the local part header of a zip file and add the info in this object. 214 | * @param {StreamReader} reader the reader to use. 215 | */ 216 | readLocalPartHeader : function(reader) 217 | { 218 | // the signature has already been consumed 219 | this.versionNeeded = reader.readInt(2); 220 | this.bitFlag = reader.readInt(2); 221 | this.compressionMethod = reader.readString(2); 222 | this.date = reader.readDate(); 223 | this.crc32 = reader.readInt(4); 224 | this.compressedSize = reader.readInt(4); 225 | this.uncompressedSize = reader.readInt(4); 226 | this.fileNameLength = reader.readInt(2); 227 | this.extraFieldsLength = reader.readInt(2); 228 | 229 | if (this.isEncrypted()) 230 | { 231 | throw new Error("Encrypted zip are not supported"); 232 | } 233 | }, 234 | /** 235 | * Read the local part of a zip file and add the info in this object. 236 | * @param {StreamReader} reader the reader to use. 237 | */ 238 | readLocalPart : function(reader) 239 | { 240 | var compression; 241 | 242 | this.readLocalPartHeader(reader); 243 | 244 | this.fileName = reader.readString(this.fileNameLength); 245 | this.readExtraFields(reader); 246 | 247 | if (!this.hasDataDescriptor()) 248 | { 249 | // easy : we know the file length 250 | this.compressedFileData = reader.readString(this.compressedSize); 251 | } 252 | else 253 | { 254 | // hard way : find the data descriptor manually 255 | this.compressedFileData = this.findDataUntilDataDescriptor(reader); 256 | this.crc32 = reader.readInt(4); 257 | this.compressedSize = reader.readInt(this.isZIP64() ? 8 : 4); 258 | this.uncompressedSize = reader.readInt(this.isZIP64() ? 8 : 4); 259 | 260 | if (this.compressedFileData.length !== this.compressedSize) 261 | { 262 | throw new Error("Bug : data descriptor incorrectly read (size mismatch)"); 263 | } 264 | } 265 | this.uncompressedFileData = null; 266 | 267 | compression = findCompression(this.compressionMethod); 268 | if (compression === null) // no compression found 269 | { 270 | throw new Error("Corrupted zip : compression " + pretty(this.compressionMethod) + 271 | " unknown (inner file : " + this.fileName + ")"); 272 | } 273 | this.uncompressedFileData = compression.uncompress(this.compressedFileData); 274 | 275 | if (this.loadOptions.checkCRC32 && JSZip.prototype.crc32(this.uncompressedFileData) !== this.crc32) 276 | { 277 | throw new Error("Corrupted zip : CRC32 mismatch"); 278 | } 279 | 280 | if (this.useUTF8()) 281 | { 282 | this.fileName = JSZip.prototype.utf8decode(this.fileName); 283 | } 284 | }, 285 | 286 | /** 287 | * Read data until a data descriptor signature is found. 288 | * @param {StreamReader} reader the reader to use. 289 | */ 290 | findDataUntilDataDescriptor : function(reader) 291 | { 292 | var data = "", 293 | buffer = reader.readString(4), 294 | aByte; 295 | 296 | while(buffer !== JSZip.signature.DATA_DESCRIPTOR) 297 | { 298 | aByte = reader.readString(1); 299 | data += buffer.slice(0, 1); 300 | buffer = (buffer + aByte).slice(-4); 301 | } 302 | return data; 303 | }, 304 | /** 305 | * Read the central part of a zip file and add the info in this object. 306 | * @param {StreamReader} reader the reader to use. 307 | */ 308 | readCentralPart : function(reader) 309 | { 310 | this.versionMadeBy = reader.readString(2); 311 | 312 | this.readLocalPartHeader(reader); 313 | 314 | this.fileCommentLength = reader.readInt(2); 315 | this.diskNumberStart = reader.readInt(2); 316 | this.internalFileAttributes = reader.readInt(2); 317 | this.externalFileAttributes = reader.readInt(4); 318 | this.localHeaderOffset = reader.readInt(4); 319 | 320 | this.fileName = reader.readString(this.fileNameLength); 321 | this.readExtraFields(reader); 322 | this.fileComment = reader.readString(this.fileCommentLength); 323 | if (this.useUTF8()) 324 | { 325 | this.fileName = JSZip.prototype.utf8decode(this.fileName); 326 | this.fileComment = JSZip.prototype.utf8decode(this.fileComment); 327 | } 328 | 329 | // warning, this is true only for zip with madeBy == DOS (plateform dependent feature) 330 | this.dir = this.externalFileAttributes & 0x00000010 ? true : false; 331 | }, 332 | /** 333 | * Parse the ZIP64 extra field and merge the info in the current ZipEntry. 334 | * @param {StreamReader} reader the reader to use. 335 | */ 336 | parseZIP64ExtraField : function(reader) 337 | { 338 | // should be something, preparing the extra reader 339 | var extraReader = new StreamReader(this.extraFields[0x0001].value); 340 | if(this.uncompressedSize === -1) 341 | { 342 | this.uncompressedSize = extraReader.readInt(8); 343 | } 344 | if(this.compressedSize === -1) 345 | { 346 | this.compressedSize = extraReader.readInt(8); 347 | } 348 | if(this.localHeaderOffset === -1) 349 | { 350 | this.localHeaderOffset = extraReader.readInt(8); 351 | } 352 | if(this.diskNumberStart === -1) 353 | { 354 | this.diskNumberStart = extraReader.readInt(4); 355 | } 356 | }, 357 | /** 358 | * Read the central part of a zip file and add the info in this object. 359 | * @param {StreamReader} reader the reader to use. 360 | */ 361 | readExtraFields : function(reader) 362 | { 363 | var start = reader.index, 364 | extraFieldId, 365 | extraFieldLength, 366 | extraFieldValue; 367 | 368 | this.extraFields = this.extraFields || {}; 369 | 370 | while (reader.index < start + this.extraFieldsLength) 371 | { 372 | extraFieldId = reader.readInt(2); 373 | extraFieldLength = reader.readInt(2); 374 | extraFieldValue = reader.readString(extraFieldLength); 375 | 376 | this.extraFields[extraFieldId] = { 377 | id: extraFieldId, 378 | length: extraFieldLength, 379 | value: extraFieldValue 380 | }; 381 | } 382 | 383 | if(this.isZIP64() && this.extraFields[0x0001]) 384 | { 385 | this.parseZIP64ExtraField(reader); 386 | } 387 | } 388 | }; 389 | // }}} end of ZipEntry 390 | 391 | // class ZipEntries {{{ 392 | /** 393 | * All the entries in the zip file. 394 | * @constructor 395 | * @param {string} data the binary stream to load. 396 | * @param {Object} loadOptions Options for loading the stream. 397 | */ 398 | function ZipEntries(data, loadOptions) { 399 | this.files = []; 400 | this.loadOptions = loadOptions; 401 | if (data) { 402 | this.load(data); 403 | } 404 | } 405 | ZipEntries.prototype = { 406 | /** 407 | * Check that the reader is on the speficied signature. 408 | * @param {string} expectedSignature the expected signature. 409 | * @throws {Error} if it is an other signature. 410 | */ 411 | checkSignature : function(expectedSignature) 412 | { 413 | var signature = this.reader.readString(4); 414 | if (signature !== expectedSignature) 415 | { 416 | throw new Error("Corrupted zip or bug : unexpected signature " + 417 | "(" + pretty(signature) + ", expected " + pretty(expectedSignature) + ")"); 418 | } 419 | }, 420 | /** 421 | * Read the end of the central directory. 422 | */ 423 | readBlockEndOfCentral : function () 424 | { 425 | this.diskNumber = this.reader.readInt(2); 426 | this.diskWithCentralDirStart = this.reader.readInt(2); 427 | this.centralDirRecordsOnThisDisk = this.reader.readInt(2); 428 | this.centralDirRecords = this.reader.readInt(2); 429 | this.centralDirSize = this.reader.readInt(4); 430 | this.centralDirOffset = this.reader.readInt(4); 431 | 432 | this.zipCommentLength = this.reader.readInt(2); 433 | this.zipComment = this.reader.readString(this.zipCommentLength); 434 | }, 435 | /** 436 | * Read the end of the Zip 64 central directory. 437 | * Not merged with the method readEndOfCentral : 438 | * The end of central can coexist with its Zip64 brother, 439 | * I don't want to read the wrong number of bytes ! 440 | */ 441 | readBlockZip64EndOfCentral : function () 442 | { 443 | this.zip64EndOfCentralSize = this.reader.readInt(8); 444 | this.versionMadeBy = this.reader.readString(2); 445 | this.versionNeeded = this.reader.readInt(2); 446 | this.diskNumber = this.reader.readInt(4); 447 | this.diskWithCentralDirStart = this.reader.readInt(4); 448 | this.centralDirRecordsOnThisDisk = this.reader.readInt(8); 449 | this.centralDirRecords = this.reader.readInt(8); 450 | this.centralDirSize = this.reader.readInt(8); 451 | this.centralDirOffset = this.reader.readInt(8); 452 | 453 | this.zip64ExtensibleData = {}; 454 | var extraDataSize = this.zip64EndOfCentralSize - 44, 455 | index = 0, 456 | extraFieldId, 457 | extraFieldLength, 458 | extraFieldValue; 459 | while(index < extraDataSize) 460 | { 461 | extraFieldId = this.reader.readInt(2); 462 | extraFieldLength = this.reader.readInt(4); 463 | extraFieldValue = this.reader.readString(extraFieldLength); 464 | this.zip64ExtensibleData[extraFieldId] = { 465 | id: extraFieldId, 466 | length: extraFieldLength, 467 | value: extraFieldValue 468 | }; 469 | } 470 | }, 471 | /** 472 | * Read the end of the Zip 64 central directory locator. 473 | */ 474 | readBlockZip64EndOfCentralLocator : function () 475 | { 476 | this.diskWithZip64CentralDirStart = this.reader.readInt(4); 477 | this.relativeOffsetEndOfZip64CentralDir = this.reader.readInt(8); 478 | this.disksCount = this.reader.readInt(4); 479 | if (this.disksCount > 1) 480 | { 481 | throw new Error("Multi-volumes zip are not supported"); 482 | } 483 | }, 484 | /** 485 | * Read the local files, based on the offset read in the central part. 486 | */ 487 | readLocalFiles : function() 488 | { 489 | var i, file; 490 | for(i = 0; i < this.files.length; i++) 491 | { 492 | file = this.files[i]; 493 | this.reader.setIndex(file.localHeaderOffset); 494 | this.checkSignature(JSZip.signature.LOCAL_FILE_HEADER); 495 | file.readLocalPart(this.reader); 496 | } 497 | }, 498 | /** 499 | * Read the central directory. 500 | */ 501 | readCentralDir : function() 502 | { 503 | var file; 504 | 505 | this.reader.setIndex(this.centralDirOffset); 506 | while(this.reader.readString(4) === JSZip.signature.CENTRAL_FILE_HEADER) 507 | { 508 | file = new ZipEntry({ 509 | zip64: this.zip64 510 | }, this.loadOptions); 511 | file.readCentralPart(this.reader); 512 | this.files.push(file); 513 | } 514 | }, 515 | /** 516 | * Read the end of central directory. 517 | */ 518 | readEndOfCentral : function() 519 | { 520 | // zip 64 ? 521 | var offset = this.reader.stream.lastIndexOf(JSZip.signature.ZIP64_CENTRAL_DIRECTORY_LOCATOR); 522 | if (offset === -1) // nope 523 | { 524 | this.zip64 = false; 525 | offset = this.reader.stream.lastIndexOf(JSZip.signature.CENTRAL_DIRECTORY_END); 526 | if (offset === -1) 527 | { 528 | throw new Error("Corrupted zip : can't find end of central directory"); 529 | } 530 | 531 | this.reader.setIndex(offset); 532 | this.checkSignature(JSZip.signature.CENTRAL_DIRECTORY_END); 533 | this.readBlockEndOfCentral(); 534 | } 535 | else // zip 64 ! 536 | { 537 | this.zip64 = true; 538 | this.reader.setIndex(offset); 539 | this.checkSignature(JSZip.signature.ZIP64_CENTRAL_DIRECTORY_LOCATOR); 540 | this.readBlockZip64EndOfCentralLocator(); 541 | 542 | this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir); 543 | this.checkSignature(JSZip.signature.ZIP64_CENTRAL_DIRECTORY_END); 544 | this.readBlockZip64EndOfCentral(); 545 | } 546 | }, 547 | /** 548 | * Read a zip file and create ZipEntries. 549 | * @param {string} data the binary string representing a zip file. 550 | */ 551 | load : function(data) 552 | { 553 | this.reader = new StreamReader(data); 554 | 555 | this.readEndOfCentral(); 556 | this.readCentralDir(); 557 | this.readLocalFiles(); 558 | } 559 | }; 560 | // }}} end of ZipEntries 561 | 562 | /** 563 | * Implementation of the load method of JSZip. 564 | * It uses the above classes to decode a zip file, and load every files. 565 | * @param {string} data the data to load. 566 | * @param {Object} options Options for loading the stream. 567 | * options.base64 : is the stream in base64 ? default : false 568 | */ 569 | JSZip.prototype.load = function(data, options) { 570 | var files, zipEntries, i, input; 571 | options = options || {}; 572 | if(options.base64) 573 | { 574 | data = JSZipBase64.decode(data); 575 | } 576 | 577 | zipEntries = new ZipEntries(data, options); 578 | files = zipEntries.files; 579 | for (i in files) 580 | { 581 | input = files[i]; 582 | this.file(input.fileName, input.uncompressedFileData, { 583 | binary:true, 584 | date:input.date, 585 | dir:input.dir 586 | }); 587 | } 588 | 589 | return this; 590 | }; 591 | 592 | }()); 593 | // enforcing Stuk's coding style 594 | // vim: set shiftwidth=3 softtabstop=3 foldmethod=marker: 595 | -------------------------------------------------------------------------------- /js-zip/jszip-inflate.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Port of a script by Masanao Izumo. 3 | * 4 | * Only changes : wrap all the variables in a function and add the 5 | * main function to JSZip (DEFLATE compression method). 6 | * Everything else was written by M. Izumo. 7 | * 8 | * Original code can be found here: http://www.onicos.com/staff/iz/amuse/javascript/expert/inflate.txt 9 | */ 10 | 11 | if(!JSZip) 12 | { 13 | throw "JSZip not defined"; 14 | } 15 | 16 | /* 17 | * Original: 18 | * http://www.onicos.com/staff/iz/amuse/javascript/expert/inflate.txt 19 | */ 20 | 21 | (function(){ 22 | // the original implementation leaks a global variable. 23 | // Defining the variable here doesn't break anything. 24 | var zip_fixed_bd; 25 | 26 | /* Copyright (C) 1999 Masanao Izumo 27 | * Version: 1.0.0.1 28 | * LastModified: Dec 25 1999 29 | */ 30 | 31 | /* Interface: 32 | * data = zip_inflate(src); 33 | */ 34 | 35 | /* constant parameters */ 36 | var zip_WSIZE = 32768; // Sliding Window size 37 | var zip_STORED_BLOCK = 0; 38 | var zip_STATIC_TREES = 1; 39 | var zip_DYN_TREES = 2; 40 | 41 | /* for inflate */ 42 | var zip_lbits = 9; // bits in base literal/length lookup table 43 | var zip_dbits = 6; // bits in base distance lookup table 44 | var zip_INBUFSIZ = 32768; // Input buffer size 45 | var zip_INBUF_EXTRA = 64; // Extra buffer 46 | 47 | /* variables (inflate) */ 48 | var zip_slide; 49 | var zip_wp; // current position in slide 50 | var zip_fixed_tl = null; // inflate static 51 | var zip_fixed_td; // inflate static 52 | var zip_fixed_bl, fixed_bd; // inflate static 53 | var zip_bit_buf; // bit buffer 54 | var zip_bit_len; // bits in bit buffer 55 | var zip_method; 56 | var zip_eof; 57 | var zip_copy_leng; 58 | var zip_copy_dist; 59 | var zip_tl, zip_td; // literal/length and distance decoder tables 60 | var zip_bl, zip_bd; // number of bits decoded by tl and td 61 | 62 | var zip_inflate_data; 63 | var zip_inflate_pos; 64 | 65 | 66 | /* constant tables (inflate) */ 67 | var zip_MASK_BITS = new Array( 68 | 0x0000, 69 | 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 70 | 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff); 71 | // Tables for deflate from PKZIP's appnote.txt. 72 | var zip_cplens = new Array( // Copy lengths for literal codes 257..285 73 | 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 74 | 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0); 75 | /* note: see note #13 above about the 258 in this list. */ 76 | var zip_cplext = new Array( // Extra bits for literal codes 257..285 77 | 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 78 | 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99); // 99==invalid 79 | var zip_cpdist = new Array( // Copy offsets for distance codes 0..29 80 | 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 81 | 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 82 | 8193, 12289, 16385, 24577); 83 | var zip_cpdext = new Array( // Extra bits for distance codes 84 | 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 85 | 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 86 | 12, 12, 13, 13); 87 | var zip_border = new Array( // Order of the bit length code lengths 88 | 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15); 89 | /* objects (inflate) */ 90 | 91 | function zip_HuftList() { 92 | this.next = null; 93 | this.list = null; 94 | } 95 | 96 | function zip_HuftNode() { 97 | this.e = 0; // number of extra bits or operation 98 | this.b = 0; // number of bits in this code or subcode 99 | 100 | // union 101 | this.n = 0; // literal, length base, or distance base 102 | this.t = null; // (zip_HuftNode) pointer to next level of table 103 | } 104 | 105 | function zip_HuftBuild(b, // code lengths in bits (all assumed <= BMAX) 106 | n, // number of codes (assumed <= N_MAX) 107 | s, // number of simple-valued codes (0..s-1) 108 | d, // list of base values for non-simple codes 109 | e, // list of extra bits for non-simple codes 110 | mm // maximum lookup bits 111 | ) { 112 | this.BMAX = 16; // maximum bit length of any code 113 | this.N_MAX = 288; // maximum number of codes in any set 114 | this.status = 0; // 0: success, 1: incomplete table, 2: bad input 115 | this.root = null; // (zip_HuftList) starting table 116 | this.m = 0; // maximum lookup bits, returns actual 117 | 118 | /* Given a list of code lengths and a maximum table size, make a set of 119 | tables to decode that set of codes. Return zero on success, one if 120 | the given code set is incomplete (the tables are still built in this 121 | case), two if the input is invalid (all zero length codes or an 122 | oversubscribed set of lengths), and three if not enough memory. 123 | The code with value 256 is special, and the tables are constructed 124 | so that no bits beyond that code are fetched when that code is 125 | decoded. */ 126 | { 127 | var a; // counter for codes of length k 128 | var c = new Array(this.BMAX+1); // bit length count table 129 | var el; // length of EOB code (value 256) 130 | var f; // i repeats in table every f entries 131 | var g; // maximum code length 132 | var h; // table level 133 | var i; // counter, current code 134 | var j; // counter 135 | var k; // number of bits in current code 136 | var lx = new Array(this.BMAX+1); // stack of bits per table 137 | var p; // pointer into c[], b[], or v[] 138 | var pidx; // index of p 139 | var q; // (zip_HuftNode) points to current table 140 | var r = new zip_HuftNode(); // table entry for structure assignment 141 | var u = new Array(this.BMAX); // zip_HuftNode[BMAX][] table stack 142 | var v = new Array(this.N_MAX); // values in order of bit length 143 | var w; 144 | var x = new Array(this.BMAX+1);// bit offsets, then code stack 145 | var xp; // pointer into x or c 146 | var y; // number of dummy codes added 147 | var z; // number of entries in current table 148 | var o; 149 | var tail; // (zip_HuftList) 150 | 151 | tail = this.root = null; 152 | for(i = 0; i < c.length; i++) 153 | c[i] = 0; 154 | for(i = 0; i < lx.length; i++) 155 | lx[i] = 0; 156 | for(i = 0; i < u.length; i++) 157 | u[i] = null; 158 | for(i = 0; i < v.length; i++) 159 | v[i] = 0; 160 | for(i = 0; i < x.length; i++) 161 | x[i] = 0; 162 | 163 | // Generate counts for each bit length 164 | el = n > 256 ? b[256] : this.BMAX; // set length of EOB code, if any 165 | p = b; pidx = 0; 166 | i = n; 167 | do { 168 | c[p[pidx]]++; // assume all entries <= BMAX 169 | pidx++; 170 | } while(--i > 0); 171 | if(c[0] == n) { // null input--all zero length codes 172 | this.root = null; 173 | this.m = 0; 174 | this.status = 0; 175 | return; 176 | } 177 | 178 | // Find minimum and maximum length, bound *m by those 179 | for(j = 1; j <= this.BMAX; j++) 180 | if(c[j] != 0) 181 | break; 182 | k = j; // minimum code length 183 | if(mm < j) 184 | mm = j; 185 | for(i = this.BMAX; i != 0; i--) 186 | if(c[i] != 0) 187 | break; 188 | g = i; // maximum code length 189 | if(mm > i) 190 | mm = i; 191 | 192 | // Adjust last length count to fill out codes, if needed 193 | for(y = 1 << j; j < i; j++, y <<= 1) 194 | if((y -= c[j]) < 0) { 195 | this.status = 2; // bad input: more codes than bits 196 | this.m = mm; 197 | return; 198 | } 199 | if((y -= c[i]) < 0) { 200 | this.status = 2; 201 | this.m = mm; 202 | return; 203 | } 204 | c[i] += y; 205 | 206 | // Generate starting offsets into the value table for each length 207 | x[1] = j = 0; 208 | p = c; 209 | pidx = 1; 210 | xp = 2; 211 | while(--i > 0) // note that i == g from above 212 | x[xp++] = (j += p[pidx++]); 213 | 214 | // Make a table of values in order of bit lengths 215 | p = b; pidx = 0; 216 | i = 0; 217 | do { 218 | if((j = p[pidx++]) != 0) 219 | v[x[j]++] = i; 220 | } while(++i < n); 221 | n = x[g]; // set n to length of v 222 | 223 | // Generate the Huffman codes and for each, make the table entries 224 | x[0] = i = 0; // first Huffman code is zero 225 | p = v; pidx = 0; // grab values in bit order 226 | h = -1; // no tables yet--level -1 227 | w = lx[0] = 0; // no bits decoded yet 228 | q = null; // ditto 229 | z = 0; // ditto 230 | 231 | // go through the bit lengths (k already is bits in shortest code) 232 | for(; k <= g; k++) { 233 | a = c[k]; 234 | while(a-- > 0) { 235 | // here i is the Huffman code of length k bits for value p[pidx] 236 | // make tables up to required level 237 | while(k > w + lx[1 + h]) { 238 | w += lx[1 + h]; // add bits already decoded 239 | h++; 240 | 241 | // compute minimum size table less than or equal to *m bits 242 | z = (z = g - w) > mm ? mm : z; // upper limit 243 | if((f = 1 << (j = k - w)) > a + 1) { // try a k-w bit table 244 | // too few codes for k-w bit table 245 | f -= a + 1; // deduct codes from patterns left 246 | xp = k; 247 | while(++j < z) { // try smaller tables up to z bits 248 | if((f <<= 1) <= c[++xp]) 249 | break; // enough codes to use up j bits 250 | f -= c[xp]; // else deduct codes from patterns 251 | } 252 | } 253 | if(w + j > el && w < el) 254 | j = el - w; // make EOB code end at table 255 | z = 1 << j; // table entries for j-bit table 256 | lx[1 + h] = j; // set table size in stack 257 | 258 | // allocate and link in new table 259 | q = new Array(z); 260 | for(o = 0; o < z; o++) { 261 | q[o] = new zip_HuftNode(); 262 | } 263 | 264 | if(tail == null) 265 | tail = this.root = new zip_HuftList(); 266 | else 267 | tail = tail.next = new zip_HuftList(); 268 | tail.next = null; 269 | tail.list = q; 270 | u[h] = q; // table starts after link 271 | 272 | /* connect to last table, if there is one */ 273 | if(h > 0) { 274 | x[h] = i; // save pattern for backing up 275 | r.b = lx[h]; // bits to dump before this table 276 | r.e = 16 + j; // bits in this table 277 | r.t = q; // pointer to this table 278 | j = (i & ((1 << w) - 1)) >> (w - lx[h]); 279 | u[h-1][j].e = r.e; 280 | u[h-1][j].b = r.b; 281 | u[h-1][j].n = r.n; 282 | u[h-1][j].t = r.t; 283 | } 284 | } 285 | 286 | // set up table entry in r 287 | r.b = k - w; 288 | if(pidx >= n) 289 | r.e = 99; // out of values--invalid code 290 | else if(p[pidx] < s) { 291 | r.e = (p[pidx] < 256 ? 16 : 15); // 256 is end-of-block code 292 | r.n = p[pidx++]; // simple code is just the value 293 | } else { 294 | r.e = e[p[pidx] - s]; // non-simple--look up in lists 295 | r.n = d[p[pidx++] - s]; 296 | } 297 | 298 | // fill code-like entries with r // 299 | f = 1 << (k - w); 300 | for(j = i >> w; j < z; j += f) { 301 | q[j].e = r.e; 302 | q[j].b = r.b; 303 | q[j].n = r.n; 304 | q[j].t = r.t; 305 | } 306 | 307 | // backwards increment the k-bit code i 308 | for(j = 1 << (k - 1); (i & j) != 0; j >>= 1) 309 | i ^= j; 310 | i ^= j; 311 | 312 | // backup over finished tables 313 | while((i & ((1 << w) - 1)) != x[h]) { 314 | w -= lx[h]; // don't need to update q 315 | h--; 316 | } 317 | } 318 | } 319 | 320 | /* return actual size of base table */ 321 | this.m = lx[1]; 322 | 323 | /* Return true (1) if we were given an incomplete table */ 324 | this.status = ((y != 0 && g != 1) ? 1 : 0); 325 | } /* end of constructor */ 326 | } 327 | 328 | 329 | /* routines (inflate) */ 330 | 331 | function zip_GET_BYTE() { 332 | if(zip_inflate_data.length == zip_inflate_pos) 333 | return -1; 334 | return zip_inflate_data.charCodeAt(zip_inflate_pos++) & 0xff; 335 | } 336 | 337 | function zip_NEEDBITS(n) { 338 | while(zip_bit_len < n) { 339 | zip_bit_buf |= zip_GET_BYTE() << zip_bit_len; 340 | zip_bit_len += 8; 341 | } 342 | } 343 | 344 | function zip_GETBITS(n) { 345 | return zip_bit_buf & zip_MASK_BITS[n]; 346 | } 347 | 348 | function zip_DUMPBITS(n) { 349 | zip_bit_buf >>= n; 350 | zip_bit_len -= n; 351 | } 352 | 353 | function zip_inflate_codes(buff, off, size) { 354 | /* inflate (decompress) the codes in a deflated (compressed) block. 355 | Return an error code or zero if it all goes ok. */ 356 | var e; // table entry flag/number of extra bits 357 | var t; // (zip_HuftNode) pointer to table entry 358 | var n; 359 | 360 | if(size == 0) 361 | return 0; 362 | 363 | // inflate the coded data 364 | n = 0; 365 | for(;;) { // do until end of block 366 | zip_NEEDBITS(zip_bl); 367 | t = zip_tl.list[zip_GETBITS(zip_bl)]; 368 | e = t.e; 369 | while(e > 16) { 370 | if(e == 99) 371 | return -1; 372 | zip_DUMPBITS(t.b); 373 | e -= 16; 374 | zip_NEEDBITS(e); 375 | t = t.t[zip_GETBITS(e)]; 376 | e = t.e; 377 | } 378 | zip_DUMPBITS(t.b); 379 | 380 | if(e == 16) { // then it's a literal 381 | zip_wp &= zip_WSIZE - 1; 382 | buff[off + n++] = zip_slide[zip_wp++] = t.n; 383 | if(n == size) 384 | return size; 385 | continue; 386 | } 387 | 388 | // exit if end of block 389 | if(e == 15) 390 | break; 391 | 392 | // it's an EOB or a length 393 | 394 | // get length of block to copy 395 | zip_NEEDBITS(e); 396 | zip_copy_leng = t.n + zip_GETBITS(e); 397 | zip_DUMPBITS(e); 398 | 399 | // decode distance of block to copy 400 | zip_NEEDBITS(zip_bd); 401 | t = zip_td.list[zip_GETBITS(zip_bd)]; 402 | e = t.e; 403 | 404 | while(e > 16) { 405 | if(e == 99) 406 | return -1; 407 | zip_DUMPBITS(t.b); 408 | e -= 16; 409 | zip_NEEDBITS(e); 410 | t = t.t[zip_GETBITS(e)]; 411 | e = t.e; 412 | } 413 | zip_DUMPBITS(t.b); 414 | zip_NEEDBITS(e); 415 | zip_copy_dist = zip_wp - t.n - zip_GETBITS(e); 416 | zip_DUMPBITS(e); 417 | 418 | // do the copy 419 | while(zip_copy_leng > 0 && n < size) { 420 | zip_copy_leng--; 421 | zip_copy_dist &= zip_WSIZE - 1; 422 | zip_wp &= zip_WSIZE - 1; 423 | buff[off + n++] = zip_slide[zip_wp++] 424 | = zip_slide[zip_copy_dist++]; 425 | } 426 | 427 | if(n == size) 428 | return size; 429 | } 430 | 431 | zip_method = -1; // done 432 | return n; 433 | } 434 | 435 | function zip_inflate_stored(buff, off, size) { 436 | /* "decompress" an inflated type 0 (stored) block. */ 437 | var n; 438 | 439 | // go to byte boundary 440 | n = zip_bit_len & 7; 441 | zip_DUMPBITS(n); 442 | 443 | // get the length and its complement 444 | zip_NEEDBITS(16); 445 | n = zip_GETBITS(16); 446 | zip_DUMPBITS(16); 447 | zip_NEEDBITS(16); 448 | if(n != ((~zip_bit_buf) & 0xffff)) 449 | return -1; // error in compressed data 450 | zip_DUMPBITS(16); 451 | 452 | // read and output the compressed data 453 | zip_copy_leng = n; 454 | 455 | n = 0; 456 | while(zip_copy_leng > 0 && n < size) { 457 | zip_copy_leng--; 458 | zip_wp &= zip_WSIZE - 1; 459 | zip_NEEDBITS(8); 460 | buff[off + n++] = zip_slide[zip_wp++] = 461 | zip_GETBITS(8); 462 | zip_DUMPBITS(8); 463 | } 464 | 465 | if(zip_copy_leng == 0) 466 | zip_method = -1; // done 467 | return n; 468 | } 469 | 470 | function zip_inflate_fixed(buff, off, size) { 471 | /* decompress an inflated type 1 (fixed Huffman codes) block. We should 472 | either replace this with a custom decoder, or at least precompute the 473 | Huffman tables. */ 474 | 475 | // if first time, set up tables for fixed blocks 476 | if(zip_fixed_tl == null) { 477 | var i; // temporary variable 478 | var l = new Array(288); // length list for huft_build 479 | var h; // zip_HuftBuild 480 | 481 | // literal table 482 | for(i = 0; i < 144; i++) 483 | l[i] = 8; 484 | for(; i < 256; i++) 485 | l[i] = 9; 486 | for(; i < 280; i++) 487 | l[i] = 7; 488 | for(; i < 288; i++) // make a complete, but wrong code set 489 | l[i] = 8; 490 | zip_fixed_bl = 7; 491 | 492 | h = new zip_HuftBuild(l, 288, 257, zip_cplens, zip_cplext, 493 | zip_fixed_bl); 494 | if(h.status != 0) { 495 | alert("HufBuild error: "+h.status); 496 | return -1; 497 | } 498 | zip_fixed_tl = h.root; 499 | zip_fixed_bl = h.m; 500 | 501 | // distance table 502 | for(i = 0; i < 30; i++) // make an incomplete code set 503 | l[i] = 5; 504 | zip_fixed_bd = 5; 505 | 506 | h = new zip_HuftBuild(l, 30, 0, zip_cpdist, zip_cpdext, zip_fixed_bd); 507 | if(h.status > 1) { 508 | zip_fixed_tl = null; 509 | alert("HufBuild error: "+h.status); 510 | return -1; 511 | } 512 | zip_fixed_td = h.root; 513 | zip_fixed_bd = h.m; 514 | } 515 | 516 | zip_tl = zip_fixed_tl; 517 | zip_td = zip_fixed_td; 518 | zip_bl = zip_fixed_bl; 519 | zip_bd = zip_fixed_bd; 520 | return zip_inflate_codes(buff, off, size); 521 | } 522 | 523 | function zip_inflate_dynamic(buff, off, size) { 524 | // decompress an inflated type 2 (dynamic Huffman codes) block. 525 | var i; // temporary variables 526 | var j; 527 | var l; // last length 528 | var n; // number of lengths to get 529 | var t; // (zip_HuftNode) literal/length code table 530 | var nb; // number of bit length codes 531 | var nl; // number of literal/length codes 532 | var nd; // number of distance codes 533 | var ll = new Array(286+30); // literal/length and distance code lengths 534 | var h; // (zip_HuftBuild) 535 | 536 | for(i = 0; i < ll.length; i++) 537 | ll[i] = 0; 538 | 539 | // read in table lengths 540 | zip_NEEDBITS(5); 541 | nl = 257 + zip_GETBITS(5); // number of literal/length codes 542 | zip_DUMPBITS(5); 543 | zip_NEEDBITS(5); 544 | nd = 1 + zip_GETBITS(5); // number of distance codes 545 | zip_DUMPBITS(5); 546 | zip_NEEDBITS(4); 547 | nb = 4 + zip_GETBITS(4); // number of bit length codes 548 | zip_DUMPBITS(4); 549 | if(nl > 286 || nd > 30) 550 | return -1; // bad lengths 551 | 552 | // read in bit-length-code lengths 553 | for(j = 0; j < nb; j++) 554 | { 555 | zip_NEEDBITS(3); 556 | ll[zip_border[j]] = zip_GETBITS(3); 557 | zip_DUMPBITS(3); 558 | } 559 | for(; j < 19; j++) 560 | ll[zip_border[j]] = 0; 561 | 562 | // build decoding table for trees--single level, 7 bit lookup 563 | zip_bl = 7; 564 | h = new zip_HuftBuild(ll, 19, 19, null, null, zip_bl); 565 | if(h.status != 0) 566 | return -1; // incomplete code set 567 | 568 | zip_tl = h.root; 569 | zip_bl = h.m; 570 | 571 | // read in literal and distance code lengths 572 | n = nl + nd; 573 | i = l = 0; 574 | while(i < n) { 575 | zip_NEEDBITS(zip_bl); 576 | t = zip_tl.list[zip_GETBITS(zip_bl)]; 577 | j = t.b; 578 | zip_DUMPBITS(j); 579 | j = t.n; 580 | if(j < 16) // length of code in bits (0..15) 581 | ll[i++] = l = j; // save last length in l 582 | else if(j == 16) { // repeat last length 3 to 6 times 583 | zip_NEEDBITS(2); 584 | j = 3 + zip_GETBITS(2); 585 | zip_DUMPBITS(2); 586 | if(i + j > n) 587 | return -1; 588 | while(j-- > 0) 589 | ll[i++] = l; 590 | } else if(j == 17) { // 3 to 10 zero length codes 591 | zip_NEEDBITS(3); 592 | j = 3 + zip_GETBITS(3); 593 | zip_DUMPBITS(3); 594 | if(i + j > n) 595 | return -1; 596 | while(j-- > 0) 597 | ll[i++] = 0; 598 | l = 0; 599 | } else { // j == 18: 11 to 138 zero length codes 600 | zip_NEEDBITS(7); 601 | j = 11 + zip_GETBITS(7); 602 | zip_DUMPBITS(7); 603 | if(i + j > n) 604 | return -1; 605 | while(j-- > 0) 606 | ll[i++] = 0; 607 | l = 0; 608 | } 609 | } 610 | 611 | // build the decoding tables for literal/length and distance codes 612 | zip_bl = zip_lbits; 613 | h = new zip_HuftBuild(ll, nl, 257, zip_cplens, zip_cplext, zip_bl); 614 | if(zip_bl == 0) // no literals or lengths 615 | h.status = 1; 616 | if(h.status != 0) { 617 | if(h.status == 1) 618 | ;// **incomplete literal tree** 619 | return -1; // incomplete code set 620 | } 621 | zip_tl = h.root; 622 | zip_bl = h.m; 623 | 624 | for(i = 0; i < nd; i++) 625 | ll[i] = ll[i + nl]; 626 | zip_bd = zip_dbits; 627 | h = new zip_HuftBuild(ll, nd, 0, zip_cpdist, zip_cpdext, zip_bd); 628 | zip_td = h.root; 629 | zip_bd = h.m; 630 | 631 | if(zip_bd == 0 && nl > 257) { // lengths but no distances 632 | // **incomplete distance tree** 633 | return -1; 634 | } 635 | 636 | if(h.status == 1) { 637 | ;// **incomplete distance tree** 638 | } 639 | if(h.status != 0) 640 | return -1; 641 | 642 | // decompress until an end-of-block code 643 | return zip_inflate_codes(buff, off, size); 644 | } 645 | 646 | function zip_inflate_start() { 647 | var i; 648 | 649 | if(zip_slide == null) 650 | zip_slide = new Array(2 * zip_WSIZE); 651 | zip_wp = 0; 652 | zip_bit_buf = 0; 653 | zip_bit_len = 0; 654 | zip_method = -1; 655 | zip_eof = false; 656 | zip_copy_leng = zip_copy_dist = 0; 657 | zip_tl = null; 658 | } 659 | 660 | function zip_inflate_internal(buff, off, size) { 661 | // decompress an inflated entry 662 | var n, i; 663 | 664 | n = 0; 665 | while(n < size) { 666 | if(zip_eof && zip_method == -1) 667 | return n; 668 | 669 | if(zip_copy_leng > 0) { 670 | if(zip_method != zip_STORED_BLOCK) { 671 | // STATIC_TREES or DYN_TREES 672 | while(zip_copy_leng > 0 && n < size) { 673 | zip_copy_leng--; 674 | zip_copy_dist &= zip_WSIZE - 1; 675 | zip_wp &= zip_WSIZE - 1; 676 | buff[off + n++] = zip_slide[zip_wp++] = 677 | zip_slide[zip_copy_dist++]; 678 | } 679 | } else { 680 | while(zip_copy_leng > 0 && n < size) { 681 | zip_copy_leng--; 682 | zip_wp &= zip_WSIZE - 1; 683 | zip_NEEDBITS(8); 684 | buff[off + n++] = zip_slide[zip_wp++] = zip_GETBITS(8); 685 | zip_DUMPBITS(8); 686 | } 687 | if(zip_copy_leng == 0) 688 | zip_method = -1; // done 689 | } 690 | if(n == size) 691 | return n; 692 | } 693 | 694 | if(zip_method == -1) { 695 | if(zip_eof) 696 | break; 697 | 698 | // read in last block bit 699 | zip_NEEDBITS(1); 700 | if(zip_GETBITS(1) != 0) 701 | zip_eof = true; 702 | zip_DUMPBITS(1); 703 | 704 | // read in block type 705 | zip_NEEDBITS(2); 706 | zip_method = zip_GETBITS(2); 707 | zip_DUMPBITS(2); 708 | zip_tl = null; 709 | zip_copy_leng = 0; 710 | } 711 | 712 | switch(zip_method) { 713 | case 0: // zip_STORED_BLOCK 714 | i = zip_inflate_stored(buff, off + n, size - n); 715 | break; 716 | 717 | case 1: // zip_STATIC_TREES 718 | if(zip_tl != null) 719 | i = zip_inflate_codes(buff, off + n, size - n); 720 | else 721 | i = zip_inflate_fixed(buff, off + n, size - n); 722 | break; 723 | 724 | case 2: // zip_DYN_TREES 725 | if(zip_tl != null) 726 | i = zip_inflate_codes(buff, off + n, size - n); 727 | else 728 | i = zip_inflate_dynamic(buff, off + n, size - n); 729 | break; 730 | 731 | default: // error 732 | i = -1; 733 | break; 734 | } 735 | 736 | if(i == -1) { 737 | if(zip_eof) 738 | return 0; 739 | return -1; 740 | } 741 | n += i; 742 | } 743 | return n; 744 | } 745 | 746 | function zip_inflate(str) { 747 | var out, buff; 748 | var i, j; 749 | 750 | zip_inflate_start(); 751 | zip_inflate_data = str; 752 | zip_inflate_pos = 0; 753 | 754 | buff = new Array(1024); 755 | out = ""; 756 | while((i = zip_inflate_internal(buff, 0, buff.length)) > 0) { 757 | for(j = 0; j < i; j++) 758 | out += String.fromCharCode(buff[j]); 759 | } 760 | zip_inflate_data = null; // G.C. 761 | return out; 762 | } 763 | 764 | // 765 | // end of the script of Masanao Izumo. 766 | // 767 | 768 | // we add the compression method for JSZip 769 | if(!JSZip.compressions["DEFLATE"]) { 770 | JSZip.compressions["DEFLATE"] = { 771 | magic : "\x08\x00", 772 | uncompress : zip_inflate 773 | } 774 | } else { 775 | JSZip.compressions["DEFLATE"].uncompress = zip_inflate; 776 | } 777 | 778 | })(); 779 | -------------------------------------------------------------------------------- /js-zip/jszip.js: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | JSZip - A Javascript class for generating and reading zip files 4 | 5 | 6 | (c) 2009-2012 Stuart Knightley 7 | Dual licenced under the MIT license or GPLv3. See LICENSE.markdown. 8 | 9 | Usage: 10 | zip = new JSZip(); 11 | zip.file("hello.txt", "Hello, World!").add("tempfile", "nothing"); 12 | zip.folder("images").file("smile.gif", base64Data, {base64: true}); 13 | zip.file("Xmas.txt", "Ho ho ho !", {date : new Date("December 25, 2007 00:00:01")}); 14 | zip.remove("tempfile"); 15 | 16 | base64zip = zip.generate(); 17 | 18 | **/ 19 | 20 | /** 21 | * Representation a of zip file in js 22 | * @constructor 23 | * @param {String=} data the data to load, if any (optional). 24 | * @param {Object=} options the options for creating this objects (optional). 25 | */ 26 | var JSZip = function(data, options) { 27 | // object containing the files : 28 | // { 29 | // "folder/" : {...}, 30 | // "folder/data.txt" : {...} 31 | // } 32 | this.files = {}; 33 | 34 | // Where we are in the hierarchy 35 | this.root = ""; 36 | 37 | if(data) { 38 | this.load(data, options); 39 | } 40 | }; 41 | 42 | JSZip.signature = { 43 | LOCAL_FILE_HEADER : "\x50\x4b\x03\x04", 44 | CENTRAL_FILE_HEADER : "\x50\x4b\x01\x02", 45 | CENTRAL_DIRECTORY_END : "\x50\x4b\x05\x06", 46 | ZIP64_CENTRAL_DIRECTORY_LOCATOR : "\x50\x4b\x06\x07", 47 | ZIP64_CENTRAL_DIRECTORY_END : "\x50\x4b\x06\x06", 48 | DATA_DESCRIPTOR : "\x50\x4b\x07\x08" 49 | }; 50 | 51 | // Default properties for a new file 52 | JSZip.defaults = { 53 | base64: false, 54 | binary: false, 55 | dir: false, 56 | date: null 57 | }; 58 | 59 | 60 | JSZip.prototype = (function () 61 | { 62 | /** 63 | * A simple object representing a file in the zip file. 64 | * @constructor 65 | * @param {string} name the name of the file 66 | * @param {string} data the data 67 | * @param {Object} options the options of the file 68 | */ 69 | var ZipObject = function (name, data, options) { 70 | this.name = name; 71 | this.data = data; 72 | this.options = options; 73 | }; 74 | 75 | ZipObject.prototype = { 76 | /** 77 | * Return the content as UTF8 string. 78 | * @return {string} the UTF8 string. 79 | */ 80 | asText : function () 81 | { 82 | return this.options.binary ? JSZip.prototype.utf8decode(this.data) : this.data; 83 | }, 84 | /** 85 | * Returns the binary content. 86 | * @return {string} the content as binary. 87 | */ 88 | asBinary : function () 89 | { 90 | return this.options.binary ? this.data : JSZip.prototype.utf8encode(this.data); 91 | } 92 | }; 93 | 94 | /** 95 | * Transform an integer into a string in hexadecimal. 96 | * @private 97 | * @param {number} dec the number to convert. 98 | * @param {number} bytes the number of bytes to generate. 99 | * @returns {string} the result. 100 | */ 101 | var decToHex = function(dec, bytes) { 102 | var hex = "", i; 103 | for(i = 0; i < bytes; i++) 104 | { 105 | hex += String.fromCharCode(dec&0xff); 106 | dec=dec>>>8; 107 | } 108 | return hex; 109 | }; 110 | 111 | /** 112 | * Merge the objects passed as parameters into a new one. 113 | * @private 114 | * @param {...Object} var_args All objects to merge. 115 | * @return {Object} a new object with the data of the others. 116 | */ 117 | var extend = function () { 118 | var result = {}, i, attr; 119 | for (i = 0; i < arguments.length; i++) // arguments is not enumerable in some browsers 120 | { 121 | for (attr in arguments[i]) 122 | { 123 | if(typeof result[attr] === "undefined") 124 | { 125 | result[attr] = arguments[i][attr]; 126 | } 127 | } 128 | } 129 | return result; 130 | }; 131 | 132 | /** 133 | * Transforms the (incomplete) options from the user into the complete 134 | * set of options to create a file. 135 | * @private 136 | * @param {Object} o the options from the user. 137 | * @return {Object} the complete set of options. 138 | */ 139 | var prepareFileAttrs = function (o) { 140 | o = o || {}; 141 | if (o.base64 === true && o.binary == null) { 142 | o.binary = true; 143 | } 144 | o = extend(o, JSZip.defaults); 145 | o.date = o.date || new Date(); 146 | 147 | return o; 148 | }; 149 | 150 | /** 151 | * Add a file in the current folder. 152 | * @private 153 | * @param {string} name the name of the file 154 | * @param {string} data the data of the file 155 | * @param {Object} o the options of the file 156 | * @return {Object} the new file. 157 | */ 158 | var fileAdd = function (name, data, o) { 159 | // be sure sub folders exist 160 | var parent = parentFolder(name); 161 | if (parent) { 162 | folderAdd.call(this, parent); 163 | } 164 | 165 | o = prepareFileAttrs(o); 166 | 167 | return this.files[name] = new ZipObject(name, data, o); 168 | }; 169 | 170 | 171 | /** 172 | * Find the parent folder of the path. 173 | * @private 174 | * @param {string} path the path to use 175 | * @return {string} the parent folder, or "" 176 | */ 177 | var parentFolder = function (path) { 178 | if (path.slice(-1) == '/') 179 | { 180 | path = path.substring(0, path.length - 1); 181 | } 182 | var lastSlash = path.lastIndexOf('/'); 183 | return (lastSlash > 0) ? path.substring(0, lastSlash) : ""; 184 | }; 185 | 186 | /** 187 | * Add a (sub) folder in the current folder. 188 | * @private 189 | * @param {string} name the folder's name 190 | * @return {Object} the new folder. 191 | */ 192 | var folderAdd = function (name) { 193 | // Check the name ends with a / 194 | if (name.slice(-1) != "/") { 195 | name += "/"; // IE doesn't like substr(-1) 196 | } 197 | 198 | // Does this folder already exist? 199 | if (!this.files[name]) 200 | { 201 | // be sure sub folders exist 202 | var parent = parentFolder(name); 203 | if (parent) { 204 | folderAdd.call(this, parent); 205 | } 206 | 207 | fileAdd.call(this, name, '', {dir:true}); 208 | } 209 | return this.files[name]; 210 | }; 211 | 212 | /** 213 | * Generate the data found in the local header of a zip file. 214 | * Do not create it now, as some parts are re-used later. 215 | * @private 216 | * @param {Object} file the file to use. 217 | * @param {string} utfEncodedFileName the file name, utf8 encoded. 218 | * @param {string} compressionType the compression to use. 219 | * @return {Object} an object containing header and compressedData. 220 | */ 221 | var prepareLocalHeaderData = function(file, utfEncodedFileName, compressionType) { 222 | var useUTF8 = utfEncodedFileName !== file.name, 223 | data = file.data, 224 | o = file.options, 225 | dosTime, 226 | dosDate; 227 | 228 | // date 229 | // @see http://www.delorie.com/djgpp/doc/rbinter/it/52/13.html 230 | // @see http://www.delorie.com/djgpp/doc/rbinter/it/65/16.html 231 | // @see http://www.delorie.com/djgpp/doc/rbinter/it/66/16.html 232 | 233 | dosTime = o.date.getHours(); 234 | dosTime = dosTime << 6; 235 | dosTime = dosTime | o.date.getMinutes(); 236 | dosTime = dosTime << 5; 237 | dosTime = dosTime | o.date.getSeconds() / 2; 238 | 239 | dosDate = o.date.getFullYear() - 1980; 240 | dosDate = dosDate << 4; 241 | dosDate = dosDate | (o.date.getMonth() + 1); 242 | dosDate = dosDate << 5; 243 | dosDate = dosDate | o.date.getDate(); 244 | 245 | if (o.base64 === true) { 246 | data = JSZipBase64.decode(data); 247 | } 248 | // decode UTF-8 strings if we are dealing with text data 249 | if(o.binary === false) { 250 | data = this.utf8encode(data); 251 | } 252 | 253 | 254 | var compression = JSZip.compressions[compressionType]; 255 | var compressedData = compression.compress(data); 256 | 257 | var header = ""; 258 | 259 | // version needed to extract 260 | header += "\x0A\x00"; 261 | // general purpose bit flag 262 | // set bit 11 if utf8 263 | header += useUTF8 ? "\x00\x08" : "\x00\x00"; 264 | // compression method 265 | header += compression.magic; 266 | // last mod file time 267 | header += decToHex(dosTime, 2); 268 | // last mod file date 269 | header += decToHex(dosDate, 2); 270 | // crc-32 271 | header += decToHex(this.crc32(data), 4); 272 | // compressed size 273 | header += decToHex(compressedData.length, 4); 274 | // uncompressed size 275 | header += decToHex(data.length, 4); 276 | // file name length 277 | header += decToHex(utfEncodedFileName.length, 2); 278 | // extra field length 279 | header += "\x00\x00"; 280 | 281 | return { 282 | header:header, 283 | compressedData:compressedData 284 | }; 285 | }; 286 | 287 | 288 | // return the actual prototype of JSZip 289 | return { 290 | /** 291 | * Read an existing zip and merge the data in the current JSZip object. 292 | * The implementation is in jszip-load.js, don't forget to include it. 293 | * @param {string} stream The stream to load 294 | * @param {Object} options Options for loading the stream. 295 | * options.base64 : is the stream in base64 ? default : false 296 | * @return {JSZip} the current JSZip object 297 | */ 298 | load : function (stream, options) 299 | { 300 | throw new Error("Load method is not defined. Is the file jszip-load.js included ?"); 301 | }, 302 | 303 | /** 304 | * Filter nested files/folders with the specified function. 305 | * @param {Function} search the predicate to use : 306 | * function (relativePath, file) {...} 307 | * It takes 2 arguments : the relative path and the file. 308 | * @return {Array} An array of matching elements. 309 | */ 310 | filter : function (search) 311 | { 312 | var result = [], filename, relativePath, file, fileClone; 313 | for (filename in this.files) 314 | { 315 | file = this.files[filename]; 316 | // return a new object, don't let the user mess with our internal objects :) 317 | fileClone = new ZipObject(file.name, file.data, extend(file.options)); 318 | relativePath = filename.slice(this.root.length, filename.length); 319 | if (filename.slice(0, this.root.length) === this.root && // the file is in the current root 320 | search(relativePath, fileClone)) // and the file matches the function 321 | { 322 | result.push(fileClone); 323 | } 324 | } 325 | return result; 326 | }, 327 | 328 | /** 329 | * Add a file to the zip file, or search a file. 330 | * @param {string|RegExp} name The name of the file to add (if data is defined), 331 | * the name of the file to find (if no data) or a regex to match files. 332 | * @param {string} data The file data, either raw or base64 encoded 333 | * @param {Object} o File options 334 | * @return {JSZip|Object|Array} this JSZip object (when adding a file), 335 | * a file (when searching by string) or an array of files (when searching by regex). 336 | */ 337 | file : function(name, data, o) 338 | { 339 | if (arguments.length === 1) 340 | { 341 | if (name instanceof RegExp) 342 | { 343 | var regexp = name; 344 | return this.filter(function(relativePath, file) { 345 | return !file.options.dir && regexp.test(relativePath); 346 | }); 347 | } 348 | else // text 349 | { 350 | return this.filter(function (relativePath, file) { 351 | return !file.options.dir && relativePath === name; 352 | })[0]||null; 353 | } 354 | } 355 | else // more than one argument : we have data ! 356 | { 357 | name = this.root+name; 358 | fileAdd.call(this, name, data, o); 359 | } 360 | return this; 361 | }, 362 | 363 | /** 364 | * Add a directory to the zip file, or search. 365 | * @param {String|RegExp} arg The name of the directory to add, or a regex to search folders. 366 | * @return {JSZip} an object with the new directory as the root, or an array containing matching folders. 367 | */ 368 | folder : function(arg) 369 | { 370 | if (!arg) 371 | { 372 | throw new Error("folder : wrong argument"); 373 | } 374 | 375 | if (arg instanceof RegExp) 376 | { 377 | return this.filter(function(relativePath, file) { 378 | return file.options.dir && arg.test(relativePath); 379 | }); 380 | } 381 | 382 | // else, name is a new folder 383 | var name = this.root + arg; 384 | var newFolder = folderAdd.call(this, name); 385 | 386 | // Allow chaining by returning a new object with this folder as the root 387 | var ret = this.clone(); 388 | ret.root = newFolder.name; 389 | return ret; 390 | }, 391 | 392 | /** 393 | * Delete a file, or a directory and all sub-files, from the zip 394 | * @param {string} name the name of the file to delete 395 | * @return {JSZip} this JSZip object 396 | */ 397 | remove : function(name) 398 | { 399 | name = this.root + name; 400 | var file = this.files[name]; 401 | if (!file) 402 | { 403 | // Look for any folders 404 | if (name.slice(-1) != "/") { 405 | name += "/"; 406 | } 407 | file = this.files[name]; 408 | } 409 | 410 | if (file) 411 | { 412 | if (!file.options.dir) 413 | { 414 | // file 415 | delete this.files[name]; 416 | } 417 | else 418 | { 419 | // folder 420 | var kids = this.filter(function (relativePath, file) { 421 | return file.name.slice(0, name.length) === name; 422 | }); 423 | for (var i = 0; i < kids.length; i++) 424 | { 425 | delete this.files[kids[i].name]; 426 | } 427 | } 428 | } 429 | 430 | return this; 431 | }, 432 | 433 | /** 434 | * Generate the complete zip file 435 | * @param {Object} options the options to generate the zip file : 436 | * - base64, true to generate base64. 437 | * - compression, "STORE" by default. 438 | * @return {string} the zip file 439 | */ 440 | generate : function(options) 441 | { 442 | options = extend(options || {}, { 443 | base64 : true, 444 | compression : "STORE" 445 | }); 446 | var compression = options.compression.toUpperCase(); 447 | 448 | // The central directory, and files data 449 | var directory = [], files = [], fileOffset = 0; 450 | 451 | if (!JSZip.compressions[compression]) { 452 | throw compression + " is not a valid compression method !"; 453 | } 454 | 455 | for (var name in this.files) 456 | { 457 | if( !this.files.hasOwnProperty(name) ) { continue; } 458 | 459 | var file = this.files[name]; 460 | 461 | var utfEncodedFileName = this.utf8encode(file.name); 462 | 463 | var fileRecord = "", 464 | dirRecord = "", 465 | data = prepareLocalHeaderData.call(this, file, utfEncodedFileName, compression); 466 | fileRecord = JSZip.signature.LOCAL_FILE_HEADER + data.header + utfEncodedFileName + data.compressedData; 467 | 468 | dirRecord = JSZip.signature.CENTRAL_FILE_HEADER + 469 | // version made by (00: DOS) 470 | "\x14\x00" + 471 | // file header (common to file and central directory) 472 | data.header + 473 | // file comment length 474 | "\x00\x00" + 475 | // disk number start 476 | "\x00\x00" + 477 | // internal file attributes TODO 478 | "\x00\x00" + 479 | // external file attributes 480 | (this.files[name].dir===true?"\x10\x00\x00\x00":"\x00\x00\x00\x00")+ 481 | // relative offset of local header 482 | decToHex(fileOffset, 4) + 483 | // file name 484 | utfEncodedFileName; 485 | 486 | fileOffset += fileRecord.length; 487 | 488 | files.push(fileRecord); 489 | directory.push(dirRecord); 490 | } 491 | 492 | var fileData = files.join(""); 493 | var dirData = directory.join(""); 494 | 495 | var dirEnd = ""; 496 | 497 | // end of central dir signature 498 | dirEnd = JSZip.signature.CENTRAL_DIRECTORY_END + 499 | // number of this disk 500 | "\x00\x00" + 501 | // number of the disk with the start of the central directory 502 | "\x00\x00" + 503 | // total number of entries in the central directory on this disk 504 | decToHex(files.length, 2) + 505 | // total number of entries in the central directory 506 | decToHex(files.length, 2) + 507 | // size of the central directory 4 bytes 508 | decToHex(dirData.length, 4) + 509 | // offset of start of central directory with respect to the starting disk number 510 | decToHex(fileData.length, 4) + 511 | // .ZIP file comment length 512 | "\x00\x00"; 513 | 514 | var zip = fileData + dirData + dirEnd; 515 | return (options.base64) ? JSZipBase64.encode(zip) : zip; 516 | }, 517 | 518 | /** 519 | * 520 | * Javascript crc32 521 | * http://www.webtoolkit.info/ 522 | * 523 | */ 524 | crc32 : function(str, crc) 525 | { 526 | 527 | if (str === "" || typeof str === "undefined") { 528 | return 0; 529 | } 530 | 531 | var table = [ 532 | 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 533 | 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 534 | 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 535 | 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 536 | 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 537 | 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 538 | 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 539 | 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 540 | 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 541 | 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 542 | 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 543 | 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 544 | 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 545 | 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 546 | 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 547 | 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 548 | 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 549 | 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 550 | 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 551 | 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 552 | 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 553 | 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 554 | 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 555 | 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 556 | 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 557 | 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 558 | 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 559 | 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 560 | 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 561 | 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 562 | 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 563 | 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 564 | 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 565 | 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 566 | 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 567 | 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 568 | 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 569 | 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 570 | 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 571 | 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 572 | 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 573 | 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 574 | 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 575 | 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 576 | 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 577 | 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 578 | 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 579 | 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 580 | 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 581 | 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 582 | 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 583 | 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 584 | 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 585 | 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 586 | 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 587 | 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 588 | 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 589 | 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 590 | 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 591 | 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 592 | 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 593 | 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 594 | 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 595 | 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D 596 | ]; 597 | 598 | if (typeof(crc) == "undefined") { crc = 0; } 599 | var x = 0; 600 | var y = 0; 601 | 602 | crc = crc ^ (-1); 603 | for( var i = 0, iTop = str.length; i < iTop; i++ ) { 604 | y = ( crc ^ str.charCodeAt( i ) ) & 0xFF; 605 | x = table[y]; 606 | crc = ( crc >>> 8 ) ^ x; 607 | } 608 | 609 | return crc ^ (-1); 610 | }, 611 | 612 | // Inspired by http://my.opera.com/GreyWyvern/blog/show.dml/1725165 613 | clone : function() 614 | { 615 | var newObj = new JSZip(); 616 | for (var i in this) 617 | { 618 | if (typeof this[i] !== "function") 619 | { 620 | newObj[i] = this[i]; 621 | } 622 | } 623 | return newObj; 624 | }, 625 | 626 | 627 | /** 628 | * http://www.webtoolkit.info/javascript-utf8.html 629 | */ 630 | utf8encode : function (string) { 631 | string = string.replace(/\r\n/g,"\n"); 632 | var utftext = ""; 633 | 634 | for (var n = 0; n < string.length; n++) { 635 | 636 | var c = string.charCodeAt(n); 637 | 638 | if (c < 128) { 639 | utftext += String.fromCharCode(c); 640 | } 641 | else if((c > 127) && (c < 2048)) { 642 | utftext += String.fromCharCode((c >> 6) | 192); 643 | utftext += String.fromCharCode((c & 63) | 128); 644 | } 645 | else { 646 | utftext += String.fromCharCode((c >> 12) | 224); 647 | utftext += String.fromCharCode(((c >> 6) & 63) | 128); 648 | utftext += String.fromCharCode((c & 63) | 128); 649 | } 650 | 651 | } 652 | 653 | return utftext; 654 | }, 655 | 656 | /** 657 | * http://www.webtoolkit.info/javascript-utf8.html 658 | */ 659 | utf8decode : function (utftext) { 660 | var string = ""; 661 | var i = 0; 662 | var c = 0, c1 = 0, c2 = 0, c3 = 0; 663 | 664 | while ( i < utftext.length ) { 665 | 666 | c = utftext.charCodeAt(i); 667 | 668 | if (c < 128) { 669 | string += String.fromCharCode(c); 670 | i++; 671 | } 672 | else if((c > 191) && (c < 224)) { 673 | c2 = utftext.charCodeAt(i+1); 674 | string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); 675 | i += 2; 676 | } 677 | else { 678 | c2 = utftext.charCodeAt(i+1); 679 | c3 = utftext.charCodeAt(i+2); 680 | string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); 681 | i += 3; 682 | } 683 | 684 | } 685 | 686 | return string; 687 | } 688 | }; 689 | }()); 690 | 691 | /* 692 | * Compression methods 693 | * This object is filled in as follow : 694 | * name : { 695 | * magic // the 2 bytes indentifying the compression method 696 | * compress // function, take the uncompressed content and return it compressed. 697 | * uncompress // function, take the compressed content and return it uncompressed. 698 | * } 699 | * 700 | * STORE is the default compression method, so it's included in this file. 701 | * Other methods should go to separated files : the user wants modularity. 702 | */ 703 | JSZip.compressions = { 704 | "STORE" : { 705 | magic : "\x00\x00", 706 | compress : function (content) 707 | { 708 | return content; // no compression 709 | }, 710 | uncompress : function (content) 711 | { 712 | return content; // no compression 713 | } 714 | } 715 | }; 716 | 717 | /** 718 | * 719 | * Base64 encode / decode 720 | * http://www.webtoolkit.info/ 721 | * 722 | * Hacked so that it doesn't utf8 en/decode everything 723 | **/ 724 | var JSZipBase64 = (function() { 725 | // private property 726 | var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; 727 | 728 | return { 729 | // public method for encoding 730 | encode : function(input, utf8) { 731 | var output = ""; 732 | var chr1, chr2, chr3, enc1, enc2, enc3, enc4; 733 | var i = 0; 734 | 735 | while (i < input.length) { 736 | 737 | chr1 = input.charCodeAt(i++); 738 | chr2 = input.charCodeAt(i++); 739 | chr3 = input.charCodeAt(i++); 740 | 741 | enc1 = chr1 >> 2; 742 | enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); 743 | enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); 744 | enc4 = chr3 & 63; 745 | 746 | if (isNaN(chr2)) { 747 | enc3 = enc4 = 64; 748 | } else if (isNaN(chr3)) { 749 | enc4 = 64; 750 | } 751 | 752 | output = output + 753 | _keyStr.charAt(enc1) + _keyStr.charAt(enc2) + 754 | _keyStr.charAt(enc3) + _keyStr.charAt(enc4); 755 | 756 | } 757 | 758 | return output; 759 | }, 760 | 761 | // public method for decoding 762 | decode : function(input, utf8) { 763 | var output = ""; 764 | var chr1, chr2, chr3; 765 | var enc1, enc2, enc3, enc4; 766 | var i = 0; 767 | 768 | input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); 769 | 770 | while (i < input.length) { 771 | 772 | enc1 = _keyStr.indexOf(input.charAt(i++)); 773 | enc2 = _keyStr.indexOf(input.charAt(i++)); 774 | enc3 = _keyStr.indexOf(input.charAt(i++)); 775 | enc4 = _keyStr.indexOf(input.charAt(i++)); 776 | 777 | chr1 = (enc1 << 2) | (enc2 >> 4); 778 | chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); 779 | chr3 = ((enc3 & 3) << 6) | enc4; 780 | 781 | output = output + String.fromCharCode(chr1); 782 | 783 | if (enc3 != 64) { 784 | output = output + String.fromCharCode(chr2); 785 | } 786 | if (enc4 != 64) { 787 | output = output + String.fromCharCode(chr3); 788 | } 789 | 790 | } 791 | 792 | return output; 793 | 794 | } 795 | }; 796 | }()); 797 | 798 | // enforcing Stuk's coding style 799 | // vim: set shiftwidth=3 softtabstop=3: 800 | -------------------------------------------------------------------------------- /js-zip/LICENSE.markdown: -------------------------------------------------------------------------------- 1 | JSZip is dual licensed. You may use it under the MIT license *or* the GPLv3 2 | license. 3 | 4 | The MIT License 5 | =============== 6 | 7 | Copyright (c) 2009-2012 Stuart Knightley, David Duponchel, Franz Buchinger, António Afonso 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in 17 | all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | THE SOFTWARE. 26 | 27 | 28 | GPL version 3 29 | ============= 30 | 31 | GNU GENERAL PUBLIC LICENSE 32 | Version 3, 29 June 2007 33 | 34 | Copyright (C) 2007 Free Software Foundation, Inc. 35 | Everyone is permitted to copy and distribute verbatim copies 36 | of this license document, but changing it is not allowed. 37 | 38 | Preamble 39 | 40 | The GNU General Public License is a free, copyleft license for 41 | software and other kinds of works. 42 | 43 | The licenses for most software and other practical works are designed 44 | to take away your freedom to share and change the works. By contrast, 45 | the GNU General Public License is intended to guarantee your freedom to 46 | share and change all versions of a program--to make sure it remains free 47 | software for all its users. We, the Free Software Foundation, use the 48 | GNU General Public License for most of our software; it applies also to 49 | any other work released this way by its authors. You can apply it to 50 | your programs, too. 51 | 52 | When we speak of free software, we are referring to freedom, not 53 | price. Our General Public Licenses are designed to make sure that you 54 | have the freedom to distribute copies of free software (and charge for 55 | them if you wish), that you receive source code or can get it if you 56 | want it, that you can change the software or use pieces of it in new 57 | free programs, and that you know you can do these things. 58 | 59 | To protect your rights, we need to prevent others from denying you 60 | these rights or asking you to surrender the rights. Therefore, you have 61 | certain responsibilities if you distribute copies of the software, or if 62 | you modify it: responsibilities to respect the freedom of others. 63 | 64 | For example, if you distribute copies of such a program, whether 65 | gratis or for a fee, you must pass on to the recipients the same 66 | freedoms that you received. You must make sure that they, too, receive 67 | or can get the source code. And you must show them these terms so they 68 | know their rights. 69 | 70 | Developers that use the GNU GPL protect your rights with two steps: 71 | (1) assert copyright on the software, and (2) offer you this License 72 | giving you legal permission to copy, distribute and/or modify it. 73 | 74 | For the developers' and authors' protection, the GPL clearly explains 75 | that there is no warranty for this free software. For both users' and 76 | authors' sake, the GPL requires that modified versions be marked as 77 | changed, so that their problems will not be attributed erroneously to 78 | authors of previous versions. 79 | 80 | Some devices are designed to deny users access to install or run 81 | modified versions of the software inside them, although the manufacturer 82 | can do so. This is fundamentally incompatible with the aim of 83 | protecting users' freedom to change the software. The systematic 84 | pattern of such abuse occurs in the area of products for individuals to 85 | use, which is precisely where it is most unacceptable. Therefore, we 86 | have designed this version of the GPL to prohibit the practice for those 87 | products. If such problems arise substantially in other domains, we 88 | stand ready to extend this provision to those domains in future versions 89 | of the GPL, as needed to protect the freedom of users. 90 | 91 | Finally, every program is threatened constantly by software patents. 92 | States should not allow patents to restrict development and use of 93 | software on general-purpose computers, but in those that do, we wish to 94 | avoid the special danger that patents applied to a free program could 95 | make it effectively proprietary. To prevent this, the GPL assures that 96 | patents cannot be used to render the program non-free. 97 | 98 | The precise terms and conditions for copying, distribution and 99 | modification follow. 100 | 101 | TERMS AND CONDITIONS 102 | 103 | 0. Definitions. 104 | 105 | "This License" refers to version 3 of the GNU General Public License. 106 | 107 | "Copyright" also means copyright-like laws that apply to other kinds of 108 | works, such as semiconductor masks. 109 | 110 | "The Program" refers to any copyrightable work licensed under this 111 | License. Each licensee is addressed as "you". "Licensees" and 112 | "recipients" may be individuals or organizations. 113 | 114 | To "modify" a work means to copy from or adapt all or part of the work 115 | in a fashion requiring copyright permission, other than the making of an 116 | exact copy. The resulting work is called a "modified version" of the 117 | earlier work or a work "based on" the earlier work. 118 | 119 | A "covered work" means either the unmodified Program or a work based 120 | on the Program. 121 | 122 | To "propagate" a work means to do anything with it that, without 123 | permission, would make you directly or secondarily liable for 124 | infringement under applicable copyright law, except executing it on a 125 | computer or modifying a private copy. Propagation includes copying, 126 | distribution (with or without modification), making available to the 127 | public, and in some countries other activities as well. 128 | 129 | To "convey" a work means any kind of propagation that enables other 130 | parties to make or receive copies. Mere interaction with a user through 131 | a computer network, with no transfer of a copy, is not conveying. 132 | 133 | An interactive user interface displays "Appropriate Legal Notices" 134 | to the extent that it includes a convenient and prominently visible 135 | feature that (1) displays an appropriate copyright notice, and (2) 136 | tells the user that there is no warranty for the work (except to the 137 | extent that warranties are provided), that licensees may convey the 138 | work under this License, and how to view a copy of this License. If 139 | the interface presents a list of user commands or options, such as a 140 | menu, a prominent item in the list meets this criterion. 141 | 142 | 1. Source Code. 143 | 144 | The "source code" for a work means the preferred form of the work 145 | for making modifications to it. "Object code" means any non-source 146 | form of a work. 147 | 148 | A "Standard Interface" means an interface that either is an official 149 | standard defined by a recognized standards body, or, in the case of 150 | interfaces specified for a particular programming language, one that 151 | is widely used among developers working in that language. 152 | 153 | The "System Libraries" of an executable work include anything, other 154 | than the work as a whole, that (a) is included in the normal form of 155 | packaging a Major Component, but which is not part of that Major 156 | Component, and (b) serves only to enable use of the work with that 157 | Major Component, or to implement a Standard Interface for which an 158 | implementation is available to the public in source code form. A 159 | "Major Component", in this context, means a major essential component 160 | (kernel, window system, and so on) of the specific operating system 161 | (if any) on which the executable work runs, or a compiler used to 162 | produce the work, or an object code interpreter used to run it. 163 | 164 | The "Corresponding Source" for a work in object code form means all 165 | the source code needed to generate, install, and (for an executable 166 | work) run the object code and to modify the work, including scripts to 167 | control those activities. However, it does not include the work's 168 | System Libraries, or general-purpose tools or generally available free 169 | programs which are used unmodified in performing those activities but 170 | which are not part of the work. For example, Corresponding Source 171 | includes interface definition files associated with source files for 172 | the work, and the source code for shared libraries and dynamically 173 | linked subprograms that the work is specifically designed to require, 174 | such as by intimate data communication or control flow between those 175 | subprograms and other parts of the work. 176 | 177 | The Corresponding Source need not include anything that users 178 | can regenerate automatically from other parts of the Corresponding 179 | Source. 180 | 181 | The Corresponding Source for a work in source code form is that 182 | same work. 183 | 184 | 2. Basic Permissions. 185 | 186 | All rights granted under this License are granted for the term of 187 | copyright on the Program, and are irrevocable provided the stated 188 | conditions are met. This License explicitly affirms your unlimited 189 | permission to run the unmodified Program. The output from running a 190 | covered work is covered by this License only if the output, given its 191 | content, constitutes a covered work. This License acknowledges your 192 | rights of fair use or other equivalent, as provided by copyright law. 193 | 194 | You may make, run and propagate covered works that you do not 195 | convey, without conditions so long as your license otherwise remains 196 | in force. You may convey covered works to others for the sole purpose 197 | of having them make modifications exclusively for you, or provide you 198 | with facilities for running those works, provided that you comply with 199 | the terms of this License in conveying all material for which you do 200 | not control copyright. Those thus making or running the covered works 201 | for you must do so exclusively on your behalf, under your direction 202 | and control, on terms that prohibit them from making any copies of 203 | your copyrighted material outside their relationship with you. 204 | 205 | Conveying under any other circumstances is permitted solely under 206 | the conditions stated below. Sublicensing is not allowed; section 10 207 | makes it unnecessary. 208 | 209 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 210 | 211 | No covered work shall be deemed part of an effective technological 212 | measure under any applicable law fulfilling obligations under article 213 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 214 | similar laws prohibiting or restricting circumvention of such 215 | measures. 216 | 217 | When you convey a covered work, you waive any legal power to forbid 218 | circumvention of technological measures to the extent such circumvention 219 | is effected by exercising rights under this License with respect to 220 | the covered work, and you disclaim any intention to limit operation or 221 | modification of the work as a means of enforcing, against the work's 222 | users, your or third parties' legal rights to forbid circumvention of 223 | technological measures. 224 | 225 | 4. Conveying Verbatim Copies. 226 | 227 | You may convey verbatim copies of the Program's source code as you 228 | receive it, in any medium, provided that you conspicuously and 229 | appropriately publish on each copy an appropriate copyright notice; 230 | keep intact all notices stating that this License and any 231 | non-permissive terms added in accord with section 7 apply to the code; 232 | keep intact all notices of the absence of any warranty; and give all 233 | recipients a copy of this License along with the Program. 234 | 235 | You may charge any price or no price for each copy that you convey, 236 | and you may offer support or warranty protection for a fee. 237 | 238 | 5. Conveying Modified Source Versions. 239 | 240 | You may convey a work based on the Program, or the modifications to 241 | produce it from the Program, in the form of source code under the 242 | terms of section 4, provided that you also meet all of these conditions: 243 | 244 | a) The work must carry prominent notices stating that you modified 245 | it, and giving a relevant date. 246 | 247 | b) The work must carry prominent notices stating that it is 248 | released under this License and any conditions added under section 249 | 7. This requirement modifies the requirement in section 4 to 250 | "keep intact all notices". 251 | 252 | c) You must license the entire work, as a whole, under this 253 | License to anyone who comes into possession of a copy. This 254 | License will therefore apply, along with any applicable section 7 255 | additional terms, to the whole of the work, and all its parts, 256 | regardless of how they are packaged. This License gives no 257 | permission to license the work in any other way, but it does not 258 | invalidate such permission if you have separately received it. 259 | 260 | d) If the work has interactive user interfaces, each must display 261 | Appropriate Legal Notices; however, if the Program has interactive 262 | interfaces that do not display Appropriate Legal Notices, your 263 | work need not make them do so. 264 | 265 | A compilation of a covered work with other separate and independent 266 | works, which are not by their nature extensions of the covered work, 267 | and which are not combined with it such as to form a larger program, 268 | in or on a volume of a storage or distribution medium, is called an 269 | "aggregate" if the compilation and its resulting copyright are not 270 | used to limit the access or legal rights of the compilation's users 271 | beyond what the individual works permit. Inclusion of a covered work 272 | in an aggregate does not cause this License to apply to the other 273 | parts of the aggregate. 274 | 275 | 6. Conveying Non-Source Forms. 276 | 277 | You may convey a covered work in object code form under the terms 278 | of sections 4 and 5, provided that you also convey the 279 | machine-readable Corresponding Source under the terms of this License, 280 | in one of these ways: 281 | 282 | a) Convey the object code in, or embodied in, a physical product 283 | (including a physical distribution medium), accompanied by the 284 | Corresponding Source fixed on a durable physical medium 285 | customarily used for software interchange. 286 | 287 | b) Convey the object code in, or embodied in, a physical product 288 | (including a physical distribution medium), accompanied by a 289 | written offer, valid for at least three years and valid for as 290 | long as you offer spare parts or customer support for that product 291 | model, to give anyone who possesses the object code either (1) a 292 | copy of the Corresponding Source for all the software in the 293 | product that is covered by this License, on a durable physical 294 | medium customarily used for software interchange, for a price no 295 | more than your reasonable cost of physically performing this 296 | conveying of source, or (2) access to copy the 297 | Corresponding Source from a network server at no charge. 298 | 299 | c) Convey individual copies of the object code with a copy of the 300 | written offer to provide the Corresponding Source. This 301 | alternative is allowed only occasionally and noncommercially, and 302 | only if you received the object code with such an offer, in accord 303 | with subsection 6b. 304 | 305 | d) Convey the object code by offering access from a designated 306 | place (gratis or for a charge), and offer equivalent access to the 307 | Corresponding Source in the same way through the same place at no 308 | further charge. You need not require recipients to copy the 309 | Corresponding Source along with the object code. If the place to 310 | copy the object code is a network server, the Corresponding Source 311 | may be on a different server (operated by you or a third party) 312 | that supports equivalent copying facilities, provided you maintain 313 | clear directions next to the object code saying where to find the 314 | Corresponding Source. Regardless of what server hosts the 315 | Corresponding Source, you remain obligated to ensure that it is 316 | available for as long as needed to satisfy these requirements. 317 | 318 | e) Convey the object code using peer-to-peer transmission, provided 319 | you inform other peers where the object code and Corresponding 320 | Source of the work are being offered to the general public at no 321 | charge under subsection 6d. 322 | 323 | A separable portion of the object code, whose source code is excluded 324 | from the Corresponding Source as a System Library, need not be 325 | included in conveying the object code work. 326 | 327 | A "User Product" is either (1) a "consumer product", which means any 328 | tangible personal property which is normally used for personal, family, 329 | or household purposes, or (2) anything designed or sold for incorporation 330 | into a dwelling. In determining whether a product is a consumer product, 331 | doubtful cases shall be resolved in favor of coverage. For a particular 332 | product received by a particular user, "normally used" refers to a 333 | typical or common use of that class of product, regardless of the status 334 | of the particular user or of the way in which the particular user 335 | actually uses, or expects or is expected to use, the product. A product 336 | is a consumer product regardless of whether the product has substantial 337 | commercial, industrial or non-consumer uses, unless such uses represent 338 | the only significant mode of use of the product. 339 | 340 | "Installation Information" for a User Product means any methods, 341 | procedures, authorization keys, or other information required to install 342 | and execute modified versions of a covered work in that User Product from 343 | a modified version of its Corresponding Source. The information must 344 | suffice to ensure that the continued functioning of the modified object 345 | code is in no case prevented or interfered with solely because 346 | modification has been made. 347 | 348 | If you convey an object code work under this section in, or with, or 349 | specifically for use in, a User Product, and the conveying occurs as 350 | part of a transaction in which the right of possession and use of the 351 | User Product is transferred to the recipient in perpetuity or for a 352 | fixed term (regardless of how the transaction is characterized), the 353 | Corresponding Source conveyed under this section must be accompanied 354 | by the Installation Information. But this requirement does not apply 355 | if neither you nor any third party retains the ability to install 356 | modified object code on the User Product (for example, the work has 357 | been installed in ROM). 358 | 359 | The requirement to provide Installation Information does not include a 360 | requirement to continue to provide support service, warranty, or updates 361 | for a work that has been modified or installed by the recipient, or for 362 | the User Product in which it has been modified or installed. Access to a 363 | network may be denied when the modification itself materially and 364 | adversely affects the operation of the network or violates the rules and 365 | protocols for communication across the network. 366 | 367 | Corresponding Source conveyed, and Installation Information provided, 368 | in accord with this section must be in a format that is publicly 369 | documented (and with an implementation available to the public in 370 | source code form), and must require no special password or key for 371 | unpacking, reading or copying. 372 | 373 | 7. Additional Terms. 374 | 375 | "Additional permissions" are terms that supplement the terms of this 376 | License by making exceptions from one or more of its conditions. 377 | Additional permissions that are applicable to the entire Program shall 378 | be treated as though they were included in this License, to the extent 379 | that they are valid under applicable law. If additional permissions 380 | apply only to part of the Program, that part may be used separately 381 | under those permissions, but the entire Program remains governed by 382 | this License without regard to the additional permissions. 383 | 384 | When you convey a copy of a covered work, you may at your option 385 | remove any additional permissions from that copy, or from any part of 386 | it. (Additional permissions may be written to require their own 387 | removal in certain cases when you modify the work.) You may place 388 | additional permissions on material, added by you to a covered work, 389 | for which you have or can give appropriate copyright permission. 390 | 391 | Notwithstanding any other provision of this License, for material you 392 | add to a covered work, you may (if authorized by the copyright holders of 393 | that material) supplement the terms of this License with terms: 394 | 395 | a) Disclaiming warranty or limiting liability differently from the 396 | terms of sections 15 and 16 of this License; or 397 | 398 | b) Requiring preservation of specified reasonable legal notices or 399 | author attributions in that material or in the Appropriate Legal 400 | Notices displayed by works containing it; or 401 | 402 | c) Prohibiting misrepresentation of the origin of that material, or 403 | requiring that modified versions of such material be marked in 404 | reasonable ways as different from the original version; or 405 | 406 | d) Limiting the use for publicity purposes of names of licensors or 407 | authors of the material; or 408 | 409 | e) Declining to grant rights under trademark law for use of some 410 | trade names, trademarks, or service marks; or 411 | 412 | f) Requiring indemnification of licensors and authors of that 413 | material by anyone who conveys the material (or modified versions of 414 | it) with contractual assumptions of liability to the recipient, for 415 | any liability that these contractual assumptions directly impose on 416 | those licensors and authors. 417 | 418 | All other non-permissive additional terms are considered "further 419 | restrictions" within the meaning of section 10. If the Program as you 420 | received it, or any part of it, contains a notice stating that it is 421 | governed by this License along with a term that is a further 422 | restriction, you may remove that term. If a license document contains 423 | a further restriction but permits relicensing or conveying under this 424 | License, you may add to a covered work material governed by the terms 425 | of that license document, provided that the further restriction does 426 | not survive such relicensing or conveying. 427 | 428 | If you add terms to a covered work in accord with this section, you 429 | must place, in the relevant source files, a statement of the 430 | additional terms that apply to those files, or a notice indicating 431 | where to find the applicable terms. 432 | 433 | Additional terms, permissive or non-permissive, may be stated in the 434 | form of a separately written license, or stated as exceptions; 435 | the above requirements apply either way. 436 | 437 | 8. Termination. 438 | 439 | You may not propagate or modify a covered work except as expressly 440 | provided under this License. Any attempt otherwise to propagate or 441 | modify it is void, and will automatically terminate your rights under 442 | this License (including any patent licenses granted under the third 443 | paragraph of section 11). 444 | 445 | However, if you cease all violation of this License, then your 446 | license from a particular copyright holder is reinstated (a) 447 | provisionally, unless and until the copyright holder explicitly and 448 | finally terminates your license, and (b) permanently, if the copyright 449 | holder fails to notify you of the violation by some reasonable means 450 | prior to 60 days after the cessation. 451 | 452 | Moreover, your license from a particular copyright holder is 453 | reinstated permanently if the copyright holder notifies you of the 454 | violation by some reasonable means, this is the first time you have 455 | received notice of violation of this License (for any work) from that 456 | copyright holder, and you cure the violation prior to 30 days after 457 | your receipt of the notice. 458 | 459 | Termination of your rights under this section does not terminate the 460 | licenses of parties who have received copies or rights from you under 461 | this License. If your rights have been terminated and not permanently 462 | reinstated, you do not qualify to receive new licenses for the same 463 | material under section 10. 464 | 465 | 9. Acceptance Not Required for Having Copies. 466 | 467 | You are not required to accept this License in order to receive or 468 | run a copy of the Program. Ancillary propagation of a covered work 469 | occurring solely as a consequence of using peer-to-peer transmission 470 | to receive a copy likewise does not require acceptance. However, 471 | nothing other than this License grants you permission to propagate or 472 | modify any covered work. These actions infringe copyright if you do 473 | not accept this License. Therefore, by modifying or propagating a 474 | covered work, you indicate your acceptance of this License to do so. 475 | 476 | 10. Automatic Licensing of Downstream Recipients. 477 | 478 | Each time you convey a covered work, the recipient automatically 479 | receives a license from the original licensors, to run, modify and 480 | propagate that work, subject to this License. You are not responsible 481 | for enforcing compliance by third parties with this License. 482 | 483 | An "entity transaction" is a transaction transferring control of an 484 | organization, or substantially all assets of one, or subdividing an 485 | organization, or merging organizations. If propagation of a covered 486 | work results from an entity transaction, each party to that 487 | transaction who receives a copy of the work also receives whatever 488 | licenses to the work the party's predecessor in interest had or could 489 | give under the previous paragraph, plus a right to possession of the 490 | Corresponding Source of the work from the predecessor in interest, if 491 | the predecessor has it or can get it with reasonable efforts. 492 | 493 | You may not impose any further restrictions on the exercise of the 494 | rights granted or affirmed under this License. For example, you may 495 | not impose a license fee, royalty, or other charge for exercise of 496 | rights granted under this License, and you may not initiate litigation 497 | (including a cross-claim or counterclaim in a lawsuit) alleging that 498 | any patent claim is infringed by making, using, selling, offering for 499 | sale, or importing the Program or any portion of it. 500 | 501 | 11. Patents. 502 | 503 | A "contributor" is a copyright holder who authorizes use under this 504 | License of the Program or a work on which the Program is based. The 505 | work thus licensed is called the contributor's "contributor version". 506 | 507 | A contributor's "essential patent claims" are all patent claims 508 | owned or controlled by the contributor, whether already acquired or 509 | hereafter acquired, that would be infringed by some manner, permitted 510 | by this License, of making, using, or selling its contributor version, 511 | but do not include claims that would be infringed only as a 512 | consequence of further modification of the contributor version. For 513 | purposes of this definition, "control" includes the right to grant 514 | patent sublicenses in a manner consistent with the requirements of 515 | this License. 516 | 517 | Each contributor grants you a non-exclusive, worldwide, royalty-free 518 | patent license under the contributor's essential patent claims, to 519 | make, use, sell, offer for sale, import and otherwise run, modify and 520 | propagate the contents of its contributor version. 521 | 522 | In the following three paragraphs, a "patent license" is any express 523 | agreement or commitment, however denominated, not to enforce a patent 524 | (such as an express permission to practice a patent or covenant not to 525 | sue for patent infringement). To "grant" such a patent license to a 526 | party means to make such an agreement or commitment not to enforce a 527 | patent against the party. 528 | 529 | If you convey a covered work, knowingly relying on a patent license, 530 | and the Corresponding Source of the work is not available for anyone 531 | to copy, free of charge and under the terms of this License, through a 532 | publicly available network server or other readily accessible means, 533 | then you must either (1) cause the Corresponding Source to be so 534 | available, or (2) arrange to deprive yourself of the benefit of the 535 | patent license for this particular work, or (3) arrange, in a manner 536 | consistent with the requirements of this License, to extend the patent 537 | license to downstream recipients. "Knowingly relying" means you have 538 | actual knowledge that, but for the patent license, your conveying the 539 | covered work in a country, or your recipient's use of the covered work 540 | in a country, would infringe one or more identifiable patents in that 541 | country that you have reason to believe are valid. 542 | 543 | If, pursuant to or in connection with a single transaction or 544 | arrangement, you convey, or propagate by procuring conveyance of, a 545 | covered work, and grant a patent license to some of the parties 546 | receiving the covered work authorizing them to use, propagate, modify 547 | or convey a specific copy of the covered work, then the patent license 548 | you grant is automatically extended to all recipients of the covered 549 | work and works based on it. 550 | 551 | A patent license is "discriminatory" if it does not include within 552 | the scope of its coverage, prohibits the exercise of, or is 553 | conditioned on the non-exercise of one or more of the rights that are 554 | specifically granted under this License. You may not convey a covered 555 | work if you are a party to an arrangement with a third party that is 556 | in the business of distributing software, under which you make payment 557 | to the third party based on the extent of your activity of conveying 558 | the work, and under which the third party grants, to any of the 559 | parties who would receive the covered work from you, a discriminatory 560 | patent license (a) in connection with copies of the covered work 561 | conveyed by you (or copies made from those copies), or (b) primarily 562 | for and in connection with specific products or compilations that 563 | contain the covered work, unless you entered into that arrangement, 564 | or that patent license was granted, prior to 28 March 2007. 565 | 566 | Nothing in this License shall be construed as excluding or limiting 567 | any implied license or other defenses to infringement that may 568 | otherwise be available to you under applicable patent law. 569 | 570 | 12. No Surrender of Others' Freedom. 571 | 572 | If conditions are imposed on you (whether by court order, agreement or 573 | otherwise) that contradict the conditions of this License, they do not 574 | excuse you from the conditions of this License. If you cannot convey a 575 | covered work so as to satisfy simultaneously your obligations under this 576 | License and any other pertinent obligations, then as a consequence you may 577 | not convey it at all. For example, if you agree to terms that obligate you 578 | to collect a royalty for further conveying from those to whom you convey 579 | the Program, the only way you could satisfy both those terms and this 580 | License would be to refrain entirely from conveying the Program. 581 | 582 | 13. Use with the GNU Affero General Public License. 583 | 584 | Notwithstanding any other provision of this License, you have 585 | permission to link or combine any covered work with a work licensed 586 | under version 3 of the GNU Affero General Public License into a single 587 | combined work, and to convey the resulting work. The terms of this 588 | License will continue to apply to the part which is the covered work, 589 | but the special requirements of the GNU Affero General Public License, 590 | section 13, concerning interaction through a network will apply to the 591 | combination as such. 592 | 593 | 14. Revised Versions of this License. 594 | 595 | The Free Software Foundation may publish revised and/or new versions of 596 | the GNU General Public License from time to time. Such new versions will 597 | be similar in spirit to the present version, but may differ in detail to 598 | address new problems or concerns. 599 | 600 | Each version is given a distinguishing version number. If the 601 | Program specifies that a certain numbered version of the GNU General 602 | Public License "or any later version" applies to it, you have the 603 | option of following the terms and conditions either of that numbered 604 | version or of any later version published by the Free Software 605 | Foundation. If the Program does not specify a version number of the 606 | GNU General Public License, you may choose any version ever published 607 | by the Free Software Foundation. 608 | 609 | If the Program specifies that a proxy can decide which future 610 | versions of the GNU General Public License can be used, that proxy's 611 | public statement of acceptance of a version permanently authorizes you 612 | to choose that version for the Program. 613 | 614 | Later license versions may give you additional or different 615 | permissions. However, no additional obligations are imposed on any 616 | author or copyright holder as a result of your choosing to follow a 617 | later version. 618 | 619 | 15. Disclaimer of Warranty. 620 | 621 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 622 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 623 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 624 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 625 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 626 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 627 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 628 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 629 | 630 | 16. Limitation of Liability. 631 | 632 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 633 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 634 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 635 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 636 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 637 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 638 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 639 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 640 | SUCH DAMAGES. 641 | 642 | 17. Interpretation of Sections 15 and 16. 643 | 644 | If the disclaimer of warranty and limitation of liability provided 645 | above cannot be given local legal effect according to their terms, 646 | reviewing courts shall apply local law that most closely approximates 647 | an absolute waiver of all civil liability in connection with the 648 | Program, unless a warranty or assumption of liability accompanies a 649 | copy of the Program in return for a fee. 650 | 651 | END OF TERMS AND CONDITIONS 652 | -------------------------------------------------------------------------------- /js-zip/jszip-deflate.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Port of a script by Masanao Izumo. 3 | * 4 | * Only changes : wrap all the variables in a function and add the 5 | * main function to JSZip (DEFLATE compression method). 6 | * Everything else was written by M. Izumo. 7 | * 8 | * Original code can be found here: http://www.onicos.com/staff/iz/amuse/javascript/expert/deflate.txt 9 | */ 10 | 11 | if(!JSZip) 12 | { 13 | throw "JSZip not defined"; 14 | } 15 | 16 | /* 17 | * Original: 18 | * http://www.onicos.com/staff/iz/amuse/javascript/expert/deflate.txt 19 | */ 20 | 21 | (function(){ 22 | 23 | /* Copyright (C) 1999 Masanao Izumo 24 | * Version: 1.0.1 25 | * LastModified: Dec 25 1999 26 | */ 27 | 28 | /* Interface: 29 | * data = zip_deflate(src); 30 | */ 31 | 32 | /* constant parameters */ 33 | var zip_WSIZE = 32768; // Sliding Window size 34 | var zip_STORED_BLOCK = 0; 35 | var zip_STATIC_TREES = 1; 36 | var zip_DYN_TREES = 2; 37 | 38 | /* for deflate */ 39 | var zip_DEFAULT_LEVEL = 6; 40 | var zip_FULL_SEARCH = true; 41 | var zip_INBUFSIZ = 32768; // Input buffer size 42 | var zip_INBUF_EXTRA = 64; // Extra buffer 43 | var zip_OUTBUFSIZ = 1024 * 8; 44 | var zip_window_size = 2 * zip_WSIZE; 45 | var zip_MIN_MATCH = 3; 46 | var zip_MAX_MATCH = 258; 47 | var zip_BITS = 16; 48 | // for SMALL_MEM 49 | var zip_LIT_BUFSIZE = 0x2000; 50 | var zip_HASH_BITS = 13; 51 | // for MEDIUM_MEM 52 | // var zip_LIT_BUFSIZE = 0x4000; 53 | // var zip_HASH_BITS = 14; 54 | // for BIG_MEM 55 | // var zip_LIT_BUFSIZE = 0x8000; 56 | // var zip_HASH_BITS = 15; 57 | if(zip_LIT_BUFSIZE > zip_INBUFSIZ) 58 | alert("error: zip_INBUFSIZ is too small"); 59 | if((zip_WSIZE<<1) > (1< zip_BITS-1) 62 | alert("error: zip_HASH_BITS is too large"); 63 | if(zip_HASH_BITS < 8 || zip_MAX_MATCH != 258) 64 | alert("error: Code too clever"); 65 | var zip_DIST_BUFSIZE = zip_LIT_BUFSIZE; 66 | var zip_HASH_SIZE = 1 << zip_HASH_BITS; 67 | var zip_HASH_MASK = zip_HASH_SIZE - 1; 68 | var zip_WMASK = zip_WSIZE - 1; 69 | var zip_NIL = 0; // Tail of hash chains 70 | var zip_TOO_FAR = 4096; 71 | var zip_MIN_LOOKAHEAD = zip_MAX_MATCH + zip_MIN_MATCH + 1; 72 | var zip_MAX_DIST = zip_WSIZE - zip_MIN_LOOKAHEAD; 73 | var zip_SMALLEST = 1; 74 | var zip_MAX_BITS = 15; 75 | var zip_MAX_BL_BITS = 7; 76 | var zip_LENGTH_CODES = 29; 77 | var zip_LITERALS =256; 78 | var zip_END_BLOCK = 256; 79 | var zip_L_CODES = zip_LITERALS + 1 + zip_LENGTH_CODES; 80 | var zip_D_CODES = 30; 81 | var zip_BL_CODES = 19; 82 | var zip_REP_3_6 = 16; 83 | var zip_REPZ_3_10 = 17; 84 | var zip_REPZ_11_138 = 18; 85 | var zip_HEAP_SIZE = 2 * zip_L_CODES + 1; 86 | var zip_H_SHIFT = parseInt((zip_HASH_BITS + zip_MIN_MATCH - 1) / 87 | zip_MIN_MATCH); 88 | 89 | /* variables */ 90 | var zip_free_queue; 91 | var zip_qhead, zip_qtail; 92 | var zip_initflag; 93 | var zip_outbuf = null; 94 | var zip_outcnt, zip_outoff; 95 | var zip_complete; 96 | var zip_window; 97 | var zip_d_buf; 98 | var zip_l_buf; 99 | var zip_prev; 100 | var zip_bi_buf; 101 | var zip_bi_valid; 102 | var zip_block_start; 103 | var zip_ins_h; 104 | var zip_hash_head; 105 | var zip_prev_match; 106 | var zip_match_available; 107 | var zip_match_length; 108 | var zip_prev_length; 109 | var zip_strstart; 110 | var zip_match_start; 111 | var zip_eofile; 112 | var zip_lookahead; 113 | var zip_max_chain_length; 114 | var zip_max_lazy_match; 115 | var zip_compr_level; 116 | var zip_good_match; 117 | var zip_nice_match; 118 | var zip_dyn_ltree; 119 | var zip_dyn_dtree; 120 | var zip_static_ltree; 121 | var zip_static_dtree; 122 | var zip_bl_tree; 123 | var zip_l_desc; 124 | var zip_d_desc; 125 | var zip_bl_desc; 126 | var zip_bl_count; 127 | var zip_heap; 128 | var zip_heap_len; 129 | var zip_heap_max; 130 | var zip_depth; 131 | var zip_length_code; 132 | var zip_dist_code; 133 | var zip_base_length; 134 | var zip_base_dist; 135 | var zip_flag_buf; 136 | var zip_last_lit; 137 | var zip_last_dist; 138 | var zip_last_flags; 139 | var zip_flags; 140 | var zip_flag_bit; 141 | var zip_opt_len; 142 | var zip_static_len; 143 | var zip_deflate_data; 144 | var zip_deflate_pos; 145 | 146 | /* objects (deflate) */ 147 | 148 | var zip_DeflateCT = function() { 149 | this.fc = 0; // frequency count or bit string 150 | this.dl = 0; // father node in Huffman tree or length of bit string 151 | } 152 | 153 | var zip_DeflateTreeDesc = function() { 154 | this.dyn_tree = null; // the dynamic tree 155 | this.static_tree = null; // corresponding static tree or NULL 156 | this.extra_bits = null; // extra bits for each code or NULL 157 | this.extra_base = 0; // base index for extra_bits 158 | this.elems = 0; // max number of elements in the tree 159 | this.max_length = 0; // max bit length for the codes 160 | this.max_code = 0; // largest code with non zero frequency 161 | } 162 | 163 | /* Values for max_lazy_match, good_match and max_chain_length, depending on 164 | * the desired pack level (0..9). The values given below have been tuned to 165 | * exclude worst case performance for pathological files. Better values may be 166 | * found for specific files. 167 | */ 168 | var zip_DeflateConfiguration = function(a, b, c, d) { 169 | this.good_length = a; // reduce lazy search above this match length 170 | this.max_lazy = b; // do not perform lazy search above this match length 171 | this.nice_length = c; // quit search above this match length 172 | this.max_chain = d; 173 | } 174 | 175 | var zip_DeflateBuffer = function() { 176 | this.next = null; 177 | this.len = 0; 178 | this.ptr = new Array(zip_OUTBUFSIZ); 179 | this.off = 0; 180 | } 181 | 182 | /* constant tables */ 183 | var zip_extra_lbits = new Array( 184 | 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0); 185 | var zip_extra_dbits = new Array( 186 | 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13); 187 | var zip_extra_blbits = new Array( 188 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7); 189 | var zip_bl_order = new Array( 190 | 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15); 191 | var zip_configuration_table = new Array( 192 | new zip_DeflateConfiguration(0, 0, 0, 0), 193 | new zip_DeflateConfiguration(4, 4, 8, 4), 194 | new zip_DeflateConfiguration(4, 5, 16, 8), 195 | new zip_DeflateConfiguration(4, 6, 32, 32), 196 | new zip_DeflateConfiguration(4, 4, 16, 16), 197 | new zip_DeflateConfiguration(8, 16, 32, 32), 198 | new zip_DeflateConfiguration(8, 16, 128, 128), 199 | new zip_DeflateConfiguration(8, 32, 128, 256), 200 | new zip_DeflateConfiguration(32, 128, 258, 1024), 201 | new zip_DeflateConfiguration(32, 258, 258, 4096)); 202 | 203 | 204 | /* routines (deflate) */ 205 | 206 | var zip_deflate_start = function(level) { 207 | var i; 208 | 209 | if(!level) 210 | level = zip_DEFAULT_LEVEL; 211 | else if(level < 1) 212 | level = 1; 213 | else if(level > 9) 214 | level = 9; 215 | 216 | zip_compr_level = level; 217 | zip_initflag = false; 218 | zip_eofile = false; 219 | if(zip_outbuf != null) 220 | return; 221 | 222 | zip_free_queue = zip_qhead = zip_qtail = null; 223 | zip_outbuf = new Array(zip_OUTBUFSIZ); 224 | zip_window = new Array(zip_window_size); 225 | zip_d_buf = new Array(zip_DIST_BUFSIZE); 226 | zip_l_buf = new Array(zip_INBUFSIZ + zip_INBUF_EXTRA); 227 | zip_prev = new Array(1 << zip_BITS); 228 | zip_dyn_ltree = new Array(zip_HEAP_SIZE); 229 | for(i = 0; i < zip_HEAP_SIZE; i++) 230 | zip_dyn_ltree[i] = new zip_DeflateCT(); 231 | zip_dyn_dtree = new Array(2*zip_D_CODES+1); 232 | for(i = 0; i < 2*zip_D_CODES+1; i++) 233 | zip_dyn_dtree[i] = new zip_DeflateCT(); 234 | zip_static_ltree = new Array(zip_L_CODES+2); 235 | for(i = 0; i < zip_L_CODES+2; i++) 236 | zip_static_ltree[i] = new zip_DeflateCT(); 237 | zip_static_dtree = new Array(zip_D_CODES); 238 | for(i = 0; i < zip_D_CODES; i++) 239 | zip_static_dtree[i] = new zip_DeflateCT(); 240 | zip_bl_tree = new Array(2*zip_BL_CODES+1); 241 | for(i = 0; i < 2*zip_BL_CODES+1; i++) 242 | zip_bl_tree[i] = new zip_DeflateCT(); 243 | zip_l_desc = new zip_DeflateTreeDesc(); 244 | zip_d_desc = new zip_DeflateTreeDesc(); 245 | zip_bl_desc = new zip_DeflateTreeDesc(); 246 | zip_bl_count = new Array(zip_MAX_BITS+1); 247 | zip_heap = new Array(2*zip_L_CODES+1); 248 | zip_depth = new Array(2*zip_L_CODES+1); 249 | zip_length_code = new Array(zip_MAX_MATCH-zip_MIN_MATCH+1); 250 | zip_dist_code = new Array(512); 251 | zip_base_length = new Array(zip_LENGTH_CODES); 252 | zip_base_dist = new Array(zip_D_CODES); 253 | zip_flag_buf = new Array(parseInt(zip_LIT_BUFSIZE / 8)); 254 | } 255 | 256 | var zip_deflate_end = function() { 257 | zip_free_queue = zip_qhead = zip_qtail = null; 258 | zip_outbuf = null; 259 | zip_window = null; 260 | zip_d_buf = null; 261 | zip_l_buf = null; 262 | zip_prev = null; 263 | zip_dyn_ltree = null; 264 | zip_dyn_dtree = null; 265 | zip_static_ltree = null; 266 | zip_static_dtree = null; 267 | zip_bl_tree = null; 268 | zip_l_desc = null; 269 | zip_d_desc = null; 270 | zip_bl_desc = null; 271 | zip_bl_count = null; 272 | zip_heap = null; 273 | zip_depth = null; 274 | zip_length_code = null; 275 | zip_dist_code = null; 276 | zip_base_length = null; 277 | zip_base_dist = null; 278 | zip_flag_buf = null; 279 | } 280 | 281 | var zip_reuse_queue = function(p) { 282 | p.next = zip_free_queue; 283 | zip_free_queue = p; 284 | } 285 | 286 | var zip_new_queue = function() { 287 | var p; 288 | 289 | if(zip_free_queue != null) 290 | { 291 | p = zip_free_queue; 292 | zip_free_queue = zip_free_queue.next; 293 | } 294 | else 295 | p = new zip_DeflateBuffer(); 296 | p.next = null; 297 | p.len = p.off = 0; 298 | 299 | return p; 300 | } 301 | 302 | var zip_head1 = function(i) { 303 | return zip_prev[zip_WSIZE + i]; 304 | } 305 | 306 | var zip_head2 = function(i, val) { 307 | return zip_prev[zip_WSIZE + i] = val; 308 | } 309 | 310 | /* put_byte is used for the compressed output, put_ubyte for the 311 | * uncompressed output. However unlzw() uses window for its 312 | * suffix table instead of its output buffer, so it does not use put_ubyte 313 | * (to be cleaned up). 314 | */ 315 | var zip_put_byte = function(c) { 316 | zip_outbuf[zip_outoff + zip_outcnt++] = c; 317 | if(zip_outoff + zip_outcnt == zip_OUTBUFSIZ) 318 | zip_qoutbuf(); 319 | } 320 | 321 | /* Output a 16 bit value, lsb first */ 322 | var zip_put_short = function(w) { 323 | w &= 0xffff; 324 | if(zip_outoff + zip_outcnt < zip_OUTBUFSIZ - 2) { 325 | zip_outbuf[zip_outoff + zip_outcnt++] = (w & 0xff); 326 | zip_outbuf[zip_outoff + zip_outcnt++] = (w >>> 8); 327 | } else { 328 | zip_put_byte(w & 0xff); 329 | zip_put_byte(w >>> 8); 330 | } 331 | } 332 | 333 | /* ========================================================================== 334 | * Insert string s in the dictionary and set match_head to the previous head 335 | * of the hash chain (the most recent string with same hash key). Return 336 | * the previous length of the hash chain. 337 | * IN assertion: all calls to to INSERT_STRING are made with consecutive 338 | * input characters and the first MIN_MATCH bytes of s are valid 339 | * (except for the last MIN_MATCH-1 bytes of the input file). 340 | */ 341 | var zip_INSERT_STRING = function() { 342 | zip_ins_h = ((zip_ins_h << zip_H_SHIFT) 343 | ^ (zip_window[zip_strstart + zip_MIN_MATCH - 1] & 0xff)) 344 | & zip_HASH_MASK; 345 | zip_hash_head = zip_head1(zip_ins_h); 346 | zip_prev[zip_strstart & zip_WMASK] = zip_hash_head; 347 | zip_head2(zip_ins_h, zip_strstart); 348 | } 349 | 350 | /* Send a code of the given tree. c and tree must not have side effects */ 351 | var zip_SEND_CODE = function(c, tree) { 352 | zip_send_bits(tree[c].fc, tree[c].dl); 353 | } 354 | 355 | /* Mapping from a distance to a distance code. dist is the distance - 1 and 356 | * must not have side effects. dist_code[256] and dist_code[257] are never 357 | * used. 358 | */ 359 | var zip_D_CODE = function(dist) { 360 | return (dist < 256 ? zip_dist_code[dist] 361 | : zip_dist_code[256 + (dist>>7)]) & 0xff; 362 | } 363 | 364 | /* ========================================================================== 365 | * Compares to subtrees, using the tree depth as tie breaker when 366 | * the subtrees have equal frequency. This minimizes the worst case length. 367 | */ 368 | var zip_SMALLER = function(tree, n, m) { 369 | return tree[n].fc < tree[m].fc || 370 | (tree[n].fc == tree[m].fc && zip_depth[n] <= zip_depth[m]); 371 | } 372 | 373 | /* ========================================================================== 374 | * read string data 375 | */ 376 | var zip_read_buff = function(buff, offset, n) { 377 | var i; 378 | for(i = 0; i < n && zip_deflate_pos < zip_deflate_data.length; i++) 379 | buff[offset + i] = 380 | zip_deflate_data.charCodeAt(zip_deflate_pos++) & 0xff; 381 | return i; 382 | } 383 | 384 | /* ========================================================================== 385 | * Initialize the "longest match" routines for a new file 386 | */ 387 | var zip_lm_init = function() { 388 | var j; 389 | 390 | /* Initialize the hash table. */ 391 | for(j = 0; j < zip_HASH_SIZE; j++) 392 | // zip_head2(j, zip_NIL); 393 | zip_prev[zip_WSIZE + j] = 0; 394 | /* prev will be initialized on the fly */ 395 | 396 | /* Set the default configuration parameters: 397 | */ 398 | zip_max_lazy_match = zip_configuration_table[zip_compr_level].max_lazy; 399 | zip_good_match = zip_configuration_table[zip_compr_level].good_length; 400 | if(!zip_FULL_SEARCH) 401 | zip_nice_match = zip_configuration_table[zip_compr_level].nice_length; 402 | zip_max_chain_length = zip_configuration_table[zip_compr_level].max_chain; 403 | 404 | zip_strstart = 0; 405 | zip_block_start = 0; 406 | 407 | zip_lookahead = zip_read_buff(zip_window, 0, 2 * zip_WSIZE); 408 | if(zip_lookahead <= 0) { 409 | zip_eofile = true; 410 | zip_lookahead = 0; 411 | return; 412 | } 413 | zip_eofile = false; 414 | /* Make sure that we always have enough lookahead. This is important 415 | * if input comes from a device such as a tty. 416 | */ 417 | while(zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile) 418 | zip_fill_window(); 419 | 420 | /* If lookahead < MIN_MATCH, ins_h is garbage, but this is 421 | * not important since only literal bytes will be emitted. 422 | */ 423 | zip_ins_h = 0; 424 | for(j = 0; j < zip_MIN_MATCH - 1; j++) { 425 | // UPDATE_HASH(ins_h, window[j]); 426 | zip_ins_h = ((zip_ins_h << zip_H_SHIFT) ^ (zip_window[j] & 0xff)) & zip_HASH_MASK; 427 | } 428 | } 429 | 430 | /* ========================================================================== 431 | * Set match_start to the longest match starting at the given string and 432 | * return its length. Matches shorter or equal to prev_length are discarded, 433 | * in which case the result is equal to prev_length and match_start is 434 | * garbage. 435 | * IN assertions: cur_match is the head of the hash chain for the current 436 | * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 437 | */ 438 | var zip_longest_match = function(cur_match) { 439 | var chain_length = zip_max_chain_length; // max hash chain length 440 | var scanp = zip_strstart; // current string 441 | var matchp; // matched string 442 | var len; // length of current match 443 | var best_len = zip_prev_length; // best match length so far 444 | 445 | /* Stop when cur_match becomes <= limit. To simplify the code, 446 | * we prevent matches with the string of window index 0. 447 | */ 448 | var limit = (zip_strstart > zip_MAX_DIST ? zip_strstart - zip_MAX_DIST : zip_NIL); 449 | 450 | var strendp = zip_strstart + zip_MAX_MATCH; 451 | var scan_end1 = zip_window[scanp + best_len - 1]; 452 | var scan_end = zip_window[scanp + best_len]; 453 | 454 | /* Do not waste too much time if we already have a good match: */ 455 | if(zip_prev_length >= zip_good_match) 456 | chain_length >>= 2; 457 | 458 | // Assert(encoder->strstart <= window_size-MIN_LOOKAHEAD, "insufficient lookahead"); 459 | 460 | do { 461 | // Assert(cur_match < encoder->strstart, "no future"); 462 | matchp = cur_match; 463 | 464 | /* Skip to next match if the match length cannot increase 465 | * or if the match length is less than 2: 466 | */ 467 | if(zip_window[matchp + best_len] != scan_end || 468 | zip_window[matchp + best_len - 1] != scan_end1 || 469 | zip_window[matchp] != zip_window[scanp] || 470 | zip_window[++matchp] != zip_window[scanp + 1]) { 471 | continue; 472 | } 473 | 474 | /* The check at best_len-1 can be removed because it will be made 475 | * again later. (This heuristic is not always a win.) 476 | * It is not necessary to compare scan[2] and match[2] since they 477 | * are always equal when the other bytes match, given that 478 | * the hash keys are equal and that HASH_BITS >= 8. 479 | */ 480 | scanp += 2; 481 | matchp++; 482 | 483 | /* We check for insufficient lookahead only every 8th comparison; 484 | * the 256th check will be made at strstart+258. 485 | */ 486 | do { 487 | } while(zip_window[++scanp] == zip_window[++matchp] && 488 | zip_window[++scanp] == zip_window[++matchp] && 489 | zip_window[++scanp] == zip_window[++matchp] && 490 | zip_window[++scanp] == zip_window[++matchp] && 491 | zip_window[++scanp] == zip_window[++matchp] && 492 | zip_window[++scanp] == zip_window[++matchp] && 493 | zip_window[++scanp] == zip_window[++matchp] && 494 | zip_window[++scanp] == zip_window[++matchp] && 495 | scanp < strendp); 496 | 497 | len = zip_MAX_MATCH - (strendp - scanp); 498 | scanp = strendp - zip_MAX_MATCH; 499 | 500 | if(len > best_len) { 501 | zip_match_start = cur_match; 502 | best_len = len; 503 | if(zip_FULL_SEARCH) { 504 | if(len >= zip_MAX_MATCH) break; 505 | } else { 506 | if(len >= zip_nice_match) break; 507 | } 508 | 509 | scan_end1 = zip_window[scanp + best_len-1]; 510 | scan_end = zip_window[scanp + best_len]; 511 | } 512 | } while((cur_match = zip_prev[cur_match & zip_WMASK]) > limit 513 | && --chain_length != 0); 514 | 515 | return best_len; 516 | } 517 | 518 | /* ========================================================================== 519 | * Fill the window when the lookahead becomes insufficient. 520 | * Updates strstart and lookahead, and sets eofile if end of input file. 521 | * IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0 522 | * OUT assertions: at least one byte has been read, or eofile is set; 523 | * file reads are performed for at least two bytes (required for the 524 | * translate_eol option). 525 | */ 526 | var zip_fill_window = function() { 527 | var n, m; 528 | 529 | // Amount of free space at the end of the window. 530 | var more = zip_window_size - zip_lookahead - zip_strstart; 531 | 532 | /* If the window is almost full and there is insufficient lookahead, 533 | * move the upper half to the lower one to make room in the upper half. 534 | */ 535 | if(more == -1) { 536 | /* Very unlikely, but possible on 16 bit machine if strstart == 0 537 | * and lookahead == 1 (input done one byte at time) 538 | */ 539 | more--; 540 | } else if(zip_strstart >= zip_WSIZE + zip_MAX_DIST) { 541 | /* By the IN assertion, the window is not empty so we can't confuse 542 | * more == 0 with more == 64K on a 16 bit machine. 543 | */ 544 | // Assert(window_size == (ulg)2*WSIZE, "no sliding with BIG_MEM"); 545 | 546 | // System.arraycopy(window, WSIZE, window, 0, WSIZE); 547 | for(n = 0; n < zip_WSIZE; n++) 548 | zip_window[n] = zip_window[n + zip_WSIZE]; 549 | 550 | zip_match_start -= zip_WSIZE; 551 | zip_strstart -= zip_WSIZE; /* we now have strstart >= MAX_DIST: */ 552 | zip_block_start -= zip_WSIZE; 553 | 554 | for(n = 0; n < zip_HASH_SIZE; n++) { 555 | m = zip_head1(n); 556 | zip_head2(n, m >= zip_WSIZE ? m - zip_WSIZE : zip_NIL); 557 | } 558 | for(n = 0; n < zip_WSIZE; n++) { 559 | /* If n is not on any hash chain, prev[n] is garbage but 560 | * its value will never be used. 561 | */ 562 | m = zip_prev[n]; 563 | zip_prev[n] = (m >= zip_WSIZE ? m - zip_WSIZE : zip_NIL); 564 | } 565 | more += zip_WSIZE; 566 | } 567 | // At this point, more >= 2 568 | if(!zip_eofile) { 569 | n = zip_read_buff(zip_window, zip_strstart + zip_lookahead, more); 570 | if(n <= 0) 571 | zip_eofile = true; 572 | else 573 | zip_lookahead += n; 574 | } 575 | } 576 | 577 | /* ========================================================================== 578 | * Processes a new input file and return its compressed length. This 579 | * function does not perform lazy evaluationof matches and inserts 580 | * new strings in the dictionary only for unmatched strings or for short 581 | * matches. It is used only for the fast compression options. 582 | */ 583 | var zip_deflate_fast = function() { 584 | while(zip_lookahead != 0 && zip_qhead == null) { 585 | var flush; // set if current block must be flushed 586 | 587 | /* Insert the string window[strstart .. strstart+2] in the 588 | * dictionary, and set hash_head to the head of the hash chain: 589 | */ 590 | zip_INSERT_STRING(); 591 | 592 | /* Find the longest match, discarding those <= prev_length. 593 | * At this point we have always match_length < MIN_MATCH 594 | */ 595 | if(zip_hash_head != zip_NIL && 596 | zip_strstart - zip_hash_head <= zip_MAX_DIST) { 597 | /* To simplify the code, we prevent matches with the string 598 | * of window index 0 (in particular we have to avoid a match 599 | * of the string with itself at the start of the input file). 600 | */ 601 | zip_match_length = zip_longest_match(zip_hash_head); 602 | /* longest_match() sets match_start */ 603 | if(zip_match_length > zip_lookahead) 604 | zip_match_length = zip_lookahead; 605 | } 606 | if(zip_match_length >= zip_MIN_MATCH) { 607 | // check_match(strstart, match_start, match_length); 608 | 609 | flush = zip_ct_tally(zip_strstart - zip_match_start, 610 | zip_match_length - zip_MIN_MATCH); 611 | zip_lookahead -= zip_match_length; 612 | 613 | /* Insert new strings in the hash table only if the match length 614 | * is not too large. This saves time but degrades compression. 615 | */ 616 | if(zip_match_length <= zip_max_lazy_match) { 617 | zip_match_length--; // string at strstart already in hash table 618 | do { 619 | zip_strstart++; 620 | zip_INSERT_STRING(); 621 | /* strstart never exceeds WSIZE-MAX_MATCH, so there are 622 | * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH 623 | * these bytes are garbage, but it does not matter since 624 | * the next lookahead bytes will be emitted as literals. 625 | */ 626 | } while(--zip_match_length != 0); 627 | zip_strstart++; 628 | } else { 629 | zip_strstart += zip_match_length; 630 | zip_match_length = 0; 631 | zip_ins_h = zip_window[zip_strstart] & 0xff; 632 | // UPDATE_HASH(ins_h, window[strstart + 1]); 633 | zip_ins_h = ((zip_ins_h< zip_lookahead) 685 | zip_match_length = zip_lookahead; 686 | 687 | /* Ignore a length 3 match if it is too distant: */ 688 | if(zip_match_length == zip_MIN_MATCH && 689 | zip_strstart - zip_match_start > zip_TOO_FAR) { 690 | /* If prev_match is also MIN_MATCH, match_start is garbage 691 | * but we will ignore the current match anyway. 692 | */ 693 | zip_match_length--; 694 | } 695 | } 696 | /* If there was a match at the previous step and the current 697 | * match is not better, output the previous match: 698 | */ 699 | if(zip_prev_length >= zip_MIN_MATCH && 700 | zip_match_length <= zip_prev_length) { 701 | var flush; // set if current block must be flushed 702 | 703 | // check_match(strstart - 1, prev_match, prev_length); 704 | flush = zip_ct_tally(zip_strstart - 1 - zip_prev_match, 705 | zip_prev_length - zip_MIN_MATCH); 706 | 707 | /* Insert in hash table all strings up to the end of the match. 708 | * strstart-1 and strstart are already inserted. 709 | */ 710 | zip_lookahead -= zip_prev_length - 1; 711 | zip_prev_length -= 2; 712 | do { 713 | zip_strstart++; 714 | zip_INSERT_STRING(); 715 | /* strstart never exceeds WSIZE-MAX_MATCH, so there are 716 | * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH 717 | * these bytes are garbage, but it does not matter since the 718 | * next lookahead bytes will always be emitted as literals. 719 | */ 720 | } while(--zip_prev_length != 0); 721 | zip_match_available = 0; 722 | zip_match_length = zip_MIN_MATCH - 1; 723 | zip_strstart++; 724 | if(flush) { 725 | zip_flush_block(0); 726 | zip_block_start = zip_strstart; 727 | } 728 | } else if(zip_match_available != 0) { 729 | /* If there was no match at the previous position, output a 730 | * single literal. If there was a match but the current match 731 | * is longer, truncate the previous match to a single literal. 732 | */ 733 | if(zip_ct_tally(0, zip_window[zip_strstart - 1] & 0xff)) { 734 | zip_flush_block(0); 735 | zip_block_start = zip_strstart; 736 | } 737 | zip_strstart++; 738 | zip_lookahead--; 739 | } else { 740 | /* There is no previous match to compare with, wait for 741 | * the next step to decide. 742 | */ 743 | zip_match_available = 1; 744 | zip_strstart++; 745 | zip_lookahead--; 746 | } 747 | 748 | /* Make sure that we always have enough lookahead, except 749 | * at the end of the input file. We need MAX_MATCH bytes 750 | * for the next match, plus MIN_MATCH bytes to insert the 751 | * string following the next match. 752 | */ 753 | while(zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile) 754 | zip_fill_window(); 755 | } 756 | } 757 | 758 | var zip_init_deflate = function() { 759 | if(zip_eofile) 760 | return; 761 | zip_bi_buf = 0; 762 | zip_bi_valid = 0; 763 | zip_ct_init(); 764 | zip_lm_init(); 765 | 766 | zip_qhead = null; 767 | zip_outcnt = 0; 768 | zip_outoff = 0; 769 | 770 | if(zip_compr_level <= 3) 771 | { 772 | zip_prev_length = zip_MIN_MATCH - 1; 773 | zip_match_length = 0; 774 | } 775 | else 776 | { 777 | zip_match_length = zip_MIN_MATCH - 1; 778 | zip_match_available = 0; 779 | } 780 | 781 | zip_complete = false; 782 | } 783 | 784 | /* ========================================================================== 785 | * Same as above, but achieves better compression. We use a lazy 786 | * evaluation for matches: a match is finally adopted only if there is 787 | * no better match at the next window position. 788 | */ 789 | var zip_deflate_internal = function(buff, off, buff_size) { 790 | var n; 791 | 792 | if(!zip_initflag) 793 | { 794 | zip_init_deflate(); 795 | zip_initflag = true; 796 | if(zip_lookahead == 0) { // empty 797 | zip_complete = true; 798 | return 0; 799 | } 800 | } 801 | 802 | if((n = zip_qcopy(buff, off, buff_size)) == buff_size) 803 | return buff_size; 804 | 805 | if(zip_complete) 806 | return n; 807 | 808 | if(zip_compr_level <= 3) // optimized for speed 809 | zip_deflate_fast(); 810 | else 811 | zip_deflate_better(); 812 | if(zip_lookahead == 0) { 813 | if(zip_match_available != 0) 814 | zip_ct_tally(0, zip_window[zip_strstart - 1] & 0xff); 815 | zip_flush_block(1); 816 | zip_complete = true; 817 | } 818 | return n + zip_qcopy(buff, n + off, buff_size - n); 819 | } 820 | 821 | var zip_qcopy = function(buff, off, buff_size) { 822 | var n, i, j; 823 | 824 | n = 0; 825 | while(zip_qhead != null && n < buff_size) 826 | { 827 | i = buff_size - n; 828 | if(i > zip_qhead.len) 829 | i = zip_qhead.len; 830 | // System.arraycopy(qhead.ptr, qhead.off, buff, off + n, i); 831 | for(j = 0; j < i; j++) 832 | buff[off + n + j] = zip_qhead.ptr[zip_qhead.off + j]; 833 | 834 | zip_qhead.off += i; 835 | zip_qhead.len -= i; 836 | n += i; 837 | if(zip_qhead.len == 0) { 838 | var p; 839 | p = zip_qhead; 840 | zip_qhead = zip_qhead.next; 841 | zip_reuse_queue(p); 842 | } 843 | } 844 | 845 | if(n == buff_size) 846 | return n; 847 | 848 | if(zip_outoff < zip_outcnt) { 849 | i = buff_size - n; 850 | if(i > zip_outcnt - zip_outoff) 851 | i = zip_outcnt - zip_outoff; 852 | // System.arraycopy(outbuf, outoff, buff, off + n, i); 853 | for(j = 0; j < i; j++) 854 | buff[off + n + j] = zip_outbuf[zip_outoff + j]; 855 | zip_outoff += i; 856 | n += i; 857 | if(zip_outcnt == zip_outoff) 858 | zip_outcnt = zip_outoff = 0; 859 | } 860 | return n; 861 | } 862 | 863 | /* ========================================================================== 864 | * Allocate the match buffer, initialize the various tables and save the 865 | * location of the internal file attribute (ascii/binary) and method 866 | * (DEFLATE/STORE). 867 | */ 868 | var zip_ct_init = function() { 869 | var n; // iterates over tree elements 870 | var bits; // bit counter 871 | var length; // length value 872 | var code; // code value 873 | var dist; // distance index 874 | 875 | if(zip_static_dtree[0].dl != 0) return; // ct_init already called 876 | 877 | zip_l_desc.dyn_tree = zip_dyn_ltree; 878 | zip_l_desc.static_tree = zip_static_ltree; 879 | zip_l_desc.extra_bits = zip_extra_lbits; 880 | zip_l_desc.extra_base = zip_LITERALS + 1; 881 | zip_l_desc.elems = zip_L_CODES; 882 | zip_l_desc.max_length = zip_MAX_BITS; 883 | zip_l_desc.max_code = 0; 884 | 885 | zip_d_desc.dyn_tree = zip_dyn_dtree; 886 | zip_d_desc.static_tree = zip_static_dtree; 887 | zip_d_desc.extra_bits = zip_extra_dbits; 888 | zip_d_desc.extra_base = 0; 889 | zip_d_desc.elems = zip_D_CODES; 890 | zip_d_desc.max_length = zip_MAX_BITS; 891 | zip_d_desc.max_code = 0; 892 | 893 | zip_bl_desc.dyn_tree = zip_bl_tree; 894 | zip_bl_desc.static_tree = null; 895 | zip_bl_desc.extra_bits = zip_extra_blbits; 896 | zip_bl_desc.extra_base = 0; 897 | zip_bl_desc.elems = zip_BL_CODES; 898 | zip_bl_desc.max_length = zip_MAX_BL_BITS; 899 | zip_bl_desc.max_code = 0; 900 | 901 | // Initialize the mapping length (0..255) -> length code (0..28) 902 | length = 0; 903 | for(code = 0; code < zip_LENGTH_CODES-1; code++) { 904 | zip_base_length[code] = length; 905 | for(n = 0; n < (1< dist code (0..29) */ 917 | dist = 0; 918 | for(code = 0 ; code < 16; code++) { 919 | zip_base_dist[code] = dist; 920 | for(n = 0; n < (1<>= 7; // from now on, all distances are divided by 128 926 | for( ; code < zip_D_CODES; code++) { 927 | zip_base_dist[code] = dist << 7; 928 | for(n = 0; n < (1<<(zip_extra_dbits[code]-7)); n++) 929 | zip_dist_code[256 + dist++] = code; 930 | } 931 | // Assert (dist == 256, "ct_init: 256+dist != 512"); 932 | 933 | // Construct the codes of the static literal tree 934 | for(bits = 0; bits <= zip_MAX_BITS; bits++) 935 | zip_bl_count[bits] = 0; 936 | n = 0; 937 | while(n <= 143) { zip_static_ltree[n++].dl = 8; zip_bl_count[8]++; } 938 | while(n <= 255) { zip_static_ltree[n++].dl = 9; zip_bl_count[9]++; } 939 | while(n <= 279) { zip_static_ltree[n++].dl = 7; zip_bl_count[7]++; } 940 | while(n <= 287) { zip_static_ltree[n++].dl = 8; zip_bl_count[8]++; } 941 | /* Codes 286 and 287 do not exist, but we must include them in the 942 | * tree construction to get a canonical Huffman tree (longest code 943 | * all ones) 944 | */ 945 | zip_gen_codes(zip_static_ltree, zip_L_CODES + 1); 946 | 947 | /* The static distance tree is trivial: */ 948 | for(n = 0; n < zip_D_CODES; n++) { 949 | zip_static_dtree[n].dl = 5; 950 | zip_static_dtree[n].fc = zip_bi_reverse(n, 5); 951 | } 952 | 953 | // Initialize the first block of the first file: 954 | zip_init_block(); 955 | } 956 | 957 | /* ========================================================================== 958 | * Initialize a new block. 959 | */ 960 | var zip_init_block = function() { 961 | var n; // iterates over tree elements 962 | 963 | // Initialize the trees. 964 | for(n = 0; n < zip_L_CODES; n++) zip_dyn_ltree[n].fc = 0; 965 | for(n = 0; n < zip_D_CODES; n++) zip_dyn_dtree[n].fc = 0; 966 | for(n = 0; n < zip_BL_CODES; n++) zip_bl_tree[n].fc = 0; 967 | 968 | zip_dyn_ltree[zip_END_BLOCK].fc = 1; 969 | zip_opt_len = zip_static_len = 0; 970 | zip_last_lit = zip_last_dist = zip_last_flags = 0; 971 | zip_flags = 0; 972 | zip_flag_bit = 1; 973 | } 974 | 975 | /* ========================================================================== 976 | * Restore the heap property by moving down the tree starting at node k, 977 | * exchanging a node with the smallest of its two sons if necessary, stopping 978 | * when the heap property is re-established (each father smaller than its 979 | * two sons). 980 | */ 981 | var zip_pqdownheap = function( 982 | tree, // the tree to restore 983 | k) { // node to move down 984 | var v = zip_heap[k]; 985 | var j = k << 1; // left son of k 986 | 987 | while(j <= zip_heap_len) { 988 | // Set j to the smallest of the two sons: 989 | if(j < zip_heap_len && 990 | zip_SMALLER(tree, zip_heap[j + 1], zip_heap[j])) 991 | j++; 992 | 993 | // Exit if v is smaller than both sons 994 | if(zip_SMALLER(tree, v, zip_heap[j])) 995 | break; 996 | 997 | // Exchange v with the smallest son 998 | zip_heap[k] = zip_heap[j]; 999 | k = j; 1000 | 1001 | // And continue down the tree, setting j to the left son of k 1002 | j <<= 1; 1003 | } 1004 | zip_heap[k] = v; 1005 | } 1006 | 1007 | /* ========================================================================== 1008 | * Compute the optimal bit lengths for a tree and update the total bit length 1009 | * for the current block. 1010 | * IN assertion: the fields freq and dad are set, heap[heap_max] and 1011 | * above are the tree nodes sorted by increasing frequency. 1012 | * OUT assertions: the field len is set to the optimal bit length, the 1013 | * array bl_count contains the frequencies for each bit length. 1014 | * The length opt_len is updated; static_len is also updated if stree is 1015 | * not null. 1016 | */ 1017 | var zip_gen_bitlen = function(desc) { // the tree descriptor 1018 | var tree = desc.dyn_tree; 1019 | var extra = desc.extra_bits; 1020 | var base = desc.extra_base; 1021 | var max_code = desc.max_code; 1022 | var max_length = desc.max_length; 1023 | var stree = desc.static_tree; 1024 | var h; // heap index 1025 | var n, m; // iterate over the tree elements 1026 | var bits; // bit length 1027 | var xbits; // extra bits 1028 | var f; // frequency 1029 | var overflow = 0; // number of elements with bit length too large 1030 | 1031 | for(bits = 0; bits <= zip_MAX_BITS; bits++) 1032 | zip_bl_count[bits] = 0; 1033 | 1034 | /* In a first pass, compute the optimal bit lengths (which may 1035 | * overflow in the case of the bit length tree). 1036 | */ 1037 | tree[zip_heap[zip_heap_max]].dl = 0; // root of the heap 1038 | 1039 | for(h = zip_heap_max + 1; h < zip_HEAP_SIZE; h++) { 1040 | n = zip_heap[h]; 1041 | bits = tree[tree[n].dl].dl + 1; 1042 | if(bits > max_length) { 1043 | bits = max_length; 1044 | overflow++; 1045 | } 1046 | tree[n].dl = bits; 1047 | // We overwrite tree[n].dl which is no longer needed 1048 | 1049 | if(n > max_code) 1050 | continue; // not a leaf node 1051 | 1052 | zip_bl_count[bits]++; 1053 | xbits = 0; 1054 | if(n >= base) 1055 | xbits = extra[n - base]; 1056 | f = tree[n].fc; 1057 | zip_opt_len += f * (bits + xbits); 1058 | if(stree != null) 1059 | zip_static_len += f * (stree[n].dl + xbits); 1060 | } 1061 | if(overflow == 0) 1062 | return; 1063 | 1064 | // This happens for example on obj2 and pic of the Calgary corpus 1065 | 1066 | // Find the first bit length which could increase: 1067 | do { 1068 | bits = max_length - 1; 1069 | while(zip_bl_count[bits] == 0) 1070 | bits--; 1071 | zip_bl_count[bits]--; // move one leaf down the tree 1072 | zip_bl_count[bits + 1] += 2; // move one overflow item as its brother 1073 | zip_bl_count[max_length]--; 1074 | /* The brother of the overflow item also moves one step up, 1075 | * but this does not affect bl_count[max_length] 1076 | */ 1077 | overflow -= 2; 1078 | } while(overflow > 0); 1079 | 1080 | /* Now recompute all bit lengths, scanning in increasing frequency. 1081 | * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all 1082 | * lengths instead of fixing only the wrong ones. This idea is taken 1083 | * from 'ar' written by Haruhiko Okumura.) 1084 | */ 1085 | for(bits = max_length; bits != 0; bits--) { 1086 | n = zip_bl_count[bits]; 1087 | while(n != 0) { 1088 | m = zip_heap[--h]; 1089 | if(m > max_code) 1090 | continue; 1091 | if(tree[m].dl != bits) { 1092 | zip_opt_len += (bits - tree[m].dl) * tree[m].fc; 1093 | tree[m].fc = bits; 1094 | } 1095 | n--; 1096 | } 1097 | } 1098 | } 1099 | 1100 | /* ========================================================================== 1101 | * Generate the codes for a given tree and bit counts (which need not be 1102 | * optimal). 1103 | * IN assertion: the array bl_count contains the bit length statistics for 1104 | * the given tree and the field len is set for all tree elements. 1105 | * OUT assertion: the field code is set for all tree elements of non 1106 | * zero code length. 1107 | */ 1108 | var zip_gen_codes = function(tree, // the tree to decorate 1109 | max_code) { // largest code with non zero frequency 1110 | var next_code = new Array(zip_MAX_BITS+1); // next code value for each bit length 1111 | var code = 0; // running code value 1112 | var bits; // bit index 1113 | var n; // code index 1114 | 1115 | /* The distribution counts are first used to generate the code values 1116 | * without bit reversal. 1117 | */ 1118 | for(bits = 1; bits <= zip_MAX_BITS; bits++) { 1119 | code = ((code + zip_bl_count[bits-1]) << 1); 1120 | next_code[bits] = code; 1121 | } 1122 | 1123 | /* Check that the bit counts in bl_count are consistent. The last code 1124 | * must be all ones. 1125 | */ 1126 | // Assert (code + encoder->bl_count[MAX_BITS]-1 == (1<> 1; n >= 1; n--) 1193 | zip_pqdownheap(tree, n); 1194 | 1195 | /* Construct the Huffman tree by repeatedly combining the least two 1196 | * frequent nodes. 1197 | */ 1198 | do { 1199 | n = zip_heap[zip_SMALLEST]; 1200 | zip_heap[zip_SMALLEST] = zip_heap[zip_heap_len--]; 1201 | zip_pqdownheap(tree, zip_SMALLEST); 1202 | 1203 | m = zip_heap[zip_SMALLEST]; // m = node of next least frequency 1204 | 1205 | // keep the nodes sorted by frequency 1206 | zip_heap[--zip_heap_max] = n; 1207 | zip_heap[--zip_heap_max] = m; 1208 | 1209 | // Create a new node father of n and m 1210 | tree[node].fc = tree[n].fc + tree[m].fc; 1211 | // depth[node] = (char)(MAX(depth[n], depth[m]) + 1); 1212 | if(zip_depth[n] > zip_depth[m] + 1) 1213 | zip_depth[node] = zip_depth[n]; 1214 | else 1215 | zip_depth[node] = zip_depth[m] + 1; 1216 | tree[n].dl = tree[m].dl = node; 1217 | 1218 | // and insert the new node in the heap 1219 | zip_heap[zip_SMALLEST] = node++; 1220 | zip_pqdownheap(tree, zip_SMALLEST); 1221 | 1222 | } while(zip_heap_len >= 2); 1223 | 1224 | zip_heap[--zip_heap_max] = zip_heap[zip_SMALLEST]; 1225 | 1226 | /* At this point, the fields freq and dad are set. We can now 1227 | * generate the bit lengths. 1228 | */ 1229 | zip_gen_bitlen(desc); 1230 | 1231 | // The field len is now set, we can generate the bit codes 1232 | zip_gen_codes(tree, max_code); 1233 | } 1234 | 1235 | /* ========================================================================== 1236 | * Scan a literal or distance tree to determine the frequencies of the codes 1237 | * in the bit length tree. Updates opt_len to take into account the repeat 1238 | * counts. (The contribution of the bit length codes will be added later 1239 | * during the construction of bl_tree.) 1240 | */ 1241 | var zip_scan_tree = function(tree,// the tree to be scanned 1242 | max_code) { // and its largest code of non zero frequency 1243 | var n; // iterates over all tree elements 1244 | var prevlen = -1; // last emitted length 1245 | var curlen; // length of current code 1246 | var nextlen = tree[0].dl; // length of next code 1247 | var count = 0; // repeat count of the current code 1248 | var max_count = 7; // max repeat count 1249 | var min_count = 4; // min repeat count 1250 | 1251 | if(nextlen == 0) { 1252 | max_count = 138; 1253 | min_count = 3; 1254 | } 1255 | tree[max_code + 1].dl = 0xffff; // guard 1256 | 1257 | for(n = 0; n <= max_code; n++) { 1258 | curlen = nextlen; 1259 | nextlen = tree[n + 1].dl; 1260 | if(++count < max_count && curlen == nextlen) 1261 | continue; 1262 | else if(count < min_count) 1263 | zip_bl_tree[curlen].fc += count; 1264 | else if(curlen != 0) { 1265 | if(curlen != prevlen) 1266 | zip_bl_tree[curlen].fc++; 1267 | zip_bl_tree[zip_REP_3_6].fc++; 1268 | } else if(count <= 10) 1269 | zip_bl_tree[zip_REPZ_3_10].fc++; 1270 | else 1271 | zip_bl_tree[zip_REPZ_11_138].fc++; 1272 | count = 0; prevlen = curlen; 1273 | if(nextlen == 0) { 1274 | max_count = 138; 1275 | min_count = 3; 1276 | } else if(curlen == nextlen) { 1277 | max_count = 6; 1278 | min_count = 3; 1279 | } else { 1280 | max_count = 7; 1281 | min_count = 4; 1282 | } 1283 | } 1284 | } 1285 | 1286 | /* ========================================================================== 1287 | * Send a literal or distance tree in compressed form, using the codes in 1288 | * bl_tree. 1289 | */ 1290 | var zip_send_tree = function(tree, // the tree to be scanned 1291 | max_code) { // and its largest code of non zero frequency 1292 | var n; // iterates over all tree elements 1293 | var prevlen = -1; // last emitted length 1294 | var curlen; // length of current code 1295 | var nextlen = tree[0].dl; // length of next code 1296 | var count = 0; // repeat count of the current code 1297 | var max_count = 7; // max repeat count 1298 | var min_count = 4; // min repeat count 1299 | 1300 | /* tree[max_code+1].dl = -1; */ /* guard already set */ 1301 | if(nextlen == 0) { 1302 | max_count = 138; 1303 | min_count = 3; 1304 | } 1305 | 1306 | for(n = 0; n <= max_code; n++) { 1307 | curlen = nextlen; 1308 | nextlen = tree[n+1].dl; 1309 | if(++count < max_count && curlen == nextlen) { 1310 | continue; 1311 | } else if(count < min_count) { 1312 | do { zip_SEND_CODE(curlen, zip_bl_tree); } while(--count != 0); 1313 | } else if(curlen != 0) { 1314 | if(curlen != prevlen) { 1315 | zip_SEND_CODE(curlen, zip_bl_tree); 1316 | count--; 1317 | } 1318 | // Assert(count >= 3 && count <= 6, " 3_6?"); 1319 | zip_SEND_CODE(zip_REP_3_6, zip_bl_tree); 1320 | zip_send_bits(count - 3, 2); 1321 | } else if(count <= 10) { 1322 | zip_SEND_CODE(zip_REPZ_3_10, zip_bl_tree); 1323 | zip_send_bits(count-3, 3); 1324 | } else { 1325 | zip_SEND_CODE(zip_REPZ_11_138, zip_bl_tree); 1326 | zip_send_bits(count-11, 7); 1327 | } 1328 | count = 0; 1329 | prevlen = curlen; 1330 | if(nextlen == 0) { 1331 | max_count = 138; 1332 | min_count = 3; 1333 | } else if(curlen == nextlen) { 1334 | max_count = 6; 1335 | min_count = 3; 1336 | } else { 1337 | max_count = 7; 1338 | min_count = 4; 1339 | } 1340 | } 1341 | } 1342 | 1343 | /* ========================================================================== 1344 | * Construct the Huffman tree for the bit lengths and return the index in 1345 | * bl_order of the last bit length code to send. 1346 | */ 1347 | var zip_build_bl_tree = function() { 1348 | var max_blindex; // index of last bit length code of non zero freq 1349 | 1350 | // Determine the bit length frequencies for literal and distance trees 1351 | zip_scan_tree(zip_dyn_ltree, zip_l_desc.max_code); 1352 | zip_scan_tree(zip_dyn_dtree, zip_d_desc.max_code); 1353 | 1354 | // Build the bit length tree: 1355 | zip_build_tree(zip_bl_desc); 1356 | /* opt_len now includes the length of the tree representations, except 1357 | * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. 1358 | */ 1359 | 1360 | /* Determine the number of bit length codes to send. The pkzip format 1361 | * requires that at least 4 bit length codes be sent. (appnote.txt says 1362 | * 3 but the actual value used is 4.) 1363 | */ 1364 | for(max_blindex = zip_BL_CODES-1; max_blindex >= 3; max_blindex--) { 1365 | if(zip_bl_tree[zip_bl_order[max_blindex]].dl != 0) break; 1366 | } 1367 | /* Update opt_len to include the bit length tree and counts */ 1368 | zip_opt_len += 3*(max_blindex+1) + 5+5+4; 1369 | // Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", 1370 | // encoder->opt_len, encoder->static_len)); 1371 | 1372 | return max_blindex; 1373 | } 1374 | 1375 | /* ========================================================================== 1376 | * Send the header for a block using dynamic Huffman trees: the counts, the 1377 | * lengths of the bit length codes, the literal tree and the distance tree. 1378 | * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. 1379 | */ 1380 | var zip_send_all_trees = function(lcodes, dcodes, blcodes) { // number of codes for each tree 1381 | var rank; // index in bl_order 1382 | 1383 | // Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); 1384 | // Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, 1385 | // "too many codes"); 1386 | // Tracev((stderr, "\nbl counts: ")); 1387 | zip_send_bits(lcodes-257, 5); // not +255 as stated in appnote.txt 1388 | zip_send_bits(dcodes-1, 5); 1389 | zip_send_bits(blcodes-4, 4); // not -3 as stated in appnote.txt 1390 | for(rank = 0; rank < blcodes; rank++) { 1391 | // Tracev((stderr, "\nbl code %2d ", bl_order[rank])); 1392 | zip_send_bits(zip_bl_tree[zip_bl_order[rank]].dl, 3); 1393 | } 1394 | 1395 | // send the literal tree 1396 | zip_send_tree(zip_dyn_ltree,lcodes-1); 1397 | 1398 | // send the distance tree 1399 | zip_send_tree(zip_dyn_dtree,dcodes-1); 1400 | } 1401 | 1402 | /* ========================================================================== 1403 | * Determine the best encoding for the current block: dynamic trees, static 1404 | * trees or store, and output the encoded block to the zip file. 1405 | */ 1406 | var zip_flush_block = function(eof) { // true if this is the last block for a file 1407 | var opt_lenb, static_lenb; // opt_len and static_len in bytes 1408 | var max_blindex; // index of last bit length code of non zero freq 1409 | var stored_len; // length of input block 1410 | 1411 | stored_len = zip_strstart - zip_block_start; 1412 | zip_flag_buf[zip_last_flags] = zip_flags; // Save the flags for the last 8 items 1413 | 1414 | // Construct the literal and distance trees 1415 | zip_build_tree(zip_l_desc); 1416 | // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", 1417 | // encoder->opt_len, encoder->static_len)); 1418 | 1419 | zip_build_tree(zip_d_desc); 1420 | // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", 1421 | // encoder->opt_len, encoder->static_len)); 1422 | /* At this point, opt_len and static_len are the total bit lengths of 1423 | * the compressed block data, excluding the tree representations. 1424 | */ 1425 | 1426 | /* Build the bit length tree for the above two trees, and get the index 1427 | * in bl_order of the last bit length code to send. 1428 | */ 1429 | max_blindex = zip_build_bl_tree(); 1430 | 1431 | // Determine the best encoding. Compute first the block length in bytes 1432 | opt_lenb = (zip_opt_len +3+7)>>3; 1433 | static_lenb = (zip_static_len+3+7)>>3; 1434 | 1435 | // Trace((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ", 1436 | // opt_lenb, encoder->opt_len, 1437 | // static_lenb, encoder->static_len, stored_len, 1438 | // encoder->last_lit, encoder->last_dist)); 1439 | 1440 | if(static_lenb <= opt_lenb) 1441 | opt_lenb = static_lenb; 1442 | if(stored_len + 4 <= opt_lenb // 4: two words for the lengths 1443 | && zip_block_start >= 0) { 1444 | var i; 1445 | 1446 | /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. 1447 | * Otherwise we can't have processed more than WSIZE input bytes since 1448 | * the last block flush, because compression would have been 1449 | * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to 1450 | * transform a block into a stored block. 1451 | */ 1452 | zip_send_bits((zip_STORED_BLOCK<<1)+eof, 3); /* send block type */ 1453 | zip_bi_windup(); /* align on byte boundary */ 1454 | zip_put_short(stored_len); 1455 | zip_put_short(~stored_len); 1456 | 1457 | // copy block 1458 | /* 1459 | p = &window[block_start]; 1460 | for(i = 0; i < stored_len; i++) 1461 | put_byte(p[i]); 1462 | */ 1463 | for(i = 0; i < stored_len; i++) 1464 | zip_put_byte(zip_window[zip_block_start + i]); 1465 | 1466 | } else if(static_lenb == opt_lenb) { 1467 | zip_send_bits((zip_STATIC_TREES<<1)+eof, 3); 1468 | zip_compress_block(zip_static_ltree, zip_static_dtree); 1469 | } else { 1470 | zip_send_bits((zip_DYN_TREES<<1)+eof, 3); 1471 | zip_send_all_trees(zip_l_desc.max_code+1, 1472 | zip_d_desc.max_code+1, 1473 | max_blindex+1); 1474 | zip_compress_block(zip_dyn_ltree, zip_dyn_dtree); 1475 | } 1476 | 1477 | zip_init_block(); 1478 | 1479 | if(eof != 0) 1480 | zip_bi_windup(); 1481 | } 1482 | 1483 | /* ========================================================================== 1484 | * Save the match info and tally the frequency counts. Return true if 1485 | * the current block must be flushed. 1486 | */ 1487 | var zip_ct_tally = function( 1488 | dist, // distance of matched string 1489 | lc) { // match length-MIN_MATCH or unmatched char (if dist==0) 1490 | zip_l_buf[zip_last_lit++] = lc; 1491 | if(dist == 0) { 1492 | // lc is the unmatched char 1493 | zip_dyn_ltree[lc].fc++; 1494 | } else { 1495 | // Here, lc is the match length - MIN_MATCH 1496 | dist--; // dist = match distance - 1 1497 | // Assert((ush)dist < (ush)MAX_DIST && 1498 | // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && 1499 | // (ush)D_CODE(dist) < (ush)D_CODES, "ct_tally: bad match"); 1500 | 1501 | zip_dyn_ltree[zip_length_code[lc]+zip_LITERALS+1].fc++; 1502 | zip_dyn_dtree[zip_D_CODE(dist)].fc++; 1503 | 1504 | zip_d_buf[zip_last_dist++] = dist; 1505 | zip_flags |= zip_flag_bit; 1506 | } 1507 | zip_flag_bit <<= 1; 1508 | 1509 | // Output the flags if they fill a byte 1510 | if((zip_last_lit & 7) == 0) { 1511 | zip_flag_buf[zip_last_flags++] = zip_flags; 1512 | zip_flags = 0; 1513 | zip_flag_bit = 1; 1514 | } 1515 | // Try to guess if it is profitable to stop the current block here 1516 | if(zip_compr_level > 2 && (zip_last_lit & 0xfff) == 0) { 1517 | // Compute an upper bound for the compressed length 1518 | var out_length = zip_last_lit * 8; 1519 | var in_length = zip_strstart - zip_block_start; 1520 | var dcode; 1521 | 1522 | for(dcode = 0; dcode < zip_D_CODES; dcode++) { 1523 | out_length += zip_dyn_dtree[dcode].fc * (5 + zip_extra_dbits[dcode]); 1524 | } 1525 | out_length >>= 3; 1526 | // Trace((stderr,"\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ", 1527 | // encoder->last_lit, encoder->last_dist, in_length, out_length, 1528 | // 100L - out_length*100L/in_length)); 1529 | if(zip_last_dist < parseInt(zip_last_lit/2) && 1530 | out_length < parseInt(in_length/2)) 1531 | return true; 1532 | } 1533 | return (zip_last_lit == zip_LIT_BUFSIZE-1 || 1534 | zip_last_dist == zip_DIST_BUFSIZE); 1535 | /* We avoid equality with LIT_BUFSIZE because of wraparound at 64K 1536 | * on 16 bit machines and because stored blocks are restricted to 1537 | * 64K-1 bytes. 1538 | */ 1539 | } 1540 | 1541 | /* ========================================================================== 1542 | * Send the block data compressed using the given Huffman trees 1543 | */ 1544 | var zip_compress_block = function( 1545 | ltree, // literal tree 1546 | dtree) { // distance tree 1547 | var dist; // distance of matched string 1548 | var lc; // match length or unmatched char (if dist == 0) 1549 | var lx = 0; // running index in l_buf 1550 | var dx = 0; // running index in d_buf 1551 | var fx = 0; // running index in flag_buf 1552 | var flag = 0; // current flags 1553 | var code; // the code to send 1554 | var extra; // number of extra bits to send 1555 | 1556 | if(zip_last_lit != 0) do { 1557 | if((lx & 7) == 0) 1558 | flag = zip_flag_buf[fx++]; 1559 | lc = zip_l_buf[lx++] & 0xff; 1560 | if((flag & 1) == 0) { 1561 | zip_SEND_CODE(lc, ltree); /* send a literal byte */ 1562 | // Tracecv(isgraph(lc), (stderr," '%c' ", lc)); 1563 | } else { 1564 | // Here, lc is the match length - MIN_MATCH 1565 | code = zip_length_code[lc]; 1566 | zip_SEND_CODE(code+zip_LITERALS+1, ltree); // send the length code 1567 | extra = zip_extra_lbits[code]; 1568 | if(extra != 0) { 1569 | lc -= zip_base_length[code]; 1570 | zip_send_bits(lc, extra); // send the extra length bits 1571 | } 1572 | dist = zip_d_buf[dx++]; 1573 | // Here, dist is the match distance - 1 1574 | code = zip_D_CODE(dist); 1575 | // Assert (code < D_CODES, "bad d_code"); 1576 | 1577 | zip_SEND_CODE(code, dtree); // send the distance code 1578 | extra = zip_extra_dbits[code]; 1579 | if(extra != 0) { 1580 | dist -= zip_base_dist[code]; 1581 | zip_send_bits(dist, extra); // send the extra distance bits 1582 | } 1583 | } // literal or match pair ? 1584 | flag >>= 1; 1585 | } while(lx < zip_last_lit); 1586 | 1587 | zip_SEND_CODE(zip_END_BLOCK, ltree); 1588 | } 1589 | 1590 | /* ========================================================================== 1591 | * Send a value on a given number of bits. 1592 | * IN assertion: length <= 16 and value fits in length bits. 1593 | */ 1594 | var zip_Buf_size = 16; // bit size of bi_buf 1595 | var zip_send_bits = function( 1596 | value, // value to send 1597 | length) { // number of bits 1598 | /* If not enough room in bi_buf, use (valid) bits from bi_buf and 1599 | * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) 1600 | * unused bits in value. 1601 | */ 1602 | if(zip_bi_valid > zip_Buf_size - length) { 1603 | zip_bi_buf |= (value << zip_bi_valid); 1604 | zip_put_short(zip_bi_buf); 1605 | zip_bi_buf = (value >> (zip_Buf_size - zip_bi_valid)); 1606 | zip_bi_valid += length - zip_Buf_size; 1607 | } else { 1608 | zip_bi_buf |= value << zip_bi_valid; 1609 | zip_bi_valid += length; 1610 | } 1611 | } 1612 | 1613 | /* ========================================================================== 1614 | * Reverse the first len bits of a code, using straightforward code (a faster 1615 | * method would use a table) 1616 | * IN assertion: 1 <= len <= 15 1617 | */ 1618 | var zip_bi_reverse = function( 1619 | code, // the value to invert 1620 | len) { // its bit length 1621 | var res = 0; 1622 | do { 1623 | res |= code & 1; 1624 | code >>= 1; 1625 | res <<= 1; 1626 | } while(--len > 0); 1627 | return res >> 1; 1628 | } 1629 | 1630 | /* ========================================================================== 1631 | * Write out any remaining bits in an incomplete byte. 1632 | */ 1633 | var zip_bi_windup = function() { 1634 | if(zip_bi_valid > 8) { 1635 | zip_put_short(zip_bi_buf); 1636 | } else if(zip_bi_valid > 0) { 1637 | zip_put_byte(zip_bi_buf); 1638 | } 1639 | zip_bi_buf = 0; 1640 | zip_bi_valid = 0; 1641 | } 1642 | 1643 | var zip_qoutbuf = function() { 1644 | if(zip_outcnt != 0) { 1645 | var q, i; 1646 | q = zip_new_queue(); 1647 | if(zip_qhead == null) 1648 | zip_qhead = zip_qtail = q; 1649 | else 1650 | zip_qtail = zip_qtail.next = q; 1651 | q.len = zip_outcnt - zip_outoff; 1652 | // System.arraycopy(zip_outbuf, zip_outoff, q.ptr, 0, q.len); 1653 | for(i = 0; i < q.len; i++) 1654 | q.ptr[i] = zip_outbuf[zip_outoff + i]; 1655 | zip_outcnt = zip_outoff = 0; 1656 | } 1657 | } 1658 | 1659 | var zip_deflate = function(str, level) { 1660 | var i, j; 1661 | 1662 | zip_deflate_data = str; 1663 | zip_deflate_pos = 0; 1664 | if(typeof level == "undefined") 1665 | level = zip_DEFAULT_LEVEL; 1666 | zip_deflate_start(level); 1667 | 1668 | var buff = new Array(1024); 1669 | var aout = []; 1670 | while((i = zip_deflate_internal(buff, 0, buff.length)) > 0) { 1671 | var cbuf = new Array(i); 1672 | for(j = 0; j < i; j++){ 1673 | cbuf[j] = String.fromCharCode(buff[j]); 1674 | } 1675 | aout[aout.length] = cbuf.join(""); 1676 | } 1677 | zip_deflate_data = null; // G.C. 1678 | return aout.join(""); 1679 | } 1680 | 1681 | // 1682 | // end of the script of Masanao Izumo. 1683 | // 1684 | 1685 | // we add the compression method for JSZip 1686 | if(!JSZip.compressions["DEFLATE"]) { 1687 | JSZip.compressions["DEFLATE"] = { 1688 | magic : "\x08\x00", 1689 | compress : zip_deflate 1690 | } 1691 | } else { 1692 | JSZip.compressions["DEFLATE"].compress = zip_deflate; 1693 | } 1694 | 1695 | })(); 1696 | --------------------------------------------------------------------------------