Adds LZMA to ByteArray.uncompress

This commit is contained in:
Yury Delendik 2015-01-31 16:35:12 -06:00
Родитель baedad115d
Коммит b1b5c832c1
8 изменённых файлов: 81 добавлений и 28 удалений

Просмотреть файл

@ -797,7 +797,7 @@ module Shumway.ArrayUtilities {
var output = new DataBuffer();
deflate.onData = output.writeRawBytes.bind(output);
deflate.push(this._u8.subarray(0, this._length));
deflate.finish();
deflate.close();
this._ensureCapacity(output._u8.length);
this._u8.set(output._u8);
@ -808,7 +808,7 @@ module Shumway.ArrayUtilities {
private _uncompress(algorithm: string): void {
algorithm = asCoerceString(algorithm);
var inflate: Inflate;
var inflate: IDataDecoder;
switch (algorithm) {
case 'zlib':
inflate = Inflate.create(true);
@ -816,14 +816,19 @@ module Shumway.ArrayUtilities {
case 'deflate':
inflate = Inflate.create(false);
break;
case 'lzma':
inflate = new LzmaDecoder(false);
break;
default:
return;
}
var output = new DataBuffer();
var error;
inflate.onData = output.writeRawBytes.bind(output);
inflate.onError = (e) => error = e;
inflate.push(this._u8.subarray(0, this._length));
if (inflate.error) {
if (error) {
throwError('IOError', Errors.CompressedDataError);
}
inflate.close();

Просмотреть файл

@ -54,14 +54,10 @@ module Shumway.ArrayUtilities {
export class Inflate implements IDataDecoder {
public onData:(buffer:Uint8Array) => void;
_error: any;
public get error() {
return this._error;
}
public onError: (e) => void;
constructor(verifyHeader: boolean) {
this._error = null;
//
}
public push(data: Uint8Array) {
@ -94,7 +90,9 @@ module Shumway.ArrayUtilities {
error = 'inflate: FDICT bit set';
}
if (error) {
this._error = error;
if (this.onError) {
this.onError(error);
}
return -1;
} else {
return ZLIB_HEADER_SIZE;
@ -131,10 +129,6 @@ module Shumway.ArrayUtilities {
private _block2State: DeflateBlock2State;
private _copyState: DeflateCopyState;
public get error() {
return this._error;
}
constructor(verifyHeader: boolean) {
super(verifyHeader);
this._buffer = null;
@ -157,7 +151,6 @@ module Shumway.ArrayUtilities {
dist: 0,
distBits: 0
};
this._error = undefined;
if (!areTablesInitialized) {
initializeTables();
@ -278,7 +271,7 @@ module Shumway.ArrayUtilities {
var length2 = buffer[position + 2] | (buffer[position + 3] << 8);
position += 4;
if ((length ^ length2) !== 0xFFFF) {
this._error = 'inflate: invalid block 0 length';
this._error('inflate: invalid block 0 length');
state = InflateState.ERROR;
break;
}
@ -337,7 +330,7 @@ module Shumway.ArrayUtilities {
state = InflateState.BLOCK_2_PRE;
break;
default:
this._error = 'inflate: unsupported block type';
this._error('inflate: unsupported block type');
state = InflateState.ERROR;
return false;
}
@ -348,6 +341,11 @@ module Shumway.ArrayUtilities {
this._bitLength = bitLength;
return false;
}
private _error(e: string) {
if (this.onError) {
this.onError(e);
}
}
private _decodeBlock0() {
var position = this._bufferPosition;
var windowPosition = this._windowPosition;
@ -414,7 +412,7 @@ module Shumway.ArrayUtilities {
var code = codeTable.codes[bitBuffer & ((1 << maxBits) - 1)];
var len = code >> 16;
if ((code & 0x8000)) {
this._error = 'inflate: invalid encoding';
this._error('inflate: invalid encoding');
this._state = InflateState.ERROR;
return -1;
}
@ -693,9 +691,7 @@ module Shumway.ArrayUtilities {
data = buffer.subarray(processed);
}
}
if (!this._error) {
this._specialInflate.push(data);
}
this._specialInflate.push(data);
}
public close() {
@ -737,8 +733,9 @@ module Shumway.ArrayUtilities {
}
}
export class Deflate {
export class Deflate implements IDataDecoder {
public onData: (data: Uint8Array) => void;
public onError: (e) => void;
private _writeZlibHeader: boolean;
private _state: DeflateState;
@ -789,7 +786,7 @@ module Shumway.ArrayUtilities {
}
}
public finish() {
public close() {
this._state = DeflateState.DONE;
this.onData(new Uint8Array([
0x01,

Просмотреть файл

@ -666,6 +666,7 @@ module Shumway.ArrayUtilities {
export class LzmaDecoder implements IDataDecoder {
public onData: (data: Uint8Array) => void;
public onError: (e) => void;
private _state: LzmaDecoderState;
buffer: Uint8Array;
private _inStream: InputStream;
@ -752,17 +753,22 @@ module Shumway.ArrayUtilities {
}
private _checkError(res) {
var error;
if (res === LZMA_RES_ERROR) {
throw new Error("LZMA decoding error");
error = "LZMA decoding error";
} else if (res === LZMA_RES_NOT_COMPLETE) {
throw new Error("Decoding is not complete");
error = "Decoding is not complete";
} else if (res === LZMA_RES_FINISHED_WITH_MARKER) {
if (this._decoder.unpackSize !== undefined &&
this._decoder.unpackSize !== this._outStream.processed) {
throw new Error("Finished with end marker before than specified size");
error = "Finished with end marker before than specified size";
}
} else {
throw new Error("Internal Error");
error = "Internal LZMA Error";
}
if (error && this.onError) {
this.onError(error);
}
}
}

Просмотреть файл

@ -585,6 +585,7 @@ module Shumway {
export interface IDataDecoder {
onData: (data: Uint8Array) => void;
onError: (e) => void;
push(data: Uint8Array);
close();
}

41
test/swfs/lzma_bytes.as Normal file
Просмотреть файл

@ -0,0 +1,41 @@
/**
* Compiled with:
* node ./utils/compileabc.js --swf LzmaBytesTest,600,600,60 -p test/swfs/lzma_bytes.as
*/
package {
import flash.display.Sprite;
import flash.utils.ByteArray;
import flash.system.fscommand;
public class LzmaBytesTest extends Sprite {
public function LzmaBytesTest() {
var bytes = [93, 0, 0, 16, 0, 19, 0, 0, 0, 0, 0, 0, 0,
0, 34, 25, 73, -89, 30, -111, 20, -25, 96,
-50, -33, -3, -28, -126, 36, 55, -94, 119, 0];
var ba:ByteArray = new ByteArray();
var i:int;
for (i = 0; i < bytes.length; i++) {
ba.writeByte(bytes[i]);
}
ba.position = 0;
ba.uncompress('lzma');
var s:String = '';
ba.position = 0;
for (i = 0; i < ba.length; i++) {
s += String.fromCharCode(ba.readByte());
}
trace(ba.length);
trace(s);
fscommand("quit");
}
}
}

Двоичные данные
test/swfs/lzma_bytes.swf Executable file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,2 @@
19
Demo LZMA demo demo

Просмотреть файл

@ -68,7 +68,8 @@
{ "id": "lzma",
"stas": "swfs/lzma.stas",
"filenames": [
"swfs/lzma.swf"
"swfs/lzma.swf",
"swfs/lzma_bytes.swf"
],
"type": "stas"
},