/
inflate_stream.js
117 lines (98 loc) · 2.78 KB
/
inflate_stream.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
goog.provide('Zlib.InflateStream');
goog.require('USE_TYPEDARRAY');
goog.require('Zlib');
//goog.require('Zlib.Adler32');
goog.require('Zlib.RawInflateStream');
goog.scope(function() {
/**
* @param {!(Uint8Array|Array)} input deflated buffer.
* @constructor
*/
Zlib.InflateStream = function(input) {
/** @type {!(Uint8Array|Array)} */
this.input = input === void 0 ? new (USE_TYPEDARRAY ? Uint8Array : Array)() : input;
/** @type {number} */
this.ip = 0;
/** @type {Zlib.RawInflateStream} */
this.rawinflate = new Zlib.RawInflateStream(this.input, this.ip);
/** @type {Zlib.CompressionMethod} */
this.method;
/** @type {!(Array|Uint8Array)} */
this.output = this.rawinflate.output;
};
/**
* decompress.
* @return {!(Uint8Array|Array)} inflated buffer.
*/
Zlib.InflateStream.prototype.decompress = function(input) {
/** @type {!(Uint8Array|Array)} inflated buffer. */
var buffer;
/** @type {number} adler-32 checksum */
var adler32;
// 新しい入力を入力バッファに結合する
// XXX Array, Uint8Array のチェックを行うか確認する
if (input !== void 0) {
if (USE_TYPEDARRAY) {
var tmp = new Uint8Array(this.input.length + input.length);
tmp.set(this.input, 0);
tmp.set(input, this.input.length);
this.input = tmp;
} else {
this.input = this.input.concat(input);
}
}
if (this.method === void 0) {
if(this.readHeader() < 0) {
return new (USE_TYPEDARRAY ? Uint8Array : Array)();
}
}
buffer = this.rawinflate.decompress(this.input, this.ip);
if (this.rawinflate.ip !== 0) {
this.input = USE_TYPEDARRAY ?
this.input.subarray(this.rawinflate.ip) :
this.input.slice(this.rawinflate.ip);
this.ip = 0;
}
// verify adler-32
/*
if (this.verify) {
adler32 =
input[this.ip++] << 24 | input[this.ip++] << 16 |
input[this.ip++] << 8 | input[this.ip++];
if (adler32 !== Zlib.Adler32(buffer)) {
throw new Error('invalid adler-32 checksum');
}
}
*/
return buffer;
};
Zlib.InflateStream.prototype.readHeader = function() {
var ip = this.ip;
var input = this.input;
// Compression Method and Flags
var cmf = input[ip++];
var flg = input[ip++];
if (cmf === void 0 || flg === void 0) {
return -1;
}
// compression method
switch (cmf & 0x0f) {
case Zlib.CompressionMethod.DEFLATE:
this.method = Zlib.CompressionMethod.DEFLATE;
break;
default:
throw new Error('unsupported compression method');
}
// fcheck
if (((cmf << 8) + flg) % 31 !== 0) {
throw new Error('invalid fcheck flag:' + ((cmf << 8) + flg) % 31);
}
// fdict (not supported)
if (flg & 0x20) {
throw new Error('fdict flag is not supported');
}
this.ip = ip;
};
// end of scope
});
/* vim:set expandtab ts=2 sw=2 tw=80: */