1/* 2Copyright (c) 2017 Marcel Greter (http://github.com/mgreter) 3 4Permission is hereby granted, free of charge, to any person obtaining a copy 5of this software and associated documentation files (the "Software"), to deal 6in the Software without restriction, including without limitation the rights 7to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8copies of the Software, and to permit persons to whom the Software is 9furnished to do so, subject to the following conditions: 10 11The above copyright notice and this permission notice shall be included in 12all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20THE SOFTWARE. 21*/ 22 23var LZMA = LZMA || {}; 24 25(function (LZMA) { 26 27 // very simple in memory input stream class 28 LZMA.iStream = function(buffer) 29 { 30 // create byte array view of buffer 31 this.array = new Uint8Array(buffer); 32 // convenience status member 33 this.size = buffer.byteLength; 34 // position pointer 35 this.offset = 0; 36 } 37 38 // simply return the next byte from memory 39 LZMA.iStream.prototype.readByte = function() 40 { 41 // advance pointer and return byte 42 return this.array[this.offset++]; 43 } 44 45 // output stream constructor 46 LZMA.oStream = function(buffers) 47 { 48 // aggregated size 49 this.size = 0; 50 // initialize empty 51 this.buffers = []; 52 buffers = buffers || []; 53 // make sure size matches data 54 for (var i = 0, L = buffers.length; i < L; i++) { 55 // unwrap nested output streams 56 if (buffers[i] instanceof LZMA.oStream) { 57 var oBuffers = buffers[i].buffers; 58 for (var n = 0; n < oBuffers.length; n++) { 59 this.buffers.push(buffers[i].buffers[n]); 60 this.size += buffers[i].buffers[n].length; 61 } 62 } else { 63 // simply append the one buffer 64 this.buffers.push(buffers[i]); 65 this.size += buffers[i].length; 66 } 67 } 68 } 69 70 // we expect a Uint8Array buffer and the size to read from 71 // creates a copy of the buffer as needed so you can re-use it 72 // tests with js-lzma have shown that this is at most for 16MB 73 LZMA.oStream.prototype.writeBytes = function writeBytes(buffer, size) 74 { 75 // can we just take the full buffer? 76 // or just some part of the buffer? 77 if (size <= buffer.byteLength) { 78 // we need to make a copy, as the original 79 // buffer will be re-used. No way around! 80 this.buffers.push(buffer.slice(0, size)); 81 } 82 // assertion for out of boundary access 83 else { throw Error("Buffer too small?"); } 84 // increase counter 85 this.size += size; 86 } 87 88 // return a continous Uint8Array with the full content 89 // the typed array is guaranteed to have to correct length 90 // also meaning that there is no space remaining to add more 91 // you may should expect malloc errors if size gets a few 10MB 92 // calling this repeatedly always returns the same array instance 93 // NOTE: An alternative approach would be to use a Blob. A Blob 94 // can be created out of an array of array chunks (our buffers). 95 // Via a FileReader we can then convert it back to a continous 96 // Uint8Array. But this would make this method async in nature! 97 LZMA.oStream.prototype.toUint8Array = function toUint8Array() 98 { 99 // local variable access 100 var size = this.size, 101 buffers = this.buffers; 102 103 // the simple case with only one buffer 104 if (buffers.length == 1) { 105 // make a copy if needed! 106 return buffers[0]; 107 } 108 // otherwise we need to concat them all now 109 try { 110 // allocate the continous memory chunk 111 var continous = new Uint8Array(size); 112 // process each buffer in the output queue 113 for (var i = 0, offset = 0; i < buffers.length; i++) { 114 continous.set(buffers[i], offset); 115 offset += buffers[i].length; 116 } 117 // release memory chunks 118 buffers[0] = continous; 119 // only one chunk left 120 buffers.length = 1; 121 // return typed array 122 return continous; 123 // Asynchronous alternative: 124 // var blob = new Blob(outStream.buffers); 125 // var reader = new FileReader(); 126 // reader.onload = function() { ... }; 127 // reader.readAsArrayBuffer(blob); 128 } 129 // probably allocation error 130 catch (err) { 131 // this error is somewhat expected so you should take care of it
132 console.error("Error allocating Uint8Array of size: ", size); 133 console.error("Message given was: ", err.toString()); 134 } 135 // malloc error 136 return null; 137 } 138 139 // invoke fn on every Uint8Array in the stream 140 // using this interface can avoid the need to 141 // create a full continous buffer of the result 142 LZMA.oStream.prototype.forEach = function forEach(fn) 143 { 144 for (var i = 0; i < this.buffers.length; i++) { 145 fn.call(this, this.buffers[i]); 146 } 147 } 148 149 // returns a typed array of codepoints; depending if 150 // UTF8 decoder is loaded, we treat the byte sequence 151 // either as an UTF8 sequence or fixed one byte encoding 152 // the result can then be converted back to a JS string 153 LZMA.oStream.prototype.toCodePoints = function toCodePoints() 154 { 155 // treat as one byte encoding (i.e. US-ASCII) 156 if (!LZMA.UTF8) { this.toUint8Array(); } 157 // we could probably make this work with our chunked 158 // buffers directly, but unsure how much we could gain 159 return LZMA.UTF8.decode(this.toUint8Array()); 160 } 161 162 // convert the buffer to a javascript string object 163 LZMA.oStream.prototype.toString = function toString() 164 { 165 var buffers = this.buffers, string = ''; 166 // optionally get the UTF8 codepoints 167 // possibly avoid creating a continous buffer 168 if (LZMA.UTF8) buffers = [ this.toCodePoints() ]; 169 for (var n = 0, nL = buffers.length; n < nL; n++) { 170 for (var i = 0, iL = buffers[n].length; i < iL; i++) { 171 string += String.fromCharCode(buffers[n][i]); 172 } 173 } 174 return string; 175 } 176 177})(LZMA);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.